diff --git a/[refs] b/[refs]
index 00264dc255d2..b81459e5b312 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 5a559057b4fa0f60b2772fb590bf13e90af7a57d
+refs/heads/master: 5d9ac7fd32f600f9451ea58abdb07f7ed42e921d
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/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt
index f084af0cb8e0..2c85c0692b01 100644
--- a/trunk/Documentation/kernel-parameters.txt
+++ b/trunk/Documentation/kernel-parameters.txt
@@ -2629,10 +2629,8 @@ and is between 256 and 4096 characters. It is defined in the file
aux-ide-disks -- unplug non-primary-master IDE devices
nics -- unplug network devices
all -- unplug all emulated devices (NICs and IDE disks)
- unnecessary -- unplugging emulated devices is
- unnecessary even if the host did not respond to
- the unplug protocol
- never -- do not unplug even if version check succeeds
+ ignore -- continue loading the Xen platform PCI driver even
+ if the version check failed
xirc2ps_cs= [NET,PCMCIA]
Format:
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 5fa8451ec80c..b5b8baa1d70e 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -454,20 +454,9 @@ L: linux-rdma@vger.kernel.org
S: Maintained
F: drivers/infiniband/hw/amso1100/
-ANALOG DEVICES INC ASOC DRIVERS
-L: uclinux-dist-devel@blackfin.uclinux.org
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-W: http://blackfin.uclinux.org/
-S: Supported
-F: sound/soc/blackfin/*
-F: sound/soc/codecs/ad1*
-F: sound/soc/codecs/adau*
-F: sound/soc/codecs/adav*
-F: sound/soc/codecs/ssm*
-
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/
@@ -1483,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
@@ -1676,7 +1665,8 @@ F: kernel/cgroup*
F: mm/*cgroup*
CORETEMP HARDWARE MONITORING DRIVER
-M: Fenghua Yu
+M: Rudolf Marek
+M: Huaxu Wan
L: lm-sensors@lm-sensors.org
S: Maintained
F: Documentation/hwmon/coretemp
@@ -2381,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
@@ -2403,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/
@@ -2411,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
@@ -2419,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
@@ -2574,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_*
@@ -3486,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/
@@ -3505,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
@@ -3515,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/
@@ -3532,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/
@@ -3541,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*
@@ -3551,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*
@@ -4611,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
@@ -4632,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
@@ -5078,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.*
@@ -5495,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 031b61cb5274..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*
@@ -1408,8 +1408,8 @@ checkstack:
$(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
$(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH)
-kernelrelease:
- @echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))"
+kernelrelease: include/config/kernel.release
+ @echo $(KERNELRELEASE)
kernelversion:
@echo $(KERNELVERSION)
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/mach-imx/mach-cpuimx27.c b/trunk/arch/arm/mach-imx/mach-cpuimx27.c
index 339150ab0ea5..575ff1ae85a7 100644
--- a/trunk/arch/arm/mach-imx/mach-cpuimx27.c
+++ b/trunk/arch/arm/mach-imx/mach-cpuimx27.c
@@ -279,13 +279,13 @@ static void __init eukrea_cpuimx27_init(void)
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
mxc_register_device(&mxc_otg_host, &otg_pdata);
}
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
#endif
diff --git a/trunk/arch/arm/mach-imx/mach-pca100.c b/trunk/arch/arm/mach-imx/mach-pca100.c
index 23c9e1f37b9c..a389d1148f18 100644
--- a/trunk/arch/arm/mach-imx/mach-pca100.c
+++ b/trunk/arch/arm/mach-imx/mach-pca100.c
@@ -419,13 +419,13 @@ static void __init pca100_init(void)
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
mxc_register_device(&mxc_otg_host, &otg_pdata);
}
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
#endif
diff --git a/trunk/arch/arm/mach-mx25/mach-cpuimx25.c b/trunk/arch/arm/mach-mx25/mach-cpuimx25.c
index a5f0174290b4..56b2e26d23b4 100644
--- a/trunk/arch/arm/mach-mx25/mach-cpuimx25.c
+++ b/trunk/arch/arm/mach-mx25/mach-cpuimx25.c
@@ -138,7 +138,7 @@ static void __init eukrea_cpuimx25_init(void)
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
mxc_register_device(&mxc_otg, &otg_pdata);
}
diff --git a/trunk/arch/arm/mach-mx3/mach-cpuimx35.c b/trunk/arch/arm/mach-mx3/mach-cpuimx35.c
index 9770a6a973be..63f970f340a2 100644
--- a/trunk/arch/arm/mach-mx3/mach-cpuimx35.c
+++ b/trunk/arch/arm/mach-mx3/mach-cpuimx35.c
@@ -192,7 +192,7 @@ static void __init mxc_board_init(void)
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
mxc_register_device(&mxc_otg_host, &otg_pdata);
}
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/include/asm/bitops.h b/trunk/arch/blackfin/include/asm/bitops.h
index 3f7ef4d97791..d5872cd967ab 100644
--- a/trunk/arch/blackfin/include/asm/bitops.h
+++ b/trunk/arch/blackfin/include/asm/bitops.h
@@ -22,9 +22,7 @@
#include
#include
-#include
#include
-
#include
#include
#include
@@ -117,7 +115,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
* of bits set) of a N-bit word
*/
-static inline unsigned int __arch_hweight32(unsigned int w)
+static inline unsigned int hweight32(unsigned int w)
{
unsigned int res;
@@ -127,20 +125,19 @@ static inline unsigned int __arch_hweight32(unsigned int w)
return res;
}
-static inline unsigned int __arch_hweight64(__u64 w)
+static inline unsigned int hweight64(__u64 w)
{
- return __arch_hweight32((unsigned int)(w >> 32)) +
- __arch_hweight32((unsigned int)w);
+ return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
}
-static inline unsigned int __arch_hweight16(unsigned int w)
+static inline unsigned int hweight16(unsigned int w)
{
- return __arch_hweight32(w & 0xffff);
+ return hweight32(w & 0xffff);
}
-static inline unsigned int __arch_hweight8(unsigned int w)
+static inline unsigned int hweight8(unsigned int w)
{
- return __arch_hweight32(w & 0xff);
+ return hweight32(w & 0xff);
}
#endif /* _BLACKFIN_BITOPS_H */
diff --git a/trunk/arch/blackfin/include/asm/unistd.h b/trunk/arch/blackfin/include/asm/unistd.h
index 14fcd254b185..22886cbdae7a 100644
--- a/trunk/arch/blackfin/include/asm/unistd.h
+++ b/trunk/arch/blackfin/include/asm/unistd.h
@@ -389,11 +389,8 @@
#define __NR_rt_tgsigqueueinfo 368
#define __NR_perf_event_open 369
#define __NR_recvmmsg 370
-#define __NR_fanotify_init 371
-#define __NR_fanotify_mark 372
-#define __NR_prlimit64 373
-#define __NR_syscall 374
+#define __NR_syscall 371
#define NR_syscalls __NR_syscall
/* Old optional stuff no one actually uses */
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/blackfin/mach-common/entry.S b/trunk/arch/blackfin/mach-common/entry.S
index af1bffa21dc1..a5847f5d67c7 100644
--- a/trunk/arch/blackfin/mach-common/entry.S
+++ b/trunk/arch/blackfin/mach-common/entry.S
@@ -1628,9 +1628,6 @@ ENTRY(_sys_call_table)
.long _sys_rt_tgsigqueueinfo
.long _sys_perf_event_open
.long _sys_recvmmsg /* 370 */
- .long _sys_fanotify_init
- .long _sys_fanotify_mark
- .long _sys_prlimit64
.rept NR_syscalls-(.-_sys_call_table)/4
.long _sys_ni_syscall
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/mn10300/mm/dma-alloc.c b/trunk/arch/mn10300/mm/dma-alloc.c
index 159acb02cfd4..4e34880bea03 100644
--- a/trunk/arch/mn10300/mm/dma-alloc.c
+++ b/trunk/arch/mn10300/mm/dma-alloc.c
@@ -25,8 +25,7 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
unsigned long addr;
void *ret;
- pr_debug("dma_alloc_coherent(%s,%zu,%x)\n",
- dev ? dev_name(dev) : "?", size, gfp);
+ printk("dma_alloc_coherent(%s,%zu,,%x)\n", dev_name(dev), size, gfp);
if (0xbe000000 - pci_sram_allocated >= size) {
size = (size + 255) & ~255;
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/Makefile b/trunk/arch/powerpc/Makefile
index b7212b619c52..e3ea151c9597 100644
--- a/trunk/arch/powerpc/Makefile
+++ b/trunk/arch/powerpc/Makefile
@@ -164,7 +164,7 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
all: zImage
# With make 3.82 we cannot mix normal and wildcard targets
-BOOT_TARGETS1 := zImage zImage.initrd uImage
+BOOT_TARGETS1 := zImage zImage.initrd uImaged
BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.%
PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2)
diff --git a/trunk/arch/powerpc/boot/dts/canyonlands.dts b/trunk/arch/powerpc/boot/dts/canyonlands.dts
index a30370396250..5806ef0b860b 100644
--- a/trunk/arch/powerpc/boot/dts/canyonlands.dts
+++ b/trunk/arch/powerpc/boot/dts/canyonlands.dts
@@ -163,14 +163,6 @@
interrupts = <0x1e 4>;
};
- SATA0: sata@bffd1000 {
- compatible = "amcc,sata-460ex";
- reg = <4 0xbffd1000 0x800 4 0xbffd0800 0x400>;
- interrupt-parent = <&UIC3>;
- interrupts = <0x0 0x4 /* SATA */
- 0x5 0x4>; /* AHBDMA */
- };
-
POB0: opb {
compatible = "ibm,opb-460ex", "ibm,opb";
#address-cells = <1>;
diff --git a/trunk/arch/powerpc/include/asm/mmu-hash64.h b/trunk/arch/powerpc/include/asm/mmu-hash64.h
index acac35d5b382..0e398cfee2c8 100644
--- a/trunk/arch/powerpc/include/asm/mmu-hash64.h
+++ b/trunk/arch/powerpc/include/asm/mmu-hash64.h
@@ -433,7 +433,7 @@ typedef struct {
* with. However gcc is not clever enough to compute the
* modulus (2^n-1) without a second multiply.
*/
-#define vsid_scramble(protovsid, size) \
+#define vsid_scrample(protovsid, size) \
((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size))
#else /* 1 */
diff --git a/trunk/arch/powerpc/include/asm/reg.h b/trunk/arch/powerpc/include/asm/reg.h
index ff0005eec7dd..d8be016d2ede 100644
--- a/trunk/arch/powerpc/include/asm/reg.h
+++ b/trunk/arch/powerpc/include/asm/reg.h
@@ -951,14 +951,7 @@
#ifdef CONFIG_PPC64
extern void ppc64_runlatch_on(void);
-extern void __ppc64_runlatch_off(void);
-
-#define ppc64_runlatch_off() \
- do { \
- if (cpu_has_feature(CPU_FTR_CTRL) && \
- test_thread_flag(TIF_RUNLATCH)) \
- __ppc64_runlatch_off(); \
- } while (0)
+extern void ppc64_runlatch_off(void);
extern unsigned long scom970_read(unsigned int address);
extern void scom970_write(unsigned int address, unsigned long value);
diff --git a/trunk/arch/powerpc/include/asm/rwsem.h b/trunk/arch/powerpc/include/asm/rwsem.h
index 8447d89fbe72..24cd9281ec37 100644
--- a/trunk/arch/powerpc/include/asm/rwsem.h
+++ b/trunk/arch/powerpc/include/asm/rwsem.h
@@ -21,20 +21,15 @@
/*
* the semaphore definition
*/
-#ifdef CONFIG_PPC64
-# define RWSEM_ACTIVE_MASK 0xffffffffL
-#else
-# define RWSEM_ACTIVE_MASK 0x0000ffffL
-#endif
-
-#define RWSEM_UNLOCKED_VALUE 0x00000000L
-#define RWSEM_ACTIVE_BIAS 0x00000001L
-#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1)
+struct rw_semaphore {
+ /* XXX this should be able to be an atomic_t -- paulus */
+ signed int count;
+#define RWSEM_UNLOCKED_VALUE 0x00000000
+#define RWSEM_ACTIVE_BIAS 0x00000001
+#define RWSEM_ACTIVE_MASK 0x0000ffff
+#define RWSEM_WAITING_BIAS (-0x00010000)
#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
-
-struct rw_semaphore {
- long count;
spinlock_t wait_lock;
struct list_head wait_list;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -48,13 +43,9 @@ struct rw_semaphore {
# define __RWSEM_DEP_MAP_INIT(lockname)
#endif
-#define __RWSEM_INITIALIZER(name) \
-{ \
- RWSEM_UNLOCKED_VALUE, \
- __SPIN_LOCK_UNLOCKED((name).wait_lock), \
- LIST_HEAD_INIT((name).wait_list) \
- __RWSEM_DEP_MAP_INIT(name) \
-}
+#define __RWSEM_INITIALIZER(name) \
+ { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
+ LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) }
#define DECLARE_RWSEM(name) \
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
@@ -79,13 +70,13 @@ extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
*/
static inline void __down_read(struct rw_semaphore *sem)
{
- if (unlikely(atomic_long_inc_return((atomic_long_t *)&sem->count) <= 0))
+ if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0))
rwsem_down_read_failed(sem);
}
static inline int __down_read_trylock(struct rw_semaphore *sem)
{
- long tmp;
+ int tmp;
while ((tmp = sem->count) >= 0) {
if (tmp == cmpxchg(&sem->count, tmp,
@@ -101,10 +92,10 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
*/
static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
- long tmp;
+ int tmp;
- tmp = atomic_long_add_return(RWSEM_ACTIVE_WRITE_BIAS,
- (atomic_long_t *)&sem->count);
+ tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+ (atomic_t *)(&sem->count));
if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
rwsem_down_write_failed(sem);
}
@@ -116,7 +107,7 @@ static inline void __down_write(struct rw_semaphore *sem)
static inline int __down_write_trylock(struct rw_semaphore *sem)
{
- long tmp;
+ int tmp;
tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
RWSEM_ACTIVE_WRITE_BIAS);
@@ -128,9 +119,9 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
*/
static inline void __up_read(struct rw_semaphore *sem)
{
- long tmp;
+ int tmp;
- tmp = atomic_long_dec_return((atomic_long_t *)&sem->count);
+ tmp = atomic_dec_return((atomic_t *)(&sem->count));
if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0))
rwsem_wake(sem);
}
@@ -140,17 +131,17 @@ static inline void __up_read(struct rw_semaphore *sem)
*/
static inline void __up_write(struct rw_semaphore *sem)
{
- if (unlikely(atomic_long_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
- (atomic_long_t *)&sem->count) < 0))
+ if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+ (atomic_t *)(&sem->count)) < 0))
rwsem_wake(sem);
}
/*
* implement atomic add functionality
*/
-static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
+static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
{
- atomic_long_add(delta, (atomic_long_t *)&sem->count);
+ atomic_add(delta, (atomic_t *)(&sem->count));
}
/*
@@ -158,10 +149,9 @@ static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
*/
static inline void __downgrade_write(struct rw_semaphore *sem)
{
- long tmp;
+ int tmp;
- tmp = atomic_long_add_return(-RWSEM_WAITING_BIAS,
- (atomic_long_t *)&sem->count);
+ tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
if (tmp < 0)
rwsem_downgrade_wake(sem);
}
@@ -169,14 +159,14 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
/*
* implement exchange and add functionality
*/
-static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
+static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
{
- return atomic_long_add_return(delta, (atomic_long_t *)&sem->count);
+ return atomic_add_return(delta, (atomic_t *)(&sem->count));
}
static inline int rwsem_is_locked(struct rw_semaphore *sem)
{
- return sem->count != 0;
+ return (sem->count != 0);
}
#endif /* __KERNEL__ */
diff --git a/trunk/arch/powerpc/include/asm/systbl.h b/trunk/arch/powerpc/include/asm/systbl.h
index 3d212669a130..a5ee345b6a5c 100644
--- a/trunk/arch/powerpc/include/asm/systbl.h
+++ b/trunk/arch/powerpc/include/asm/systbl.h
@@ -326,6 +326,3 @@ SYSCALL_SPU(perf_event_open)
COMPAT_SYS_SPU(preadv)
COMPAT_SYS_SPU(pwritev)
COMPAT_SYS(rt_tgsigqueueinfo)
-SYSCALL(fanotify_init)
-COMPAT_SYS(fanotify_mark)
-SYSCALL_SPU(prlimit64)
diff --git a/trunk/arch/powerpc/include/asm/unistd.h b/trunk/arch/powerpc/include/asm/unistd.h
index 597e6f9d094a..f0a10266e7f7 100644
--- a/trunk/arch/powerpc/include/asm/unistd.h
+++ b/trunk/arch/powerpc/include/asm/unistd.h
@@ -345,13 +345,10 @@
#define __NR_preadv 320
#define __NR_pwritev 321
#define __NR_rt_tgsigqueueinfo 322
-#define __NR_fanotify_init 323
-#define __NR_fanotify_mark 324
-#define __NR_prlimit64 325
#ifdef __KERNEL__
-#define __NR_syscalls 326
+#define __NR_syscalls 323
#define __NR__exit __NR_exit
#define NR_syscalls __NR_syscalls
diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c
index 1f9123f412ec..65e2b4e10f97 100644
--- a/trunk/arch/powerpc/kernel/cputable.c
+++ b/trunk/arch/powerpc/kernel/cputable.c
@@ -1826,6 +1826,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_47X,
.cpu_user_features = COMMON_USER_BOOKE |
PPC_FEATURE_HAS_FPU,
+ .cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_47x |
MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL,
.icache_bsize = 32,
diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c
index 4457382f8667..417f7b05a9ce 100644
--- a/trunk/arch/powerpc/kernel/crash.c
+++ b/trunk/arch/powerpc/kernel/crash.c
@@ -402,18 +402,6 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
*/
hard_irq_disable();
- /*
- * Make a note of crashing cpu. Will be used in machine_kexec
- * such that another IPI will not be sent.
- */
- crashing_cpu = smp_processor_id();
- crash_save_cpu(regs, crashing_cpu);
- crash_kexec_prepare_cpus(crashing_cpu);
- cpu_set(crashing_cpu, cpus_in_crash);
-#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP)
- crash_kexec_wait_realmode(crashing_cpu);
-#endif
-
for_each_irq(i) {
struct irq_desc *desc = irq_to_desc(i);
@@ -450,8 +438,18 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
crash_shutdown_cpu = -1;
__debugger_fault_handler = old_handler;
+ /*
+ * Make a note of crashing cpu. Will be used in machine_kexec
+ * such that another IPI will not be sent.
+ */
+ crashing_cpu = smp_processor_id();
+ crash_save_cpu(regs, crashing_cpu);
+ crash_kexec_prepare_cpus(crashing_cpu);
+ cpu_set(crashing_cpu, cpus_in_crash);
crash_kexec_stop_spus();
-
+#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP)
+ crash_kexec_wait_realmode(crashing_cpu);
+#endif
if (ppc_md.kexec_cpu_down)
ppc_md.kexec_cpu_down(1, 0);
}
diff --git a/trunk/arch/powerpc/kernel/head_44x.S b/trunk/arch/powerpc/kernel/head_44x.S
index 562305b40a8e..5ab484ef06a7 100644
--- a/trunk/arch/powerpc/kernel/head_44x.S
+++ b/trunk/arch/powerpc/kernel/head_44x.S
@@ -113,10 +113,6 @@ _ENTRY(_start);
stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
stw r6, 0(r5)
- /* Clear the Machine Check Syndrome Register */
- li r0,0
- mtspr SPRN_MCSR,r0
-
/* Let's move on */
lis r4,start_kernel@h
ori r4,r4,start_kernel@l
diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S
index 4d6681dce816..844a44b64472 100644
--- a/trunk/arch/powerpc/kernel/head_64.S
+++ b/trunk/arch/powerpc/kernel/head_64.S
@@ -572,6 +572,9 @@ __secondary_start:
/* Set thread priority to MEDIUM */
HMT_MEDIUM
+ /* Do early setup for that CPU (stab, slb, hash table pointer) */
+ bl .early_setup_secondary
+
/* Initialize the kernel stack. Just a repeat for iSeries. */
LOAD_REG_ADDR(r3, current_set)
sldi r28,r24,3 /* get current_set[cpu#] */
@@ -579,9 +582,6 @@ __secondary_start:
addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
std r1,PACAKSAVE(r13)
- /* Do early setup for that CPU (stab, slb, hash table pointer) */
- bl .early_setup_secondary
-
/* Clear backchain so we get nice backtraces */
li r7,0
mtlr r7
diff --git a/trunk/arch/powerpc/kernel/idle.c b/trunk/arch/powerpc/kernel/idle.c
index 39a2baa6ad58..049dda60e475 100644
--- a/trunk/arch/powerpc/kernel/idle.c
+++ b/trunk/arch/powerpc/kernel/idle.c
@@ -94,9 +94,9 @@ void cpu_idle(void)
HMT_medium();
ppc64_runlatch_on();
tick_nohz_restart_sched_tick();
- preempt_enable_no_resched();
if (cpu_should_die())
cpu_die();
+ preempt_enable_no_resched();
schedule();
preempt_disable();
}
diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c
index 4a65386995d7..d3ce67cf03be 100644
--- a/trunk/arch/powerpc/kernel/irq.c
+++ b/trunk/arch/powerpc/kernel/irq.c
@@ -67,7 +67,6 @@
#include
#include
#include
-#include
#ifdef CONFIG_PPC64
#include
@@ -447,23 +446,22 @@ struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly;
void exc_lvl_ctx_init(void)
{
struct thread_info *tp;
- int i, hw_cpu;
+ int i;
for_each_possible_cpu(i) {
- hw_cpu = get_hard_smp_processor_id(i);
- memset((void *)critirq_ctx[hw_cpu], 0, THREAD_SIZE);
- tp = critirq_ctx[hw_cpu];
+ memset((void *)critirq_ctx[i], 0, THREAD_SIZE);
+ tp = critirq_ctx[i];
tp->cpu = i;
tp->preempt_count = 0;
#ifdef CONFIG_BOOKE
- memset((void *)dbgirq_ctx[hw_cpu], 0, THREAD_SIZE);
- tp = dbgirq_ctx[hw_cpu];
+ memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE);
+ tp = dbgirq_ctx[i];
tp->cpu = i;
tp->preempt_count = 0;
- memset((void *)mcheckirq_ctx[hw_cpu], 0, THREAD_SIZE);
- tp = mcheckirq_ctx[hw_cpu];
+ memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE);
+ tp = mcheckirq_ctx[i];
tp->cpu = i;
tp->preempt_count = HARDIRQ_OFFSET;
#endif
diff --git a/trunk/arch/powerpc/kernel/pci_of_scan.c b/trunk/arch/powerpc/kernel/pci_of_scan.c
index e751506323b4..6ddb795f83e8 100644
--- a/trunk/arch/powerpc/kernel/pci_of_scan.c
+++ b/trunk/arch/powerpc/kernel/pci_of_scan.c
@@ -336,7 +336,7 @@ static void __devinit __of_scan_bus(struct device_node *node,
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
struct device_node *child = pci_device_to_OF_node(dev);
- if (child)
+ if (dev)
of_scan_pci_bridge(child, dev);
}
}
diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c
index b1c648a36b03..feacfb789686 100644
--- a/trunk/arch/powerpc/kernel/process.c
+++ b/trunk/arch/powerpc/kernel/process.c
@@ -728,7 +728,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
p->thread.regs = childregs;
if (clone_flags & CLONE_SETTLS) {
#ifdef CONFIG_PPC64
- if (!is_32bit_task())
+ if (!test_thread_flag(TIF_32BIT))
childregs->gpr[13] = childregs->gpr[6];
else
#endif
@@ -823,7 +823,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
regs->nip = start;
regs->msr = MSR_USER;
#else
- if (!is_32bit_task()) {
+ if (!test_thread_flag(TIF_32BIT)) {
unsigned long entry, toc;
/* start is a relocated pointer to the function descriptor for
@@ -995,7 +995,7 @@ int sys_clone(unsigned long clone_flags, unsigned long usp,
if (usp == 0)
usp = regs->gpr[1]; /* stack pointer for child */
#ifdef CONFIG_PPC64
- if (is_32bit_task()) {
+ if (test_thread_flag(TIF_32BIT)) {
parent_tidp = TRUNC_PTR(parent_tidp);
child_tidp = TRUNC_PTR(child_tidp);
}
@@ -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;
@@ -1199,17 +1198,19 @@ void ppc64_runlatch_on(void)
}
}
-void __ppc64_runlatch_off(void)
+void ppc64_runlatch_off(void)
{
unsigned long ctrl;
- HMT_medium();
+ if (cpu_has_feature(CPU_FTR_CTRL) && test_thread_flag(TIF_RUNLATCH)) {
+ HMT_medium();
- clear_thread_flag(TIF_RUNLATCH);
+ clear_thread_flag(TIF_RUNLATCH);
- ctrl = mfspr(SPRN_CTRLF);
- ctrl &= ~CTRL_RUNLATCH;
- mtspr(SPRN_CTRLT, ctrl);
+ ctrl = mfspr(SPRN_CTRLF);
+ ctrl &= ~CTRL_RUNLATCH;
+ mtspr(SPRN_CTRLT, ctrl);
+ }
}
#endif
diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c
index 93666f9cabf1..a10ffc85ada7 100644
--- a/trunk/arch/powerpc/kernel/setup_32.c
+++ b/trunk/arch/powerpc/kernel/setup_32.c
@@ -258,18 +258,17 @@ static void __init irqstack_early_init(void)
#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
static void __init exc_lvl_early_init(void)
{
- unsigned int i, hw_cpu;
+ unsigned int i;
/* interrupt stacks must be in lowmem, we get that for free on ppc32
* as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */
for_each_possible_cpu(i) {
- hw_cpu = get_hard_smp_processor_id(i);
- critirq_ctx[hw_cpu] = (struct thread_info *)
+ critirq_ctx[i] = (struct thread_info *)
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
#ifdef CONFIG_BOOKE
- dbgirq_ctx[hw_cpu] = (struct thread_info *)
+ dbgirq_ctx[i] = (struct thread_info *)
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
- mcheckirq_ctx[hw_cpu] = (struct thread_info *)
+ mcheckirq_ctx[i] = (struct thread_info *)
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
#endif
}
diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c
index e72690ec9b87..1bee4b68fa45 100644
--- a/trunk/arch/powerpc/kernel/setup_64.c
+++ b/trunk/arch/powerpc/kernel/setup_64.c
@@ -95,7 +95,7 @@ int ucache_bsize;
#ifdef CONFIG_SMP
-static char *smt_enabled_cmdline;
+static int smt_enabled_cmdline;
/* Look for ibm,smt-enabled OF option */
static void check_smt_enabled(void)
@@ -103,46 +103,37 @@ static void check_smt_enabled(void)
struct device_node *dn;
const char *smt_option;
- /* Default to enabling all threads */
- smt_enabled_at_boot = threads_per_core;
-
/* Allow the command line to overrule the OF option */
- if (smt_enabled_cmdline) {
- if (!strcmp(smt_enabled_cmdline, "on"))
- smt_enabled_at_boot = threads_per_core;
- else if (!strcmp(smt_enabled_cmdline, "off"))
- smt_enabled_at_boot = 0;
- else {
- long smt;
- int rc;
-
- rc = strict_strtol(smt_enabled_cmdline, 10, &smt);
- if (!rc)
- smt_enabled_at_boot =
- min(threads_per_core, (int)smt);
- }
- } else {
- dn = of_find_node_by_path("/options");
- if (dn) {
- smt_option = of_get_property(dn, "ibm,smt-enabled",
- NULL);
-
- if (smt_option) {
- if (!strcmp(smt_option, "on"))
- smt_enabled_at_boot = threads_per_core;
- else if (!strcmp(smt_option, "off"))
- smt_enabled_at_boot = 0;
- }
-
- of_node_put(dn);
- }
- }
+ if (smt_enabled_cmdline)
+ return;
+
+ dn = of_find_node_by_path("/options");
+
+ if (dn) {
+ smt_option = of_get_property(dn, "ibm,smt-enabled", NULL);
+
+ if (smt_option) {
+ if (!strcmp(smt_option, "on"))
+ smt_enabled_at_boot = 1;
+ else if (!strcmp(smt_option, "off"))
+ smt_enabled_at_boot = 0;
+ }
+ }
}
/* Look for smt-enabled= cmdline option */
static int __init early_smt_enabled(char *p)
{
- smt_enabled_cmdline = p;
+ smt_enabled_cmdline = 1;
+
+ if (!p)
+ return 0;
+
+ if (!strcmp(p, "on") || !strcmp(p, "1"))
+ smt_enabled_at_boot = 1;
+ else if (!strcmp(p, "off") || !strcmp(p, "0"))
+ smt_enabled_at_boot = 0;
+
return 0;
}
early_param("smt-enabled", early_smt_enabled);
@@ -389,8 +380,8 @@ void __init setup_system(void)
*/
xmon_setup();
- smp_setup_cpu_maps();
check_smt_enabled();
+ smp_setup_cpu_maps();
#ifdef CONFIG_SMP
/* Release secondary cpus out of their spinloops at 0x60 now that
diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c
index 0008bc58e826..a61b3ddd7bb3 100644
--- a/trunk/arch/powerpc/kernel/smp.c
+++ b/trunk/arch/powerpc/kernel/smp.c
@@ -427,11 +427,11 @@ int __cpuinit __cpu_up(unsigned int cpu)
#endif
if (!cpu_callin_map[cpu]) {
- printk(KERN_ERR "Processor %u is stuck.\n", cpu);
+ printk("Processor %u is stuck.\n", cpu);
return -ENOENT;
}
- DBG("Processor %u found.\n", cpu);
+ printk("Processor %u found.\n", cpu);
if (smp_ops->give_timebase)
smp_ops->give_timebase();
diff --git a/trunk/arch/powerpc/kernel/sys_ppc32.c b/trunk/arch/powerpc/kernel/sys_ppc32.c
index b1b6043a56c4..20fd701a686a 100644
--- a/trunk/arch/powerpc/kernel/sys_ppc32.c
+++ b/trunk/arch/powerpc/kernel/sys_ppc32.c
@@ -616,11 +616,3 @@ asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags,
return sys_sync_file_range(fd, offset, nbytes, flags);
}
-
-asmlinkage long compat_sys_fanotify_mark(int fanotify_fd, unsigned int flags,
- unsigned mask_hi, unsigned mask_lo,
- int dfd, const char __user *pathname)
-{
- u64 mask = ((u64)mask_hi << 32) | mask_lo;
- return sys_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname);
-}
diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c
index fa3469ddaef8..00b9436f7652 100644
--- a/trunk/arch/powerpc/kernel/vio.c
+++ b/trunk/arch/powerpc/kernel/vio.c
@@ -1059,7 +1059,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
if (!dma_window)
return NULL;
- tbl = kzalloc(sizeof(*tbl), GFP_KERNEL);
+ tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
if (tbl == NULL)
return NULL;
@@ -1072,7 +1072,6 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
tbl->it_busno = 0;
tbl->it_type = TCE_VB;
- tbl->it_blocksize = 16;
return iommu_init_table(tbl, -1);
}
diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c
index ace85fa74b29..71f1415e2472 100644
--- a/trunk/arch/powerpc/mm/init_64.c
+++ b/trunk/arch/powerpc/mm/init_64.c
@@ -79,9 +79,7 @@
#endif /* CONFIG_PPC_STD_MMU_64 */
phys_addr_t memstart_addr = ~0;
-EXPORT_SYMBOL_GPL(memstart_addr);
phys_addr_t kernstart_addr;
-EXPORT_SYMBOL_GPL(kernstart_addr);
void free_initmem(void)
{
diff --git a/trunk/arch/powerpc/mm/tlb_nohash_low.S b/trunk/arch/powerpc/mm/tlb_nohash_low.S
index b9d9fed8f36e..cfa768203d08 100644
--- a/trunk/arch/powerpc/mm/tlb_nohash_low.S
+++ b/trunk/arch/powerpc/mm/tlb_nohash_low.S
@@ -200,7 +200,6 @@ _GLOBAL(_tlbivax_bcast)
rlwimi r5,r4,0,16,31
wrteei 0
mtspr SPRN_MMUCR,r5
- isync
/* tlbivax 0,r3 - use .long to avoid binutils deps */
.long 0x7c000624 | (r3 << 11)
isync
diff --git a/trunk/arch/powerpc/platforms/Kconfig b/trunk/arch/powerpc/platforms/Kconfig
index 81c9208025fa..d1663db7810f 100644
--- a/trunk/arch/powerpc/platforms/Kconfig
+++ b/trunk/arch/powerpc/platforms/Kconfig
@@ -106,7 +106,8 @@ config MMIO_NVRAM
config MPIC_U3_HT_IRQS
bool
- default n
+ depends on PPC_MAPLE
+ default y
config MPIC_BROKEN_REGREAD
bool
diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c
index 26a067122a54..58b13ce3847e 100644
--- a/trunk/arch/powerpc/platforms/cell/iommu.c
+++ b/trunk/arch/powerpc/platforms/cell/iommu.c
@@ -477,7 +477,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
ioid = cell_iommu_get_ioid(np);
- window = kzalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid);
+ window = kmalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid);
BUG_ON(window == NULL);
window->offset = offset;
diff --git a/trunk/arch/powerpc/platforms/iseries/iommu.c b/trunk/arch/powerpc/platforms/iseries/iommu.c
index d8b76335bd13..ce61cea0afb5 100644
--- a/trunk/arch/powerpc/platforms/iseries/iommu.c
+++ b/trunk/arch/powerpc/platforms/iseries/iommu.c
@@ -184,7 +184,7 @@ static void pci_dma_dev_setup_iseries(struct pci_dev *pdev)
BUG_ON(lsn == NULL);
- tbl = kzalloc(sizeof(struct iommu_table), GFP_KERNEL);
+ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl);
diff --git a/trunk/arch/powerpc/platforms/powermac/feature.c b/trunk/arch/powerpc/platforms/powermac/feature.c
index df423993f175..39df6ab1735a 100644
--- a/trunk/arch/powerpc/platforms/powermac/feature.c
+++ b/trunk/arch/powerpc/platforms/powermac/feature.c
@@ -2873,11 +2873,12 @@ set_initial_features(void)
/* Switch airport off */
for_each_node_by_name(np, "radio") {
- if (np->parent == macio_chips[0].of_node) {
+ if (np && np->parent == macio_chips[0].of_node) {
macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
core99_airport_enable(np, 0, 0);
}
}
+ of_node_put(np);
}
/* On all machines that support sound PM, switch sound off */
diff --git a/trunk/arch/powerpc/platforms/powermac/pci.c b/trunk/arch/powerpc/platforms/powermac/pci.c
index 3bc075c788ef..ab2027cdf893 100644
--- a/trunk/arch/powerpc/platforms/powermac/pci.c
+++ b/trunk/arch/powerpc/platforms/powermac/pci.c
@@ -1155,11 +1155,13 @@ void __init pmac_pcibios_after_init(void)
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
}
}
+ of_node_put(nd);
for_each_node_by_name(nd, "ethernet") {
if (nd->parent && of_device_is_compatible(nd, "gmac")
&& of_device_is_compatible(nd->parent, "uni-north"))
pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
}
+ of_node_put(nd);
}
void pmac_pci_fixup_cardbus(struct pci_dev* dev)
diff --git a/trunk/arch/powerpc/platforms/pseries/iommu.c b/trunk/arch/powerpc/platforms/pseries/iommu.c
index a77bcaed80af..395848e30c52 100644
--- a/trunk/arch/powerpc/platforms/pseries/iommu.c
+++ b/trunk/arch/powerpc/platforms/pseries/iommu.c
@@ -403,7 +403,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
pci->phb->dma_window_size = 0x8000000ul;
pci->phb->dma_window_base_cur = 0x8000000ul;
- tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
+ tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
pci->phb->node);
iommu_table_setparms(pci->phb, dn, tbl);
@@ -448,7 +448,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
pdn->full_name, ppci->iommu_table);
if (!ppci->iommu_table) {
- tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
+ tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
ppci->phb->node);
iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window,
bus->number);
@@ -478,7 +478,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
struct pci_controller *phb = PCI_DN(dn)->phb;
pr_debug(" --> first child, no bridge. Allocating iommu table.\n");
- tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
+ tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
phb->node);
iommu_table_setparms(phb, dn, tbl);
PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
@@ -544,7 +544,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
pci = PCI_DN(pdn);
if (!pci->iommu_table) {
- tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
+ tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
pci->phb->node);
iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window,
pci->phb->bus->number);
diff --git a/trunk/arch/powerpc/platforms/pseries/smp.c b/trunk/arch/powerpc/platforms/pseries/smp.c
index 0317cce877c6..3b1bf61c45be 100644
--- a/trunk/arch/powerpc/platforms/pseries/smp.c
+++ b/trunk/arch/powerpc/platforms/pseries/smp.c
@@ -182,13 +182,10 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
/* Special case - we inhibit secondary thread startup
* during boot if the user requests it.
*/
- if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) {
- if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
- return 0;
- if (smt_enabled_at_boot
- && cpu_thread_in_core(nr) >= smt_enabled_at_boot)
- return 0;
- }
+ if (system_state < SYSTEM_RUNNING &&
+ cpu_has_feature(CPU_FTR_SMT) &&
+ !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
+ return 0;
return 1;
}
diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c
index 93834b0d8272..5b22b07c8f67 100644
--- a/trunk/arch/powerpc/platforms/pseries/xics.c
+++ b/trunk/arch/powerpc/platforms/pseries/xics.c
@@ -928,10 +928,8 @@ void xics_migrate_irqs_away(void)
if (xics_status[0] != hw_cpu)
goto unlock;
- /* This is expected during cpu offline. */
- if (cpu_online(cpu))
- printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
- virq, cpu);
+ printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
+ virq, cpu);
/* Reset affinity to all cpus */
cpumask_setall(irq_to_desc(virq)->affinity);
diff --git a/trunk/arch/s390/include/asm/hugetlb.h b/trunk/arch/s390/include/asm/hugetlb.h
index bb8343d157bc..670a1d1745d2 100644
--- a/trunk/arch/s390/include/asm/hugetlb.h
+++ b/trunk/arch/s390/include/asm/hugetlb.h
@@ -97,7 +97,6 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
{
pte_t pte = huge_ptep_get(ptep);
- mm->context.flush_mm = 1;
pmd_clear((pmd_t *) ptep);
return pte;
}
@@ -168,8 +167,7 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
({ \
pte_t __pte = huge_ptep_get(__ptep); \
if (pte_write(__pte)) { \
- (__mm)->context.flush_mm = 1; \
- if (atomic_read(&(__mm)->context.attach_count) > 1 || \
+ if (atomic_read(&(__mm)->mm_users) > 1 || \
(__mm) != current->active_mm) \
huge_ptep_invalidate(__mm, __addr, __ptep); \
set_huge_pte_at(__mm, __addr, __ptep, \
diff --git a/trunk/arch/s390/include/asm/mmu.h b/trunk/arch/s390/include/asm/mmu.h
index 78522cdefdd4..99e3409102b9 100644
--- a/trunk/arch/s390/include/asm/mmu.h
+++ b/trunk/arch/s390/include/asm/mmu.h
@@ -2,8 +2,6 @@
#define __MMU_H
typedef struct {
- atomic_t attach_count;
- unsigned int flush_mm;
spinlock_t list_lock;
struct list_head crst_list;
struct list_head pgtable_list;
diff --git a/trunk/arch/s390/include/asm/mmu_context.h b/trunk/arch/s390/include/asm/mmu_context.h
index a6f0e7cc9cde..976e273988c2 100644
--- a/trunk/arch/s390/include/asm/mmu_context.h
+++ b/trunk/arch/s390/include/asm/mmu_context.h
@@ -11,14 +11,11 @@
#include
#include
-#include
#include
static inline int init_new_context(struct task_struct *tsk,
struct mm_struct *mm)
{
- atomic_set(&mm->context.attach_count, 0);
- mm->context.flush_mm = 0;
mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
#ifdef CONFIG_64BIT
mm->context.asce_bits |= _ASCE_TYPE_REGION3;
@@ -79,12 +76,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
{
cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
update_mm(next, tsk);
- atomic_dec(&prev->context.attach_count);
- WARN_ON(atomic_read(&prev->context.attach_count) < 0);
- atomic_inc(&next->context.attach_count);
- /* Check for TLBs not flushed yet */
- if (next->context.flush_mm)
- __tlb_flush_mm(next);
}
#define enter_lazy_tlb(mm,tsk) do { } while (0)
diff --git a/trunk/arch/s390/include/asm/pgtable.h b/trunk/arch/s390/include/asm/pgtable.h
index 3157441ee1da..89a504c3f12e 100644
--- a/trunk/arch/s390/include/asm/pgtable.h
+++ b/trunk/arch/s390/include/asm/pgtable.h
@@ -880,8 +880,7 @@ static inline void ptep_invalidate(struct mm_struct *mm,
#define ptep_get_and_clear(__mm, __address, __ptep) \
({ \
pte_t __pte = *(__ptep); \
- (__mm)->context.flush_mm = 1; \
- if (atomic_read(&(__mm)->context.attach_count) > 1 || \
+ if (atomic_read(&(__mm)->mm_users) > 1 || \
(__mm) != current->active_mm) \
ptep_invalidate(__mm, __address, __ptep); \
else \
@@ -924,8 +923,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
({ \
pte_t __pte = *(__ptep); \
if (pte_write(__pte)) { \
- (__mm)->context.flush_mm = 1; \
- if (atomic_read(&(__mm)->context.attach_count) > 1 || \
+ if (atomic_read(&(__mm)->mm_users) > 1 || \
(__mm) != current->active_mm) \
ptep_invalidate(__mm, __addr, __ptep); \
set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \
diff --git a/trunk/arch/s390/include/asm/tlb.h b/trunk/arch/s390/include/asm/tlb.h
index fd1c00d08bf5..81150b053689 100644
--- a/trunk/arch/s390/include/asm/tlb.h
+++ b/trunk/arch/s390/include/asm/tlb.h
@@ -50,7 +50,8 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
- tlb->fullmm = full_mm_flush;
+ tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) ||
+ (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm);
tlb->nr_ptes = 0;
tlb->nr_pxds = TLB_NR_PTRS;
if (tlb->fullmm)
diff --git a/trunk/arch/s390/include/asm/tlbflush.h b/trunk/arch/s390/include/asm/tlbflush.h
index 29d5d6d4becc..304cffa623e1 100644
--- a/trunk/arch/s390/include/asm/tlbflush.h
+++ b/trunk/arch/s390/include/asm/tlbflush.h
@@ -94,12 +94,8 @@ static inline void __tlb_flush_mm(struct mm_struct * mm)
static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
{
- spin_lock(&mm->page_table_lock);
- if (mm->context.flush_mm) {
+ if (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm)
__tlb_flush_mm(mm);
- mm->context.flush_mm = 0;
- }
- spin_unlock(&mm->page_table_lock);
}
/*
diff --git a/trunk/arch/s390/kernel/entry.h b/trunk/arch/s390/kernel/entry.h
index ff579b6bde06..403fb430a896 100644
--- a/trunk/arch/s390/kernel/entry.h
+++ b/trunk/arch/s390/kernel/entry.h
@@ -42,8 +42,8 @@ long sys_clone(unsigned long newsp, unsigned long clone_flags,
int __user *parent_tidptr, int __user *child_tidptr);
long sys_vfork(void);
void execve_tail(void);
-long sys_execve(const char __user *name, const char __user *const __user *argv,
- const char __user *const __user *envp);
+long sys_execve(const char __user *name, char __user * __user *argv,
+ char __user * __user *envp);
long sys_sigsuspend(int history0, int history1, old_sigset_t mask);
long sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact);
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/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c
index 8127ebd59c4d..541053ed234e 100644
--- a/trunk/arch/s390/kernel/smp.c
+++ b/trunk/arch/s390/kernel/smp.c
@@ -583,7 +583,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
sf->gprs[9] = (unsigned long) sf;
cpu_lowcore->save_area[15] = (unsigned long) sf;
__ctl_store(cpu_lowcore->cregs_save_area, 0, 15);
- atomic_inc(&init_mm.context.attach_count);
asm volatile(
" stam 0,15,0(%0)"
: : "a" (&cpu_lowcore->access_regs_save_area) : "memory");
@@ -660,7 +659,6 @@ void __cpu_die(unsigned int cpu)
while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy)
udelay(10);
smp_free_lowcore(cpu);
- atomic_dec(&init_mm.context.attach_count);
pr_info("Processor %d stopped\n", cpu);
}
diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c
index 30eb6d02ddb8..acc91c75bc94 100644
--- a/trunk/arch/s390/mm/init.c
+++ b/trunk/arch/s390/mm/init.c
@@ -74,8 +74,6 @@ void __init paging_init(void)
__ctl_load(S390_lowcore.kernel_asce, 13, 13);
__raw_local_irq_ssm(ssm_mask);
- atomic_set(&init_mm.context.attach_count, 1);
-
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
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 bdb2ff880bdd..2050ca02c423 100644
--- a/trunk/arch/sparc/include/asm/atomic_64.h
+++ b/trunk/arch/sparc/include/asm/atomic_64.h
@@ -20,14 +20,14 @@
#define atomic64_set(v, i) (((v)->counter) = i)
extern void atomic_add(int, atomic_t *);
-extern void atomic64_add(long, atomic64_t *);
+extern void atomic64_add(int, atomic64_t *);
extern void atomic_sub(int, atomic_t *);
-extern void atomic64_sub(long, atomic64_t *);
+extern void atomic64_sub(int, atomic64_t *);
extern int atomic_add_ret(int, atomic_t *);
-extern long atomic64_add_ret(long, atomic64_t *);
+extern int atomic64_add_ret(int, atomic64_t *);
extern int atomic_sub_ret(int, atomic_t *);
-extern long atomic64_sub_ret(long, 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/backoff.h b/trunk/arch/sparc/include/asm/backoff.h
index db3af0d30fb1..fa1fdf67e350 100644
--- a/trunk/arch/sparc/include/asm/backoff.h
+++ b/trunk/arch/sparc/include/asm/backoff.h
@@ -8,9 +8,6 @@
#define BACKOFF_SETUP(reg) \
mov 1, reg
-#define BACKOFF_LABEL(spin_label, continue_label) \
- spin_label
-
#define BACKOFF_SPIN(reg, tmp, label) \
mov reg, tmp; \
88: brnz,pt tmp, 88b; \
@@ -25,11 +22,9 @@
#else
#define BACKOFF_SETUP(reg)
-
-#define BACKOFF_LABEL(spin_label, continue_label) \
- continue_label
-
-#define BACKOFF_SPIN(reg, tmp, label)
+#define BACKOFF_SPIN(reg, tmp, label) \
+ ba,pt %xcc, label; \
+ nop;
#endif
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/oplib_64.h b/trunk/arch/sparc/include/asm/oplib_64.h
index 3e0b2d62303d..a5db0317b5fb 100644
--- a/trunk/arch/sparc/include/asm/oplib_64.h
+++ b/trunk/arch/sparc/include/asm/oplib_64.h
@@ -185,8 +185,9 @@ extern int prom_getunumber(int syndrome_code,
char *buf, int buflen);
/* Retain physical memory to the caller across soft resets. */
-extern int prom_retain(const char *name, unsigned long size,
- unsigned long align, unsigned long *paddr);
+extern unsigned long prom_retain(const char *name,
+ unsigned long pa_low, unsigned long pa_high,
+ long size, long align);
/* Load explicit I/D TLB entries into the calling processor. */
extern long prom_itlb_load(unsigned long index,
@@ -286,6 +287,26 @@ extern void prom_sun4v_guest_soft_state(void);
extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
/* Client interface level routines. */
-extern void p1275_cmd_direct(unsigned long *);
+extern long p1275_cmd(const char *, long, ...);
+
+#if 0
+#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
+#else
+#define P1275_SIZE(x) x
+#endif
+
+/* We support at most 16 input and 1 output argument */
+#define P1275_ARG_NUMBER 0
+#define P1275_ARG_IN_STRING 1
+#define P1275_ARG_OUT_BUF 2
+#define P1275_ARG_OUT_32B 3
+#define P1275_ARG_IN_FUNCTION 4
+#define P1275_ARG_IN_BUF 5
+#define P1275_ARG_IN_64B 6
+
+#define P1275_IN(x) ((x) & 0xf)
+#define P1275_OUT(x) (((x) << 4) & 0xf0)
+#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
+#define P1275_ARG(n,x) ((x) << ((n)*3 + 8))
#endif /* !(__SPARC64_OPLIB_H) */
diff --git a/trunk/arch/sparc/include/asm/rwsem-const.h b/trunk/arch/sparc/include/asm/rwsem-const.h
new file mode 100644
index 000000000000..a303c9d64d84
--- /dev/null
+++ b/trunk/arch/sparc/include/asm/rwsem-const.h
@@ -0,0 +1,12 @@
+/* rwsem-const.h: RW semaphore counter constants. */
+#ifndef _SPARC64_RWSEM_CONST_H
+#define _SPARC64_RWSEM_CONST_H
+
+#define RWSEM_UNLOCKED_VALUE 0x00000000
+#define RWSEM_ACTIVE_BIAS 0x00000001
+#define RWSEM_ACTIVE_MASK 0x0000ffff
+#define RWSEM_WAITING_BIAS 0xffff0000
+#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+
+#endif /* _SPARC64_RWSEM_CONST_H */
diff --git a/trunk/arch/sparc/include/asm/rwsem.h b/trunk/arch/sparc/include/asm/rwsem.h
index a2b4302869bc..6e5621006f85 100644
--- a/trunk/arch/sparc/include/asm/rwsem.h
+++ b/trunk/arch/sparc/include/asm/rwsem.h
@@ -15,21 +15,16 @@
#include
#include
+#include
struct rwsem_waiter;
struct rw_semaphore {
- signed long count;
-#define RWSEM_UNLOCKED_VALUE 0x00000000L
-#define RWSEM_ACTIVE_BIAS 0x00000001L
-#define RWSEM_ACTIVE_MASK 0xffffffffL
-#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1)
-#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
-#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
- spinlock_t wait_lock;
- struct list_head wait_list;
+ signed int count;
+ spinlock_t wait_lock;
+ struct list_head wait_list;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
- struct lockdep_map dep_map;
+ struct lockdep_map dep_map;
#endif
};
@@ -46,11 +41,6 @@ struct rw_semaphore {
#define DECLARE_RWSEM(name) \
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
-extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
-
extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
struct lock_class_key *key);
@@ -61,103 +51,27 @@ do { \
__init_rwsem((sem), #sem, &__key); \
} while (0)
-/*
- * lock for reading
- */
-static inline void __down_read(struct rw_semaphore *sem)
-{
- if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L))
- rwsem_down_read_failed(sem);
-}
-
-static inline int __down_read_trylock(struct rw_semaphore *sem)
-{
- long tmp;
-
- while ((tmp = sem->count) >= 0L) {
- if (tmp == cmpxchg(&sem->count, tmp,
- tmp + RWSEM_ACTIVE_READ_BIAS)) {
- return 1;
- }
- }
- return 0;
-}
+extern void __down_read(struct rw_semaphore *sem);
+extern int __down_read_trylock(struct rw_semaphore *sem);
+extern void __down_write(struct rw_semaphore *sem);
+extern int __down_write_trylock(struct rw_semaphore *sem);
+extern void __up_read(struct rw_semaphore *sem);
+extern void __up_write(struct rw_semaphore *sem);
+extern void __downgrade_write(struct rw_semaphore *sem);
-/*
- * lock for writing
- */
static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
- long tmp;
-
- tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS,
- (atomic64_t *)(&sem->count));
- if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
- rwsem_down_write_failed(sem);
+ __down_write(sem);
}
-static inline void __down_write(struct rw_semaphore *sem)
+static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
{
- __down_write_nested(sem, 0);
-}
-
-static inline int __down_write_trylock(struct rw_semaphore *sem)
-{
- long tmp;
-
- tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
- RWSEM_ACTIVE_WRITE_BIAS);
- return tmp == RWSEM_UNLOCKED_VALUE;
+ return atomic_add_return(delta, (atomic_t *)(&sem->count));
}
-/*
- * unlock after reading
- */
-static inline void __up_read(struct rw_semaphore *sem)
-{
- long tmp;
-
- tmp = atomic64_dec_return((atomic64_t *)(&sem->count));
- if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L))
- rwsem_wake(sem);
-}
-
-/*
- * unlock after writing
- */
-static inline void __up_write(struct rw_semaphore *sem)
-{
- if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
- (atomic64_t *)(&sem->count)) < 0L))
- rwsem_wake(sem);
-}
-
-/*
- * implement atomic add functionality
- */
-static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
-{
- atomic64_add(delta, (atomic64_t *)(&sem->count));
-}
-
-/*
- * downgrade write lock to read lock
- */
-static inline void __downgrade_write(struct rw_semaphore *sem)
-{
- long tmp;
-
- tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count));
- if (tmp < 0L)
- rwsem_downgrade_wake(sem);
-}
-
-/*
- * implement exchange and add functionality
- */
-static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
+static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
{
- return atomic64_add_return(delta, (atomic64_t *)(&sem->count));
+ atomic_add(delta, (atomic_t *)(&sem->count));
}
static inline int rwsem_is_locked(struct rw_semaphore *sem)
diff --git a/trunk/arch/sparc/include/asm/system_64.h b/trunk/arch/sparc/include/asm/system_64.h
index e3b65d8cf41b..d24cfe16afc1 100644
--- a/trunk/arch/sparc/include/asm/system_64.h
+++ b/trunk/arch/sparc/include/asm/system_64.h
@@ -106,7 +106,6 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
*/
#define write_pic(__p) \
__asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \
- " nop\n\t" \
".align 64\n" \
"99:wr %0, 0x0, %%pic\n\t" \
"rd %%pic, %%g0" : : "r" (__p))
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/sparc/lib/Makefile b/trunk/arch/sparc/lib/Makefile
index 846d1c4374ea..c4b5e03af115 100644
--- a/trunk/arch/sparc/lib/Makefile
+++ b/trunk/arch/sparc/lib/Makefile
@@ -15,7 +15,7 @@ lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o
lib-$(CONFIG_SPARC32) += copy_user.o locks.o
lib-y += atomic_$(BITS).o
lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
-lib-$(CONFIG_SPARC32) += rwsem_32.o
+lib-y += rwsem_$(BITS).o
lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o
diff --git a/trunk/arch/sparc/lib/atomic_64.S b/trunk/arch/sparc/lib/atomic_64.S
index 59186e0fcf39..0268210ca168 100644
--- a/trunk/arch/sparc/lib/atomic_64.S
+++ b/trunk/arch/sparc/lib/atomic_64.S
@@ -21,7 +21,7 @@ atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
add %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %icc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %icc, 2f
nop
retl
nop
@@ -36,7 +36,7 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %icc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %icc, 2f
nop
retl
nop
@@ -51,10 +51,11 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
add %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %icc, BACKOFF_LABEL(2f, 1b)
- add %g1, %o0, %g1
+ bne,pn %icc, 2f
+ add %g7, %o0, %g7
+ sra %g7, 0, %o0
retl
- sra %g1, 0, %o0
+ nop
2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic_add_ret, .-atomic_add_ret
@@ -66,10 +67,11 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %icc, BACKOFF_LABEL(2f, 1b)
- sub %g1, %o0, %g1
+ bne,pn %icc, 2f
+ sub %g7, %o0, %g7
+ sra %g7, 0, %o0
retl
- sra %g1, 0, %o0
+ nop
2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic_sub_ret, .-atomic_sub_ret
@@ -81,7 +83,7 @@ atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
add %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %xcc, 2f
nop
retl
nop
@@ -96,7 +98,7 @@ atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %xcc, 2f
nop
retl
nop
@@ -111,10 +113,11 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
add %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
- nop
+ bne,pn %xcc, 2f
+ add %g7, %o0, %g7
+ mov %g7, %o0
retl
- add %g1, %o0, %o0
+ nop
2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic64_add_ret, .-atomic64_add_ret
@@ -126,9 +129,10 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
- nop
+ bne,pn %xcc, 2f
+ sub %g7, %o0, %g7
+ mov %g7, %o0
retl
- sub %g1, %o0, %o0
+ nop
2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic64_sub_ret, .-atomic64_sub_ret
diff --git a/trunk/arch/sparc/lib/bitops.S b/trunk/arch/sparc/lib/bitops.S
index 3dc61d5537c0..2b7228cb8c22 100644
--- a/trunk/arch/sparc/lib/bitops.S
+++ b/trunk/arch/sparc/lib/bitops.S
@@ -22,7 +22,7 @@ test_and_set_bit: /* %o0=nr, %o1=addr */
or %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %xcc, 2f
and %g7, %o2, %g2
clr %o0
movrne %g2, 1, %o0
@@ -45,7 +45,7 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */
andn %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %xcc, 2f
and %g7, %o2, %g2
clr %o0
movrne %g2, 1, %o0
@@ -68,7 +68,7 @@ test_and_change_bit: /* %o0=nr, %o1=addr */
xor %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %xcc, 2f
and %g7, %o2, %g2
clr %o0
movrne %g2, 1, %o0
@@ -91,7 +91,7 @@ set_bit: /* %o0=nr, %o1=addr */
or %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %xcc, 2f
nop
retl
nop
@@ -112,7 +112,7 @@ clear_bit: /* %o0=nr, %o1=addr */
andn %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %xcc, 2f
nop
retl
nop
@@ -133,7 +133,7 @@ change_bit: /* %o0=nr, %o1=addr */
xor %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
+ bne,pn %xcc, 2f
nop
retl
nop
diff --git a/trunk/arch/sparc/lib/rwsem_64.S b/trunk/arch/sparc/lib/rwsem_64.S
new file mode 100644
index 000000000000..91a7d29a79d5
--- /dev/null
+++ b/trunk/arch/sparc/lib/rwsem_64.S
@@ -0,0 +1,163 @@
+/* rwsem.S: RW semaphore assembler.
+ *
+ * Written by David S. Miller (davem@redhat.com), 2001.
+ * Derived from asm-i386/rwsem.h
+ */
+
+#include
+
+ .section .sched.text, "ax"
+
+ .globl __down_read
+__down_read:
+1: lduw [%o0], %g1
+ add %g1, 1, %g7
+ cas [%o0], %g1, %g7
+ cmp %g1, %g7
+ bne,pn %icc, 1b
+ add %g7, 1, %g7
+ cmp %g7, 0
+ bl,pn %icc, 3f
+ nop
+2:
+ retl
+ nop
+3:
+ save %sp, -192, %sp
+ call rwsem_down_read_failed
+ mov %i0, %o0
+ ret
+ restore
+ .size __down_read, .-__down_read
+
+ .globl __down_read_trylock
+__down_read_trylock:
+1: lduw [%o0], %g1
+ add %g1, 1, %g7
+ cmp %g7, 0
+ bl,pn %icc, 2f
+ mov 0, %o1
+ cas [%o0], %g1, %g7
+ cmp %g1, %g7
+ bne,pn %icc, 1b
+ mov 1, %o1
+2: retl
+ mov %o1, %o0
+ .size __down_read_trylock, .-__down_read_trylock
+
+ .globl __down_write
+__down_write:
+ sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
+ or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
+1:
+ lduw [%o0], %g3
+ add %g3, %g1, %g7
+ cas [%o0], %g3, %g7
+ cmp %g3, %g7
+ bne,pn %icc, 1b
+ cmp %g7, 0
+ bne,pn %icc, 3f
+ nop
+2: retl
+ nop
+3:
+ save %sp, -192, %sp
+ call rwsem_down_write_failed
+ mov %i0, %o0
+ ret
+ restore
+ .size __down_write, .-__down_write
+
+ .globl __down_write_trylock
+__down_write_trylock:
+ sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
+ or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
+1:
+ lduw [%o0], %g3
+ cmp %g3, 0
+ bne,pn %icc, 2f
+ mov 0, %o1
+ add %g3, %g1, %g7
+ cas [%o0], %g3, %g7
+ cmp %g3, %g7
+ bne,pn %icc, 1b
+ mov 1, %o1
+2: retl
+ mov %o1, %o0
+ .size __down_write_trylock, .-__down_write_trylock
+
+ .globl __up_read
+__up_read:
+1:
+ lduw [%o0], %g1
+ sub %g1, 1, %g7
+ cas [%o0], %g1, %g7
+ cmp %g1, %g7
+ bne,pn %icc, 1b
+ cmp %g7, 0
+ bl,pn %icc, 3f
+ nop
+2: retl
+ nop
+3: sethi %hi(RWSEM_ACTIVE_MASK), %g1
+ sub %g7, 1, %g7
+ or %g1, %lo(RWSEM_ACTIVE_MASK), %g1
+ andcc %g7, %g1, %g0
+ bne,pn %icc, 2b
+ nop
+ save %sp, -192, %sp
+ call rwsem_wake
+ mov %i0, %o0
+ ret
+ restore
+ .size __up_read, .-__up_read
+
+ .globl __up_write
+__up_write:
+ sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
+ or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
+1:
+ lduw [%o0], %g3
+ sub %g3, %g1, %g7
+ cas [%o0], %g3, %g7
+ cmp %g3, %g7
+ bne,pn %icc, 1b
+ sub %g7, %g1, %g7
+ cmp %g7, 0
+ bl,pn %icc, 3f
+ nop
+2:
+ retl
+ nop
+3:
+ save %sp, -192, %sp
+ call rwsem_wake
+ mov %i0, %o0
+ ret
+ restore
+ .size __up_write, .-__up_write
+
+ .globl __downgrade_write
+__downgrade_write:
+ sethi %hi(RWSEM_WAITING_BIAS), %g1
+ or %g1, %lo(RWSEM_WAITING_BIAS), %g1
+1:
+ lduw [%o0], %g3
+ sub %g3, %g1, %g7
+ cas [%o0], %g3, %g7
+ cmp %g3, %g7
+ bne,pn %icc, 1b
+ sub %g7, %g1, %g7
+ cmp %g7, 0
+ bl,pn %icc, 3f
+ nop
+2:
+ retl
+ nop
+3:
+ save %sp, -192, %sp
+ call rwsem_downgrade_wake
+ mov %i0, %o0
+ ret
+ restore
+ .size __downgrade_write, .-__downgrade_write
diff --git a/trunk/arch/sparc/prom/cif.S b/trunk/arch/sparc/prom/cif.S
index 9c86b4b7d429..5f27ad779c0c 100644
--- a/trunk/arch/sparc/prom/cif.S
+++ b/trunk/arch/sparc/prom/cif.S
@@ -9,18 +9,18 @@
#include
.text
- .globl prom_cif_direct
-prom_cif_direct:
- sethi %hi(p1275buf), %o1
- or %o1, %lo(p1275buf), %o1
- ldx [%o1 + 0x0010], %o2 ! prom_cif_stack
- save %o2, -192, %sp
- ldx [%i1 + 0x0008], %l2 ! prom_cif_handler
+ .globl prom_cif_interface
+prom_cif_interface:
+ sethi %hi(p1275buf), %o0
+ or %o0, %lo(p1275buf), %o0
+ ldx [%o0 + 0x010], %o1 ! prom_cif_stack
+ save %o1, -192, %sp
+ ldx [%i0 + 0x008], %l2 ! prom_cif_handler
mov %g4, %l0
mov %g5, %l1
mov %g6, %l3
call %l2
- mov %i0, %o0 ! prom_args
+ add %i0, 0x018, %o0 ! prom_args
mov %l0, %g4
mov %l1, %g5
mov %l3, %g6
diff --git a/trunk/arch/sparc/prom/console_64.c b/trunk/arch/sparc/prom/console_64.c
index 10322dc2f557..f55d58a8a156 100644
--- a/trunk/arch/sparc/prom/console_64.c
+++ b/trunk/arch/sparc/prom/console_64.c
@@ -21,22 +21,14 @@ extern int prom_stdin, prom_stdout;
inline int
prom_nbgetchar(void)
{
- unsigned long args[7];
char inc;
- args[0] = (unsigned long) "read";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) prom_stdin;
- args[4] = (unsigned long) &inc;
- args[5] = 1;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- if (args[6] == 1)
+ if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)|
+ P1275_INOUT(3,1),
+ prom_stdin, &inc, P1275_SIZE(1)) == 1)
return inc;
- return -1;
+ else
+ return -1;
}
/* Non blocking put character to console device, returns -1 if
@@ -45,22 +37,12 @@ prom_nbgetchar(void)
inline int
prom_nbputchar(char c)
{
- unsigned long args[7];
char outc;
outc = c;
-
- args[0] = (unsigned long) "write";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) prom_stdout;
- args[4] = (unsigned long) &outc;
- args[5] = 1;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- if (args[6] == 1)
+ if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
+ P1275_INOUT(3,1),
+ prom_stdout, &outc, P1275_SIZE(1)) == 1)
return 0;
else
return -1;
@@ -85,15 +67,7 @@ prom_putchar(char c)
void
prom_puts(const char *s, int len)
{
- unsigned long args[7];
-
- args[0] = (unsigned long) "write";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) prom_stdout;
- args[4] = (unsigned long) s;
- args[5] = len;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
+ p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
+ P1275_INOUT(3,1),
+ prom_stdout, s, P1275_SIZE(len));
}
diff --git a/trunk/arch/sparc/prom/devops_64.c b/trunk/arch/sparc/prom/devops_64.c
index a017119e7ef1..9dbd803e46e1 100644
--- a/trunk/arch/sparc/prom/devops_64.c
+++ b/trunk/arch/sparc/prom/devops_64.c
@@ -18,32 +18,16 @@
int
prom_devopen(const char *dstr)
{
- unsigned long args[5];
-
- args[0] = (unsigned long) "open";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned long) dstr;
- args[4] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[4];
+ return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
+ P1275_INOUT(1,1),
+ dstr);
}
/* Close the device described by device handle 'dhandle'. */
int
prom_devclose(int dhandle)
{
- unsigned long args[4];
-
- args[0] = (unsigned long) "close";
- args[1] = 1;
- args[2] = 0;
- args[3] = (unsigned int) dhandle;
-
- p1275_cmd_direct(args);
-
+ p1275_cmd ("close", P1275_INOUT(1,0), dhandle);
return 0;
}
@@ -53,15 +37,5 @@ prom_devclose(int dhandle)
void
prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
{
- unsigned long args[7];
-
- args[0] = (unsigned long) "seek";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) dhandle;
- args[4] = seekhi;
- args[5] = seeklo;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
+ p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo);
}
diff --git a/trunk/arch/sparc/prom/misc_64.c b/trunk/arch/sparc/prom/misc_64.c
index 6cb1581d6aef..39fc6af21b7c 100644
--- a/trunk/arch/sparc/prom/misc_64.c
+++ b/trunk/arch/sparc/prom/misc_64.c
@@ -20,17 +20,10 @@
int prom_service_exists(const char *service_name)
{
- unsigned long args[5];
+ int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) |
+ P1275_INOUT(1, 1), service_name);
- args[0] = (unsigned long) "test";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned long) service_name;
- args[4] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- if (args[4])
+ if (err)
return 0;
return 1;
}
@@ -38,47 +31,30 @@ int prom_service_exists(const char *service_name)
void prom_sun4v_guest_soft_state(void)
{
const char *svc = "SUNW,soft-state-supported";
- unsigned long args[3];
if (!prom_service_exists(svc))
return;
- args[0] = (unsigned long) svc;
- args[1] = 0;
- args[2] = 0;
- p1275_cmd_direct(args);
+ p1275_cmd(svc, P1275_INOUT(0, 0));
}
/* Reset and reboot the machine with the command 'bcommand'. */
void prom_reboot(const char *bcommand)
{
- unsigned long args[4];
-
#ifdef CONFIG_SUN_LDOMS
if (ldom_domaining_enabled)
ldom_reboot(bcommand);
#endif
- args[0] = (unsigned long) "boot";
- args[1] = 1;
- args[2] = 0;
- args[3] = (unsigned long) bcommand;
-
- p1275_cmd_direct(args);
+ p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) |
+ P1275_INOUT(1, 0), bcommand);
}
/* Forth evaluate the expression contained in 'fstring'. */
void prom_feval(const char *fstring)
{
- unsigned long args[5];
-
if (!fstring || fstring[0] == 0)
return;
- args[0] = (unsigned long) "interpret";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned long) fstring;
- args[4] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
+ p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) |
+ P1275_INOUT(1, 1), fstring);
}
EXPORT_SYMBOL(prom_feval);
@@ -92,7 +68,6 @@ extern void smp_release(void);
*/
void prom_cmdline(void)
{
- unsigned long args[3];
unsigned long flags;
local_irq_save(flags);
@@ -101,11 +76,7 @@ void prom_cmdline(void)
smp_capture();
#endif
- args[0] = (unsigned long) "enter";
- args[1] = 0;
- args[2] = 0;
-
- p1275_cmd_direct(args);
+ p1275_cmd("enter", P1275_INOUT(0, 0));
#ifdef CONFIG_SMP
smp_release();
@@ -119,32 +90,22 @@ void prom_cmdline(void)
*/
void notrace prom_halt(void)
{
- unsigned long args[3];
-
#ifdef CONFIG_SUN_LDOMS
if (ldom_domaining_enabled)
ldom_power_off();
#endif
again:
- args[0] = (unsigned long) "exit";
- args[1] = 0;
- args[2] = 0;
- p1275_cmd_direct(args);
+ p1275_cmd("exit", P1275_INOUT(0, 0));
goto again; /* PROM is out to get me -DaveM */
}
void prom_halt_power_off(void)
{
- unsigned long args[3];
-
#ifdef CONFIG_SUN_LDOMS
if (ldom_domaining_enabled)
ldom_power_off();
#endif
- args[0] = (unsigned long) "SUNW,power-off";
- args[1] = 0;
- args[2] = 0;
- p1275_cmd_direct(args);
+ p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0));
/* if nothing else helps, we just halt */
prom_halt();
@@ -153,15 +114,10 @@ void prom_halt_power_off(void)
/* Set prom sync handler to call function 'funcp'. */
void prom_setcallback(callback_func_t funcp)
{
- unsigned long args[5];
if (!funcp)
return;
- args[0] = (unsigned long) "set-callback";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned long) funcp;
- args[4] = (unsigned long) -1;
- p1275_cmd_direct(args);
+ p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) |
+ P1275_INOUT(1, 1), funcp);
}
/* Get the idprom and stuff it into buffer 'idbuf'. Returns the
@@ -217,61 +173,57 @@ static int prom_get_memory_ihandle(void)
}
/* Load explicit I/D TLB entries. */
-static long tlb_load(const char *type, unsigned long index,
- unsigned long tte_data, unsigned long vaddr)
-{
- unsigned long args[9];
-
- args[0] = (unsigned long) prom_callmethod_name;
- args[1] = 5;
- args[2] = 1;
- args[3] = (unsigned long) type;
- args[4] = (unsigned int) prom_get_mmu_ihandle();
- args[5] = vaddr;
- args[6] = tte_data;
- args[7] = index;
- args[8] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (long) args[8];
-}
-
long prom_itlb_load(unsigned long index,
unsigned long tte_data,
unsigned long vaddr)
{
- return tlb_load("SUNW,itlb-load", index, tte_data, vaddr);
+ return p1275_cmd(prom_callmethod_name,
+ (P1275_ARG(0, P1275_ARG_IN_STRING) |
+ P1275_ARG(2, P1275_ARG_IN_64B) |
+ P1275_ARG(3, P1275_ARG_IN_64B) |
+ P1275_INOUT(5, 1)),
+ "SUNW,itlb-load",
+ prom_get_mmu_ihandle(),
+ /* And then our actual args are pushed backwards. */
+ vaddr,
+ tte_data,
+ index);
}
long prom_dtlb_load(unsigned long index,
unsigned long tte_data,
unsigned long vaddr)
{
- return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr);
+ return p1275_cmd(prom_callmethod_name,
+ (P1275_ARG(0, P1275_ARG_IN_STRING) |
+ P1275_ARG(2, P1275_ARG_IN_64B) |
+ P1275_ARG(3, P1275_ARG_IN_64B) |
+ P1275_INOUT(5, 1)),
+ "SUNW,dtlb-load",
+ prom_get_mmu_ihandle(),
+ /* And then our actual args are pushed backwards. */
+ vaddr,
+ tte_data,
+ index);
}
int prom_map(int mode, unsigned long size,
unsigned long vaddr, unsigned long paddr)
{
- unsigned long args[11];
- int ret;
-
- args[0] = (unsigned long) prom_callmethod_name;
- args[1] = 7;
- args[2] = 1;
- args[3] = (unsigned long) prom_map_name;
- args[4] = (unsigned int) prom_get_mmu_ihandle();
- args[5] = (unsigned int) mode;
- args[6] = size;
- args[7] = vaddr;
- args[8] = 0;
- args[9] = paddr;
- args[10] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- ret = (int) args[10];
+ int ret = p1275_cmd(prom_callmethod_name,
+ (P1275_ARG(0, P1275_ARG_IN_STRING) |
+ P1275_ARG(3, P1275_ARG_IN_64B) |
+ P1275_ARG(4, P1275_ARG_IN_64B) |
+ P1275_ARG(6, P1275_ARG_IN_64B) |
+ P1275_INOUT(7, 1)),
+ prom_map_name,
+ prom_get_mmu_ihandle(),
+ mode,
+ size,
+ vaddr,
+ 0,
+ paddr);
+
if (ret == 0)
ret = -1;
return ret;
@@ -279,51 +231,40 @@ int prom_map(int mode, unsigned long size,
void prom_unmap(unsigned long size, unsigned long vaddr)
{
- unsigned long args[7];
-
- args[0] = (unsigned long) prom_callmethod_name;
- args[1] = 4;
- args[2] = 0;
- args[3] = (unsigned long) prom_unmap_name;
- args[4] = (unsigned int) prom_get_mmu_ihandle();
- args[5] = size;
- args[6] = vaddr;
-
- p1275_cmd_direct(args);
+ p1275_cmd(prom_callmethod_name,
+ (P1275_ARG(0, P1275_ARG_IN_STRING) |
+ P1275_ARG(2, P1275_ARG_IN_64B) |
+ P1275_ARG(3, P1275_ARG_IN_64B) |
+ P1275_INOUT(4, 0)),
+ prom_unmap_name,
+ prom_get_mmu_ihandle(),
+ size,
+ vaddr);
}
/* Set aside physical memory which is not touched or modified
* across soft resets.
*/
-int prom_retain(const char *name, unsigned long size,
- unsigned long align, unsigned long *paddr)
+unsigned long prom_retain(const char *name,
+ unsigned long pa_low, unsigned long pa_high,
+ long size, long align)
{
- unsigned long args[11];
-
- args[0] = (unsigned long) prom_callmethod_name;
- args[1] = 5;
- args[2] = 3;
- args[3] = (unsigned long) "SUNW,retain";
- args[4] = (unsigned int) prom_get_memory_ihandle();
- args[5] = align;
- args[6] = size;
- args[7] = (unsigned long) name;
- args[8] = (unsigned long) -1;
- args[9] = (unsigned long) -1;
- args[10] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- if (args[8])
- return (int) args[8];
-
- /* Next we get "phys_high" then "phys_low". On 64-bit
- * the phys_high cell is don't care since the phys_low
- * cell has the full value.
+ /* XXX I don't think we return multiple values correctly.
+ * XXX OBP supposedly returns pa_low/pa_high here, how does
+ * XXX it work?
*/
- *paddr = args[10];
- return 0;
+ /* If align is zero, the pa_low/pa_high args are passed,
+ * else they are not.
+ */
+ if (align == 0)
+ return p1275_cmd("SUNW,retain",
+ (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)),
+ name, pa_low, pa_high, size, align);
+ else
+ return p1275_cmd("SUNW,retain",
+ (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)),
+ name, size, align);
}
/* Get "Unumber" string for the SIMM at the given
@@ -336,129 +277,62 @@ int prom_getunumber(int syndrome_code,
unsigned long phys_addr,
char *buf, int buflen)
{
- unsigned long args[12];
-
- args[0] = (unsigned long) prom_callmethod_name;
- args[1] = 7;
- args[2] = 2;
- args[3] = (unsigned long) "SUNW,get-unumber";
- args[4] = (unsigned int) prom_get_memory_ihandle();
- args[5] = buflen;
- args[6] = (unsigned long) buf;
- args[7] = 0;
- args[8] = phys_addr;
- args[9] = (unsigned int) syndrome_code;
- args[10] = (unsigned long) -1;
- args[11] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[10];
+ return p1275_cmd(prom_callmethod_name,
+ (P1275_ARG(0, P1275_ARG_IN_STRING) |
+ P1275_ARG(3, P1275_ARG_OUT_BUF) |
+ P1275_ARG(6, P1275_ARG_IN_64B) |
+ P1275_INOUT(8, 2)),
+ "SUNW,get-unumber", prom_get_memory_ihandle(),
+ buflen, buf, P1275_SIZE(buflen),
+ 0, phys_addr, syndrome_code);
}
/* Power management extensions. */
void prom_sleepself(void)
{
- unsigned long args[3];
-
- args[0] = (unsigned long) "SUNW,sleep-self";
- args[1] = 0;
- args[2] = 0;
- p1275_cmd_direct(args);
+ p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0));
}
int prom_sleepsystem(void)
{
- unsigned long args[4];
-
- args[0] = (unsigned long) "SUNW,sleep-system";
- args[1] = 0;
- args[2] = 1;
- args[3] = (unsigned long) -1;
- p1275_cmd_direct(args);
-
- return (int) args[3];
+ return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1));
}
int prom_wakeupsystem(void)
{
- unsigned long args[4];
-
- args[0] = (unsigned long) "SUNW,wakeup-system";
- args[1] = 0;
- args[2] = 1;
- args[3] = (unsigned long) -1;
- p1275_cmd_direct(args);
-
- return (int) args[3];
+ return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1));
}
#ifdef CONFIG_SMP
void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg)
{
- unsigned long args[6];
-
- args[0] = (unsigned long) "SUNW,start-cpu";
- args[1] = 3;
- args[2] = 0;
- args[3] = (unsigned int) cpunode;
- args[4] = pc;
- args[5] = arg;
- p1275_cmd_direct(args);
+ p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg);
}
void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg)
{
- unsigned long args[6];
-
- args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid";
- args[1] = 3;
- args[2] = 0;
- args[3] = (unsigned int) cpuid;
- args[4] = pc;
- args[5] = arg;
- p1275_cmd_direct(args);
+ p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0),
+ cpuid, pc, arg);
}
void prom_stopcpu_cpuid(int cpuid)
{
- unsigned long args[4];
-
- args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid";
- args[1] = 1;
- args[2] = 0;
- args[3] = (unsigned int) cpuid;
- p1275_cmd_direct(args);
+ p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0),
+ cpuid);
}
void prom_stopself(void)
{
- unsigned long args[3];
-
- args[0] = (unsigned long) "SUNW,stop-self";
- args[1] = 0;
- args[2] = 0;
- p1275_cmd_direct(args);
+ p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0));
}
void prom_idleself(void)
{
- unsigned long args[3];
-
- args[0] = (unsigned long) "SUNW,idle-self";
- args[1] = 0;
- args[2] = 0;
- p1275_cmd_direct(args);
+ p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0));
}
void prom_resumecpu(int cpunode)
{
- unsigned long args[4];
-
- args[0] = (unsigned long) "SUNW,resume-cpu";
- args[1] = 1;
- args[2] = 0;
- args[3] = (unsigned int) cpunode;
- p1275_cmd_direct(args);
+ p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode);
}
#endif
diff --git a/trunk/arch/sparc/prom/p1275.c b/trunk/arch/sparc/prom/p1275.c
index fa6e4e219b9c..2d8b70d397f1 100644
--- a/trunk/arch/sparc/prom/p1275.c
+++ b/trunk/arch/sparc/prom/p1275.c
@@ -22,11 +22,13 @@ struct {
long prom_callback; /* 0x00 */
void (*prom_cif_handler)(long *); /* 0x08 */
unsigned long prom_cif_stack; /* 0x10 */
+ unsigned long prom_args [23]; /* 0x18 */
+ char prom_buffer [3000];
} p1275buf;
extern void prom_world(int);
-extern void prom_cif_direct(unsigned long *args);
+extern void prom_cif_interface(void);
extern void prom_cif_callback(void);
/*
@@ -34,20 +36,114 @@ extern void prom_cif_callback(void);
*/
DEFINE_RAW_SPINLOCK(prom_entry_lock);
-void p1275_cmd_direct(unsigned long *args)
+long p1275_cmd(const char *service, long fmt, ...)
{
+ char *p, *q;
unsigned long flags;
+ int nargs, nrets, i;
+ va_list list;
+ long attrs, x;
+
+ p = p1275buf.prom_buffer;
raw_local_save_flags(flags);
raw_local_irq_restore(PIL_NMI);
raw_spin_lock(&prom_entry_lock);
+ p1275buf.prom_args[0] = (unsigned long)p; /* service */
+ strcpy (p, service);
+ p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
+ p1275buf.prom_args[1] = nargs = (fmt & 0x0f); /* nargs */
+ p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4); /* nrets */
+ attrs = fmt >> 8;
+ va_start(list, fmt);
+ for (i = 0; i < nargs; i++, attrs >>= 3) {
+ switch (attrs & 0x7) {
+ case P1275_ARG_NUMBER:
+ p1275buf.prom_args[i + 3] =
+ (unsigned)va_arg(list, long);
+ break;
+ case P1275_ARG_IN_64B:
+ p1275buf.prom_args[i + 3] =
+ va_arg(list, unsigned long);
+ break;
+ case P1275_ARG_IN_STRING:
+ strcpy (p, va_arg(list, char *));
+ p1275buf.prom_args[i + 3] = (unsigned long)p;
+ p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
+ break;
+ case P1275_ARG_OUT_BUF:
+ (void) va_arg(list, char *);
+ p1275buf.prom_args[i + 3] = (unsigned long)p;
+ x = va_arg(list, long);
+ i++; attrs >>= 3;
+ p = (char *)(((long)(p + (int)x + 7)) & ~7);
+ p1275buf.prom_args[i + 3] = x;
+ break;
+ case P1275_ARG_IN_BUF:
+ q = va_arg(list, char *);
+ p1275buf.prom_args[i + 3] = (unsigned long)p;
+ x = va_arg(list, long);
+ i++; attrs >>= 3;
+ memcpy (p, q, (int)x);
+ p = (char *)(((long)(p + (int)x + 7)) & ~7);
+ p1275buf.prom_args[i + 3] = x;
+ break;
+ case P1275_ARG_OUT_32B:
+ (void) va_arg(list, char *);
+ p1275buf.prom_args[i + 3] = (unsigned long)p;
+ p += 32;
+ break;
+ case P1275_ARG_IN_FUNCTION:
+ p1275buf.prom_args[i + 3] =
+ (unsigned long)prom_cif_callback;
+ p1275buf.prom_callback = va_arg(list, long);
+ break;
+ }
+ }
+ va_end(list);
+
prom_world(1);
- prom_cif_direct(args);
+ prom_cif_interface();
prom_world(0);
+ attrs = fmt >> 8;
+ va_start(list, fmt);
+ for (i = 0; i < nargs; i++, attrs >>= 3) {
+ switch (attrs & 0x7) {
+ case P1275_ARG_NUMBER:
+ (void) va_arg(list, long);
+ break;
+ case P1275_ARG_IN_STRING:
+ (void) va_arg(list, char *);
+ break;
+ case P1275_ARG_IN_FUNCTION:
+ (void) va_arg(list, long);
+ break;
+ case P1275_ARG_IN_BUF:
+ (void) va_arg(list, char *);
+ (void) va_arg(list, long);
+ i++; attrs >>= 3;
+ break;
+ case P1275_ARG_OUT_BUF:
+ p = va_arg(list, char *);
+ x = va_arg(list, long);
+ memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x);
+ i++; attrs >>= 3;
+ break;
+ case P1275_ARG_OUT_32B:
+ p = va_arg(list, char *);
+ memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32);
+ break;
+ }
+ }
+ va_end(list);
+ x = p1275buf.prom_args [nargs + 3];
+
raw_spin_unlock(&prom_entry_lock);
raw_local_irq_restore(flags);
+
+ return x;
}
void prom_cif_init(void *cif_handler, void *cif_stack)
diff --git a/trunk/arch/sparc/prom/tree_64.c b/trunk/arch/sparc/prom/tree_64.c
index 9d3f9137a43a..3c0d2dd9f693 100644
--- a/trunk/arch/sparc/prom/tree_64.c
+++ b/trunk/arch/sparc/prom/tree_64.c
@@ -16,39 +16,22 @@
#include
#include
-static int prom_node_to_node(const char *type, int node)
-{
- unsigned long args[5];
-
- args[0] = (unsigned long) type;
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned int) node;
- args[4] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[4];
-}
-
/* Return the child of node 'node' or zero if no this node has no
* direct descendent.
*/
inline int __prom_getchild(int node)
{
- return prom_node_to_node("child", node);
+ return p1275_cmd ("child", P1275_INOUT(1, 1), node);
}
inline int prom_getchild(int node)
{
int cnode;
- if (node == -1)
- return 0;
+ if(node == -1) return 0;
cnode = __prom_getchild(node);
- if (cnode == -1)
- return 0;
- return cnode;
+ if(cnode == -1) return 0;
+ return (int)cnode;
}
EXPORT_SYMBOL(prom_getchild);
@@ -56,12 +39,10 @@ inline int prom_getparent(int node)
{
int cnode;
- if (node == -1)
- return 0;
- cnode = prom_node_to_node("parent", node);
- if (cnode == -1)
- return 0;
- return cnode;
+ if(node == -1) return 0;
+ cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node);
+ if(cnode == -1) return 0;
+ return (int)cnode;
}
/* Return the next sibling of node 'node' or zero if no more siblings
@@ -69,7 +50,7 @@ inline int prom_getparent(int node)
*/
inline int __prom_getsibling(int node)
{
- return prom_node_to_node(prom_peer_name, node);
+ return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node);
}
inline int prom_getsibling(int node)
@@ -91,21 +72,11 @@ EXPORT_SYMBOL(prom_getsibling);
*/
inline int prom_getproplen(int node, const char *prop)
{
- unsigned long args[6];
-
- if (!node || !prop)
- return -1;
-
- args[0] = (unsigned long) "getproplen";
- args[1] = 2;
- args[2] = 1;
- args[3] = (unsigned int) node;
- args[4] = (unsigned long) prop;
- args[5] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[5];
+ if((!node) || (!prop)) return -1;
+ return p1275_cmd ("getproplen",
+ P1275_ARG(1,P1275_ARG_IN_STRING)|
+ P1275_INOUT(2, 1),
+ node, prop);
}
EXPORT_SYMBOL(prom_getproplen);
@@ -116,25 +87,19 @@ EXPORT_SYMBOL(prom_getproplen);
inline int prom_getproperty(int node, const char *prop,
char *buffer, int bufsize)
{
- unsigned long args[8];
int plen;
plen = prom_getproplen(node, prop);
- if ((plen > bufsize) || (plen == 0) || (plen == -1))
+ if ((plen > bufsize) || (plen == 0) || (plen == -1)) {
return -1;
-
- args[0] = (unsigned long) prom_getprop_name;
- args[1] = 4;
- args[2] = 1;
- args[3] = (unsigned int) node;
- args[4] = (unsigned long) prop;
- args[5] = (unsigned long) buffer;
- args[6] = bufsize;
- args[7] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[7];
+ } else {
+ /* Ok, things seem all right. */
+ return p1275_cmd(prom_getprop_name,
+ P1275_ARG(1,P1275_ARG_IN_STRING)|
+ P1275_ARG(2,P1275_ARG_OUT_BUF)|
+ P1275_INOUT(4, 1),
+ node, prop, buffer, P1275_SIZE(plen));
+ }
}
EXPORT_SYMBOL(prom_getproperty);
@@ -145,7 +110,7 @@ inline int prom_getint(int node, const char *prop)
{
int intprop;
- if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
+ if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
return intprop;
return -1;
@@ -161,8 +126,7 @@ int prom_getintdefault(int node, const char *property, int deflt)
int retval;
retval = prom_getint(node, property);
- if (retval == -1)
- return deflt;
+ if(retval == -1) return deflt;
return retval;
}
@@ -174,8 +138,7 @@ int prom_getbool(int node, const char *prop)
int retval;
retval = prom_getproplen(node, prop);
- if (retval == -1)
- return 0;
+ if(retval == -1) return 0;
return 1;
}
EXPORT_SYMBOL(prom_getbool);
@@ -189,8 +152,7 @@ void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
int len;
len = prom_getproperty(node, prop, user_buf, ubuf_size);
- if (len != -1)
- return;
+ if(len != -1) return;
user_buf[0] = 0;
}
EXPORT_SYMBOL(prom_getstring);
@@ -202,8 +164,7 @@ int prom_nodematch(int node, const char *name)
{
char namebuf[128];
prom_getproperty(node, "name", namebuf, sizeof(namebuf));
- if (strcmp(namebuf, name) == 0)
- return 1;
+ if(strcmp(namebuf, name) == 0) return 1;
return 0;
}
@@ -229,29 +190,16 @@ int prom_searchsiblings(int node_start, const char *nodename)
}
EXPORT_SYMBOL(prom_searchsiblings);
-static const char *prom_nextprop_name = "nextprop";
-
/* Return the first property type for node 'node'.
* buffer should be at least 32B in length
*/
inline char *prom_firstprop(int node, char *buffer)
{
- unsigned long args[7];
-
*buffer = 0;
- if (node == -1)
- return buffer;
-
- args[0] = (unsigned long) prom_nextprop_name;
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) node;
- args[4] = 0;
- args[5] = (unsigned long) buffer;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
+ if(node == -1) return buffer;
+ p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)|
+ P1275_INOUT(3, 0),
+ node, (char *) 0x0, buffer);
return buffer;
}
EXPORT_SYMBOL(prom_firstprop);
@@ -262,10 +210,9 @@ EXPORT_SYMBOL(prom_firstprop);
*/
inline char *prom_nextprop(int node, const char *oprop, char *buffer)
{
- unsigned long args[7];
char buf[32];
- if (node == -1) {
+ if(node == -1) {
*buffer = 0;
return buffer;
}
@@ -273,17 +220,10 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer)
strcpy (buf, oprop);
oprop = buf;
}
-
- args[0] = (unsigned long) prom_nextprop_name;
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) node;
- args[4] = (unsigned long) oprop;
- args[5] = (unsigned long) buffer;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
+ p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
+ P1275_ARG(2,P1275_ARG_OUT_32B)|
+ P1275_INOUT(3, 0),
+ node, oprop, buffer);
return buffer;
}
EXPORT_SYMBOL(prom_nextprop);
@@ -291,19 +231,12 @@ EXPORT_SYMBOL(prom_nextprop);
int
prom_finddevice(const char *name)
{
- unsigned long args[5];
-
if (!name)
return 0;
- args[0] = (unsigned long) "finddevice";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned long) name;
- args[4] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[4];
+ return p1275_cmd(prom_finddev_name,
+ P1275_ARG(0,P1275_ARG_IN_STRING)|
+ P1275_INOUT(1, 1),
+ name);
}
EXPORT_SYMBOL(prom_finddevice);
@@ -314,7 +247,7 @@ int prom_node_has_property(int node, const char *prop)
*buf = 0;
do {
prom_nextprop(node, buf, buf);
- if (!strcmp(buf, prop))
+ if(!strcmp(buf, prop))
return 1;
} while (*buf);
return 0;
@@ -327,8 +260,6 @@ EXPORT_SYMBOL(prom_node_has_property);
int
prom_setprop(int node, const char *pname, char *value, int size)
{
- unsigned long args[8];
-
if (size == 0)
return 0;
if ((pname == 0) || (value == 0))
@@ -340,37 +271,19 @@ prom_setprop(int node, const char *pname, char *value, int size)
return 0;
}
#endif
- args[0] = (unsigned long) "setprop";
- args[1] = 4;
- args[2] = 1;
- args[3] = (unsigned int) node;
- args[4] = (unsigned long) pname;
- args[5] = (unsigned long) value;
- args[6] = size;
- args[7] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[7];
+ return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
+ P1275_ARG(2,P1275_ARG_IN_BUF)|
+ P1275_INOUT(4, 1),
+ node, pname, value, P1275_SIZE(size));
}
EXPORT_SYMBOL(prom_setprop);
inline int prom_inst2pkg(int inst)
{
- unsigned long args[5];
int node;
- args[0] = (unsigned long) "instance-to-package";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned int) inst;
- args[4] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- node = (int) args[4];
- if (node == -1)
- return 0;
+ node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst);
+ if (node == -1) return 0;
return node;
}
@@ -383,28 +296,17 @@ prom_pathtoinode(const char *path)
int node, inst;
inst = prom_devopen (path);
- if (inst == 0)
- return 0;
- node = prom_inst2pkg(inst);
- prom_devclose(inst);
- if (node == -1)
- return 0;
+ if (inst == 0) return 0;
+ node = prom_inst2pkg (inst);
+ prom_devclose (inst);
+ if (node == -1) return 0;
return node;
}
int prom_ihandle2path(int handle, char *buffer, int bufsize)
{
- unsigned long args[7];
-
- args[0] = (unsigned long) "instance-to-path";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) handle;
- args[4] = (unsigned long) buffer;
- args[5] = bufsize;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[6];
+ return p1275_cmd("instance-to-path",
+ P1275_ARG(1,P1275_ARG_OUT_BUF)|
+ P1275_INOUT(3, 1),
+ handle, buffer, P1275_SIZE(bufsize));
}
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/include/asm/tsc.h b/trunk/arch/x86/include/asm/tsc.h
index 1ca132fc0d03..c0427295e8f5 100644
--- a/trunk/arch/x86/include/asm/tsc.h
+++ b/trunk/arch/x86/include/asm/tsc.h
@@ -59,7 +59,5 @@ extern void check_tsc_sync_source(int cpu);
extern void check_tsc_sync_target(void);
extern int notsc_setup(char *);
-extern void save_sched_clock_state(void);
-extern void restore_sched_clock_state(void);
#endif /* _ASM_X86_TSC_H */
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/kernel/tsc.c b/trunk/arch/x86/kernel/tsc.c
index d632934cb638..ce8e50239332 100644
--- a/trunk/arch/x86/kernel/tsc.c
+++ b/trunk/arch/x86/kernel/tsc.c
@@ -626,44 +626,6 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
local_irq_restore(flags);
}
-static unsigned long long cyc2ns_suspend;
-
-void save_sched_clock_state(void)
-{
- if (!sched_clock_stable)
- return;
-
- cyc2ns_suspend = sched_clock();
-}
-
-/*
- * Even on processors with invariant TSC, TSC gets reset in some the
- * ACPI system sleep states. And in some systems BIOS seem to reinit TSC to
- * arbitrary value (still sync'd across cpu's) during resume from such sleep
- * states. To cope up with this, recompute the cyc2ns_offset for each cpu so
- * that sched_clock() continues from the point where it was left off during
- * suspend.
- */
-void restore_sched_clock_state(void)
-{
- unsigned long long offset;
- unsigned long flags;
- int cpu;
-
- if (!sched_clock_stable)
- return;
-
- local_irq_save(flags);
-
- get_cpu_var(cyc2ns_offset) = 0;
- offset = cyc2ns_suspend - sched_clock();
-
- for_each_possible_cpu(cpu)
- per_cpu(cyc2ns_offset, cpu) = offset;
-
- local_irq_restore(flags);
-}
-
#ifdef CONFIG_CPU_FREQ
/* Frequency scaling support. Adjust the TSC based timer when the cpu frequency
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/x86/power/cpu.c b/trunk/arch/x86/power/cpu.c
index 87bb35e34ef1..e7e8c5f54956 100644
--- a/trunk/arch/x86/power/cpu.c
+++ b/trunk/arch/x86/power/cpu.c
@@ -113,7 +113,6 @@ static void __save_processor_state(struct saved_context *ctxt)
void save_processor_state(void)
{
__save_processor_state(&saved_context);
- save_sched_clock_state();
}
#ifdef CONFIG_X86_32
EXPORT_SYMBOL(save_processor_state);
@@ -230,7 +229,6 @@ static void __restore_processor_state(struct saved_context *ctxt)
void restore_processor_state(void)
{
__restore_processor_state(&saved_context);
- restore_sched_clock_state();
}
#ifdef CONFIG_X86_32
EXPORT_SYMBOL(restore_processor_state);
diff --git a/trunk/arch/x86/xen/platform-pci-unplug.c b/trunk/arch/x86/xen/platform-pci-unplug.c
index 0f456386cce5..554c002a1e1a 100644
--- a/trunk/arch/x86/xen/platform-pci-unplug.c
+++ b/trunk/arch/x86/xen/platform-pci-unplug.c
@@ -72,17 +72,13 @@ void __init xen_unplug_emulated_devices(void)
{
int r;
- /* user explicitly requested no unplug */
- if (xen_emul_unplug & XEN_UNPLUG_NEVER)
- return;
/* check the version of the xen platform PCI device */
r = check_platform_magic();
/* If the version matches enable the Xen platform PCI driver.
- * Also enable the Xen platform PCI driver if the host does
- * not support the unplug protocol (XEN_PLATFORM_ERR_MAGIC)
- * but the user told us that unplugging is unnecessary. */
+ * Also enable the Xen platform PCI driver if the version is really old
+ * and the user told us to ignore it. */
if (r && !(r == XEN_PLATFORM_ERR_MAGIC &&
- (xen_emul_unplug & XEN_UNPLUG_UNNECESSARY)))
+ (xen_emul_unplug & XEN_UNPLUG_IGNORE)))
return;
/* Set the default value of xen_emul_unplug depending on whether or
* not the Xen PV frontends and the Xen platform PCI driver have
@@ -103,7 +99,7 @@ void __init xen_unplug_emulated_devices(void)
}
}
/* Now unplug the emulated devices */
- if (!(xen_emul_unplug & XEN_UNPLUG_UNNECESSARY))
+ if (!(xen_emul_unplug & XEN_UNPLUG_IGNORE))
outw(xen_emul_unplug, XEN_IOPORT_UNPLUG);
xen_platform_pci_unplug = xen_emul_unplug;
}
@@ -129,10 +125,8 @@ static int __init parse_xen_emul_unplug(char *arg)
xen_emul_unplug |= XEN_UNPLUG_AUX_IDE_DISKS;
else if (!strncmp(p, "nics", l))
xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
- else if (!strncmp(p, "unnecessary", l))
- xen_emul_unplug |= XEN_UNPLUG_UNNECESSARY;
- else if (!strncmp(p, "never", l))
- xen_emul_unplug |= XEN_UNPLUG_NEVER;
+ else if (!strncmp(p, "ignore", l))
+ xen_emul_unplug |= XEN_UNPLUG_IGNORE;
else
printk(KERN_WARNING "unrecognised option '%s' "
"in parameter 'xen_emul_unplug'\n", p);
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/base/firmware_class.c b/trunk/drivers/base/firmware_class.c
index 40af43ebd92d..c8a44f5e0584 100644
--- a/trunk/drivers/base/firmware_class.c
+++ b/trunk/drivers/base/firmware_class.c
@@ -568,7 +568,7 @@ static int _request_firmware(const struct firmware **firmware_p,
out:
if (retval) {
release_firmware(firmware);
- *firmware_p = NULL;
+ firmware_p = NULL;
}
return retval;
diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c
index ab735a605cf3..ac1b682edecb 100644
--- a/trunk/drivers/block/xen-blkfront.c
+++ b/trunk/drivers/block/xen-blkfront.c
@@ -834,7 +834,7 @@ static int blkfront_probe(struct xenbus_device *dev,
char *type;
int len;
/* no unplug has been done: do not hook devices != xen vbds */
- if (xen_platform_pci_unplug & XEN_UNPLUG_UNNECESSARY) {
+ if (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE) {
int major;
if (!VDEV_IS_EXTENDED(vdevice))
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/ip2/ip2main.c b/trunk/drivers/char/ip2/ip2main.c
index d4b71e8d0d23..07f3ea38b582 100644
--- a/trunk/drivers/char/ip2/ip2main.c
+++ b/trunk/drivers/char/ip2/ip2main.c
@@ -1650,7 +1650,7 @@ ip2_close( PTTY tty, struct file *pFile )
/* disable DSS reporting */
i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
- if (tty->termios->c_cflag & HUPCL) {
+ if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
@@ -2930,8 +2930,6 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
if ( pCh )
{
rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
- if (rc)
- rc = -EFAULT;
} else {
rc = -ENODEV;
}
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/rocket.c b/trunk/drivers/char/rocket.c
index 7c79d243acc9..79c3bc69165a 100644
--- a/trunk/drivers/char/rocket.c
+++ b/trunk/drivers/char/rocket.c
@@ -1244,7 +1244,6 @@ static int set_config(struct tty_struct *tty, struct r_port *info,
}
info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
configure_r_port(tty, info, NULL);
- mutex_unlock(&info->port.mutex);
return 0;
}
diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c
index e63b830c86cc..fef80cfcab5c 100644
--- a/trunk/drivers/char/synclink_gt.c
+++ b/trunk/drivers/char/synclink_gt.c
@@ -691,10 +691,8 @@ static int open(struct tty_struct *tty, struct file *filp)
if (info->port.count == 1) {
/* 1st open on this device, init hardware */
retval = startup(info);
- if (retval < 0) {
- mutex_unlock(&info->port.mutex);
+ if (retval < 0)
goto cleanup;
- }
}
mutex_unlock(&info->port.mutex);
retval = block_til_ready(tty, filp, info);
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/drm_drv.c b/trunk/drivers/gpu/drm/drm_drv.c
index 84da748555bc..90288ec7c284 100644
--- a/trunk/drivers/gpu/drm/drm_drv.c
+++ b/trunk/drivers/gpu/drm/drm_drv.c
@@ -55,9 +55,6 @@
static int drm_version(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
- [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0}
-
/** Ioctl table */
static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0),
@@ -424,7 +421,6 @@ long drm_ioctl(struct file *filp,
int retcode = -EINVAL;
char stack_kdata[128];
char *kdata = NULL;
- unsigned int usize, asize;
dev = file_priv->minor->dev;
atomic_inc(&dev->ioctl_count);
@@ -440,18 +436,11 @@ long drm_ioctl(struct file *filp,
((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
goto err_i1;
if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
- (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
- u32 drv_size;
+ (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
- drv_size = _IOC_SIZE(ioctl->cmd_drv);
- usize = asize = _IOC_SIZE(cmd);
- if (drv_size > asize)
- asize = drv_size;
- }
else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
ioctl = &drm_ioctls[nr];
cmd = ioctl->cmd;
- usize = asize = _IOC_SIZE(cmd);
} else
goto err_i1;
@@ -471,10 +460,10 @@ long drm_ioctl(struct file *filp,
retcode = -EACCES;
} else {
if (cmd & (IOC_IN | IOC_OUT)) {
- if (asize <= sizeof(stack_kdata)) {
+ if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) {
kdata = stack_kdata;
} else {
- kdata = kmalloc(asize, GFP_KERNEL);
+ kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
if (!kdata) {
retcode = -ENOMEM;
goto err_i1;
@@ -484,13 +473,11 @@ long drm_ioctl(struct file *filp,
if (cmd & IOC_IN) {
if (copy_from_user(kdata, (void __user *)arg,
- usize) != 0) {
+ _IOC_SIZE(cmd)) != 0) {
retcode = -EFAULT;
goto err_i1;
}
- } else
- memset(kdata, 0, usize);
-
+ }
if (ioctl->flags & DRM_UNLOCKED)
retcode = func(dev, kdata, file_priv);
else {
@@ -501,7 +488,7 @@ long drm_ioctl(struct file *filp,
if (cmd & IOC_OUT) {
if (copy_to_user((void __user *)arg, kdata,
- usize) != 0)
+ _IOC_SIZE(cmd)) != 0)
retcode = -EFAULT;
}
}
diff --git a/trunk/drivers/gpu/drm/drm_fb_helper.c b/trunk/drivers/gpu/drm/drm_fb_helper.c
index 8dd7e6f86bb3..de82e201d682 100644
--- a/trunk/drivers/gpu/drm/drm_fb_helper.c
+++ b/trunk/drivers/gpu/drm/drm_fb_helper.c
@@ -94,11 +94,10 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn
int i;
enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
struct drm_fb_helper_cmdline_mode *cmdline_mode;
- struct drm_connector *connector;
+ struct drm_connector *connector = fb_helper_conn->connector;
if (!fb_helper_conn)
return false;
- connector = fb_helper_conn->connector;
cmdline_mode = &fb_helper_conn->cmdline_mode;
if (!mode_option)
diff --git a/trunk/drivers/gpu/drm/drm_vm.c b/trunk/drivers/gpu/drm/drm_vm.c
index fda67468e603..3778360eceea 100644
--- a/trunk/drivers/gpu/drm/drm_vm.c
+++ b/trunk/drivers/gpu/drm/drm_vm.c
@@ -138,7 +138,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
break;
}
- if (&agpmem->head == &dev->agp->memory)
+ if (!agpmem)
goto vm_fault_error;
/*
diff --git a/trunk/drivers/gpu/drm/i810/i810_dma.c b/trunk/drivers/gpu/drm/i810/i810_dma.c
index 61b4caf220fa..0e6c131313d9 100644
--- a/trunk/drivers/gpu/drm/i810/i810_dma.c
+++ b/trunk/drivers/gpu/drm/i810/i810_dma.c
@@ -1255,21 +1255,21 @@ long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
struct drm_ioctl_desc i810_ioctls[] = {
- DRM_IOCTL_DEF_DRV(I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED),
};
int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
diff --git a/trunk/drivers/gpu/drm/i830/i830_dma.c b/trunk/drivers/gpu/drm/i830/i830_dma.c
index 671aa18415ac..5168862c9227 100644
--- a/trunk/drivers/gpu/drm/i830/i830_dma.c
+++ b/trunk/drivers/gpu/drm/i830/i830_dma.c
@@ -1524,20 +1524,20 @@ long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
struct drm_ioctl_desc i830_ioctls[] = {
- DRM_IOCTL_DEF_DRV(I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED),
};
int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
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 a7ec93e62f81..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;
@@ -2367,46 +2360,46 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
}
struct drm_ioctl_desc i915_ioctls[] = {
- DRM_IOCTL_DEF_DRV(I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_FLIP, i915_flip_bufs, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
+ DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
+ DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
+ DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
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 11a3394f5fe1..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),
- 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/gpu/drm/mga/mga_state.c b/trunk/drivers/gpu/drm/mga/mga_state.c
index 9ce2827f8c00..fff82045c427 100644
--- a/trunk/drivers/gpu/drm/mga/mga_state.c
+++ b/trunk/drivers/gpu/drm/mga/mga_state.c
@@ -1085,19 +1085,19 @@ file_priv)
}
struct drm_ioctl_desc mga_ioctls[] = {
- DRM_IOCTL_DEF_DRV(MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(MGA_FLUSH, mga_dma_flush, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_RESET, mga_dma_reset, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_SWAP, mga_dma_swap, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_CLEAR, mga_dma_clear, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_VERTEX, mga_dma_vertex, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_INDICES, mga_dma_indices, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_ILOAD, mga_dma_iload, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_BLIT, mga_dma_blit, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_GETPARAM, mga_getparam, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_SET_FENCE, mga_set_fence, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_MGA_FLUSH, mga_dma_flush, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_RESET, mga_dma_reset, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_SWAP, mga_dma_swap, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_CLEAR, mga_dma_clear, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_VERTEX, mga_dma_vertex, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_INDICES, mga_dma_indices, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_ILOAD, mga_dma_iload, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_BLIT, mga_dma_blit, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_GETPARAM, mga_getparam, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_SET_FENCE, mga_set_fence, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
};
int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls);
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c
index e4f33a4edea1..0b69a9628c95 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -2166,7 +2166,7 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb,
uint32_t val = 0;
if (off < pci_resource_len(dev->pdev, 1)) {
- uint8_t __iomem *p =
+ uint32_t __iomem *p =
io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0);
val = ioread32(p + (off & ~PAGE_MASK));
@@ -2182,7 +2182,7 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb,
uint32_t off, uint32_t val)
{
if (off < pci_resource_len(dev->pdev, 1)) {
- uint8_t __iomem *p =
+ uint32_t __iomem *p =
io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0);
iowrite32(val, p + (off & ~PAGE_MASK));
@@ -4587,7 +4587,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script);
+ NV_TRACE(dev, "0x%04X: parsing output script 0\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
} else
if (pxclk == -1) {
@@ -4597,7 +4597,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script);
+ NV_TRACE(dev, "0x%04X: parsing output script 1\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
} else
if (pxclk == -2) {
@@ -4610,7 +4610,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script);
+ NV_TRACE(dev, "0x%04X: parsing output script 2\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
} else
if (pxclk > 0) {
@@ -4622,7 +4622,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script);
+ NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
} else
if (pxclk < 0) {
@@ -4634,7 +4634,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script);
+ NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
}
@@ -5357,17 +5357,19 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios,
}
tmdstableptr = ROM16(bios->data[bitentry->offset]);
- if (!tmdstableptr) {
+
+ if (tmdstableptr == 0x0) {
NV_ERROR(dev, "Pointer to TMDS table invalid\n");
return -EINVAL;
}
- NV_INFO(dev, "TMDS table version %d.%d\n",
- bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf);
-
/* nv50+ has v2.0, but we don't parse it atm */
- if (bios->data[tmdstableptr] != 0x11)
+ if (bios->data[tmdstableptr] != 0x11) {
+ NV_WARN(dev,
+ "TMDS table revision %d.%d not currently supported\n",
+ bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf);
return -ENOSYS;
+ }
/*
* These two scripts are odd: they don't seem to get run even when
@@ -5807,22 +5809,6 @@ parse_dcb_gpio_table(struct nvbios *bios)
gpio->line = tvdac_gpio[1] >> 4;
gpio->invert = tvdac_gpio[0] & 2;
}
- } else {
- /*
- * No systematic way to store GPIO info on pre-v2.2
- * DCBs, try to match the PCI device IDs.
- */
-
- /* Apple iMac G4 NV18 */
- if (dev->pdev->device == 0x0189 &&
- dev->pdev->subsystem_vendor == 0x10de &&
- dev->pdev->subsystem_device == 0x0010) {
- struct dcb_gpio_entry *gpio = new_gpio_entry(bios);
-
- gpio->tag = DCB_GPIO_TVDAC0;
- gpio->line = 4;
- }
-
}
if (!gpio_table_ptr)
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c
index f6f44779d82f..84f85183d041 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -36,21 +36,6 @@
#include
#include
-int
-nouveau_bo_sync_gpu(struct nouveau_bo *nvbo, struct nouveau_channel *chan)
-{
- struct nouveau_fence *prev_fence = nvbo->bo.sync_obj;
- int ret;
-
- if (!prev_fence || nouveau_fence_channel(prev_fence) == chan)
- return 0;
-
- spin_lock(&nvbo->bo.lock);
- ret = ttm_bo_wait(&nvbo->bo, false, false, false);
- spin_unlock(&nvbo->bo.lock);
- return ret;
-}
-
static void
nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
{
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_channel.c b/trunk/drivers/gpu/drm/nouveau/nouveau_channel.c
index 0480f064f2c1..90fdcda332be 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -426,18 +426,18 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
***********************************/
struct drm_ioctl_desc nouveau_ioctls[] = {
- DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH),
};
int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c
index a1473fff06ac..b1b22baf1428 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -104,7 +104,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
int i;
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
- struct nouveau_i2c_chan *i2c = NULL;
+ struct nouveau_i2c_chan *i2c;
struct nouveau_encoder *nv_encoder;
struct drm_mode_object *obj;
int id;
@@ -117,9 +117,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
if (!obj)
continue;
nv_encoder = nouveau_encoder(obj_to_encoder(obj));
-
- if (nv_encoder->dcb->i2c_index < 0xf)
- i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+ i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) {
*pnv_encoder = nv_encoder;
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h
index 1e093a069b7b..e424bf74d706 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1165,7 +1165,6 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val);
-extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *);
/* nouveau_fence.c */
struct nouveau_fence;
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c
index 79fc5ffff226..0f417ac1b696 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -361,11 +361,16 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
list_for_each_entry(nvbo, list, entry) {
struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
+ struct nouveau_fence *prev_fence = nvbo->bo.sync_obj;
- ret = nouveau_bo_sync_gpu(nvbo, chan);
- if (unlikely(ret)) {
- NV_ERROR(dev, "fail pre-validate sync\n");
- return ret;
+ if (prev_fence && nouveau_fence_channel(prev_fence) != chan) {
+ spin_lock(&nvbo->bo.lock);
+ ret = ttm_bo_wait(&nvbo->bo, false, false, false);
+ spin_unlock(&nvbo->bo.lock);
+ if (unlikely(ret)) {
+ NV_ERROR(dev, "fail wait other chan\n");
+ return ret;
+ }
}
ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains,
@@ -376,7 +381,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
return ret;
}
- nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan;
+ nvbo->channel = chan;
ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement,
false, false, false);
nvbo->channel = NULL;
@@ -385,12 +390,6 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
return ret;
}
- ret = nouveau_bo_sync_gpu(nvbo, chan);
- if (unlikely(ret)) {
- NV_ERROR(dev, "fail post-validate sync\n");
- return ret;
- }
-
if (nvbo->bo.offset == b->presumed.offset &&
((nvbo->bo.mem.mem_type == TTM_PL_VRAM &&
b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) ||
@@ -616,21 +615,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
mutex_lock(&dev->struct_mutex);
- /* Mark push buffers as being used on PFIFO, the validation code
- * will then make sure that if the pushbuf bo moves, that they
- * happen on the kernel channel, which will in turn cause a sync
- * to happen before we try and submit the push buffer.
- */
- for (i = 0; i < req->nr_push; i++) {
- if (push[i].bo_index >= req->nr_buffers) {
- NV_ERROR(dev, "push %d buffer not in list\n", i);
- ret = -EINVAL;
- goto out;
- }
-
- bo[push[i].bo_index].read_domains |= (1 << 31);
- }
-
/* Validate buffer list */
ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers,
req->nr_buffers, &op, &do_reloc);
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c b/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c
index 84614858728b..0bd407ca3d42 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c
@@ -163,7 +163,7 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
if (entry->chan)
return -EEXIST;
- if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) {
+ if (dev_priv->card_type == NV_C0 && entry->read >= NV50_I2C_PORTS) {
NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
return -EINVAL;
}
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/trunk/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index 6b9187d7f67d..491767fe4fcf 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -214,7 +214,6 @@ int
nouveau_sgdma_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct pci_dev *pdev = dev->pdev;
struct nouveau_gpuobj *gpuobj = NULL;
uint32_t aper_size, obj_size;
int i, ret;
@@ -240,19 +239,10 @@ nouveau_sgdma_init(struct drm_device *dev)
dev_priv->gart_info.sg_dummy_page =
alloc_page(GFP_KERNEL|__GFP_DMA32);
- if (!dev_priv->gart_info.sg_dummy_page) {
- nouveau_gpuobj_del(dev, &gpuobj);
- return -ENOMEM;
- }
-
set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags);
dev_priv->gart_info.sg_dummy_bus =
- pci_map_page(pdev, dev_priv->gart_info.sg_dummy_page, 0,
+ pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0,
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(pdev, dev_priv->gart_info.sg_dummy_bus)) {
- nouveau_gpuobj_del(dev, &gpuobj);
- return -EFAULT;
- }
if (dev_priv->card_type < NV_50) {
/* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and
diff --git a/trunk/drivers/gpu/drm/nouveau/nv17_tv.c b/trunk/drivers/gpu/drm/nouveau/nv17_tv.c
index eefa5c856932..44fefb0c7083 100644
--- a/trunk/drivers/gpu/drm/nouveau/nv17_tv.c
+++ b/trunk/drivers/gpu/drm/nouveau/nv17_tv.c
@@ -129,14 +129,6 @@ get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask)
return false;
}
- /* MSI nForce2 IGP */
- if (dev->pdev->device == 0x01f0 &&
- dev->pdev->subsystem_vendor == 0x1462 &&
- dev->pdev->subsystem_device == 0x5710) {
- *pin_mask = 0xc;
- return false;
- }
-
return true;
}
diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_instmem.c b/trunk/drivers/gpu/drm/nouveau/nv50_instmem.c
index c95bf9b681dd..37c7b48ab24a 100644
--- a/trunk/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/trunk/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -278,7 +278,7 @@ nv50_instmem_init(struct drm_device *dev)
/*XXX: incorrect, but needed to make hash func "work" */
dev_priv->ramht_offset = 0x10000;
dev_priv->ramht_bits = 9;
- dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8;
+ dev_priv->ramht_size = (1 << dev_priv->ramht_bits);
return 0;
}
diff --git a/trunk/drivers/gpu/drm/nouveau/nvc0_instmem.c b/trunk/drivers/gpu/drm/nouveau/nvc0_instmem.c
index 6b451f864783..3ab3cdc42173 100644
--- a/trunk/drivers/gpu/drm/nouveau/nvc0_instmem.c
+++ b/trunk/drivers/gpu/drm/nouveau/nvc0_instmem.c
@@ -142,16 +142,14 @@ int
nvc0_instmem_suspend(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 *buf;
int i;
dev_priv->susres.ramin_copy = vmalloc(65536);
if (!dev_priv->susres.ramin_copy)
return -ENOMEM;
- buf = dev_priv->susres.ramin_copy;
- for (i = 0; i < 65536; i += 4)
- buf[i/4] = nv_rd32(dev, NV04_PRAMIN + i);
+ for (i = 0x700000; i < 0x710000; i += 4)
+ dev_priv->susres.ramin_copy[i/4] = nv_rd32(dev, i);
return 0;
}
@@ -159,15 +157,14 @@ void
nvc0_instmem_resume(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 *buf = dev_priv->susres.ramin_copy;
u64 chan;
int i;
chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram;
nv_wr32(dev, 0x001700, chan >> 16);
- for (i = 0; i < 65536; i += 4)
- nv_wr32(dev, NV04_PRAMIN + i, buf[i/4]);
+ for (i = 0x700000; i < 0x710000; i += 4)
+ nv_wr32(dev, i, dev_priv->susres.ramin_copy[i/4]);
vfree(dev_priv->susres.ramin_copy);
dev_priv->susres.ramin_copy = NULL;
@@ -224,7 +221,7 @@ nvc0_instmem_init(struct drm_device *dev)
/*XXX: incorrect, but needed to make hash func "work" */
dev_priv->ramht_offset = 0x10000;
dev_priv->ramht_bits = 9;
- dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8;
+ dev_priv->ramht_size = (1 << dev_priv->ramht_bits);
return 0;
}
diff --git a/trunk/drivers/gpu/drm/r128/r128_state.c b/trunk/drivers/gpu/drm/r128/r128_state.c
index a9e33ce65918..077af1f2f9b4 100644
--- a/trunk/drivers/gpu/drm/r128/r128_state.c
+++ b/trunk/drivers/gpu/drm/r128/r128_state.c
@@ -1639,29 +1639,30 @@ void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
r128_do_cleanup_pageflip(dev);
}
}
+
void r128_driver_lastclose(struct drm_device *dev)
{
r128_do_cleanup_cce(dev);
}
struct drm_ioctl_desc r128_ioctls[] = {
- DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(R128_CCE_IDLE, r128_cce_idle, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_RESET, r128_engine_reset, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_FULLSCREEN, r128_fullscreen, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_SWAP, r128_cce_swap, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_FLIP, r128_cce_flip, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_CLEAR, r128_cce_clear, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_VERTEX, r128_cce_vertex, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_INDICES, r128_cce_indices, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_BLIT, r128_cce_blit, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_DEPTH, r128_cce_depth, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_STIPPLE, r128_cce_stipple, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_R128_CCE_IDLE, r128_cce_idle, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_RESET, r128_engine_reset, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_FULLSCREEN, r128_fullscreen, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_SWAP, r128_cce_swap, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_FLIP, r128_cce_flip, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_CLEAR, r128_cce_clear, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_VERTEX, r128_cce_vertex, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_INDICES, r128_cce_indices, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_BLIT, r128_cce_blit, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_DEPTH, r128_cce_depth, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_STIPPLE, r128_cce_stipple, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_R128_GETPARAM, r128_getparam, DRM_AUTH),
};
int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls);
diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c
index 577239a24fd5..12ad512bd3d3 100644
--- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -471,8 +471,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
struct radeon_encoder *radeon_encoder = NULL;
u32 adjusted_clock = mode->clock;
int encoder_mode = 0;
- u32 dp_clock = mode->clock;
- int bpc = 8;
/* reset the pll flags */
pll->flags = 0;
@@ -515,17 +513,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (encoder->crtc == crtc) {
radeon_encoder = to_radeon_encoder(encoder);
encoder_mode = atombios_get_encoder_mode(encoder);
- if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) {
- struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
- if (connector) {
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- struct radeon_connector_atom_dig *dig_connector =
- radeon_connector->con_priv;
-
- dp_clock = dig_connector->dp_clock;
- }
- }
-
if (ASIC_IS_AVIVO(rdev)) {
/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
@@ -568,14 +555,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
args.v1.ucTransmitterID = radeon_encoder->encoder_id;
args.v1.ucEncodeMode = encoder_mode;
- if (encoder_mode == ATOM_ENCODER_MODE_DP) {
- /* may want to enable SS on DP eventually */
- /* args.v1.ucConfig |=
- ADJUST_DISPLAY_CONFIG_SS_ENABLE;*/
- } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) {
- args.v1.ucConfig |=
- ADJUST_DISPLAY_CONFIG_SS_ENABLE;
- }
atom_execute_table(rdev->mode_info.atom_context,
index, (uint32_t *)&args);
@@ -589,20 +568,10 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- if (encoder_mode == ATOM_ENCODER_MODE_DP) {
- /* may want to enable SS on DP/eDP eventually */
- /*args.v3.sInput.ucDispPllConfig |=
- DISPPLL_CONFIG_SS_ENABLE;*/
+ if (encoder_mode == ATOM_ENCODER_MODE_DP)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_COHERENT_MODE;
- /* 16200 or 27000 */
- args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
- } else {
- if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
- /* deep color support */
- args.v3.sInput.usPixelClock =
- cpu_to_le16((mode->clock * bpc / 8) / 10);
- }
+ else {
if (dig->coherent_mode)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_COHERENT_MODE;
@@ -611,19 +580,13 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
DISPPLL_CONFIG_DUAL_LINK;
}
} else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
- if (encoder_mode == ATOM_ENCODER_MODE_DP) {
- /* may want to enable SS on DP/eDP eventually */
- /*args.v3.sInput.ucDispPllConfig |=
- DISPPLL_CONFIG_SS_ENABLE;*/
+ /* may want to enable SS on DP/eDP eventually */
+ /*args.v3.sInput.ucDispPllConfig |=
+ DISPPLL_CONFIG_SS_ENABLE;*/
+ if (encoder_mode == ATOM_ENCODER_MODE_DP)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_COHERENT_MODE;
- /* 16200 or 27000 */
- args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
- } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) {
- /* want to enable SS on LVDS eventually */
- /*args.v3.sInput.ucDispPllConfig |=
- DISPPLL_CONFIG_SS_ENABLE;*/
- } else {
+ else {
if (mode->clock > 165000)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_DUAL_LINK;
diff --git a/trunk/drivers/gpu/drm/radeon/atombios_dp.c b/trunk/drivers/gpu/drm/radeon/atombios_dp.c
index 4e7778d44b8d..36e0d4b545e6 100644
--- a/trunk/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/trunk/drivers/gpu/drm/radeon/atombios_dp.c
@@ -610,7 +610,7 @@ void dp_link_train(struct drm_encoder *encoder,
enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
else
enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
- if (dig->linkb)
+ if (dig_connector->linkb)
enc_id |= ATOM_DP_CONFIG_LINK_B;
else
enc_id |= ATOM_DP_CONFIG_LINK_A;
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_agp.c b/trunk/drivers/gpu/drm/radeon/radeon_agp.c
index bd2f33e5c91a..f40dfb77f9b1 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_agp.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_agp.c
@@ -156,13 +156,7 @@ int radeon_agp_init(struct radeon_device *rdev)
}
mode.mode = info.mode;
- /* chips with the agp to pcie bridge don't have the AGP_STATUS register
- * Just use the whatever mode the host sets up.
- */
- if (rdev->family <= CHIP_RV350)
- agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode;
- else
- agp_status = mode.mode;
+ agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode;
is_v3 = !!(agp_status & RADEON_AGPv3_MODE);
if (is_v3) {
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.c b/trunk/drivers/gpu/drm/radeon/radeon_asic.c
index a21bf88e8c2d..646f96f97c77 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.c
@@ -733,7 +733,6 @@ static struct radeon_asic evergreen_asic = {
.set_engine_clock = &radeon_atom_set_engine_clock,
.get_memory_clock = &radeon_atom_get_memory_clock,
.set_memory_clock = &radeon_atom_set_memory_clock,
- .get_pcie_lanes = NULL,
.set_pcie_lanes = NULL,
.set_clock_gating = NULL,
.set_surface_reg = r600_set_surface_reg,
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c
index 61141981880d..6d30868744ee 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -32,11 +32,11 @@
/* from radeon_encoder.c */
extern uint32_t
-radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device,
- uint8_t dac);
+radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device,
+ uint8_t dac);
extern void radeon_link_encoder_connector(struct drm_device *dev);
extern void
-radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum,
+radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id,
uint32_t supported_device);
/* from radeon_connector.c */
@@ -46,14 +46,14 @@ radeon_add_atom_connector(struct drm_device *dev,
uint32_t supported_device,
int connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
- uint32_t igp_lane_info,
+ bool linkb, uint32_t igp_lane_info,
uint16_t connector_object_id,
struct radeon_hpd *hpd,
struct radeon_router *router);
/* from radeon_legacy_encoder.c */
extern void
-radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,
+radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id,
uint32_t supported_device);
union atom_supported_devices {
@@ -226,8 +226,6 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device
struct radeon_hpd hpd;
u32 reg;
- memset(&hpd, 0, sizeof(struct radeon_hpd));
-
if (ASIC_IS_DCE4(rdev))
reg = EVERGREEN_DC_GPIO_HPD_A;
else
@@ -479,6 +477,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
int i, j, k, path_size, device_support;
int connector_type;
u16 igp_lane_info, conn_id, connector_object_id;
+ bool linkb;
struct radeon_i2c_bus_rec ddc_bus;
struct radeon_router router;
struct radeon_gpio_rec gpio;
@@ -511,7 +510,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
addr += path_size;
path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
path_size += le16_to_cpu(path->usSize);
-
+ linkb = false;
if (device_support & le16_to_cpu(path->usDeviceTag)) {
uint8_t con_obj_id, con_obj_num, con_obj_type;
@@ -602,10 +601,13 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
- u16 encoder_obj = le16_to_cpu(path->usGraphicObjIds[j]);
+ if (grph_obj_num == 2)
+ linkb = true;
+ else
+ linkb = false;
radeon_add_atom_encoder(dev,
- encoder_obj,
+ grph_obj_id,
le16_to_cpu
(path->
usDeviceTag));
@@ -742,7 +744,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
le16_to_cpu(path->
usDeviceTag),
connector_type, &ddc_bus,
- igp_lane_info,
+ linkb, igp_lane_info,
connector_object_id,
&hpd,
&router);
@@ -931,13 +933,13 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom)
radeon_add_atom_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
(1 << i),
dac),
(1 << i));
else
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
(1 << i),
dac),
(1 << i));
@@ -994,7 +996,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
bios_connectors[i].
connector_type,
&bios_connectors[i].ddc_bus,
- 0,
+ false, 0,
connector_object_id,
&bios_connectors[i].hpd,
&router);
@@ -1181,7 +1183,7 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev)
return true;
break;
case 2:
- if (igp_info->info_2.ulBootUpSidePortClock)
+ if (igp_info->info_2.ucMemoryType & 0x0f)
return true;
break;
default:
@@ -1303,7 +1305,6 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
union lvds_info *lvds_info;
uint8_t frev, crev;
struct radeon_encoder_atom_dig *lvds = NULL;
- int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
&frev, &crev, &data_offset)) {
@@ -1367,12 +1368,6 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
}
encoder->native_mode = lvds->native_mode;
-
- if (encoder_enum == 2)
- lvds->linkb = true;
- else
- lvds->linkb = false;
-
}
return lvds;
}
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c
index bd74e428bd14..885dcfac1838 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c
@@ -39,8 +39,8 @@
/* from radeon_encoder.c */
extern uint32_t
-radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device,
- uint8_t dac);
+radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device,
+ uint8_t dac);
extern void radeon_link_encoder_connector(struct drm_device *dev);
/* from radeon_connector.c */
@@ -55,7 +55,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
/* from radeon_legacy_encoder.c */
extern void
-radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,
+radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id,
uint32_t supported_device);
/* old legacy ATI BIOS routines */
@@ -1505,7 +1505,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
@@ -1520,7 +1520,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
0),
ATOM_DEVICE_LCD1_SUPPORT);
@@ -1535,7 +1535,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
@@ -1550,12 +1550,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
hpd.hpd = RADEON_HPD_1;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP1_SUPPORT,
0),
ATOM_DEVICE_DFP1_SUPPORT);
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
ATOM_DEVICE_CRT2_SUPPORT);
@@ -1571,7 +1571,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
@@ -1588,7 +1588,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
ATOM_DEVICE_TV1_SUPPORT);
@@ -1607,7 +1607,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
0),
ATOM_DEVICE_LCD1_SUPPORT);
@@ -1619,7 +1619,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
ATOM_DEVICE_CRT2_SUPPORT);
@@ -1631,7 +1631,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
ATOM_DEVICE_TV1_SUPPORT);
@@ -1648,7 +1648,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
0),
ATOM_DEVICE_LCD1_SUPPORT);
@@ -1660,12 +1660,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
hpd.hpd = RADEON_HPD_2; /* ??? */
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP2_SUPPORT,
0),
ATOM_DEVICE_DFP2_SUPPORT);
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
@@ -1680,7 +1680,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
ATOM_DEVICE_TV1_SUPPORT);
@@ -1697,7 +1697,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
0),
ATOM_DEVICE_LCD1_SUPPORT);
@@ -1709,12 +1709,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
hpd.hpd = RADEON_HPD_1; /* ??? */
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP1_SUPPORT,
0),
ATOM_DEVICE_DFP1_SUPPORT);
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
@@ -1728,7 +1728,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
ATOM_DEVICE_TV1_SUPPORT);
@@ -1745,7 +1745,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
0),
ATOM_DEVICE_LCD1_SUPPORT);
@@ -1757,7 +1757,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
@@ -1769,7 +1769,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
ATOM_DEVICE_TV1_SUPPORT);
@@ -1786,12 +1786,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
hpd.hpd = RADEON_HPD_2; /* ??? */
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP2_SUPPORT,
0),
ATOM_DEVICE_DFP2_SUPPORT);
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
ATOM_DEVICE_CRT2_SUPPORT);
@@ -1806,7 +1806,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
ATOM_DEVICE_TV1_SUPPORT);
@@ -1823,12 +1823,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
hpd.hpd = RADEON_HPD_1; /* ??? */
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP1_SUPPORT,
0),
ATOM_DEVICE_DFP1_SUPPORT);
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
ATOM_DEVICE_CRT2_SUPPORT);
@@ -1842,7 +1842,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
ATOM_DEVICE_TV1_SUPPORT);
@@ -1859,7 +1859,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
hpd.hpd = RADEON_HPD_1; /* ??? */
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP1_SUPPORT,
0),
ATOM_DEVICE_DFP1_SUPPORT);
@@ -1871,7 +1871,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
ATOM_DEVICE_CRT2_SUPPORT);
@@ -1883,7 +1883,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
ATOM_DEVICE_TV1_SUPPORT);
@@ -1900,7 +1900,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
@@ -1912,7 +1912,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
ATOM_DEVICE_CRT2_SUPPORT);
@@ -1924,7 +1924,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
ATOM_DEVICE_TV1_SUPPORT);
@@ -1941,7 +1941,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
@@ -1952,7 +1952,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
ATOM_DEVICE_CRT2_SUPPORT);
@@ -2109,7 +2109,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
else
devices = ATOM_DEVICE_DFP1_SUPPORT;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev, devices, 0),
devices);
radeon_add_legacy_connector(dev, i, devices,
@@ -2123,7 +2123,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
if (tmp & 0x1) {
devices = ATOM_DEVICE_CRT2_SUPPORT;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
@@ -2131,7 +2131,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
} else {
devices = ATOM_DEVICE_CRT1_SUPPORT;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
@@ -2151,7 +2151,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
if (tmp & 0x1) {
devices |= ATOM_DEVICE_CRT2_SUPPORT;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
@@ -2159,7 +2159,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
} else {
devices |= ATOM_DEVICE_CRT1_SUPPORT;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
@@ -2168,7 +2168,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
if ((tmp >> 4) & 0x1) {
devices |= ATOM_DEVICE_DFP2_SUPPORT;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev,
ATOM_DEVICE_DFP2_SUPPORT,
0),
@@ -2177,7 +2177,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
} else {
devices |= ATOM_DEVICE_DFP1_SUPPORT;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev,
ATOM_DEVICE_DFP1_SUPPORT,
0),
@@ -2202,7 +2202,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
}
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev, devices, 0),
devices);
radeon_add_legacy_connector(dev, i, devices,
@@ -2215,7 +2215,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
case CONNECTOR_CTV_LEGACY:
case CONNECTOR_STV_LEGACY:
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
@@ -2242,12 +2242,12 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n");
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP1_SUPPORT,
0),
ATOM_DEVICE_DFP1_SUPPORT);
@@ -2268,7 +2268,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n");
if (crt_info) {
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
@@ -2297,7 +2297,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
COMBIOS_LCD_DDC_INFO_TABLE);
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum(dev,
+ radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
0),
ATOM_DEVICE_LCD1_SUPPORT);
@@ -2351,7 +2351,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
hpd.hpd = RADEON_HPD_NONE;
ddc_i2c.valid = false;
radeon_add_legacy_encoder(dev,
- radeon_get_encoder_enum
+ radeon_get_encoder_id
(dev,
ATOM_DEVICE_TV1_SUPPORT,
2),
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c
index 31a09cd279ab..47c4b276d30c 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -977,25 +977,24 @@ static enum drm_connector_status radeon_dp_detect(struct drm_connector *connecto
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
enum drm_connector_status ret = connector_status_disconnected;
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
+ u8 sink_type;
if (radeon_connector->edid) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
}
- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
- /* eDP is always DP */
- radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
- if (radeon_dp_getdpcd(radeon_connector))
+ sink_type = radeon_dp_getsinktype(radeon_connector);
+ if ((sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+ (sink_type == CONNECTOR_OBJECT_ID_eDP)) {
+ if (radeon_dp_getdpcd(radeon_connector)) {
+ radeon_dig_connector->dp_sink_type = sink_type;
ret = connector_status_connected;
+ }
} else {
- radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
- if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
- if (radeon_dp_getdpcd(radeon_connector))
- ret = connector_status_connected;
- } else {
- if (radeon_ddc_probe(radeon_connector))
- ret = connector_status_connected;
+ if (radeon_ddc_probe(radeon_connector)) {
+ radeon_dig_connector->dp_sink_type = sink_type;
+ ret = connector_status_connected;
}
}
@@ -1038,6 +1037,7 @@ radeon_add_atom_connector(struct drm_device *dev,
uint32_t supported_device,
int connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
+ bool linkb,
uint32_t igp_lane_info,
uint16_t connector_object_id,
struct radeon_hpd *hpd,
@@ -1128,6 +1128,7 @@ radeon_add_atom_connector(struct drm_device *dev,
radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
if (!radeon_dig_connector)
goto failed;
+ radeon_dig_connector->linkb = linkb;
radeon_dig_connector->igp_lane_info = igp_lane_info;
radeon_connector->con_priv = radeon_dig_connector;
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
@@ -1157,6 +1158,7 @@ radeon_add_atom_connector(struct drm_device *dev,
radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
if (!radeon_dig_connector)
goto failed;
+ radeon_dig_connector->linkb = linkb;
radeon_dig_connector->igp_lane_info = igp_lane_info;
radeon_connector->con_priv = radeon_dig_connector;
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
@@ -1180,6 +1182,7 @@ radeon_add_atom_connector(struct drm_device *dev,
radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
if (!radeon_dig_connector)
goto failed;
+ radeon_dig_connector->linkb = linkb;
radeon_dig_connector->igp_lane_info = igp_lane_info;
radeon_connector->con_priv = radeon_dig_connector;
drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
@@ -1226,6 +1229,7 @@ radeon_add_atom_connector(struct drm_device *dev,
radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
if (!radeon_dig_connector)
goto failed;
+ radeon_dig_connector->linkb = linkb;
radeon_dig_connector->igp_lane_info = igp_lane_info;
radeon_connector->con_priv = radeon_dig_connector;
drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c
index 69b3c2291e92..4f7a170d1566 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_device.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c
@@ -199,7 +199,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64
mc->mc_vram_size = mc->aper_size;
}
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
- if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_start <= mc->gtt_end) {
+ if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_end <= mc->gtt_end) {
dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n");
mc->real_vram_size = mc->aper_size;
mc->mc_vram_size = mc->aper_size;
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c
index 6dd434ad2429..5764f4d3b4f1 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_display.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c
@@ -1094,18 +1094,6 @@ void radeon_modeset_fini(struct radeon_device *rdev)
radeon_i2c_fini(rdev);
}
-static bool is_hdtv_mode(struct drm_display_mode *mode)
-{
- /* try and guess if this is a tv or a monitor */
- if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */
- (mode->vdisplay == 576) || /* 576p */
- (mode->vdisplay == 720) || /* 720p */
- (mode->vdisplay == 1080)) /* 1080p */
- return true;
- else
- return false;
-}
-
bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -1153,8 +1141,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
if (ASIC_IS_AVIVO(rdev) &&
((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
- drm_detect_hdmi_monitor(radeon_connector->edid) &&
- is_hdtv_mode(mode)))) {
+ drm_detect_hdmi_monitor(radeon_connector->edid)))) {
radeon_crtc->h_border = (mode->hdisplay >> 5) + 16;
radeon_crtc->v_border = (mode->vdisplay >> 5) + 16;
radeon_crtc->rmx_type = RMX_FULL;
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c
index 2c293e8304d6..263c8098d7dd 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -81,7 +81,7 @@ void radeon_setup_encoder_clones(struct drm_device *dev)
}
uint32_t
-radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
+radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
{
struct radeon_device *rdev = dev->dev_private;
uint32_t ret = 0;
@@ -97,59 +97,59 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8
if ((rdev->family == CHIP_RS300) ||
(rdev->family == CHIP_RS400) ||
(rdev->family == CHIP_RS480))
- ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
else if (ASIC_IS_AVIVO(rdev))
- ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
else
- ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_DAC1;
break;
case 2: /* dac b */
if (ASIC_IS_AVIVO(rdev))
- ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
else {
/*if (rdev->family == CHIP_R200)
- ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
else*/
- ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
}
break;
case 3: /* external dac */
if (ASIC_IS_AVIVO(rdev))
- ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
else
- ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
break;
}
break;
case ATOM_DEVICE_LCD1_SUPPORT:
if (ASIC_IS_AVIVO(rdev))
- ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
else
- ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_LVDS;
break;
case ATOM_DEVICE_DFP1_SUPPORT:
if ((rdev->family == CHIP_RS300) ||
(rdev->family == CHIP_RS400) ||
(rdev->family == CHIP_RS480))
- ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
else if (ASIC_IS_AVIVO(rdev))
- ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1;
else
- ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1;
break;
case ATOM_DEVICE_LCD2_SUPPORT:
case ATOM_DEVICE_DFP2_SUPPORT:
if ((rdev->family == CHIP_RS600) ||
(rdev->family == CHIP_RS690) ||
(rdev->family == CHIP_RS740))
- ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_DDI;
else if (ASIC_IS_AVIVO(rdev))
- ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
else
- ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
break;
case ATOM_DEVICE_DFP3_SUPPORT:
- ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
+ ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
break;
}
@@ -228,6 +228,32 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
return NULL;
}
+static struct radeon_connector_atom_dig *
+radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector;
+ struct radeon_connector_atom_dig *dig_connector;
+
+ if (!rdev->is_atom_bios)
+ return NULL;
+
+ connector = radeon_get_connector_for_encoder(encoder);
+ if (!connector)
+ return NULL;
+
+ radeon_connector = to_radeon_connector(connector);
+
+ if (!radeon_connector->con_priv)
+ return NULL;
+
+ dig_connector = radeon_connector->con_priv;
+
+ return dig_connector;
+}
+
void radeon_panel_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
@@ -486,12 +512,14 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ struct radeon_connector_atom_dig *dig_connector =
+ radeon_get_atom_connector_priv_from_encoder(encoder);
union lvds_encoder_control args;
int index = 0;
int hdmi_detected = 0;
uint8_t frev, crev;
- if (!dig)
+ if (!dig || !dig_connector)
return;
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
@@ -534,7 +562,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
args.v1.ucMisc |= (1 << 1);
} else {
- if (dig->linkb)
+ if (dig_connector->linkb)
args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
if (radeon_encoder->pixel_clock > 165000)
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
@@ -573,7 +601,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
}
} else {
- if (dig->linkb)
+ if (dig_connector->linkb)
args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
if (radeon_encoder->pixel_clock > 165000)
args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
@@ -595,8 +623,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
int
atombios_get_encoder_mode(struct drm_encoder *encoder)
{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
struct radeon_connector_atom_dig *dig_connector;
@@ -610,13 +636,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
- if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
- /* fix me */
- if (ASIC_IS_DCE4(rdev))
- return ATOM_ENCODER_MODE_DVI;
- else
- return ATOM_ENCODER_MODE_HDMI;
- } else if (radeon_connector->use_digital)
+ if (drm_detect_hdmi_monitor(radeon_connector->edid))
+ return ATOM_ENCODER_MODE_HDMI;
+ else if (radeon_connector->use_digital)
return ATOM_ENCODER_MODE_DVI;
else
return ATOM_ENCODER_MODE_CRT;
@@ -624,13 +646,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
case DRM_MODE_CONNECTOR_DVID:
case DRM_MODE_CONNECTOR_HDMIA:
default:
- if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
- /* fix me */
- if (ASIC_IS_DCE4(rdev))
- return ATOM_ENCODER_MODE_DVI;
- else
- return ATOM_ENCODER_MODE_HDMI;
- } else
+ if (drm_detect_hdmi_monitor(radeon_connector->edid))
+ return ATOM_ENCODER_MODE_HDMI;
+ else
return ATOM_ENCODER_MODE_DVI;
break;
case DRM_MODE_CONNECTOR_LVDS:
@@ -642,13 +660,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
return ATOM_ENCODER_MODE_DP;
- else if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
- /* fix me */
- if (ASIC_IS_DCE4(rdev))
- return ATOM_ENCODER_MODE_DVI;
- else
- return ATOM_ENCODER_MODE_HDMI;
- } else
+ else if (drm_detect_hdmi_monitor(radeon_connector->edid))
+ return ATOM_ENCODER_MODE_HDMI;
+ else
return ATOM_ENCODER_MODE_DVI;
break;
case DRM_MODE_CONNECTOR_DVIA:
@@ -715,24 +729,13 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ struct radeon_connector_atom_dig *dig_connector =
+ radeon_get_atom_connector_priv_from_encoder(encoder);
union dig_encoder_control args;
int index = 0;
uint8_t frev, crev;
- int dp_clock = 0;
- int dp_lane_count = 0;
-
- if (connector) {
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- struct radeon_connector_atom_dig *dig_connector =
- radeon_connector->con_priv;
- dp_clock = dig_connector->dp_clock;
- dp_lane_count = dig_connector->dp_lane_count;
- }
-
- /* no dig encoder assigned */
- if (dig->dig_encoder == -1)
+ if (!dig || !dig_connector)
return;
memset(&args, 0, sizeof(args));
@@ -754,9 +757,9 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
- if (dp_clock == 270000)
+ if (dig_connector->dp_clock == 270000)
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
- args.v1.ucLaneNum = dp_lane_count;
+ args.v1.ucLaneNum = dig_connector->dp_lane_count;
} else if (radeon_encoder->pixel_clock > 165000)
args.v1.ucLaneNum = 8;
else
@@ -778,7 +781,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
break;
}
- if (dig->linkb)
+ if (dig_connector->linkb)
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
else
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
@@ -801,47 +804,38 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ struct radeon_connector_atom_dig *dig_connector =
+ radeon_get_atom_connector_priv_from_encoder(encoder);
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector;
union dig_transmitter_control args;
int index = 0;
uint8_t frev, crev;
bool is_dp = false;
int pll_id = 0;
- int dp_clock = 0;
- int dp_lane_count = 0;
- int connector_object_id = 0;
- int igp_lane_info = 0;
-
- if (connector) {
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- struct radeon_connector_atom_dig *dig_connector =
- radeon_connector->con_priv;
-
- dp_clock = dig_connector->dp_clock;
- dp_lane_count = dig_connector->dp_lane_count;
- connector_object_id =
- (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
- igp_lane_info = dig_connector->igp_lane_info;
- }
- /* no dig encoder assigned */
- if (dig->dig_encoder == -1)
+ if (!dig || !dig_connector)
return;
+ connector = radeon_get_connector_for_encoder(encoder);
+ radeon_connector = to_radeon_connector(connector);
+
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
is_dp = true;
memset(&args, 0, sizeof(args));
- switch (radeon_encoder->encoder_id) {
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+ if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev))
index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
- break;
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl);
- break;
+ else {
+ switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+ index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+ index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
+ break;
+ }
}
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
@@ -849,14 +843,14 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
args.v1.ucAction = action;
if (action == ATOM_TRANSMITTER_ACTION_INIT) {
- args.v1.usInitInfo = connector_object_id;
+ args.v1.usInitInfo = radeon_connector->connector_object_id;
} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
args.v1.asMode.ucLaneSel = lane_num;
args.v1.asMode.ucLaneSet = lane_set;
} else {
if (is_dp)
args.v1.usPixelClock =
- cpu_to_le16(dp_clock / 10);
+ cpu_to_le16(dig_connector->dp_clock / 10);
else if (radeon_encoder->pixel_clock > 165000)
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
@@ -864,13 +858,13 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
}
if (ASIC_IS_DCE4(rdev)) {
if (is_dp)
- args.v3.ucLaneNum = dp_lane_count;
+ args.v3.ucLaneNum = dig_connector->dp_lane_count;
else if (radeon_encoder->pixel_clock > 165000)
args.v3.ucLaneNum = 8;
else
args.v3.ucLaneNum = 4;
- if (dig->linkb) {
+ if (dig_connector->linkb) {
args.v3.acConfig.ucLinkSel = 1;
args.v3.acConfig.ucEncoderSel = 1;
}
@@ -910,7 +904,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
}
} else if (ASIC_IS_DCE32(rdev)) {
args.v2.acConfig.ucEncoderSel = dig->dig_encoder;
- if (dig->linkb)
+ if (dig_connector->linkb)
args.v2.acConfig.ucLinkSel = 1;
switch (radeon_encoder->encoder_id) {
@@ -944,23 +938,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if ((rdev->flags & RADEON_IS_IGP) &&
(radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
if (is_dp || (radeon_encoder->pixel_clock <= 165000)) {
- if (igp_lane_info & 0x1)
+ if (dig_connector->igp_lane_info & 0x1)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
- else if (igp_lane_info & 0x2)
+ else if (dig_connector->igp_lane_info & 0x2)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
- else if (igp_lane_info & 0x4)
+ else if (dig_connector->igp_lane_info & 0x4)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
- else if (igp_lane_info & 0x8)
+ else if (dig_connector->igp_lane_info & 0x8)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
} else {
- if (igp_lane_info & 0x3)
+ if (dig_connector->igp_lane_info & 0x3)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
- else if (igp_lane_info & 0xc)
+ else if (dig_connector->igp_lane_info & 0xc)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
}
}
- if (dig->linkb)
+ if (dig_connector->linkb)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
else
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
@@ -1078,7 +1072,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
if (is_dig) {
switch (mode) {
case DRM_MODE_DPMS_ON:
- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+ if (!ASIC_IS_DCE4(rdev))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
@@ -1090,7 +1085,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+ if (!ASIC_IS_DCE4(rdev))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
@@ -1294,22 +1290,24 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
uint32_t dig_enc_in_use = 0;
if (ASIC_IS_DCE4(rdev)) {
- dig = radeon_encoder->enc_priv;
+ struct radeon_connector_atom_dig *dig_connector =
+ radeon_get_atom_connector_priv_from_encoder(encoder);
+
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- if (dig->linkb)
+ if (dig_connector->linkb)
return 1;
else
return 0;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
- if (dig->linkb)
+ if (dig_connector->linkb)
return 3;
else
return 2;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
- if (dig->linkb)
+ if (dig_connector->linkb)
return 5;
else
return 4;
@@ -1643,7 +1641,6 @@ radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
struct radeon_encoder_atom_dig *
radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
{
- int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
if (!dig)
@@ -1653,16 +1650,11 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
dig->coherent_mode = true;
dig->dig_encoder = -1;
- if (encoder_enum == 2)
- dig->linkb = true;
- else
- dig->linkb = false;
-
return dig;
}
void
-radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device)
+radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
{
struct radeon_device *rdev = dev->dev_private;
struct drm_encoder *encoder;
@@ -1671,7 +1663,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
/* see if we already added it */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
radeon_encoder = to_radeon_encoder(encoder);
- if (radeon_encoder->encoder_enum == encoder_enum) {
+ if (radeon_encoder->encoder_id == encoder_id) {
radeon_encoder->devices |= supported_device;
return;
}
@@ -1699,8 +1691,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
radeon_encoder->enc_priv = NULL;
- radeon_encoder->encoder_enum = encoder_enum;
- radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+ radeon_encoder->encoder_id = encoder_id;
radeon_encoder->devices = supported_device;
radeon_encoder->rmx_type = RMX_OFF;
radeon_encoder->underscan_type = UNDERSCAN_OFF;
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_fb.c b/trunk/drivers/gpu/drm/radeon/radeon_fb.c
index c74a8b20d941..dbf86962bdd1 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_fb.c
@@ -118,7 +118,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
aligned_size = ALIGN(size, PAGE_SIZE);
ret = radeon_gem_object_create(rdev, aligned_size, 0,
RADEON_GEM_DOMAIN_VRAM,
- false, true,
+ false, ttm_bo_type_kernel,
&gobj);
if (ret) {
printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c
index 0416804d8f30..bfd2ce5f5372 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -99,13 +99,6 @@ static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
}
}
- /* switch the pads to ddc mode */
- if (ASIC_IS_DCE3(rdev) && rec->hw_capable) {
- temp = RREG32(rec->mask_clk_reg);
- temp &= ~(1 << 16);
- WREG32(rec->mask_clk_reg, temp);
- }
-
/* clear the output pin values */
temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask;
WREG32(rec->a_clk_reg, temp);
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c
index a108c7ed14f5..059bfa4098d7 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -121,12 +121,11 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
* chips. Disable MSI on them for now.
*/
if ((rdev->family >= CHIP_RV380) &&
- (!(rdev->flags & RADEON_IS_IGP)) &&
- (!(rdev->flags & RADEON_IS_AGP))) {
+ (!(rdev->flags & RADEON_IS_IGP))) {
int ret = pci_enable_msi(rdev->pdev);
if (!ret) {
rdev->msi_enabled = 1;
- dev_info(rdev->dev, "radeon: using MSI.\n");
+ DRM_INFO("radeon: using MSI.\n");
}
}
rdev->irq.installed = true;
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_kms.c
index 5eee3c41d124..b1c8ace5f080 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_kms.c
@@ -161,7 +161,6 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
DRM_DEBUG_KMS("tiling config is r6xx+ only!\n");
return -EINVAL;
}
- break;
case RADEON_INFO_WANT_HYPERZ:
/* The "value" here is both an input and output parameter.
* If the input value is 1, filp requests hyper-z access.
@@ -324,45 +323,45 @@ KMS_INVALID_IOCTL(radeon_surface_free_kms)
struct drm_ioctl_desc radeon_ioctls_kms[] = {
- DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH),
/* KMS */
- DRM_IOCTL_DEF_DRV(RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
};
int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms);
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 305049afde15..989df519a1e4 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -272,7 +272,7 @@ static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div,
if (!ref_div)
return 1;
- vcoFreq = ((unsigned)ref_freq * fb_div) / ref_div;
+ vcoFreq = ((unsigned)ref_freq & fb_div) / ref_div;
/*
* This is horribly crude: the VCO frequency range is divided into
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 0b8397000f4c..b8149cbc0c70 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -1345,7 +1345,7 @@ static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct ra
}
void
-radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device)
+radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
{
struct radeon_device *rdev = dev->dev_private;
struct drm_encoder *encoder;
@@ -1354,7 +1354,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_
/* see if we already added it */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
radeon_encoder = to_radeon_encoder(encoder);
- if (radeon_encoder->encoder_enum == encoder_enum) {
+ if (radeon_encoder->encoder_id == encoder_id) {
radeon_encoder->devices |= supported_device;
return;
}
@@ -1374,8 +1374,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_
radeon_encoder->enc_priv = NULL;
- radeon_encoder->encoder_enum = encoder_enum;
- radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+ radeon_encoder->encoder_id = encoder_id;
radeon_encoder->devices = supported_device;
radeon_encoder->rmx_type = RMX_OFF;
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h
index 8f93e2b4b0c8..5bbc086b9267 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h
@@ -342,7 +342,6 @@ struct radeon_atom_ss {
};
struct radeon_encoder_atom_dig {
- bool linkb;
/* atom dig */
bool coherent_mode;
int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */
@@ -361,7 +360,6 @@ struct radeon_encoder_atom_dac {
struct radeon_encoder {
struct drm_encoder base;
- uint32_t encoder_enum;
uint32_t encoder_id;
uint32_t devices;
uint32_t active_device;
@@ -380,6 +378,7 @@ struct radeon_encoder {
struct radeon_connector_atom_dig {
uint32_t igp_lane_info;
+ bool linkb;
/* displayport */
struct radeon_i2c_chan *dp_i2c_bus;
u8 dpcd[8];
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_pm.c b/trunk/drivers/gpu/drm/radeon/radeon_pm.c
index 477ba673e1b4..58038f5cab38 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_pm.c
@@ -226,11 +226,6 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
{
int i;
- /* no need to take locks, etc. if nothing's going to change */
- if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) &&
- (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index))
- return;
-
mutex_lock(&rdev->ddev->struct_mutex);
mutex_lock(&rdev->vram_mutex);
mutex_lock(&rdev->cp.mutex);
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_state.c b/trunk/drivers/gpu/drm/radeon/radeon_state.c
index 4ae5a3d1074e..b3ba44c0a818 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_state.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_state.c
@@ -3228,34 +3228,34 @@ void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
}
struct drm_ioctl_desc radeon_ioctls[] = {
- DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH)
+ DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH)
};
int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
diff --git a/trunk/drivers/gpu/drm/savage/savage_bci.c b/trunk/drivers/gpu/drm/savage/savage_bci.c
index bf5f83ea14fe..976dc8d25280 100644
--- a/trunk/drivers/gpu/drm/savage/savage_bci.c
+++ b/trunk/drivers/gpu/drm/savage/savage_bci.c
@@ -1082,10 +1082,10 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv)
}
struct drm_ioctl_desc savage_ioctls[] = {
- DRM_IOCTL_DEF_DRV(SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH),
};
int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls);
diff --git a/trunk/drivers/gpu/drm/sis/sis_mm.c b/trunk/drivers/gpu/drm/sis/sis_mm.c
index 7fe2b63412ce..07d0f2979cac 100644
--- a/trunk/drivers/gpu/drm/sis/sis_mm.c
+++ b/trunk/drivers/gpu/drm/sis/sis_mm.c
@@ -320,12 +320,12 @@ void sis_reclaim_buffers_locked(struct drm_device *dev,
}
struct drm_ioctl_desc sis_ioctls[] = {
- DRM_IOCTL_DEF_DRV(SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(SIS_FB_FREE, sis_drm_free, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(SIS_AGP_FREE, sis_drm_free, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SIS_FB_FREE, sis_drm_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SIS_AGP_FREE, sis_drm_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
};
int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
diff --git a/trunk/drivers/gpu/drm/via/via_dma.c b/trunk/drivers/gpu/drm/via/via_dma.c
index cc0ffa9abd00..68dda74a50ae 100644
--- a/trunk/drivers/gpu/drm/via/via_dma.c
+++ b/trunk/drivers/gpu/drm/via/via_dma.c
@@ -722,20 +722,20 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *
}
struct drm_ioctl_desc via_ioctls[] = {
- DRM_IOCTL_DEF_DRV(VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_FREEMEM, via_mem_free, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER),
- DRM_IOCTL_DEF_DRV(VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER),
- DRM_IOCTL_DEF_DRV(VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER),
- DRM_IOCTL_DEF_DRV(VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_DMA_INIT, via_dma_init, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_FLUSH, via_flush_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_DMA_BLIT, via_dma_blit, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH)
+ DRM_IOCTL_DEF(DRM_VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_FREEMEM, via_mem_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER),
+ DRM_IOCTL_DEF(DRM_VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER),
+ DRM_IOCTL_DEF(DRM_VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER),
+ DRM_IOCTL_DEF(DRM_VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_DMA_INIT, via_dma_init, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_FLUSH, via_flush_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_DMA_BLIT, via_dma_blit, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH)
};
int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls);
diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 72ec2e2b6e97..9dd395b90216 100644
--- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -99,47 +99,47 @@
*/
#define VMW_IOCTL_DEF(ioctl, func, flags) \
- [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {DRM_##ioctl, flags, func, DRM_IOCTL_##ioctl}
+ [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
/**
* Ioctl definitions.
*/
static struct drm_ioctl_desc vmw_ioctls[] = {
- VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_CURSOR_BYPASS,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS,
vmw_kms_cursor_bypass_ioctl,
DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_CONTROL_STREAM, vmw_overlay_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl,
DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_CLAIM_STREAM, vmw_stream_claim_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl,
DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_UNREF_STREAM, vmw_stream_unref_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl,
DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_CREATE_CONTEXT, vmw_context_define_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_CREATE_SURFACE, vmw_surface_define_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_REF_SURFACE, vmw_surface_reference_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl,
DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_wait_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl,
DRM_AUTH | DRM_UNLOCKED),
- VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl,
+ VMW_IOCTL_DEF(DRM_IOCTL_VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl,
DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED)
};
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/ads7871.c b/trunk/drivers/hwmon/ads7871.c
index 52319340e182..b300a2048af1 100644
--- a/trunk/drivers/hwmon/ads7871.c
+++ b/trunk/drivers/hwmon/ads7871.c
@@ -160,12 +160,30 @@ static const struct attribute_group ads7871_group = {
static int __devinit ads7871_probe(struct spi_device *spi)
{
- int ret, err;
+ int status, ret, err = 0;
uint8_t val;
struct ads7871_data *pdata;
dev_dbg(&spi->dev, "probe\n");
+ pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL);
+ if (!pdata) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ status = sysfs_create_group(&spi->dev.kobj, &ads7871_group);
+ if (status < 0)
+ goto error_free;
+
+ pdata->hwmon_dev = hwmon_device_register(&spi->dev);
+ if (IS_ERR(pdata->hwmon_dev)) {
+ err = PTR_ERR(pdata->hwmon_dev);
+ goto error_remove;
+ }
+
+ spi_set_drvdata(spi, pdata);
+
/* Configure the SPI bus */
spi->mode = (SPI_MODE_0);
spi->bits_per_word = 8;
@@ -183,24 +201,6 @@ static int __devinit ads7871_probe(struct spi_device *spi)
we need to make sure we really have a chip*/
if (val != ret) {
err = -ENODEV;
- goto exit;
- }
-
- pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL);
- if (!pdata) {
- err = -ENOMEM;
- goto exit;
- }
-
- err = sysfs_create_group(&spi->dev.kobj, &ads7871_group);
- if (err < 0)
- goto error_free;
-
- spi_set_drvdata(spi, pdata);
-
- pdata->hwmon_dev = hwmon_device_register(&spi->dev);
- if (IS_ERR(pdata->hwmon_dev)) {
- err = PTR_ERR(pdata->hwmon_dev);
goto error_remove;
}
diff --git a/trunk/drivers/hwmon/coretemp.c b/trunk/drivers/hwmon/coretemp.c
index de8111114f46..c070c9714cbe 100644
--- a/trunk/drivers/hwmon/coretemp.c
+++ b/trunk/drivers/hwmon/coretemp.c
@@ -518,6 +518,7 @@ static struct notifier_block coretemp_cpu_notifier __refdata = {
static int __init coretemp_init(void)
{
int i, err = -ENODEV;
+ struct pdev_entry *p, *n;
/* quick check if we run Intel */
if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
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/hwmon/k8temp.c b/trunk/drivers/hwmon/k8temp.c
index 39ead2a4d3c5..b9bb3e0ca530 100644
--- a/trunk/drivers/hwmon/k8temp.c
+++ b/trunk/drivers/hwmon/k8temp.c
@@ -143,37 +143,6 @@ static const struct pci_device_id k8temp_ids[] = {
MODULE_DEVICE_TABLE(pci, k8temp_ids);
-static int __devinit is_rev_g_desktop(u8 model)
-{
- u32 brandidx;
-
- if (model < 0x69)
- return 0;
-
- if (model == 0xc1 || model == 0x6c || model == 0x7c)
- return 0;
-
- /*
- * Differentiate between AM2 and ASB1.
- * See "Constructing the processor Name String" in "Revision
- * Guide for AMD NPT Family 0Fh Processors" (33610).
- */
- brandidx = cpuid_ebx(0x80000001);
- brandidx = (brandidx >> 9) & 0x1f;
-
- /* Single core */
- if ((model == 0x6f || model == 0x7f) &&
- (brandidx == 0x7 || brandidx == 0x9 || brandidx == 0xc))
- return 0;
-
- /* Dual core */
- if (model == 0x6b &&
- (brandidx == 0xb || brandidx == 0xc))
- return 0;
-
- return 1;
-}
-
static int __devinit k8temp_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@@ -210,7 +179,9 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
"wrong - check erratum #141\n");
}
- if (is_rev_g_desktop(model)) {
+ if ((model >= 0x69) &&
+ !(model == 0xc1 || model == 0x6c || model == 0x7c ||
+ model == 0x6b || model == 0x6f || model == 0x7f)) {
/*
* RevG desktop CPUs (i.e. no socket S1G1 or
* ASB1 parts) need additional offset,
diff --git a/trunk/drivers/isdn/hardware/avm/Kconfig b/trunk/drivers/isdn/hardware/avm/Kconfig
index b99b906ea9b1..5dbcbe3a54a6 100644
--- a/trunk/drivers/isdn/hardware/avm/Kconfig
+++ b/trunk/drivers/isdn/hardware/avm/Kconfig
@@ -36,13 +36,12 @@ config ISDN_DRV_AVMB1_T1ISA
config ISDN_DRV_AVMB1_B1PCMCIA
tristate "AVM B1/M1/M2 PCMCIA support"
- depends on PCMCIA
help
Enable support for the PCMCIA version of the AVM B1 card.
config ISDN_DRV_AVMB1_AVM_CS
tristate "AVM B1/M1/M2 PCMCIA cs module"
- depends on ISDN_DRV_AVMB1_B1PCMCIA
+ depends on ISDN_DRV_AVMB1_B1PCMCIA && PCMCIA
help
Enable the PCMCIA client driver for the AVM B1/M1/M2
PCMCIA cards.
diff --git a/trunk/drivers/macintosh/via-pmu.c b/trunk/drivers/macintosh/via-pmu.c
index 2d17e76066bd..35bc2737412f 100644
--- a/trunk/drivers/macintosh/via-pmu.c
+++ b/trunk/drivers/macintosh/via-pmu.c
@@ -45,7 +45,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -2350,52 +2349,11 @@ static long pmu_unlocked_ioctl(struct file *filp,
return ret;
}
-#ifdef CONFIG_COMPAT
-#define PMU_IOC_GET_BACKLIGHT32 _IOR('B', 1, compat_size_t)
-#define PMU_IOC_SET_BACKLIGHT32 _IOW('B', 2, compat_size_t)
-#define PMU_IOC_GET_MODEL32 _IOR('B', 3, compat_size_t)
-#define PMU_IOC_HAS_ADB32 _IOR('B', 4, compat_size_t)
-#define PMU_IOC_CAN_SLEEP32 _IOR('B', 5, compat_size_t)
-#define PMU_IOC_GRAB_BACKLIGHT32 _IOR('B', 6, compat_size_t)
-
-static long compat_pmu_ioctl (struct file *filp, u_int cmd, u_long arg)
-{
- switch (cmd) {
- case PMU_IOC_SLEEP:
- break;
- case PMU_IOC_GET_BACKLIGHT32:
- cmd = PMU_IOC_GET_BACKLIGHT;
- break;
- case PMU_IOC_SET_BACKLIGHT32:
- cmd = PMU_IOC_SET_BACKLIGHT;
- break;
- case PMU_IOC_GET_MODEL32:
- cmd = PMU_IOC_GET_MODEL;
- break;
- case PMU_IOC_HAS_ADB32:
- cmd = PMU_IOC_HAS_ADB;
- break;
- case PMU_IOC_CAN_SLEEP32:
- cmd = PMU_IOC_CAN_SLEEP;
- break;
- case PMU_IOC_GRAB_BACKLIGHT32:
- cmd = PMU_IOC_GRAB_BACKLIGHT;
- break;
- default:
- return -ENOIOCTLCMD;
- }
- return pmu_unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
-}
-#endif
-
static const struct file_operations pmu_device_fops = {
.read = pmu_read,
.write = pmu_write,
.poll = pmu_fpoll,
.unlocked_ioctl = pmu_unlocked_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = compat_pmu_ioctl,
-#endif
.open = pmu_open,
.release = pmu_release,
};
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/media/dvb/mantis/Kconfig b/trunk/drivers/media/dvb/mantis/Kconfig
index fd0830ed10d8..decdeda840d0 100644
--- a/trunk/drivers/media/dvb/mantis/Kconfig
+++ b/trunk/drivers/media/dvb/mantis/Kconfig
@@ -1,6 +1,6 @@
config MANTIS_CORE
tristate "Mantis/Hopper PCI bridge based devices"
- depends on PCI && I2C && INPUT && IR_CORE
+ depends on PCI && I2C && INPUT
help
Support for PCI cards based on the Mantis and Hopper PCi bridge.
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/Kconfig b/trunk/drivers/net/Kconfig
index 2cc81a54cbf3..5a6895320b48 100644
--- a/trunk/drivers/net/Kconfig
+++ b/trunk/drivers/net/Kconfig
@@ -928,16 +928,6 @@ config SMC91X
The module will be called smc91x. If you want to compile it as a
module, say M here and read .
-config PXA168_ETH
- tristate "Marvell pxa168 ethernet support"
- depends on CPU_PXA168
- select PHYLIB
- help
- This driver supports the pxa168 Ethernet ports.
-
- To compile this driver as a module, choose M here. The module
- will be called pxa168_eth.
-
config NET_NETX
tristate "NetX Ethernet support"
select MII
diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile
index 3e8f150c4b14..56e8c27f77ce 100644
--- a/trunk/drivers/net/Makefile
+++ b/trunk/drivers/net/Makefile
@@ -244,7 +244,6 @@ obj-$(CONFIG_MYRI10GE) += myri10ge/
obj-$(CONFIG_SMC91X) += smc91x.o
obj-$(CONFIG_SMC911X) += smc911x.o
obj-$(CONFIG_SMSC911X) += smsc911x.o
-obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o
obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
obj-$(CONFIG_DM9000) += dm9000.o
obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
diff --git a/trunk/drivers/net/bnx2x/bnx2x.h b/trunk/drivers/net/bnx2x/bnx2x.h
index 0c2d96ed561c..53af9c93e75c 100644
--- a/trunk/drivers/net/bnx2x/bnx2x.h
+++ b/trunk/drivers/net/bnx2x/bnx2x.h
@@ -20,8 +20,8 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
-#define DRV_MODULE_VERSION "1.52.53-4"
-#define DRV_MODULE_RELDATE "2010/16/08"
+#define DRV_MODULE_VERSION "1.52.53-3"
+#define DRV_MODULE_RELDATE "2010/18/04"
#define BNX2X_BC_VER 0x040200
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
diff --git a/trunk/drivers/net/bnx2x/bnx2x_main.c b/trunk/drivers/net/bnx2x/bnx2x_main.c
index f8c3f08e4ce7..b4ec2b02a465 100644
--- a/trunk/drivers/net/bnx2x/bnx2x_main.c
+++ b/trunk/drivers/net/bnx2x/bnx2x_main.c
@@ -4328,12 +4328,10 @@ static int bnx2x_init_port(struct bnx2x *bp)
val |= aeu_gpio_mask;
REG_WR(bp, offset, val);
}
- bp->port.need_hw_lock = 1;
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- bp->port.need_hw_lock = 1;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
/* add SPIO 5 to group 0 */
{
u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
@@ -4343,10 +4341,7 @@ static int bnx2x_init_port(struct bnx2x *bp)
REG_WR(bp, reg_addr, val);
}
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- bp->port.need_hw_lock = 1;
- break;
+
default:
break;
}
diff --git a/trunk/drivers/net/e1000e/82571.c b/trunk/drivers/net/e1000e/82571.c
index d3d4a57e2450..a4a0d2b6eb1c 100644
--- a/trunk/drivers/net/e1000e/82571.c
+++ b/trunk/drivers/net/e1000e/82571.c
@@ -936,14 +936,12 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
ew32(IMC, 0xffffffff);
icr = er32(ICR);
- if (hw->mac.type == e1000_82571) {
- /* Install any alternate MAC address into RAR0 */
- ret_val = e1000_check_alt_mac_addr_generic(hw);
- if (ret_val)
- return ret_val;
+ /* Install any alternate MAC address into RAR0 */
+ ret_val = e1000_check_alt_mac_addr_generic(hw);
+ if (ret_val)
+ return ret_val;
- e1000e_set_laa_state_82571(hw, true);
- }
+ e1000e_set_laa_state_82571(hw, true);
/* Reinitialize the 82571 serdes link state machine */
if (hw->phy.media_type == e1000_media_type_internal_serdes)
@@ -1620,16 +1618,14 @@ static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw)
{
s32 ret_val = 0;
- if (hw->mac.type == e1000_82571) {
- /*
- * If there's an alternate MAC address place it in RAR0
- * so that it will override the Si installed default perm
- * address.
- */
- ret_val = e1000_check_alt_mac_addr_generic(hw);
- if (ret_val)
- goto out;
- }
+ /*
+ * If there's an alternate MAC address place it in RAR0
+ * so that it will override the Si installed default perm
+ * address.
+ */
+ ret_val = e1000_check_alt_mac_addr_generic(hw);
+ if (ret_val)
+ goto out;
ret_val = e1000_read_mac_addr_generic(hw);
@@ -1837,7 +1833,6 @@ struct e1000_info e1000_82573_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_SWSM_ON_LOAD,
- .flags2 = FLAG2_DISABLE_ASPM_L1,
.pba = 20,
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
diff --git a/trunk/drivers/net/e1000e/defines.h b/trunk/drivers/net/e1000e/defines.h
index 93b3bedae8d2..307a72f483ee 100644
--- a/trunk/drivers/net/e1000e/defines.h
+++ b/trunk/drivers/net/e1000e/defines.h
@@ -621,7 +621,6 @@
#define E1000_FLASH_UPDATES 2000
/* NVM Word Offsets */
-#define NVM_COMPAT 0x0003
#define NVM_ID_LED_SETTINGS 0x0004
#define NVM_INIT_CONTROL2_REG 0x000F
#define NVM_INIT_CONTROL3_PORT_B 0x0014
@@ -644,9 +643,6 @@
/* Mask bits for fields in Word 0x1a of the NVM */
#define NVM_WORD1A_ASPM_MASK 0x000C
-/* Mask bits for fields in Word 0x03 of the EEPROM */
-#define NVM_COMPAT_LOM 0x0800
-
/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
#define NVM_SUM 0xBABA
diff --git a/trunk/drivers/net/e1000e/lib.c b/trunk/drivers/net/e1000e/lib.c
index 0fd4eb5ac5fb..df4a27922931 100644
--- a/trunk/drivers/net/e1000e/lib.c
+++ b/trunk/drivers/net/e1000e/lib.c
@@ -183,16 +183,6 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
u16 offset, nvm_alt_mac_addr_offset, nvm_data;
u8 alt_mac_addr[ETH_ALEN];
- ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data);
- if (ret_val)
- goto out;
-
- /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */
- if (!((nvm_data & NVM_COMPAT_LOM) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)))
- goto out;
-
ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
&nvm_alt_mac_addr_offset);
if (ret_val) {
diff --git a/trunk/drivers/net/ehea/ehea.h b/trunk/drivers/net/ehea/ehea.h
index 1846623c6ae6..99a929964e3c 100644
--- a/trunk/drivers/net/ehea/ehea.h
+++ b/trunk/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
#include
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0106"
+#define DRV_VERSION "EHEA_0105"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
@@ -400,7 +400,6 @@ struct ehea_port_res {
u32 poll_counter;
struct net_lro_mgr lro_mgr;
struct net_lro_desc lro_desc[MAX_LRO_DESCRIPTORS];
- int sq_restart_flag;
};
diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c
index a333b42111b8..897719b49f96 100644
--- a/trunk/drivers/net/ehea/ehea_main.c
+++ b/trunk/drivers/net/ehea/ehea_main.c
@@ -776,53 +776,6 @@ static int ehea_proc_rwqes(struct net_device *dev,
return processed;
}
-#define SWQE_RESTART_CHECK 0xdeadbeaff00d0000ull
-
-static void reset_sq_restart_flag(struct ehea_port *port)
-{
- int i;
-
- for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
- struct ehea_port_res *pr = &port->port_res[i];
- pr->sq_restart_flag = 0;
- }
-}
-
-static void check_sqs(struct ehea_port *port)
-{
- struct ehea_swqe *swqe;
- int swqe_index;
- int i, k;
-
- for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
- struct ehea_port_res *pr = &port->port_res[i];
- k = 0;
- swqe = ehea_get_swqe(pr->qp, &swqe_index);
- memset(swqe, 0, SWQE_HEADER_SIZE);
- atomic_dec(&pr->swqe_avail);
-
- swqe->tx_control |= EHEA_SWQE_PURGE;
- swqe->wr_id = SWQE_RESTART_CHECK;
- swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION;
- swqe->tx_control |= EHEA_SWQE_IMM_DATA_PRESENT;
- swqe->immediate_data_length = 80;
-
- ehea_post_swqe(pr->qp, swqe);
-
- while (pr->sq_restart_flag == 0) {
- msleep(5);
- if (++k == 100) {
- ehea_error("HW/SW queues out of sync");
- ehea_schedule_port_reset(pr->port);
- return;
- }
- }
- }
-
- return;
-}
-
-
static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota)
{
struct sk_buff *skb;
@@ -840,13 +793,6 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota)
cqe_counter++;
rmb();
-
- if (cqe->wr_id == SWQE_RESTART_CHECK) {
- pr->sq_restart_flag = 1;
- swqe_av++;
- break;
- }
-
if (cqe->status & EHEA_CQE_STAT_ERR_MASK) {
ehea_error("Bad send completion status=0x%04X",
cqe->status);
@@ -2729,10 +2675,8 @@ static void ehea_flush_sq(struct ehea_port *port)
int k = 0;
while (atomic_read(&pr->swqe_avail) < swqe_max) {
msleep(5);
- if (++k == 20) {
- ehea_error("WARNING: sq not flushed completely");
+ if (++k == 20)
break;
- }
}
}
}
@@ -2973,7 +2917,6 @@ static void ehea_rereg_mrs(struct work_struct *work)
port_napi_disable(port);
mutex_unlock(&port->port_lock);
}
- reset_sq_restart_flag(port);
}
/* Unregister old memory region */
@@ -3008,7 +2951,6 @@ static void ehea_rereg_mrs(struct work_struct *work)
mutex_lock(&port->port_lock);
port_napi_enable(port);
ret = ehea_restart_qps(dev);
- check_sqs(port);
if (!ret)
netif_wake_queue(dev);
mutex_unlock(&port->port_lock);
diff --git a/trunk/drivers/net/ibmveth.c b/trunk/drivers/net/ibmveth.c
index 4734c939ad03..2602852cc55a 100644
--- a/trunk/drivers/net/ibmveth.c
+++ b/trunk/drivers/net/ibmveth.c
@@ -1113,8 +1113,7 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
struct ibmveth_adapter *adapter = netdev_priv(dev);
struct vio_dev *viodev = adapter->vdev;
int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH;
- int i, rc;
- int need_restart = 0;
+ int i;
if (new_mtu < IBMVETH_MAX_MTU)
return -EINVAL;
@@ -1128,32 +1127,35 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
/* Deactivate all the buffer pools so that the next loop can activate
only the buffer pools necessary to hold the new MTU */
- if (netif_running(adapter->netdev)) {
- need_restart = 1;
- adapter->pool_config = 1;
- ibmveth_close(adapter->netdev);
- adapter->pool_config = 0;
- }
+ for (i = 0; i < IbmVethNumBufferPools; i++)
+ if (adapter->rx_buff_pool[i].active) {
+ ibmveth_free_buffer_pool(adapter,
+ &adapter->rx_buff_pool[i]);
+ adapter->rx_buff_pool[i].active = 0;
+ }
/* Look for an active buffer pool that can hold the new MTU */
for(i = 0; irx_buff_pool[i].active = 1;
if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) {
- dev->mtu = new_mtu;
- vio_cmo_set_dev_desired(viodev,
+ if (netif_running(adapter->netdev)) {
+ adapter->pool_config = 1;
+ ibmveth_close(adapter->netdev);
+ adapter->pool_config = 0;
+ dev->mtu = new_mtu;
+ vio_cmo_set_dev_desired(viodev,
ibmveth_get_desired_dma
(viodev));
- if (need_restart) {
return ibmveth_open(adapter->netdev);
}
+ dev->mtu = new_mtu;
+ vio_cmo_set_dev_desired(viodev,
+ ibmveth_get_desired_dma
+ (viodev));
return 0;
}
}
-
- if (need_restart && (rc = ibmveth_open(adapter->netdev)))
- return rc;
-
return -EINVAL;
}
diff --git a/trunk/drivers/net/ll_temac_main.c b/trunk/drivers/net/ll_temac_main.c
index bdf2149e5296..c7b624711f5e 100644
--- a/trunk/drivers/net/ll_temac_main.c
+++ b/trunk/drivers/net/ll_temac_main.c
@@ -902,8 +902,8 @@ temac_poll_controller(struct net_device *ndev)
disable_irq(lp->tx_irq);
disable_irq(lp->rx_irq);
- ll_temac_rx_irq(lp->tx_irq, ndev);
- ll_temac_tx_irq(lp->rx_irq, ndev);
+ ll_temac_rx_irq(lp->tx_irq, lp);
+ ll_temac_tx_irq(lp->rx_irq, lp);
enable_irq(lp->tx_irq);
enable_irq(lp->rx_irq);
diff --git a/trunk/drivers/net/netxen/netxen_nic.h b/trunk/drivers/net/netxen/netxen_nic.h
index 6dca3574e355..ffa1b9ce1cc5 100644
--- a/trunk/drivers/net/netxen/netxen_nic.h
+++ b/trunk/drivers/net/netxen/netxen_nic.h
@@ -53,8 +53,8 @@
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 74
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.74"
+#define _NETXEN_NIC_LINUX_SUBVERSION 73
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.73"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c
index cabae7bb1fc6..c865dda2adf1 100644
--- a/trunk/drivers/net/netxen/netxen_nic_init.c
+++ b/trunk/drivers/net/netxen/netxen_nic_init.c
@@ -1805,6 +1805,8 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
netxen_ctx_msg msg = 0;
struct list_head *head;
+ spin_lock(&rds_ring->lock);
+
producer = rds_ring->producer;
head = &rds_ring->free_list;
@@ -1851,6 +1853,8 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
NETXEN_RCV_PRODUCER_OFFSET), msg);
}
}
+
+ spin_unlock(&rds_ring->lock);
}
static void
diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c
index cb30df106a2c..fd86e18604e6 100644
--- a/trunk/drivers/net/netxen/netxen_nic_main.c
+++ b/trunk/drivers/net/netxen/netxen_nic_main.c
@@ -2032,6 +2032,8 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
struct netxen_adapter *adapter = netdev_priv(netdev);
struct net_device_stats *stats = &netdev->stats;
+ memset(stats, 0, sizeof(*stats));
+
stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
stats->tx_packets = adapter->stats.xmitfinished;
stats->rx_bytes = adapter->stats.rxbytes;
diff --git a/trunk/drivers/net/pxa168_eth.c b/trunk/drivers/net/pxa168_eth.c
deleted file mode 100644
index ecc64d750cce..000000000000
--- a/trunk/drivers/net/pxa168_eth.c
+++ /dev/null
@@ -1,1666 +0,0 @@
-/*
- * PXA168 ethernet driver.
- * Most of the code is derived from mv643xx ethernet driver.
- *
- * Copyright (C) 2010 Marvell International Ltd.
- * Sachin Sanap
- * Philip Rakity
- * Mark Brown
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define DRIVER_NAME "pxa168-eth"
-#define DRIVER_VERSION "0.3"
-
-/*
- * Registers
- */
-
-#define PHY_ADDRESS 0x0000
-#define SMI 0x0010
-#define PORT_CONFIG 0x0400
-#define PORT_CONFIG_EXT 0x0408
-#define PORT_COMMAND 0x0410
-#define PORT_STATUS 0x0418
-#define HTPR 0x0428
-#define SDMA_CONFIG 0x0440
-#define SDMA_CMD 0x0448
-#define INT_CAUSE 0x0450
-#define INT_W_CLEAR 0x0454
-#define INT_MASK 0x0458
-#define ETH_F_RX_DESC_0 0x0480
-#define ETH_C_RX_DESC_0 0x04A0
-#define ETH_C_TX_DESC_1 0x04E4
-
-/* smi register */
-#define SMI_BUSY (1 << 28) /* 0 - Write, 1 - Read */
-#define SMI_R_VALID (1 << 27) /* 0 - Write, 1 - Read */
-#define SMI_OP_W (0 << 26) /* Write operation */
-#define SMI_OP_R (1 << 26) /* Read operation */
-
-#define PHY_WAIT_ITERATIONS 10
-
-#define PXA168_ETH_PHY_ADDR_DEFAULT 0
-/* RX & TX descriptor command */
-#define BUF_OWNED_BY_DMA (1 << 31)
-
-/* RX descriptor status */
-#define RX_EN_INT (1 << 23)
-#define RX_FIRST_DESC (1 << 17)
-#define RX_LAST_DESC (1 << 16)
-#define RX_ERROR (1 << 15)
-
-/* TX descriptor command */
-#define TX_EN_INT (1 << 23)
-#define TX_GEN_CRC (1 << 22)
-#define TX_ZERO_PADDING (1 << 18)
-#define TX_FIRST_DESC (1 << 17)
-#define TX_LAST_DESC (1 << 16)
-#define TX_ERROR (1 << 15)
-
-/* SDMA_CMD */
-#define SDMA_CMD_AT (1 << 31)
-#define SDMA_CMD_TXDL (1 << 24)
-#define SDMA_CMD_TXDH (1 << 23)
-#define SDMA_CMD_AR (1 << 15)
-#define SDMA_CMD_ERD (1 << 7)
-
-/* Bit definitions of the Port Config Reg */
-#define PCR_HS (1 << 12)
-#define PCR_EN (1 << 7)
-#define PCR_PM (1 << 0)
-
-/* Bit definitions of the Port Config Extend Reg */
-#define PCXR_2BSM (1 << 28)
-#define PCXR_DSCP_EN (1 << 21)
-#define PCXR_MFL_1518 (0 << 14)
-#define PCXR_MFL_1536 (1 << 14)
-#define PCXR_MFL_2048 (2 << 14)
-#define PCXR_MFL_64K (3 << 14)
-#define PCXR_FLP (1 << 11)
-#define PCXR_PRIO_TX_OFF 3
-#define PCXR_TX_HIGH_PRI (7 << PCXR_PRIO_TX_OFF)
-
-/* Bit definitions of the SDMA Config Reg */
-#define SDCR_BSZ_OFF 12
-#define SDCR_BSZ8 (3 << SDCR_BSZ_OFF)
-#define SDCR_BSZ4 (2 << SDCR_BSZ_OFF)
-#define SDCR_BSZ2 (1 << SDCR_BSZ_OFF)
-#define SDCR_BSZ1 (0 << SDCR_BSZ_OFF)
-#define SDCR_BLMR (1 << 6)
-#define SDCR_BLMT (1 << 7)
-#define SDCR_RIFB (1 << 9)
-#define SDCR_RC_OFF 2
-#define SDCR_RC_MAX_RETRANS (0xf << SDCR_RC_OFF)
-
-/*
- * Bit definitions of the Interrupt Cause Reg
- * and Interrupt MASK Reg is the same
- */
-#define ICR_RXBUF (1 << 0)
-#define ICR_TXBUF_H (1 << 2)
-#define ICR_TXBUF_L (1 << 3)
-#define ICR_TXEND_H (1 << 6)
-#define ICR_TXEND_L (1 << 7)
-#define ICR_RXERR (1 << 8)
-#define ICR_TXERR_H (1 << 10)
-#define ICR_TXERR_L (1 << 11)
-#define ICR_TX_UDR (1 << 13)
-#define ICR_MII_CH (1 << 28)
-
-#define ALL_INTS (ICR_TXBUF_H | ICR_TXBUF_L | ICR_TX_UDR |\
- ICR_TXERR_H | ICR_TXERR_L |\
- ICR_TXEND_H | ICR_TXEND_L |\
- ICR_RXBUF | ICR_RXERR | ICR_MII_CH)
-
-#define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */
-
-#define NUM_RX_DESCS 64
-#define NUM_TX_DESCS 64
-
-#define HASH_ADD 0
-#define HASH_DELETE 1
-#define HASH_ADDR_TABLE_SIZE 0x4000 /* 16K (1/2K address - PCR_HS == 1) */
-#define HOP_NUMBER 12
-
-/* Bit definitions for Port status */
-#define PORT_SPEED_100 (1 << 0)
-#define FULL_DUPLEX (1 << 1)
-#define FLOW_CONTROL_ENABLED (1 << 2)
-#define LINK_UP (1 << 3)
-
-/* Bit definitions for work to be done */
-#define WORK_LINK (1 << 0)
-#define WORK_TX_DONE (1 << 1)
-
-/*
- * Misc definitions.
- */
-#define SKB_DMA_REALIGN ((PAGE_SIZE - NET_SKB_PAD) % SMP_CACHE_BYTES)
-
-struct rx_desc {
- u32 cmd_sts; /* Descriptor command status */
- u16 byte_cnt; /* Descriptor buffer byte count */
- u16 buf_size; /* Buffer size */
- u32 buf_ptr; /* Descriptor buffer pointer */
- u32 next_desc_ptr; /* Next descriptor pointer */
-};
-
-struct tx_desc {
- u32 cmd_sts; /* Command/status field */
- u16 reserved;
- u16 byte_cnt; /* buffer byte count */
- u32 buf_ptr; /* pointer to buffer for this descriptor */
- u32 next_desc_ptr; /* Pointer to next descriptor */
-};
-
-struct pxa168_eth_private {
- int port_num; /* User Ethernet port number */
-
- int rx_resource_err; /* Rx ring resource error flag */
-
- /* Next available and first returning Rx resource */
- int rx_curr_desc_q, rx_used_desc_q;
-
- /* Next available and first returning Tx resource */
- int tx_curr_desc_q, tx_used_desc_q;
-
- struct rx_desc *p_rx_desc_area;
- dma_addr_t rx_desc_dma;
- int rx_desc_area_size;
- struct sk_buff **rx_skb;
-
- struct tx_desc *p_tx_desc_area;
- dma_addr_t tx_desc_dma;
- int tx_desc_area_size;
- struct sk_buff **tx_skb;
-
- struct work_struct tx_timeout_task;
-
- struct net_device *dev;
- struct napi_struct napi;
- u8 work_todo;
- int skb_size;
-
- struct net_device_stats stats;
- /* Size of Tx Ring per queue */
- int tx_ring_size;
- /* Number of tx descriptors in use */
- int tx_desc_count;
- /* Size of Rx Ring per queue */
- int rx_ring_size;
- /* Number of rx descriptors in use */
- int rx_desc_count;
-
- /*
- * Used in case RX Ring is empty, which can occur when
- * system does not have resources (skb's)
- */
- struct timer_list timeout;
- struct mii_bus *smi_bus;
- struct phy_device *phy;
-
- /* clock */
- struct clk *clk;
- struct pxa168_eth_platform_data *pd;
- /*
- * Ethernet controller base address.
- */
- void __iomem *base;
-
- /* Pointer to the hardware address filter table */
- void *htpr;
- dma_addr_t htpr_dma;
-};
-
-struct addr_table_entry {
- __le32 lo;
- __le32 hi;
-};
-
-/* Bit fields of a Hash Table Entry */
-enum hash_table_entry {
- HASH_ENTRY_VALID = 1,
- SKIP = 2,
- HASH_ENTRY_RECEIVE_DISCARD = 4,
- HASH_ENTRY_RECEIVE_DISCARD_BIT = 2
-};
-
-static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
-static int pxa168_set_settings(struct net_device *dev, struct ethtool_cmd *cmd);
-static int pxa168_init_hw(struct pxa168_eth_private *pep);
-static void eth_port_reset(struct net_device *dev);
-static void eth_port_start(struct net_device *dev);
-static int pxa168_eth_open(struct net_device *dev);
-static int pxa168_eth_stop(struct net_device *dev);
-static int ethernet_phy_setup(struct net_device *dev);
-
-static inline u32 rdl(struct pxa168_eth_private *pep, int offset)
-{
- return readl(pep->base + offset);
-}
-
-static inline void wrl(struct pxa168_eth_private *pep, int offset, u32 data)
-{
- writel(data, pep->base + offset);
-}
-
-static void abort_dma(struct pxa168_eth_private *pep)
-{
- int delay;
- int max_retries = 40;
-
- do {
- wrl(pep, SDMA_CMD, SDMA_CMD_AR | SDMA_CMD_AT);
- udelay(100);
-
- delay = 10;
- while ((rdl(pep, SDMA_CMD) & (SDMA_CMD_AR | SDMA_CMD_AT))
- && delay-- > 0) {
- udelay(10);
- }
- } while (max_retries-- > 0 && delay <= 0);
-
- if (max_retries <= 0)
- printk(KERN_ERR "%s : DMA Stuck\n", __func__);
-}
-
-static int ethernet_phy_get(struct pxa168_eth_private *pep)
-{
- unsigned int reg_data;
-
- reg_data = rdl(pep, PHY_ADDRESS);
-
- return (reg_data >> (5 * pep->port_num)) & 0x1f;
-}
-
-static void ethernet_phy_set_addr(struct pxa168_eth_private *pep, int phy_addr)
-{
- u32 reg_data;
- int addr_shift = 5 * pep->port_num;
-
- reg_data = rdl(pep, PHY_ADDRESS);
- reg_data &= ~(0x1f << addr_shift);
- reg_data |= (phy_addr & 0x1f) << addr_shift;
- wrl(pep, PHY_ADDRESS, reg_data);
-}
-
-static void ethernet_phy_reset(struct pxa168_eth_private *pep)
-{
- int data;
-
- data = phy_read(pep->phy, MII_BMCR);
- if (data < 0)
- return;
-
- data |= BMCR_RESET;
- if (phy_write(pep->phy, MII_BMCR, data) < 0)
- return;
-
- do {
- data = phy_read(pep->phy, MII_BMCR);
- } while (data >= 0 && data & BMCR_RESET);
-}
-
-static void rxq_refill(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- struct sk_buff *skb;
- struct rx_desc *p_used_rx_desc;
- int used_rx_desc;
-
- while (pep->rx_desc_count < pep->rx_ring_size) {
- int size;
-
- skb = dev_alloc_skb(pep->skb_size);
- if (!skb)
- break;
- if (SKB_DMA_REALIGN)
- skb_reserve(skb, SKB_DMA_REALIGN);
- pep->rx_desc_count++;
- /* Get 'used' Rx descriptor */
- used_rx_desc = pep->rx_used_desc_q;
- p_used_rx_desc = &pep->p_rx_desc_area[used_rx_desc];
- size = skb->end - skb->data;
- p_used_rx_desc->buf_ptr = dma_map_single(NULL,
- skb->data,
- size,
- DMA_FROM_DEVICE);
- p_used_rx_desc->buf_size = size;
- pep->rx_skb[used_rx_desc] = skb;
-
- /* Return the descriptor to DMA ownership */
- wmb();
- p_used_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT;
- wmb();
-
- /* Move the used descriptor pointer to the next descriptor */
- pep->rx_used_desc_q = (used_rx_desc + 1) % pep->rx_ring_size;
-
- /* Any Rx return cancels the Rx resource error status */
- pep->rx_resource_err = 0;
-
- skb_reserve(skb, ETH_HW_IP_ALIGN);
- }
-
- /*
- * If RX ring is empty of SKB, set a timer to try allocating
- * again at a later time.
- */
- if (pep->rx_desc_count == 0) {
- pep->timeout.expires = jiffies + (HZ / 10);
- add_timer(&pep->timeout);
- }
-}
-
-static inline void rxq_refill_timer_wrapper(unsigned long data)
-{
- struct pxa168_eth_private *pep = (void *)data;
- napi_schedule(&pep->napi);
-}
-
-static inline u8 flip_8_bits(u8 x)
-{
- return (((x) & 0x01) << 3) | (((x) & 0x02) << 1)
- | (((x) & 0x04) >> 1) | (((x) & 0x08) >> 3)
- | (((x) & 0x10) << 3) | (((x) & 0x20) << 1)
- | (((x) & 0x40) >> 1) | (((x) & 0x80) >> 3);
-}
-
-static void nibble_swap_every_byte(unsigned char *mac_addr)
-{
- int i;
- for (i = 0; i < ETH_ALEN; i++) {
- mac_addr[i] = ((mac_addr[i] & 0x0f) << 4) |
- ((mac_addr[i] & 0xf0) >> 4);
- }
-}
-
-static void inverse_every_nibble(unsigned char *mac_addr)
-{
- int i;
- for (i = 0; i < ETH_ALEN; i++)
- mac_addr[i] = flip_8_bits(mac_addr[i]);
-}
-
-/*
- * ----------------------------------------------------------------------------
- * This function will calculate the hash function of the address.
- * Inputs
- * mac_addr_orig - MAC address.
- * Outputs
- * return the calculated entry.
- */
-static u32 hash_function(unsigned char *mac_addr_orig)
-{
- u32 hash_result;
- u32 addr0;
- u32 addr1;
- u32 addr2;
- u32 addr3;
- unsigned char mac_addr[ETH_ALEN];
-
- /* Make a copy of MAC address since we are going to performe bit
- * operations on it
- */
- memcpy(mac_addr, mac_addr_orig, ETH_ALEN);
-
- nibble_swap_every_byte(mac_addr);
- inverse_every_nibble(mac_addr);
-
- addr0 = (mac_addr[5] >> 2) & 0x3f;
- addr1 = (mac_addr[5] & 0x03) | (((mac_addr[4] & 0x7f)) << 2);
- addr2 = ((mac_addr[4] & 0x80) >> 7) | mac_addr[3] << 1;
- addr3 = (mac_addr[2] & 0xff) | ((mac_addr[1] & 1) << 8);
-
- hash_result = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);
- hash_result = hash_result & 0x07ff;
- return hash_result;
-}
-
-/*
- * ----------------------------------------------------------------------------
- * This function will add/del an entry to the address table.
- * Inputs
- * pep - ETHERNET .
- * mac_addr - MAC address.
- * skip - if 1, skip this address.Used in case of deleting an entry which is a
- * part of chain in the hash table.We cant just delete the entry since
- * that will break the chain.We need to defragment the tables time to
- * time.
- * rd - 0 Discard packet upon match.
- * - 1 Receive packet upon match.
- * Outputs
- * address table entry is added/deleted.
- * 0 if success.
- * -ENOSPC if table full
- */
-static int add_del_hash_entry(struct pxa168_eth_private *pep,
- unsigned char *mac_addr,
- u32 rd, u32 skip, int del)
-{
- struct addr_table_entry *entry, *start;
- u32 new_high;
- u32 new_low;
- u32 i;
-
- new_low = (((mac_addr[1] >> 4) & 0xf) << 15)
- | (((mac_addr[1] >> 0) & 0xf) << 11)
- | (((mac_addr[0] >> 4) & 0xf) << 7)
- | (((mac_addr[0] >> 0) & 0xf) << 3)
- | (((mac_addr[3] >> 4) & 0x1) << 31)
- | (((mac_addr[3] >> 0) & 0xf) << 27)
- | (((mac_addr[2] >> 4) & 0xf) << 23)
- | (((mac_addr[2] >> 0) & 0xf) << 19)
- | (skip << SKIP) | (rd << HASH_ENTRY_RECEIVE_DISCARD_BIT)
- | HASH_ENTRY_VALID;
-
- new_high = (((mac_addr[5] >> 4) & 0xf) << 15)
- | (((mac_addr[5] >> 0) & 0xf) << 11)
- | (((mac_addr[4] >> 4) & 0xf) << 7)
- | (((mac_addr[4] >> 0) & 0xf) << 3)
- | (((mac_addr[3] >> 5) & 0x7) << 0);
-
- /*
- * Pick the appropriate table, start scanning for free/reusable
- * entries at the index obtained by hashing the specified MAC address
- */
- start = (struct addr_table_entry *)(pep->htpr);
- entry = start + hash_function(mac_addr);
- for (i = 0; i < HOP_NUMBER; i++) {
- if (!(le32_to_cpu(entry->lo) & HASH_ENTRY_VALID)) {
- break;
- } else {
- /* if same address put in same position */
- if (((le32_to_cpu(entry->lo) & 0xfffffff8) ==
- (new_low & 0xfffffff8)) &&
- (le32_to_cpu(entry->hi) == new_high)) {
- break;
- }
- }
- if (entry == start + 0x7ff)
- entry = start;
- else
- entry++;
- }
-
- if (((le32_to_cpu(entry->lo) & 0xfffffff8) != (new_low & 0xfffffff8)) &&
- (le32_to_cpu(entry->hi) != new_high) && del)
- return 0;
-
- if (i == HOP_NUMBER) {
- if (!del) {
- printk(KERN_INFO "%s: table section is full, need to "
- "move to 16kB implementation?\n",
- __FILE__);
- return -ENOSPC;
- } else
- return 0;
- }
-
- /*
- * Update the selected entry
- */
- if (del) {
- entry->hi = 0;
- entry->lo = 0;
- } else {
- entry->hi = cpu_to_le32(new_high);
- entry->lo = cpu_to_le32(new_low);
- }
-
- return 0;
-}
-
-/*
- * ----------------------------------------------------------------------------
- * Create an addressTable entry from MAC address info
- * found in the specifed net_device struct
- *
- * Input : pointer to ethernet interface network device structure
- * Output : N/A
- */
-static void update_hash_table_mac_address(struct pxa168_eth_private *pep,
- unsigned char *oaddr,
- unsigned char *addr)
-{
- /* Delete old entry */
- if (oaddr)
- add_del_hash_entry(pep, oaddr, 1, 0, HASH_DELETE);
- /* Add new entry */
- add_del_hash_entry(pep, addr, 1, 0, HASH_ADD);
-}
-
-static int init_hash_table(struct pxa168_eth_private *pep)
-{
- /*
- * Hardware expects CPU to build a hash table based on a predefined
- * hash function and populate it based on hardware address. The
- * location of the hash table is identified by 32-bit pointer stored
- * in HTPR internal register. Two possible sizes exists for the hash
- * table 8kB (256kB of DRAM required (4 x 64 kB banks)) and 1/2kB
- * (16kB of DRAM required (4 x 4 kB banks)).We currently only support
- * 1/2kB.
- */
- /* TODO: Add support for 8kB hash table and alternative hash
- * function.Driver can dynamically switch to them if the 1/2kB hash
- * table is full.
- */
- if (pep->htpr == NULL) {
- pep->htpr = dma_alloc_coherent(pep->dev->dev.parent,
- HASH_ADDR_TABLE_SIZE,
- &pep->htpr_dma, GFP_KERNEL);
- if (pep->htpr == NULL)
- return -ENOMEM;
- }
- memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE);
- wrl(pep, HTPR, pep->htpr_dma);
- return 0;
-}
-
-static void pxa168_eth_set_rx_mode(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- struct netdev_hw_addr *ha;
- u32 val;
-
- val = rdl(pep, PORT_CONFIG);
- if (dev->flags & IFF_PROMISC)
- val |= PCR_PM;
- else
- val &= ~PCR_PM;
- wrl(pep, PORT_CONFIG, val);
-
- /*
- * Remove the old list of MAC address and add dev->addr
- * and multicast address.
- */
- memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE);
- update_hash_table_mac_address(pep, NULL, dev->dev_addr);
-
- netdev_for_each_mc_addr(ha, dev)
- update_hash_table_mac_address(pep, NULL, ha->addr);
-}
-
-static int pxa168_eth_set_mac_address(struct net_device *dev, void *addr)
-{
- struct sockaddr *sa = addr;
- struct pxa168_eth_private *pep = netdev_priv(dev);
- unsigned char oldMac[ETH_ALEN];
-
- if (!is_valid_ether_addr(sa->sa_data))
- return -EINVAL;
- memcpy(oldMac, dev->dev_addr, ETH_ALEN);
- memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
- netif_addr_lock_bh(dev);
- update_hash_table_mac_address(pep, oldMac, dev->dev_addr);
- netif_addr_unlock_bh(dev);
- return 0;
-}
-
-static void eth_port_start(struct net_device *dev)
-{
- unsigned int val = 0;
- struct pxa168_eth_private *pep = netdev_priv(dev);
- int tx_curr_desc, rx_curr_desc;
-
- /* Perform PHY reset, if there is a PHY. */
- if (pep->phy != NULL) {
- struct ethtool_cmd cmd;
-
- pxa168_get_settings(pep->dev, &cmd);
- ethernet_phy_reset(pep);
- pxa168_set_settings(pep->dev, &cmd);
- }
-
- /* Assignment of Tx CTRP of given queue */
- tx_curr_desc = pep->tx_curr_desc_q;
- wrl(pep, ETH_C_TX_DESC_1,
- (u32) ((struct tx_desc *)pep->tx_desc_dma + tx_curr_desc));
-
- /* Assignment of Rx CRDP of given queue */
- rx_curr_desc = pep->rx_curr_desc_q;
- wrl(pep, ETH_C_RX_DESC_0,
- (u32) ((struct rx_desc *)pep->rx_desc_dma + rx_curr_desc));
-
- wrl(pep, ETH_F_RX_DESC_0,
- (u32) ((struct rx_desc *)pep->rx_desc_dma + rx_curr_desc));
-
- /* Clear all interrupts */
- wrl(pep, INT_CAUSE, 0);
-
- /* Enable all interrupts for receive, transmit and error. */
- wrl(pep, INT_MASK, ALL_INTS);
-
- val = rdl(pep, PORT_CONFIG);
- val |= PCR_EN;
- wrl(pep, PORT_CONFIG, val);
-
- /* Start RX DMA engine */
- val = rdl(pep, SDMA_CMD);
- val |= SDMA_CMD_ERD;
- wrl(pep, SDMA_CMD, val);
-}
-
-static void eth_port_reset(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- unsigned int val = 0;
-
- /* Stop all interrupts for receive, transmit and error. */
- wrl(pep, INT_MASK, 0);
-
- /* Clear all interrupts */
- wrl(pep, INT_CAUSE, 0);
-
- /* Stop RX DMA */
- val = rdl(pep, SDMA_CMD);
- val &= ~SDMA_CMD_ERD; /* abort dma command */
-
- /* Abort any transmit and receive operations and put DMA
- * in idle state.
- */
- abort_dma(pep);
-
- /* Disable port */
- val = rdl(pep, PORT_CONFIG);
- val &= ~PCR_EN;
- wrl(pep, PORT_CONFIG, val);
-}
-
-/*
- * txq_reclaim - Free the tx desc data for completed descriptors
- * If force is non-zero, frees uncompleted descriptors as well
- */
-static int txq_reclaim(struct net_device *dev, int force)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- struct tx_desc *desc;
- u32 cmd_sts;
- struct sk_buff *skb;
- int tx_index;
- dma_addr_t addr;
- int count;
- int released = 0;
-
- netif_tx_lock(dev);
-
- pep->work_todo &= ~WORK_TX_DONE;
- while (pep->tx_desc_count > 0) {
- tx_index = pep->tx_used_desc_q;
- desc = &pep->p_tx_desc_area[tx_index];
- cmd_sts = desc->cmd_sts;
- if (!force && (cmd_sts & BUF_OWNED_BY_DMA)) {
- if (released > 0) {
- goto txq_reclaim_end;
- } else {
- released = -1;
- goto txq_reclaim_end;
- }
- }
- pep->tx_used_desc_q = (tx_index + 1) % pep->tx_ring_size;
- pep->tx_desc_count--;
- addr = desc->buf_ptr;
- count = desc->byte_cnt;
- skb = pep->tx_skb[tx_index];
- if (skb)
- pep->tx_skb[tx_index] = NULL;
-
- if (cmd_sts & TX_ERROR) {
- if (net_ratelimit())
- printk(KERN_ERR "%s: Error in TX\n", dev->name);
- dev->stats.tx_errors++;
- }
- dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);
- if (skb)
- dev_kfree_skb_irq(skb);
- released++;
- }
-txq_reclaim_end:
- netif_tx_unlock(dev);
- return released;
-}
-
-static void pxa168_eth_tx_timeout(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
-
- printk(KERN_INFO "%s: TX timeout desc_count %d\n",
- dev->name, pep->tx_desc_count);
-
- schedule_work(&pep->tx_timeout_task);
-}
-
-static void pxa168_eth_tx_timeout_task(struct work_struct *work)
-{
- struct pxa168_eth_private *pep = container_of(work,
- struct pxa168_eth_private,
- tx_timeout_task);
- struct net_device *dev = pep->dev;
- pxa168_eth_stop(dev);
- pxa168_eth_open(dev);
-}
-
-static int rxq_process(struct net_device *dev, int budget)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- unsigned int received_packets = 0;
- struct sk_buff *skb;
-
- while (budget-- > 0) {
- int rx_next_curr_desc, rx_curr_desc, rx_used_desc;
- struct rx_desc *rx_desc;
- unsigned int cmd_sts;
-
- /* Do not process Rx ring in case of Rx ring resource error */
- if (pep->rx_resource_err)
- break;
- rx_curr_desc = pep->rx_curr_desc_q;
- rx_used_desc = pep->rx_used_desc_q;
- rx_desc = &pep->p_rx_desc_area[rx_curr_desc];
- cmd_sts = rx_desc->cmd_sts;
- rmb();
- if (cmd_sts & (BUF_OWNED_BY_DMA))
- break;
- skb = pep->rx_skb[rx_curr_desc];
- pep->rx_skb[rx_curr_desc] = NULL;
-
- rx_next_curr_desc = (rx_curr_desc + 1) % pep->rx_ring_size;
- pep->rx_curr_desc_q = rx_next_curr_desc;
-
- /* Rx descriptors exhausted. */
- /* Set the Rx ring resource error flag */
- if (rx_next_curr_desc == rx_used_desc)
- pep->rx_resource_err = 1;
- pep->rx_desc_count--;
- dma_unmap_single(NULL, rx_desc->buf_ptr,
- rx_desc->buf_size,
- DMA_FROM_DEVICE);
- received_packets++;
- /*
- * Update statistics.
- * Note byte count includes 4 byte CRC count
- */
- stats->rx_packets++;
- stats->rx_bytes += rx_desc->byte_cnt;
- /*
- * In case received a packet without first / last bits on OR
- * the error summary bit is on, the packets needs to be droped.
- */
- if (((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
- (RX_FIRST_DESC | RX_LAST_DESC))
- || (cmd_sts & RX_ERROR)) {
-
- stats->rx_dropped++;
- if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
- (RX_FIRST_DESC | RX_LAST_DESC)) {
- if (net_ratelimit())
- printk(KERN_ERR
- "%s: Rx pkt on multiple desc\n",
- dev->name);
- }
- if (cmd_sts & RX_ERROR)
- stats->rx_errors++;
- dev_kfree_skb_irq(skb);
- } else {
- /*
- * The -4 is for the CRC in the trailer of the
- * received packet
- */
- skb_put(skb, rx_desc->byte_cnt - 4);
- skb->protocol = eth_type_trans(skb, dev);
- netif_receive_skb(skb);
- }
- dev->last_rx = jiffies;
- }
- /* Fill RX ring with skb's */
- rxq_refill(dev);
- return received_packets;
-}
-
-static int pxa168_eth_collect_events(struct pxa168_eth_private *pep,
- struct net_device *dev)
-{
- u32 icr;
- int ret = 0;
-
- icr = rdl(pep, INT_CAUSE);
- if (icr == 0)
- return IRQ_NONE;
-
- wrl(pep, INT_CAUSE, ~icr);
- if (icr & (ICR_TXBUF_H | ICR_TXBUF_L)) {
- pep->work_todo |= WORK_TX_DONE;
- ret = 1;
- }
- if (icr & ICR_RXBUF)
- ret = 1;
- if (icr & ICR_MII_CH) {
- pep->work_todo |= WORK_LINK;
- ret = 1;
- }
- return ret;
-}
-
-static void handle_link_event(struct pxa168_eth_private *pep)
-{
- struct net_device *dev = pep->dev;
- u32 port_status;
- int speed;
- int duplex;
- int fc;
-
- port_status = rdl(pep, PORT_STATUS);
- if (!(port_status & LINK_UP)) {
- if (netif_carrier_ok(dev)) {
- printk(KERN_INFO "%s: link down\n", dev->name);
- netif_carrier_off(dev);
- txq_reclaim(dev, 1);
- }
- return;
- }
- if (port_status & PORT_SPEED_100)
- speed = 100;
- else
- speed = 10;
-
- duplex = (port_status & FULL_DUPLEX) ? 1 : 0;
- fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0;
- printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
- "flow control %sabled\n", dev->name,
- speed, duplex ? "full" : "half", fc ? "en" : "dis");
- if (!netif_carrier_ok(dev))
- netif_carrier_on(dev);
-}
-
-static irqreturn_t pxa168_eth_int_handler(int irq, void *dev_id)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct pxa168_eth_private *pep = netdev_priv(dev);
-
- if (unlikely(!pxa168_eth_collect_events(pep, dev)))
- return IRQ_NONE;
- /* Disable interrupts */
- wrl(pep, INT_MASK, 0);
- napi_schedule(&pep->napi);
- return IRQ_HANDLED;
-}
-
-static void pxa168_eth_recalc_skb_size(struct pxa168_eth_private *pep)
-{
- int skb_size;
-
- /*
- * Reserve 2+14 bytes for an ethernet header (the hardware
- * automatically prepends 2 bytes of dummy data to each
- * received packet), 16 bytes for up to four VLAN tags, and
- * 4 bytes for the trailing FCS -- 36 bytes total.
- */
- skb_size = pep->dev->mtu + 36;
-
- /*
- * Make sure that the skb size is a multiple of 8 bytes, as
- * the lower three bits of the receive descriptor's buffer
- * size field are ignored by the hardware.
- */
- pep->skb_size = (skb_size + 7) & ~7;
-
- /*
- * If NET_SKB_PAD is smaller than a cache line,
- * netdev_alloc_skb() will cause skb->data to be misaligned
- * to a cache line boundary. If this is the case, include
- * some extra space to allow re-aligning the data area.
- */
- pep->skb_size += SKB_DMA_REALIGN;
-
-}
-
-static int set_port_config_ext(struct pxa168_eth_private *pep)
-{
- int skb_size;
-
- pxa168_eth_recalc_skb_size(pep);
- if (pep->skb_size <= 1518)
- skb_size = PCXR_MFL_1518;
- else if (pep->skb_size <= 1536)
- skb_size = PCXR_MFL_1536;
- else if (pep->skb_size <= 2048)
- skb_size = PCXR_MFL_2048;
- else
- skb_size = PCXR_MFL_64K;
-
- /* Extended Port Configuration */
- wrl(pep,
- PORT_CONFIG_EXT, PCXR_2BSM | /* Two byte prefix aligns IP hdr */
- PCXR_DSCP_EN | /* Enable DSCP in IP */
- skb_size | PCXR_FLP | /* do not force link pass */
- PCXR_TX_HIGH_PRI); /* Transmit - high priority queue */
-
- return 0;
-}
-
-static int pxa168_init_hw(struct pxa168_eth_private *pep)
-{
- int err = 0;
-
- /* Disable interrupts */
- wrl(pep, INT_MASK, 0);
- wrl(pep, INT_CAUSE, 0);
- /* Write to ICR to clear interrupts. */
- wrl(pep, INT_W_CLEAR, 0);
- /* Abort any transmit and receive operations and put DMA
- * in idle state.
- */
- abort_dma(pep);
- /* Initialize address hash table */
- err = init_hash_table(pep);
- if (err)
- return err;
- /* SDMA configuration */
- wrl(pep, SDMA_CONFIG, SDCR_BSZ8 | /* Burst size = 32 bytes */
- SDCR_RIFB | /* Rx interrupt on frame */
- SDCR_BLMT | /* Little endian transmit */
- SDCR_BLMR | /* Little endian receive */
- SDCR_RC_MAX_RETRANS); /* Max retransmit count */
- /* Port Configuration */
- wrl(pep, PORT_CONFIG, PCR_HS); /* Hash size is 1/2kb */
- set_port_config_ext(pep);
-
- return err;
-}
-
-static int rxq_init(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- struct rx_desc *p_rx_desc;
- int size = 0, i = 0;
- int rx_desc_num = pep->rx_ring_size;
-
- /* Allocate RX skb rings */
- pep->rx_skb = kmalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size,
- GFP_KERNEL);
- if (!pep->rx_skb) {
- printk(KERN_ERR "%s: Cannot alloc RX skb ring\n", dev->name);
- return -ENOMEM;
- }
- /* Allocate RX ring */
- pep->rx_desc_count = 0;
- size = pep->rx_ring_size * sizeof(struct rx_desc);
- pep->rx_desc_area_size = size;
- pep->p_rx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size,
- &pep->rx_desc_dma, GFP_KERNEL);
- if (!pep->p_rx_desc_area) {
- printk(KERN_ERR "%s: Cannot alloc RX ring (size %d bytes)\n",
- dev->name, size);
- goto out;
- }
- memset((void *)pep->p_rx_desc_area, 0, size);
- /* initialize the next_desc_ptr links in the Rx descriptors ring */
- p_rx_desc = (struct rx_desc *)pep->p_rx_desc_area;
- for (i = 0; i < rx_desc_num; i++) {
- p_rx_desc[i].next_desc_ptr = pep->rx_desc_dma +
- ((i + 1) % rx_desc_num) * sizeof(struct rx_desc);
- }
- /* Save Rx desc pointer to driver struct. */
- pep->rx_curr_desc_q = 0;
- pep->rx_used_desc_q = 0;
- pep->rx_desc_area_size = rx_desc_num * sizeof(struct rx_desc);
- return 0;
-out:
- kfree(pep->rx_skb);
- return -ENOMEM;
-}
-
-static void rxq_deinit(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- int curr;
-
- /* Free preallocated skb's on RX rings */
- for (curr = 0; pep->rx_desc_count && curr < pep->rx_ring_size; curr++) {
- if (pep->rx_skb[curr]) {
- dev_kfree_skb(pep->rx_skb[curr]);
- pep->rx_desc_count--;
- }
- }
- if (pep->rx_desc_count)
- printk(KERN_ERR
- "Error in freeing Rx Ring. %d skb's still\n",
- pep->rx_desc_count);
- /* Free RX ring */
- if (pep->p_rx_desc_area)
- dma_free_coherent(pep->dev->dev.parent, pep->rx_desc_area_size,
- pep->p_rx_desc_area, pep->rx_desc_dma);
- kfree(pep->rx_skb);
-}
-
-static int txq_init(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- struct tx_desc *p_tx_desc;
- int size = 0, i = 0;
- int tx_desc_num = pep->tx_ring_size;
-
- pep->tx_skb = kmalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size,
- GFP_KERNEL);
- if (!pep->tx_skb) {
- printk(KERN_ERR "%s: Cannot alloc TX skb ring\n", dev->name);
- return -ENOMEM;
- }
- /* Allocate TX ring */
- pep->tx_desc_count = 0;
- size = pep->tx_ring_size * sizeof(struct tx_desc);
- pep->tx_desc_area_size = size;
- pep->p_tx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size,
- &pep->tx_desc_dma, GFP_KERNEL);
- if (!pep->p_tx_desc_area) {
- printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n",
- dev->name, size);
- goto out;
- }
- memset((void *)pep->p_tx_desc_area, 0, pep->tx_desc_area_size);
- /* Initialize the next_desc_ptr links in the Tx descriptors ring */
- p_tx_desc = (struct tx_desc *)pep->p_tx_desc_area;
- for (i = 0; i < tx_desc_num; i++) {
- p_tx_desc[i].next_desc_ptr = pep->tx_desc_dma +
- ((i + 1) % tx_desc_num) * sizeof(struct tx_desc);
- }
- pep->tx_curr_desc_q = 0;
- pep->tx_used_desc_q = 0;
- pep->tx_desc_area_size = tx_desc_num * sizeof(struct tx_desc);
- return 0;
-out:
- kfree(pep->tx_skb);
- return -ENOMEM;
-}
-
-static void txq_deinit(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
-
- /* Free outstanding skb's on TX ring */
- txq_reclaim(dev, 1);
- BUG_ON(pep->tx_used_desc_q != pep->tx_curr_desc_q);
- /* Free TX ring */
- if (pep->p_tx_desc_area)
- dma_free_coherent(pep->dev->dev.parent, pep->tx_desc_area_size,
- pep->p_tx_desc_area, pep->tx_desc_dma);
- kfree(pep->tx_skb);
-}
-
-static int pxa168_eth_open(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- int err;
-
- err = request_irq(dev->irq, pxa168_eth_int_handler,
- IRQF_DISABLED, dev->name, dev);
- if (err) {
- dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n");
- return -EAGAIN;
- }
- pep->rx_resource_err = 0;
- err = rxq_init(dev);
- if (err != 0)
- goto out_free_irq;
- err = txq_init(dev);
- if (err != 0)
- goto out_free_rx_skb;
- pep->rx_used_desc_q = 0;
- pep->rx_curr_desc_q = 0;
-
- /* Fill RX ring with skb's */
- rxq_refill(dev);
- pep->rx_used_desc_q = 0;
- pep->rx_curr_desc_q = 0;
- netif_carrier_off(dev);
- eth_port_start(dev);
- napi_enable(&pep->napi);
- return 0;
-out_free_rx_skb:
- rxq_deinit(dev);
-out_free_irq:
- free_irq(dev->irq, dev);
- return err;
-}
-
-static int pxa168_eth_stop(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- eth_port_reset(dev);
-
- /* Disable interrupts */
- wrl(pep, INT_MASK, 0);
- wrl(pep, INT_CAUSE, 0);
- /* Write to ICR to clear interrupts. */
- wrl(pep, INT_W_CLEAR, 0);
- napi_disable(&pep->napi);
- del_timer_sync(&pep->timeout);
- netif_carrier_off(dev);
- free_irq(dev->irq, dev);
- rxq_deinit(dev);
- txq_deinit(dev);
-
- return 0;
-}
-
-static int pxa168_eth_change_mtu(struct net_device *dev, int mtu)
-{
- int retval;
- struct pxa168_eth_private *pep = netdev_priv(dev);
-
- if ((mtu > 9500) || (mtu < 68))
- return -EINVAL;
-
- dev->mtu = mtu;
- retval = set_port_config_ext(pep);
-
- if (!netif_running(dev))
- return 0;
-
- /*
- * Stop and then re-open the interface. This will allocate RX
- * skbs of the new MTU.
- * There is a possible danger that the open will not succeed,
- * due to memory being full.
- */
- pxa168_eth_stop(dev);
- if (pxa168_eth_open(dev)) {
- dev_printk(KERN_ERR, &dev->dev,
- "fatal error on re-opening device after "
- "MTU change\n");
- }
-
- return 0;
-}
-
-static int eth_alloc_tx_desc_index(struct pxa168_eth_private *pep)
-{
- int tx_desc_curr;
-
- tx_desc_curr = pep->tx_curr_desc_q;
- pep->tx_curr_desc_q = (tx_desc_curr + 1) % pep->tx_ring_size;
- BUG_ON(pep->tx_curr_desc_q == pep->tx_used_desc_q);
- pep->tx_desc_count++;
-
- return tx_desc_curr;
-}
-
-static int pxa168_rx_poll(struct napi_struct *napi, int budget)
-{
- struct pxa168_eth_private *pep =
- container_of(napi, struct pxa168_eth_private, napi);
- struct net_device *dev = pep->dev;
- int work_done = 0;
-
- if (unlikely(pep->work_todo & WORK_LINK)) {
- pep->work_todo &= ~(WORK_LINK);
- handle_link_event(pep);
- }
- /*
- * We call txq_reclaim every time since in NAPI interupts are disabled
- * and due to this we miss the TX_DONE interrupt,which is not updated in
- * interrupt status register.
- */
- txq_reclaim(dev, 0);
- if (netif_queue_stopped(dev)
- && pep->tx_ring_size - pep->tx_desc_count > 1) {
- netif_wake_queue(dev);
- }
- work_done = rxq_process(dev, budget);
- if (work_done < budget) {
- napi_complete(napi);
- wrl(pep, INT_MASK, ALL_INTS);
- }
-
- return work_done;
-}
-
-static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- struct tx_desc *desc;
- int tx_index;
- int length;
-
- tx_index = eth_alloc_tx_desc_index(pep);
- desc = &pep->p_tx_desc_area[tx_index];
- length = skb->len;
- pep->tx_skb[tx_index] = skb;
- desc->byte_cnt = length;
- desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
- wmb();
- desc->cmd_sts = BUF_OWNED_BY_DMA | TX_GEN_CRC | TX_FIRST_DESC |
- TX_ZERO_PADDING | TX_LAST_DESC | TX_EN_INT;
- wmb();
- wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD);
-
- stats->tx_bytes += skb->len;
- stats->tx_packets++;
- dev->trans_start = jiffies;
- if (pep->tx_ring_size - pep->tx_desc_count <= 1) {
- /* We handled the current skb, but now we are out of space.*/
- netif_stop_queue(dev);
- }
-
- return NETDEV_TX_OK;
-}
-
-static int smi_wait_ready(struct pxa168_eth_private *pep)
-{
- int i = 0;
-
- /* wait for the SMI register to become available */
- for (i = 0; rdl(pep, SMI) & SMI_BUSY; i++) {
- if (i == PHY_WAIT_ITERATIONS)
- return -ETIMEDOUT;
- msleep(10);
- }
-
- return 0;
-}
-
-static int pxa168_smi_read(struct mii_bus *bus, int phy_addr, int regnum)
-{
- struct pxa168_eth_private *pep = bus->priv;
- int i = 0;
- int val;
-
- if (smi_wait_ready(pep)) {
- printk(KERN_WARNING "pxa168_eth: SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
- wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) | SMI_OP_R);
- /* now wait for the data to be valid */
- for (i = 0; !((val = rdl(pep, SMI)) & SMI_R_VALID); i++) {
- if (i == PHY_WAIT_ITERATIONS) {
- printk(KERN_WARNING
- "pxa168_eth: SMI bus read not valid\n");
- return -ENODEV;
- }
- msleep(10);
- }
-
- return val & 0xffff;
-}
-
-static int pxa168_smi_write(struct mii_bus *bus, int phy_addr, int regnum,
- u16 value)
-{
- struct pxa168_eth_private *pep = bus->priv;
-
- if (smi_wait_ready(pep)) {
- printk(KERN_WARNING "pxa168_eth: SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) |
- SMI_OP_W | (value & 0xffff));
-
- if (smi_wait_ready(pep)) {
- printk(KERN_ERR "pxa168_eth: SMI bus busy timeout\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int pxa168_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr,
- int cmd)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- if (pep->phy != NULL)
- return phy_mii_ioctl(pep->phy, if_mii(ifr), cmd);
-
- return -EOPNOTSUPP;
-}
-
-static struct phy_device *phy_scan(struct pxa168_eth_private *pep, int phy_addr)
-{
- struct mii_bus *bus = pep->smi_bus;
- struct phy_device *phydev;
- int start;
- int num;
- int i;
-
- if (phy_addr == PXA168_ETH_PHY_ADDR_DEFAULT) {
- /* Scan entire range */
- start = ethernet_phy_get(pep);
- num = 32;
- } else {
- /* Use phy addr specific to platform */
- start = phy_addr & 0x1f;
- num = 1;
- }
- phydev = NULL;
- for (i = 0; i < num; i++) {
- int addr = (start + i) & 0x1f;
- if (bus->phy_map[addr] == NULL)
- mdiobus_scan(bus, addr);
-
- if (phydev == NULL) {
- phydev = bus->phy_map[addr];
- if (phydev != NULL)
- ethernet_phy_set_addr(pep, addr);
- }
- }
-
- return phydev;
-}
-
-static void phy_init(struct pxa168_eth_private *pep, int speed, int duplex)
-{
- struct phy_device *phy = pep->phy;
- ethernet_phy_reset(pep);
-
- phy_attach(pep->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_MII);
-
- if (speed == 0) {
- phy->autoneg = AUTONEG_ENABLE;
- phy->speed = 0;
- phy->duplex = 0;
- phy->supported &= PHY_BASIC_FEATURES;
- phy->advertising = phy->supported | ADVERTISED_Autoneg;
- } else {
- phy->autoneg = AUTONEG_DISABLE;
- phy->advertising = 0;
- phy->speed = speed;
- phy->duplex = duplex;
- }
- phy_start_aneg(phy);
-}
-
-static int ethernet_phy_setup(struct net_device *dev)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
-
- if (pep->pd != NULL) {
- if (pep->pd->init)
- pep->pd->init();
- }
- pep->phy = phy_scan(pep, pep->pd->phy_addr & 0x1f);
- if (pep->phy != NULL)
- phy_init(pep, pep->pd->speed, pep->pd->duplex);
- update_hash_table_mac_address(pep, NULL, dev->dev_addr);
-
- return 0;
-}
-
-static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
- int err;
-
- err = phy_read_status(pep->phy);
- if (err == 0)
- err = phy_ethtool_gset(pep->phy, cmd);
-
- return err;
-}
-
-static int pxa168_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct pxa168_eth_private *pep = netdev_priv(dev);
-
- return phy_ethtool_sset(pep->phy, cmd);
-}
-
-static void pxa168_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strncpy(info->driver, DRIVER_NAME, 32);
- strncpy(info->version, DRIVER_VERSION, 32);
- strncpy(info->fw_version, "N/A", 32);
- strncpy(info->bus_info, "N/A", 32);
-}
-
-static u32 pxa168_get_link(struct net_device *dev)
-{
- return !!netif_carrier_ok(dev);
-}
-
-static const struct ethtool_ops pxa168_ethtool_ops = {
- .get_settings = pxa168_get_settings,
- .set_settings = pxa168_set_settings,
- .get_drvinfo = pxa168_get_drvinfo,
- .get_link = pxa168_get_link,
-};
-
-static const struct net_device_ops pxa168_eth_netdev_ops = {
- .ndo_open = pxa168_eth_open,
- .ndo_stop = pxa168_eth_stop,
- .ndo_start_xmit = pxa168_eth_start_xmit,
- .ndo_set_rx_mode = pxa168_eth_set_rx_mode,
- .ndo_set_mac_address = pxa168_eth_set_mac_address,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = pxa168_eth_do_ioctl,
- .ndo_change_mtu = pxa168_eth_change_mtu,
- .ndo_tx_timeout = pxa168_eth_tx_timeout,
-};
-
-static int pxa168_eth_probe(struct platform_device *pdev)
-{
- struct pxa168_eth_private *pep = NULL;
- struct net_device *dev = NULL;
- struct resource *res;
- struct clk *clk;
- int err;
-
- printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
-
- clk = clk_get(&pdev->dev, "MFUCLK");
- if (IS_ERR(clk)) {
- printk(KERN_ERR "%s: Fast Ethernet failed to get clock\n",
- DRIVER_NAME);
- return -ENODEV;
- }
- clk_enable(clk);
-
- dev = alloc_etherdev(sizeof(struct pxa168_eth_private));
- if (!dev) {
- err = -ENOMEM;
- goto out;
- }
-
- platform_set_drvdata(pdev, dev);
- pep = netdev_priv(dev);
- pep->dev = dev;
- pep->clk = clk;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- err = -ENODEV;
- goto out;
- }
- pep->base = ioremap(res->start, res->end - res->start + 1);
- if (pep->base == NULL) {
- err = -ENOMEM;
- goto out;
- }
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- BUG_ON(!res);
- dev->irq = res->start;
- dev->netdev_ops = &pxa168_eth_netdev_ops;
- dev->watchdog_timeo = 2 * HZ;
- dev->base_addr = 0;
- SET_ETHTOOL_OPS(dev, &pxa168_ethtool_ops);
-
- INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
-
- printk(KERN_INFO "%s:Using random mac address\n", DRIVER_NAME);
- random_ether_addr(dev->dev_addr);
-
- pep->pd = pdev->dev.platform_data;
- pep->rx_ring_size = NUM_RX_DESCS;
- if (pep->pd->rx_queue_size)
- pep->rx_ring_size = pep->pd->rx_queue_size;
-
- pep->tx_ring_size = NUM_TX_DESCS;
- if (pep->pd->tx_queue_size)
- pep->tx_ring_size = pep->pd->tx_queue_size;
-
- pep->port_num = pep->pd->port_number;
- /* Hardware supports only 3 ports */
- BUG_ON(pep->port_num > 2);
- netif_napi_add(dev, &pep->napi, pxa168_rx_poll, pep->rx_ring_size);
-
- memset(&pep->timeout, 0, sizeof(struct timer_list));
- init_timer(&pep->timeout);
- pep->timeout.function = rxq_refill_timer_wrapper;
- pep->timeout.data = (unsigned long)pep;
-
- pep->smi_bus = mdiobus_alloc();
- if (pep->smi_bus == NULL) {
- err = -ENOMEM;
- goto out;
- }
- pep->smi_bus->priv = pep;
- pep->smi_bus->name = "pxa168_eth smi";
- pep->smi_bus->read = pxa168_smi_read;
- pep->smi_bus->write = pxa168_smi_write;
- snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id);
- pep->smi_bus->parent = &pdev->dev;
- pep->smi_bus->phy_mask = 0xffffffff;
- if (mdiobus_register(pep->smi_bus) < 0) {
- err = -ENOMEM;
- goto out;
- }
- pxa168_init_hw(pep);
- err = ethernet_phy_setup(dev);
- if (err)
- goto out;
- SET_NETDEV_DEV(dev, &pdev->dev);
- err = register_netdev(dev);
- if (err)
- goto out;
- return 0;
-out:
- if (pep->clk) {
- clk_disable(pep->clk);
- clk_put(pep->clk);
- pep->clk = NULL;
- }
- if (pep->base) {
- iounmap(pep->base);
- pep->base = NULL;
- }
- if (dev)
- free_netdev(dev);
- return err;
-}
-
-static int pxa168_eth_remove(struct platform_device *pdev)
-{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct pxa168_eth_private *pep = netdev_priv(dev);
-
- if (pep->htpr) {
- dma_free_coherent(pep->dev->dev.parent, HASH_ADDR_TABLE_SIZE,
- pep->htpr, pep->htpr_dma);
- pep->htpr = NULL;
- }
- if (pep->clk) {
- clk_disable(pep->clk);
- clk_put(pep->clk);
- pep->clk = NULL;
- }
- if (pep->phy != NULL)
- phy_detach(pep->phy);
-
- iounmap(pep->base);
- pep->base = NULL;
- unregister_netdev(dev);
- flush_scheduled_work();
- free_netdev(dev);
- platform_set_drvdata(pdev, NULL);
- return 0;
-}
-
-static void pxa168_eth_shutdown(struct platform_device *pdev)
-{
- struct net_device *dev = platform_get_drvdata(pdev);
- eth_port_reset(dev);
-}
-
-#ifdef CONFIG_PM
-static int pxa168_eth_resume(struct platform_device *pdev)
-{
- return -ENOSYS;
-}
-
-static int pxa168_eth_suspend(struct platform_device *pdev, pm_message_t state)
-{
- return -ENOSYS;
-}
-
-#else
-#define pxa168_eth_resume NULL
-#define pxa168_eth_suspend NULL
-#endif
-
-static struct platform_driver pxa168_eth_driver = {
- .probe = pxa168_eth_probe,
- .remove = pxa168_eth_remove,
- .shutdown = pxa168_eth_shutdown,
- .resume = pxa168_eth_resume,
- .suspend = pxa168_eth_suspend,
- .driver = {
- .name = DRIVER_NAME,
- },
-};
-
-static int __init pxa168_init_module(void)
-{
- return platform_driver_register(&pxa168_eth_driver);
-}
-
-static void __exit pxa168_cleanup_module(void)
-{
- platform_driver_unregister(&pxa168_eth_driver);
-}
-
-module_init(pxa168_init_module);
-module_exit(pxa168_cleanup_module);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Ethernet driver for Marvell PXA168");
-MODULE_ALIAS("platform:pxa168_eth");
diff --git a/trunk/drivers/net/qlcnic/qlcnic_main.c b/trunk/drivers/net/qlcnic/qlcnic_main.c
index 213e3656d953..bf6d87adda4f 100644
--- a/trunk/drivers/net/qlcnic/qlcnic_main.c
+++ b/trunk/drivers/net/qlcnic/qlcnic_main.c
@@ -1983,6 +1983,8 @@ static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct net_device_stats *stats = &netdev->stats;
+ memset(stats, 0, sizeof(*stats));
+
stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
stats->tx_packets = adapter->stats.xmitfinished;
stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes;
diff --git a/trunk/drivers/net/sh_eth.c b/trunk/drivers/net/sh_eth.c
index 79fd02bc69fd..f5a9eb1df593 100644
--- a/trunk/drivers/net/sh_eth.c
+++ b/trunk/drivers/net/sh_eth.c
@@ -1437,7 +1437,7 @@ static const struct net_device_ops sh_eth_netdev_ops = {
static int sh_eth_drv_probe(struct platform_device *pdev)
{
- int ret, devno = 0;
+ int ret, i, devno = 0;
struct resource *res;
struct net_device *ndev = NULL;
struct sh_eth_private *mdp;
diff --git a/trunk/drivers/net/usb/ipheth.c b/trunk/drivers/net/usb/ipheth.c
index 8ed30fa35d0a..08e7b6abacdd 100644
--- a/trunk/drivers/net/usb/ipheth.c
+++ b/trunk/drivers/net/usb/ipheth.c
@@ -58,7 +58,6 @@
#define USB_PRODUCT_IPHONE 0x1290
#define USB_PRODUCT_IPHONE_3G 0x1292
#define USB_PRODUCT_IPHONE_3GS 0x1294
-#define USB_PRODUCT_IPHONE_4 0x1297
#define IPHETH_USBINTF_CLASS 255
#define IPHETH_USBINTF_SUBCLASS 253
@@ -93,10 +92,6 @@ static struct usb_device_id ipheth_table[] = {
USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS,
IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
IPHETH_USBINTF_PROTO) },
- { USB_DEVICE_AND_INTERFACE_INFO(
- USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4,
- IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
- IPHETH_USBINTF_PROTO) },
{ }
};
MODULE_DEVICE_TABLE(usb, ipheth_table);
diff --git a/trunk/drivers/net/wireless/adm8211.c b/trunk/drivers/net/wireless/adm8211.c
index f9aa1bc0a947..a105087af963 100644
--- a/trunk/drivers/net/wireless/adm8211.c
+++ b/trunk/drivers/net/wireless/adm8211.c
@@ -732,7 +732,7 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan)
/* Nothing to do for ADMtek BBP */
} else if (priv->bbp_type != ADM8211_TYPE_ADMTEK)
- wiphy_debug(dev->wiphy, "unsupported BBP type %d\n",
+ wiphy_debug(dev->wiphy, "unsupported bbp type %d\n",
priv->bbp_type);
ADM8211_RESTORE();
@@ -1032,7 +1032,7 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev)
break;
}
} else
- wiphy_debug(dev->wiphy, "unsupported BBP %d\n", priv->bbp_type);
+ wiphy_debug(dev->wiphy, "unsupported bbp %d\n", priv->bbp_type);
ADM8211_CSR_WRITE(SYNRF, 0);
@@ -1525,7 +1525,7 @@ static int adm8211_start(struct ieee80211_hw *dev)
retval = request_irq(priv->pdev->irq, adm8211_interrupt,
IRQF_SHARED, "adm8211", dev);
if (retval) {
- wiphy_err(dev->wiphy, "failed to register IRQ handler\n");
+ wiphy_err(dev->wiphy, "failed to register irq handler\n");
goto fail;
}
@@ -1902,7 +1902,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
goto err_free_eeprom;
}
- wiphy_info(dev->wiphy, "hwaddr %pM, Rev 0x%02x\n",
+ wiphy_info(dev->wiphy, "hwaddr %pm, rev 0x%02x\n",
dev->wiphy->perm_addr, pdev->revision);
return 0;
diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c
index 1128fa8c9ed5..d5140a87f073 100644
--- a/trunk/drivers/net/wireless/at76c50x-usb.c
+++ b/trunk/drivers/net/wireless/at76c50x-usb.c
@@ -655,7 +655,7 @@ static int at76_get_hw_config(struct at76_priv *priv)
exit:
kfree(hwcfg);
if (ret < 0)
- wiphy_err(priv->hw->wiphy, "cannot get HW Config (error %d)\n",
+ wiphy_err(priv->hw->wiphy, "cannot get hw config (error %d)\n",
ret);
return ret;
@@ -960,7 +960,7 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv)
sizeof(struct mib_mac_addr));
if (ret < 0) {
wiphy_err(priv->hw->wiphy,
- "at76_get_mib (MAC_ADDR) failed: %d\n", ret);
+ "at76_get_mib (mac_addr) failed: %d\n", ret);
goto exit;
}
@@ -989,7 +989,7 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
sizeof(struct mib_mac_wep));
if (ret < 0) {
wiphy_err(priv->hw->wiphy,
- "at76_get_mib (MAC_WEP) failed: %d\n", ret);
+ "at76_get_mib (mac_wep) failed: %d\n", ret);
goto exit;
}
@@ -1026,7 +1026,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
sizeof(struct mib_mac_mgmt));
if (ret < 0) {
wiphy_err(priv->hw->wiphy,
- "at76_get_mib (MAC_MGMT) failed: %d\n", ret);
+ "at76_get_mib (mac_mgmt) failed: %d\n", ret);
goto exit;
}
@@ -1062,7 +1062,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
if (ret < 0) {
wiphy_err(priv->hw->wiphy,
- "at76_get_mib (MAC) failed: %d\n", ret);
+ "at76_get_mib (mac) failed: %d\n", ret);
goto exit;
}
@@ -1099,7 +1099,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
if (ret < 0) {
wiphy_err(priv->hw->wiphy,
- "at76_get_mib (PHY) failed: %d\n", ret);
+ "at76_get_mib (phy) failed: %d\n", ret);
goto exit;
}
@@ -1132,7 +1132,7 @@ static void at76_dump_mib_local(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
if (ret < 0) {
wiphy_err(priv->hw->wiphy,
- "at76_get_mib (LOCAL) failed: %d\n", ret);
+ "at76_get_mib (local) failed: %d\n", ret);
goto exit;
}
@@ -1158,7 +1158,7 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv)
sizeof(struct mib_mdomain));
if (ret < 0) {
wiphy_err(priv->hw->wiphy,
- "at76_get_mib (MDOMAIN) failed: %d\n", ret);
+ "at76_get_mib (mdomain) failed: %d\n", ret);
goto exit;
}
@@ -1229,7 +1229,7 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
struct sk_buff *skb = priv->rx_skb;
if (!priv->rx_urb) {
- wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is NULL\n",
+ wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is null\n",
__func__);
return -EFAULT;
}
@@ -1792,7 +1792,7 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret);
if (ret == -EINVAL)
wiphy_err(priv->hw->wiphy,
- "-EINVAL: tx urb %p hcpriv %p complete %p\n",
+ "-einval: tx urb %p hcpriv %p complete %p\n",
priv->tx_urb,
priv->tx_urb->hcpriv, priv->tx_urb->complete);
}
@@ -2310,7 +2310,7 @@ static int at76_init_new_device(struct at76_priv *priv,
priv->mac80211_registered = 1;
- wiphy_info(priv->hw->wiphy, "USB %s, MAC %pM, firmware %d.%d.%d-%d\n",
+ wiphy_info(priv->hw->wiphy, "usb %s, mac %pm, firmware %d.%d.%d-%d\n",
dev_name(&interface->dev), priv->mac_addr,
priv->fw_version.major, priv->fw_version.minor,
priv->fw_version.patch, priv->fw_version.build);
diff --git a/trunk/drivers/net/wireless/ath/ar9170/main.c b/trunk/drivers/net/wireless/ath/ar9170/main.c
index debfb0fbc7c5..c67b05f3bcbd 100644
--- a/trunk/drivers/net/wireless/ath/ar9170/main.c
+++ b/trunk/drivers/net/wireless/ath/ar9170/main.c
@@ -245,7 +245,7 @@ static void __ar9170_dump_txstats(struct ar9170 *ar)
{
int i;
- wiphy_debug(ar->hw->wiphy, "QoS queue stats\n");
+ wiphy_debug(ar->hw->wiphy, "qos queue stats\n");
for (i = 0; i < __AR9170_NUM_TXQ; i++)
wiphy_debug(ar->hw->wiphy,
@@ -387,7 +387,7 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
#ifdef AR9170_QUEUE_DEBUG
wiphy_debug(ar->hw->wiphy,
- "skip frame => DA %pM != %pM\n",
+ "skip frame => da %pm != %pm\n",
mac, ieee80211_get_DA(hdr));
ar9170_print_txheader(ar, skb);
#endif /* AR9170_QUEUE_DEBUG */
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 996e9d7d7586..16bbfa3189a5 100644
--- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -2723,6 +2723,14 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
packet = &priv->rx_buffers[i];
+ /* Sync the DMA for the STATUS buffer so CPU is sure to get
+ * the correct values */
+ pci_dma_sync_single_for_cpu(priv->pci_dev,
+ sq->nic +
+ sizeof(struct ipw2100_status) * i,
+ sizeof(struct ipw2100_status),
+ PCI_DMA_FROMDEVICE);
+
/* Sync the DMA for the RX buffer so CPU is sure to get
* the correct values */
pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr,
@@ -6657,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/iwlwifi/iwl-1000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c
index 0b779a41a142..fec026212326 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -265,7 +265,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 128,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -297,7 +297,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 128,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8ccfcd08218d..6950a783913b 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2731,7 +2731,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.led_compensation = 64,
.broken_powersave = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.tx_power_by_driver = true,
};
@@ -2752,7 +2752,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.led_compensation = 64,
.broken_powersave = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.tx_power_by_driver = true,
};
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c
index d92b72909233..d6da356608fa 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2322,7 +2322,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.led_compensation = 61,
.chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.temperature_kelvin = true,
.max_event_log_size = 512,
.tx_power_by_driver = true,
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c
index 48bdcd8d2e94..aacf3770f075 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -510,7 +510,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -541,7 +541,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -570,7 +570,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -601,7 +601,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -632,7 +632,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -663,7 +663,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -693,7 +693,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c
index cee06b968de8..af4fd50f3405 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -388,7 +388,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -424,7 +424,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
@@ -459,7 +459,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
@@ -496,7 +496,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
@@ -532,7 +532,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
@@ -570,7 +570,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
@@ -606,7 +606,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
@@ -644,7 +644,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
@@ -680,7 +680,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
@@ -721,7 +721,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -756,7 +756,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -791,7 +791,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -828,7 +828,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1500,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -866,7 +866,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1500,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -902,7 +902,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1500,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -940,7 +940,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
index 10d7b9b7f064..c1882fd8345d 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3667,49 +3667,6 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static void iwlagn_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast)
-{
- struct iwl_priv *priv = hw->priv;
- __le32 filter_or = 0, filter_nand = 0;
-
-#define CHK(test, flag) do { \
- if (*total_flags & (test)) \
- filter_or |= (flag); \
- else \
- filter_nand |= (flag); \
- } while (0)
-
- IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
- changed_flags, *total_flags);
-
- CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
- CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
- CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
-
-#undef CHK
-
- mutex_lock(&priv->mutex);
-
- priv->staging_rxon.filter_flags &= ~filter_nand;
- priv->staging_rxon.filter_flags |= filter_or;
-
- iwlcore_commit_rxon(priv);
-
- mutex_unlock(&priv->mutex);
-
- /*
- * Receiving all multicast frames is always enabled by the
- * default flags setup in iwl_connection_init_rx_config()
- * since we currently do not support programming multicast
- * filters into the device.
- */
- *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
- FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
-}
-
static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop)
{
struct iwl_priv *priv = hw->priv;
@@ -3910,7 +3867,7 @@ static struct ieee80211_ops iwl_hw_ops = {
.add_interface = iwl_mac_add_interface,
.remove_interface = iwl_mac_remove_interface,
.config = iwl_mac_config,
- .configure_filter = iwlagn_configure_filter,
+ .configure_filter = iwl_configure_filter,
.set_key = iwl_mac_set_key,
.update_tkip_key = iwl_mac_update_tkip_key,
.conf_tx = iwl_mac_conf_tx,
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c
index 07dbc2796448..2c03c6e20a72 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1328,6 +1328,51 @@ int iwl_apm_init(struct iwl_priv *priv)
EXPORT_SYMBOL(iwl_apm_init);
+
+void iwl_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast)
+{
+ struct iwl_priv *priv = hw->priv;
+ __le32 filter_or = 0, filter_nand = 0;
+
+#define CHK(test, flag) do { \
+ if (*total_flags & (test)) \
+ filter_or |= (flag); \
+ else \
+ filter_nand |= (flag); \
+ } while (0)
+
+ IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
+ changed_flags, *total_flags);
+
+ CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
+ CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
+ CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
+
+#undef CHK
+
+ mutex_lock(&priv->mutex);
+
+ priv->staging_rxon.filter_flags &= ~filter_nand;
+ priv->staging_rxon.filter_flags |= filter_or;
+
+ iwlcore_commit_rxon(priv);
+
+ mutex_unlock(&priv->mutex);
+
+ /*
+ * Receiving all multicast frames is always enabled by the
+ * default flags setup in iwl_connection_init_rx_config()
+ * since we currently do not support programming multicast
+ * filters into the device.
+ */
+ *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
+ FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
+}
+EXPORT_SYMBOL(iwl_configure_filter);
+
int iwl_set_hw_params(struct iwl_priv *priv)
{
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h
index 5e6ee3da6bbf..4a71dfb10a15 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -372,6 +372,9 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
u32 decrypt_res,
struct ieee80211_rx_status *stats);
void iwl_irq_handle_error(struct iwl_priv *priv);
+void iwl_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags, u64 multicast);
int iwl_set_hw_params(struct iwl_priv *priv);
void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
void iwl_bss_info_changed(struct ieee80211_hw *hw,
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
index 2e97cd2fa98a..f35bcad56e36 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1049,8 +1049,7 @@ struct iwl_event_log {
#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
/* timer constants use to monitor and recover stuck tx queues in mSecs */
-#define IWL_DEF_MONITORING_PERIOD (1000)
-#define IWL_LONG_MONITORING_PERIOD (5000)
+#define IWL_MONITORING_PERIOD (1000)
#define IWL_ONE_HUNDRED_MSECS (100)
#define IWL_SIXTY_SECS (60000)
diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 59a308b02f95..70c4b8fba0ee 100644
--- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3391,55 +3391,6 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
return 0;
}
-
-static void iwl3945_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast)
-{
- struct iwl_priv *priv = hw->priv;
- __le32 filter_or = 0, filter_nand = 0;
-
-#define CHK(test, flag) do { \
- if (*total_flags & (test)) \
- filter_or |= (flag); \
- else \
- filter_nand |= (flag); \
- } while (0)
-
- IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
- changed_flags, *total_flags);
-
- CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
- CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
- CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
-
-#undef CHK
-
- mutex_lock(&priv->mutex);
-
- priv->staging_rxon.filter_flags &= ~filter_nand;
- priv->staging_rxon.filter_flags |= filter_or;
-
- /*
- * Committing directly here breaks for some reason,
- * but we'll eventually commit the filter flags
- * change anyway.
- */
-
- mutex_unlock(&priv->mutex);
-
- /*
- * Receiving all multicast frames is always enabled by the
- * default flags setup in iwl_connection_init_rx_config()
- * since we currently do not support programming multicast
- * filters into the device.
- */
- *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
- FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
-}
-
-
/*****************************************************************************
*
* sysfs attributes
@@ -3845,7 +3796,7 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.add_interface = iwl_mac_add_interface,
.remove_interface = iwl_mac_remove_interface,
.config = iwl_mac_config,
- .configure_filter = iwl3945_configure_filter,
+ .configure_filter = iwl_configure_filter,
.set_key = iwl3945_mac_set_key,
.conf_tx = iwl_mac_conf_tx,
.reset_tsf = iwl_mac_reset_tsf,
diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c
index 86fa8abdd66f..01ad7f77383a 100644
--- a/trunk/drivers/net/wireless/mac80211_hwsim.c
+++ b/trunk/drivers/net/wireless/mac80211_hwsim.c
@@ -486,7 +486,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
struct ieee80211_rx_status rx_status;
if (data->idle) {
- wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n");
+ wiphy_debug(hw->wiphy, "trying to tx when idle - reject\n");
return false;
}
diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c
index f152a25be59f..d761ed2d8af4 100644
--- a/trunk/drivers/net/wireless/mwl8k.c
+++ b/trunk/drivers/net/wireless/mwl8k.c
@@ -910,14 +910,14 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma);
if (rxq->rxd == NULL) {
- wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n");
+ wiphy_err(hw->wiphy, "failed to alloc rx descriptors\n");
return -ENOMEM;
}
memset(rxq->rxd, 0, size);
rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL);
if (rxq->buf == NULL) {
- wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n");
+ wiphy_err(hw->wiphy, "failed to alloc rx skbuff list\n");
pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
return -ENOMEM;
}
@@ -1145,14 +1145,14 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma);
if (txq->txd == NULL) {
- wiphy_err(hw->wiphy, "failed to alloc TX descriptors\n");
+ wiphy_err(hw->wiphy, "failed to alloc tx descriptors\n");
return -ENOMEM;
}
memset(txq->txd, 0, size);
txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL);
if (txq->skb == NULL) {
- wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n");
+ wiphy_err(hw->wiphy, "failed to alloc tx skbuff list\n");
pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma);
return -ENOMEM;
}
@@ -1573,7 +1573,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
PCI_DMA_BIDIRECTIONAL);
if (!timeout) {
- wiphy_err(hw->wiphy, "Command %s timeout after %u ms\n",
+ wiphy_err(hw->wiphy, "command %s timeout after %u ms\n",
mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
MWL8K_CMD_TIMEOUT_MS);
rc = -ETIMEDOUT;
@@ -1584,11 +1584,11 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
rc = cmd->result ? -EINVAL : 0;
if (rc)
- wiphy_err(hw->wiphy, "Command %s error 0x%x\n",
+ wiphy_err(hw->wiphy, "command %s error 0x%x\n",
mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
le16_to_cpu(cmd->result));
else if (ms > 2000)
- wiphy_notice(hw->wiphy, "Command %s took %d ms\n",
+ wiphy_notice(hw->wiphy, "command %s took %d ms\n",
mwl8k_cmd_name(cmd->code,
buf, sizeof(buf)),
ms);
@@ -3210,7 +3210,7 @@ static int mwl8k_start(struct ieee80211_hw *hw)
rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
IRQF_SHARED, MWL8K_NAME, hw);
if (rc) {
- wiphy_err(hw->wiphy, "failed to register IRQ handler\n");
+ wiphy_err(hw->wiphy, "failed to register irq handler\n");
return -EIO;
}
@@ -3926,7 +3926,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
priv->sram = pci_iomap(pdev, 0, 0x10000);
if (priv->sram == NULL) {
- wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
+ wiphy_err(hw->wiphy, "cannot map device sram\n");
goto err_iounmap;
}
@@ -3938,7 +3938,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
if (priv->regs == NULL) {
priv->regs = pci_iomap(pdev, 2, 0x10000);
if (priv->regs == NULL) {
- wiphy_err(hw->wiphy, "Cannot map device registers\n");
+ wiphy_err(hw->wiphy, "cannot map device registers\n");
goto err_iounmap;
}
}
@@ -3950,14 +3950,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
/* Ask userland hotplug daemon for the device firmware */
rc = mwl8k_request_firmware(priv);
if (rc) {
- wiphy_err(hw->wiphy, "Firmware files not found\n");
+ wiphy_err(hw->wiphy, "firmware files not found\n");
goto err_stop_firmware;
}
/* Load firmware into hardware */
rc = mwl8k_load_firmware(hw);
if (rc) {
- wiphy_err(hw->wiphy, "Cannot start firmware\n");
+ wiphy_err(hw->wiphy, "cannot start firmware\n");
goto err_stop_firmware;
}
@@ -4047,7 +4047,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
IRQF_SHARED, MWL8K_NAME, hw);
if (rc) {
- wiphy_err(hw->wiphy, "failed to register IRQ handler\n");
+ wiphy_err(hw->wiphy, "failed to register irq handler\n");
goto err_free_queues;
}
@@ -4067,7 +4067,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
rc = mwl8k_cmd_get_hw_spec_sta(hw);
}
if (rc) {
- wiphy_err(hw->wiphy, "Cannot initialise firmware\n");
+ wiphy_err(hw->wiphy, "cannot initialise firmware\n");
goto err_free_irq;
}
@@ -4081,14 +4081,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
/* Turn radio off */
rc = mwl8k_cmd_radio_disable(hw);
if (rc) {
- wiphy_err(hw->wiphy, "Cannot disable\n");
+ wiphy_err(hw->wiphy, "cannot disable\n");
goto err_free_irq;
}
/* Clear MAC address */
rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
if (rc) {
- wiphy_err(hw->wiphy, "Cannot clear MAC address\n");
+ wiphy_err(hw->wiphy, "cannot clear mac address\n");
goto err_free_irq;
}
@@ -4098,7 +4098,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
rc = ieee80211_register_hw(hw);
if (rc) {
- wiphy_err(hw->wiphy, "Cannot register device\n");
+ wiphy_err(hw->wiphy, "cannot register device\n");
goto err_free_queues;
}
diff --git a/trunk/drivers/net/wireless/p54/eeprom.c b/trunk/drivers/net/wireless/p54/eeprom.c
index 78347041ec40..d687cb7f2a59 100644
--- a/trunk/drivers/net/wireless/p54/eeprom.c
+++ b/trunk/drivers/net/wireless/p54/eeprom.c
@@ -167,7 +167,7 @@ static int p54_generate_band(struct ieee80211_hw *dev,
}
if (j == 0) {
- wiphy_err(dev->wiphy, "Disabling totally damaged %d GHz band\n",
+ wiphy_err(dev->wiphy, "disabling totally damaged %d GHz band\n",
(band == IEEE80211_BAND_2GHZ) ? 2 : 5);
ret = -ENODATA;
@@ -695,12 +695,12 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
u8 perm_addr[ETH_ALEN];
wiphy_warn(dev->wiphy,
- "Invalid hwaddr! Using randomly generated MAC addr\n");
+ "invalid hwaddr! using randomly generated mac addr\n");
random_ether_addr(perm_addr);
SET_IEEE80211_PERM_ADDR(dev, perm_addr);
}
- wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n",
+ wiphy_info(dev->wiphy, "hwaddr %pm, mac:isl38%02x rf:%s\n",
dev->wiphy->perm_addr, priv->version,
p54_rf_chips[priv->rxhw]);
diff --git a/trunk/drivers/net/wireless/p54/fwio.c b/trunk/drivers/net/wireless/p54/fwio.c
index 15b20c29a604..47006bca4852 100644
--- a/trunk/drivers/net/wireless/p54/fwio.c
+++ b/trunk/drivers/net/wireless/p54/fwio.c
@@ -125,7 +125,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
if (fw_version)
wiphy_info(priv->hw->wiphy,
- "FW rev %s - Softmac protocol %x.%x\n",
+ "fw rev %s - softmac protocol %x.%x\n",
fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
if (priv->fw_var < 0x500)
diff --git a/trunk/drivers/net/wireless/p54/led.c b/trunk/drivers/net/wireless/p54/led.c
index 3837e1eec5f4..ea91f5cce6b3 100644
--- a/trunk/drivers/net/wireless/p54/led.c
+++ b/trunk/drivers/net/wireless/p54/led.c
@@ -58,7 +58,7 @@ static void p54_update_leds(struct work_struct *work)
err = p54_set_leds(priv);
if (err && net_ratelimit())
wiphy_err(priv->hw->wiphy,
- "failed to update LEDs (%d).\n", err);
+ "failed to update leds (%d).\n", err);
if (rerun)
ieee80211_queue_delayed_work(priv->hw, &priv->led_work,
@@ -103,7 +103,7 @@ static int p54_register_led(struct p54_common *priv,
err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev);
if (err)
wiphy_err(priv->hw->wiphy,
- "Failed to register %s LED.\n", name);
+ "failed to register %s led.\n", name);
else
led->registered = 1;
diff --git a/trunk/drivers/net/wireless/p54/p54pci.c b/trunk/drivers/net/wireless/p54/p54pci.c
index 1eacba4daa5b..822f8dc26e9c 100644
--- a/trunk/drivers/net/wireless/p54/p54pci.c
+++ b/trunk/drivers/net/wireless/p54/p54pci.c
@@ -466,7 +466,7 @@ static int p54p_open(struct ieee80211_hw *dev)
P54P_READ(dev_int);
if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
- wiphy_err(dev->wiphy, "Cannot boot firmware!\n");
+ wiphy_err(dev->wiphy, "cannot boot firmware!\n");
p54p_stop(dev);
return -ETIMEDOUT;
}
diff --git a/trunk/drivers/net/wireless/p54/txrx.c b/trunk/drivers/net/wireless/p54/txrx.c
index 173aec3d6e7e..427b46f558ed 100644
--- a/trunk/drivers/net/wireless/p54/txrx.c
+++ b/trunk/drivers/net/wireless/p54/txrx.c
@@ -540,7 +540,7 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
case P54_TRAP_BEACON_TX:
break;
case P54_TRAP_RADAR:
- wiphy_info(priv->hw->wiphy, "radar (freq:%d MHz)\n", freq);
+ wiphy_info(priv->hw->wiphy, "radar (freq:%d mhz)\n", freq);
break;
case P54_TRAP_NO_BEACON:
if (priv->vif)
diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 30107ce78dfb..b50c39aaec05 100644
--- a/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -445,7 +445,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
&priv->rx_ring_dma);
if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
- wiphy_err(dev->wiphy, "Cannot allocate RX ring\n");
+ wiphy_err(dev->wiphy, "cannot allocate rx ring\n");
return -ENOMEM;
}
@@ -502,7 +502,7 @@ static int rtl8180_init_tx_ring(struct ieee80211_hw *dev,
ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
if (!ring || (unsigned long)ring & 0xFF) {
- wiphy_err(dev->wiphy, "Cannot allocate TX ring (prio = %d)\n",
+ wiphy_err(dev->wiphy, "cannot allocate tx ring (prio = %d)\n",
prio);
return -ENOMEM;
}
@@ -568,7 +568,7 @@ static int rtl8180_start(struct ieee80211_hw *dev)
ret = request_irq(priv->pdev->irq, rtl8180_interrupt,
IRQF_SHARED, KBUILD_MODNAME, dev);
if (ret) {
- wiphy_err(dev->wiphy, "failed to register IRQ handler\n");
+ wiphy_err(dev->wiphy, "failed to register irq handler\n");
goto err_free_rings;
}
diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 98e0351c1dd6..5738a55c1b06 100644
--- a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -573,7 +573,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
} while (--i);
if (!i) {
- wiphy_err(dev->wiphy, "Reset timeout!\n");
+ wiphy_err(dev->wiphy, "reset timeout!\n");
return -ETIMEDOUT;
}
@@ -1526,7 +1526,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
mutex_init(&priv->conf_mutex);
skb_queue_head_init(&priv->b_tx_status.queue);
- wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
+ wiphy_info(dev->wiphy, "hwaddr %pm, %s v%d + %s, rfkill mask %d\n",
mac_addr, chip_name, priv->asic_rev, priv->rf->name,
priv->rfkill_mask);
diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/trunk/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
index 97eebdcf7eb9..fd96f9112322 100644
--- a/trunk/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
+++ b/trunk/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
@@ -366,7 +366,7 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev)
rtl8225_write(dev, 0x02, 0x044d);
msleep(100);
if (!(rtl8225_read(dev, 6) & (1 << 7)))
- wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n",
+ wiphy_warn(dev->wiphy, "rf calibration failed! %x\n",
rtl8225_read(dev, 6));
}
@@ -735,7 +735,7 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
rtl8225_write(dev, 0x02, 0x044D);
msleep(100);
if (!(rtl8225_read(dev, 6) & (1 << 7)))
- wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n",
+ wiphy_warn(dev->wiphy, "rf calibration failed! %x\n",
rtl8225_read(dev, 6));
}
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/Kconfig b/trunk/drivers/platform/x86/Kconfig
index cff7cc2c1f02..044f430f3b43 100644
--- a/trunk/drivers/platform/x86/Kconfig
+++ b/trunk/drivers/platform/x86/Kconfig
@@ -486,12 +486,10 @@ config TOPSTAR_LAPTOP
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on ACPI
- depends on LEDS_CLASS
- depends on NEW_LEDS
- depends on BACKLIGHT_CLASS_DEVICE
depends on INPUT
depends on RFKILL || RFKILL = n
select INPUT_POLLDEV
+ select BACKLIGHT_CLASS_DEVICE
---help---
This driver adds support for access to certain system settings
on "legacy free" Toshiba laptops. These laptops can be recognized by
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/hp-wmi.c b/trunk/drivers/platform/x86/hp-wmi.c
index c1741142a4cb..f15516374987 100644
--- a/trunk/drivers/platform/x86/hp-wmi.c
+++ b/trunk/drivers/platform/x86/hp-wmi.c
@@ -79,13 +79,12 @@ struct bios_args {
u32 command;
u32 commandtype;
u32 datasize;
- u32 data;
+ char *data;
};
struct bios_return {
u32 sigpass;
u32 return_code;
- u32 value;
};
struct key_entry {
@@ -149,7 +148,7 @@ static struct platform_driver hp_wmi_driver = {
* buffer = kzalloc(128, GFP_KERNEL);
* ret = hp_wmi_perform_query(0x7, 0, buffer, 128)
*/
-static int hp_wmi_perform_query(int query, int write, u32 *buffer,
+static int hp_wmi_perform_query(int query, int write, char *buffer,
int buffersize)
{
struct bios_return bios_return;
@@ -160,7 +159,7 @@ static int hp_wmi_perform_query(int query, int write, u32 *buffer,
.command = write ? 0x2 : 0x1,
.commandtype = query,
.datasize = buffersize,
- .data = *buffer,
+ .data = buffer,
};
struct acpi_buffer input = { sizeof(struct bios_args), &args };
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -178,14 +177,29 @@ static int hp_wmi_perform_query(int query, int write, u32 *buffer,
bios_return = *((struct bios_return *)obj->buffer.pointer);
- memcpy(buffer, &bios_return.value, sizeof(bios_return.value));
+ if (bios_return.return_code) {
+ printk(KERN_WARNING PREFIX "Query %d returned %d\n", query,
+ bios_return.return_code);
+ kfree(obj);
+ return bios_return.return_code;
+ }
+ if (obj->buffer.length - sizeof(bios_return) > buffersize) {
+ kfree(obj);
+ return -EINVAL;
+ }
+
+ memset(buffer, 0, buffersize);
+ memcpy(buffer,
+ ((char *)obj->buffer.pointer) + sizeof(struct bios_return),
+ obj->buffer.length - sizeof(bios_return));
+ kfree(obj);
return 0;
}
static int hp_wmi_display_state(void)
{
- int state = 0;
- int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, &state,
+ int state;
+ int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, (char *)&state,
sizeof(state));
if (ret)
return -EINVAL;
@@ -194,8 +208,8 @@ static int hp_wmi_display_state(void)
static int hp_wmi_hddtemp_state(void)
{
- int state = 0;
- int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, &state,
+ int state;
+ int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, (char *)&state,
sizeof(state));
if (ret)
return -EINVAL;
@@ -204,8 +218,8 @@ static int hp_wmi_hddtemp_state(void)
static int hp_wmi_als_state(void)
{
- int state = 0;
- int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, &state,
+ int state;
+ int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, (char *)&state,
sizeof(state));
if (ret)
return -EINVAL;
@@ -214,8 +228,8 @@ static int hp_wmi_als_state(void)
static int hp_wmi_dock_state(void)
{
- int state = 0;
- int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state,
+ int state;
+ int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state,
sizeof(state));
if (ret)
@@ -226,8 +240,8 @@ static int hp_wmi_dock_state(void)
static int hp_wmi_tablet_state(void)
{
- int state = 0;
- int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state,
+ int state;
+ int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state,
sizeof(state));
if (ret)
return ret;
@@ -242,7 +256,7 @@ static int hp_wmi_set_block(void *data, bool blocked)
int ret;
ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1,
- &query, sizeof(query));
+ (char *)&query, sizeof(query));
if (ret)
return -EINVAL;
return 0;
@@ -254,10 +268,10 @@ static const struct rfkill_ops hp_wmi_rfkill_ops = {
static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
{
- int wireless = 0;
+ int wireless;
int mask;
hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0,
- &wireless, sizeof(wireless));
+ (char *)&wireless, sizeof(wireless));
/* TBD: Pass error */
mask = 0x200 << (r * 8);
@@ -270,10 +284,10 @@ static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
{
- int wireless = 0;
+ int wireless;
int mask;
hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0,
- &wireless, sizeof(wireless));
+ (char *)&wireless, sizeof(wireless));
/* TBD: Pass error */
mask = 0x800 << (r * 8);
@@ -333,7 +347,7 @@ static ssize_t set_als(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
u32 tmp = simple_strtoul(buf, NULL, 10);
- int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, &tmp,
+ int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, (char *)&tmp,
sizeof(tmp));
if (ret)
return -EINVAL;
@@ -407,7 +421,7 @@ static void hp_wmi_notify(u32 value, void *context)
static struct key_entry *key;
union acpi_object *obj;
u32 event_id, event_data;
- int key_code = 0, ret;
+ int key_code, ret;
u32 *location;
acpi_status status;
@@ -461,7 +475,7 @@ static void hp_wmi_notify(u32 value, void *context)
break;
case HPWMI_BEZEL_BUTTON:
ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0,
- &key_code,
+ (char *)&key_code,
sizeof(key_code));
if (ret)
break;
@@ -564,9 +578,9 @@ static void cleanup_sysfs(struct platform_device *device)
static int __devinit hp_wmi_bios_setup(struct platform_device *device)
{
int err;
- int wireless = 0;
+ int wireless;
- err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, &wireless,
+ err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, (char *)&wireless,
sizeof(wireless));
if (err)
return err;
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/intel_rar_register.c b/trunk/drivers/platform/x86/intel_rar_register.c
index 2b11a33325e6..73f8e6d72669 100644
--- a/trunk/drivers/platform/x86/intel_rar_register.c
+++ b/trunk/drivers/platform/x86/intel_rar_register.c
@@ -145,7 +145,7 @@ static void free_rar_device(struct rar_device *rar)
*/
static struct rar_device *_rar_to_device(int rar, int *off)
{
- if (rar >= 0 && rar < MRST_NUM_RAR) {
+ if (rar >= 0 && rar <= 3) {
*off = rar;
return &my_rar_device;
}
diff --git a/trunk/drivers/platform/x86/intel_scu_ipc.c b/trunk/drivers/platform/x86/intel_scu_ipc.c
index 6abe18e638e9..943f9084dcb1 100644
--- a/trunk/drivers/platform/x86/intel_scu_ipc.c
+++ b/trunk/drivers/platform/x86/intel_scu_ipc.c
@@ -487,7 +487,7 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
mdelay(1);
*data = readl(ipcdev.i2c_base + I2C_DATA_ADDR);
} else if (cmd == IPC_I2C_WRITE) {
- writel(*data, ipcdev.i2c_base + I2C_DATA_ADDR);
+ writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR);
mdelay(1);
writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR);
} else {
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/68328serial.c b/trunk/drivers/serial/68328serial.c
index be0ebce36e54..7356a56ac458 100644
--- a/trunk/drivers/serial/68328serial.c
+++ b/trunk/drivers/serial/68328serial.c
@@ -869,9 +869,7 @@ static int get_serial_info(struct m68k_serial * info,
tmp.close_delay = info->close_delay;
tmp.closing_wait = info->closing_wait;
tmp.custom_divisor = info->custom_divisor;
- if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
- return -EFAULT;
-
+ copy_to_user(retinfo,&tmp,sizeof(*retinfo));
return 0;
}
@@ -884,8 +882,7 @@ static int set_serial_info(struct m68k_serial * info,
if (!new_info)
return -EFAULT;
- if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
- return -EFAULT;
+ copy_from_user(&new_serial,new_info,sizeof(new_serial));
old_info = *info;
if (!capable(CAP_SYS_ADMIN)) {
@@ -946,7 +943,8 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value)
status = 0;
#endif
local_irq_restore(flags);
- return put_user(status, value);
+ put_user(status,value);
+ return 0;
}
/*
@@ -1001,18 +999,27 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
send_break(info, arg ? arg*(100) : 250);
return 0;
case TIOCGSERIAL:
- return get_serial_info(info,
- (struct serial_struct *) arg);
+ if (access_ok(VERIFY_WRITE, (void *) arg,
+ sizeof(struct serial_struct)))
+ return get_serial_info(info,
+ (struct serial_struct *) arg);
+ return -EFAULT;
case TIOCSSERIAL:
return set_serial_info(info,
(struct serial_struct *) arg);
case TIOCSERGETLSR: /* Get line status register */
- return get_lsr_info(info, (unsigned int *) arg);
+ if (access_ok(VERIFY_WRITE, (void *) arg,
+ sizeof(unsigned int)))
+ return get_lsr_info(info, (unsigned int *) arg);
+ return -EFAULT;
case TIOCSERGSTRUCT:
- if (copy_to_user((struct m68k_serial *) arg,
- info, sizeof(struct m68k_serial)))
+ if (!access_ok(VERIFY_WRITE, (void *) arg,
+ sizeof(struct m68k_serial)))
return -EFAULT;
+ copy_to_user((struct m68k_serial *) arg,
+ info, sizeof(struct m68k_serial));
return 0;
+
default:
return -ENOIOCTLCMD;
}
diff --git a/trunk/drivers/serial/8250_early.c b/trunk/drivers/serial/8250_early.c
index eaafb98debed..b745792ec25a 100644
--- a/trunk/drivers/serial/8250_early.c
+++ b/trunk/drivers/serial/8250_early.c
@@ -203,13 +203,13 @@ static int __init parse_options(struct early_serial8250_device *device,
if (mmio || mmio32)
printk(KERN_INFO
- "Early serial console at MMIO%s 0x%llx (options '%s')\n",
+ "Early serial console at MMIO%s 0x%llu (options '%s')\n",
mmio32 ? "32" : "",
(unsigned long long)port->mapbase,
device->options);
else
printk(KERN_INFO
- "Early serial console at I/O port 0x%lx (options '%s')\n",
+ "Early serial console at I/O port 0x%lu (options '%s')\n",
port->iobase,
device->options);
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/Kconfig b/trunk/drivers/staging/Kconfig
index 335311a98fdc..4a7a7a7f11b6 100644
--- a/trunk/drivers/staging/Kconfig
+++ b/trunk/drivers/staging/Kconfig
@@ -113,6 +113,8 @@ source "drivers/staging/vme/Kconfig"
source "drivers/staging/memrar/Kconfig"
+source "drivers/staging/sep/Kconfig"
+
source "drivers/staging/iio/Kconfig"
source "drivers/staging/zram/Kconfig"
diff --git a/trunk/drivers/staging/Makefile b/trunk/drivers/staging/Makefile
index e3f1e1b6095e..ca5c03eb3ce3 100644
--- a/trunk/drivers/staging/Makefile
+++ b/trunk/drivers/staging/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_FB_UDL) += udlfb/
obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
+obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_ZRAM) += zram/
obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
diff --git a/trunk/drivers/staging/batman-adv/bat_sysfs.c b/trunk/drivers/staging/batman-adv/bat_sysfs.c
index 05ca15a6c9f8..b4a8d5eb64fa 100644
--- a/trunk/drivers/staging/batman-adv/bat_sysfs.c
+++ b/trunk/drivers/staging/batman-adv/bat_sysfs.c
@@ -267,10 +267,6 @@ static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr,
if (atomic_read(&bat_priv->log_level) == log_level_tmp)
return count;
- bat_info(net_dev, "Changing log level from: %i to: %li\n",
- atomic_read(&bat_priv->log_level),
- log_level_tmp);
-
atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp);
return count;
}
diff --git a/trunk/drivers/staging/batman-adv/hard-interface.c b/trunk/drivers/staging/batman-adv/hard-interface.c
index baa8b05b9e8d..92c216a56885 100644
--- a/trunk/drivers/staging/batman-adv/hard-interface.c
+++ b/trunk/drivers/staging/batman-adv/hard-interface.c
@@ -129,9 +129,6 @@ static bool hardif_is_iface_up(struct batman_if *batman_if)
static void update_mac_addresses(struct batman_if *batman_if)
{
- if (!batman_if || !batman_if->packet_buff)
- return;
-
addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
@@ -197,6 +194,8 @@ static void hardif_activate_interface(struct net_device *net_dev,
if (batman_if->if_status != IF_INACTIVE)
return;
+ dev_hold(batman_if->net_dev);
+
update_mac_addresses(batman_if);
batman_if->if_status = IF_TO_BE_ACTIVATED;
@@ -223,6 +222,8 @@ static void hardif_deactivate_interface(struct net_device *net_dev,
(batman_if->if_status != IF_TO_BE_ACTIVATED))
return;
+ dev_put(batman_if->net_dev);
+
batman_if->if_status = IF_INACTIVE;
bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
@@ -317,13 +318,11 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
if (ret != 1)
goto out;
- dev_hold(net_dev);
-
batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
if (!batman_if) {
pr_err("Can't add interface (%s): out of memory\n",
net_dev->name);
- goto release_dev;
+ goto out;
}
batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC);
@@ -337,7 +336,6 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
batman_if->if_num = -1;
batman_if->net_dev = net_dev;
batman_if->if_status = IF_NOT_IN_USE;
- batman_if->packet_buff = NULL;
INIT_LIST_HEAD(&batman_if->list);
check_known_mac_addr(batman_if->net_dev->dev_addr);
@@ -348,8 +346,6 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
kfree(batman_if->dev);
free_if:
kfree(batman_if);
-release_dev:
- dev_put(net_dev);
out:
return NULL;
}
@@ -378,7 +374,6 @@ static void hardif_remove_interface(struct batman_if *batman_if)
batman_if->if_status = IF_TO_BE_REMOVED;
list_del_rcu(&batman_if->list);
sysfs_del_hardif(&batman_if->hardif_obj);
- dev_put(batman_if->net_dev);
call_rcu(&batman_if->rcu, hardif_free_interface);
}
@@ -398,13 +393,15 @@ static int hard_if_event(struct notifier_block *this,
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
- if (!batman_if && event == NETDEV_REGISTER)
- batman_if = hardif_add_interface(net_dev);
+ if (!batman_if)
+ batman_if = hardif_add_interface(net_dev);
if (!batman_if)
goto out;
switch (event) {
+ case NETDEV_REGISTER:
+ break;
case NETDEV_UP:
hardif_activate_interface(soft_device, bat_priv, batman_if);
break;
@@ -445,6 +442,8 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct batman_packet *batman_packet;
struct batman_if *batman_if;
+ struct net_device_stats *stats;
+ struct rtnl_link_stats64 temp;
int ret;
skb = skb_share_check(skb, GFP_ATOMIC);
@@ -480,6 +479,12 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
if (batman_if->if_status != IF_ACTIVE)
goto err_free;
+ stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp);
+ if (stats) {
+ stats->rx_packets++;
+ stats->rx_bytes += skb->len;
+ }
+
batman_packet = (struct batman_packet *)skb->data;
if (batman_packet->version != COMPAT_VERSION) {
diff --git a/trunk/drivers/staging/batman-adv/icmp_socket.c b/trunk/drivers/staging/batman-adv/icmp_socket.c
index 3ae7dd2d2d4d..fc3d32c12729 100644
--- a/trunk/drivers/staging/batman-adv/icmp_socket.c
+++ b/trunk/drivers/staging/batman-adv/icmp_socket.c
@@ -67,7 +67,6 @@ static int bat_socket_open(struct inode *inode, struct file *file)
INIT_LIST_HEAD(&socket_client->queue_list);
socket_client->queue_len = 0;
socket_client->index = i;
- socket_client->bat_priv = inode->i_private;
spin_lock_init(&socket_client->lock);
init_waitqueue_head(&socket_client->queue_wait);
@@ -152,8 +151,9 @@ static ssize_t bat_socket_read(struct file *file, char __user *buf,
static ssize_t bat_socket_write(struct file *file, const char __user *buff,
size_t len, loff_t *off)
{
+ /* FIXME: each orig_node->batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
struct socket_client *socket_client = file->private_data;
- struct bat_priv *bat_priv = socket_client->bat_priv;
struct icmp_packet_rr icmp_packet;
struct orig_node *orig_node;
struct batman_if *batman_if;
@@ -168,9 +168,6 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
return -EINVAL;
}
- if (!bat_priv->primary_if)
- return -EFAULT;
-
if (len >= sizeof(struct icmp_packet_rr))
packet_len = sizeof(struct icmp_packet_rr);
@@ -226,8 +223,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
if (batman_if->if_status != IF_ACTIVE)
goto dst_unreach;
- memcpy(icmp_packet.orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN);
if (packet_len == sizeof(struct icmp_packet_rr))
memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN);
@@ -275,7 +271,7 @@ int bat_socket_setup(struct bat_priv *bat_priv)
goto err;
d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR,
- bat_priv->debug_dir, bat_priv, &fops);
+ bat_priv->debug_dir, NULL, &fops);
if (d)
goto err;
diff --git a/trunk/drivers/staging/batman-adv/main.c b/trunk/drivers/staging/batman-adv/main.c
index ef7c20ae7979..2686019fe4e1 100644
--- a/trunk/drivers/staging/batman-adv/main.c
+++ b/trunk/drivers/staging/batman-adv/main.c
@@ -250,13 +250,10 @@ int choose_orig(void *data, int32_t size)
int is_my_mac(uint8_t *addr)
{
struct batman_if *batman_if;
-
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
- if (batman_if->if_status != IF_ACTIVE)
- continue;
-
- if (compare_orig(batman_if->net_dev->dev_addr, addr)) {
+ if ((batman_if->net_dev) &&
+ (compare_orig(batman_if->net_dev->dev_addr, addr))) {
rcu_read_unlock();
return 1;
}
diff --git a/trunk/drivers/staging/batman-adv/originator.c b/trunk/drivers/staging/batman-adv/originator.c
index de5a8c1a8104..28bb627ffa13 100644
--- a/trunk/drivers/staging/batman-adv/originator.c
+++ b/trunk/drivers/staging/batman-adv/originator.c
@@ -391,12 +391,11 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
{
struct orig_node *orig_node;
- unsigned long flags;
HASHIT(hashit);
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock(&orig_hash_lock);
while (hash_iterate(orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
@@ -405,11 +404,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
goto err;
}
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock(&orig_hash_lock);
return 0;
err:
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock(&orig_hash_lock);
return -ENOMEM;
}
@@ -469,13 +468,12 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
{
struct batman_if *batman_if_tmp;
struct orig_node *orig_node;
- unsigned long flags;
HASHIT(hashit);
int ret;
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock(&orig_hash_lock);
while (hash_iterate(orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
@@ -502,10 +500,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
rcu_read_unlock();
batman_if->if_num = -1;
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock(&orig_hash_lock);
return 0;
err:
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock(&orig_hash_lock);
return -ENOMEM;
}
diff --git a/trunk/drivers/staging/batman-adv/routing.c b/trunk/drivers/staging/batman-adv/routing.c
index 032195e6de94..066cc9149bf1 100644
--- a/trunk/drivers/staging/batman-adv/routing.c
+++ b/trunk/drivers/staging/batman-adv/routing.c
@@ -783,8 +783,6 @@ int recv_bat_packet(struct sk_buff *skb,
static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct orig_node *orig_node;
struct icmp_packet_rr *icmp_packet;
struct ethhdr *ethhdr;
@@ -803,9 +801,6 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
return NET_RX_DROP;
}
- if (!bat_priv->primary_if)
- return NET_RX_DROP;
-
/* answer echo request (ping) */
/* get routing information */
spin_lock_irqsave(&orig_hash_lock, flags);
@@ -835,8 +830,7 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
}
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
icmp_packet->msg_type = ECHO_REPLY;
icmp_packet->ttl = TTL;
@@ -851,8 +845,6 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct orig_node *orig_node;
struct icmp_packet *icmp_packet;
struct ethhdr *ethhdr;
@@ -873,9 +865,6 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
return NET_RX_DROP;
}
- if (!bat_priv->primary_if)
- return NET_RX_DROP;
-
/* get routing information */
spin_lock_irqsave(&orig_hash_lock, flags);
orig_node = ((struct orig_node *)
@@ -903,8 +892,7 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
}
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
icmp_packet->msg_type = TTL_EXCEEDED;
icmp_packet->ttl = TTL;
diff --git a/trunk/drivers/staging/batman-adv/types.h b/trunk/drivers/staging/batman-adv/types.h
index 9aa9d369c752..21d0717afb09 100644
--- a/trunk/drivers/staging/batman-adv/types.h
+++ b/trunk/drivers/staging/batman-adv/types.h
@@ -126,7 +126,6 @@ struct socket_client {
unsigned char index;
spinlock_t lock;
wait_queue_head_t queue_wait;
- struct bat_priv *bat_priv;
};
struct socket_packet {
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/staging/sep/Kconfig b/trunk/drivers/staging/sep/Kconfig
new file mode 100644
index 000000000000..0a9c39c7f2bd
--- /dev/null
+++ b/trunk/drivers/staging/sep/Kconfig
@@ -0,0 +1,10 @@
+config DX_SEP
+ tristate "Discretix SEP driver"
+# depends on MRST
+ depends on RAR_REGISTER && PCI
+ default y
+ help
+ Discretix SEP driver
+
+ If unsure say M. The compiled module will be
+ called sep_driver.ko
diff --git a/trunk/drivers/staging/sep/Makefile b/trunk/drivers/staging/sep/Makefile
new file mode 100644
index 000000000000..628d5f919414
--- /dev/null
+++ b/trunk/drivers/staging/sep/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_DX_SEP) := sep_driver.o
+
diff --git a/trunk/drivers/staging/sep/TODO b/trunk/drivers/staging/sep/TODO
new file mode 100644
index 000000000000..ff0e931dab64
--- /dev/null
+++ b/trunk/drivers/staging/sep/TODO
@@ -0,0 +1,8 @@
+Todo's so far (from Alan Cox)
+- Fix firmware loading
+- Get firmware into firmware git tree
+- Review and tidy each algorithm function
+- Check whether it can be plugged into any of the kernel crypto API
+ interfaces
+- Do something about the magic shared memory interface and replace it
+ with something saner (in Linux terms)
diff --git a/trunk/drivers/staging/sep/sep_dev.h b/trunk/drivers/staging/sep/sep_dev.h
new file mode 100644
index 000000000000..9200524bb64d
--- /dev/null
+++ b/trunk/drivers/staging/sep/sep_dev.h
@@ -0,0 +1,110 @@
+#ifndef __SEP_DEV_H__
+#define __SEP_DEV_H__
+
+/*
+ *
+ * sep_dev.h - Security Processor Device Structures
+ *
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 Discretix. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * CONTACTS:
+ *
+ * Alan Cox alan@linux.intel.com
+ *
+ */
+
+struct sep_device {
+ /* pointer to pci dev */
+ struct pci_dev *pdev;
+
+ unsigned long in_use;
+
+ /* address of the shared memory allocated during init for SEP driver
+ (coherent alloc) */
+ void *shared_addr;
+ /* the physical address of the shared area */
+ dma_addr_t shared_bus;
+
+ /* restricted access region (coherent alloc) */
+ dma_addr_t rar_bus;
+ void *rar_addr;
+ /* firmware regions: cache is at rar_addr */
+ unsigned long cache_size;
+
+ /* follows the cache */
+ dma_addr_t resident_bus;
+ unsigned long resident_size;
+ void *resident_addr;
+
+ /* start address of the access to the SEP registers from driver */
+ void __iomem *reg_addr;
+ /* transaction counter that coordinates the transactions between SEP and HOST */
+ unsigned long send_ct;
+ /* counter for the messages from sep */
+ unsigned long reply_ct;
+ /* counter for the number of bytes allocated in the pool for the current
+ transaction */
+ unsigned long data_pool_bytes_allocated;
+
+ /* array of pointers to the pages that represent input data for the synchronic
+ DMA action */
+ struct page **in_page_array;
+
+ /* array of pointers to the pages that represent out data for the synchronic
+ DMA action */
+ struct page **out_page_array;
+
+ /* number of pages in the sep_in_page_array */
+ unsigned long in_num_pages;
+
+ /* number of pages in the sep_out_page_array */
+ unsigned long out_num_pages;
+
+ /* global data for every flow */
+ struct sep_flow_context_t flows[SEP_DRIVER_NUM_FLOWS];
+
+ /* pointer to the workqueue that handles the flow done interrupts */
+ struct workqueue_struct *flow_wq;
+
+};
+
+static struct sep_device *sep_dev;
+
+static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value)
+{
+ void __iomem *addr = dev->reg_addr + reg;
+ writel(value, addr);
+}
+
+static inline u32 sep_read_reg(struct sep_device *dev, int reg)
+{
+ void __iomem *addr = dev->reg_addr + reg;
+ return readl(addr);
+}
+
+/* wait for SRAM write complete(indirect write */
+static inline void sep_wait_sram_write(struct sep_device *dev)
+{
+ u32 reg_val;
+ do
+ reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR);
+ while (!(reg_val & 1));
+}
+
+
+#endif
diff --git a/trunk/drivers/staging/sep/sep_driver.c b/trunk/drivers/staging/sep/sep_driver.c
new file mode 100644
index 000000000000..ecbde3467b1b
--- /dev/null
+++ b/trunk/drivers/staging/sep/sep_driver.c
@@ -0,0 +1,2742 @@
+/*
+ *
+ * sep_driver.c - Security Processor Driver main group of functions
+ *
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 Discretix. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * CONTACTS:
+ *
+ * Mark Allyn mark.a.allyn@intel.com
+ *
+ * CHANGES:
+ *
+ * 2009.06.26 Initial publish
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sep_driver_hw_defs.h"
+#include "sep_driver_config.h"
+#include "sep_driver_api.h"
+#include "sep_dev.h"
+
+#if SEP_DRIVER_ARM_DEBUG_MODE
+
+#define CRYS_SEP_ROM_length 0x4000
+#define CRYS_SEP_ROM_start_address 0x8000C000UL
+#define CRYS_SEP_ROM_start_address_offset 0xC000UL
+#define SEP_ROM_BANK_register 0x80008420UL
+#define SEP_ROM_BANK_register_offset 0x8420UL
+#define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0x82000000
+
+/*
+ * THESE 2 definitions are specific to the board - must be
+ * defined during integration
+ */
+#define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0xFF0D0000
+
+/* 2M size */
+
+static void sep_load_rom_code(struct sep_device *sep)
+{
+ /* Index variables */
+ unsigned long i, k, j;
+ u32 reg;
+ u32 error;
+ u32 warning;
+
+ /* Loading ROM from SEP_ROM_image.h file */
+ k = sizeof(CRYS_SEP_ROM);
+
+ edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n");
+
+ edbg("SEP Driver: k is %lu\n", k);
+ edbg("SEP Driver: sep->reg_addr is %p\n", sep->reg_addr);
+ edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset);
+
+ for (i = 0; i < 4; i++) {
+ /* write bank */
+ sep_write_reg(sep, SEP_ROM_BANK_register_offset, i);
+
+ for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) {
+ sep_write_reg(sep, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]);
+
+ k = k - 4;
+
+ if (k == 0) {
+ j = CRYS_SEP_ROM_length;
+ i = 4;
+ }
+ }
+ }
+
+ /* reset the SEP */
+ sep_write_reg(sep, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1);
+
+ /* poll for SEP ROM boot finish */
+ do
+ reg = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+ while (!reg);
+
+ edbg("SEP Driver: ROM polling ended\n");
+
+ switch (reg) {
+ case 0x1:
+ /* fatal error - read erro status from GPRO */
+ error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
+ edbg("SEP Driver: ROM polling case 1\n");
+ break;
+ case 0x4:
+ /* Cold boot ended successfully */
+ case 0x8:
+ /* Warmboot ended successfully */
+ case 0x10:
+ /* ColdWarm boot ended successfully */
+ error = 0;
+ case 0x2:
+ /* Boot First Phase ended */
+ warning = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
+ case 0x20:
+ edbg("SEP Driver: ROM polling case %d\n", reg);
+ break;
+ }
+
+}
+
+#else
+static void sep_load_rom_code(struct sep_device *sep) { }
+#endif /* SEP_DRIVER_ARM_DEBUG_MODE */
+
+
+
+/*----------------------------------------
+ DEFINES
+-----------------------------------------*/
+
+#define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000
+#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000
+
+/*--------------------------------------------
+ GLOBAL variables
+--------------------------------------------*/
+
+/* debug messages level */
+static int debug;
+module_param(debug, int , 0);
+MODULE_PARM_DESC(debug, "Flag to enable SEP debug messages");
+
+/* Keep this a single static object for now to keep the conversion easy */
+
+static struct sep_device sep_instance;
+static struct sep_device *sep_dev = &sep_instance;
+
+/*
+ mutex for the access to the internals of the sep driver
+*/
+static DEFINE_MUTEX(sep_mutex);
+
+
+/* wait queue head (event) of the driver */
+static DECLARE_WAIT_QUEUE_HEAD(sep_event);
+
+/**
+ * sep_load_firmware - copy firmware cache/resident
+ * @sep: device we are loading
+ *
+ * This functions copies the cache and resident from their source
+ * location into destination shared memory.
+ */
+
+static int sep_load_firmware(struct sep_device *sep)
+{
+ const struct firmware *fw;
+ char *cache_name = "sep/cache.image.bin";
+ char *res_name = "sep/resident.image.bin";
+ int error;
+
+ edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
+ edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
+
+ /* load cache */
+ error = request_firmware(&fw, cache_name, &sep->pdev->dev);
+ if (error) {
+ edbg("SEP Driver:cant request cache fw\n");
+ return error;
+ }
+ edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data);
+
+ memcpy(sep->rar_addr, (void *)fw->data, fw->size);
+ sep->cache_size = fw->size;
+ release_firmware(fw);
+
+ sep->resident_bus = sep->rar_bus + sep->cache_size;
+ sep->resident_addr = sep->rar_addr + sep->cache_size;
+
+ /* load resident */
+ error = request_firmware(&fw, res_name, &sep->pdev->dev);
+ if (error) {
+ edbg("SEP Driver:cant request res fw\n");
+ return error;
+ }
+ edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data);
+
+ memcpy(sep->resident_addr, (void *) fw->data, fw->size);
+ sep->resident_size = fw->size;
+ release_firmware(fw);
+
+ edbg("sep: resident v %p b %08llx cache v %p b %08llx\n",
+ sep->resident_addr, (unsigned long long)sep->resident_bus,
+ sep->rar_addr, (unsigned long long)sep->rar_bus);
+ return 0;
+}
+
+MODULE_FIRMWARE("sep/cache.image.bin");
+MODULE_FIRMWARE("sep/resident.image.bin");
+
+/**
+ * sep_map_and_alloc_shared_area - allocate shared block
+ * @sep: security processor
+ * @size: size of shared area
+ *
+ * Allocate a shared buffer in host memory that can be used by both the
+ * kernel and also the hardware interface via DMA.
+ */
+
+static int sep_map_and_alloc_shared_area(struct sep_device *sep,
+ unsigned long size)
+{
+ /* shared_addr = ioremap_nocache(0xda00000,shared_area_size); */
+ sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, size,
+ &sep->shared_bus, GFP_KERNEL);
+
+ if (!sep->shared_addr) {
+ edbg("sep_driver :shared memory dma_alloc_coherent failed\n");
+ return -ENOMEM;
+ }
+ /* set the bus address of the shared area */
+ edbg("sep: shared_addr %ld bytes @%p (bus %08llx)\n",
+ size, sep->shared_addr, (unsigned long long)sep->shared_bus);
+ return 0;
+}
+
+/**
+ * sep_unmap_and_free_shared_area - free shared block
+ * @sep: security processor
+ *
+ * Free the shared area allocated to the security processor. The
+ * processor must have finished with this and any final posted
+ * writes cleared before we do so.
+ */
+static void sep_unmap_and_free_shared_area(struct sep_device *sep, int size)
+{
+ dma_free_coherent(&sep->pdev->dev, size,
+ sep->shared_addr, sep->shared_bus);
+}
+
+/**
+ * sep_shared_virt_to_bus - convert bus/virt addresses
+ *
+ * Returns the bus address inside the shared area according
+ * to the virtual address.
+ */
+
+static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep,
+ void *virt_address)
+{
+ dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
+ edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa,
+ virt_address);
+ return pa;
+}
+
+/**
+ * sep_shared_bus_to_virt - convert bus/virt addresses
+ *
+ * Returns virtual address inside the shared area according
+ * to the bus address.
+ */
+
+static void *sep_shared_bus_to_virt(struct sep_device *sep,
+ dma_addr_t bus_address)
+{
+ return sep->shared_addr + (bus_address - sep->shared_bus);
+}
+
+
+/**
+ * sep_try_open - attempt to open a SEP device
+ * @sep: device to attempt to open
+ *
+ * Atomically attempt to get ownership of a SEP device.
+ * Returns 1 if the device was opened, 0 on failure.
+ */
+
+static int sep_try_open(struct sep_device *sep)
+{
+ if (!test_and_set_bit(0, &sep->in_use))
+ return 1;
+ return 0;
+}
+
+/**
+ * sep_open - device open method
+ * @inode: inode of sep device
+ * @filp: file handle to sep device
+ *
+ * Open method for the SEP device. Called when userspace opens
+ * the SEP device node. Must also release the memory data pool
+ * allocations.
+ *
+ * Returns zero on success otherwise an error code.
+ */
+
+static int sep_open(struct inode *inode, struct file *filp)
+{
+ if (sep_dev == NULL)
+ return -ENODEV;
+
+ /* check the blocking mode */
+ if (filp->f_flags & O_NDELAY) {
+ if (sep_try_open(sep_dev) == 0)
+ return -EAGAIN;
+ } else
+ if (wait_event_interruptible(sep_event, sep_try_open(sep_dev)) < 0)
+ return -EINTR;
+
+ /* Bind to the device, we only have one which makes it easy */
+ filp->private_data = sep_dev;
+ /* release data pool allocations */
+ sep_dev->data_pool_bytes_allocated = 0;
+ return 0;
+}
+
+
+/**
+ * sep_release - close a SEP device
+ * @inode: inode of SEP device
+ * @filp: file handle being closed
+ *
+ * Called on the final close of a SEP device. As the open protects against
+ * multiple simultaenous opens that means this method is called when the
+ * final reference to the open handle is dropped.
+ */
+
+static int sep_release(struct inode *inode, struct file *filp)
+{
+ struct sep_device *sep = filp->private_data;
+#if 0 /*!SEP_DRIVER_POLLING_MODE */
+ /* close IMR */
+ sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
+ /* release IRQ line */
+ free_irq(SEP_DIRVER_IRQ_NUM, sep);
+
+#endif
+ /* Ensure any blocked open progresses */
+ clear_bit(0, &sep->in_use);
+ wake_up(&sep_event);
+ return 0;
+}
+
+/*---------------------------------------------------------------
+ map function - this functions maps the message shared area
+-----------------------------------------------------------------*/
+static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ dma_addr_t bus_addr;
+ struct sep_device *sep = filp->private_data;
+
+ dbg("-------->SEP Driver: mmap start\n");
+
+ /* check that the size of the mapped range is as the size of the message
+ shared area */
+ if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
+ edbg("SEP Driver mmap requested size is more than allowed\n");
+ printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n");
+ printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end);
+ printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start);
+ return -EAGAIN;
+ }
+
+ edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
+
+ /* get bus address */
+ bus_addr = sep->shared_bus;
+
+ edbg("SEP Driver: phys_addr is %08llx\n", (unsigned long long)bus_addr);
+
+ if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ edbg("SEP Driver remap_page_range failed\n");
+ printk(KERN_WARNING "SEP Driver remap_page_range failed\n");
+ return -EAGAIN;
+ }
+
+ dbg("SEP Driver:<-------- mmap end\n");
+
+ return 0;
+}
+
+
+/*-----------------------------------------------
+ poll function
+*----------------------------------------------*/
+static unsigned int sep_poll(struct file *filp, poll_table * wait)
+{
+ unsigned long count;
+ unsigned int mask = 0;
+ unsigned long retval = 0; /* flow id */
+ struct sep_device *sep = filp->private_data;
+
+ dbg("---------->SEP Driver poll: start\n");
+
+
+#if SEP_DRIVER_POLLING_MODE
+
+ while (sep->send_ct != (retval & 0x7FFFFFFF)) {
+ retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+
+ for (count = 0; count < 10 * 4; count += 4)
+ edbg("Poll Debug Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count)));
+ }
+
+ sep->reply_ct++;
+#else
+ /* add the event to the polling wait table */
+ poll_wait(filp, &sep_event, wait);
+
+#endif
+
+ edbg("sep->send_ct is %lu\n", sep->send_ct);
+ edbg("sep->reply_ct is %lu\n", sep->reply_ct);
+
+ /* check if the data is ready */
+ if (sep->send_ct == sep->reply_ct) {
+ for (count = 0; count < 12 * 4; count += 4)
+ edbg("Sep Mesg Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count)));
+
+ for (count = 0; count < 10 * 4; count += 4)
+ edbg("Debug Data Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + 0x1800 + count)));
+
+ retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+ edbg("retval is %lu\n", retval);
+ /* check if the this is sep reply or request */
+ if (retval >> 31) {
+ edbg("SEP Driver: sep request in\n");
+ /* request */
+ mask |= POLLOUT | POLLWRNORM;
+ } else {
+ edbg("SEP Driver: sep reply in\n");
+ mask |= POLLIN | POLLRDNORM;
+ }
+ }
+ dbg("SEP Driver:<-------- poll exit\n");
+ return mask;
+}
+
+/**
+ * sep_time_address - address in SEP memory of time
+ * @sep: SEP device we want the address from
+ *
+ * Return the address of the two dwords in memory used for time
+ * setting.
+ */
+
+static u32 *sep_time_address(struct sep_device *sep)
+{
+ return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
+}
+
+/**
+ * sep_set_time - set the SEP time
+ * @sep: the SEP we are setting the time for
+ *
+ * Calculates time and sets it at the predefined address.
+ * Called with the sep mutex held.
+ */
+static unsigned long sep_set_time(struct sep_device *sep)
+{
+ struct timeval time;
+ u32 *time_addr; /* address of time as seen by the kernel */
+
+
+ dbg("sep:sep_set_time start\n");
+
+ do_gettimeofday(&time);
+
+ /* set value in the SYSTEM MEMORY offset */
+ time_addr = sep_time_address(sep);
+
+ time_addr[0] = SEP_TIME_VAL_TOKEN;
+ time_addr[1] = time.tv_sec;
+
+ edbg("SEP Driver:time.tv_sec is %lu\n", time.tv_sec);
+ edbg("SEP Driver:time_addr is %p\n", time_addr);
+ edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
+
+ return time.tv_sec;
+}
+
+/**
+ * sep_dump_message - dump the message that is pending
+ * @sep: sep device
+ *
+ * Dump out the message pending in the shared message area
+ */
+
+static void sep_dump_message(struct sep_device *sep)
+{
+ int count;
+ for (count = 0; count < 12 * 4; count += 4)
+ edbg("Word %d of the message is %u\n", count, *((u32 *) (sep->shared_addr + count)));
+}
+
+/**
+ * sep_send_command_handler - kick off a command
+ * @sep: sep being signalled
+ *
+ * This function raises interrupt to SEP that signals that is has a new
+ * command from the host
+ */
+
+static void sep_send_command_handler(struct sep_device *sep)
+{
+ dbg("sep:sep_send_command_handler start\n");
+
+ mutex_lock(&sep_mutex);
+ sep_set_time(sep);
+
+ /* FIXME: flush cache */
+ flush_cache_all();
+
+ sep_dump_message(sep);
+ /* update counter */
+ sep->send_ct++;
+ /* send interrupt to SEP */
+ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
+ dbg("SEP Driver:<-------- sep_send_command_handler end\n");
+ mutex_unlock(&sep_mutex);
+ return;
+}
+
+/**
+ * sep_send_reply_command_handler - kick off a command reply
+ * @sep: sep being signalled
+ *
+ * This function raises interrupt to SEP that signals that is has a new
+ * command from the host
+ */
+
+static void sep_send_reply_command_handler(struct sep_device *sep)
+{
+ dbg("sep:sep_send_reply_command_handler start\n");
+
+ /* flash cache */
+ flush_cache_all();
+
+ sep_dump_message(sep);
+
+ mutex_lock(&sep_mutex);
+ sep->send_ct++; /* update counter */
+ /* send the interrupt to SEP */
+ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct);
+ /* update both counters */
+ sep->send_ct++;
+ sep->reply_ct++;
+ mutex_unlock(&sep_mutex);
+ dbg("sep: sep_send_reply_command_handler end\n");
+}
+
+/*
+ This function handles the allocate data pool memory request
+ This function returns calculates the bus address of the
+ allocated memory, and the offset of this area from the mapped address.
+ Therefore, the FVOs in user space can calculate the exact virtual
+ address of this allocated memory
+*/
+static int sep_allocate_data_pool_memory_handler(struct sep_device *sep,
+ unsigned long arg)
+{
+ int error;
+ struct sep_driver_alloc_t command_args;
+
+ dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n");
+
+ error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t));
+ if (error) {
+ error = -EFAULT;
+ goto end_function;
+ }
+
+ /* allocate memory */
+ if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
+ error = -ENOMEM;
+ goto end_function;
+ }
+
+ /* set the virtual and bus address */
+ command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
+ command_args.phys_address = sep->shared_bus + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
+
+ /* write the memory back to the user space */
+ error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t));
+ if (error) {
+ error = -EFAULT;
+ goto end_function;
+ }
+
+ /* set the allocation */
+ sep->data_pool_bytes_allocated += command_args.num_bytes;
+
+end_function:
+ dbg("SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n");
+ return error;
+}
+
+/*
+ This function handles write into allocated data pool command
+*/
+static int sep_write_into_data_pool_handler(struct sep_device *sep, unsigned long arg)
+{
+ int error;
+ void *virt_address;
+ unsigned long va;
+ unsigned long app_in_address;
+ unsigned long num_bytes;
+ void *data_pool_area_addr;
+
+ dbg("SEP Driver:--------> sep_write_into_data_pool_handler start\n");
+
+ /* get the application address */
+ error = get_user(app_in_address, &(((struct sep_driver_write_t *) arg)->app_address));
+ if (error)
+ goto end_function;
+
+ /* get the virtual kernel address address */
+ error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
+ if (error)
+ goto end_function;
+ virt_address = (void *)va;
+
+ /* get the number of bytes */
+ error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
+ if (error)
+ goto end_function;
+
+ /* calculate the start of the data pool */
+ data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
+
+
+ /* check that the range of the virtual kernel address is correct */
+ if (virt_address < data_pool_area_addr || virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)) {
+ error = -EINVAL;
+ goto end_function;
+ }
+ /* copy the application data */
+ error = copy_from_user(virt_address, (void *) app_in_address, num_bytes);
+ if (error)
+ error = -EFAULT;
+end_function:
+ dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n");
+ return error;
+}
+
+/*
+ this function handles the read from data pool command
+*/
+static int sep_read_from_data_pool_handler(struct sep_device *sep, unsigned long arg)
+{
+ int error;
+ /* virtual address of dest application buffer */
+ unsigned long app_out_address;
+ /* virtual address of the data pool */
+ unsigned long va;
+ void *virt_address;
+ unsigned long num_bytes;
+ void *data_pool_area_addr;
+
+ dbg("SEP Driver:--------> sep_read_from_data_pool_handler start\n");
+
+ /* get the application address */
+ error = get_user(app_out_address, &(((struct sep_driver_write_t *) arg)->app_address));
+ if (error)
+ goto end_function;
+
+ /* get the virtual kernel address address */
+ error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
+ if (error)
+ goto end_function;
+ virt_address = (void *)va;
+
+ /* get the number of bytes */
+ error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
+ if (error)
+ goto end_function;
+
+ /* calculate the start of the data pool */
+ data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
+
+ /* FIXME: These are incomplete all over the driver: what about + len
+ and when doing that also overflows */
+ /* check that the range of the virtual kernel address is correct */
+ if (virt_address < data_pool_area_addr || virt_address > data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
+ error = -EINVAL;
+ goto end_function;
+ }
+
+ /* copy the application data */
+ error = copy_to_user((void *) app_out_address, virt_address, num_bytes);
+ if (error)
+ error = -EFAULT;
+end_function:
+ dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n");
+ return error;
+}
+
+/*
+ This function releases all the application virtual buffer physical pages,
+ that were previously locked
+*/
+static int sep_free_dma_pages(struct page **page_array_ptr, unsigned long num_pages, unsigned long dirtyFlag)
+{
+ unsigned long count;
+
+ if (dirtyFlag) {
+ for (count = 0; count < num_pages; count++) {
+ /* the out array was written, therefore the data was changed */
+ if (!PageReserved(page_array_ptr[count]))
+ SetPageDirty(page_array_ptr[count]);
+ page_cache_release(page_array_ptr[count]);
+ }
+ } else {
+ /* free in pages - the data was only read, therefore no update was done
+ on those pages */
+ for (count = 0; count < num_pages; count++)
+ page_cache_release(page_array_ptr[count]);
+ }
+
+ if (page_array_ptr)
+ /* free the array */
+ kfree(page_array_ptr);
+
+ return 0;
+}
+
+/*
+ This function locks all the physical pages of the kernel virtual buffer
+ and construct a basic lli array, where each entry holds the physical
+ page address and the size that application data holds in this physical pages
+*/
+static int sep_lock_kernel_pages(struct sep_device *sep,
+ unsigned long kernel_virt_addr,
+ unsigned long data_size,
+ unsigned long *num_pages_ptr,
+ struct sep_lli_entry_t **lli_array_ptr,
+ struct page ***page_array_ptr)
+{
+ int error = 0;
+ /* the the page of the end address of the user space buffer */
+ unsigned long end_page;
+ /* the page of the start address of the user space buffer */
+ unsigned long start_page;
+ /* the range in pages */
+ unsigned long num_pages;
+ struct sep_lli_entry_t *lli_array;
+ /* next kernel address to map */
+ unsigned long next_kernel_address;
+ unsigned long count;
+
+ dbg("SEP Driver:--------> sep_lock_kernel_pages start\n");
+
+ /* set start and end pages and num pages */
+ end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT;
+ start_page = kernel_virt_addr >> PAGE_SHIFT;
+ num_pages = end_page - start_page + 1;
+
+ edbg("SEP Driver: kernel_virt_addr is %08lx\n", kernel_virt_addr);
+ edbg("SEP Driver: data_size is %lu\n", data_size);
+ edbg("SEP Driver: start_page is %lx\n", start_page);
+ edbg("SEP Driver: end_page is %lx\n", end_page);
+ edbg("SEP Driver: num_pages is %lu\n", num_pages);
+
+ lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
+ if (!lli_array) {
+ edbg("SEP Driver: kmalloc for lli_array failed\n");
+ error = -ENOMEM;
+ goto end_function;
+ }
+
+ /* set the start address of the first page - app data may start not at
+ the beginning of the page */
+ lli_array[0].physical_address = (unsigned long) virt_to_phys((unsigned long *) kernel_virt_addr);
+
+ /* check that not all the data is in the first page only */
+ if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size)
+ lli_array[0].block_size = data_size;
+ else
+ lli_array[0].block_size = PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK));
+
+ /* debug print */
+ dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
+
+ /* advance the address to the start of the next page */
+ next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE;
+
+ /* go from the second page to the prev before last */
+ for (count = 1; count < (num_pages - 1); count++) {
+ lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
+ lli_array[count].block_size = PAGE_SIZE;
+
+ edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
+ next_kernel_address += PAGE_SIZE;
+ }
+
+ /* if more then 1 pages locked - then update for the last page size needed */
+ if (num_pages > 1) {
+ /* update the address of the last page */
+ lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
+
+ /* set the size of the last page */
+ lli_array[count].block_size = (kernel_virt_addr + data_size) & (~PAGE_MASK);
+
+ if (lli_array[count].block_size == 0) {
+ dbg("app_virt_addr is %08lx\n", kernel_virt_addr);
+ dbg("data_size is %lu\n", data_size);
+ while (1);
+ }
+
+ edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
+ }
+ /* set output params */
+ *lli_array_ptr = lli_array;
+ *num_pages_ptr = num_pages;
+ *page_array_ptr = 0;
+end_function:
+ dbg("SEP Driver:<-------- sep_lock_kernel_pages end\n");
+ return 0;
+}
+
+/*
+ This function locks all the physical pages of the application virtual buffer
+ and construct a basic lli array, where each entry holds the physical page
+ address and the size that application data holds in this physical pages
+*/
+static int sep_lock_user_pages(struct sep_device *sep,
+ unsigned long app_virt_addr,
+ unsigned long data_size,
+ unsigned long *num_pages_ptr,
+ struct sep_lli_entry_t **lli_array_ptr,
+ struct page ***page_array_ptr)
+{
+ int error = 0;
+ /* the the page of the end address of the user space buffer */
+ unsigned long end_page;
+ /* the page of the start address of the user space buffer */
+ unsigned long start_page;
+ /* the range in pages */
+ unsigned long num_pages;
+ struct page **page_array;
+ struct sep_lli_entry_t *lli_array;
+ unsigned long count;
+ int result;
+
+ dbg("SEP Driver:--------> sep_lock_user_pages start\n");
+
+ /* set start and end pages and num pages */
+ end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
+ start_page = app_virt_addr >> PAGE_SHIFT;
+ num_pages = end_page - start_page + 1;
+
+ edbg("SEP Driver: app_virt_addr is %08lx\n", app_virt_addr);
+ edbg("SEP Driver: data_size is %lu\n", data_size);
+ edbg("SEP Driver: start_page is %lu\n", start_page);
+ edbg("SEP Driver: end_page is %lu\n", end_page);
+ edbg("SEP Driver: num_pages is %lu\n", num_pages);
+
+ /* allocate array of pages structure pointers */
+ page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC);
+ if (!page_array) {
+ edbg("SEP Driver: kmalloc for page_array failed\n");
+
+ error = -ENOMEM;
+ goto end_function;
+ }
+
+ lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
+ if (!lli_array) {
+ edbg("SEP Driver: kmalloc for lli_array failed\n");
+
+ error = -ENOMEM;
+ goto end_function_with_error1;
+ }
+
+ /* convert the application virtual address into a set of physical */
+ down_read(¤t->mm->mmap_sem);
+ result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, page_array, 0);
+ up_read(¤t->mm->mmap_sem);
+
+ /* check the number of pages locked - if not all then exit with error */
+ if (result != num_pages) {
+ dbg("SEP Driver: not all pages locked by get_user_pages\n");
+
+ error = -ENOMEM;
+ goto end_function_with_error2;
+ }
+
+ /* flush the cache */
+ for (count = 0; count < num_pages; count++)
+ flush_dcache_page(page_array[count]);
+
+ /* set the start address of the first page - app data may start not at
+ the beginning of the page */
+ lli_array[0].physical_address = ((unsigned long) page_to_phys(page_array[0])) + (app_virt_addr & (~PAGE_MASK));
+
+ /* check that not all the data is in the first page only */
+ if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
+ lli_array[0].block_size = data_size;
+ else
+ lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
+
+ /* debug print */
+ dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
+
+ /* go from the second page to the prev before last */
+ for (count = 1; count < (num_pages - 1); count++) {
+ lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
+ lli_array[count].block_size = PAGE_SIZE;
+
+ edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
+ }
+
+ /* if more then 1 pages locked - then update for the last page size needed */
+ if (num_pages > 1) {
+ /* update the address of the last page */
+ lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
+
+ /* set the size of the last page */
+ lli_array[count].block_size = (app_virt_addr + data_size) & (~PAGE_MASK);
+
+ if (lli_array[count].block_size == 0) {
+ dbg("app_virt_addr is %08lx\n", app_virt_addr);
+ dbg("data_size is %lu\n", data_size);
+ while (1);
+ }
+ edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n",
+ count, lli_array[count].physical_address,
+ count, lli_array[count].block_size);
+ }
+
+ /* set output params */
+ *lli_array_ptr = lli_array;
+ *num_pages_ptr = num_pages;
+ *page_array_ptr = page_array;
+ goto end_function;
+
+end_function_with_error2:
+ /* release the cache */
+ for (count = 0; count < num_pages; count++)
+ page_cache_release(page_array[count]);
+ kfree(lli_array);
+end_function_with_error1:
+ kfree(page_array);
+end_function:
+ dbg("SEP Driver:<-------- sep_lock_user_pages end\n");
+ return 0;
+}
+
+
+/*
+ this function calculates the size of data that can be inserted into the lli
+ table from this array the condition is that either the table is full
+ (all etnries are entered), or there are no more entries in the lli array
+*/
+static unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries)
+{
+ unsigned long table_data_size = 0;
+ unsigned long counter;
+
+ /* calculate the data in the out lli table if till we fill the whole
+ table or till the data has ended */
+ for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && (counter < num_array_entries); counter++)
+ table_data_size += lli_in_array_ptr[counter].block_size;
+ return table_data_size;
+}
+
+/*
+ this functions builds ont lli table from the lli_array according to
+ the given size of data
+*/
+static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size)
+{
+ unsigned long curr_table_data_size;
+ /* counter of lli array entry */
+ unsigned long array_counter;
+
+ dbg("SEP Driver:--------> sep_build_lli_table start\n");
+
+ /* init currrent table data size and lli array entry counter */
+ curr_table_data_size = 0;
+ array_counter = 0;
+ *num_table_entries_ptr = 1;
+
+ edbg("SEP Driver:table_data_size is %lu\n", table_data_size);
+
+ /* fill the table till table size reaches the needed amount */
+ while (curr_table_data_size < table_data_size) {
+ /* update the number of entries in table */
+ (*num_table_entries_ptr)++;
+
+ lli_table_ptr->physical_address = lli_array_ptr[array_counter].physical_address;
+ lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size;
+ curr_table_data_size += lli_table_ptr->block_size;
+
+ edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
+ edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
+ edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
+
+ /* check for overflow of the table data */
+ if (curr_table_data_size > table_data_size) {
+ edbg("SEP Driver:curr_table_data_size > table_data_size\n");
+
+ /* update the size of block in the table */
+ lli_table_ptr->block_size -= (curr_table_data_size - table_data_size);
+
+ /* update the physical address in the lli array */
+ lli_array_ptr[array_counter].physical_address += lli_table_ptr->block_size;
+
+ /* update the block size left in the lli array */
+ lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size);
+ } else
+ /* advance to the next entry in the lli_array */
+ array_counter++;
+
+ edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
+ edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
+
+ /* move to the next entry in table */
+ lli_table_ptr++;
+ }
+
+ /* set the info entry to default */
+ lli_table_ptr->physical_address = 0xffffffff;
+ lli_table_ptr->block_size = 0;
+
+ edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
+ edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
+ edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
+
+ /* set the output parameter */
+ *num_processed_entries_ptr += array_counter;
+
+ edbg("SEP Driver:*num_processed_entries_ptr is %lu\n", *num_processed_entries_ptr);
+ dbg("SEP Driver:<-------- sep_build_lli_table end\n");
+ return;
+}
+
+/*
+ this function goes over the list of the print created tables and
+ prints all the data
+*/
+static void sep_debug_print_lli_tables(struct sep_device *sep, struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size)
+{
+ unsigned long table_count;
+ unsigned long entries_count;
+
+ dbg("SEP Driver:--------> sep_debug_print_lli_tables start\n");
+
+ table_count = 1;
+ while ((unsigned long) lli_table_ptr != 0xffffffff) {
+ edbg("SEP Driver: lli table %08lx, table_data_size is %lu\n", table_count, table_data_size);
+ edbg("SEP Driver: num_table_entries is %lu\n", num_table_entries);
+
+ /* print entries of the table (without info entry) */
+ for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) {
+ edbg("SEP Driver:lli_table_ptr address is %08lx\n", (unsigned long) lli_table_ptr);
+ edbg("SEP Driver:phys address is %08lx block size is %lu\n", lli_table_ptr->physical_address, lli_table_ptr->block_size);
+ }
+
+ /* point to the info entry */
+ lli_table_ptr--;
+
+ edbg("SEP Driver:phys lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
+ edbg("SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
+
+
+ table_data_size = lli_table_ptr->block_size & 0xffffff;
+ num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;
+ lli_table_ptr = (struct sep_lli_entry_t *)
+ (lli_table_ptr->physical_address);
+
+ edbg("SEP Driver:phys table_data_size is %lu num_table_entries is %lu lli_table_ptr is%lu\n", table_data_size, num_table_entries, (unsigned long) lli_table_ptr);
+
+ if ((unsigned long) lli_table_ptr != 0xffffffff)
+ lli_table_ptr = (struct sep_lli_entry_t *) sep_shared_bus_to_virt(sep, (unsigned long) lli_table_ptr);
+
+ table_count++;
+ }
+ dbg("SEP Driver:<-------- sep_debug_print_lli_tables end\n");
+}
+
+
+/*
+ This function prepares only input DMA table for synhronic symmetric
+ operations (HASH)
+*/
+static int sep_prepare_input_dma_table(struct sep_device *sep,
+ unsigned long app_virt_addr,
+ unsigned long data_size,
+ unsigned long block_size,
+ unsigned long *lli_table_ptr,
+ unsigned long *num_entries_ptr,
+ unsigned long *table_data_size_ptr,
+ bool isKernelVirtualAddress)
+{
+ /* pointer to the info entry of the table - the last entry */
+ struct sep_lli_entry_t *info_entry_ptr;
+ /* array of pointers ot page */
+ struct sep_lli_entry_t *lli_array_ptr;
+ /* points to the first entry to be processed in the lli_in_array */
+ unsigned long current_entry;
+ /* num entries in the virtual buffer */
+ unsigned long sep_lli_entries;
+ /* lli table pointer */
+ struct sep_lli_entry_t *in_lli_table_ptr;
+ /* the total data in one table */
+ unsigned long table_data_size;
+ /* number of entries in lli table */
+ unsigned long num_entries_in_table;
+ /* next table address */
+ void *lli_table_alloc_addr;
+ unsigned long result;
+
+ dbg("SEP Driver:--------> sep_prepare_input_dma_table start\n");
+
+ edbg("SEP Driver:data_size is %lu\n", data_size);
+ edbg("SEP Driver:block_size is %lu\n", block_size);
+
+ /* initialize the pages pointers */
+ sep->in_page_array = 0;
+ sep->in_num_pages = 0;
+
+ if (data_size == 0) {
+ /* special case - created 2 entries table with zero data */
+ in_lli_table_ptr = (struct sep_lli_entry_t *) (sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES);
+ /* FIXME: Should the entry below not be for _bus */
+ in_lli_table_ptr->physical_address = (unsigned long)sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+ in_lli_table_ptr->block_size = 0;
+
+ in_lli_table_ptr++;
+ in_lli_table_ptr->physical_address = 0xFFFFFFFF;
+ in_lli_table_ptr->block_size = 0;
+
+ *lli_table_ptr = sep->shared_bus + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+ *num_entries_ptr = 2;
+ *table_data_size_ptr = 0;
+
+ goto end_function;
+ }
+
+ /* check if the pages are in Kernel Virtual Address layout */
+ if (isKernelVirtualAddress == true)
+ /* lock the pages of the kernel buffer and translate them to pages */
+ result = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
+ else
+ /* lock the pages of the user buffer and translate them to pages */
+ result = sep_lock_user_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
+
+ if (result)
+ return result;
+
+ edbg("SEP Driver:output sep->in_num_pages is %lu\n", sep->in_num_pages);
+
+ current_entry = 0;
+ info_entry_ptr = 0;
+ sep_lli_entries = sep->in_num_pages;
+
+ /* initiate to point after the message area */
+ lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+
+ /* loop till all the entries in in array are not processed */
+ while (current_entry < sep_lli_entries) {
+ /* set the new input and output tables */
+ in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
+
+ lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+ /* calculate the maximum size of data for input table */
+ table_data_size = sep_calculate_lli_table_max_size(&lli_array_ptr[current_entry], (sep_lli_entries - current_entry));
+
+ /* now calculate the table size so that it will be module block size */
+ table_data_size = (table_data_size / block_size) * block_size;
+
+ edbg("SEP Driver:output table_data_size is %lu\n", table_data_size);
+
+ /* construct input lli table */
+ sep_build_lli_table(&lli_array_ptr[current_entry], in_lli_table_ptr, ¤t_entry, &num_entries_in_table, table_data_size);
+
+ if (info_entry_ptr == 0) {
+ /* set the output parameters to physical addresses */
+ *lli_table_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
+ *num_entries_ptr = num_entries_in_table;
+ *table_data_size_ptr = table_data_size;
+
+ edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_ptr);
+ } else {
+ /* update the info entry of the previous in table */
+ info_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
+ info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
+ }
+
+ /* save the pointer to the info entry of the current tables */
+ info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
+ }
+
+ /* print input tables */
+ sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
+ sep_shared_bus_to_virt(sep, *lli_table_ptr), *num_entries_ptr, *table_data_size_ptr);
+
+ /* the array of the pages */
+ kfree(lli_array_ptr);
+end_function:
+ dbg("SEP Driver:<-------- sep_prepare_input_dma_table end\n");
+ return 0;
+
+}
+
+/*
+ This function creates the input and output dma tables for
+ symmetric operations (AES/DES) according to the block size from LLI arays
+*/
+static int sep_construct_dma_tables_from_lli(struct sep_device *sep,
+ struct sep_lli_entry_t *lli_in_array,
+ unsigned long sep_in_lli_entries,
+ struct sep_lli_entry_t *lli_out_array,
+ unsigned long sep_out_lli_entries,
+ unsigned long block_size, unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr)
+{
+ /* points to the area where next lli table can be allocated: keep void *
+ as there is pointer scaling to fix otherwise */
+ void *lli_table_alloc_addr;
+ /* input lli table */
+ struct sep_lli_entry_t *in_lli_table_ptr;
+ /* output lli table */
+ struct sep_lli_entry_t *out_lli_table_ptr;
+ /* pointer to the info entry of the table - the last entry */
+ struct sep_lli_entry_t *info_in_entry_ptr;
+ /* pointer to the info entry of the table - the last entry */
+ struct sep_lli_entry_t *info_out_entry_ptr;
+ /* points to the first entry to be processed in the lli_in_array */
+ unsigned long current_in_entry;
+ /* points to the first entry to be processed in the lli_out_array */
+ unsigned long current_out_entry;
+ /* max size of the input table */
+ unsigned long in_table_data_size;
+ /* max size of the output table */
+ unsigned long out_table_data_size;
+ /* flag te signifies if this is the first tables build from the arrays */
+ unsigned long first_table_flag;
+ /* the data size that should be in table */
+ unsigned long table_data_size;
+ /* number of etnries in the input table */
+ unsigned long num_entries_in_table;
+ /* number of etnries in the output table */
+ unsigned long num_entries_out_table;
+
+ dbg("SEP Driver:--------> sep_construct_dma_tables_from_lli start\n");
+
+ /* initiate to pint after the message area */
+ lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+
+ current_in_entry = 0;
+ current_out_entry = 0;
+ first_table_flag = 1;
+ info_in_entry_ptr = 0;
+ info_out_entry_ptr = 0;
+
+ /* loop till all the entries in in array are not processed */
+ while (current_in_entry < sep_in_lli_entries) {
+ /* set the new input and output tables */
+ in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
+
+ lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+ /* set the first output tables */
+ out_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
+
+ lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+ /* calculate the maximum size of data for input table */
+ in_table_data_size = sep_calculate_lli_table_max_size(&lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry));
+
+ /* calculate the maximum size of data for output table */
+ out_table_data_size = sep_calculate_lli_table_max_size(&lli_out_array[current_out_entry], (sep_out_lli_entries - current_out_entry));
+
+ edbg("SEP Driver:in_table_data_size is %lu\n", in_table_data_size);
+ edbg("SEP Driver:out_table_data_size is %lu\n", out_table_data_size);
+
+ /* check where the data is smallest */
+ table_data_size = in_table_data_size;
+ if (table_data_size > out_table_data_size)
+ table_data_size = out_table_data_size;
+
+ /* now calculate the table size so that it will be module block size */
+ table_data_size = (table_data_size / block_size) * block_size;
+
+ dbg("SEP Driver:table_data_size is %lu\n", table_data_size);
+
+ /* construct input lli table */
+ sep_build_lli_table(&lli_in_array[current_in_entry], in_lli_table_ptr, ¤t_in_entry, &num_entries_in_table, table_data_size);
+
+ /* construct output lli table */
+ sep_build_lli_table(&lli_out_array[current_out_entry], out_lli_table_ptr, ¤t_out_entry, &num_entries_out_table, table_data_size);
+
+ /* if info entry is null - this is the first table built */
+ if (info_in_entry_ptr == 0) {
+ /* set the output parameters to physical addresses */
+ *lli_table_in_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
+ *in_num_entries_ptr = num_entries_in_table;
+ *lli_table_out_ptr = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
+ *out_num_entries_ptr = num_entries_out_table;
+ *table_data_size_ptr = table_data_size;
+
+ edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr);
+ edbg("SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr);
+ } else {
+ /* update the info entry of the previous in table */
+ info_in_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
+ info_in_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
+
+ /* update the info entry of the previous in table */
+ info_out_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
+ info_out_entry_ptr->block_size = ((num_entries_out_table) << 24) | (table_data_size);
+ }
+
+ /* save the pointer to the info entry of the current tables */
+ info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
+ info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1;
+
+ edbg("SEP Driver:output num_entries_out_table is %lu\n", (unsigned long) num_entries_out_table);
+ edbg("SEP Driver:output info_in_entry_ptr is %lu\n", (unsigned long) info_in_entry_ptr);
+ edbg("SEP Driver:output info_out_entry_ptr is %lu\n", (unsigned long) info_out_entry_ptr);
+ }
+
+ /* print input tables */
+ sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
+ sep_shared_bus_to_virt(sep, *lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr);
+ /* print output tables */
+ sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
+ sep_shared_bus_to_virt(sep, *lli_table_out_ptr), *out_num_entries_ptr, *table_data_size_ptr);
+ dbg("SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n");
+ return 0;
+}
+
+
+/*
+ This function builds input and output DMA tables for synhronic
+ symmetric operations (AES, DES). It also checks that each table
+ is of the modular block size
+*/
+static int sep_prepare_input_output_dma_table(struct sep_device *sep,
+ unsigned long app_virt_in_addr,
+ unsigned long app_virt_out_addr,
+ unsigned long data_size,
+ unsigned long block_size,
+ unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress)
+{
+ /* array of pointers of page */
+ struct sep_lli_entry_t *lli_in_array;
+ /* array of pointers of page */
+ struct sep_lli_entry_t *lli_out_array;
+ int result = 0;
+
+ dbg("SEP Driver:--------> sep_prepare_input_output_dma_table start\n");
+
+ /* initialize the pages pointers */
+ sep->in_page_array = 0;
+ sep->out_page_array = 0;
+
+ /* check if the pages are in Kernel Virtual Address layout */
+ if (isKernelVirtualAddress == true) {
+ /* lock the pages of the kernel buffer and translate them to pages */
+ result = sep_lock_kernel_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
+ if (result) {
+ edbg("SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n");
+ goto end_function;
+ }
+ } else {
+ /* lock the pages of the user buffer and translate them to pages */
+ result = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
+ if (result) {
+ edbg("SEP Driver: sep_lock_user_pages for input virtual buffer failed\n");
+ goto end_function;
+ }
+ }
+
+ if (isKernelVirtualAddress == true) {
+ result = sep_lock_kernel_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
+ if (result) {
+ edbg("SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n");
+ goto end_function_with_error1;
+ }
+ } else {
+ result = sep_lock_user_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
+ if (result) {
+ edbg("SEP Driver: sep_lock_user_pages for output virtual buffer failed\n");
+ goto end_function_with_error1;
+ }
+ }
+ edbg("sep->in_num_pages is %lu\n", sep->in_num_pages);
+ edbg("sep->out_num_pages is %lu\n", sep->out_num_pages);
+ edbg("SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
+
+
+ /* call the fucntion that creates table from the lli arrays */
+ result = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->in_num_pages, lli_out_array, sep->out_num_pages, block_size, lli_table_in_ptr, lli_table_out_ptr, in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr);
+ if (result) {
+ edbg("SEP Driver: sep_construct_dma_tables_from_lli failed\n");
+ goto end_function_with_error2;
+ }
+
+ /* fall through - free the lli entry arrays */
+ dbg("in_num_entries_ptr is %08lx\n", *in_num_entries_ptr);
+ dbg("out_num_entries_ptr is %08lx\n", *out_num_entries_ptr);
+ dbg("table_data_size_ptr is %08lx\n", *table_data_size_ptr);
+end_function_with_error2:
+ kfree(lli_out_array);
+end_function_with_error1:
+ kfree(lli_in_array);
+end_function:
+ dbg("SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", (int) result);
+ return result;
+
+}
+
+/*
+ this function handles tha request for creation of the DMA table
+ for the synchronic symmetric operations (AES,DES)
+*/
+static int sep_create_sync_dma_tables_handler(struct sep_device *sep,
+ unsigned long arg)
+{
+ int error;
+ /* command arguments */
+ struct sep_driver_build_sync_table_t command_args;
+
+ dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n");
+
+ error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t));
+ if (error) {
+ error = -EFAULT;
+ goto end_function;
+ }
+
+ edbg("app_in_address is %08lx\n", command_args.app_in_address);
+ edbg("app_out_address is %08lx\n", command_args.app_out_address);
+ edbg("data_size is %lu\n", command_args.data_in_size);
+ edbg("block_size is %lu\n", command_args.block_size);
+
+ /* check if we need to build only input table or input/output */
+ if (command_args.app_out_address)
+ /* prepare input and output tables */
+ error = sep_prepare_input_output_dma_table(sep,
+ command_args.app_in_address,
+ command_args.app_out_address,
+ command_args.data_in_size,
+ command_args.block_size,
+ &command_args.in_table_address,
+ &command_args.out_table_address, &command_args.in_table_num_entries, &command_args.out_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
+ else
+ /* prepare input tables */
+ error = sep_prepare_input_dma_table(sep,
+ command_args.app_in_address,
+ command_args.data_in_size, command_args.block_size, &command_args.in_table_address, &command_args.in_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
+
+ if (error)
+ goto end_function;
+ /* copy to user */
+ if (copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_build_sync_table_t)))
+ error = -EFAULT;
+end_function:
+ dbg("SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n");
+ return error;
+}
+
+/*
+ this function handles the request for freeing dma table for synhronic actions
+*/
+static int sep_free_dma_table_data_handler(struct sep_device *sep)
+{
+ dbg("SEP Driver:--------> sep_free_dma_table_data_handler start\n");
+
+ /* free input pages array */
+ sep_free_dma_pages(sep->in_page_array, sep->in_num_pages, 0);
+
+ /* free output pages array if needed */
+ if (sep->out_page_array)
+ sep_free_dma_pages(sep->out_page_array, sep->out_num_pages, 1);
+
+ /* reset all the values */
+ sep->in_page_array = 0;
+ sep->out_page_array = 0;
+ sep->in_num_pages = 0;
+ sep->out_num_pages = 0;
+ dbg("SEP Driver:<-------- sep_free_dma_table_data_handler end\n");
+ return 0;
+}
+
+/*
+ this function find a space for the new flow dma table
+*/
+static int sep_find_free_flow_dma_table_space(struct sep_device *sep,
+ unsigned long **table_address_ptr)
+{
+ int error = 0;
+ /* pointer to the id field of the flow dma table */
+ unsigned long *start_table_ptr;
+ /* Do not make start_addr unsigned long * unless fixing the offset
+ computations ! */
+ void *flow_dma_area_start_addr;
+ unsigned long *flow_dma_area_end_addr;
+ /* maximum table size in words */
+ unsigned long table_size_in_words;
+
+ /* find the start address of the flow DMA table area */
+ flow_dma_area_start_addr = sep->shared_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+
+ /* set end address of the flow table area */
+ flow_dma_area_end_addr = flow_dma_area_start_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES;
+
+ /* set table size in words */
+ table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2;
+
+ /* set the pointer to the start address of DMA area */
+ start_table_ptr = flow_dma_area_start_addr;
+
+ /* find the space for the next table */
+ while (((*start_table_ptr & 0x7FFFFFFF) != 0) && start_table_ptr < flow_dma_area_end_addr)
+ start_table_ptr += table_size_in_words;
+
+ /* check if we reached the end of floa tables area */
+ if (start_table_ptr >= flow_dma_area_end_addr)
+ error = -1;
+ else
+ *table_address_ptr = start_table_ptr;
+
+ return error;
+}
+
+/*
+ This function creates one DMA table for flow and returns its data,
+ and pointer to its info entry
+*/
+static int sep_prepare_one_flow_dma_table(struct sep_device *sep,
+ unsigned long virt_buff_addr,
+ unsigned long virt_buff_size,
+ struct sep_lli_entry_t *table_data,
+ struct sep_lli_entry_t **info_entry_ptr,
+ struct sep_flow_context_t *flow_data_ptr,
+ bool isKernelVirtualAddress)
+{
+ int error;
+ /* the range in pages */
+ unsigned long lli_array_size;
+ struct sep_lli_entry_t *lli_array;
+ struct sep_lli_entry_t *flow_dma_table_entry_ptr;
+ unsigned long *start_dma_table_ptr;
+ /* total table data counter */
+ unsigned long dma_table_data_count;
+ /* pointer that will keep the pointer to the pages of the virtual buffer */
+ struct page **page_array_ptr;
+ unsigned long entry_count;
+
+ /* find the space for the new table */
+ error = sep_find_free_flow_dma_table_space(sep, &start_dma_table_ptr);
+ if (error)
+ goto end_function;
+
+ /* check if the pages are in Kernel Virtual Address layout */
+ if (isKernelVirtualAddress == true)
+ /* lock kernel buffer in the memory */
+ error = sep_lock_kernel_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
+ else
+ /* lock user buffer in the memory */
+ error = sep_lock_user_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
+
+ if (error)
+ goto end_function;
+
+ /* set the pointer to page array at the beginning of table - this table is
+ now considered taken */
+ *start_dma_table_ptr = lli_array_size;
+
+ /* point to the place of the pages pointers of the table */
+ start_dma_table_ptr++;
+
+ /* set the pages pointer */
+ *start_dma_table_ptr = (unsigned long) page_array_ptr;
+
+ /* set the pointer to the first entry */
+ flow_dma_table_entry_ptr = (struct sep_lli_entry_t *) (++start_dma_table_ptr);
+
+ /* now create the entries for table */
+ for (dma_table_data_count = entry_count = 0; entry_count < lli_array_size; entry_count++) {
+ flow_dma_table_entry_ptr->physical_address = lli_array[entry_count].physical_address;
+
+ flow_dma_table_entry_ptr->block_size = lli_array[entry_count].block_size;
+
+ /* set the total data of a table */
+ dma_table_data_count += lli_array[entry_count].block_size;
+
+ flow_dma_table_entry_ptr++;
+ }
+
+ /* set the physical address */
+ table_data->physical_address = virt_to_phys(start_dma_table_ptr);
+
+ /* set the num_entries and total data size */
+ table_data->block_size = ((lli_array_size + 1) << SEP_NUM_ENTRIES_OFFSET_IN_BITS) | (dma_table_data_count);
+
+ /* set the info entry */
+ flow_dma_table_entry_ptr->physical_address = 0xffffffff;
+ flow_dma_table_entry_ptr->block_size = 0;
+
+ /* set the pointer to info entry */
+ *info_entry_ptr = flow_dma_table_entry_ptr;
+
+ /* the array of the lli entries */
+ kfree(lli_array);
+end_function:
+ return error;
+}
+
+
+
+/*
+ This function creates a list of tables for flow and returns the data for
+ the first and last tables of the list
+*/
+static int sep_prepare_flow_dma_tables(struct sep_device *sep,
+ unsigned long num_virtual_buffers,
+ unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress)
+{
+ int error;
+ unsigned long virt_buff_addr;
+ unsigned long virt_buff_size;
+ struct sep_lli_entry_t table_data;
+ struct sep_lli_entry_t *info_entry_ptr;
+ struct sep_lli_entry_t *prev_info_entry_ptr;
+ unsigned long i;
+
+ /* init vars */
+ error = 0;
+ prev_info_entry_ptr = 0;
+
+ /* init the first table to default */
+ table_data.physical_address = 0xffffffff;
+ first_table_data_ptr->physical_address = 0xffffffff;
+ table_data.block_size = 0;
+
+ for (i = 0; i < num_virtual_buffers; i++) {
+ /* get the virtual buffer address */
+ error = get_user(virt_buff_addr, &first_buff_addr);
+ if (error)
+ goto end_function;
+
+ /* get the virtual buffer size */
+ first_buff_addr++;
+ error = get_user(virt_buff_size, &first_buff_addr);
+ if (error)
+ goto end_function;
+
+ /* advance the address to point to the next pair of address|size */
+ first_buff_addr++;
+
+ /* now prepare the one flow LLI table from the data */
+ error = sep_prepare_one_flow_dma_table(sep, virt_buff_addr, virt_buff_size, &table_data, &info_entry_ptr, flow_data_ptr, isKernelVirtualAddress);
+ if (error)
+ goto end_function;
+
+ if (i == 0) {
+ /* if this is the first table - save it to return to the user
+ application */
+ *first_table_data_ptr = table_data;
+
+ /* set the pointer to info entry */
+ prev_info_entry_ptr = info_entry_ptr;
+ } else {
+ /* not first table - the previous table info entry should
+ be updated */
+ prev_info_entry_ptr->block_size = (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | (table_data.block_size);
+
+ /* set the pointer to info entry */
+ prev_info_entry_ptr = info_entry_ptr;
+ }
+ }
+
+ /* set the last table data */
+ *last_table_data_ptr = table_data;
+end_function:
+ return error;
+}
+
+/*
+ this function goes over all the flow tables connected to the given
+ table and deallocate them
+*/
+static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr)
+{
+ /* id pointer */
+ unsigned long *table_ptr;
+ /* end address of the flow dma area */
+ unsigned long num_entries;
+ unsigned long num_pages;
+ struct page **pages_ptr;
+ /* maximum table size in words */
+ struct sep_lli_entry_t *info_entry_ptr;
+
+ /* set the pointer to the first table */
+ table_ptr = (unsigned long *) first_table_ptr->physical_address;
+
+ /* set the num of entries */
+ num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS)
+ & SEP_NUM_ENTRIES_MASK;
+
+ /* go over all the connected tables */
+ while (*table_ptr != 0xffffffff) {
+ /* get number of pages */
+ num_pages = *(table_ptr - 2);
+
+ /* get the pointer to the pages */
+ pages_ptr = (struct page **) (*(table_ptr - 1));
+
+ /* free the pages */
+ sep_free_dma_pages(pages_ptr, num_pages, 1);
+
+ /* goto to the info entry */
+ info_entry_ptr = ((struct sep_lli_entry_t *) table_ptr) + (num_entries - 1);
+
+ table_ptr = (unsigned long *) info_entry_ptr->physical_address;
+ num_entries = (info_entry_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
+ }
+
+ return;
+}
+
+/**
+ * sep_find_flow_context - find a flow
+ * @sep: the SEP we are working with
+ * @flow_id: flow identifier
+ *
+ * Returns a pointer the matching flow, or NULL if the flow does not
+ * exist.
+ */
+
+static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep,
+ unsigned long flow_id)
+{
+ int count;
+ /*
+ * always search for flow with id default first - in case we
+ * already started working on the flow there can be no situation
+ * when 2 flows are with default flag
+ */
+ for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) {
+ if (sep->flows[count].flow_id == flow_id)
+ return &sep->flows[count];
+ }
+ return NULL;
+}
+
+
+/*
+ this function handles the request to create the DMA tables for flow
+*/
+static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
+ unsigned long arg)
+{
+ int error = -ENOENT;
+ struct sep_driver_build_flow_table_t command_args;
+ /* first table - output */
+ struct sep_lli_entry_t first_table_data;
+ /* dma table data */
+ struct sep_lli_entry_t last_table_data;
+ /* pointer to the info entry of the previuos DMA table */
+ struct sep_lli_entry_t *prev_info_entry_ptr;
+ /* pointer to the flow data strucutre */
+ struct sep_flow_context_t *flow_context_ptr;
+
+ dbg("SEP Driver:--------> sep_create_flow_dma_tables_handler start\n");
+
+ /* init variables */
+ prev_info_entry_ptr = 0;
+ first_table_data.physical_address = 0xffffffff;
+
+ /* find the free structure for flow data */
+ error = -EINVAL;
+ flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID);
+ if (flow_context_ptr == NULL)
+ goto end_function;
+
+ error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t));
+ if (error) {
+ error = -EFAULT;
+ goto end_function;
+ }
+
+ /* create flow tables */
+ error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
+ if (error)
+ goto end_function_with_error;
+
+ /* check if flow is static */
+ if (!command_args.flow_type)
+ /* point the info entry of the last to the info entry of the first */
+ last_table_data = first_table_data;
+
+ /* set output params */
+ command_args.first_table_addr = first_table_data.physical_address;
+ command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
+ command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
+
+ /* send the parameters to user application */
+ error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t));
+ if (error) {
+ error = -EFAULT;
+ goto end_function_with_error;
+ }
+
+ /* all the flow created - update the flow entry with temp id */
+ flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID;
+
+ /* set the processing tables data in the context */
+ if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG)
+ flow_context_ptr->input_tables_in_process = first_table_data;
+ else
+ flow_context_ptr->output_tables_in_process = first_table_data;
+
+ goto end_function;
+
+end_function_with_error:
+ /* free the allocated tables */
+ sep_deallocated_flow_tables(&first_table_data);
+end_function:
+ dbg("SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n");
+ return error;
+}
+
+/*
+ this function handles add tables to flow
+*/
+static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg)
+{
+ int error;
+ unsigned long num_entries;
+ struct sep_driver_add_flow_table_t command_args;
+ struct sep_flow_context_t *flow_context_ptr;
+ /* first dma table data */
+ struct sep_lli_entry_t first_table_data;
+ /* last dma table data */
+ struct sep_lli_entry_t last_table_data;
+ /* pointer to the info entry of the current DMA table */
+ struct sep_lli_entry_t *info_entry_ptr;
+
+ dbg("SEP Driver:--------> sep_add_flow_tables_handler start\n");
+
+ /* get input parameters */
+ error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t));
+ if (error) {
+ error = -EFAULT;
+ goto end_function;
+ }
+
+ /* find the flow structure for the flow id */
+ flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
+ if (flow_context_ptr == NULL)
+ goto end_function;
+
+ /* prepare the flow dma tables */
+ error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
+ if (error)
+ goto end_function_with_error;
+
+ /* now check if there is already an existing add table for this flow */
+ if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) {
+ /* this buffer was for input buffers */
+ if (flow_context_ptr->input_tables_flag) {
+ /* add table already exists - add the new tables to the end
+ of the previous */
+ num_entries = (flow_context_ptr->last_input_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
+
+ info_entry_ptr = (struct sep_lli_entry_t *)
+ (flow_context_ptr->last_input_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
+
+ /* connect to list of tables */
+ *info_entry_ptr = first_table_data;
+
+ /* set the first table data */
+ first_table_data = flow_context_ptr->first_input_table;
+ } else {
+ /* set the input flag */
+ flow_context_ptr->input_tables_flag = 1;
+
+ /* set the first table data */
+ flow_context_ptr->first_input_table = first_table_data;
+ }
+ /* set the last table data */
+ flow_context_ptr->last_input_table = last_table_data;
+ } else { /* this is output tables */
+
+ /* this buffer was for input buffers */
+ if (flow_context_ptr->output_tables_flag) {
+ /* add table already exists - add the new tables to
+ the end of the previous */
+ num_entries = (flow_context_ptr->last_output_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
+
+ info_entry_ptr = (struct sep_lli_entry_t *)
+ (flow_context_ptr->last_output_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
+
+ /* connect to list of tables */
+ *info_entry_ptr = first_table_data;
+
+ /* set the first table data */
+ first_table_data = flow_context_ptr->first_output_table;
+ } else {
+ /* set the input flag */
+ flow_context_ptr->output_tables_flag = 1;
+
+ /* set the first table data */
+ flow_context_ptr->first_output_table = first_table_data;
+ }
+ /* set the last table data */
+ flow_context_ptr->last_output_table = last_table_data;
+ }
+
+ /* set output params */
+ command_args.first_table_addr = first_table_data.physical_address;
+ command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
+ command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
+
+ /* send the parameters to user application */
+ error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t));
+ if (error)
+ error = -EFAULT;
+end_function_with_error:
+ /* free the allocated tables */
+ sep_deallocated_flow_tables(&first_table_data);
+end_function:
+ dbg("SEP Driver:<-------- sep_add_flow_tables_handler end\n");
+ return error;
+}
+
+/*
+ this function add the flow add message to the specific flow
+*/
+static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned long arg)
+{
+ int error;
+ struct sep_driver_add_message_t command_args;
+ struct sep_flow_context_t *flow_context_ptr;
+
+ dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n");
+
+ error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t));
+ if (error) {
+ error = -EFAULT;
+ goto end_function;
+ }
+
+ /* check input */
+ if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) {
+ error = -ENOMEM;
+ goto end_function;
+ }
+
+ /* find the flow context */
+ flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
+ if (flow_context_ptr == NULL)
+ goto end_function;
+
+ /* copy the message into context */
+ flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes;
+ error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes);
+ if (error)
+ error = -EFAULT;
+end_function:
+ dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n");
+ return error;
+}
+
+
+/*
+ this function returns the bus and virtual addresses of the static pool
+*/
+static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg)
+{
+ int error;
+ struct sep_driver_static_pool_addr_t command_args;
+
+ dbg("SEP Driver:--------> sep_get_static_pool_addr_handler start\n");
+
+ /*prepare the output parameters in the struct */
+ command_args.physical_static_address = sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
+ command_args.virtual_static_address = (unsigned long)sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
+
+ edbg("SEP Driver:bus_static_address is %08lx, virtual_static_address %08lx\n", command_args.physical_static_address, command_args.virtual_static_address);
+
+ /* send the parameters to user application */
+ error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t));
+ if (error)
+ error = -EFAULT;
+ dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n");
+ return error;
+}
+
+/*
+ this address gets the offset of the physical address from the start
+ of the mapped area
+*/
+static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsigned long arg)
+{
+ int error;
+ struct sep_driver_get_mapped_offset_t command_args;
+
+ dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n");
+
+ error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t));
+ if (error) {
+ error = -EFAULT;
+ goto end_function;
+ }
+
+ if (command_args.physical_address < sep->shared_bus) {
+ error = -EINVAL;
+ goto end_function;
+ }
+
+ /*prepare the output parameters in the struct */
+ command_args.offset = command_args.physical_address - sep->shared_bus;
+
+ edbg("SEP Driver:bus_address is %08lx, offset is %lu\n", command_args.physical_address, command_args.offset);
+
+ /* send the parameters to user application */
+ error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t));
+ if (error)
+ error = -EFAULT;
+end_function:
+ dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n");
+ return error;
+}
+
+
+/*
+ ?
+*/
+static int sep_start_handler(struct sep_device *sep)
+{
+ unsigned long reg_val;
+ unsigned long error = 0;
+
+ dbg("SEP Driver:--------> sep_start_handler start\n");
+
+ /* wait in polling for message from SEP */
+ do
+ reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+ while (!reg_val);
+
+ /* check the value */
+ if (reg_val == 0x1)
+ /* fatal error - read error status from GPRO */
+ error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
+ dbg("SEP Driver:<-------- sep_start_handler end\n");
+ return error;
+}
+
+/*
+ this function handles the request for SEP initialization
+*/
+static int sep_init_handler(struct sep_device *sep, unsigned long arg)
+{
+ unsigned long message_word;
+ unsigned long *message_ptr;
+ struct sep_driver_init_t command_args;
+ unsigned long counter;
+ unsigned long error;
+ unsigned long reg_val;
+
+ dbg("SEP Driver:--------> sep_init_handler start\n");
+ error = 0;
+
+ error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t));
+ if (error) {
+ error = -EFAULT;
+ goto end_function;
+ }
+ dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user\n");
+
+ /* PATCH - configure the DMA to single -burst instead of multi-burst */
+ /*sep_configure_dma_burst(); */
+
+ dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n");
+
+ message_ptr = (unsigned long *) command_args.message_addr;
+
+ /* set the base address of the SRAM */
+ sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS);
+
+ for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) {
+ get_user(message_word, message_ptr);
+ /* write data to SRAM */
+ sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, message_word);
+ edbg("SEP Driver:message_word is %lu\n", message_word);
+ /* wait for write complete */
+ sep_wait_sram_write(sep);
+ }
+ dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n");
+ /* signal SEP */
+ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1);
+
+ do
+ reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+ while (!(reg_val & 0xFFFFFFFD));
+
+ dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n");
+
+ /* check the value */
+ if (reg_val == 0x1) {
+ edbg("SEP Driver:init failed\n");
+
+ error = sep_read_reg(sep, 0x8060);
+ edbg("SEP Driver:sw monitor is %lu\n", error);
+
+ /* fatal error - read erro status from GPRO */
+ error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
+ edbg("SEP Driver:error is %lu\n", error);
+ }
+end_function:
+ dbg("SEP Driver:<-------- sep_init_handler end\n");
+ return error;
+
+}
+
+/*
+ this function handles the request cache and resident reallocation
+*/
+static int sep_realloc_cache_resident_handler(struct sep_device *sep,
+ unsigned long arg)
+{
+ struct sep_driver_realloc_cache_resident_t command_args;
+ int error;
+
+ /* copy cache and resident to the their intended locations */
+ error = sep_load_firmware(sep);
+ if (error)
+ return error;
+
+ command_args.new_base_addr = sep->shared_bus;
+
+ /* find the new base address according to the lowest address between
+ cache, resident and shared area */
+ if (sep->resident_bus < command_args.new_base_addr)
+ command_args.new_base_addr = sep->resident_bus;
+ if (sep->rar_bus < command_args.new_base_addr)
+ command_args.new_base_addr = sep->rar_bus;
+
+ /* set the return parameters */
+ command_args.new_cache_addr = sep->rar_bus;
+ command_args.new_resident_addr = sep->resident_bus;
+
+ /* set the new shared area */
+ command_args.new_shared_area_addr = sep->shared_bus;
+
+ edbg("SEP Driver:command_args.new_shared_addr is %08llx\n", command_args.new_shared_area_addr);
+ edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr);
+ edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr);
+ edbg("SEP Driver:command_args.new_rar_addr is %08llx\n", command_args.new_cache_addr);
+
+ /* return to user */
+ if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t)))
+ return -EFAULT;
+ return 0;
+}
+
+/**
+ * sep_get_time_handler - time request from user space
+ * @sep: sep we are to set the time for
+ * @arg: pointer to user space arg buffer
+ *
+ * This function reports back the time and the address in the SEP
+ * shared buffer at which it has been placed. (Do we really need this!!!)
+ */
+
+static int sep_get_time_handler(struct sep_device *sep, unsigned long arg)
+{
+ struct sep_driver_get_time_t command_args;
+
+ mutex_lock(&sep_mutex);
+ command_args.time_value = sep_set_time(sep);
+ command_args.time_physical_address = (unsigned long)sep_time_address(sep);
+ mutex_unlock(&sep_mutex);
+ if (copy_to_user((void __user *)arg,
+ &command_args, sizeof(struct sep_driver_get_time_t)))
+ return -EFAULT;
+ return 0;
+
+}
+
+/*
+ This API handles the end transaction request
+*/
+static int sep_end_transaction_handler(struct sep_device *sep, unsigned long arg)
+{
+ dbg("SEP Driver:--------> sep_end_transaction_handler start\n");
+
+#if 0 /*!SEP_DRIVER_POLLING_MODE */
+ /* close IMR */
+ sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
+
+ /* release IRQ line */
+ free_irq(SEP_DIRVER_IRQ_NUM, sep);
+
+ /* lock the sep mutex */
+ mutex_unlock(&sep_mutex);
+#endif
+
+ dbg("SEP Driver:<-------- sep_end_transaction_handler end\n");
+
+ return 0;
+}
+
+
+/**
+ * sep_set_flow_id_handler - handle flow setting
+ * @sep: the SEP we are configuring
+ * @flow_id: the flow we are setting
+ *
+ * This function handler the set flow id command
+ */
+static int sep_set_flow_id_handler(struct sep_device *sep,
+ unsigned long flow_id)
+{
+ int error = 0;
+ struct sep_flow_context_t *flow_data_ptr;
+
+ /* find the flow data structure that was just used for creating new flow
+ - its id should be default */
+
+ mutex_lock(&sep_mutex);
+ flow_data_ptr = sep_find_flow_context(sep, SEP_TEMP_FLOW_ID);
+ if (flow_data_ptr)
+ flow_data_ptr->flow_id = flow_id; /* set flow id */
+ else
+ error = -EINVAL;
+ mutex_unlock(&sep_mutex);
+ return error;
+}
+
+static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int error = 0;
+ struct sep_device *sep = filp->private_data;
+
+ dbg("------------>SEP Driver: ioctl start\n");
+
+ edbg("SEP Driver: cmd is %x\n", cmd);
+
+ switch (cmd) {
+ case SEP_IOCSENDSEPCOMMAND:
+ /* send command to SEP */
+ sep_send_command_handler(sep);
+ edbg("SEP Driver: after sep_send_command_handler\n");
+ break;
+ case SEP_IOCSENDSEPRPLYCOMMAND:
+ /* send reply command to SEP */
+ sep_send_reply_command_handler(sep);
+ break;
+ case SEP_IOCALLOCDATAPOLL:
+ /* allocate data pool */
+ error = sep_allocate_data_pool_memory_handler(sep, arg);
+ break;
+ case SEP_IOCWRITEDATAPOLL:
+ /* write data into memory pool */
+ error = sep_write_into_data_pool_handler(sep, arg);
+ break;
+ case SEP_IOCREADDATAPOLL:
+ /* read data from data pool into application memory */
+ error = sep_read_from_data_pool_handler(sep, arg);
+ break;
+ case SEP_IOCCREATESYMDMATABLE:
+ /* create dma table for synhronic operation */
+ error = sep_create_sync_dma_tables_handler(sep, arg);
+ break;
+ case SEP_IOCCREATEFLOWDMATABLE:
+ /* create flow dma tables */
+ error = sep_create_flow_dma_tables_handler(sep, arg);
+ break;
+ case SEP_IOCFREEDMATABLEDATA:
+ /* free the pages */
+ error = sep_free_dma_table_data_handler(sep);
+ break;
+ case SEP_IOCSETFLOWID:
+ /* set flow id */
+ error = sep_set_flow_id_handler(sep, (unsigned long)arg);
+ break;
+ case SEP_IOCADDFLOWTABLE:
+ /* add tables to the dynamic flow */
+ error = sep_add_flow_tables_handler(sep, arg);
+ break;
+ case SEP_IOCADDFLOWMESSAGE:
+ /* add message of add tables to flow */
+ error = sep_add_flow_tables_message_handler(sep, arg);
+ break;
+ case SEP_IOCSEPSTART:
+ /* start command to sep */
+ error = sep_start_handler(sep);
+ break;
+ case SEP_IOCSEPINIT:
+ /* init command to sep */
+ error = sep_init_handler(sep, arg);
+ break;
+ case SEP_IOCGETSTATICPOOLADDR:
+ /* get the physical and virtual addresses of the static pool */
+ error = sep_get_static_pool_addr_handler(sep, arg);
+ break;
+ case SEP_IOCENDTRANSACTION:
+ error = sep_end_transaction_handler(sep, arg);
+ break;
+ case SEP_IOCREALLOCCACHERES:
+ error = sep_realloc_cache_resident_handler(sep, arg);
+ break;
+ case SEP_IOCGETMAPPEDADDROFFSET:
+ error = sep_get_physical_mapped_offset_handler(sep, arg);
+ break;
+ case SEP_IOCGETIME:
+ error = sep_get_time_handler(sep, arg);
+ break;
+ default:
+ error = -ENOTTY;
+ break;
+ }
+ dbg("SEP Driver:<-------- ioctl end\n");
+ return error;
+}
+
+
+
+#if !SEP_DRIVER_POLLING_MODE
+
+/* handler for flow done interrupt */
+
+static void sep_flow_done_handler(struct work_struct *work)
+{
+ struct sep_flow_context_t *flow_data_ptr;
+
+ /* obtain the mutex */
+ mutex_lock(&sep_mutex);
+
+ /* get the pointer to context */
+ flow_data_ptr = (struct sep_flow_context_t *) work;
+
+ /* free all the current input tables in sep */
+ sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process);
+
+ /* free all the current tables output tables in SEP (if needed) */
+ if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff)
+ sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process);
+
+ /* check if we have additional tables to be sent to SEP only input
+ flag may be checked */
+ if (flow_data_ptr->input_tables_flag) {
+ /* copy the message to the shared RAM and signal SEP */
+ memcpy((void *) flow_data_ptr->message, (void *) sep->shared_addr, flow_data_ptr->message_size_in_bytes);
+
+ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, 0x2);
+ }
+ mutex_unlock(&sep_mutex);
+}
+/*
+ interrupt handler function
+*/
+static irqreturn_t sep_inthandler(int irq, void *dev_id)
+{
+ irqreturn_t int_error;
+ unsigned long reg_val;
+ unsigned long flow_id;
+ struct sep_flow_context_t *flow_context_ptr;
+ struct sep_device *sep = dev_id;
+
+ int_error = IRQ_HANDLED;
+
+ /* read the IRR register to check if this is SEP interrupt */
+ reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
+ edbg("SEP Interrupt - reg is %08lx\n", reg_val);
+
+ /* check if this is the flow interrupt */
+ if (0 /*reg_val & (0x1 << 11) */ ) {
+ /* read GPRO to find out the which flow is done */
+ flow_id = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
+
+ /* find the contex of the flow */
+ flow_context_ptr = sep_find_flow_context(sep, flow_id >> 28);
+ if (flow_context_ptr == NULL)
+ goto end_function_with_error;
+
+ /* queue the work */
+ INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler);
+ queue_work(sep->flow_wq, &flow_context_ptr->flow_wq);
+
+ } else {
+ /* check if this is reply interrupt from SEP */
+ if (reg_val & (0x1 << 13)) {
+ /* update the counter of reply messages */
+ sep->reply_ct++;
+ /* wake up the waiting process */
+ wake_up(&sep_event);
+ } else {
+ int_error = IRQ_NONE;
+ goto end_function;
+ }
+ }
+end_function_with_error:
+ /* clear the interrupt */
+ sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val);
+end_function:
+ return int_error;
+}
+
+#endif
+
+
+
+#if 0
+
+static void sep_wait_busy(struct sep_device *sep)
+{
+ u32 reg;
+
+ do {
+ reg = sep_read_reg(sep, HW_HOST_SEP_BUSY_REG_ADDR);
+ } while (reg);
+}
+
+/*
+ PATCH for configuring the DMA to single burst instead of multi-burst
+*/
+static void sep_configure_dma_burst(struct sep_device *sep)
+{
+#define HW_AHB_RD_WR_BURSTS_REG_ADDR 0x0E10UL
+
+ dbg("SEP Driver:<-------- sep_configure_dma_burst start \n");
+
+ /* request access to registers from SEP */
+ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
+
+ dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg) \n");
+
+ sep_wait_busy(sep);
+
+ dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop) \n");
+
+ /* set the DMA burst register to single burst */
+ sep_write_reg(sep, HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL);
+
+ /* release the sep busy */
+ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL);
+ sep_wait_busy(sep);
+
+ dbg("SEP Driver:<-------- sep_configure_dma_burst done \n");
+
+}
+
+#endif
+
+/*
+ Function that is activated on the successful probe of the SEP device
+*/
+static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ int error = 0;
+ struct sep_device *sep;
+ int counter;
+ int size; /* size of memory for allocation */
+
+ edbg("Sep pci probe starting\n");
+ if (sep_dev != NULL) {
+ dev_warn(&pdev->dev, "only one SEP supported.\n");
+ return -EBUSY;
+ }
+
+ /* enable the device */
+ error = pci_enable_device(pdev);
+ if (error) {
+ edbg("error enabling pci device\n");
+ goto end_function;
+ }
+
+ /* set the pci dev pointer */
+ sep_dev = &sep_instance;
+ sep = &sep_instance;
+
+ edbg("sep->shared_addr = %p\n", sep->shared_addr);
+ /* transaction counter that coordinates the transactions between SEP
+ and HOST */
+ sep->send_ct = 0;
+ /* counter for the messages from sep */
+ sep->reply_ct = 0;
+ /* counter for the number of bytes allocated in the pool
+ for the current transaction */
+ sep->data_pool_bytes_allocated = 0;
+
+ /* calculate the total size for allocation */
+ size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
+ SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
+
+ /* allocate the shared area */
+ if (sep_map_and_alloc_shared_area(sep, size)) {
+ error = -ENOMEM;
+ /* allocation failed */
+ goto end_function_error;
+ }
+ /* now set the memory regions */
+#if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1)
+ /* Note: this test section will need moving before it could ever
+ work as the registers are not yet mapped ! */
+ /* send the new SHARED MESSAGE AREA to the SEP */
+ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);
+
+ /* poll for SEP response */
+ retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
+ while (retval != 0xffffffff && retval != sep->shared_bus)
+ retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
+
+ /* check the return value (register) */
+ if (retval != sep->shared_bus) {
+ error = -ENOMEM;
+ goto end_function_deallocate_sep_shared_area;
+ }
+#endif
+ /* init the flow contextes */
+ for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++)
+ sep->flows[counter].flow_id = SEP_FREE_FLOW_ID;
+
+ sep->flow_wq = create_singlethread_workqueue("sepflowwq");
+ if (sep->flow_wq == NULL) {
+ error = -ENOMEM;
+ edbg("sep_driver:flow queue creation failed\n");
+ goto end_function_deallocate_sep_shared_area;
+ }
+ edbg("SEP Driver: create flow workqueue \n");
+ sep->pdev = pci_dev_get(pdev);
+
+ sep->reg_addr = pci_ioremap_bar(pdev, 0);
+ if (!sep->reg_addr) {
+ edbg("sep: ioremap of registers failed.\n");
+ goto end_function_deallocate_sep_shared_area;
+ }
+ edbg("SEP Driver:reg_addr is %p\n", sep->reg_addr);
+
+ /* load the rom code */
+ sep_load_rom_code(sep);
+
+ /* set up system base address and shared memory location */
+ sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev,
+ 2 * SEP_RAR_IO_MEM_REGION_SIZE,
+ &sep->rar_bus, GFP_KERNEL);
+
+ if (!sep->rar_addr) {
+ edbg("SEP Driver:can't allocate rar\n");
+ goto end_function_uniomap;
+ }
+
+
+ edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
+ edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
+
+#if !SEP_DRIVER_POLLING_MODE
+
+ edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n");
+
+ /* clear ICR register */
+ sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
+
+ /* set the IMR register - open only GPR 2 */
+ sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
+
+ edbg("SEP Driver: about to call request_irq\n");
+ /* get the interrupt line */
+ error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep);
+ if (error)
+ goto end_function_free_res;
+ return 0;
+ edbg("SEP Driver: about to write IMR REG_ADDR");
+
+ /* set the IMR register - open only GPR 2 */
+ sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
+
+end_function_free_res:
+ dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE,
+ sep->rar_addr, sep->rar_bus);
+#endif /* SEP_DRIVER_POLLING_MODE */
+end_function_uniomap:
+ iounmap(sep->reg_addr);
+end_function_deallocate_sep_shared_area:
+ /* de-allocate shared area */
+ sep_unmap_and_free_shared_area(sep, size);
+end_function_error:
+ sep_dev = NULL;
+end_function:
+ return error;
+}
+
+static const struct pci_device_id sep_pci_id_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
+
+/* field for registering driver to PCI device */
+static struct pci_driver sep_pci_driver = {
+ .name = "sep_sec_driver",
+ .id_table = sep_pci_id_tbl,
+ .probe = sep_probe
+ /* FIXME: remove handler */
+};
+
+/* major and minor device numbers */
+static dev_t sep_devno;
+
+/* the files operations structure of the driver */
+static struct file_operations sep_file_operations = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = sep_ioctl,
+ .poll = sep_poll,
+ .open = sep_open,
+ .release = sep_release,
+ .mmap = sep_mmap,
+};
+
+
+/* cdev struct of the driver */
+static struct cdev sep_cdev;
+
+/*
+ this function registers the driver to the file system
+*/
+static int sep_register_driver_to_fs(void)
+{
+ int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver");
+ if (ret_val) {
+ edbg("sep: major number allocation failed, retval is %d\n",
+ ret_val);
+ return ret_val;
+ }
+ /* init cdev */
+ cdev_init(&sep_cdev, &sep_file_operations);
+ sep_cdev.owner = THIS_MODULE;
+
+ /* register the driver with the kernel */
+ ret_val = cdev_add(&sep_cdev, sep_devno, 1);
+ if (ret_val) {
+ edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val);
+ /* unregister dev numbers */
+ unregister_chrdev_region(sep_devno, 1);
+ }
+ return ret_val;
+}
+
+
+/*--------------------------------------------------------------
+ init function
+----------------------------------------------------------------*/
+static int __init sep_init(void)
+{
+ int ret_val = 0;
+ dbg("SEP Driver:-------->Init start\n");
+ /* FIXME: Probe can occur before we are ready to survive a probe */
+ ret_val = pci_register_driver(&sep_pci_driver);
+ if (ret_val) {
+ edbg("sep_driver:sep_driver_to_device failed, ret_val is %d\n", ret_val);
+ goto end_function_unregister_from_fs;
+ }
+ /* register driver to fs */
+ ret_val = sep_register_driver_to_fs();
+ if (ret_val)
+ goto end_function_unregister_pci;
+ goto end_function;
+end_function_unregister_pci:
+ pci_unregister_driver(&sep_pci_driver);
+end_function_unregister_from_fs:
+ /* unregister from fs */
+ cdev_del(&sep_cdev);
+ /* unregister dev numbers */
+ unregister_chrdev_region(sep_devno, 1);
+end_function:
+ dbg("SEP Driver:<-------- Init end\n");
+ return ret_val;
+}
+
+
+/*-------------------------------------------------------------
+ exit function
+--------------------------------------------------------------*/
+static void __exit sep_exit(void)
+{
+ int size;
+
+ dbg("SEP Driver:--------> Exit start\n");
+
+ /* unregister from fs */
+ cdev_del(&sep_cdev);
+ /* unregister dev numbers */
+ unregister_chrdev_region(sep_devno, 1);
+ /* calculate the total size for de-allocation */
+ size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
+ SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
+ /* FIXME: We need to do this in the unload for the device */
+ /* free shared area */
+ if (sep_dev) {
+ sep_unmap_and_free_shared_area(sep_dev, size);
+ edbg("SEP Driver: free pages SEP SHARED AREA \n");
+ iounmap((void *) sep_dev->reg_addr);
+ edbg("SEP Driver: iounmap \n");
+ }
+ edbg("SEP Driver: release_mem_region \n");
+ dbg("SEP Driver:<-------- Exit end\n");
+}
+
+
+module_init(sep_init);
+module_exit(sep_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/staging/sep/sep_driver_api.h b/trunk/drivers/staging/sep/sep_driver_api.h
new file mode 100644
index 000000000000..7ef16da7c4ef
--- /dev/null
+++ b/trunk/drivers/staging/sep/sep_driver_api.h
@@ -0,0 +1,425 @@
+/*
+ *
+ * sep_driver_api.h - Security Processor Driver api definitions
+ *
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 Discretix. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * CONTACTS:
+ *
+ * Mark Allyn mark.a.allyn@intel.com
+ *
+ * CHANGES:
+ *
+ * 2009.06.26 Initial publish
+ *
+ */
+
+#ifndef __SEP_DRIVER_API_H__
+#define __SEP_DRIVER_API_H__
+
+
+
+/*----------------------------------------------------------------
+ IOCTL command defines
+ -----------------------------------------------------------------*/
+
+/* magic number 1 of the sep IOCTL command */
+#define SEP_IOC_MAGIC_NUMBER 's'
+
+/* sends interrupt to sep that message is ready */
+#define SEP_IOCSENDSEPCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 0)
+
+/* sends interrupt to sep that message is ready */
+#define SEP_IOCSENDSEPRPLYCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 1)
+
+/* allocate memory in data pool */
+#define SEP_IOCALLOCDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 2)
+
+/* write to pre-allocated memory in data pool */
+#define SEP_IOCWRITEDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 3)
+
+/* read from pre-allocated memory in data pool */
+#define SEP_IOCREADDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 4)
+
+/* create sym dma lli tables */
+#define SEP_IOCCREATESYMDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 5)
+
+/* create flow dma lli tables */
+#define SEP_IOCCREATEFLOWDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 6)
+
+/* free dynamic data aalocated during table creation */
+#define SEP_IOCFREEDMATABLEDATA _IO(SEP_IOC_MAGIC_NUMBER , 7)
+
+/* get the static pool area addresses (physical and virtual) */
+#define SEP_IOCGETSTATICPOOLADDR _IO(SEP_IOC_MAGIC_NUMBER , 8)
+
+/* set flow id command */
+#define SEP_IOCSETFLOWID _IO(SEP_IOC_MAGIC_NUMBER , 9)
+
+/* add tables to the dynamic flow */
+#define SEP_IOCADDFLOWTABLE _IO(SEP_IOC_MAGIC_NUMBER , 10)
+
+/* add flow add tables message */
+#define SEP_IOCADDFLOWMESSAGE _IO(SEP_IOC_MAGIC_NUMBER , 11)
+
+/* start sep command */
+#define SEP_IOCSEPSTART _IO(SEP_IOC_MAGIC_NUMBER , 12)
+
+/* init sep command */
+#define SEP_IOCSEPINIT _IO(SEP_IOC_MAGIC_NUMBER , 13)
+
+/* end transaction command */
+#define SEP_IOCENDTRANSACTION _IO(SEP_IOC_MAGIC_NUMBER , 15)
+
+/* reallocate cache and resident */
+#define SEP_IOCREALLOCCACHERES _IO(SEP_IOC_MAGIC_NUMBER , 16)
+
+/* get the offset of the address starting from the beginnnig of the map area */
+#define SEP_IOCGETMAPPEDADDROFFSET _IO(SEP_IOC_MAGIC_NUMBER , 17)
+
+/* get time address and value */
+#define SEP_IOCGETIME _IO(SEP_IOC_MAGIC_NUMBER , 19)
+
+/*-------------------------------------------
+ TYPEDEFS
+----------------------------------------------*/
+
+/*
+ init command struct
+*/
+struct sep_driver_init_t {
+ /* start of the 1G of the host memory address that SEP can access */
+ unsigned long message_addr;
+
+ /* start address of resident */
+ unsigned long message_size_in_words;
+
+};
+
+
+/*
+ realloc cache resident command
+*/
+struct sep_driver_realloc_cache_resident_t {
+ /* new cache address */
+ u64 new_cache_addr;
+ /* new resident address */
+ u64 new_resident_addr;
+ /* new resident address */
+ u64 new_shared_area_addr;
+ /* new base address */
+ u64 new_base_addr;
+};
+
+struct sep_driver_alloc_t {
+ /* virtual address of allocated space */
+ unsigned long offset;
+
+ /* physical address of allocated space */
+ unsigned long phys_address;
+
+ /* number of bytes to allocate */
+ unsigned long num_bytes;
+};
+
+/*
+ */
+struct sep_driver_write_t {
+ /* application space address */
+ unsigned long app_address;
+
+ /* address of the data pool */
+ unsigned long datapool_address;
+
+ /* number of bytes to write */
+ unsigned long num_bytes;
+};
+
+/*
+ */
+struct sep_driver_read_t {
+ /* application space address */
+ unsigned long app_address;
+
+ /* address of the data pool */
+ unsigned long datapool_address;
+
+ /* number of bytes to read */
+ unsigned long num_bytes;
+};
+
+/*
+*/
+struct sep_driver_build_sync_table_t {
+ /* address value of the data in */
+ unsigned long app_in_address;
+
+ /* size of data in */
+ unsigned long data_in_size;
+
+ /* address of the data out */
+ unsigned long app_out_address;
+
+ /* the size of the block of the operation - if needed,
+ every table will be modulo this parameter */
+ unsigned long block_size;
+
+ /* the physical address of the first input DMA table */
+ unsigned long in_table_address;
+
+ /* number of entries in the first input DMA table */
+ unsigned long in_table_num_entries;
+
+ /* the physical address of the first output DMA table */
+ unsigned long out_table_address;
+
+ /* number of entries in the first output DMA table */
+ unsigned long out_table_num_entries;
+
+ /* data in the first input table */
+ unsigned long table_data_size;
+
+ /* distinct user/kernel layout */
+ bool isKernelVirtualAddress;
+
+};
+
+/*
+*/
+struct sep_driver_build_flow_table_t {
+ /* flow type */
+ unsigned long flow_type;
+
+ /* flag for input output */
+ unsigned long input_output_flag;
+
+ /* address value of the data in */
+ unsigned long virt_buff_data_addr;
+
+ /* size of data in */
+ unsigned long num_virtual_buffers;
+
+ /* the physical address of the first input DMA table */
+ unsigned long first_table_addr;
+
+ /* number of entries in the first input DMA table */
+ unsigned long first_table_num_entries;
+
+ /* data in the first input table */
+ unsigned long first_table_data_size;
+
+ /* distinct user/kernel layout */
+ bool isKernelVirtualAddress;
+};
+
+
+struct sep_driver_add_flow_table_t {
+ /* flow id */
+ unsigned long flow_id;
+
+ /* flag for input output */
+ unsigned long inputOutputFlag;
+
+ /* address value of the data in */
+ unsigned long virt_buff_data_addr;
+
+ /* size of data in */
+ unsigned long num_virtual_buffers;
+
+ /* address of the first table */
+ unsigned long first_table_addr;
+
+ /* number of entries in the first table */
+ unsigned long first_table_num_entries;
+
+ /* data size of the first table */
+ unsigned long first_table_data_size;
+
+ /* distinct user/kernel layout */
+ bool isKernelVirtualAddress;
+
+};
+
+/*
+ command struct for set flow id
+*/
+struct sep_driver_set_flow_id_t {
+ /* flow id to set */
+ unsigned long flow_id;
+};
+
+
+/* command struct for add tables message */
+struct sep_driver_add_message_t {
+ /* flow id to set */
+ unsigned long flow_id;
+
+ /* message size in bytes */
+ unsigned long message_size_in_bytes;
+
+ /* address of the message */
+ unsigned long message_address;
+};
+
+/* command struct for static pool addresses */
+struct sep_driver_static_pool_addr_t {
+ /* physical address of the static pool */
+ unsigned long physical_static_address;
+
+ /* virtual address of the static pool */
+ unsigned long virtual_static_address;
+};
+
+/* command struct for getiing offset of the physical address from
+ the start of the mapped area */
+struct sep_driver_get_mapped_offset_t {
+ /* physical address of the static pool */
+ unsigned long physical_address;
+
+ /* virtual address of the static pool */
+ unsigned long offset;
+};
+
+/* command struct for getting time value and address */
+struct sep_driver_get_time_t {
+ /* physical address of stored time */
+ unsigned long time_physical_address;
+
+ /* value of the stored time */
+ unsigned long time_value;
+};
+
+
+/*
+ structure that represent one entry in the DMA LLI table
+*/
+struct sep_lli_entry_t {
+ /* physical address */
+ unsigned long physical_address;
+
+ /* block size */
+ unsigned long block_size;
+};
+
+/*
+ structure that reperesents data needed for lli table construction
+*/
+struct sep_lli_prepare_table_data_t {
+ /* pointer to the memory where the first lli entry to be built */
+ struct sep_lli_entry_t *lli_entry_ptr;
+
+ /* pointer to the array of lli entries from which the table is to be built */
+ struct sep_lli_entry_t *lli_array_ptr;
+
+ /* number of elements in lli array */
+ int lli_array_size;
+
+ /* number of entries in the created table */
+ int num_table_entries;
+
+ /* number of array entries processed during table creation */
+ int num_array_entries_processed;
+
+ /* the totatl data size in the created table */
+ int lli_table_total_data_size;
+};
+
+/*
+ structure that represent tone table - it is not used in code, jkust
+ to show what table looks like
+*/
+struct sep_lli_table_t {
+ /* number of pages mapped in this tables. If 0 - means that the table
+ is not defined (used as a valid flag) */
+ unsigned long num_pages;
+ /*
+ pointer to array of page pointers that represent the mapping of the
+ virtual buffer defined by the table to the physical memory. If this
+ pointer is NULL, it means that the table is not defined
+ (used as a valid flag)
+ */
+ struct page **table_page_array_ptr;
+
+ /* maximum flow entries in table */
+ struct sep_lli_entry_t lli_entries[SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE];
+};
+
+
+/*
+ structure for keeping the mapping of the virtual buffer into physical pages
+*/
+struct sep_flow_buffer_data {
+ /* pointer to the array of page structs pointers to the pages of the
+ virtual buffer */
+ struct page **page_array_ptr;
+
+ /* number of pages taken by the virtual buffer */
+ unsigned long num_pages;
+
+ /* this flag signals if this page_array is the last one among many that were
+ sent in one setting to SEP */
+ unsigned long last_page_array_flag;
+};
+
+/*
+ struct that keeps all the data for one flow
+*/
+struct sep_flow_context_t {
+ /*
+ work struct for handling the flow done interrupt in the workqueue
+ this structure must be in the first place, since it will be used
+ forcasting to the containing flow context
+ */
+ struct work_struct flow_wq;
+
+ /* flow id */
+ unsigned long flow_id;
+
+ /* additional input tables exists */
+ unsigned long input_tables_flag;
+
+ /* additional output tables exists */
+ unsigned long output_tables_flag;
+
+ /* data of the first input file */
+ struct sep_lli_entry_t first_input_table;
+
+ /* data of the first output table */
+ struct sep_lli_entry_t first_output_table;
+
+ /* last input table data */
+ struct sep_lli_entry_t last_input_table;
+
+ /* last output table data */
+ struct sep_lli_entry_t last_output_table;
+
+ /* first list of table */
+ struct sep_lli_entry_t input_tables_in_process;
+
+ /* output table in process (in sep) */
+ struct sep_lli_entry_t output_tables_in_process;
+
+ /* size of messages in bytes */
+ unsigned long message_size_in_bytes;
+
+ /* message */
+ unsigned char message[SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES];
+};
+
+
+#endif
diff --git a/trunk/drivers/staging/sep/sep_driver_config.h b/trunk/drivers/staging/sep/sep_driver_config.h
new file mode 100644
index 000000000000..6008fe5eca09
--- /dev/null
+++ b/trunk/drivers/staging/sep/sep_driver_config.h
@@ -0,0 +1,225 @@
+/*
+ *
+ * sep_driver_config.h - Security Processor Driver configuration
+ *
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 Discretix. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * CONTACTS:
+ *
+ * Mark Allyn mark.a.allyn@intel.com
+ *
+ * CHANGES:
+ *
+ * 2009.06.26 Initial publish
+ *
+ */
+
+#ifndef __SEP_DRIVER_CONFIG_H__
+#define __SEP_DRIVER_CONFIG_H__
+
+
+/*--------------------------------------
+ DRIVER CONFIGURATION FLAGS
+ -------------------------------------*/
+
+/* if flag is on , then the driver is running in polling and
+ not interrupt mode */
+#define SEP_DRIVER_POLLING_MODE 1
+
+/* flag which defines if the shared area address should be
+ reconfiged (send to SEP anew) during init of the driver */
+#define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0
+
+/* the mode for running on the ARM1172 Evaluation platform (flag is 1) */
+#define SEP_DRIVER_ARM_DEBUG_MODE 0
+
+/*-------------------------------------------
+ INTERNAL DATA CONFIGURATION
+ -------------------------------------------*/
+
+/* flag for the input array */
+#define SEP_DRIVER_IN_FLAG 0
+
+/* flag for output array */
+#define SEP_DRIVER_OUT_FLAG 1
+
+/* maximum number of entries in one LLI tables */
+#define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 8
+
+
+/*--------------------------------------------------------
+ SHARED AREA memory total size is 36K
+ it is divided is following:
+
+ SHARED_MESSAGE_AREA 8K }
+ }
+ STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K)
+ }
+ DATA_POOL_AREA 12K }
+
+ SYNCHRONIC_DMA_TABLES_AREA 5K
+
+ FLOW_DMA_TABLES_AREA 4K
+
+ SYSTEM_MEMORY_AREA 3k
+
+ SYSTEM_MEMORY total size is 3k
+ it is divided as following:
+
+ TIME_MEMORY_AREA 8B
+-----------------------------------------------------------*/
+
+
+
+/*
+ the maximum length of the message - the rest of the message shared
+ area will be dedicated to the dma lli tables
+*/
+#define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024)
+
+/* the size of the message shared area in pages */
+#define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024)
+
+/* the size of the data pool static area in pages */
+#define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024)
+
+/* the size of the data pool shared area size in pages */
+#define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (12 * 1024)
+
+/* the size of the message shared area in pages */
+#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 5)
+
+
+/* the size of the data pool shared area size in pages */
+#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4)
+
+/* system data (time, caller id etc') pool */
+#define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES 100
+
+
+/* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and
+ DATA POOL areas. area must be module 4k */
+#define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 24)
+
+
+/*-----------------------------------------------
+ offsets of the areas starting from the shared area start address
+*/
+
+/* message area offset */
+#define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0
+
+/* static pool area offset */
+#define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \
+ (SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES)
+
+/* data pool area offset */
+#define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \
+ (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \
+ SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES)
+
+/* synhronic dma tables area offset */
+#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES \
+ (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \
+ SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)
+
+/* sep driver flow dma tables area offset */
+#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES \
+ (SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
+ SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES)
+
+/* system memory offset in bytes */
+#define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \
+ (SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
+ SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES)
+
+/* offset of the time area */
+#define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \
+ (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES)
+
+
+
+/* start physical address of the SEP registers memory in HOST */
+#define SEP_IO_MEM_REGION_START_ADDRESS 0x80000000
+
+/* size of the SEP registers memory region in HOST (for now 100 registers) */
+#define SEP_IO_MEM_REGION_SIZE (2 * 0x100000)
+
+/* define the number of IRQ for SEP interrupts */
+#define SEP_DIRVER_IRQ_NUM 1
+
+/* maximum number of add buffers */
+#define SEP_MAX_NUM_ADD_BUFFERS 100
+
+/* number of flows */
+#define SEP_DRIVER_NUM_FLOWS 4
+
+/* maximum number of entries in flow table */
+#define SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE 25
+
+/* offset of the num entries in the block length entry of the LLI */
+#define SEP_NUM_ENTRIES_OFFSET_IN_BITS 24
+
+/* offset of the interrupt flag in the block length entry of the LLI */
+#define SEP_INT_FLAG_OFFSET_IN_BITS 31
+
+/* mask for extracting data size from LLI */
+#define SEP_TABLE_DATA_SIZE_MASK 0xFFFFFF
+
+/* mask for entries after being shifted left */
+#define SEP_NUM_ENTRIES_MASK 0x7F
+
+/* default flow id */
+#define SEP_FREE_FLOW_ID 0xFFFFFFFF
+
+/* temp flow id used during cretiong of new flow until receiving
+ real flow id from sep */
+#define SEP_TEMP_FLOW_ID (SEP_DRIVER_NUM_FLOWS + 1)
+
+/* maximum add buffers message length in bytes */
+#define SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES (7 * 4)
+
+/* maximum number of concurrent virtual buffers */
+#define SEP_MAX_VIRT_BUFFERS_CONCURRENT 100
+
+/* the token that defines the start of time address */
+#define SEP_TIME_VAL_TOKEN 0x12345678
+
+/* DEBUG LEVEL MASKS */
+#define SEP_DEBUG_LEVEL_BASIC 0x1
+
+#define SEP_DEBUG_LEVEL_EXTENDED 0x4
+
+
+/* Debug helpers */
+
+#define dbg(fmt, args...) \
+do {\
+ if (debug & SEP_DEBUG_LEVEL_BASIC) \
+ printk(KERN_DEBUG fmt, ##args); \
+} while(0);
+
+#define edbg(fmt, args...) \
+do { \
+ if (debug & SEP_DEBUG_LEVEL_EXTENDED) \
+ printk(KERN_DEBUG fmt, ##args); \
+} while(0);
+
+
+
+#endif
diff --git a/trunk/drivers/staging/sep/sep_driver_hw_defs.h b/trunk/drivers/staging/sep/sep_driver_hw_defs.h
new file mode 100644
index 000000000000..ea6abd8a14b4
--- /dev/null
+++ b/trunk/drivers/staging/sep/sep_driver_hw_defs.h
@@ -0,0 +1,232 @@
+/*
+ *
+ * sep_driver_hw_defs.h - Security Processor Driver hardware definitions
+ *
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 Discretix. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * CONTACTS:
+ *
+ * Mark Allyn mark.a.allyn@intel.com
+ *
+ * CHANGES:
+ *
+ * 2009.06.26 Initial publish
+ *
+ */
+
+#ifndef SEP_DRIVER_HW_DEFS__H
+#define SEP_DRIVER_HW_DEFS__H
+
+/*--------------------------------------------------------------------------*/
+/* Abstract: HW Registers Defines. */
+/* */
+/* Note: This file was automatically created !!! */
+/* DO NOT EDIT THIS FILE !!! */
+/*--------------------------------------------------------------------------*/
+
+
+/* cf registers */
+#define HW_R0B_ADDR_0_REG_ADDR 0x0000UL
+#define HW_R0B_ADDR_1_REG_ADDR 0x0004UL
+#define HW_R0B_ADDR_2_REG_ADDR 0x0008UL
+#define HW_R0B_ADDR_3_REG_ADDR 0x000cUL
+#define HW_R0B_ADDR_4_REG_ADDR 0x0010UL
+#define HW_R0B_ADDR_5_REG_ADDR 0x0014UL
+#define HW_R0B_ADDR_6_REG_ADDR 0x0018UL
+#define HW_R0B_ADDR_7_REG_ADDR 0x001cUL
+#define HW_R0B_ADDR_8_REG_ADDR 0x0020UL
+#define HW_R2B_ADDR_0_REG_ADDR 0x0080UL
+#define HW_R2B_ADDR_1_REG_ADDR 0x0084UL
+#define HW_R2B_ADDR_2_REG_ADDR 0x0088UL
+#define HW_R2B_ADDR_3_REG_ADDR 0x008cUL
+#define HW_R2B_ADDR_4_REG_ADDR 0x0090UL
+#define HW_R2B_ADDR_5_REG_ADDR 0x0094UL
+#define HW_R2B_ADDR_6_REG_ADDR 0x0098UL
+#define HW_R2B_ADDR_7_REG_ADDR 0x009cUL
+#define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL
+#define HW_R3B_REG_ADDR 0x00C0UL
+#define HW_R4B_REG_ADDR 0x0100UL
+#define HW_CSA_ADDR_0_REG_ADDR 0x0140UL
+#define HW_CSA_ADDR_1_REG_ADDR 0x0144UL
+#define HW_CSA_ADDR_2_REG_ADDR 0x0148UL
+#define HW_CSA_ADDR_3_REG_ADDR 0x014cUL
+#define HW_CSA_ADDR_4_REG_ADDR 0x0150UL
+#define HW_CSA_ADDR_5_REG_ADDR 0x0154UL
+#define HW_CSA_ADDR_6_REG_ADDR 0x0158UL
+#define HW_CSA_ADDR_7_REG_ADDR 0x015cUL
+#define HW_CSA_ADDR_8_REG_ADDR 0x0160UL
+#define HW_CSA_REG_ADDR 0x0140UL
+#define HW_SINB_REG_ADDR 0x0180UL
+#define HW_SOUTB_REG_ADDR 0x0184UL
+#define HW_PKI_CONTROL_REG_ADDR 0x01C0UL
+#define HW_PKI_STATUS_REG_ADDR 0x01C4UL
+#define HW_PKI_BUSY_REG_ADDR 0x01C8UL
+#define HW_PKI_A_1025_REG_ADDR 0x01CCUL
+#define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL
+#define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL
+#define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL
+#define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL
+#define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL
+#define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL
+#define HW_PKI_CLR_REG_ADDR 0x01E8UL
+#define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL
+#define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL
+#define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL
+#define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL
+#define HW_DES_KEY_0_REG_ADDR 0x0208UL
+#define HW_DES_KEY_1_REG_ADDR 0x020CUL
+#define HW_DES_KEY_2_REG_ADDR 0x0210UL
+#define HW_DES_KEY_3_REG_ADDR 0x0214UL
+#define HW_DES_KEY_4_REG_ADDR 0x0218UL
+#define HW_DES_KEY_5_REG_ADDR 0x021CUL
+#define HW_DES_CONTROL_0_REG_ADDR 0x0220UL
+#define HW_DES_CONTROL_1_REG_ADDR 0x0224UL
+#define HW_DES_IV_0_REG_ADDR 0x0228UL
+#define HW_DES_IV_1_REG_ADDR 0x022CUL
+#define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL
+#define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL
+#define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL
+#define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL
+#define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL
+#define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL
+#define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL
+#define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL
+#define HW_AES_KEY_0_REG_ADDR 0x0400UL
+#define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL
+#define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL
+#define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL
+#define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL
+#define HW_AES_IV_0_REG_ADDR 0x0440UL
+#define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL
+#define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL
+#define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL
+#define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL
+#define HW_AES_CTR1_REG_ADDR 0x0460UL
+#define HW_AES_SK_REG_ADDR 0x0478UL
+#define HW_AES_MAC_OK_REG_ADDR 0x0480UL
+#define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL
+#define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL
+#define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL
+#define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL
+#define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL
+#define HW_AES_CONTROL_REG_ADDR 0x04C0UL
+#define HW_HASH_H0_REG_ADDR 0x0640UL
+#define HW_HASH_H1_REG_ADDR 0x0644UL
+#define HW_HASH_H2_REG_ADDR 0x0648UL
+#define HW_HASH_H3_REG_ADDR 0x064CUL
+#define HW_HASH_H4_REG_ADDR 0x0650UL
+#define HW_HASH_H5_REG_ADDR 0x0654UL
+#define HW_HASH_H6_REG_ADDR 0x0658UL
+#define HW_HASH_H7_REG_ADDR 0x065CUL
+#define HW_HASH_H8_REG_ADDR 0x0660UL
+#define HW_HASH_H9_REG_ADDR 0x0664UL
+#define HW_HASH_H10_REG_ADDR 0x0668UL
+#define HW_HASH_H11_REG_ADDR 0x066CUL
+#define HW_HASH_H12_REG_ADDR 0x0670UL
+#define HW_HASH_H13_REG_ADDR 0x0674UL
+#define HW_HASH_H14_REG_ADDR 0x0678UL
+#define HW_HASH_H15_REG_ADDR 0x067CUL
+#define HW_HASH_CONTROL_REG_ADDR 0x07C0UL
+#define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL
+#define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL
+#define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL
+#define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL
+#define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL
+#define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL
+#define HW_HASH_PARAM_REG_ADDR 0x07DCUL
+#define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL
+#define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL
+#define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL
+#define HW_HASH_DATA_REG_ADDR 0x07ECUL
+#define HW_DRNG_CONTROL_REG_ADDR 0x0800UL
+#define HW_DRNG_VALID_REG_ADDR 0x0804UL
+#define HW_DRNG_DATA_REG_ADDR 0x0808UL
+#define HW_RND_SRC_EN_REG_ADDR 0x080CUL
+#define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL
+#define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL
+#define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL
+#define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL
+#define HW_CLK_STATUS_REG_ADDR 0x0824UL
+#define HW_CLK_ENABLE_REG_ADDR 0x0828UL
+#define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL
+#define HW_RND_SRC_CTL_REG_ADDR 0x0858UL
+#define HW_CRYPTO_CTL_REG_ADDR 0x0900UL
+#define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL
+#define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL
+#define HW_AES_BUSY_REG_ADDR 0x0914UL
+#define HW_DES_BUSY_REG_ADDR 0x0918UL
+#define HW_HASH_BUSY_REG_ADDR 0x091CUL
+#define HW_CONTENT_REG_ADDR 0x0924UL
+#define HW_VERSION_REG_ADDR 0x0928UL
+#define HW_CONTEXT_ID_REG_ADDR 0x0930UL
+#define HW_DIN_BUFFER_REG_ADDR 0x0C00UL
+#define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL
+#define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL
+#define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL
+#define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL
+#define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL
+#define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL
+#define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL
+#define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL
+#define HW_OLD_DATA_REG_ADDR 0x0C48UL
+#define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL
+#define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL
+#define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL
+#define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL
+#define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL
+#define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL
+#define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL
+#define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL
+#define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL
+#define HW_READ_ALIGN_REG_ADDR 0x0D3CUL
+#define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL
+#define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL
+#define HW_AHB_SINGLE_REG_ADDR 0x0E00UL
+#define HW_SRAM_DATA_REG_ADDR 0x0F00UL
+#define HW_SRAM_ADDR_REG_ADDR 0x0F04UL
+#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL
+#define HW_HOST_IRR_REG_ADDR 0x0A00UL
+#define HW_HOST_IMR_REG_ADDR 0x0A04UL
+#define HW_HOST_ICR_REG_ADDR 0x0A08UL
+#define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL
+#define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL
+#define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL
+#define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL
+#define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL
+#define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL
+#define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL
+#define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL
+#define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL
+#define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL
+#define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL
+#define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL
+#define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL
+#define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL
+#define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL
+#define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL
+#define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL
+#define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL
+#define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL
+#define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL
+#define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL
+#define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL
+#define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL
+#define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL
+#define HW_CC_SRAM_BASE_ADDRESS 0x5800UL
+
+#endif /* ifndef HW_DEFS */
diff --git a/trunk/drivers/staging/spectra/ffsport.c b/trunk/drivers/staging/spectra/ffsport.c
index 44a7fbe7eccd..d0c5c97eda3e 100644
--- a/trunk/drivers/staging/spectra/ffsport.c
+++ b/trunk/drivers/staging/spectra/ffsport.c
@@ -27,7 +27,6 @@
#include
#include
#include
-#include
/**** Helper functions used for Div, Remainder operation on u64 ****/
@@ -114,6 +113,7 @@ u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type)
#define GLOB_SBD_NAME "nd"
#define GLOB_SBD_IRQ_NUM (29)
+#define GLOB_VERSION "driver version 20091110"
#define GLOB_SBD_IOCTL_GC (0x7701)
#define GLOB_SBD_IOCTL_WL (0x7702)
@@ -272,6 +272,13 @@ static int get_res_blk_num_os(void)
return res_blks;
}
+static void SBD_prepare_flush(struct request_queue *q, struct request *rq)
+{
+ rq->cmd_type = REQ_TYPE_LINUX_BLOCK;
+ /* rq->timeout = 5 * HZ; */
+ rq->cmd[0] = REQ_LB_OP_FLUSH;
+}
+
/* Transfer a full request. */
static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
{
@@ -289,7 +296,8 @@ static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
IdentifyDeviceData.PagesPerBlock *
res_blks_os;
- if (req->cmd_type & REQ_FLUSH) {
+ if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+ req->cmd[0] == REQ_LB_OP_FLUSH) {
if (force_flush_cache()) /* Fail to flush cache */
return -EIO;
else
@@ -589,23 +597,11 @@ int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode,
return -ENOTTY;
}
-int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
-{
- int ret;
-
- lock_kernel();
- ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg);
- unlock_kernel();
-
- return ret;
-}
-
static struct block_device_operations GLOB_SBD_ops = {
.owner = THIS_MODULE,
.open = GLOB_SBD_open,
.release = GLOB_SBD_release,
- .ioctl = GLOB_SBD_unlocked_ioctl,
+ .locked_ioctl = GLOB_SBD_ioctl,
.getgeo = GLOB_SBD_getgeo,
};
@@ -654,7 +650,8 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
/* Here we force report 512 byte hardware sector size to Kernel */
blk_queue_logical_block_size(dev->queue, 512);
- blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH);
+ blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH,
+ SBD_prepare_flush);
dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
if (IS_ERR(dev->thread)) {
diff --git a/trunk/drivers/staging/spectra/flash.c b/trunk/drivers/staging/spectra/flash.c
index 9b5218b6ada8..134aa5166a8d 100644
--- a/trunk/drivers/staging/spectra/flash.c
+++ b/trunk/drivers/staging/spectra/flash.c
@@ -61,6 +61,7 @@ static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr,
static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr,
u8 cache_blk, u16 flag);
static int FTL_Cache_Write(void);
+static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr);
static void FTL_Calculate_LRU(void);
static u32 FTL_Get_Block_Index(u32 wBlockNum);
@@ -85,6 +86,8 @@ static u32 FTL_Replace_MWBlock(void);
static int FTL_Replace_Block(u64 blk_addr);
static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX);
+static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, u64 blk_addr);
+
struct device_info_tag DeviceInfo;
struct flash_cache_tag Cache;
static struct spectra_l2_cache_info cache_l2;
@@ -772,7 +775,7 @@ static void dump_cache_l2_table(void)
{
struct list_head *p;
struct spectra_l2_cache_list *pnd;
- int n;
+ int n, i;
n = 0;
list_for_each(p, &cache_l2.table.list) {
@@ -1534,6 +1537,79 @@ static int FTL_Cache_Write_All(u8 *pData, u64 blk_addr)
return wResult;
}
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Update_Block
+* Inputs: pointer to buffer,page address,block address
+* Outputs: PASS=0 / FAIL=1
+* Description: It updates the cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Update_Block(u8 *pData,
+ u64 old_page_addr, u64 blk_addr)
+{
+ int i, j;
+ u8 *buf = pData;
+ int wResult = PASS;
+ int wFoundInCache;
+ u64 page_addr;
+ u64 addr;
+ u64 old_blk_addr;
+ u16 page_offset;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ old_blk_addr = (u64)(old_page_addr >>
+ DeviceInfo.nBitsInBlockDataSize) * DeviceInfo.wBlockDataSize;
+ page_offset = (u16)(GLOB_u64_Remainder(old_page_addr, 2) >>
+ DeviceInfo.nBitsInPageDataSize);
+
+ for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) {
+ page_addr = old_blk_addr + i * DeviceInfo.wPageDataSize;
+ if (i != page_offset) {
+ wFoundInCache = FAIL;
+ for (j = 0; j < CACHE_ITEM_NUM; j++) {
+ addr = Cache.array[j].address;
+ addr = FTL_Get_Physical_Block_Addr(addr) +
+ GLOB_u64_Remainder(addr, 2);
+ if ((addr >= page_addr) && addr <
+ (page_addr + Cache.cache_item_size)) {
+ wFoundInCache = PASS;
+ buf = Cache.array[j].buf;
+ Cache.array[j].changed = SET;
+#if CMD_DMA
+#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
+ int_cache[ftl_cmd_cnt].item = j;
+ int_cache[ftl_cmd_cnt].cache.address =
+ Cache.array[j].address;
+ int_cache[ftl_cmd_cnt].cache.changed =
+ Cache.array[j].changed;
+#endif
+#endif
+ break;
+ }
+ }
+ if (FAIL == wFoundInCache) {
+ if (ERR == FTL_Cache_Read_All(g_pTempBuf,
+ page_addr)) {
+ wResult = FAIL;
+ break;
+ }
+ buf = g_pTempBuf;
+ }
+ } else {
+ buf = pData;
+ }
+
+ if (FAIL == FTL_Cache_Write_All(buf,
+ blk_addr + (page_addr - old_blk_addr))) {
+ wResult = FAIL;
+ break;
+ }
+ }
+
+ return wResult;
+}
+
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Copy_Block
* Inputs: source block address
@@ -1622,7 +1698,7 @@ static int get_l2_cache_blks(void)
static int erase_l2_cache_blocks(void)
{
int i, ret = PASS;
- u32 pblk, lblk = BAD_BLOCK;
+ u32 pblk, lblk;
u64 addr;
u32 *pbt = (u32 *)g_pBlockTable;
@@ -1928,6 +2004,87 @@ static int search_l2_cache(u8 *buf, u64 logical_addr)
return ret;
}
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Write_Back
+* Inputs: pointer to data cached in sys memory
+* address of free block in flash
+* Outputs: PASS=0 / FAIL=1
+* Description: writes all the pages of Cache Block to flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr)
+{
+ int i, j, iErase;
+ u64 old_page_addr, addr, phy_addr;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 lba;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ old_page_addr = FTL_Get_Physical_Block_Addr(blk_addr) +
+ GLOB_u64_Remainder(blk_addr, 2);
+
+ iErase = (FAIL == FTL_Replace_Block(blk_addr)) ? PASS : FAIL;
+
+ pbt[BLK_FROM_ADDR(blk_addr)] &= (~SPARE_BLOCK);
+
+#if CMD_DMA
+ p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
+ p_BTableChangesDelta->BT_Index = (u32)(blk_addr >>
+ DeviceInfo.nBitsInBlockDataSize);
+ p_BTableChangesDelta->BT_Entry_Value =
+ pbt[(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize)];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+
+ if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+
+ for (i = 0; i < RETRY_TIMES; i++) {
+ if (PASS == iErase) {
+ phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
+ if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
+ lba = BLK_FROM_ADDR(blk_addr);
+ MARK_BLOCK_AS_BAD(pbt[lba]);
+ i = RETRY_TIMES;
+ break;
+ }
+ }
+
+ for (j = 0; j < CACHE_ITEM_NUM; j++) {
+ addr = Cache.array[j].address;
+ if ((addr <= blk_addr) &&
+ ((addr + Cache.cache_item_size) > blk_addr))
+ cache_block_to_write = j;
+ }
+
+ phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
+ if (PASS == FTL_Cache_Update_Block(pData,
+ old_page_addr, phy_addr)) {
+ cache_block_to_write = UNHIT_CACHE_ITEM;
+ break;
+ } else {
+ iErase = PASS;
+ }
+ }
+
+ if (i >= RETRY_TIMES) {
+ if (ERR == FTL_Flash_Error_Handle(pData,
+ old_page_addr, blk_addr))
+ return ERR;
+ else
+ return FAIL;
+ }
+
+ return PASS;
+}
+
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Cache_Write_Page
* Inputs: Pointer to buffer, page address, cache block number
@@ -2213,6 +2370,159 @@ static int FTL_Write_Block_Table(int wForce)
return 1;
}
+/******************************************************************
+* Function: GLOB_FTL_Flash_Format
+* Inputs: none
+* Outputs: PASS
+* Description: The block table stores bad block info, including MDF+
+* blocks gone bad over the ages. Therefore, if we have a
+* block table in place, then use it to scan for bad blocks
+* If not, then scan for MDF.
+* Now, a block table will only be found if spectra was already
+* being used. For a fresh flash, we'll go thru scanning for
+* MDF. If spectra was being used, then there is a chance that
+* the MDF has been corrupted. Spectra avoids writing to the
+* first 2 bytes of the spare area to all pages in a block. This
+* covers all known flash devices. However, since flash
+* manufacturers have no standard of where the MDF is stored,
+* this cannot guarantee that the MDF is protected for future
+* devices too. The initial scanning for the block table assures
+* this. It is ok even if the block table is outdated, as all
+* we're looking for are bad block markers.
+* Use this when mounting a file system or starting a
+* new flash.
+*
+*********************************************************************/
+static int FTL_Format_Flash(u8 valid_block_table)
+{
+ u32 i, j;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 tempNode;
+ int ret;
+
+#if CMD_DMA
+ u32 *pbtStartingCopy = (u32 *)g_pBTStartingCopy;
+ if (ftl_cmd_cnt)
+ return FAIL;
+#endif
+
+ if (FAIL == FTL_Check_Block_Table(FAIL))
+ valid_block_table = 0;
+
+ if (valid_block_table) {
+ u8 switched = 1;
+ u32 block, k;
+
+ k = DeviceInfo.wSpectraStartBlock;
+ while (switched && (k < DeviceInfo.wSpectraEndBlock)) {
+ switched = 0;
+ k++;
+ for (j = DeviceInfo.wSpectraStartBlock, i = 0;
+ j <= DeviceInfo.wSpectraEndBlock;
+ j++, i++) {
+ block = (pbt[i] & ~BAD_BLOCK) -
+ DeviceInfo.wSpectraStartBlock;
+ if (block != i) {
+ switched = 1;
+ tempNode = pbt[i];
+ pbt[i] = pbt[block];
+ pbt[block] = tempNode;
+ }
+ }
+ }
+ if ((k == DeviceInfo.wSpectraEndBlock) && switched)
+ valid_block_table = 0;
+ }
+
+ if (!valid_block_table) {
+ memset(g_pBlockTable, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u32));
+ memset(g_pWearCounter, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u8));
+ if (DeviceInfo.MLCDevice)
+ memset(g_pReadCounter, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u16));
+#if CMD_DMA
+ memset(g_pBTStartingCopy, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u32));
+ memset(g_pWearCounterCopy, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u8));
+ if (DeviceInfo.MLCDevice)
+ memset(g_pReadCounterCopy, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u16));
+#endif
+ for (j = DeviceInfo.wSpectraStartBlock, i = 0;
+ j <= DeviceInfo.wSpectraEndBlock;
+ j++, i++) {
+ if (GLOB_LLD_Get_Bad_Block((u32)j))
+ pbt[i] = (u32)(BAD_BLOCK | j);
+ }
+ }
+
+ nand_dbg_print(NAND_DBG_WARN, "Erasing all blocks in the NAND\n");
+
+ for (j = DeviceInfo.wSpectraStartBlock, i = 0;
+ j <= DeviceInfo.wSpectraEndBlock;
+ j++, i++) {
+ if ((pbt[i] & BAD_BLOCK) != BAD_BLOCK) {
+ ret = GLOB_LLD_Erase_Block(j);
+ if (FAIL == ret) {
+ pbt[i] = (u32)(j);
+ MARK_BLOCK_AS_BAD(pbt[i]);
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__, (int)j);
+ } else {
+ pbt[i] = (u32)(SPARE_BLOCK | j);
+ }
+ }
+#if CMD_DMA
+ pbtStartingCopy[i] = pbt[i];
+#endif
+ }
+
+ g_wBlockTableOffset = 0;
+ for (i = 0; (i <= (DeviceInfo.wSpectraEndBlock -
+ DeviceInfo.wSpectraStartBlock))
+ && ((pbt[i] & BAD_BLOCK) == BAD_BLOCK); i++)
+ ;
+ if (i > (DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock)) {
+ printk(KERN_ERR "All blocks bad!\n");
+ return FAIL;
+ } else {
+ g_wBlockTableIndex = pbt[i] & ~BAD_BLOCK;
+ if (i != BLOCK_TABLE_INDEX) {
+ tempNode = pbt[i];
+ pbt[i] = pbt[BLOCK_TABLE_INDEX];
+ pbt[BLOCK_TABLE_INDEX] = tempNode;
+ }
+ }
+ pbt[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
+
+#if CMD_DMA
+ pbtStartingCopy[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
+#endif
+
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ memset(g_pBTBlocks, 0xFF,
+ (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32));
+ g_pBTBlocks[FIRST_BT_ID-FIRST_BT_ID] = g_wBlockTableIndex;
+ FTL_Write_Block_Table(FAIL);
+
+ for (i = 0; i < CACHE_ITEM_NUM; i++) {
+ Cache.array[i].address = NAND_CACHE_INIT_ADDR;
+ Cache.array[i].use_cnt = 0;
+ Cache.array[i].changed = CLEAR;
+ }
+
+#if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA)
+ memcpy((void *)&cache_start_copy, (void *)&Cache,
+ sizeof(struct flash_cache_tag));
+#endif
+ return PASS;
+}
+
static int force_format_nand(void)
{
u32 i;
@@ -2721,6 +3031,112 @@ static int FTL_Read_Block_Table(void)
return wResult;
}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Flash_Error_Handle
+* Inputs: Pointer to data
+* Page address
+* Block address
+* Outputs: PASS=0 / FAIL=1
+* Description: It handles any error occured during Spectra operation
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr,
+ u64 blk_addr)
+{
+ u32 i;
+ int j;
+ u32 tmp_node, blk_node = BLK_FROM_ADDR(blk_addr);
+ u64 phy_addr;
+ int wErase = FAIL;
+ int wResult = FAIL;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (ERR == GLOB_FTL_Garbage_Collection())
+ return ERR;
+
+ do {
+ for (i = DeviceInfo.wSpectraEndBlock -
+ DeviceInfo.wSpectraStartBlock;
+ i > 0; i--) {
+ if (IS_SPARE_BLOCK(i)) {
+ tmp_node = (u32)(BAD_BLOCK |
+ pbt[blk_node]);
+ pbt[blk_node] = (u32)(pbt[i] &
+ (~SPARE_BLOCK));
+ pbt[i] = tmp_node;
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)
+ g_pBTDelta_Free;
+ g_pBTDelta_Free +=
+ sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->ftl_cmd_cnt =
+ ftl_cmd_cnt;
+ p_BTableChangesDelta->BT_Index =
+ blk_node;
+ p_BTableChangesDelta->BT_Entry_Value =
+ pbt[blk_node];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)
+ g_pBTDelta_Free;
+ g_pBTDelta_Free +=
+ sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->ftl_cmd_cnt =
+ ftl_cmd_cnt;
+ p_BTableChangesDelta->BT_Index = i;
+ p_BTableChangesDelta->BT_Entry_Value = pbt[i];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+ wResult = PASS;
+ break;
+ }
+ }
+
+ if (FAIL == wResult) {
+ if (FAIL == GLOB_FTL_Garbage_Collection())
+ break;
+ else
+ continue;
+ }
+
+ if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+
+ phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
+
+ for (j = 0; j < RETRY_TIMES; j++) {
+ if (PASS == wErase) {
+ if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
+ MARK_BLOCK_AS_BAD(pbt[blk_node]);
+ break;
+ }
+ }
+ if (PASS == FTL_Cache_Update_Block(pData,
+ old_page_addr,
+ phy_addr)) {
+ wResult = PASS;
+ break;
+ } else {
+ wResult = FAIL;
+ wErase = PASS;
+ }
+ }
+ } while (FAIL == wResult);
+
+ FTL_Write_Block_Table(FAIL);
+
+ return wResult;
+}
+
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Get_Page_Num
* Inputs: Size in bytes
diff --git a/trunk/drivers/usb/gadget/composite.c b/trunk/drivers/usb/gadget/composite.c
index 1160c55de7f2..e483f80822d2 100644
--- a/trunk/drivers/usb/gadget/composite.c
+++ b/trunk/drivers/usb/gadget/composite.c
@@ -723,12 +723,12 @@ int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str)
/**
* usb_string_ids_n() - allocate unused string IDs in batch
- * @c: the device whose string descriptor IDs are being allocated
+ * @cdev: the device whose string descriptor IDs are being allocated
* @n: number of string IDs to allocate
* Context: single threaded during gadget setup
*
* Returns the first requested ID. This ID and next @n-1 IDs are now
- * valid IDs. At least provided that @n is non-zero because if it
+ * valid IDs. At least providind that @n is non zore because if it
* is, returns last requested ID which is now very useful information.
*
* @usb_string_ids_n() is called from bind() callbacks to allocate
diff --git a/trunk/drivers/usb/gadget/m66592-udc.c b/trunk/drivers/usb/gadget/m66592-udc.c
index e03058fe23cb..166bf71fd348 100644
--- a/trunk/drivers/usb/gadget/m66592-udc.c
+++ b/trunk/drivers/usb/gadget/m66592-udc.c
@@ -1609,7 +1609,6 @@ static int __init m66592_probe(struct platform_device *pdev)
/* initialize ucd */
m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
if (m66592 == NULL) {
- ret = -ENOMEM;
pr_err("kzalloc error\n");
goto clean_up;
}
diff --git a/trunk/drivers/usb/gadget/r8a66597-udc.c b/trunk/drivers/usb/gadget/r8a66597-udc.c
index 2456ccd9965e..70a817842755 100644
--- a/trunk/drivers/usb/gadget/r8a66597-udc.c
+++ b/trunk/drivers/usb/gadget/r8a66597-udc.c
@@ -1557,7 +1557,6 @@ static int __init r8a66597_probe(struct platform_device *pdev)
/* initialize ucd */
r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL);
if (r8a66597 == NULL) {
- ret = -ENOMEM;
printk(KERN_ERR "kzalloc error\n");
goto clean_up;
}
diff --git a/trunk/drivers/usb/gadget/uvc_v4l2.c b/trunk/drivers/usb/gadget/uvc_v4l2.c
index 5e807f083bc8..2dcffdac86d2 100644
--- a/trunk/drivers/usb/gadget/uvc_v4l2.c
+++ b/trunk/drivers/usb/gadget/uvc_v4l2.c
@@ -94,7 +94,7 @@ uvc_v4l2_set_format(struct uvc_video *video, struct v4l2_format *fmt)
break;
}
- if (i == ARRAY_SIZE(uvc_formats)) {
+ if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) {
printk(KERN_INFO "Unsupported format 0x%08x.\n",
fmt->fmt.pix.pixelformat);
return -EINVAL;
diff --git a/trunk/drivers/usb/host/isp1760-hcd.c b/trunk/drivers/usb/host/isp1760-hcd.c
index bdba8c5d844a..d1a3dfc9a408 100644
--- a/trunk/drivers/usb/host/isp1760-hcd.c
+++ b/trunk/drivers/usb/host/isp1760-hcd.c
@@ -829,7 +829,6 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
* almost immediately. With ISP1761, this register requires a delay of
* 195ns between a write and subsequent read (see section 15.1.1.3).
*/
- mmiowb();
ndelay(195);
skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG);
@@ -871,7 +870,6 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
* almost immediately. With ISP1761, this register requires a delay of
* 195ns between a write and subsequent read (see section 15.1.1.3).
*/
- mmiowb();
ndelay(195);
skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG);
diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c
index 48e60d166ff0..bc3f4f427065 100644
--- a/trunk/drivers/usb/host/xhci-ring.c
+++ b/trunk/drivers/usb/host/xhci-ring.c
@@ -131,7 +131,7 @@ static void next_trb(struct xhci_hcd *xhci,
*seg = (*seg)->next;
*trb = ((*seg)->trbs);
} else {
- (*trb)++;
+ *trb = (*trb)++;
}
}
@@ -1551,10 +1551,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
/* calc actual length */
if (ep->skip) {
td->urb->iso_frame_desc[idx].actual_length = 0;
- /* Update ring dequeue pointer */
- while (ep_ring->dequeue != td->last_trb)
- inc_deq(xhci, ep_ring, false);
- inc_deq(xhci, ep_ring, false);
return finish_td(xhci, td, event_trb, event, ep, status, true);
}
diff --git a/trunk/drivers/usb/misc/adutux.c b/trunk/drivers/usb/misc/adutux.c
index 801324af9470..d240de097c62 100644
--- a/trunk/drivers/usb/misc/adutux.c
+++ b/trunk/drivers/usb/misc/adutux.c
@@ -439,7 +439,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
/* drain secondary buffer */
int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary;
i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount);
- if (i) {
+ if (i < 0) {
retval = -EFAULT;
goto exit;
}
diff --git a/trunk/drivers/usb/misc/iowarrior.c b/trunk/drivers/usb/misc/iowarrior.c
index bc88c79875a1..2de49c8887c5 100644
--- a/trunk/drivers/usb/misc/iowarrior.c
+++ b/trunk/drivers/usb/misc/iowarrior.c
@@ -542,7 +542,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd,
retval = io_res;
else {
io_res = copy_to_user(user_buffer, buffer, dev->report_size);
- if (io_res)
+ if (io_res < 0)
retval = -EFAULT;
}
break;
@@ -574,7 +574,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd,
}
io_res = copy_to_user((struct iowarrior_info __user *)arg, &info,
sizeof(struct iowarrior_info));
- if (io_res)
+ if (io_res < 0)
retval = -EFAULT;
break;
}
diff --git a/trunk/drivers/usb/otg/twl4030-usb.c b/trunk/drivers/usb/otg/twl4030-usb.c
index 05aaac1c3861..0e8888588d4e 100644
--- a/trunk/drivers/usb/otg/twl4030-usb.c
+++ b/trunk/drivers/usb/otg/twl4030-usb.c
@@ -550,7 +550,6 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
struct twl4030_usb_data *pdata = pdev->dev.platform_data;
struct twl4030_usb *twl;
int status, err;
- u8 pwr;
if (!pdata) {
dev_dbg(&pdev->dev, "platform_data not available\n");
@@ -569,10 +568,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
twl->otg.set_peripheral = twl4030_set_peripheral;
twl->otg.set_suspend = twl4030_set_suspend;
twl->usb_mode = pdata->usb_mode;
-
- pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
-
- twl->asleep = (pwr & PHY_PWR_PHYPWD);
+ twl->asleep = 1;
/* init spinlock for workqueue */
spin_lock_init(&twl->lock);
diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c
index 80bf8333bb03..2bef4415c19c 100644
--- a/trunk/drivers/usb/serial/cp210x.c
+++ b/trunk/drivers/usb/serial/cp210x.c
@@ -222,8 +222,8 @@ static struct usb_serial_driver cp210x_device = {
#define BITS_STOP_2 0x0002
/* CP210X_SET_BREAK */
-#define BREAK_ON 0x0001
-#define BREAK_OFF 0x0000
+#define BREAK_ON 0x0000
+#define BREAK_OFF 0x0001
/* CP210X_(SET_MHS|GET_MDMSTS) */
#define CONTROL_DTR 0x0001
diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c
index 63ddb2f65cee..eb12d9b096b4 100644
--- a/trunk/drivers/usb/serial/ftdi_sio.c
+++ b/trunk/drivers/usb/serial/ftdi_sio.c
@@ -180,7 +180,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
- { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) },
@@ -751,8 +750,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) },
- { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID),
- .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -1379,7 +1376,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port)
}
/* set max packet size based on descriptor */
- priv->max_packet_size = le16_to_cpu(ep_desc->wMaxPacketSize);
+ priv->max_packet_size = ep_desc->wMaxPacketSize;
dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);
}
diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h
index 2e95857c9633..6e612c52e763 100644
--- a/trunk/drivers/usb/serial/ftdi_sio_ids.h
+++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h
@@ -110,9 +110,6 @@
/* Propox devices */
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
-/* Lenz LI-USB Computer Interface. */
-#define FTDI_LENZ_LIUSB_PID 0xD780
-
/*
* Xsens Technologies BV products (http://www.xsens.com).
*/
@@ -991,12 +988,6 @@
#define ALTI2_VID 0x1BC9
#define ALTI2_N3_PID 0x6001 /* Neptune 3 */
-/*
- * Ionics PlugComputer
- */
-#define IONICS_VID 0x1c0c
-#define IONICS_PLUGCOMPUTER_PID 0x0102
-
/*
* Dresden Elektronik Sensor Terminal Board
*/
diff --git a/trunk/drivers/usb/serial/generic.c b/trunk/drivers/usb/serial/generic.c
index 0b1a13384c6d..ca92f67747cc 100644
--- a/trunk/drivers/usb/serial/generic.c
+++ b/trunk/drivers/usb/serial/generic.c
@@ -518,7 +518,6 @@ void usb_serial_generic_disconnect(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; ++i)
generic_cleanup(serial->port[i]);
}
-EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect);
void usb_serial_generic_release(struct usb_serial *serial)
{
diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c
index a7cfc5952937..dc47f986df57 100644
--- a/trunk/drivers/usb/serial/io_ti.c
+++ b/trunk/drivers/usb/serial/io_ti.c
@@ -1151,7 +1151,7 @@ static int download_fw(struct edgeport_serial *serial)
/* Check if we have an old version in the I2C and
update if necessary */
- if (download_cur_ver < download_new_ver) {
+ if (download_cur_ver != download_new_ver) {
dbg("%s - Update I2C dld from %d.%d to %d.%d",
__func__,
firmware_version->Ver_Major,
@@ -1284,7 +1284,7 @@ static int download_fw(struct edgeport_serial *serial)
kfree(header);
kfree(rom_desc);
kfree(ti_manuf_desc);
- return -EINVAL;
+ return status;
}
/* Update I2C with type 0xf2 record with correct
diff --git a/trunk/drivers/usb/serial/navman.c b/trunk/drivers/usb/serial/navman.c
index 1f00f243c26c..a6b207c84917 100644
--- a/trunk/drivers/usb/serial/navman.c
+++ b/trunk/drivers/usb/serial/navman.c
@@ -25,7 +25,6 @@ static int debug;
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */
- { USB_DEVICE(0x0df7, 0x0900) }, /* Mobile Action i-gotU */
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c
index adcbdb994de3..9fc6ea2c681f 100644
--- a/trunk/drivers/usb/serial/option.c
+++ b/trunk/drivers/usb/serial/option.c
@@ -365,10 +365,6 @@ static void option_instat_callback(struct urb *urb);
#define OLIVETTI_VENDOR_ID 0x0b3c
#define OLIVETTI_PRODUCT_OLICARD100 0xc000
-/* Celot products */
-#define CELOT_VENDOR_ID 0x211f
-#define CELOT_PRODUCT_CT680M 0x6801
-
/* some devices interfaces need special handling due to a number of reasons */
enum option_blacklist_reason {
OPTION_BLACKLIST_NONE = 0,
@@ -891,9 +887,10 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) },
{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
+
{ USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
+
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
- { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c
index c98f0fb675ba..6b6001822279 100644
--- a/trunk/drivers/usb/serial/pl2303.c
+++ b/trunk/drivers/usb/serial/pl2303.c
@@ -86,7 +86,6 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
- { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
diff --git a/trunk/drivers/usb/serial/pl2303.h b/trunk/drivers/usb/serial/pl2303.h
index 43eb9bdad422..a871645389dd 100644
--- a/trunk/drivers/usb/serial/pl2303.h
+++ b/trunk/drivers/usb/serial/pl2303.h
@@ -128,10 +128,6 @@
#define CRESSI_VENDOR_ID 0x04b8
#define CRESSI_EDY_PRODUCT_ID 0x0521
-/* Zeagle dive computer interface */
-#define ZEAGLE_VENDOR_ID 0x04b8
-#define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522
-
/* Sony, USB data cable for CMD-Jxx mobile phones */
#define SONY_VENDOR_ID 0x054c
#define SONY_QN3USB_PRODUCT_ID 0x0437
diff --git a/trunk/drivers/usb/serial/ssu100.c b/trunk/drivers/usb/serial/ssu100.c
index 660c31f14999..6e82d4f54bc8 100644
--- a/trunk/drivers/usb/serial/ssu100.c
+++ b/trunk/drivers/usb/serial/ssu100.c
@@ -15,7 +15,6 @@
#include
#include
#include
-#include
#include
#define QT_OPEN_CLOSE_CHANNEL 0xca
@@ -28,11 +27,36 @@
#define QT_HW_FLOW_CONTROL_MASK 0xc5
#define QT_SW_FLOW_CONTROL_MASK 0xc6
+#define MODEM_CTL_REGISTER 0x04
+#define MODEM_STATUS_REGISTER 0x06
+
+
+#define SERIAL_LSR_OE 0x02
+#define SERIAL_LSR_PE 0x04
+#define SERIAL_LSR_FE 0x08
+#define SERIAL_LSR_BI 0x10
+
+#define SERIAL_LSR_TEMT 0x40
+
+#define SERIAL_MCR_DTR 0x01
+#define SERIAL_MCR_RTS 0x02
+#define SERIAL_MCR_LOOP 0x10
+
+#define SERIAL_MSR_CTS 0x10
+#define SERIAL_MSR_CD 0x80
+#define SERIAL_MSR_RI 0x40
+#define SERIAL_MSR_DSR 0x20
#define SERIAL_MSR_MASK 0xf0
-#define SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS)
+#define SERIAL_CRTSCTS ((SERIAL_MCR_RTS << 8) | SERIAL_MSR_CTS)
-#define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR)
+#define SERIAL_8_DATA 0x03
+#define SERIAL_7_DATA 0x02
+#define SERIAL_6_DATA 0x01
+#define SERIAL_5_DATA 0x00
+
+#define SERIAL_ODD_PARITY 0X08
+#define SERIAL_EVEN_PARITY 0X18
#define MAX_BAUD_RATE 460800
@@ -75,12 +99,10 @@ static struct usb_driver ssu100_driver = {
};
struct ssu100_port_private {
- spinlock_t status_lock;
u8 shadowLSR;
u8 shadowMSR;
wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
unsigned short max_packet_size;
- struct async_icount icount;
};
static void ssu100_release(struct usb_serial *serial)
@@ -128,10 +150,9 @@ static inline int ssu100_getregister(struct usb_device *dev,
static inline int ssu100_setregister(struct usb_device *dev,
unsigned short uart,
- unsigned short reg,
u16 data)
{
- u16 value = (data << 8) | reg;
+ u16 value = (data << 8) | MODEM_CTL_REGISTER;
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0x40, value, uart,
@@ -157,11 +178,11 @@ static inline int update_mctrl(struct usb_device *dev, unsigned int set,
clear &= ~set; /* 'set' takes precedence over 'clear' */
urb_value = 0;
if (set & TIOCM_DTR)
- urb_value |= UART_MCR_DTR;
+ urb_value |= SERIAL_MCR_DTR;
if (set & TIOCM_RTS)
- urb_value |= UART_MCR_RTS;
+ urb_value |= SERIAL_MCR_RTS;
- result = ssu100_setregister(dev, 0, UART_MCR, urb_value);
+ result = ssu100_setregister(dev, 0, urb_value);
if (result < 0)
dbg("%s Error from MODEM_CTRL urb", __func__);
@@ -243,24 +264,24 @@ static void ssu100_set_termios(struct tty_struct *tty,
if (cflag & PARENB) {
if (cflag & PARODD)
- urb_value |= UART_LCR_PARITY;
+ urb_value |= SERIAL_ODD_PARITY;
else
urb_value |= SERIAL_EVEN_PARITY;
}
switch (cflag & CSIZE) {
case CS5:
- urb_value |= UART_LCR_WLEN5;
+ urb_value |= SERIAL_5_DATA;
break;
case CS6:
- urb_value |= UART_LCR_WLEN6;
+ urb_value |= SERIAL_6_DATA;
break;
case CS7:
- urb_value |= UART_LCR_WLEN7;
+ urb_value |= SERIAL_7_DATA;
break;
default:
case CS8:
- urb_value |= UART_LCR_WLEN8;
+ urb_value |= SERIAL_8_DATA;
break;
}
@@ -312,7 +333,6 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
struct ssu100_port_private *priv = usb_get_serial_port_data(port);
u8 *data;
int result;
- unsigned long flags;
dbg("%s - port %d", __func__, port->number);
@@ -330,10 +350,11 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
return result;
}
- spin_lock_irqsave(&priv->status_lock, flags);
- priv->shadowLSR = data[0];
- priv->shadowMSR = data[1];
- spin_unlock_irqrestore(&priv->status_lock, flags);
+ priv->shadowLSR = data[0] & (SERIAL_LSR_OE | SERIAL_LSR_PE |
+ SERIAL_LSR_FE | SERIAL_LSR_BI);
+
+ priv->shadowMSR = data[1] & (SERIAL_MSR_CTS | SERIAL_MSR_DSR |
+ SERIAL_MSR_RI | SERIAL_MSR_CD);
kfree(data);
@@ -377,51 +398,11 @@ static int get_serial_info(struct usb_serial_port *port,
return 0;
}
-static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
-{
- struct ssu100_port_private *priv = usb_get_serial_port_data(port);
- struct async_icount prev, cur;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->status_lock, flags);
- prev = priv->icount;
- spin_unlock_irqrestore(&priv->status_lock, flags);
-
- while (1) {
- wait_event_interruptible(priv->delta_msr_wait,
- ((priv->icount.rng != prev.rng) ||
- (priv->icount.dsr != prev.dsr) ||
- (priv->icount.dcd != prev.dcd) ||
- (priv->icount.cts != prev.cts)));
-
- if (signal_pending(current))
- return -ERESTARTSYS;
-
- spin_lock_irqsave(&priv->status_lock, flags);
- cur = priv->icount;
- spin_unlock_irqrestore(&priv->status_lock, flags);
-
- if ((prev.rng == cur.rng) &&
- (prev.dsr == cur.dsr) &&
- (prev.dcd == cur.dcd) &&
- (prev.cts == cur.cts))
- return -EIO;
-
- if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) ||
- (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) ||
- (arg & TIOCM_CD && (prev.dcd != cur.dcd)) ||
- (arg & TIOCM_CTS && (prev.cts != cur.cts)))
- return 0;
- }
- return 0;
-}
-
static int ssu100_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct usb_serial_port *port = tty->driver_data;
struct ssu100_port_private *priv = usb_get_serial_port_data(port);
- void __user *user_arg = (void __user *)arg;
dbg("%s cmd 0x%04x", __func__, cmd);
@@ -431,28 +412,28 @@ static int ssu100_ioctl(struct tty_struct *tty, struct file *file,
(struct serial_struct __user *) arg);
case TIOCMIWAIT:
- return wait_modem_info(port, arg);
-
- case TIOCGICOUNT:
- {
- struct serial_icounter_struct icount;
- struct async_icount cnow = priv->icount;
- memset(&icount, 0, sizeof(icount));
- icount.cts = cnow.cts;
- icount.dsr = cnow.dsr;
- icount.rng = cnow.rng;
- icount.dcd = cnow.dcd;
- icount.rx = cnow.rx;
- icount.tx = cnow.tx;
- icount.frame = cnow.frame;
- icount.overrun = cnow.overrun;
- icount.parity = cnow.parity;
- icount.brk = cnow.brk;
- icount.buf_overrun = cnow.buf_overrun;
- if (copy_to_user(user_arg, &icount, sizeof(icount)))
- return -EFAULT;
+ while (priv != NULL) {
+ u8 prevMSR = priv->shadowMSR & SERIAL_MSR_MASK;
+ interruptible_sleep_on(&priv->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ else {
+ u8 diff = (priv->shadowMSR & SERIAL_MSR_MASK) ^ prevMSR;
+ if (!diff)
+ return -EIO; /* no change => error */
+
+ /* Return 0 if caller wanted to know about
+ these bits */
+
+ if (((arg & TIOCM_RNG) && (diff & SERIAL_MSR_RI)) ||
+ ((arg & TIOCM_DSR) && (diff & SERIAL_MSR_DSR)) ||
+ ((arg & TIOCM_CD) && (diff & SERIAL_MSR_CD)) ||
+ ((arg & TIOCM_CTS) && (diff & SERIAL_MSR_CTS)))
+ return 0;
+ }
+ }
return 0;
- }
default:
break;
@@ -474,7 +455,6 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port)
unsigned num_endpoints;
int i;
- unsigned long flags;
num_endpoints = interface->cur_altsetting->desc.bNumEndpoints;
dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints);
@@ -486,9 +466,7 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port)
}
/* set max packet size based on descriptor */
- spin_lock_irqsave(&priv->status_lock, flags);
priv->max_packet_size = ep_desc->wMaxPacketSize;
- spin_unlock_irqrestore(&priv->status_lock, flags);
dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);
}
@@ -507,9 +485,9 @@ static int ssu100_attach(struct usb_serial *serial)
return -ENOMEM;
}
- spin_lock_init(&priv->status_lock);
init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(port, priv);
+
ssu100_set_max_packet_size(port);
return ssu100_initdevice(serial->dev);
@@ -528,20 +506,20 @@ static int ssu100_tiocmget(struct tty_struct *tty, struct file *file)
if (!d)
return -ENOMEM;
- r = ssu100_getregister(dev, 0, UART_MCR, d);
+ r = ssu100_getregister(dev, 0, MODEM_CTL_REGISTER, d);
if (r < 0)
goto mget_out;
- r = ssu100_getregister(dev, 0, UART_MSR, d+1);
+ r = ssu100_getregister(dev, 0, MODEM_STATUS_REGISTER, d+1);
if (r < 0)
goto mget_out;
- r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) |
- (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) |
- (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) |
- (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) |
- (d[1] & UART_MSR_RI ? TIOCM_RI : 0) |
- (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0);
+ r = (d[0] & SERIAL_MCR_DTR ? TIOCM_DTR : 0) |
+ (d[0] & SERIAL_MCR_RTS ? TIOCM_RTS : 0) |
+ (d[1] & SERIAL_MSR_CTS ? TIOCM_CTS : 0) |
+ (d[1] & SERIAL_MSR_CD ? TIOCM_CAR : 0) |
+ (d[1] & SERIAL_MSR_RI ? TIOCM_RI : 0) |
+ (d[1] & SERIAL_MSR_DSR ? TIOCM_DSR : 0);
mget_out:
kfree(d);
@@ -568,7 +546,7 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on)
if (!port->serial->disconnected) {
/* Disable flow control */
if (!on &&
- ssu100_setregister(dev, 0, UART_MCR, 0) < 0)
+ ssu100_setregister(dev, 0, 0) < 0)
dev_err(&port->dev, "error from flowcontrol urb\n");
/* drop RTS and DTR */
if (on)
@@ -579,88 +557,34 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on)
mutex_unlock(&port->serial->disc_mutex);
}
-static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
-{
- struct ssu100_port_private *priv = usb_get_serial_port_data(port);
- unsigned long flags;
-
- spin_lock_irqsave(&priv->status_lock, flags);
- priv->shadowMSR = msr;
- spin_unlock_irqrestore(&priv->status_lock, flags);
-
- if (msr & UART_MSR_ANY_DELTA) {
- /* update input line counters */
- if (msr & UART_MSR_DCTS)
- priv->icount.cts++;
- if (msr & UART_MSR_DDSR)
- priv->icount.dsr++;
- if (msr & UART_MSR_DDCD)
- priv->icount.dcd++;
- if (msr & UART_MSR_TERI)
- priv->icount.rng++;
- wake_up_interruptible(&priv->delta_msr_wait);
- }
-}
-
-static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr,
- char *tty_flag)
-{
- struct ssu100_port_private *priv = usb_get_serial_port_data(port);
- unsigned long flags;
-
- spin_lock_irqsave(&priv->status_lock, flags);
- priv->shadowLSR = lsr;
- spin_unlock_irqrestore(&priv->status_lock, flags);
-
- *tty_flag = TTY_NORMAL;
- if (lsr & UART_LSR_BRK_ERROR_BITS) {
- /* we always want to update icount, but we only want to
- * update tty_flag for one case */
- if (lsr & UART_LSR_BI) {
- priv->icount.brk++;
- *tty_flag = TTY_BREAK;
- usb_serial_handle_break(port);
- }
- if (lsr & UART_LSR_PE) {
- priv->icount.parity++;
- if (*tty_flag == TTY_NORMAL)
- *tty_flag = TTY_PARITY;
- }
- if (lsr & UART_LSR_FE) {
- priv->icount.frame++;
- if (*tty_flag == TTY_NORMAL)
- *tty_flag = TTY_FRAME;
- }
- if (lsr & UART_LSR_OE){
- priv->icount.overrun++;
- if (*tty_flag == TTY_NORMAL)
- *tty_flag = TTY_OVERRUN;
- }
- }
-
-}
-
static int ssu100_process_packet(struct tty_struct *tty,
struct usb_serial_port *port,
struct ssu100_port_private *priv,
char *packet, int len)
{
int i;
- char flag = TTY_NORMAL;
+ char flag;
char *ch;
dbg("%s - port %d", __func__, port->number);
- if ((len >= 4) &&
- (packet[0] == 0x1b) && (packet[1] == 0x1b) &&
+ if (len < 4) {
+ dbg("%s - malformed packet", __func__);
+ return 0;
+ }
+
+ if ((packet[0] == 0x1b) && (packet[1] == 0x1b) &&
((packet[2] == 0x00) || (packet[2] == 0x01))) {
- if (packet[2] == 0x00) {
- ssu100_update_lsr(port, packet[3], &flag);
- if (flag == TTY_OVERRUN)
- tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+ if (packet[2] == 0x00)
+ priv->shadowLSR = packet[3] & (SERIAL_LSR_OE |
+ SERIAL_LSR_PE |
+ SERIAL_LSR_FE |
+ SERIAL_LSR_BI);
+
+ if (packet[2] == 0x01) {
+ priv->shadowMSR = packet[3];
+ wake_up_interruptible(&priv->delta_msr_wait);
}
- if (packet[2] == 0x01)
- ssu100_update_msr(port, packet[3]);
len -= 4;
ch = packet + 4;
@@ -707,6 +631,7 @@ static void ssu100_process_read_urb(struct urb *urb)
tty_kref_put(tty);
}
+
static struct usb_serial_driver ssu100_device = {
.driver = {
.owner = THIS_MODULE,
@@ -728,7 +653,6 @@ static struct usb_serial_driver ssu100_device = {
.tiocmset = ssu100_tiocmset,
.ioctl = ssu100_ioctl,
.set_termios = ssu100_set_termios,
- .disconnect = usb_serial_generic_disconnect,
};
static int __init ssu100_init(void)
diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c
index 7a2177c79bde..2a982e62963b 100644
--- a/trunk/drivers/usb/serial/usb-serial.c
+++ b/trunk/drivers/usb/serial/usb-serial.c
@@ -736,7 +736,6 @@ int usb_serial_probe(struct usb_interface *interface,
serial = create_serial(dev, interface, type);
if (!serial) {
- module_put(type->driver.owner);
dev_err(&interface->dev, "%s - out of memory\n", __func__);
return -ENOMEM;
}
@@ -747,11 +746,11 @@ int usb_serial_probe(struct usb_interface *interface,
id = get_iface_id(type, interface);
retval = type->probe(serial, id);
+ module_put(type->driver.owner);
if (retval) {
dbg("sub driver rejected device");
kfree(serial);
- module_put(type->driver.owner);
return retval;
}
}
@@ -823,7 +822,6 @@ int usb_serial_probe(struct usb_interface *interface,
if (num_bulk_in == 0 || num_bulk_out == 0) {
dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
kfree(serial);
- module_put(type->driver.owner);
return -ENODEV;
}
}
@@ -837,15 +835,22 @@ int usb_serial_probe(struct usb_interface *interface,
dev_err(&interface->dev,
"Generic device with no bulk out, not allowed.\n");
kfree(serial);
- module_put(type->driver.owner);
return -EIO;
}
}
#endif
if (!num_ports) {
/* if this device type has a calc_num_ports function, call it */
- if (type->calc_num_ports)
+ if (type->calc_num_ports) {
+ if (!try_module_get(type->driver.owner)) {
+ dev_err(&interface->dev,
+ "module get failed, exiting\n");
+ kfree(serial);
+ return -EIO;
+ }
num_ports = type->calc_num_ports(serial);
+ module_put(type->driver.owner);
+ }
if (!num_ports)
num_ports = type->num_ports;
}
@@ -1034,7 +1039,13 @@ int usb_serial_probe(struct usb_interface *interface,
/* if this device type has an attach function, call it */
if (type->attach) {
+ if (!try_module_get(type->driver.owner)) {
+ dev_err(&interface->dev,
+ "module get failed, exiting\n");
+ goto probe_error;
+ }
retval = type->attach(serial);
+ module_put(type->driver.owner);
if (retval < 0)
goto probe_error;
serial->attached = 1;
@@ -1077,12 +1088,10 @@ int usb_serial_probe(struct usb_interface *interface,
exit:
/* success */
usb_set_intfdata(interface, serial);
- module_put(type->driver.owner);
return 0;
probe_error:
usb_serial_put(serial);
- module_put(type->driver.owner);
return -EIO;
}
EXPORT_SYMBOL_GPL(usb_serial_probe);
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/drivers/xen/events.c b/trunk/drivers/xen/events.c
index 13365ba35218..72f91bff29c7 100644
--- a/trunk/drivers/xen/events.c
+++ b/trunk/drivers/xen/events.c
@@ -112,7 +112,6 @@ static inline unsigned long *cpu_evtchn_mask(int cpu)
#define VALID_EVTCHN(chn) ((chn) != 0)
static struct irq_chip xen_dynamic_chip;
-static struct irq_chip xen_percpu_chip;
/* Constructor for packed IRQ information. */
static struct irq_info mk_unbound_info(void)
@@ -378,7 +377,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
irq = find_unbound_irq();
set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
- handle_edge_irq, "event");
+ handle_level_irq, "event");
evtchn_to_irq[evtchn] = irq;
irq_info[irq] = mk_evtchn_info(evtchn);
@@ -404,8 +403,8 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
if (irq < 0)
goto out;
- set_irq_chip_and_handler_name(irq, &xen_percpu_chip,
- handle_percpu_irq, "ipi");
+ set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
+ handle_level_irq, "ipi");
bind_ipi.vcpu = cpu;
if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
@@ -445,8 +444,8 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
irq = find_unbound_irq();
- set_irq_chip_and_handler_name(irq, &xen_percpu_chip,
- handle_percpu_irq, "virq");
+ set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
+ handle_level_irq, "virq");
evtchn_to_irq[evtchn] = irq;
irq_info[irq] = mk_virq_info(evtchn, virq);
@@ -965,16 +964,6 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
.retrigger = retrigger_dynirq,
};
-static struct irq_chip xen_percpu_chip __read_mostly = {
- .name = "xen-percpu",
-
- .disable = disable_dynirq,
- .mask = disable_dynirq,
- .unmask = enable_dynirq,
-
- .ack = ack_dynirq,
-};
-
int xen_set_callback_via(uint64_t via)
{
struct xen_hvm_param a;
diff --git a/trunk/firmware/Makefile b/trunk/firmware/Makefile
index 9c2d19452d0b..b27f09f05d17 100644
--- a/trunk/firmware/Makefile
+++ b/trunk/firmware/Makefile
@@ -142,7 +142,7 @@ fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin
fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)
# Directories which we _might_ need to create, so we have a rule for them.
-firmware-dirs := $(sort $(addprefix $(objtree)/$(obj)/,$(dir $(fw-external-y) $(fw-shipped-all))))
+firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(fw-external-y) $(fw-shipped-all))))
quiet_cmd_mkdir = MKDIR $(patsubst $(objtree)/%,%,$@)
cmd_mkdir = mkdir -p $@
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/cifs/dir.c b/trunk/fs/cifs/dir.c
index 578d88c5b46e..f17d50047f07 100644
--- a/trunk/fs/cifs/dir.c
+++ b/trunk/fs/cifs/dir.c
@@ -496,6 +496,11 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
struct cifsTconInfo *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
+ int oplock = 0;
+ u16 fileHandle;
+ FILE_ALL_INFO *buf = NULL;
+ unsigned int bytes_written;
+ struct win_dev *pdev;
if (!old_valid_dev(device_number))
return -EINVAL;
@@ -506,9 +511,12 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
pTcon = cifs_sb->tcon;
full_path = build_path_from_dentry(direntry);
- if (full_path == NULL)
+ if (full_path == NULL) {
rc = -ENOMEM;
- else if (pTcon->unix_ext) {
+ goto mknod_out;
+ }
+
+ if (pTcon->unix_ext) {
struct cifs_unix_set_info_args args = {
.mode = mode & ~current_umask(),
.ctime = NO_CHANGE_64,
@@ -527,87 +535,78 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (rc)
+ goto mknod_out;
- if (!rc) {
- rc = cifs_get_inode_info_unix(&newinode, full_path,
+ rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb, xid);
- if (pTcon->nocase)
- direntry->d_op = &cifs_ci_dentry_ops;
- else
- direntry->d_op = &cifs_dentry_ops;
- if (rc == 0)
- d_instantiate(direntry, newinode);
- }
- } else {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
- int oplock = 0;
- u16 fileHandle;
- FILE_ALL_INFO *buf;
+ if (pTcon->nocase)
+ direntry->d_op = &cifs_ci_dentry_ops;
+ else
+ direntry->d_op = &cifs_dentry_ops;
- cFYI(1, "sfu compat create special file");
+ if (rc == 0)
+ d_instantiate(direntry, newinode);
+ goto mknod_out;
+ }
- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
- if (buf == NULL) {
- kfree(full_path);
- rc = -ENOMEM;
- FreeXid(xid);
- return rc;
- }
+ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
+ goto mknod_out;
- rc = CIFSSMBOpen(xid, pTcon, full_path,
- FILE_CREATE, /* fail if exists */
- GENERIC_WRITE /* BB would
- WRITE_OWNER | WRITE_DAC be better? */,
- /* Create a file and set the
- file attribute to SYSTEM */
- CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
- &fileHandle, &oplock, buf,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- /* BB FIXME - add handling for backlevel servers
- which need legacy open and check for all
- calls to SMBOpen for fallback to SMBLeagcyOpen */
- if (!rc) {
- /* BB Do not bother to decode buf since no
- local inode yet to put timestamps in,
- but we can reuse it safely */
- unsigned int bytes_written;
- struct win_dev *pdev;
- pdev = (struct win_dev *)buf;
- if (S_ISCHR(mode)) {
- memcpy(pdev->type, "IntxCHR", 8);
- pdev->major =
- cpu_to_le64(MAJOR(device_number));
- pdev->minor =
- cpu_to_le64(MINOR(device_number));
- rc = CIFSSMBWrite(xid, pTcon,
- fileHandle,
- sizeof(struct win_dev),
- 0, &bytes_written, (char *)pdev,
- NULL, 0);
- } else if (S_ISBLK(mode)) {
- memcpy(pdev->type, "IntxBLK", 8);
- pdev->major =
- cpu_to_le64(MAJOR(device_number));
- pdev->minor =
- cpu_to_le64(MINOR(device_number));
- rc = CIFSSMBWrite(xid, pTcon,
- fileHandle,
- sizeof(struct win_dev),
- 0, &bytes_written, (char *)pdev,
- NULL, 0);
- } /* else if(S_ISFIFO */
- CIFSSMBClose(xid, pTcon, fileHandle);
- d_drop(direntry);
- }
- kfree(buf);
- /* add code here to set EAs */
- }
+
+ cFYI(1, "sfu compat create special file");
+
+ buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+ if (buf == NULL) {
+ kfree(full_path);
+ rc = -ENOMEM;
+ FreeXid(xid);
+ return rc;
}
+ /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
+ rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
+ GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
+ &fileHandle, &oplock, buf, cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (rc)
+ goto mknod_out;
+
+ /* BB Do not bother to decode buf since no local inode yet to put
+ * timestamps in, but we can reuse it safely */
+
+ pdev = (struct win_dev *)buf;
+ if (S_ISCHR(mode)) {
+ memcpy(pdev->type, "IntxCHR", 8);
+ pdev->major =
+ cpu_to_le64(MAJOR(device_number));
+ pdev->minor =
+ cpu_to_le64(MINOR(device_number));
+ rc = CIFSSMBWrite(xid, pTcon,
+ fileHandle,
+ sizeof(struct win_dev),
+ 0, &bytes_written, (char *)pdev,
+ NULL, 0);
+ } else if (S_ISBLK(mode)) {
+ memcpy(pdev->type, "IntxBLK", 8);
+ pdev->major =
+ cpu_to_le64(MAJOR(device_number));
+ pdev->minor =
+ cpu_to_le64(MINOR(device_number));
+ rc = CIFSSMBWrite(xid, pTcon,
+ fileHandle,
+ sizeof(struct win_dev),
+ 0, &bytes_written, (char *)pdev,
+ NULL, 0);
+ } /* else if (S_ISFIFO) */
+ CIFSSMBClose(xid, pTcon, fileHandle);
+ d_drop(direntry);
+
+ /* FIXME: add code here to set EAs */
+
+mknod_out:
kfree(full_path);
+ kfree(buf);
FreeXid(xid);
return rc;
}
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/fs/xfs/linux-2.6/xfs_aops.c b/trunk/fs/xfs/linux-2.6/xfs_aops.c
index b552f816de15..15412fe15c3a 100644
--- a/trunk/fs/xfs/linux-2.6/xfs_aops.c
+++ b/trunk/fs/xfs/linux-2.6/xfs_aops.c
@@ -852,8 +852,8 @@ xfs_convert_page(
SetPageUptodate(page);
if (count) {
- if (--wbc->nr_to_write <= 0 &&
- wbc->sync_mode == WB_SYNC_NONE)
+ wbc->nr_to_write--;
+ if (wbc->nr_to_write <= 0)
done = 1;
}
xfs_start_page_writeback(page, !page_dirty, count);
@@ -1068,7 +1068,7 @@ xfs_vm_writepage(
* by themselves.
*/
if ((current->flags & (PF_MEMALLOC|PF_KSWAPD)) == PF_MEMALLOC)
- goto redirty;
+ goto out_fail;
/*
* We need a transaction if there are delalloc or unwritten buffers
@@ -1080,7 +1080,7 @@ xfs_vm_writepage(
*/
xfs_count_page_state(page, &delalloc, &unwritten);
if ((current->flags & PF_FSTRANS) && (delalloc || unwritten))
- goto redirty;
+ goto out_fail;
/* Is this page beyond the end of the file? */
offset = i_size_read(inode);
@@ -1245,15 +1245,12 @@ xfs_vm_writepage(
if (iohead)
xfs_cancel_ioend(iohead);
- if (err == -EAGAIN)
- goto redirty;
-
xfs_aops_discard_page(page);
ClearPageUptodate(page);
unlock_page(page);
return err;
-redirty:
+out_fail:
redirty_page_for_writepage(wbc, page);
unlock_page(page);
return 0;
diff --git a/trunk/fs/xfs/linux-2.6/xfs_super.c b/trunk/fs/xfs/linux-2.6/xfs_super.c
index a4e07974955b..15c35b62ff14 100644
--- a/trunk/fs/xfs/linux-2.6/xfs_super.c
+++ b/trunk/fs/xfs/linux-2.6/xfs_super.c
@@ -1226,7 +1226,6 @@ xfs_fs_statfs(
struct xfs_inode *ip = XFS_I(dentry->d_inode);
__uint64_t fakeinos, id;
xfs_extlen_t lsize;
- __int64_t ffree;
statp->f_type = XFS_SB_MAGIC;
statp->f_namelen = MAXNAMELEN - 1;
@@ -1250,11 +1249,7 @@ xfs_fs_statfs(
statp->f_files = min_t(typeof(statp->f_files),
statp->f_files,
mp->m_maxicount);
-
- /* make sure statp->f_ffree does not underflow */
- ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
- statp->f_ffree = max_t(__int64_t, ffree, 0);
-
+ statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
spin_unlock(&mp->m_sb_lock);
if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
@@ -1407,7 +1402,7 @@ xfs_fs_freeze(
xfs_save_resvblks(mp);
xfs_quiesce_attr(mp);
- return -xfs_fs_log_dummy(mp, SYNC_WAIT);
+ return -xfs_fs_log_dummy(mp);
}
STATIC int
diff --git a/trunk/fs/xfs/linux-2.6/xfs_sync.c b/trunk/fs/xfs/linux-2.6/xfs_sync.c
index d59c4a65d492..dfcbd98d1599 100644
--- a/trunk/fs/xfs/linux-2.6/xfs_sync.c
+++ b/trunk/fs/xfs/linux-2.6/xfs_sync.c
@@ -34,7 +34,6 @@
#include "xfs_inode_item.h"
#include "xfs_quota.h"
#include "xfs_trace.h"
-#include "xfs_fsops.h"
#include
#include
@@ -341,6 +340,38 @@ xfs_sync_attr(
XFS_ICI_NO_TAG, 0, NULL);
}
+STATIC int
+xfs_commit_dummy_trans(
+ struct xfs_mount *mp,
+ uint flags)
+{
+ struct xfs_inode *ip = mp->m_rootip;
+ struct xfs_trans *tp;
+ int error;
+
+ /*
+ * Put a dummy transaction in the log to tell recovery
+ * that all others are OK.
+ */
+ tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
+ error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0);
+ if (error) {
+ xfs_trans_cancel(tp, 0);
+ return error;
+ }
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+
+ xfs_trans_ijoin(tp, ip);
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+ error = xfs_trans_commit(tp, 0);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+
+ /* the log force ensures this transaction is pushed to disk */
+ xfs_log_force(mp, (flags & SYNC_WAIT) ? XFS_LOG_SYNC : 0);
+ return error;
+}
+
STATIC int
xfs_sync_fsdata(
struct xfs_mount *mp)
@@ -401,7 +432,7 @@ xfs_quiesce_data(
/* mark the log as covered if needed */
if (xfs_log_need_covered(mp))
- error2 = xfs_fs_log_dummy(mp, SYNC_WAIT);
+ error2 = xfs_commit_dummy_trans(mp, SYNC_WAIT);
/* flush data-only devices */
if (mp->m_rtdev_targp)
@@ -532,7 +563,7 @@ xfs_flush_inodes(
/*
* Every sync period we need to unpin all items, reclaim inodes and sync
* disk quotas. We might need to cover the log to indicate that the
- * filesystem is idle and not frozen.
+ * filesystem is idle.
*/
STATIC void
xfs_sync_worker(
@@ -546,9 +577,8 @@ xfs_sync_worker(
xfs_reclaim_inodes(mp, 0);
/* dgc: errors ignored here */
error = xfs_qm_sync(mp, SYNC_TRYLOCK);
- if (mp->m_super->s_frozen == SB_UNFROZEN &&
- xfs_log_need_covered(mp))
- error = xfs_fs_log_dummy(mp, 0);
+ if (xfs_log_need_covered(mp))
+ error = xfs_commit_dummy_trans(mp, 0);
}
mp->m_sync_seq++;
wake_up(&mp->m_wait_single_sync_task);
diff --git a/trunk/fs/xfs/xfs_fsops.c b/trunk/fs/xfs/xfs_fsops.c
index 43b1d5699335..dbca5f5c37ba 100644
--- a/trunk/fs/xfs/xfs_fsops.c
+++ b/trunk/fs/xfs/xfs_fsops.c
@@ -604,36 +604,31 @@ xfs_reserve_blocks(
return 0;
}
-/*
- * Dump a transaction into the log that contains no real change. This is needed
- * to be able to make the log dirty or stamp the current tail LSN into the log
- * during the covering operation.
- *
- * We cannot use an inode here for this - that will push dirty state back up
- * into the VFS and then periodic inode flushing will prevent log covering from
- * making progress. Hence we log a field in the superblock instead.
- */
int
xfs_fs_log_dummy(
- xfs_mount_t *mp,
- int flags)
+ xfs_mount_t *mp)
{
xfs_trans_t *tp;
+ xfs_inode_t *ip;
int error;
tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP);
- error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
- XFS_DEFAULT_LOG_COUNT);
+ error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0);
if (error) {
xfs_trans_cancel(tp, 0);
return error;
}
- /* log the UUID because it is an unchanging field */
- xfs_mod_sb(tp, XFS_SB_UUID);
- if (flags & SYNC_WAIT)
- xfs_trans_set_sync(tp);
- return xfs_trans_commit(tp, 0);
+ ip = mp->m_rootip;
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+
+ xfs_trans_ijoin(tp, ip);
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+ xfs_trans_set_sync(tp);
+ error = xfs_trans_commit(tp, 0);
+
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ return error;
}
int
diff --git a/trunk/fs/xfs/xfs_fsops.h b/trunk/fs/xfs/xfs_fsops.h
index a786c5212c1e..88435e0a77c9 100644
--- a/trunk/fs/xfs/xfs_fsops.h
+++ b/trunk/fs/xfs/xfs_fsops.h
@@ -25,6 +25,6 @@ extern int xfs_fs_counts(xfs_mount_t *mp, xfs_fsop_counts_t *cnt);
extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval,
xfs_fsop_resblks_t *outval);
extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags);
-extern int xfs_fs_log_dummy(xfs_mount_t *mp, int flags);
+extern int xfs_fs_log_dummy(xfs_mount_t *mp);
#endif /* __XFS_FSOPS_H__ */
diff --git a/trunk/fs/xfs/xfs_ialloc.c b/trunk/fs/xfs/xfs_ialloc.c
index 5371d2dc360e..abf80ae1e95b 100644
--- a/trunk/fs/xfs/xfs_ialloc.c
+++ b/trunk/fs/xfs/xfs_ialloc.c
@@ -1213,6 +1213,7 @@ xfs_imap_lookup(
struct xfs_inobt_rec_incore rec;
struct xfs_btree_cur *cur;
struct xfs_buf *agbp;
+ xfs_agino_t startino;
int error;
int i;
@@ -1226,13 +1227,13 @@ xfs_imap_lookup(
}
/*
- * Lookup the inode record for the given agino. If the record cannot be
- * found, then it's an invalid inode number and we should abort. Once
- * we have a record, we need to ensure it contains the inode number
- * we are looking up.
+ * derive and lookup the exact inode record for the given agino. If the
+ * record cannot be found, then it's an invalid inode number and we
+ * should abort.
*/
cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
- error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);
+ startino = agino & ~(XFS_IALLOC_INODES(mp) - 1);
+ error = xfs_inobt_lookup(cur, startino, XFS_LOOKUP_EQ, &i);
if (!error) {
if (i)
error = xfs_inobt_get_rec(cur, &rec, &i);
@@ -1245,11 +1246,6 @@ xfs_imap_lookup(
if (error)
return error;
- /* check that the returned record contains the required inode */
- if (rec.ir_startino > agino ||
- rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino)
- return EINVAL;
-
/* for untrusted inodes check it is allocated first */
if ((flags & XFS_IGET_UNTRUSTED) &&
(rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino)))
diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c
index 34798f391c49..68415cb4f23c 100644
--- a/trunk/fs/xfs/xfs_inode.c
+++ b/trunk/fs/xfs/xfs_inode.c
@@ -1914,11 +1914,6 @@ xfs_iunlink_remove(
return 0;
}
-/*
- * A big issue when freeing the inode cluster is is that we _cannot_ skip any
- * inodes that are in memory - they all must be marked stale and attached to
- * the cluster buffer.
- */
STATIC void
xfs_ifree_cluster(
xfs_inode_t *free_ip,
@@ -1950,6 +1945,8 @@ xfs_ifree_cluster(
}
for (j = 0; j < nbufs; j++, inum += ninodes) {
+ int found = 0;
+
blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum),
XFS_INO_TO_AGBNO(mp, inum));
@@ -1968,9 +1965,7 @@ xfs_ifree_cluster(
/*
* Walk the inodes already attached to the buffer and mark them
* stale. These will all have the flush locks held, so an
- * in-memory inode walk can't lock them. By marking them all
- * stale first, we will not attempt to lock them in the loop
- * below as the XFS_ISTALE flag will be set.
+ * in-memory inode walk can't lock them.
*/
lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
while (lip) {
@@ -1982,11 +1977,11 @@ xfs_ifree_cluster(
&iip->ili_flush_lsn,
&iip->ili_item.li_lsn);
xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
+ found++;
}
lip = lip->li_bio_list;
}
-
/*
* For each inode in memory attempt to add it to the inode
* buffer and set it up for being staled on buffer IO
@@ -1998,7 +1993,6 @@ xfs_ifree_cluster(
* even trying to lock them.
*/
for (i = 0; i < ninodes; i++) {
-retry:
read_lock(&pag->pag_ici_lock);
ip = radix_tree_lookup(&pag->pag_ici_root,
XFS_INO_TO_AGINO(mp, (inum + i)));
@@ -2009,36 +2003,38 @@ xfs_ifree_cluster(
continue;
}
- /*
- * Don't try to lock/unlock the current inode, but we
- * _cannot_ skip the other inodes that we did not find
- * in the list attached to the buffer and are not
- * already marked stale. If we can't lock it, back off
- * and retry.
- */
+ /* don't try to lock/unlock the current inode */
if (ip != free_ip &&
!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
read_unlock(&pag->pag_ici_lock);
- delay(1);
- goto retry;
+ continue;
}
read_unlock(&pag->pag_ici_lock);
- xfs_iflock(ip);
+ if (!xfs_iflock_nowait(ip)) {
+ if (ip != free_ip)
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ continue;
+ }
+
xfs_iflags_set(ip, XFS_ISTALE);
+ if (xfs_inode_clean(ip)) {
+ ASSERT(ip != free_ip);
+ xfs_ifunlock(ip);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ continue;
+ }
- /*
- * we don't need to attach clean inodes or those only
- * with unlogged changes (which we throw away, anyway).
- */
iip = ip->i_itemp;
- if (!iip || xfs_inode_clean(ip)) {
+ if (!iip) {
+ /* inode with unlogged changes only */
ASSERT(ip != free_ip);
ip->i_update_core = 0;
xfs_ifunlock(ip);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
continue;
}
+ found++;
iip->ili_last_fields = iip->ili_format.ilf_fields;
iip->ili_format.ilf_fields = 0;
@@ -2053,7 +2049,8 @@ xfs_ifree_cluster(
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
- xfs_trans_stale_inode_buf(tp, bp);
+ if (found)
+ xfs_trans_stale_inode_buf(tp, bp);
xfs_trans_binval(tp, bp);
}
diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c
index 33f718f92a48..925d572bf0f4 100644
--- a/trunk/fs/xfs/xfs_log.c
+++ b/trunk/fs/xfs/xfs_log.c
@@ -3015,8 +3015,7 @@ _xfs_log_force(
XFS_STATS_INC(xs_log_force);
- if (log->l_cilp)
- xlog_cil_force(log);
+ xlog_cil_push(log, 1);
spin_lock(&log->l_icloglock);
@@ -3168,7 +3167,7 @@ _xfs_log_force_lsn(
XFS_STATS_INC(xs_log_force);
if (log->l_cilp) {
- lsn = xlog_cil_force_lsn(log, lsn);
+ lsn = xlog_cil_push_lsn(log, lsn);
if (lsn == NULLCOMMITLSN)
return 0;
}
@@ -3725,7 +3724,7 @@ xfs_log_force_umount(
* call below.
*/
if (!logerror && (mp->m_flags & XFS_MOUNT_DELAYLOG))
- xlog_cil_force(log);
+ xlog_cil_push(log, 1);
/*
* We must hold both the GRANT lock and the LOG lock,
diff --git a/trunk/fs/xfs/xfs_log_cil.c b/trunk/fs/xfs/xfs_log_cil.c
index ed575fb4b495..31e4ea2d19ac 100644
--- a/trunk/fs/xfs/xfs_log_cil.c
+++ b/trunk/fs/xfs/xfs_log_cil.c
@@ -68,7 +68,6 @@ xlog_cil_init(
ctx->sequence = 1;
ctx->cil = cil;
cil->xc_ctx = ctx;
- cil->xc_current_sequence = ctx->sequence;
cil->xc_log = log;
log->l_cilp = cil;
@@ -270,10 +269,15 @@ xlog_cil_insert(
static void
xlog_cil_format_items(
struct log *log,
- struct xfs_log_vec *log_vector)
+ struct xfs_log_vec *log_vector,
+ struct xlog_ticket *ticket,
+ xfs_lsn_t *start_lsn)
{
struct xfs_log_vec *lv;
+ if (start_lsn)
+ *start_lsn = log->l_cilp->xc_ctx->sequence;
+
ASSERT(log_vector);
for (lv = log_vector; lv; lv = lv->lv_next) {
void *ptr;
@@ -297,24 +301,9 @@ xlog_cil_format_items(
ptr += vec->i_len;
}
ASSERT(ptr == lv->lv_buf + lv->lv_buf_len);
- }
-}
-
-static void
-xlog_cil_insert_items(
- struct log *log,
- struct xfs_log_vec *log_vector,
- struct xlog_ticket *ticket,
- xfs_lsn_t *start_lsn)
-{
- struct xfs_log_vec *lv;
-
- if (start_lsn)
- *start_lsn = log->l_cilp->xc_ctx->sequence;
- ASSERT(log_vector);
- for (lv = log_vector; lv; lv = lv->lv_next)
xlog_cil_insert(log, ticket, lv->lv_item, lv);
+ }
}
static void
@@ -331,6 +320,80 @@ xlog_cil_free_logvec(
}
}
+/*
+ * Commit a transaction with the given vector to the Committed Item List.
+ *
+ * To do this, we need to format the item, pin it in memory if required and
+ * account for the space used by the transaction. Once we have done that we
+ * need to release the unused reservation for the transaction, attach the
+ * transaction to the checkpoint context so we carry the busy extents through
+ * to checkpoint completion, and then unlock all the items in the transaction.
+ *
+ * For more specific information about the order of operations in
+ * xfs_log_commit_cil() please refer to the comments in
+ * xfs_trans_commit_iclog().
+ *
+ * Called with the context lock already held in read mode to lock out
+ * background commit, returns without it held once background commits are
+ * allowed again.
+ */
+int
+xfs_log_commit_cil(
+ struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ struct xfs_log_vec *log_vector,
+ xfs_lsn_t *commit_lsn,
+ int flags)
+{
+ struct log *log = mp->m_log;
+ int log_flags = 0;
+ int push = 0;
+
+ if (flags & XFS_TRANS_RELEASE_LOG_RES)
+ log_flags = XFS_LOG_REL_PERM_RESERV;
+
+ if (XLOG_FORCED_SHUTDOWN(log)) {
+ xlog_cil_free_logvec(log_vector);
+ return XFS_ERROR(EIO);
+ }
+
+ /* lock out background commit */
+ down_read(&log->l_cilp->xc_ctx_lock);
+ xlog_cil_format_items(log, log_vector, tp->t_ticket, commit_lsn);
+
+ /* check we didn't blow the reservation */
+ if (tp->t_ticket->t_curr_res < 0)
+ xlog_print_tic_res(log->l_mp, tp->t_ticket);
+
+ /* attach the transaction to the CIL if it has any busy extents */
+ if (!list_empty(&tp->t_busy)) {
+ spin_lock(&log->l_cilp->xc_cil_lock);
+ list_splice_init(&tp->t_busy,
+ &log->l_cilp->xc_ctx->busy_extents);
+ spin_unlock(&log->l_cilp->xc_cil_lock);
+ }
+
+ tp->t_commit_lsn = *commit_lsn;
+ xfs_log_done(mp, tp->t_ticket, NULL, log_flags);
+ xfs_trans_unreserve_and_mod_sb(tp);
+
+ /* check for background commit before unlock */
+ if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log))
+ push = 1;
+ up_read(&log->l_cilp->xc_ctx_lock);
+
+ /*
+ * We need to push CIL every so often so we don't cache more than we
+ * can fit in the log. The limit really is that a checkpoint can't be
+ * more than half the log (the current checkpoint is not allowed to
+ * overwrite the previous checkpoint), but commit latency and memory
+ * usage limit this to a smaller size in most cases.
+ */
+ if (push)
+ xlog_cil_push(log, 0);
+ return 0;
+}
+
/*
* Mark all items committed and clear busy extents. We free the log vector
* chains in a separate pass so that we unpin the log items as quickly as
@@ -364,23 +427,13 @@ xlog_cil_committed(
}
/*
- * Push the Committed Item List to the log. If @push_seq flag is zero, then it
- * is a background flush and so we can chose to ignore it. Otherwise, if the
- * current sequence is the same as @push_seq we need to do a flush. If
- * @push_seq is less than the current sequence, then it has already been
- * flushed and we don't need to do anything - the caller will wait for it to
- * complete if necessary.
- *
- * @push_seq is a value rather than a flag because that allows us to do an
- * unlocked check of the sequence number for a match. Hence we can allows log
- * forces to run racily and not issue pushes for the same sequence twice. If we
- * get a race between multiple pushes for the same sequence they will block on
- * the first one and then abort, hence avoiding needless pushes.
+ * Push the Committed Item List to the log. If the push_now flag is not set,
+ * then it is a background flush and so we can chose to ignore it.
*/
-STATIC int
+int
xlog_cil_push(
struct log *log,
- xfs_lsn_t push_seq)
+ int push_now)
{
struct xfs_cil *cil = log->l_cilp;
struct xfs_log_vec *lv;
@@ -400,14 +453,12 @@ xlog_cil_push(
if (!cil)
return 0;
- ASSERT(!push_seq || push_seq <= cil->xc_ctx->sequence);
-
new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS);
new_ctx->ticket = xlog_cil_ticket_alloc(log);
/* lock out transaction commit, but don't block on background push */
if (!down_write_trylock(&cil->xc_ctx_lock)) {
- if (!push_seq)
+ if (!push_now)
goto out_free_ticket;
down_write(&cil->xc_ctx_lock);
}
@@ -418,11 +469,7 @@ xlog_cil_push(
goto out_skip;
/* check for spurious background flush */
- if (!push_seq && cil->xc_ctx->space_used < XLOG_CIL_SPACE_LIMIT(log))
- goto out_skip;
-
- /* check for a previously pushed seqeunce */
- if (push_seq < cil->xc_ctx->sequence)
+ if (!push_now && cil->xc_ctx->space_used < XLOG_CIL_SPACE_LIMIT(log))
goto out_skip;
/*
@@ -467,13 +514,6 @@ xlog_cil_push(
new_ctx->cil = cil;
cil->xc_ctx = new_ctx;
- /*
- * mirror the new sequence into the cil structure so that we can do
- * unlocked checks against the current sequence in log forces without
- * risking deferencing a freed context pointer.
- */
- cil->xc_current_sequence = new_ctx->sequence;
-
/*
* The switch is now done, so we can drop the context lock and move out
* of a shared context. We can't just go straight to the commit record,
@@ -585,102 +625,6 @@ xlog_cil_push(
return XFS_ERROR(EIO);
}
-/*
- * Commit a transaction with the given vector to the Committed Item List.
- *
- * To do this, we need to format the item, pin it in memory if required and
- * account for the space used by the transaction. Once we have done that we
- * need to release the unused reservation for the transaction, attach the
- * transaction to the checkpoint context so we carry the busy extents through
- * to checkpoint completion, and then unlock all the items in the transaction.
- *
- * For more specific information about the order of operations in
- * xfs_log_commit_cil() please refer to the comments in
- * xfs_trans_commit_iclog().
- *
- * Called with the context lock already held in read mode to lock out
- * background commit, returns without it held once background commits are
- * allowed again.
- */
-int
-xfs_log_commit_cil(
- struct xfs_mount *mp,
- struct xfs_trans *tp,
- struct xfs_log_vec *log_vector,
- xfs_lsn_t *commit_lsn,
- int flags)
-{
- struct log *log = mp->m_log;
- int log_flags = 0;
- int push = 0;
-
- if (flags & XFS_TRANS_RELEASE_LOG_RES)
- log_flags = XFS_LOG_REL_PERM_RESERV;
-
- if (XLOG_FORCED_SHUTDOWN(log)) {
- xlog_cil_free_logvec(log_vector);
- return XFS_ERROR(EIO);
- }
-
- /*
- * do all the hard work of formatting items (including memory
- * allocation) outside the CIL context lock. This prevents stalling CIL
- * pushes when we are low on memory and a transaction commit spends a
- * lot of time in memory reclaim.
- */
- xlog_cil_format_items(log, log_vector);
-
- /* lock out background commit */
- down_read(&log->l_cilp->xc_ctx_lock);
- xlog_cil_insert_items(log, log_vector, tp->t_ticket, commit_lsn);
-
- /* check we didn't blow the reservation */
- if (tp->t_ticket->t_curr_res < 0)
- xlog_print_tic_res(log->l_mp, tp->t_ticket);
-
- /* attach the transaction to the CIL if it has any busy extents */
- if (!list_empty(&tp->t_busy)) {
- spin_lock(&log->l_cilp->xc_cil_lock);
- list_splice_init(&tp->t_busy,
- &log->l_cilp->xc_ctx->busy_extents);
- spin_unlock(&log->l_cilp->xc_cil_lock);
- }
-
- tp->t_commit_lsn = *commit_lsn;
- xfs_log_done(mp, tp->t_ticket, NULL, log_flags);
- xfs_trans_unreserve_and_mod_sb(tp);
-
- /*
- * Once all the items of the transaction have been copied to the CIL,
- * the items can be unlocked and freed.
- *
- * This needs to be done before we drop the CIL context lock because we
- * have to update state in the log items and unlock them before they go
- * to disk. If we don't, then the CIL checkpoint can race with us and
- * we can run checkpoint completion before we've updated and unlocked
- * the log items. This affects (at least) processing of stale buffers,
- * inodes and EFIs.
- */
- xfs_trans_free_items(tp, *commit_lsn, 0);
-
- /* check for background commit before unlock */
- if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log))
- push = 1;
-
- up_read(&log->l_cilp->xc_ctx_lock);
-
- /*
- * We need to push CIL every so often so we don't cache more than we
- * can fit in the log. The limit really is that a checkpoint can't be
- * more than half the log (the current checkpoint is not allowed to
- * overwrite the previous checkpoint), but commit latency and memory
- * usage limit this to a smaller size in most cases.
- */
- if (push)
- xlog_cil_push(log, 0);
- return 0;
-}
-
/*
* Conditionally push the CIL based on the sequence passed in.
*
@@ -695,34 +639,39 @@ xfs_log_commit_cil(
* commit lsn is there. It'll be empty, so this is broken for now.
*/
xfs_lsn_t
-xlog_cil_force_lsn(
+xlog_cil_push_lsn(
struct log *log,
- xfs_lsn_t sequence)
+ xfs_lsn_t push_seq)
{
struct xfs_cil *cil = log->l_cilp;
struct xfs_cil_ctx *ctx;
xfs_lsn_t commit_lsn = NULLCOMMITLSN;
- ASSERT(sequence <= cil->xc_current_sequence);
-
- /*
- * check to see if we need to force out the current context.
- * xlog_cil_push() handles racing pushes for the same sequence,
- * so no need to deal with it here.
- */
- if (sequence == cil->xc_current_sequence)
- xlog_cil_push(log, sequence);
+restart:
+ down_write(&cil->xc_ctx_lock);
+ ASSERT(push_seq <= cil->xc_ctx->sequence);
+
+ /* check to see if we need to force out the current context */
+ if (push_seq == cil->xc_ctx->sequence) {
+ up_write(&cil->xc_ctx_lock);
+ xlog_cil_push(log, 1);
+ goto restart;
+ }
/*
* See if we can find a previous sequence still committing.
+ * We can drop the flush lock as soon as we have the cil lock
+ * because we are now only comparing contexts protected by
+ * the cil lock.
+ *
* We need to wait for all previous sequence commits to complete
* before allowing the force of push_seq to go ahead. Hence block
* on commits for those as well.
*/
-restart:
spin_lock(&cil->xc_cil_lock);
+ up_write(&cil->xc_ctx_lock);
list_for_each_entry(ctx, &cil->xc_committing, committing) {
- if (ctx->sequence > sequence)
+ if (ctx->sequence > push_seq)
continue;
if (!ctx->commit_lsn) {
/*
@@ -732,7 +681,7 @@ xlog_cil_force_lsn(
sv_wait(&cil->xc_commit_wait, 0, &cil->xc_cil_lock, 0);
goto restart;
}
- if (ctx->sequence != sequence)
+ if (ctx->sequence != push_seq)
continue;
/* found it! */
commit_lsn = ctx->commit_lsn;
diff --git a/trunk/fs/xfs/xfs_log_priv.h b/trunk/fs/xfs/xfs_log_priv.h
index ced52b98b322..8c072618965c 100644
--- a/trunk/fs/xfs/xfs_log_priv.h
+++ b/trunk/fs/xfs/xfs_log_priv.h
@@ -422,7 +422,6 @@ struct xfs_cil {
struct rw_semaphore xc_ctx_lock;
struct list_head xc_committing;
sv_t xc_commit_wait;
- xfs_lsn_t xc_current_sequence;
};
/*
@@ -563,16 +562,8 @@ int xlog_cil_init(struct log *log);
void xlog_cil_init_post_recovery(struct log *log);
void xlog_cil_destroy(struct log *log);
-/*
- * CIL force routines
- */
-xfs_lsn_t xlog_cil_force_lsn(struct log *log, xfs_lsn_t sequence);
-
-static inline void
-xlog_cil_force(struct log *log)
-{
- xlog_cil_force_lsn(log, log->l_cilp->xc_current_sequence);
-}
+int xlog_cil_push(struct log *log, int push_now);
+xfs_lsn_t xlog_cil_push_lsn(struct log *log, xfs_lsn_t push_sequence);
/*
* Unmount record type is used as a pseudo transaction type for the ticket.
diff --git a/trunk/fs/xfs/xfs_trans.c b/trunk/fs/xfs/xfs_trans.c
index 1c47edaea0d2..fdca7416c754 100644
--- a/trunk/fs/xfs/xfs_trans.c
+++ b/trunk/fs/xfs/xfs_trans.c
@@ -1167,7 +1167,7 @@ xfs_trans_del_item(
* Unlock all of the items of a transaction and free all the descriptors
* of that transaction.
*/
-void
+STATIC void
xfs_trans_free_items(
struct xfs_trans *tp,
xfs_lsn_t commit_lsn,
@@ -1653,6 +1653,9 @@ xfs_trans_commit_cil(
return error;
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
+
+ /* xfs_trans_free_items() unlocks them first */
+ xfs_trans_free_items(tp, *commit_lsn, 0);
xfs_trans_free(tp);
return 0;
}
diff --git a/trunk/fs/xfs/xfs_trans_priv.h b/trunk/fs/xfs/xfs_trans_priv.h
index 62da86c90de5..e2d93d8ead7b 100644
--- a/trunk/fs/xfs/xfs_trans_priv.h
+++ b/trunk/fs/xfs/xfs_trans_priv.h
@@ -25,8 +25,7 @@ struct xfs_trans;
void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *);
void xfs_trans_del_item(struct xfs_log_item *);
-void xfs_trans_free_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn,
- int flags);
+
void xfs_trans_item_committed(struct xfs_log_item *lip,
xfs_lsn_t commit_lsn, int aborted);
void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp);
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/drm/drmP.h b/trunk/include/drm/drmP.h
index 7809d230adee..2a512bc0d4ab 100644
--- a/trunk/include/drm/drmP.h
+++ b/trunk/include/drm/drmP.h
@@ -305,16 +305,14 @@ struct drm_ioctl_desc {
unsigned int cmd;
int flags;
drm_ioctl_t *func;
- unsigned int cmd_drv;
};
/**
* Creates a driver or general drm_ioctl_desc array entry for the given
* ioctl, for use by drm_ioctl().
*/
-
-#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
- [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl}
+#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
+ [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags}
struct drm_magic_entry {
struct list_head head;
diff --git a/trunk/include/drm/i830_drm.h b/trunk/include/drm/i830_drm.h
index 61315c29b8f3..4b00d2dd4f68 100644
--- a/trunk/include/drm/i830_drm.h
+++ b/trunk/include/drm/i830_drm.h
@@ -264,20 +264,20 @@ typedef struct _drm_i830_sarea {
#define DRM_I830_GETPARAM 0x0c
#define DRM_I830_SETPARAM 0x0d
-#define DRM_IOCTL_I830_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I830_INIT, drm_i830_init_t)
-#define DRM_IOCTL_I830_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_I830_VERTEX, drm_i830_vertex_t)
-#define DRM_IOCTL_I830_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_I830_CLEAR, drm_i830_clear_t)
-#define DRM_IOCTL_I830_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I830_FLUSH)
-#define DRM_IOCTL_I830_GETAGE DRM_IO ( DRM_COMMAND_BASE + DRM_I830_GETAGE)
-#define DRM_IOCTL_I830_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_GETBUF, drm_i830_dma_t)
-#define DRM_IOCTL_I830_SWAP DRM_IO ( DRM_COMMAND_BASE + DRM_I830_SWAP)
-#define DRM_IOCTL_I830_COPY DRM_IOW( DRM_COMMAND_BASE + DRM_I830_COPY, drm_i830_copy_t)
-#define DRM_IOCTL_I830_DOCOPY DRM_IO ( DRM_COMMAND_BASE + DRM_I830_DOCOPY)
-#define DRM_IOCTL_I830_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I830_FLIP)
-#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_IRQ_EMIT, drm_i830_irq_emit_t)
-#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I830_IRQ_WAIT, drm_i830_irq_wait_t)
-#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_GETPARAM, drm_i830_getparam_t)
-#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_SETPARAM, drm_i830_setparam_t)
+#define DRM_IOCTL_I830_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_INIT, drm_i830_init_t)
+#define DRM_IOCTL_I830_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_VERTEX, drm_i830_vertex_t)
+#define DRM_IOCTL_I830_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_CLEAR, drm_i830_clear_t)
+#define DRM_IOCTL_I830_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLUSH)
+#define DRM_IOCTL_I830_GETAGE DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_GETAGE)
+#define DRM_IOCTL_I830_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETBUF, drm_i830_dma_t)
+#define DRM_IOCTL_I830_SWAP DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_SWAP)
+#define DRM_IOCTL_I830_COPY DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_COPY, drm_i830_copy_t)
+#define DRM_IOCTL_I830_DOCOPY DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_DOCOPY)
+#define DRM_IOCTL_I830_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLIP)
+#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_EMIT, drm_i830_irq_emit_t)
+#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_WAIT, drm_i830_irq_wait_t)
+#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETPARAM, drm_i830_getparam_t)
+#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_SETPARAM, drm_i830_setparam_t)
typedef struct _drm_i830_clear {
int clear_color;
diff --git a/trunk/include/drm/i915_drm.h b/trunk/include/drm/i915_drm.h
index e41c74facb6a..8f8b072c4c7b 100644
--- a/trunk/include/drm/i915_drm.h
+++ b/trunk/include/drm/i915_drm.h
@@ -215,7 +215,6 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
-#define DRM_IOCTL_I915_HWS_ADDR DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init)
#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init)
#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer)
#define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
diff --git a/trunk/include/drm/mga_drm.h b/trunk/include/drm/mga_drm.h
index c16097f99be0..3ffbc4798afa 100644
--- a/trunk/include/drm/mga_drm.h
+++ b/trunk/include/drm/mga_drm.h
@@ -248,7 +248,7 @@ typedef struct _drm_mga_sarea {
#define DRM_MGA_DMA_BOOTSTRAP 0x0c
#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
-#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, struct drm_lock)
+#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t)
#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET)
#define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t)
diff --git a/trunk/include/drm/nouveau_drm.h b/trunk/include/drm/nouveau_drm.h
index 01a714119506..fe917dee723a 100644
--- a/trunk/include/drm/nouveau_drm.h
+++ b/trunk/include/drm/nouveau_drm.h
@@ -197,17 +197,4 @@ struct drm_nouveau_sarea {
#define DRM_NOUVEAU_GEM_CPU_FINI 0x43
#define DRM_NOUVEAU_GEM_INFO 0x44
-#define DRM_IOCTL_NOUVEAU_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GETPARAM, struct drm_nouveau_getparam)
-#define DRM_IOCTL_NOUVEAU_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_SETPARAM, struct drm_nouveau_setparam)
-#define DRM_IOCTL_NOUVEAU_CHANNEL_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_CHANNEL_ALLOC, struct drm_nouveau_channel_alloc)
-#define DRM_IOCTL_NOUVEAU_CHANNEL_FREE DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_CHANNEL_FREE, struct drm_nouveau_channel_free)
-#define DRM_IOCTL_NOUVEAU_GROBJ_ALLOC DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GROBJ_ALLOC, struct drm_nouveau_grobj_alloc)
-#define DRM_IOCTL_NOUVEAU_NOTIFIEROBJ_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, struct drm_nouveau_notifierobj_alloc)
-#define DRM_IOCTL_NOUVEAU_GPUOBJ_FREE DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GPUOBJ_FREE, struct drm_nouveau_gpuobj_free)
-#define DRM_IOCTL_NOUVEAU_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new)
-#define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf)
-#define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep)
-#define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini)
-#define DRM_IOCTL_NOUVEAU_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info)
-
#endif /* __NOUVEAU_DRM_H__ */
diff --git a/trunk/include/drm/radeon_drm.h b/trunk/include/drm/radeon_drm.h
index 10f8b53bdd40..0acaf8f91437 100644
--- a/trunk/include/drm/radeon_drm.h
+++ b/trunk/include/drm/radeon_drm.h
@@ -547,8 +547,8 @@ typedef struct {
#define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle)
#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
#define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info)
-#define DRM_IOCTL_RADEON_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling)
-#define DRM_IOCTL_RADEON_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling)
+#define DRM_IOCTL_RADEON_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling)
+#define DRM_IOCTL_RADEON_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling)
#define DRM_IOCTL_RADEON_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_BUSY, struct drm_radeon_gem_busy)
typedef struct drm_radeon_init {
diff --git a/trunk/include/drm/savage_drm.h b/trunk/include/drm/savage_drm.h
index 4863cf6bf96f..8a576ef01821 100644
--- a/trunk/include/drm/savage_drm.h
+++ b/trunk/include/drm/savage_drm.h
@@ -63,10 +63,10 @@ typedef struct _drm_savage_sarea {
#define DRM_SAVAGE_BCI_EVENT_EMIT 0x02
#define DRM_SAVAGE_BCI_EVENT_WAIT 0x03
-#define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
-#define DRM_IOCTL_SAVAGE_BCI_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
-#define DRM_IOCTL_SAVAGE_BCI_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
-#define DRM_IOCTL_SAVAGE_BCI_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
+#define DRM_IOCTL_SAVAGE_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
+#define DRM_IOCTL_SAVAGE_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
+#define DRM_IOCTL_SAVAGE_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
+#define DRM_IOCTL_SAVAGE_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
#define SAVAGE_DMA_PCI 1
#define SAVAGE_DMA_AGP 3
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/if_ether.h b/trunk/include/linux/if_ether.h
index bed7a4682b90..c831467774d0 100644
--- a/trunk/include/linux/if_ether.h
+++ b/trunk/include/linux/if_ether.h
@@ -119,7 +119,7 @@ struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
__be16 h_proto; /* packet type ID field */
-} __attribute__((packed));
+} __packed;
#ifdef __KERNEL__
#include
diff --git a/trunk/include/linux/if_fddi.h b/trunk/include/linux/if_fddi.h
index e6dc11e7f9a5..9947c39e62f6 100644
--- a/trunk/include/linux/if_fddi.h
+++ b/trunk/include/linux/if_fddi.h
@@ -67,7 +67,7 @@ struct fddi_8022_1_hdr {
__u8 dsap; /* destination service access point */
__u8 ssap; /* source service access point */
__u8 ctrl; /* control byte #1 */
-} __attribute__((packed));
+} __packed;
/* Define 802.2 Type 2 header */
struct fddi_8022_2_hdr {
@@ -75,7 +75,7 @@ struct fddi_8022_2_hdr {
__u8 ssap; /* source service access point */
__u8 ctrl_1; /* control byte #1 */
__u8 ctrl_2; /* control byte #2 */
-} __attribute__((packed));
+} __packed;
/* Define 802.2 SNAP header */
#define FDDI_K_OUI_LEN 3
@@ -85,7 +85,7 @@ struct fddi_snap_hdr {
__u8 ctrl; /* always 0x03 */
__u8 oui[FDDI_K_OUI_LEN]; /* organizational universal id */
__be16 ethertype; /* packet type ID field */
-} __attribute__((packed));
+} __packed;
/* Define FDDI LLC frame header */
struct fddihdr {
@@ -98,7 +98,7 @@ struct fddihdr {
struct fddi_8022_2_hdr llc_8022_2;
struct fddi_snap_hdr llc_snap;
} hdr;
-} __attribute__((packed));
+} __packed;
#ifdef __KERNEL__
#include
diff --git a/trunk/include/linux/if_hippi.h b/trunk/include/linux/if_hippi.h
index cdc049f1829a..5fe5f307c6f5 100644
--- a/trunk/include/linux/if_hippi.h
+++ b/trunk/include/linux/if_hippi.h
@@ -104,7 +104,7 @@ struct hippi_fp_hdr {
__be32 fixed;
#endif
__be32 d2_size;
-} __attribute__((packed));
+} __packed;
struct hippi_le_hdr {
#if defined (__BIG_ENDIAN_BITFIELD)
@@ -129,7 +129,7 @@ struct hippi_le_hdr {
__u8 daddr[HIPPI_ALEN];
__u16 locally_administered;
__u8 saddr[HIPPI_ALEN];
-} __attribute__((packed));
+} __packed;
#define HIPPI_OUI_LEN 3
/*
@@ -142,12 +142,12 @@ struct hippi_snap_hdr {
__u8 ctrl; /* always 0x03 */
__u8 oui[HIPPI_OUI_LEN]; /* organizational universal id (zero)*/
__be16 ethertype; /* packet type ID field */
-} __attribute__((packed));
+} __packed;
struct hippi_hdr {
struct hippi_fp_hdr fp;
struct hippi_le_hdr le;
struct hippi_snap_hdr snap;
-} __attribute__((packed));
+} __packed;
#endif /* _LINUX_IF_HIPPI_H */
diff --git a/trunk/include/linux/if_pppox.h b/trunk/include/linux/if_pppox.h
index 27741e05446f..1925e0c3f162 100644
--- a/trunk/include/linux/if_pppox.h
+++ b/trunk/include/linux/if_pppox.h
@@ -59,7 +59,7 @@ struct sockaddr_pppox {
union{
struct pppoe_addr pppoe;
}sa_addr;
-} __attribute__((packed));
+} __packed;
/* The use of the above union isn't viable because the size of this
* struct must stay fixed over time -- applications use sizeof(struct
@@ -70,7 +70,7 @@ struct sockaddr_pppol2tp {
sa_family_t sa_family; /* address family, AF_PPPOX */
unsigned int sa_protocol; /* protocol identifier */
struct pppol2tp_addr pppol2tp;
-} __attribute__((packed));
+} __packed;
/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
* bits. So we need a different sockaddr structure.
@@ -79,7 +79,7 @@ struct sockaddr_pppol2tpv3 {
sa_family_t sa_family; /* address family, AF_PPPOX */
unsigned int sa_protocol; /* protocol identifier */
struct pppol2tpv3_addr pppol2tp;
-} __attribute__((packed));
+} __packed;
/*********************************************************************
*
@@ -101,7 +101,7 @@ struct pppoe_tag {
__be16 tag_type;
__be16 tag_len;
char tag_data[0];
-} __attribute__ ((packed));
+} __attribute ((packed));
/* Tag identifiers */
#define PTT_EOL __cpu_to_be16(0x0000)
@@ -129,7 +129,7 @@ struct pppoe_hdr {
__be16 sid;
__be16 length;
struct pppoe_tag tag[0];
-} __attribute__((packed));
+} __packed;
/* Length of entire PPPoE + PPP header */
#define PPPOE_SES_HLEN 8
diff --git a/trunk/include/linux/ipv6.h b/trunk/include/linux/ipv6.h
index e62683ba88e6..ab9e9e89e407 100644
--- a/trunk/include/linux/ipv6.h
+++ b/trunk/include/linux/ipv6.h
@@ -58,7 +58,7 @@ struct ipv6_opt_hdr {
/*
* TLV encoded option data follows.
*/
-} __attribute__((packed)); /* required for some archs */
+} __packed; /* required for some archs */
#define ipv6_destopt_hdr ipv6_opt_hdr
#define ipv6_hopopt_hdr ipv6_opt_hdr
@@ -99,7 +99,7 @@ struct ipv6_destopt_hao {
__u8 type;
__u8 length;
struct in6_addr addr;
-} __attribute__((packed));
+} __packed;
/*
* IPv6 fixed header
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/kobject.h b/trunk/include/linux/kobject.h
index 7950a37a7146..cf343a852534 100644
--- a/trunk/include/linux/kobject.h
+++ b/trunk/include/linux/kobject.h
@@ -22,7 +22,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -137,8 +136,42 @@ struct kobj_attribute {
extern const struct sysfs_ops kobj_sysfs_ops;
+/*
+ * Namespace types which are used to tag kobjects and sysfs entries.
+ * Network namespace will likely be the first.
+ */
+enum kobj_ns_type {
+ KOBJ_NS_TYPE_NONE = 0,
+ KOBJ_NS_TYPE_NET,
+ KOBJ_NS_TYPES
+};
+
struct sock;
+/*
+ * Callbacks so sysfs can determine namespaces
+ * @current_ns: return calling task's namespace
+ * @netlink_ns: return namespace to which a sock belongs (right?)
+ * @initial_ns: return the initial namespace (i.e. init_net_ns)
+ */
+struct kobj_ns_type_operations {
+ enum kobj_ns_type type;
+ const void *(*current_ns)(void);
+ const void *(*netlink_ns)(struct sock *sk);
+ const void *(*initial_ns)(void);
+};
+
+int kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
+int kobj_ns_type_registered(enum kobj_ns_type type);
+const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
+const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
+
+const void *kobj_ns_current(enum kobj_ns_type type);
+const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
+const void *kobj_ns_initial(enum kobj_ns_type type);
+void kobj_ns_exit(enum kobj_ns_type type, const void *ns);
+
+
/**
* struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
*
diff --git a/trunk/include/linux/kobject_ns.h b/trunk/include/linux/kobject_ns.h
deleted file mode 100644
index 82cb5bf461fb..000000000000
--- a/trunk/include/linux/kobject_ns.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Kernel object name space definitions
- *
- * Copyright (c) 2002-2003 Patrick Mochel
- * Copyright (c) 2002-2003 Open Source Development Labs
- * Copyright (c) 2006-2008 Greg Kroah-Hartman
- * Copyright (c) 2006-2008 Novell Inc.
- *
- * Split from kobject.h by David Howells (dhowells@redhat.com)
- *
- * This file is released under the GPLv2.
- *
- * Please read Documentation/kobject.txt before using the kobject
- * interface, ESPECIALLY the parts about reference counts and object
- * destructors.
- */
-
-#ifndef _LINUX_KOBJECT_NS_H
-#define _LINUX_KOBJECT_NS_H
-
-struct sock;
-struct kobject;
-
-/*
- * Namespace types which are used to tag kobjects and sysfs entries.
- * Network namespace will likely be the first.
- */
-enum kobj_ns_type {
- KOBJ_NS_TYPE_NONE = 0,
- KOBJ_NS_TYPE_NET,
- KOBJ_NS_TYPES
-};
-
-/*
- * Callbacks so sysfs can determine namespaces
- * @current_ns: return calling task's namespace
- * @netlink_ns: return namespace to which a sock belongs (right?)
- * @initial_ns: return the initial namespace (i.e. init_net_ns)
- */
-struct kobj_ns_type_operations {
- enum kobj_ns_type type;
- const void *(*current_ns)(void);
- const void *(*netlink_ns)(struct sock *sk);
- const void *(*initial_ns)(void);
-};
-
-int kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
-int kobj_ns_type_registered(enum kobj_ns_type type);
-const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
-const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
-
-const void *kobj_ns_current(enum kobj_ns_type type);
-const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
-const void *kobj_ns_initial(enum kobj_ns_type type);
-void kobj_ns_exit(enum kobj_ns_type type, const void *ns);
-
-#endif /* _LINUX_KOBJECT_NS_H */
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.h b/trunk/include/linux/mm.h
index 831c693416b2..709f6728fc90 100644
--- a/trunk/include/linux/mm.h
+++ b/trunk/include/linux/mm.h
@@ -78,11 +78,7 @@ extern unsigned int kobjsize(const void *objp);
#define VM_MAYSHARE 0x00000080
#define VM_GROWSDOWN 0x00000100 /* general info on the segment */
-#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
#define VM_GROWSUP 0x00000200
-#else
-#define VM_GROWSUP 0x00000000
-#endif
#define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */
#define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */
@@ -1334,10 +1330,8 @@ unsigned long ra_submit(struct file_ra_state *ra,
/* Do stack extension */
extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
-#if VM_GROWSUP
+#ifdef CONFIG_IA64
extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
-#else
- #define expand_upwards(vma, address) do { } while (0)
#endif
extern int expand_stack_downwards(struct vm_area_struct *vma,
unsigned long address);
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/nbd.h b/trunk/include/linux/nbd.h
index d146ca10c0f5..bb58854a8061 100644
--- a/trunk/include/linux/nbd.h
+++ b/trunk/include/linux/nbd.h
@@ -88,7 +88,7 @@ struct nbd_request {
char handle[8];
__be64 from;
__be32 len;
-} __attribute__((packed));
+} __packed;
/*
* This is the reply packet that nbd-server sends back to the client after
diff --git a/trunk/include/linux/ncp.h b/trunk/include/linux/ncp.h
index 99f0adeeb3f3..3ace8370e61e 100644
--- a/trunk/include/linux/ncp.h
+++ b/trunk/include/linux/ncp.h
@@ -27,7 +27,7 @@ struct ncp_request_header {
__u8 conn_high;
__u8 function;
__u8 data[0];
-} __attribute__((packed));
+} __packed;
#define NCP_REPLY (0x3333)
#define NCP_WATCHDOG (0x3E3E)
@@ -42,7 +42,7 @@ struct ncp_reply_header {
__u8 completion_code;
__u8 connection_state;
__u8 data[0];
-} __attribute__((packed));
+} __packed;
#define NCP_VOLNAME_LEN (16)
#define NCP_NUMBER_OF_VOLUMES (256)
@@ -158,7 +158,7 @@ struct nw_info_struct {
#ifdef __KERNEL__
struct nw_nfs_info nfs;
#endif
-} __attribute__((packed));
+} __packed;
/* modify mask - use with MODIFY_DOS_INFO structure */
#define DM_ATTRIBUTES (cpu_to_le32(0x02))
@@ -190,12 +190,12 @@ struct nw_modify_dos_info {
__u16 inheritanceGrantMask;
__u16 inheritanceRevokeMask;
__u32 maximumSpace;
-} __attribute__((packed));
+} __packed;
struct nw_search_sequence {
__u8 volNumber;
__u32 dirBase;
__u32 sequence;
-} __attribute__((packed));
+} __packed;
#endif /* _LINUX_NCP_H */
diff --git a/trunk/include/linux/netfilter/xt_IDLETIMER.h b/trunk/include/linux/netfilter/xt_IDLETIMER.h
index 208ae9387331..3e1aa1be942e 100644
--- a/trunk/include/linux/netfilter/xt_IDLETIMER.h
+++ b/trunk/include/linux/netfilter/xt_IDLETIMER.h
@@ -39,7 +39,7 @@ struct idletimer_tg_info {
char label[MAX_IDLETIMER_LABEL_SIZE];
/* for kernel module internal use only */
- struct idletimer_tg *timer __attribute__((aligned(8)));
+ struct idletimer_tg *timer __attribute((aligned(8)));
};
#endif
diff --git a/trunk/include/linux/netfilter/xt_ipvs.h b/trunk/include/linux/netfilter/xt_ipvs.h
index eff34ac18808..1167aeb7a347 100644
--- a/trunk/include/linux/netfilter/xt_ipvs.h
+++ b/trunk/include/linux/netfilter/xt_ipvs.h
@@ -1,8 +1,6 @@
#ifndef _XT_IPVS_H
#define _XT_IPVS_H
-#include
-
enum {
XT_IPVS_IPVS_PROPERTY = 1 << 0, /* all other options imply this one */
XT_IPVS_PROTO = 1 << 1,
diff --git a/trunk/include/linux/phonet.h b/trunk/include/linux/phonet.h
index 76edadf046d3..24426c3d6b5a 100644
--- a/trunk/include/linux/phonet.h
+++ b/trunk/include/linux/phonet.h
@@ -56,7 +56,7 @@ struct phonethdr {
__be16 pn_length;
__u8 pn_robj;
__u8 pn_sobj;
-} __attribute__((packed));
+} __packed;
/* Common Phonet payload header */
struct phonetmsg {
@@ -98,7 +98,7 @@ struct sockaddr_pn {
__u8 spn_dev;
__u8 spn_resource;
__u8 spn_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - 3];
-} __attribute__((packed));
+} __packed;
/* Well known address */
#define PN_DEV_PC 0x10
diff --git a/trunk/include/linux/pxa168_eth.h b/trunk/include/linux/pxa168_eth.h
deleted file mode 100644
index 18d75e795606..000000000000
--- a/trunk/include/linux/pxa168_eth.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *pxa168 ethernet platform device data definition file.
- */
-#ifndef __LINUX_PXA168_ETH_H
-#define __LINUX_PXA168_ETH_H
-
-struct pxa168_eth_platform_data {
- int port_number;
- int phy_addr;
-
- /*
- * If speed is 0, then speed and duplex are autonegotiated.
- */
- int speed; /* 0, SPEED_10, SPEED_100 */
- int duplex; /* DUPLEX_HALF or DUPLEX_FULL */
-
- /*
- * Override default RX/TX queue sizes if nonzero.
- */
- int rx_queue_size;
- int tx_queue_size;
-
- /*
- * init callback is used for board specific initialization
- * e.g on Aspenite its used to initialize the PHY transceiver.
- */
- int (*init)(void);
-};
-
-#endif /* __LINUX_PXA168_ETH_H */
diff --git a/trunk/include/linux/rfkill.h b/trunk/include/linux/rfkill.h
index 08c32e4f261a..4f82326eb294 100644
--- a/trunk/include/linux/rfkill.h
+++ b/trunk/include/linux/rfkill.h
@@ -81,7 +81,7 @@ struct rfkill_event {
__u8 type;
__u8 op;
__u8 soft, hard;
-} __attribute__((packed));
+} __packed;
/*
* We are planning to be backward and forward compatible with changes
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/sysfs.h b/trunk/include/linux/sysfs.h
index 96eb576d82fd..3c92121ba9af 100644
--- a/trunk/include/linux/sysfs.h
+++ b/trunk/include/linux/sysfs.h
@@ -16,7 +16,6 @@
#include
#include
#include
-#include
#include
struct kobject;
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/linux/usb/composite.h b/trunk/include/linux/usb/composite.h
index 617068134ae8..890bc1472190 100644
--- a/trunk/include/linux/usb/composite.h
+++ b/trunk/include/linux/usb/composite.h
@@ -247,7 +247,6 @@ int usb_add_config(struct usb_composite_dev *,
* value; it should return zero on successful initialization.
* @unbind: Reverses @bind(); called as a side effect of unregistering
* this driver.
- * @disconnect: optional driver disconnect method
* @suspend: Notifies when the host stops sending USB traffic,
* after function notifications
* @resume: Notifies configuration when the host restarts USB traffic,
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/timer.h b/trunk/include/trace/events/timer.h
index 425bcfe56c62..c624126a9c8a 100644
--- a/trunk/include/trace/events/timer.h
+++ b/trunk/include/trace/events/timer.h
@@ -81,16 +81,14 @@ TRACE_EVENT(timer_expire_entry,
TP_STRUCT__entry(
__field( void *, timer )
__field( unsigned long, now )
- __field( void *, function)
),
TP_fast_assign(
__entry->timer = timer;
__entry->now = jiffies;
- __entry->function = timer->function;
),
- TP_printk("timer=%p function=%pf now=%lu", __entry->timer, __entry->function,__entry->now)
+ TP_printk("timer=%p now=%lu", __entry->timer, __entry->now)
);
/**
@@ -202,16 +200,14 @@ TRACE_EVENT(hrtimer_expire_entry,
TP_STRUCT__entry(
__field( void *, hrtimer )
__field( s64, now )
- __field( void *, function)
),
TP_fast_assign(
__entry->hrtimer = hrtimer;
__entry->now = now->tv64;
- __entry->function = hrtimer->function;
),
- TP_printk("hrtimer=%p function=%pf now=%llu", __entry->hrtimer, __entry->function,
+ TP_printk("hrtimer=%p now=%llu", __entry->hrtimer,
(unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now }))
);
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/include/xen/platform_pci.h b/trunk/include/xen/platform_pci.h
index a785a3b0c8c7..ce9d671c636c 100644
--- a/trunk/include/xen/platform_pci.h
+++ b/trunk/include/xen/platform_pci.h
@@ -16,15 +16,11 @@
#define XEN_IOPORT_PROTOVER (XEN_IOPORT_BASE + 2) /* 1 byte access (R) */
#define XEN_IOPORT_PRODNUM (XEN_IOPORT_BASE + 2) /* 2 byte access (W) */
-#define XEN_UNPLUG_ALL_IDE_DISKS (1<<0)
-#define XEN_UNPLUG_ALL_NICS (1<<1)
-#define XEN_UNPLUG_AUX_IDE_DISKS (1<<2)
-#define XEN_UNPLUG_ALL (XEN_UNPLUG_ALL_IDE_DISKS|\
- XEN_UNPLUG_ALL_NICS|\
- XEN_UNPLUG_AUX_IDE_DISKS)
-
-#define XEN_UNPLUG_UNNECESSARY (1<<16)
-#define XEN_UNPLUG_NEVER (1<<17)
+#define XEN_UNPLUG_ALL_IDE_DISKS 1
+#define XEN_UNPLUG_ALL_NICS 2
+#define XEN_UNPLUG_AUX_IDE_DISKS 4
+#define XEN_UNPLUG_ALL 7
+#define XEN_UNPLUG_IGNORE 8
static inline int xen_must_unplug_nics(void) {
#if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \
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/sched.c b/trunk/kernel/sched.c
index 09b574e7f4df..41541d79e3c8 100644
--- a/trunk/kernel/sched.c
+++ b/trunk/kernel/sched.c
@@ -3865,16 +3865,8 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
/*
* Owner changed, break to re-assess state.
*/
- if (lock->owner != owner) {
- /*
- * If the lock has switched to a different owner,
- * we likely have heavy contention. Return 0 to quit
- * optimistic spinning and not contend further:
- */
- if (lock->owner)
- return 0;
+ if (lock->owner != owner)
break;
- }
/*
* Is that owner really running on that cpu?
diff --git a/trunk/kernel/sched_fair.c b/trunk/kernel/sched_fair.c
index ab661ebc4895..806d1b227a21 100644
--- a/trunk/kernel/sched_fair.c
+++ b/trunk/kernel/sched_fair.c
@@ -3752,8 +3752,6 @@ static void task_fork_fair(struct task_struct *p)
raw_spin_lock_irqsave(&rq->lock, flags);
- update_rq_clock(rq);
-
if (unlikely(task_cpu(p) != this_cpu))
__set_task_cpu(p, this_cpu);
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/watchdog.c b/trunk/kernel/watchdog.c
index 0d53c8e853b1..613bc1f04610 100644
--- a/trunk/kernel/watchdog.c
+++ b/trunk/kernel/watchdog.c
@@ -206,9 +206,6 @@ void watchdog_overflow_callback(struct perf_event *event, int nmi,
struct perf_sample_data *data,
struct pt_regs *regs)
{
- /* Ensure the watchdog never gets throttled */
- event->hw.interrupts = 0;
-
if (__get_cpu_var(watchdog_nmi_touch) == true) {
__get_cpu_var(watchdog_nmi_touch) = false;
return;
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/kobject_uevent.c b/trunk/lib/kobject_uevent.c
index 70af0a7f97c0..b93579504dfa 100644
--- a/trunk/lib/kobject_uevent.c
+++ b/trunk/lib/kobject_uevent.c
@@ -123,7 +123,7 @@ static int kobj_usermode_filter(struct kobject *kobj)
* @kobj: struct kobject that the action is happening to
* @envp_ext: pointer to environmental data
*
- * Returns 0 if kobject_uevent_env() is completed with success or the
+ * Returns 0 if kobject_uevent() is completed with success or the
* corresponding error when it fails.
*/
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
@@ -317,7 +317,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
EXPORT_SYMBOL_GPL(kobject_uevent_env);
/**
- * kobject_uevent - notify userspace by sending an uevent
+ * kobject_uevent - notify userspace by ending an uevent
*
* @action: action that is happening
* @kobj: struct kobject that the action is happening to
diff --git a/trunk/lib/radix-tree.c b/trunk/lib/radix-tree.c
index efd16fa80b1c..e907858498a6 100644
--- a/trunk/lib/radix-tree.c
+++ b/trunk/lib/radix-tree.c
@@ -174,16 +174,14 @@ 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.
*/
- for (i = 0; i < RADIX_TREE_MAX_TAGS; i++)
- tag_clear(node, i, 0);
-
+ tag_clear(node, 0, 0);
+ tag_clear(node, 1, 0);
node->slots[0] = NULL;
node->count = 0;
@@ -625,30 +623,17 @@ EXPORT_SYMBOL(radix_tree_tag_get);
* also settag. The function stops either after tagging nr_to_tag items or
* after reaching last_index.
*
- * The tags must be set from the leaf level only and propagated back up the
- * path to the root. We must do this so that we resolve the full path before
- * setting any tags on intermediate nodes. If we set tags as we descend, then
- * we can get to the leaf node and find that the index that has the iftag
- * set is outside the range we are scanning. This reults in dangling tags and
- * can lead to problems with later tag operations (e.g. livelocks on lookups).
- *
* 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,
unsigned long nr_to_tag,
unsigned int iftag, unsigned int settag)
{
- unsigned int height = root->height;
- struct radix_tree_path path[height];
- struct radix_tree_path *pathp = path;
- struct radix_tree_node *slot;
- unsigned int shift;
- unsigned long tagged = 0;
- unsigned long index = *first_indexp;
+ unsigned int height = root->height, shift;
+ unsigned long tagged = 0, index = *first_indexp;
+ struct radix_tree_node *open_slots[height], *slot;
last_index = min(last_index, radix_tree_maxindex(height));
if (index > last_index)
@@ -668,13 +653,6 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
slot = radix_tree_indirect_to_ptr(root->rnode);
- /*
- * we fill the path from (root->height - 2) to 0, leaving the index at
- * (root->height - 1) as a terminator. Zero the node in the terminator
- * so that we can use this to end walk loops back up the path.
- */
- path[height - 1].node = NULL;
-
for (;;) {
int offset;
@@ -683,35 +661,21 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
goto next;
if (!tag_get(slot, iftag, offset))
goto next;
- if (height > 1) {
- /* Go down one level */
- height--;
- shift -= RADIX_TREE_MAP_SHIFT;
- path[height - 1].node = slot;
- path[height - 1].offset = offset;
- slot = slot->slots[offset];
- continue;
- }
-
- /* tag the leaf */
- tagged++;
tag_set(slot, settag, offset);
-
- /* walk back up the path tagging interior nodes */
- pathp = &path[0];
- while (pathp->node) {
- /* stop if we find a node with the tag already set */
- if (tag_get(pathp->node, settag, pathp->offset))
- break;
- tag_set(pathp->node, settag, pathp->offset);
- pathp++;
+ if (height == 1) {
+ tagged++;
+ goto next;
}
-
+ /* Go down one level */
+ height--;
+ shift -= RADIX_TREE_MAP_SHIFT;
+ open_slots[height] = slot;
+ slot = slot->slots[offset];
+ continue;
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;
@@ -721,7 +685,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
* last_index is guaranteed to be in the tree, what
* we do below cannot wander astray.
*/
- slot = path[height - 1].node;
+ slot = open_slots[height];
height++;
shift += RADIX_TREE_MAP_SHIFT;
}
diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c
index 6b2ab1051851..b6e5fd23cc5a 100644
--- a/trunk/mm/memory.c
+++ b/trunk/mm/memory.c
@@ -2760,35 +2760,21 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
}
/*
- * This is like a special single-page "expand_{down|up}wards()",
- * except we must first make sure that 'address{-|+}PAGE_SIZE'
+ * This is like a special single-page "expand_downwards()",
+ * except we must first make sure that 'address-PAGE_SIZE'
* doesn't hit another vma.
+ *
+ * The "find_vma()" will do the right thing even if we wrap
*/
static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address)
{
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;
-
- expand_stack(vma, address - PAGE_SIZE);
- }
- if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) {
- struct vm_area_struct *next = vma->vm_next;
-
- /* As VM_GROWSDOWN but s/below/above/ */
- if (next && next->vm_start == address + PAGE_SIZE)
- return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM;
+ address -= PAGE_SIZE;
+ if (find_vma(vma->vm_mm, address) != vma)
+ return -ENOMEM;
- expand_upwards(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 6128dc8e5ede..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;
@@ -1716,6 +1706,9 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
* PA-RISC uses this for its stack; IA64 for its Register Backing Store.
* vma is the last one with address > vma->vm_end. Have to extend vma.
*/
+#ifndef CONFIG_IA64
+static
+#endif
int expand_upwards(struct vm_area_struct *vma, unsigned long address)
{
int error;
@@ -1922,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--;
@@ -1930,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 a803f5e33471..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);
@@ -985,16 +984,22 @@ int write_cache_pages(struct address_space *mapping,
}
}
- /*
- * We stop writing back only if we are not doing
- * integrity sync. In case of integrity sync we have to
- * keep going until we have written all the pages
- * we tagged for writeback prior to entering this loop.
- */
- if (--wbc->nr_to_write <= 0 &&
- wbc->sync_mode == WB_SYNC_NONE) {
- done = 1;
- break;
+ if (wbc->nr_to_write > 0) {
+ if (--wbc->nr_to_write == 0 &&
+ wbc->sync_mode == WB_SYNC_NONE) {
+ /*
+ * We stop writing back only if we are
+ * not doing integrity sync. In case of
+ * integrity sync we have to keep going
+ * because someone may be concurrently
+ * dirtying pages, and we might have
+ * synced a lot of newly appeared dirty
+ * pages, but have not synced all of the
+ * old dirty pages.
+ */
+ done = 1;
+ break;
+ }
}
}
pagevec_release(&pvec);
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/8021q/vlan_dev.c b/trunk/net/8021q/vlan_dev.c
index 3bccdd12a264..3d59c9bf8feb 100644
--- a/trunk/net/8021q/vlan_dev.c
+++ b/trunk/net/8021q/vlan_dev.c
@@ -510,8 +510,7 @@ static int vlan_dev_open(struct net_device *dev)
if (vlan->flags & VLAN_FLAG_GVRP)
vlan_gvrp_request_join(dev);
- if (netif_carrier_ok(real_dev))
- netif_carrier_on(dev);
+ netif_carrier_on(dev);
return 0;
clear_allmulti:
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 e8f4f9a57f12..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();
}
@@ -1420,9 +1418,6 @@ static int translate_compat_table(const char *name,
if (ret != 0)
break;
++i;
- if (strcmp(arpt_get_target(iter1)->u.user.name,
- XT_ERROR_TARGET) == 0)
- ++newinfo->stacksize;
}
if (ret) {
/*
diff --git a/trunk/net/ipv4/netfilter/ip_tables.c b/trunk/net/ipv4/netfilter/ip_tables.c
index d163f2e3b2e9..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();
}
@@ -1751,9 +1749,6 @@ translate_compat_table(struct net *net,
if (ret != 0)
break;
++i;
- if (strcmp(ipt_get_target(iter1)->u.user.name,
- XT_ERROR_TARGET) == 0)
- ++newinfo->stacksize;
}
if (ret) {
/*
diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c
index 8e754be92c24..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();
}
@@ -1766,9 +1764,6 @@ translate_compat_table(struct net *net,
if (ret != 0)
break;
++i;
- if (strcmp(ip6t_get_target(iter1)->u.user.name,
- XT_ERROR_TARGET) == 0)
- ++newinfo->stacksize;
}
if (ret) {
/*
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/irda/irlan/irlan_eth.c b/trunk/net/irda/irlan/irlan_eth.c
index 5bb8353105cc..9616c32d1076 100644
--- a/trunk/net/irda/irlan/irlan_eth.c
+++ b/trunk/net/irda/irlan/irlan_eth.c
@@ -169,7 +169,6 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb,
{
struct irlan_cb *self = netdev_priv(dev);
int ret;
- unsigned int len;
/* skb headroom large enough to contain all IrDA-headers? */
if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) {
@@ -189,7 +188,6 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb,
dev->trans_start = jiffies;
- len = skb->len;
/* Now queue the packet in the transport layer */
if (self->use_udata)
ret = irttp_udata_request(self->tsap_data, skb);
@@ -211,7 +209,7 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb,
self->stats.tx_dropped++;
} else {
self->stats.tx_packets++;
- self->stats.tx_bytes += len;
+ self->stats.tx_bytes += skb->len;
}
return NETDEV_TX_OK;
diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c
index 980fe4ad0016..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, *data_skb;
+ struct sk_buff *skb;
int err;
if (flags&MSG_OOB)
@@ -1418,35 +1418,59 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
if (skb == NULL)
goto out;
- data_skb = skb;
-
#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
if (unlikely(skb_shinfo(skb)->frag_list)) {
+ bool need_compat = !!(flags & MSG_CMSG_COMPAT);
+
/*
- * If this skb has a frag_list, then here that means that we
- * will have to use the frag_list skb's data for compat tasks
- * and the regular skb's data for normal (non-compat) tasks.
+ * If this skb has a frag_list, then here that means that
+ * we will have to use the frag_list skb for compat tasks
+ * and the regular skb for non-compat tasks.
*
- * If we need to send the compat skb, assign it to the
- * 'data_skb' variable so that it will be used below for data
- * copying. We keep 'skb' for everything else, including
- * freeing both later.
+ * The skb might (and likely will) be cloned, so we can't
+ * just reset frag_list and go on with things -- we need to
+ * keep that. For the compat case that's easy -- simply get
+ * a reference to the compat skb and free the regular one
+ * including the frag. For the non-compat case, we need to
+ * avoid sending the frag to the user -- so assign NULL but
+ * restore it below before freeing the skb.
*/
- if (flags & MSG_CMSG_COMPAT)
- data_skb = skb_shinfo(skb)->frag_list;
+ if (need_compat) {
+ struct sk_buff *compskb = skb_shinfo(skb)->frag_list;
+ skb_get(compskb);
+ kfree_skb(skb);
+ skb = compskb;
+ } else {
+ /*
+ * 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;
+ }
}
#endif
msg->msg_namelen = 0;
- copied = data_skb->len;
+ copied = skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
copied = len;
}
- skb_reset_transport_header(data_skb);
- err = skb_copy_datagram_iovec(data_skb, 0, msg->msg_iov, copied);
+ skb_reset_transport_header(skb);
+ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (msg->msg_name) {
struct sockaddr_nl *addr = (struct sockaddr_nl *)msg->msg_name;
@@ -1466,7 +1490,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
}
siocb->scm->creds = *NETLINK_CREDS(skb);
if (flags & MSG_TRUNC)
- copied = data_skb->len;
+ copied = skb->len;
skb_free_datagram(sk, skb);
diff --git a/trunk/net/rds/recv.c b/trunk/net/rds/recv.c
index c93588c2d553..795a00b7f2cb 100644
--- a/trunk/net/rds/recv.c
+++ b/trunk/net/rds/recv.c
@@ -297,7 +297,7 @@ static int rds_still_queued(struct rds_sock *rs, struct rds_incoming *inc,
int rds_notify_queue_get(struct rds_sock *rs, struct msghdr *msghdr)
{
struct rds_notifier *notifier;
- struct rds_rdma_notify cmsg = { 0 }; /* fill holes with zero */
+ struct rds_rdma_notify cmsg;
unsigned int count = 0, max_messages = ~0U;
unsigned long flags;
LIST_HEAD(copy);
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/kconfig/confdata.c b/trunk/scripts/kconfig/confdata.c
index 515253fe46cf..c39327e60ea4 100644
--- a/trunk/scripts/kconfig/confdata.c
+++ b/trunk/scripts/kconfig/confdata.c
@@ -497,9 +497,7 @@ int conf_write_defconfig(const char *filename)
/*
* If symbol is a choice value and equals to the
* default for a choice - skip.
- * But only if value is bool and equal to "y" and
- * choice is not "optional".
- * (If choice is "optional" then all values can be "n")
+ * But only if value is bool and equal to "y" .
*/
if (sym_is_choice_value(sym)) {
struct symbol *cs;
@@ -507,7 +505,7 @@ int conf_write_defconfig(const char *filename)
cs = prop_get_symbol(sym_get_choice_prop(sym));
ds = sym_choice_default(cs);
- if (!sym_is_optional(cs) && sym == ds) {
+ if (sym == ds) {
if ((sym->type == S_BOOLEAN) &&
sym_get_tristate_value(sym) == yes)
goto next_menu;
diff --git a/trunk/scripts/kconfig/symbol.c b/trunk/scripts/kconfig/symbol.c
index 943712ca6c0a..e95718fea355 100644
--- a/trunk/scripts/kconfig/symbol.c
+++ b/trunk/scripts/kconfig/symbol.c
@@ -937,8 +937,6 @@ static void sym_check_print_recursive(struct symbol *last_sym)
sym = stack->sym;
next_sym = stack->next ? stack->next->sym : last_sym;
prop = stack->prop;
- if (prop == NULL)
- prop = stack->sym->prop;
/* for choice values find the menu entry (used below) */
if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
diff --git a/trunk/scripts/mkmakefile b/trunk/scripts/mkmakefile
index 5325423ceab4..67d59c7a18dc 100644
--- a/trunk/scripts/mkmakefile
+++ b/trunk/scripts/mkmakefile
@@ -44,9 +44,7 @@ all:
Makefile:;
-\$(all): all
+\$(all) %/: all
@:
-%/: all
- @:
EOF
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/scripts/setlocalversion b/trunk/scripts/setlocalversion
index 057b6b3c5dfb..e90a91cc5185 100755
--- a/trunk/scripts/setlocalversion
+++ b/trunk/scripts/setlocalversion
@@ -43,7 +43,7 @@ scm_version()
fi
# Check for git and a git repo.
- if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
+ if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
# it, because this version is defined in the top level Makefile.
@@ -85,7 +85,7 @@ scm_version()
fi
# Check for mercurial and a mercurial repo.
- if test -d .hg && hgid=`hg id 2>/dev/null`; then
+ if hgid=`hg id 2>/dev/null`; then
tag=`printf '%s' "$hgid" | cut -s -d' ' -f2`
# Do we have an untagged version?
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/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c
index 3827092cc1d2..dd8fb86c842b 100644
--- a/trunk/sound/pci/hda/hda_codec.c
+++ b/trunk/sound/pci/hda/hda_codec.c
@@ -589,7 +589,6 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
bus->ops = temp->ops;
mutex_init(&bus->cmd_mutex);
- mutex_init(&bus->prepare_mutex);
INIT_LIST_HEAD(&bus->codec_list);
snprintf(bus->workq_name, sizeof(bus->workq_name),
@@ -1069,6 +1068,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
codec->addr = codec_addr;
mutex_init(&codec->spdif_mutex);
mutex_init(&codec->control_mutex);
+ mutex_init(&codec->prepare_mutex);
init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
@@ -1213,7 +1213,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
u32 stream_tag,
int channel_id, int format)
{
- struct hda_codec *c;
struct hda_cvt_setup *p;
unsigned int oldval, newval;
int i;
@@ -1254,12 +1253,10 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
p->dirty = 0;
/* make other inactive cvts with the same stream-tag dirty */
- list_for_each_entry(c, &codec->bus->codec_list, list) {
- for (i = 0; i < c->cvt_setups.used; i++) {
- p = snd_array_elem(&c->cvt_setups, i);
- if (!p->active && p->stream_tag == stream_tag)
- p->dirty = 1;
- }
+ for (i = 0; i < codec->cvt_setups.used; i++) {
+ p = snd_array_elem(&codec->cvt_setups, i);
+ if (!p->active && p->stream_tag == stream_tag)
+ p->dirty = 1;
}
}
EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
@@ -1309,16 +1306,12 @@ static void really_cleanup_stream(struct hda_codec *codec,
/* clean up the all conflicting obsolete streams */
static void purify_inactive_streams(struct hda_codec *codec)
{
- struct hda_codec *c;
int i;
- list_for_each_entry(c, &codec->bus->codec_list, list) {
- for (i = 0; i < c->cvt_setups.used; i++) {
- struct hda_cvt_setup *p;
- p = snd_array_elem(&c->cvt_setups, i);
- if (p->dirty)
- really_cleanup_stream(c, p);
- }
+ for (i = 0; i < codec->cvt_setups.used; i++) {
+ struct hda_cvt_setup *p = snd_array_elem(&codec->cvt_setups, i);
+ if (p->dirty)
+ really_cleanup_stream(codec, p);
}
}
@@ -3509,11 +3502,11 @@ int snd_hda_codec_prepare(struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
int ret;
- mutex_lock(&codec->bus->prepare_mutex);
+ mutex_lock(&codec->prepare_mutex);
ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream);
if (ret >= 0)
purify_inactive_streams(codec);
- mutex_unlock(&codec->bus->prepare_mutex);
+ mutex_unlock(&codec->prepare_mutex);
return ret;
}
EXPORT_SYMBOL_HDA(snd_hda_codec_prepare);
@@ -3522,9 +3515,9 @@ void snd_hda_codec_cleanup(struct hda_codec *codec,
struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
- mutex_lock(&codec->bus->prepare_mutex);
+ mutex_lock(&codec->prepare_mutex);
hinfo->ops.cleanup(hinfo, codec, substream);
- mutex_unlock(&codec->bus->prepare_mutex);
+ mutex_unlock(&codec->prepare_mutex);
}
EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup);
diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h
index 62c702240108..4303353feda9 100644
--- a/trunk/sound/pci/hda/hda_codec.h
+++ b/trunk/sound/pci/hda/hda_codec.h
@@ -648,7 +648,6 @@ struct hda_bus {
struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
struct mutex cmd_mutex;
- struct mutex prepare_mutex;
/* unsolicited event queue */
struct hda_bus_unsolicited *unsol;
@@ -827,6 +826,7 @@ struct hda_codec {
struct mutex spdif_mutex;
struct mutex control_mutex;
+ struct mutex prepare_mutex;
unsigned int spdif_status; /* IEC958 status bits */
unsigned short spdif_ctls; /* SPDIF control bits */
unsigned int spdif_in_enable; /* SPDIF input enable? */
diff --git a/trunk/sound/pci/hda/hda_eld.c b/trunk/sound/pci/hda/hda_eld.c
index 26c3ade73583..803b298f7411 100644
--- a/trunk/sound/pci/hda/hda_eld.c
+++ b/trunk/sound/pci/hda/hda_eld.c
@@ -596,8 +596,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
}
EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
-#endif /* CONFIG_PROC_FS */
-
/* update PCM info based on ELD */
void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
struct hda_pcm_stream *codec_pars)
@@ -646,3 +644,5 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
}
EXPORT_SYMBOL_HDA(hdmi_eld_update_pcm_info);
+
+#endif /* CONFIG_PROC_FS */
diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c
index 5cdb80edbd7f..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),
@@ -3059,7 +3058,6 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD),
- SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
{}
diff --git a/trunk/sound/pci/hda/patch_hdmi.c b/trunk/sound/pci/hda/patch_hdmi.c
index afd6022a96a7..2bc0f07cf33f 100644
--- a/trunk/sound/pci/hda/patch_hdmi.c
+++ b/trunk/sound/pci/hda/patch_hdmi.c
@@ -707,6 +707,8 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
u32 stream_tag, int format)
{
struct hdmi_spec *spec = codec->spec;
+ int tag;
+ int fmt;
int pinctl;
int new_pinctl = 0;
int i;
@@ -743,7 +745,24 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
return -EINVAL;
}
- snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
+ tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
+ fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
+
+ snd_printdd("hdmi_setup_stream: "
+ "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
+ nid,
+ tag == stream_tag ? "" : "new-",
+ stream_tag,
+ fmt == format ? "" : "new-",
+ format);
+
+ if (tag != stream_tag)
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_CHANNEL_STREAMID,
+ stream_tag << 4);
+ if (fmt != format)
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_STREAM_FORMAT, format);
return 0;
}
diff --git a/trunk/sound/pci/hda/patch_intelhdmi.c b/trunk/sound/pci/hda/patch_intelhdmi.c
index 36a9b83a6174..d382d3c81c0f 100644
--- a/trunk/sound/pci/hda/patch_intelhdmi.c
+++ b/trunk/sound/pci/hda/patch_intelhdmi.c
@@ -69,12 +69,20 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
}
+static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
static struct hda_pcm_stream intel_hdmi_pcm_playback = {
.substreams = 1,
.channels_min = 2,
.ops = {
.open = hdmi_pcm_open,
.prepare = intel_hdmi_playback_pcm_prepare,
+ .cleanup = intel_hdmi_playback_pcm_cleanup,
},
};
diff --git a/trunk/sound/pci/hda/patch_nvhdmi.c b/trunk/sound/pci/hda/patch_nvhdmi.c
index 69b950d527c3..f636870dc718 100644
--- a/trunk/sound/pci/hda/patch_nvhdmi.c
+++ b/trunk/sound/pci/hda/patch_nvhdmi.c
@@ -326,6 +326,13 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
return 0;
}
+static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
@@ -343,6 +350,7 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
.ops = {
.open = hdmi_pcm_open,
.prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
+ .cleanup = nvhdmi_playback_pcm_cleanup,
},
};
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/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c
index 95148e58026c..f3f861bd1bf8 100644
--- a/trunk/sound/pci/hda/patch_sigmatel.c
+++ b/trunk/sound/pci/hda/patch_sigmatel.c
@@ -6303,21 +6303,6 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
{ .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
{ .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
{ .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
- { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx },
- { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx },
{} /* terminator */
};
diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c
index 467749249576..6433e65c9507 100644
--- a/trunk/sound/pci/intel8x0.c
+++ b/trunk/sound/pci/intel8x0.c
@@ -1774,12 +1774,6 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.name = "HP/Compaq nx7010",
.type = AC97_TUNE_MUTE_LED
},
- {
- .subvendor = 0x1014,
- .subdevice = 0x0534,
- .name = "ThinkPad X31",
- .type = AC97_TUNE_INV_EAPD
- },
{
.subvendor = 0x1014,
.subdevice = 0x1f00,
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/sound/soc/imx/imx-ssi.c b/trunk/sound/soc/imx/imx-ssi.c
index c81da05a4f11..a11daa1e905b 100644
--- a/trunk/sound/soc/imx/imx-ssi.c
+++ b/trunk/sound/soc/imx/imx-ssi.c
@@ -254,9 +254,6 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
dma_data = &ssi->dma_params_rx;
}
- if (ssi->flags & IMX_SSI_SYN)
- reg = SSI_STCCR;
-
snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
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)