diff --git a/[refs] b/[refs] index 9f9bf198d06d..60e338577ced 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 69f7876b2ab61e8114675d6092ad0b482e233612 +refs/heads/master: 01e542c65de11a47e726ebef63f5e59b4a74568d diff --git a/trunk/Documentation/DocBook/media-entities.tmpl b/trunk/Documentation/DocBook/media-entities.tmpl index fea63b45471a..5d259c632cdf 100644 --- a/trunk/Documentation/DocBook/media-entities.tmpl +++ b/trunk/Documentation/DocBook/media-entities.tmpl @@ -294,7 +294,6 @@ - diff --git a/trunk/Documentation/DocBook/v4l/media-ioc-setup-link.xml b/trunk/Documentation/DocBook/v4l/media-ioc-setup-link.xml index cec97af4dab4..2331e76ded17 100644 --- a/trunk/Documentation/DocBook/v4l/media-ioc-setup-link.xml +++ b/trunk/Documentation/DocBook/v4l/media-ioc-setup-link.xml @@ -34,7 +34,7 @@ request - MEDIA_IOC_SETUP_LINK + MEDIA_IOC_ENUM_LINKS diff --git a/trunk/Documentation/DocBook/v4l/pixfmt-y12.xml b/trunk/Documentation/DocBook/v4l/pixfmt-y12.xml deleted file mode 100644 index ff417b858cc9..000000000000 --- a/trunk/Documentation/DocBook/v4l/pixfmt-y12.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - V4L2_PIX_FMT_Y12 ('Y12 ') - &manvol; - - - V4L2_PIX_FMT_Y12 - Grey-scale image - - - Description - - This is a grey-scale image with a depth of 12 bits per pixel. Pixels -are stored in 16-bit words with unused high bits padded with 0. The least -significant byte is stored at lower memory addresses (little-endian). - - - <constant>V4L2_PIX_FMT_Y12</constant> 4 × 4 -pixel image - - - Byte Order. - Each cell is one byte. - - - - - - start + 0: - Y'00low - Y'00high - Y'01low - Y'01high - Y'02low - Y'02high - Y'03low - Y'03high - - - start + 8: - Y'10low - Y'10high - Y'11low - Y'11high - Y'12low - Y'12high - Y'13low - Y'13high - - - start + 16: - Y'20low - Y'20high - Y'21low - Y'21high - Y'22low - Y'22high - Y'23low - Y'23high - - - start + 24: - Y'30low - Y'30high - Y'31low - Y'31high - Y'32low - Y'32high - Y'33low - Y'33high - - - - - - - - - diff --git a/trunk/Documentation/DocBook/v4l/pixfmt.xml b/trunk/Documentation/DocBook/v4l/pixfmt.xml index 40af4beb48b9..c6fdcbbd1b41 100644 --- a/trunk/Documentation/DocBook/v4l/pixfmt.xml +++ b/trunk/Documentation/DocBook/v4l/pixfmt.xml @@ -696,7 +696,6 @@ information. &sub-packed-yuv; &sub-grey; &sub-y10; - &sub-y12; &sub-y16; &sub-yuyv; &sub-uyvy; diff --git a/trunk/Documentation/DocBook/v4l/subdev-formats.xml b/trunk/Documentation/DocBook/v4l/subdev-formats.xml index d7ccd25edcc1..7041127d6dfc 100644 --- a/trunk/Documentation/DocBook/v4l/subdev-formats.xml +++ b/trunk/Documentation/DocBook/v4l/subdev-formats.xml @@ -456,23 +456,6 @@ b1 b0 - - V4L2_MBUS_FMT_SGBRG8_1X8 - 0x3013 - - - - - - - - - - g7 - g6 - g5 - g4 - g3 - g2 - g1 - g0 - V4L2_MBUS_FMT_SGRBG8_1X8 0x3002 @@ -490,23 +473,6 @@ g1 g0 - - V4L2_MBUS_FMT_SRGGB8_1X8 - 0x3014 - - - - - - - - - - r7 - r6 - r5 - r4 - r3 - r2 - r1 - r0 - V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 0x300b @@ -2193,31 +2159,6 @@ u1 u0 - - V4L2_MBUS_FMT_Y12_1X12 - 0x2013 - - - - - - - - - - - - - - - - - - y11 - y10 - y9 - y8 - y7 - y6 - y5 - y4 - y3 - y2 - y1 - y0 - V4L2_MBUS_FMT_UYVY8_1X16 0x200f diff --git a/trunk/Documentation/cgroups/memory.txt b/trunk/Documentation/cgroups/memory.txt index 7c163477fcd8..b6ed61c95856 100644 --- a/trunk/Documentation/cgroups/memory.txt +++ b/trunk/Documentation/cgroups/memory.txt @@ -52,10 +52,8 @@ Brief summary of control files. tasks # attach a task(thread) and show list of threads cgroup.procs # show list of processes cgroup.event_control # an interface for event_fd() - memory.usage_in_bytes # show current res_counter usage for memory - (See 5.5 for details) - memory.memsw.usage_in_bytes # show current res_counter usage for memory+Swap - (See 5.5 for details) + memory.usage_in_bytes # show current memory(RSS+Cache) usage. + memory.memsw.usage_in_bytes # show current memory+Swap usage memory.limit_in_bytes # set/show limit of memory usage memory.memsw.limit_in_bytes # set/show limit of memory+Swap usage memory.failcnt # show the number of memory usage hits limits @@ -455,15 +453,6 @@ memory under it will be reclaimed. You can reset failcnt by writing 0 to failcnt file. # echo 0 > .../memory.failcnt -5.5 usage_in_bytes - -For efficiency, as other kernel components, memory cgroup uses some optimization -to avoid unnecessary cacheline false sharing. usage_in_bytes is affected by the -method and doesn't show 'exact' value of memory(and swap) usage, it's an fuzz -value for efficient access. (Of course, when necessary, it's synchronized.) -If you want to know more exact memory usage, you should use RSS+CACHE(+SWAP) -value in memory.stat(see 5.2). - 6. Hierarchy support The memory controller supports a deep hierarchy and hierarchical accounting. diff --git a/trunk/Documentation/hwmon/adm1021 b/trunk/Documentation/hwmon/adm1021 index 02ad96cf9b2b..03d02bfb3df1 100644 --- a/trunk/Documentation/hwmon/adm1021 +++ b/trunk/Documentation/hwmon/adm1021 @@ -14,6 +14,10 @@ Supported chips: Prefix: 'gl523sm' Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e Datasheet: + * Intel Xeon Processor + Prefix: - any other - may require 'force_adm1021' parameter + Addresses scanned: none + Datasheet: Publicly available at Intel website * Maxim MAX1617 Prefix: 'max1617' Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e @@ -87,27 +91,21 @@ will do no harm, but will return 'old' values. It is possible to make ADM1021-clones do faster measurements, but there is really no good reason for that. +Xeon support +------------ -Netburst-based Xeon support ---------------------------- +Some Xeon processors have real max1617, adm1021, or compatible chips +within them, with two temperature sensors. -Some Xeon processors based on the Netburst (early Pentium 4, from 2001 to -2003) microarchitecture had real MAX1617, ADM1021, or compatible chips -within them, with two temperature sensors. Other Xeon processors of this -era (with 400 MHz FSB) had chips with only one temperature sensor. +Other Xeons have chips with only one sensor. -If you have such an old Xeon, and you get two valid temperatures when -loading the adm1021 module, then things are good. +If you have a Xeon, and the adm1021 module loads, and both temperatures +appear valid, then things are good. -If nothing happens when loading the adm1021 module, and you are certain -that your specific Xeon processor model includes compatible sensors, you -will have to explicitly instantiate the sensor chips from user-space. See -method 4 in Documentation/i2c/instantiating-devices. Possible slave -addresses are 0x18, 0x1a, 0x29, 0x2b, 0x4c, or 0x4e. It is likely that -only temp2 will be correct and temp1 will have to be ignored. +If the adm1021 module doesn't load, you should try this: + modprobe adm1021 force_adm1021=BUS,ADDRESS + ADDRESS can only be 0x18, 0x1a, 0x29, 0x2b, 0x4c, or 0x4e. -Previous generations of the Xeon processor (based on Pentium II/III) -didn't have these sensors. Next generations of Xeon processors (533 MHz -FSB and faster) lost them, until the Core-based generation which -introduced integrated digital thermal sensors. These are supported by -the coretemp driver. +If you have dual Xeons you may have appear to have two separate +adm1021-compatible chips, or two single-temperature sensors, at distinct +addresses. diff --git a/trunk/Documentation/hwmon/lm90 b/trunk/Documentation/hwmon/lm90 index f3efd18e87f4..fa475c0a48a3 100644 --- a/trunk/Documentation/hwmon/lm90 +++ b/trunk/Documentation/hwmon/lm90 @@ -32,16 +32,6 @@ Supported chips: Addresses scanned: I2C 0x4c and 0x4d Datasheet: Publicly available at the ON Semiconductor website http://www.onsemi.com/PowerSolutions/product.do?id=ADT7461 - * Analog Devices ADT7461A - Prefix: 'adt7461a' - Addresses scanned: I2C 0x4c and 0x4d - Datasheet: Publicly available at the ON Semiconductor website - http://www.onsemi.com/PowerSolutions/product.do?id=ADT7461A - * ON Semiconductor NCT1008 - Prefix: 'nct1008' - Addresses scanned: I2C 0x4c and 0x4d - Datasheet: Publicly available at the ON Semiconductor website - http://www.onsemi.com/PowerSolutions/product.do?id=NCT1008 * Maxim MAX6646 Prefix: 'max6646' Addresses scanned: I2C 0x4d @@ -159,7 +149,7 @@ ADM1032: * ALERT is triggered by open remote sensor. * SMBus PEC support for Write Byte and Receive Byte transactions. -ADT7461, ADT7461A, NCT1008: +ADT7461: * Extended temperature range (breaks compatibility) * Lower resolution for remote temperature @@ -205,9 +195,9 @@ are exported, one for each channel, but these values are of course linked. Only the local hysteresis can be set from user-space, and the same delta applies to the remote hysteresis. -The lm90 driver will not update its values more frequently than configured with -the update_interval attribute; reading them more often will do no harm, but will -return 'old' values. +The lm90 driver will not update its values more frequently than every +other second; reading them more often will do no harm, but will return +'old' values. SMBus Alert Support ------------------- @@ -215,12 +205,11 @@ SMBus Alert Support This driver has basic support for SMBus alert. When an alert is received, the status register is read and the faulty temperature channel is logged. -The Analog Devices chips (ADM1032, ADT7461 and ADT7461A) and ON -Semiconductor chips (NCT1008) do not implement the SMBus alert protocol -properly so additional care is needed: the ALERT output is disabled when -an alert is received, and is re-enabled only when the alarm is gone. -Otherwise the chip would block alerts from other chips in the bus as long -as the alarm is active. +The Analog Devices chips (ADM1032 and ADT7461) do not implement the SMBus +alert protocol properly so additional care is needed: the ALERT output is +disabled when an alert is received, and is re-enabled only when the alarm +is gone. Otherwise the chip would block alerts from other chips in the bus +as long as the alarm is active. PEC Support ----------- diff --git a/trunk/Documentation/video4linux/sh_mobile_ceu_camera.txt b/trunk/Documentation/video4linux/sh_mobile_ceu_camera.txt index 1e96ce6e2d2f..cb47e723af74 100644 --- a/trunk/Documentation/video4linux/sh_mobile_ceu_camera.txt +++ b/trunk/Documentation/video4linux/sh_mobile_ceu_camera.txt @@ -37,7 +37,7 @@ Generic scaling / cropping scheme -1'- In the above chart minuses and slashes represent "real" data amounts, points and -accents represent "useful" data, basically, CEU scaled and cropped output, +accents represent "useful" data, basically, CEU scaled amd cropped output, mapped back onto the client's source plane. Such a configuration can be produced by user requests: @@ -65,7 +65,7 @@ Do not touch input rectangle - it is already optimal. 1. Calculate current sensor scales: - scale_s = ((2') - (2)) / ((3') - (3)) + scale_s = ((3') - (3)) / ((2') - (2)) 2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at current sensor scales onto input window - this is user S_CROP: @@ -80,7 +80,7 @@ window: 4. Calculate sensor output window by applying combined scales to real input window: - width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb + width_s_out = ((2') - (2)) / scale_comb 5. Apply iterative sensor S_FMT for sensor output window. diff --git a/trunk/Documentation/workqueue.txt b/trunk/Documentation/workqueue.txt index a0b577de918f..01c513fac40e 100644 --- a/trunk/Documentation/workqueue.txt +++ b/trunk/Documentation/workqueue.txt @@ -12,7 +12,6 @@ CONTENTS 4. Application Programming Interface (API) 5. Example Execution Scenarios 6. Guidelines -7. Debugging 1. Introduction @@ -380,42 +379,3 @@ If q1 has WQ_CPU_INTENSIVE set, * Unless work items are expected to consume a huge amount of CPU cycles, using a bound wq is usually beneficial due to the increased level of locality in wq operations and work item execution. - - -7. Debugging - -Because the work functions are executed by generic worker threads -there are a few tricks needed to shed some light on misbehaving -workqueue users. - -Worker threads show up in the process list as: - -root 5671 0.0 0.0 0 0 ? S 12:07 0:00 [kworker/0:1] -root 5672 0.0 0.0 0 0 ? S 12:07 0:00 [kworker/1:2] -root 5673 0.0 0.0 0 0 ? S 12:12 0:00 [kworker/0:0] -root 5674 0.0 0.0 0 0 ? S 12:13 0:00 [kworker/1:0] - -If kworkers are going crazy (using too much cpu), there are two types -of possible problems: - - 1. Something beeing scheduled in rapid succession - 2. A single work item that consumes lots of cpu cycles - -The first one can be tracked using tracing: - - $ echo workqueue:workqueue_queue_work > /sys/kernel/debug/tracing/set_event - $ cat /sys/kernel/debug/tracing/trace_pipe > out.txt - (wait a few secs) - ^C - -If something is busy looping on work queueing, it would be dominating -the output and the offender can be determined with the work item -function. - -For the second type of problems it should be possible to just check -the stack trace of the offending worker thread. - - $ cat /proc/THE_OFFENDING_KWORKER/stack - -The work item's function should be trivially visible in the stack -trace. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index ae65b29ad936..13803127b68f 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1032,13 +1032,12 @@ W: http://www.fluff.org/ben/linux/ S: Maintained F: arch/arm/mach-s3c64xx/ -ARM/S5P EXYNOS ARM ARCHITECTURES +ARM/S5P ARM ARCHITECTURES M: Kukjin Kim L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-s5p*/ -F: arch/arm/mach-exynos*/ ARM/SAMSUNG MOBILE MACHINE SUPPORT M: Kyungmin Park @@ -2251,10 +2250,10 @@ F: drivers/gpu/drm/ F: include/drm/ INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets) -M: Keith Packard +M: Chris Wilson L: intel-gfx@lists.freedesktop.org (subscribers-only) L: dri-devel@lists.freedesktop.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/keithp/linux-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/ickle/drm-intel.git S: Supported F: drivers/gpu/drm/i915 F: include/drm/i915* @@ -2809,7 +2808,7 @@ GPIO SUBSYSTEM M: Grant Likely S: Maintained T: git git://git.secretlab.ca/git/linux-2.6.git -F: Documentation/gpio.txt +F: Documentation/gpio/gpio.txt F: drivers/gpio/ F: include/linux/gpio* @@ -6556,7 +6555,7 @@ S: Maintained F: drivers/usb/host/uhci* USB "USBNET" DRIVER FRAMEWORK -M: Oliver Neukum +M: David Brownell L: netdev@vger.kernel.org W: http://www.linux-usb.org/usbnet S: Maintained @@ -6922,18 +6921,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86. S: Maintained F: drivers/platform/x86 -XEN HYPERVISOR INTERFACE -M: Jeremy Fitzhardinge -M: Konrad Rzeszutek Wilk -L: xen-devel@lists.xensource.com (moderated for non-subscribers) -L: virtualization@lists.linux-foundation.org -S: Supported -F: arch/x86/xen/ -F: drivers/*/xen-*front.c -F: drivers/xen/ -F: arch/x86/include/asm/xen/ -F: include/xen/ - XEN NETWORK BACKEND DRIVER M: Ian Campbell L: xen-devel@lists.xensource.com (moderated for non-subscribers) @@ -6955,6 +6942,18 @@ S: Supported F: arch/x86/xen/*swiotlb* F: drivers/xen/*swiotlb* +XEN HYPERVISOR INTERFACE +M: Jeremy Fitzhardinge +M: Konrad Rzeszutek Wilk +L: xen-devel@lists.xensource.com (moderated for non-subscribers) +L: virtualization@lists.linux-foundation.org +S: Supported +F: arch/x86/xen/ +F: drivers/*/xen-*front.c +F: drivers/xen/ +F: arch/x86/include/asm/xen/ +F: include/xen/ + XFS FILESYSTEM P: Silicon Graphics Inc M: Alex Elder diff --git a/trunk/Makefile b/trunk/Makefile index 28820f7ddf0a..5a7a2e4f5c0b 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 39 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc5 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* diff --git a/trunk/arch/arm/include/asm/kprobes.h b/trunk/arch/arm/include/asm/kprobes.h index e46bdd0097eb..bb8a19bd5822 100644 --- a/trunk/arch/arm/include/asm/kprobes.h +++ b/trunk/arch/arm/include/asm/kprobes.h @@ -39,13 +39,10 @@ typedef u32 kprobe_opcode_t; struct kprobe; typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); -typedef unsigned long (kprobe_check_cc)(unsigned long); - /* Architecture specific copy of original instruction. */ struct arch_specific_insn { kprobe_opcode_t *insn; kprobe_insn_handler_t *insn_handler; - kprobe_check_cc *insn_check_cc; }; struct prev_kprobe { diff --git a/trunk/arch/arm/kernel/kprobes-decode.c b/trunk/arch/arm/kernel/kprobes-decode.c index 15eeff6aea0e..23891317dc4b 100644 --- a/trunk/arch/arm/kernel/kprobes-decode.c +++ b/trunk/arch/arm/kernel/kprobes-decode.c @@ -34,6 +34,9 @@ * * *) If the PC is written to by the instruction, the * instruction must be fully simulated in software. + * If it is a conditional instruction, the handler + * will use insn[0] to copy its condition code to + * set r0 to 1 and insn[1] to "mov pc, lr" to return. * * *) Otherwise, a modified form of the instruction is * directly executed. Its handler calls the @@ -65,17 +68,13 @@ #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25) -#define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos)) - -/* - * Test if load/store instructions writeback the address register. - * if P (bit 24) == 0 or W (bit 21) == 1 - */ -#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000) - #define PSR_fs (PSR_f|PSR_s) #define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */ +#define SET_R0_TRUE_INSTRUCTION 0xe3a00001 /* mov r0, #1 */ + +#define truecc_insn(insn) (((insn) & 0xf0000000) | \ + (SET_R0_TRUE_INSTRUCTION & 0x0fffffff)) typedef long (insn_0arg_fn_t)(void); typedef long (insn_1arg_fn_t)(long); @@ -420,10 +419,14 @@ insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr, static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs) { + insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; kprobe_opcode_t insn = p->opcode; long iaddr = (long)p->addr; int disp = branch_displacement(insn); + if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) + return; + if (insn & (1 << 24)) regs->ARM_lr = iaddr + 4; @@ -443,10 +446,14 @@ static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs) static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) { + insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; kprobe_opcode_t insn = p->opcode; int rm = insn & 0xf; long rmv = regs->uregs[rm]; + if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) + return; + if (insn & (1 << 5)) regs->ARM_lr = (long)p->addr + 4; @@ -456,16 +463,9 @@ static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) regs->ARM_cpsr |= PSR_T_BIT; } -static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs) -{ - kprobe_opcode_t insn = p->opcode; - int rd = (insn >> 12) & 0xf; - unsigned long mask = 0xf8ff03df; /* Mask out execution state */ - regs->uregs[rd] = regs->ARM_cpsr & mask; -} - static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) { + insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; kprobe_opcode_t insn = p->opcode; int rn = (insn >> 16) & 0xf; int lbit = insn & (1 << 20); @@ -476,6 +476,9 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) int reg_bit_vector; int reg_count; + if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) + return; + reg_count = 0; reg_bit_vector = insn & 0xffff; while (reg_bit_vector) { @@ -507,6 +510,11 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) { + insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; + + if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) + return; + regs->ARM_pc = (long)p->addr + str_pc_offset; simulate_ldm1stm1(p, regs); regs->ARM_pc = (long)p->addr + 4; @@ -517,16 +525,24 @@ static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs) regs->uregs[12] = regs->uregs[13]; } +static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs) +{ + insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; + kprobe_opcode_t insn = p->opcode; + int rn = (insn >> 16) & 0xf; + long rnv = regs->uregs[rn]; + + /* Save Rn in case of writeback. */ + regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); +} + static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs) { insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; kprobe_opcode_t insn = p->opcode; - long ppc = (long)p->addr + 8; int rd = (insn >> 12) & 0xf; int rn = (insn >> 16) & 0xf; int rm = insn & 0xf; /* rm may be invalid, don't care. */ - long rmv = (rm == 15) ? ppc : regs->uregs[rm]; - long rnv = (rn == 15) ? ppc : regs->uregs[rn]; /* Not following the C calling convention here, so need asm(). */ __asm__ __volatile__ ( @@ -538,36 +554,29 @@ static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs) "str r0, %[rn] \n\t" /* in case of writeback */ "str r2, %[rd0] \n\t" "str r3, %[rd1] \n\t" - : [rn] "+m" (rnv), + : [rn] "+m" (regs->uregs[rn]), [rd0] "=m" (regs->uregs[rd]), [rd1] "=m" (regs->uregs[rd+1]) - : [rm] "m" (rmv), + : [rm] "m" (regs->uregs[rm]), [cpsr] "r" (regs->ARM_cpsr), [i_fn] "r" (i_fn) : "r0", "r1", "r2", "r3", "lr", "cc" ); - if (is_writeback(insn)) - regs->uregs[rn] = rnv; } static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs) { insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0]; kprobe_opcode_t insn = p->opcode; - long ppc = (long)p->addr + 8; int rd = (insn >> 12) & 0xf; int rn = (insn >> 16) & 0xf; int rm = insn & 0xf; - long rnv = (rn == 15) ? ppc : regs->uregs[rn]; - /* rm/rmv may be invalid, don't care. */ - long rmv = (rm == 15) ? ppc : regs->uregs[rm]; - long rnv_wb; + long rnv = regs->uregs[rn]; + long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ - rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd], + regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd], regs->uregs[rd+1], regs->ARM_cpsr, i_fn); - if (is_writeback(insn)) - regs->uregs[rn] = rnv_wb; } static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs) @@ -621,6 +630,31 @@ static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs) regs->uregs[rn] = rnv_wb; /* Save Rn in case of writeback. */ } +static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs) +{ + insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0]; + kprobe_opcode_t insn = p->opcode; + union reg_pair fnr; + int rd = (insn >> 12) & 0xf; + int rn = (insn >> 16) & 0xf; + + fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn); + regs->uregs[rn] = fnr.r0; + regs->uregs[rd] = fnr.r1; +} + +static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs) +{ + insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; + kprobe_opcode_t insn = p->opcode; + int rd = (insn >> 12) & 0xf; + int rn = (insn >> 16) & 0xf; + long rnv = regs->uregs[rn]; + long rdv = regs->uregs[rd]; + + insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn); +} + static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs) { insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; @@ -654,32 +688,32 @@ static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs) insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); } -static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs) +static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs) { + insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0]; + kprobe_opcode_t insn = p->opcode; + int rd = (insn >> 12) & 0xf; + + regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); } -static void __kprobes -emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs) +static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs) { insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; kprobe_opcode_t insn = p->opcode; - int rd = (insn >> 12) & 0xf; - long rdv = regs->uregs[rd]; + int ird = (insn >> 12) & 0xf; - regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn); + insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn); } -static void __kprobes -emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs) +static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs) { - insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; + insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; kprobe_opcode_t insn = p->opcode; - int rd = (insn >> 12) & 0xf; - int rn = insn & 0xf; - long rdv = regs->uregs[rd]; + int rn = (insn >> 16) & 0xf; long rnv = regs->uregs[rn]; - regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn); + insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); } static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs) @@ -784,17 +818,6 @@ emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs) regs->uregs[rd] = insnslot_1arg_rwflags(rnv, ®s->ARM_cpsr, i_fn); } -static void __kprobes -emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs) -{ - insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; - kprobe_opcode_t insn = p->opcode; - int rn = (insn >> 16) & 0xf; - long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn]; - - insnslot_1arg_rwflags(rnv, ®s->ARM_cpsr, i_fn); -} - static void __kprobes emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs) { @@ -831,34 +854,14 @@ emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs) insnslot_3arg_rwflags(rnv, rmv, rsv, ®s->ARM_cpsr, i_fn); } -static void __kprobes -emulate_alu_tests(struct kprobe *p, struct pt_regs *regs) -{ - insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; - kprobe_opcode_t insn = p->opcode; - long ppc = (long)p->addr + 8; - int rn = (insn >> 16) & 0xf; - int rs = (insn >> 8) & 0xf; /* rs/rsv may be invalid, don't care. */ - int rm = insn & 0xf; - long rnv = (rn == 15) ? ppc : regs->uregs[rn]; - long rmv = (rm == 15) ? ppc : regs->uregs[rm]; - long rsv = regs->uregs[rs]; - - insnslot_3arg_rwflags(rnv, rmv, rsv, ®s->ARM_cpsr, i_fn); -} - static enum kprobe_insn __kprobes prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25)) - : (~insn & (1 << 22)); - - if (is_writeback(insn) && is_r15(insn, 16)) - return INSN_REJECTED; /* Writeback to PC */ + int ibit = (insn & (1 << 26)) ? 25 : 22; insn &= 0xfff00fff; insn |= 0x00001000; /* Rn = r0, Rd = r1 */ - if (not_imm) { + if (insn & (1 << ibit)) { insn &= ~0xf; insn |= 2; /* Rm = r2 */ } @@ -868,40 +871,20 @@ prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi) } static enum kprobe_insn __kprobes -prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi) -{ - if (is_r15(insn, 12)) - return INSN_REJECTED; /* Rd is PC */ - - insn &= 0xffff0fff; /* Rd = r0 */ - asi->insn[0] = insn; - asi->insn_handler = emulate_rd12_modify; - return INSN_GOOD; -} - -static enum kprobe_insn __kprobes -prep_emulate_rd12rn0_modify(kprobe_opcode_t insn, - struct arch_specific_insn *asi) +prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - if (is_r15(insn, 12)) - return INSN_REJECTED; /* Rd is PC */ - - insn &= 0xffff0ff0; /* Rd = r0 */ - insn |= 0x00000001; /* Rn = r1 */ + insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ asi->insn[0] = insn; - asi->insn_handler = emulate_rd12rn0_modify; + asi->insn_handler = emulate_rd12rm0; return INSN_GOOD; } static enum kprobe_insn __kprobes -prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi) +prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - if (is_r15(insn, 12)) - return INSN_REJECTED; /* Rd is PC */ - - insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ + insn &= 0xffff0fff; /* Rd = r0 */ asi->insn[0] = insn; - asi->insn_handler = emulate_rd12rm0; + asi->insn_handler = emulate_rd12; return INSN_GOOD; } @@ -909,9 +892,6 @@ static enum kprobe_insn __kprobes prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - if (is_r15(insn, 12)) - return INSN_REJECTED; /* Rd is PC */ - insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ insn |= 0x00000001; /* Rm = r1 */ asi->insn[0] = insn; @@ -923,9 +903,6 @@ static enum kprobe_insn __kprobes prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - if (is_r15(insn, 16)) - return INSN_REJECTED; /* Rd is PC */ - insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */ insn |= 0x00000001; /* Rm = r1 */ asi->insn[0] = insn; @@ -937,9 +914,6 @@ static enum kprobe_insn __kprobes prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - if (is_r15(insn, 16)) - return INSN_REJECTED; /* Rd is PC */ - insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */ insn |= 0x00000102; /* Rs = r1, Rm = r2 */ asi->insn[0] = insn; @@ -951,9 +925,6 @@ static enum kprobe_insn __kprobes prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - if (is_r15(insn, 16) || is_r15(insn, 12)) - return INSN_REJECTED; /* RdHi or RdLo is PC */ - insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */ insn |= 0x00001203; /* Rs = r2, Rm = r3 */ asi->insn[0] = insn; @@ -974,13 +945,20 @@ prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn, static enum kprobe_insn __kprobes space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - /* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */ - /* PLDI : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */ - /* PLDW : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */ - /* PLD : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */ - if ((insn & 0xfe300000) == 0xf4100000) { - asi->insn_handler = emulate_nop; - return INSN_GOOD_NO_SLOT; + /* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */ + /* RFE : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */ + /* SRS : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */ + if ((insn & 0xfff30020) == 0xf1020000 || + (insn & 0xfe500f00) == 0xf8100a00 || + (insn & 0xfe5f0f00) == 0xf84d0500) + return INSN_REJECTED; + + /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */ + if ((insn & 0xfd700000) == 0xf4500000) { + insn &= 0xfff0ffff; /* Rn = r0 */ + asi->insn[0] = insn; + asi->insn_handler = emulate_rn16; + return INSN_GOOD; } /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */ @@ -989,22 +967,41 @@ space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi) return INSN_GOOD_NO_SLOT; } - /* CPS : 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */ - /* SETEND: 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ - - /* SRS : 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */ - /* RFE : 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ + /* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ + /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ + if ((insn & 0xffff00f0) == 0xf1010000 || + (insn & 0xff000010) == 0xfe000000) { + asi->insn[0] = insn; + asi->insn_handler = emulate_none; + return INSN_GOOD; + } - /* Coprocessor instructions... */ /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ - /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ - /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ - /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ - /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ - /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ + if ((insn & 0xffe00000) == 0xfc400000) { + insn &= 0xfff00fff; /* Rn = r0 */ + insn |= 0x00001000; /* Rd = r1 */ + asi->insn[0] = insn; + asi->insn_handler = + (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; + return INSN_GOOD; + } - return INSN_REJECTED; + /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ + /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ + if ((insn & 0xfe000000) == 0xfc000000) { + insn &= 0xfff0ffff; /* Rn = r0 */ + asi->insn[0] = insn; + asi->insn_handler = emulate_ldcstc; + return INSN_GOOD; + } + + /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ + /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ + insn &= 0xffff0fff; /* Rd = r0 */ + asi->insn[0] = insn; + asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12; + return INSN_GOOD; } static enum kprobe_insn __kprobes @@ -1013,18 +1010,19 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */ if ((insn & 0x0f900010) == 0x01000000) { - /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */ - if ((insn & 0x0ff000f0) == 0x01000000) { - if (is_r15(insn, 12)) - return INSN_REJECTED; /* Rd is PC */ - asi->insn_handler = simulate_mrs; - return INSN_GOOD_NO_SLOT; - } + /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ + /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ + if ((insn & 0x0ff000f0) == 0x01200020 || + (insn & 0x0fb000f0) == 0x01200000) + return INSN_REJECTED; + + /* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */ + if ((insn & 0x0fb00010) == 0x01000000) + return prep_emulate_rd12(insn, asi); /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ if ((insn & 0x0ff00090) == 0x01400080) - return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, - asi); + return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ @@ -1033,29 +1031,24 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) return prep_emulate_rd16rs8rm0_wflags(insn, asi); /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */ - /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */ - if ((insn & 0x0ff00090) == 0x01000080 || - (insn & 0x0ff000b0) == 0x01200080) - return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); - - /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ - /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ - /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */ + /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */ + return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); - /* Other instruction encodings aren't yet defined */ - return INSN_REJECTED; } /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */ else if ((insn & 0x0f900090) == 0x01000010) { + /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ + if ((insn & 0xfff000f0) == 0xe1200070) + return INSN_REJECTED; + /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ if ((insn & 0x0ff000d0) == 0x01200010) { - if ((insn & 0x0ff000ff) == 0x0120003f) - return INSN_REJECTED; /* BLX pc */ + asi->insn[0] = truecc_insn(insn); asi->insn_handler = simulate_blx2bx; - return INSN_GOOD_NO_SLOT; + return INSN_GOOD; } /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ @@ -1066,27 +1059,17 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */ /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */ /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */ - if ((insn & 0x0f9000f0) == 0x01000050) - return prep_emulate_rd12rn16rm0_wflags(insn, asi); - - /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ - /* SMC : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */ - - /* Other instruction encodings aren't yet defined */ - return INSN_REJECTED; + return prep_emulate_rd12rn16rm0_wflags(insn, asi); } /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */ - else if ((insn & 0x0f0000f0) == 0x00000090) { + else if ((insn & 0x0f000090) == 0x00000090) { /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */ /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */ /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */ /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */ /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */ - /* undef : cccc 0000 0101 xxxx xxxx xxxx 1001 xxxx : */ - /* MLS : cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx : */ - /* undef : cccc 0000 0111 xxxx xxxx xxxx 1001 xxxx : */ /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */ /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */ /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */ @@ -1095,15 +1078,13 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */ /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */ /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */ - if ((insn & 0x00d00000) == 0x00500000) - return INSN_REJECTED; - else if ((insn & 0x00e00000) == 0x00000000) - return prep_emulate_rd16rs8rm0_wflags(insn, asi); - else if ((insn & 0x00a00000) == 0x00200000) - return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); - else - return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, - asi); + if ((insn & 0x0fe000f0) == 0x00000090) { + return prep_emulate_rd16rs8rm0_wflags(insn, asi); + } else if ((insn & 0x0fe000f0) == 0x00200090) { + return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); + } else { + return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); + } } /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */ @@ -1111,45 +1092,23 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */ /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */ - /* ??? : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */ - /* ??? : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */ - /* ??? : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */ - /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */ - /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */ - /* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */ - /* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */ - /* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */ - /* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */ - /* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */ - /* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */ - /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */ /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */ + /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */ + /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */ /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */ /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */ /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */ /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */ - if ((insn & 0x0f0000f0) == 0x01000090) { - if ((insn & 0x0fb000f0) == 0x01000090) { - /* SWP/SWPB */ - return prep_emulate_rd12rn16rm0_wflags(insn, - asi); - } else { - /* STREX/LDREX variants and unallocaed space */ - return INSN_REJECTED; - } - + if ((insn & 0x0fb000f0) == 0x01000090) { + /* SWP/SWPB */ + return prep_emulate_rd12rn16rm0_wflags(insn, asi); } else if ((insn & 0x0e1000d0) == 0x00000d0) { /* STRD/LDRD */ - if ((insn & 0x0000e000) == 0x0000e000) - return INSN_REJECTED; /* Rd is LR or PC */ - if (is_writeback(insn) && is_r15(insn, 16)) - return INSN_REJECTED; /* Writeback to PC */ - insn &= 0xfff00fff; insn |= 0x00002000; /* Rn = r0, Rd = r2 */ - if (!(insn & (1 << 22))) { - /* Register index */ + if (insn & (1 << 22)) { + /* I bit */ insn &= ~0xf; insn |= 1; /* Rm = r1 */ } @@ -1159,9 +1118,6 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) return INSN_GOOD; } - /* LDRH/STRH/LDRSB/LDRSH */ - if (is_r15(insn, 12)) - return INSN_REJECTED; /* Rd is PC */ return prep_emulate_ldr_str(insn, asi); } @@ -1169,7 +1125,7 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) /* * ALU op with S bit and Rd == 15 : - * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx + * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */ if ((insn & 0x0e10f000) == 0x0010f000) return INSN_REJECTED; @@ -1198,61 +1154,22 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) insn |= 0x00000200; /* Rs = r2 */ } asi->insn[0] = insn; - - if ((insn & 0x0f900000) == 0x01100000) { - /* - * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx - * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx - * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx - * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx - */ - asi->insn_handler = emulate_alu_tests; - } else { - /* ALU ops which write to Rd */ - asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ + asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ emulate_alu_rwflags : emulate_alu_rflags; - } return INSN_GOOD; } static enum kprobe_insn __kprobes space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - /* MOVW : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ - /* MOVT : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ - if ((insn & 0x0fb00000) == 0x03000000) - return prep_emulate_rd12_modify(insn, asi); - - /* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ - if ((insn & 0x0fff0000) == 0x03200000) { - unsigned op2 = insn & 0x000000ff; - if (op2 == 0x01 || op2 == 0x04) { - /* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ - /* SEV : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ - asi->insn[0] = insn; - asi->insn_handler = emulate_none; - return INSN_GOOD; - } else if (op2 <= 0x03) { - /* NOP : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ - /* WFE : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ - /* WFI : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ - /* - * We make WFE and WFI true NOPs to avoid stalls due - * to missing events whilst processing the probe. - */ - asi->insn_handler = emulate_nop; - return INSN_GOOD_NO_SLOT; - } - /* For DBG and unallocated hints it's safest to reject them */ - return INSN_REJECTED; - } - /* * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx + * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx * ALU op with S bit and Rd == 15 : * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */ if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */ + (insn & 0x0ff00000) == 0x03400000 || /* Undef */ (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ return INSN_REJECTED; @@ -1263,22 +1180,10 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) * *S (bit 20) updates condition codes * ADC/SBC/RSC reads the C flag */ - insn &= 0xfff00fff; /* Rn = r0 and Rd = r0 */ + insn &= 0xffff0fff; /* Rd = r0 */ asi->insn[0] = insn; - - if ((insn & 0x0f900000) == 0x03100000) { - /* - * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx - * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx - * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx - * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx - */ - asi->insn_handler = emulate_alu_tests_imm; - } else { - /* ALU ops which write to Rd */ - asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ + asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ emulate_alu_imm_rwflags : emulate_alu_imm_rflags; - } return INSN_GOOD; } @@ -1287,8 +1192,6 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) { /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */ if ((insn & 0x0ff000f0) == 0x068000b0) { - if (is_r15(insn, 12)) - return INSN_REJECTED; /* Rd is PC */ insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ insn |= 0x00000001; /* Rm = r1 */ asi->insn[0] = insn; @@ -1302,8 +1205,6 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */ if ((insn & 0x0fa00030) == 0x06a00010 || (insn & 0x0fb000f0) == 0x06a00030) { - if (is_r15(insn, 12)) - return INSN_REJECTED; /* Rd is PC */ insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ asi->insn[0] = insn; asi->insn_handler = emulate_sat; @@ -1312,101 +1213,57 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */ /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */ - /* RBIT : cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */ /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */ if ((insn & 0x0ff00070) == 0x06b00030 || - (insn & 0x0ff00070) == 0x06f00030) + (insn & 0x0ff000f0) == 0x06f000b0) return prep_emulate_rd12rm0(insn, asi); - /* ??? : cccc 0110 0000 xxxx xxxx xxxx xxx1 xxxx : */ /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */ /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */ /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */ /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */ /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */ - /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1011 xxxx : */ - /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1101 xxxx : */ /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */ /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */ /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */ /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */ /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */ /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */ - /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1011 xxxx : */ - /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1101 xxxx : */ /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */ /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */ /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */ /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */ /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */ /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */ - /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1011 xxxx : */ - /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1101 xxxx : */ /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */ - /* ??? : cccc 0110 0100 xxxx xxxx xxxx xxx1 xxxx : */ /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */ /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */ /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */ /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */ /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */ - /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1011 xxxx : */ - /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1101 xxxx : */ /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */ /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */ /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */ /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */ /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */ /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */ - /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1011 xxxx : */ - /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1101 xxxx : */ /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */ /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */ /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */ /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */ /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */ /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */ - /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1011 xxxx : */ - /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1101 xxxx : */ /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */ - if ((insn & 0x0f800010) == 0x06000010) { - if ((insn & 0x00300000) == 0x00000000 || - (insn & 0x000000e0) == 0x000000a0 || - (insn & 0x000000e0) == 0x000000c0) - return INSN_REJECTED; /* Unallocated space */ - return prep_emulate_rd12rn16rm0_wflags(insn, asi); - } - /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */ /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */ - if ((insn & 0x0ff00030) == 0x06800010) - return prep_emulate_rd12rn16rm0_wflags(insn, asi); - /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */ - /* SXTB16 : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx : */ - /* ??? : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx : */ + /* SXTB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ - /* SXTB : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx : */ /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */ - /* SXTH : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx : */ /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */ - /* UXTB16 : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx : */ - /* ??? : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx : */ /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */ - /* UXTB : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx : */ /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */ - /* UXTH : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx : */ - if ((insn & 0x0f8000f0) == 0x06800070) { - if ((insn & 0x00300000) == 0x00100000) - return INSN_REJECTED; /* Unallocated space */ - - if ((insn & 0x000f0000) == 0x000f0000) - return prep_emulate_rd12rm0(insn, asi); - else - return prep_emulate_rd12rn16rm0_wflags(insn, asi); - } - - /* Other instruction encodings aren't yet defined */ - return INSN_REJECTED; + return prep_emulate_rd12rn16rm0_wflags(insn, asi); } static enum kprobe_insn __kprobes @@ -1416,49 +1273,29 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) if ((insn & 0x0ff000f0) == 0x03f000f0) return INSN_REJECTED; + /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */ + /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */ + if ((insn & 0x0ff000f0) == 0x07800010) + return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); + /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */ /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */ if ((insn & 0x0ff00090) == 0x07400010) return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */ - /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */ /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */ - /* SMUSD : cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx : */ /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */ - /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */ - /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx : */ - /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx : */ + /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ if ((insn & 0x0ff00090) == 0x07000010 || (insn & 0x0ff000d0) == 0x07500010 || - (insn & 0x0ff000f0) == 0x07800010) { - - if ((insn & 0x0000f000) == 0x0000f000) - return prep_emulate_rd16rs8rm0_wflags(insn, asi); - else - return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); - } - - /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ - if ((insn & 0x0ff000d0) == 0x075000d0) + (insn & 0x0ff000d0) == 0x075000d0) return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); - /* SBFX : cccc 0111 101x xxxx xxxx xxxx x101 xxxx : */ - /* UBFX : cccc 0111 111x xxxx xxxx xxxx x101 xxxx : */ - if ((insn & 0x0fa00070) == 0x07a00050) - return prep_emulate_rd12rm0(insn, asi); - - /* BFI : cccc 0111 110x xxxx xxxx xxxx x001 xxxx : */ - /* BFC : cccc 0111 110x xxxx xxxx xxxx x001 1111 : */ - if ((insn & 0x0fe00070) == 0x07c00010) { - - if ((insn & 0x0000000f) == 0x0000000f) - return prep_emulate_rd12_modify(insn, asi); - else - return prep_emulate_rd12rn0_modify(insn, asi); - } - - return INSN_REJECTED; + /* SMUSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx : */ + /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */ + /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */ + return prep_emulate_rd16rs8rm0_wflags(insn, asi); } static enum kprobe_insn __kprobes @@ -1472,10 +1309,6 @@ space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi) /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */ /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */ /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */ - - if ((insn & 0x00500000) == 0x00500000 && is_r15(insn, 12)) - return INSN_REJECTED; /* LDRB into PC */ - return prep_emulate_ldr_str(insn, asi); } @@ -1490,9 +1323,10 @@ space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi) /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ + asi->insn[0] = truecc_insn(insn); asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */ simulate_stm1_pc : simulate_ldm1stm1; - return INSN_GOOD_NO_SLOT; + return INSN_GOOD; } static enum kprobe_insn __kprobes @@ -1500,117 +1334,58 @@ space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi) { /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ + asi->insn[0] = truecc_insn(insn); asi->insn_handler = simulate_bbl; - return INSN_GOOD_NO_SLOT; + return INSN_GOOD; } static enum kprobe_insn __kprobes -space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi) +space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - /* Coprocessor instructions... */ /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ - /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ - /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ - /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ - /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ - /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ - - /* SVC : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ - - return INSN_REJECTED; -} - -static unsigned long __kprobes __check_eq(unsigned long cpsr) -{ - return cpsr & PSR_Z_BIT; -} - -static unsigned long __kprobes __check_ne(unsigned long cpsr) -{ - return (~cpsr) & PSR_Z_BIT; -} - -static unsigned long __kprobes __check_cs(unsigned long cpsr) -{ - return cpsr & PSR_C_BIT; -} - -static unsigned long __kprobes __check_cc(unsigned long cpsr) -{ - return (~cpsr) & PSR_C_BIT; -} - -static unsigned long __kprobes __check_mi(unsigned long cpsr) -{ - return cpsr & PSR_N_BIT; -} - -static unsigned long __kprobes __check_pl(unsigned long cpsr) -{ - return (~cpsr) & PSR_N_BIT; -} - -static unsigned long __kprobes __check_vs(unsigned long cpsr) -{ - return cpsr & PSR_V_BIT; -} - -static unsigned long __kprobes __check_vc(unsigned long cpsr) -{ - return (~cpsr) & PSR_V_BIT; -} - -static unsigned long __kprobes __check_hi(unsigned long cpsr) -{ - cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ - return cpsr & PSR_C_BIT; -} - -static unsigned long __kprobes __check_ls(unsigned long cpsr) -{ - cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ - return (~cpsr) & PSR_C_BIT; -} - -static unsigned long __kprobes __check_ge(unsigned long cpsr) -{ - cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ - return (~cpsr) & PSR_N_BIT; + insn &= 0xfff00fff; + insn |= 0x00001000; /* Rn = r0, Rd = r1 */ + asi->insn[0] = insn; + asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; + return INSN_GOOD; } -static unsigned long __kprobes __check_lt(unsigned long cpsr) +static enum kprobe_insn __kprobes +space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ - return cpsr & PSR_N_BIT; + /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ + /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ + insn &= 0xfff0ffff; /* Rn = r0 */ + asi->insn[0] = insn; + asi->insn_handler = emulate_ldcstc; + return INSN_GOOD; } -static unsigned long __kprobes __check_gt(unsigned long cpsr) +static enum kprobe_insn __kprobes +space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ - temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ - return (~temp) & PSR_N_BIT; -} + /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ + /* SWI : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ + if ((insn & 0xfff000f0) == 0xe1200070 || + (insn & 0x0f000000) == 0x0f000000) + return INSN_REJECTED; -static unsigned long __kprobes __check_le(unsigned long cpsr) -{ - unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ - temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ - return temp & PSR_N_BIT; -} + /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ + if ((insn & 0x0f000010) == 0x0e000000) { + asi->insn[0] = insn; + asi->insn_handler = emulate_none; + return INSN_GOOD; + } -static unsigned long __kprobes __check_al(unsigned long cpsr) -{ - return true; + /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ + /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ + insn &= 0xffff0fff; /* Rd = r0 */ + asi->insn[0] = insn; + asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12; + return INSN_GOOD; } -static kprobe_check_cc * const condition_checks[16] = { - &__check_eq, &__check_ne, &__check_cs, &__check_cc, - &__check_mi, &__check_pl, &__check_vs, &__check_vc, - &__check_hi, &__check_ls, &__check_ge, &__check_lt, - &__check_gt, &__check_le, &__check_al, &__check_al -}; - /* Return: * INSN_REJECTED If instruction is one not allowed to kprobe, * INSN_GOOD If instruction is supported and uses instruction slot, @@ -1626,45 +1401,133 @@ static kprobe_check_cc * const condition_checks[16] = { enum kprobe_insn __kprobes arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) { - asi->insn_check_cc = condition_checks[insn>>28]; asi->insn[1] = KPROBE_RETURN_INSTRUCTION; - if ((insn & 0xf0000000) == 0xf0000000) + if ((insn & 0xf0000000) == 0xf0000000) { return space_1111(insn, asi); - else if ((insn & 0x0e000000) == 0x00000000) + } else if ((insn & 0x0e000000) == 0x00000000) { return space_cccc_000x(insn, asi); - else if ((insn & 0x0e000000) == 0x02000000) + } else if ((insn & 0x0e000000) == 0x02000000) { return space_cccc_001x(insn, asi); - else if ((insn & 0x0f000010) == 0x06000010) + } else if ((insn & 0x0f000010) == 0x06000010) { return space_cccc_0110__1(insn, asi); - else if ((insn & 0x0f000010) == 0x07000010) + } else if ((insn & 0x0f000010) == 0x07000010) { return space_cccc_0111__1(insn, asi); - else if ((insn & 0x0c000000) == 0x04000000) + } else if ((insn & 0x0c000000) == 0x04000000) { return space_cccc_01xx(insn, asi); - else if ((insn & 0x0e000000) == 0x08000000) + } else if ((insn & 0x0e000000) == 0x08000000) { return space_cccc_100x(insn, asi); - else if ((insn & 0x0e000000) == 0x0a000000) + } else if ((insn & 0x0e000000) == 0x0a000000) { return space_cccc_101x(insn, asi); - return space_cccc_11xx(insn, asi); + } else if ((insn & 0x0fe00000) == 0x0c400000) { + + return space_cccc_1100_010x(insn, asi); + + } else if ((insn & 0x0e000000) == 0x0c000000) { + + return space_cccc_110x(insn, asi); + + } + + return space_cccc_111x(insn, asi); } void __init arm_kprobe_decode_init(void) { find_str_pc_offset(); } + + +/* + * All ARM instructions listed below. + * + * Instructions and their general purpose registers are given. + * If a particular register may not use R15, it is prefixed with a "!". + * If marked with a "*" means the value returned by reading R15 + * is implementation defined. + * + * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ + * TST: Rd, Rn, Rm, !Rs + * BX: Rm + * BLX(2): !Rm + * BX: Rm (R15 legal, but discouraged) + * BXJ: !Rm, + * CLZ: !Rd, !Rm + * CPY: Rd, Rm + * LDC/2,STC/2 immediate offset & unindex: Rn + * LDC/2,STC/2 immediate pre/post-indexed: !Rn + * LDM(1/3): !Rn, register_list + * LDM(2): !Rn, !register_list + * LDR,STR,PLD immediate offset: Rd, Rn + * LDR,STR,PLD register offset: Rd, Rn, !Rm + * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm + * LDR,STR immediate pre/post-indexed: Rd, !Rn + * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm + * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm + * LDRB,STRB immediate offset: !Rd, Rn + * LDRB,STRB register offset: !Rd, Rn, !Rm + * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm + * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn + * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm + * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm + * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn + * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm + * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm + * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn + * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm + * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn + * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm + * LDREX: !Rd, !Rn + * MCR/2: !Rd + * MCRR/2,MRRC/2: !Rd, !Rn + * MLA: !Rd, !Rn, !Rm, !Rs + * MOV: Rd + * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register) + * MRS,MSR: !Rd + * MUL: !Rd, !Rm, !Rs + * PKH{BT,TB}: !Rd, !Rn, !Rm + * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn + * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn + * REV/16/SH: !Rd, !Rm + * RFE: !Rn + * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm + * SEL: !Rd, !Rn, !Rm + * SMLA,SMLA{D,W},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs + * SMLAL,SMLA{D,LD},SMLSLD,SMMULL,SMULW: !RdHi, !RdLo, !Rm, !Rs + * SMMUL,SMUAD,SMUL,SMUSD: !Rd, !Rm, !Rs + * SSAT/16: !Rd, !Rm + * STM(1/2): !Rn, register_list* (R15 in reg list not recommended) + * STRT immediate pre/post-indexed: Rd*, !Rn + * STRT register pre/post-indexed: Rd*, !Rn, !Rm + * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm + * STREX: !Rd, !Rn, !Rm + * SWP/B: !Rd, !Rn, !Rm + * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm + * {S,U}XT{B,B16,H}: !Rd, !Rm + * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs + * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs + * + * May transfer control by writing R15 (possible mode changes or alternate + * mode accesses marked by "*"): + * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY, + * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI* + * + * Instructions that do not take general registers, nor transfer control: + * CDP/2, SETEND, SRS* + */ diff --git a/trunk/arch/arm/kernel/kprobes.c b/trunk/arch/arm/kernel/kprobes.c index 1656c87501c0..2ba7deb3072e 100644 --- a/trunk/arch/arm/kernel/kprobes.c +++ b/trunk/arch/arm/kernel/kprobes.c @@ -134,8 +134,7 @@ static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { regs->ARM_pc += 4; - if (p->ainsn.insn_check_cc(regs->ARM_cpsr)) - p->ainsn.insn_handler(p, regs); + p->ainsn.insn_handler(p, regs); } /* diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index 139e3c827369..979da3947f42 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -746,8 +746,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) tail = (struct frame_tail __user *)regs->ARM_fp - 1; - while ((entry->nr < PERF_MAX_STACK_DEPTH) && - tail && !((unsigned long)tail & 0x3)) + while (tail && !((unsigned long)tail & 0x3)) tail = user_backtrace(tail, entry); } diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index f29b8a29b174..8fe05ad932e4 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -479,7 +479,7 @@ static void broadcast_timer_set_mode(enum clock_event_mode mode, { } -static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt) +static void broadcast_timer_setup(struct clock_event_device *evt) { evt->name = "dummy_timer"; evt->features = CLOCK_EVT_FEAT_ONESHOT | diff --git a/trunk/arch/arm/kernel/sys_oabi-compat.c b/trunk/arch/arm/kernel/sys_oabi-compat.c index af0aaebf4de6..4ad8da15ef2b 100644 --- a/trunk/arch/arm/kernel/sys_oabi-compat.c +++ b/trunk/arch/arm/kernel/sys_oabi-compat.c @@ -311,7 +311,7 @@ asmlinkage long sys_oabi_semtimedop(int semid, long err; int i; - if (nsops < 1 || nsops > SEMOPM) + if (nsops < 1) return -EINVAL; sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL); if (!sops) diff --git a/trunk/arch/arm/mach-davinci/Kconfig b/trunk/arch/arm/mach-davinci/Kconfig index c0deacae778d..32f147998cd9 100644 --- a/trunk/arch/arm/mach-davinci/Kconfig +++ b/trunk/arch/arm/mach-davinci/Kconfig @@ -63,7 +63,6 @@ config MACH_DAVINCI_EVM depends on ARCH_DAVINCI_DM644x select MISC_DEVICES select EEPROM_AT24 - select I2C help Configure this option to specify the whether the board used for development is a DM644x EVM @@ -73,7 +72,6 @@ config MACH_SFFSDR depends on ARCH_DAVINCI_DM644x select MISC_DEVICES select EEPROM_AT24 - select I2C help Say Y here to select the Lyrtech Small Form Factor Software Defined Radio (SFFSDR) board. @@ -107,7 +105,6 @@ config MACH_DAVINCI_DM6467_EVM select MACH_DAVINCI_DM6467TEVM select MISC_DEVICES select EEPROM_AT24 - select I2C help Configure this option to specify the whether the board used for development is a DM6467 EVM @@ -121,7 +118,6 @@ config MACH_DAVINCI_DM365_EVM depends on ARCH_DAVINCI_DM365 select MISC_DEVICES select EEPROM_AT24 - select I2C help Configure this option to specify whether the board used for development is a DM365 EVM @@ -133,7 +129,6 @@ config MACH_DAVINCI_DA830_EVM select GPIO_PCF857X select MISC_DEVICES select EEPROM_AT24 - select I2C help Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module. @@ -210,7 +205,6 @@ config MACH_MITYOMAPL138 depends on ARCH_DAVINCI_DA850 select MISC_DEVICES select EEPROM_AT24 - select I2C help Say Y here to select the Critical Link MityDSP-L138/MityARM-1808 System on Module. Information on this SoM may be found at diff --git a/trunk/arch/arm/mach-davinci/board-mityomapl138.c b/trunk/arch/arm/mach-davinci/board-mityomapl138.c index 606a6f27ed6c..2aa79c54f98e 100644 --- a/trunk/arch/arm/mach-davinci/board-mityomapl138.c +++ b/trunk/arch/arm/mach-davinci/board-mityomapl138.c @@ -29,7 +29,7 @@ #include #include -#define MITYOMAPL138_PHY_ID "" +#define MITYOMAPL138_PHY_ID "0:03" #define FACTORY_CONFIG_MAGIC 0x012C0138 #define FACTORY_CONFIG_VERSION 0x00010001 @@ -414,7 +414,7 @@ static struct resource mityomapl138_nandflash_resource[] = { static struct platform_device mityomapl138_nandflash_device = { .name = "davinci_nand", - .id = 1, + .id = 0, .dev = { .platform_data = &mityomapl138_nandflash_data, }, diff --git a/trunk/arch/arm/mach-davinci/devices-da8xx.c b/trunk/arch/arm/mach-davinci/devices-da8xx.c index 58a02dc7b15a..625d4b66718b 100644 --- a/trunk/arch/arm/mach-davinci/devices-da8xx.c +++ b/trunk/arch/arm/mach-davinci/devices-da8xx.c @@ -39,8 +39,7 @@ #define DA8XX_GPIO_BASE 0x01e26000 #define DA8XX_I2C1_BASE 0x01e28000 #define DA8XX_SPI0_BASE 0x01c41000 -#define DA830_SPI1_BASE 0x01e12000 -#define DA850_SPI1_BASE 0x01f0e000 +#define DA8XX_SPI1_BASE 0x01f0e000 #define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000 #define DA8XX_EMAC_MOD_REG_OFFSET 0x2000 @@ -763,8 +762,8 @@ static struct resource da8xx_spi0_resources[] = { static struct resource da8xx_spi1_resources[] = { [0] = { - .start = DA830_SPI1_BASE, - .end = DA830_SPI1_BASE + SZ_4K - 1, + .start = DA8XX_SPI1_BASE, + .end = DA8XX_SPI1_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -833,10 +832,5 @@ int __init da8xx_register_spi(int instance, struct spi_board_info *info, da8xx_spi_pdata[instance].num_chipselect = len; - if (instance == 1 && cpu_is_davinci_da850()) { - da8xx_spi1_resources[0].start = DA850_SPI1_BASE; - da8xx_spi1_resources[0].end = DA850_SPI1_BASE + SZ_4K - 1; - } - return platform_device_register(&da8xx_spi_device[instance]); } diff --git a/trunk/arch/arm/mach-davinci/dm355.c b/trunk/arch/arm/mach-davinci/dm355.c index a3a94e9c9378..f68012239641 100644 --- a/trunk/arch/arm/mach-davinci/dm355.c +++ b/trunk/arch/arm/mach-davinci/dm355.c @@ -314,7 +314,7 @@ static struct clk timer2_clk = { .name = "timer2", .parent = &pll1_aux_clk, .lpsc = DAVINCI_LPSC_TIMER2, - .usecount = 1, /* REVISIT: why can't this be disabled? */ + .usecount = 1, /* REVISIT: why can't' this be disabled? */ }; static struct clk timer3_clk = { diff --git a/trunk/arch/arm/mach-davinci/dm644x.c b/trunk/arch/arm/mach-davinci/dm644x.c index 4c82c2716293..5f8a65424184 100644 --- a/trunk/arch/arm/mach-davinci/dm644x.c +++ b/trunk/arch/arm/mach-davinci/dm644x.c @@ -274,7 +274,7 @@ static struct clk timer2_clk = { .name = "timer2", .parent = &pll1_aux_clk, .lpsc = DAVINCI_LPSC_TIMER2, - .usecount = 1, /* REVISIT: why can't this be disabled? */ + .usecount = 1, /* REVISIT: why can't' this be disabled? */ }; static struct clk_lookup dm644x_clks[] = { diff --git a/trunk/arch/arm/mach-davinci/include/mach/debug-macro.S b/trunk/arch/arm/mach-davinci/include/mach/debug-macro.S index f8b7ea4f6235..9f1befc5ac38 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-davinci/include/mach/debug-macro.S @@ -24,9 +24,6 @@ #define UART_SHIFT 2 -#define davinci_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) -#define davinci_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) - .pushsection .data davinci_uart_phys: .word 0 davinci_uart_virt: .word 0 @@ -37,7 +34,7 @@ davinci_uart_virt: .word 0 /* Use davinci_uart_phys/virt if already configured */ 10: mrc p15, 0, \rp, c1, c0 tst \rp, #1 @ MMU enabled? - ldreq \rp, =davinci_uart_v2p(davinci_uart_phys) + ldreq \rp, =__virt_to_phys(davinci_uart_phys) ldrne \rp, =davinci_uart_phys add \rv, \rp, #4 @ davinci_uart_virt ldr \rp, [\rp, #0] @@ -51,18 +48,18 @@ davinci_uart_virt: .word 0 tst \rp, #1 @ MMU enabled? /* Copy uart phys address from decompressor uart info */ - ldreq \rv, =davinci_uart_v2p(davinci_uart_phys) + ldreq \rv, =__virt_to_phys(davinci_uart_phys) ldrne \rv, =davinci_uart_phys ldreq \rp, =DAVINCI_UART_INFO - ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO) + ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO) ldr \rp, [\rp, #0] str \rp, [\rv] /* Copy uart virt address from decompressor uart info */ - ldreq \rv, =davinci_uart_v2p(davinci_uart_virt) + ldreq \rv, =__virt_to_phys(davinci_uart_virt) ldrne \rv, =davinci_uart_virt ldreq \rp, =DAVINCI_UART_INFO - ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO) + ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO) ldr \rp, [\rp, #4] str \rp, [\rv] diff --git a/trunk/arch/arm/mach-davinci/include/mach/serial.h b/trunk/arch/arm/mach-davinci/include/mach/serial.h index c9e6ce185a66..8051110b8ac3 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/serial.h +++ b/trunk/arch/arm/mach-davinci/include/mach/serial.h @@ -22,7 +22,7 @@ * * This area sits just below the page tables (see arch/arm/kernel/head.S). */ -#define DAVINCI_UART_INFO (PLAT_PHYS_OFFSET + 0x3ff8) +#define DAVINCI_UART_INFO (PHYS_OFFSET + 0x3ff8) #define DAVINCI_UART0_BASE (IO_PHYS + 0x20000) #define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) diff --git a/trunk/arch/arm/mach-mx3/mach-vpr200.c b/trunk/arch/arm/mach-mx3/mach-vpr200.c index 47a69cbc31a8..2cf390fbd980 100644 --- a/trunk/arch/arm/mach-mx3/mach-vpr200.c +++ b/trunk/arch/arm/mach-mx3/mach-vpr200.c @@ -257,16 +257,11 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { .workaround = FLS_USB2_WORKAROUND_ENGCM09152, }; -static int vpr200_usbh_init(struct platform_device *pdev) -{ - return mx35_initialize_usb_hw(pdev->id, - MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY); -} - /* USB HOST config */ static const struct mxc_usbh_platform_data usb_host_pdata __initconst = { - .init = vpr200_usbh_init, - .portsc = MXC_EHCI_MODE_SERIAL, + .portsc = MXC_EHCI_MODE_SERIAL, + .flags = MXC_EHCI_INTERFACE_SINGLE_UNI | + MXC_EHCI_INTERNAL_PHY, }; static struct platform_device *devices[] __initdata = { diff --git a/trunk/arch/arm/mach-mx5/board-mx53_loco.c b/trunk/arch/arm/mach-mx5/board-mx53_loco.c index 6206b1191fe8..10a1bea10548 100644 --- a/trunk/arch/arm/mach-mx5/board-mx53_loco.c +++ b/trunk/arch/arm/mach-mx5/board-mx53_loco.c @@ -193,7 +193,7 @@ static iomux_v3_cfg_t mx53_loco_pads[] = { .wakeup = wake, \ } -static struct gpio_keys_button loco_buttons[] = { +static const struct gpio_keys_button loco_buttons[] __initconst = { GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0), GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0), GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0), diff --git a/trunk/arch/arm/mach-mxs/clock-mx28.c b/trunk/arch/arm/mach-mxs/clock-mx28.c index 5dcc59d5b9ec..1ad97fed1e94 100644 --- a/trunk/arch/arm/mach-mxs/clock-mx28.c +++ b/trunk/arch/arm/mach-mxs/clock-mx28.c @@ -295,11 +295,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ unsigned long diff, parent_rate, calc_rate; \ int i; \ \ + parent_rate = clk_get_rate(clk->parent); \ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ bm_busy = BM_CLKCTRL_##dr##_BUSY; \ \ if (clk->parent == &ref_xtal_clk) { \ - parent_rate = clk_get_rate(clk->parent); \ div = DIV_ROUND_UP(parent_rate, rate); \ if (clk == &cpu_clk) { \ div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \ @@ -309,11 +309,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ if (div == 0 || div > div_max) \ return -EINVAL; \ } else { \ - /* \ - * hack alert: this block modifies clk->parent, too, \ - * so the base to use it the grand parent. \ - */ \ - parent_rate = clk_get_rate(clk->parent->parent); \ rate >>= PARENT_RATE_SHIFT; \ parent_rate >>= PARENT_RATE_SHIFT; \ diff = parent_rate; \ diff --git a/trunk/arch/arm/mach-omap2/Makefile b/trunk/arch/arm/mach-omap2/Makefile index 512b15204450..a45cd6409686 100644 --- a/trunk/arch/arm/mach-omap2/Makefile +++ b/trunk/arch/arm/mach-omap2/Makefile @@ -68,7 +68,7 @@ obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 -AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) +AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a ifeq ($(CONFIG_PM_VERBOSE),y) CFLAGS_pm_bus.o += -DDEBUG diff --git a/trunk/arch/arm/mach-omap2/board-rx51.c b/trunk/arch/arm/mach-omap2/board-rx51.c index f8ba20a14e62..e964895b80e8 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51.c +++ b/trunk/arch/arm/mach-omap2/board-rx51.c @@ -141,19 +141,14 @@ static void __init rx51_init(void) static void __init rx51_map_io(void) { omap2_set_globals_3xxx(); - omap34xx_map_common_io(); -} - -static void __init rx51_reserve(void) -{ rx51_video_mem_init(); - omap_reserve(); + omap34xx_map_common_io(); } MACHINE_START(NOKIA_RX51, "Nokia RX-51 board") /* Maintainer: Lauri Leukkunen */ .boot_params = 0x80000100, - .reserve = rx51_reserve, + .reserve = omap_reserve, .map_io = rx51_map_io, .init_early = rx51_init_early, .init_irq = omap_init_irq, diff --git a/trunk/arch/arm/mach-omap2/clock44xx_data.c b/trunk/arch/arm/mach-omap2/clock44xx_data.c index 8c965671b4d4..276992d3b7fb 100644 --- a/trunk/arch/arm/mach-omap2/clock44xx_data.c +++ b/trunk/arch/arm/mach-omap2/clock44xx_data.c @@ -3116,9 +3116,14 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "dsp_fck", &dsp_fck, CK_443X), CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X), CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X), + CLK("omapdss_dss", "dss_clk", &dss_dss_clk, CK_443X), CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X), - CLK("omapdss_dss", "fck", &dss_dss_clk, CK_443X), - CLK("omapdss_dss", "ick", &dss_fck, CK_443X), + CLK("omapdss_dss", "fck", &dss_fck, CK_443X), + /* + * On OMAP4, DSS ick is a dummy clock; this is needed for compatibility + * with OMAP2/3. + */ + CLK("omapdss_dss", "ick", &dummy_ck, CK_443X), CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X), CLK(NULL, "emif1_fck", &emif1_fck, CK_443X), CLK(NULL, "emif2_fck", &emif2_fck, CK_443X), diff --git a/trunk/arch/arm/mach-omap2/cm2xxx_3xxx.c b/trunk/arch/arm/mach-omap2/cm2xxx_3xxx.c index 38830d8d4783..9d0dec806e92 100644 --- a/trunk/arch/arm/mach-omap2/cm2xxx_3xxx.c +++ b/trunk/arch/arm/mach-omap2/cm2xxx_3xxx.c @@ -247,7 +247,6 @@ struct omap3_cm_regs { u32 per_cm_clksel; u32 emu_cm_clksel; u32 emu_cm_clkstctrl; - u32 pll_cm_autoidle; u32 pll_cm_autoidle2; u32 pll_cm_clksel4; u32 pll_cm_clksel5; @@ -320,15 +319,6 @@ void omap3_cm_save_context(void) omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1); cm_context.emu_cm_clkstctrl = omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL); - /* - * As per erratum i671, ROM code does not respect the PER DPLL - * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1. - * In this case, even though this register has been saved in - * scratchpad contents, we need to restore AUTO_PERIPH_DPLL - * by ourselves. So, we need to save it anyway. - */ - cm_context.pll_cm_autoidle = - omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); cm_context.pll_cm_autoidle2 = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2); cm_context.pll_cm_clksel4 = @@ -451,13 +441,6 @@ void omap3_cm_restore_context(void) CM_CLKSEL1); omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL); - /* - * As per erratum i671, ROM code does not respect the PER DPLL - * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1. - * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves. - */ - omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD, - CM_AUTOIDLE); omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD, CM_AUTOIDLE2); omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD, diff --git a/trunk/arch/arm/mach-omap2/control.c b/trunk/arch/arm/mach-omap2/control.c index da53ba3917ca..695279419020 100644 --- a/trunk/arch/arm/mach-omap2/control.c +++ b/trunk/arch/arm/mach-omap2/control.c @@ -316,14 +316,8 @@ void omap3_save_scratchpad_contents(void) omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); prcm_block_contents.cm_clken_pll = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); - /* - * As per erratum i671, ROM code does not respect the PER DPLL - * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1. - * Then, in anycase, clear these bits to avoid extra latencies. - */ prcm_block_contents.cm_autoidle_pll = - omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) & - ~OMAP3430_AUTO_PERIPH_DPLL_MASK; + omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL); prcm_block_contents.cm_clksel1_pll = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL); prcm_block_contents.cm_clksel2_pll = diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c index c4d0ae87d62a..8eb3ce1bbfbe 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -1639,7 +1639,6 @@ static struct omap_hwmod_ocp_if *omap2420_gpio1_slaves[] = { static struct omap_hwmod omap2420_gpio1_hwmod = { .name = "gpio1", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap242x_gpio1_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio1_irqs), .main_clk = "gpios_fck", @@ -1670,7 +1669,6 @@ static struct omap_hwmod_ocp_if *omap2420_gpio2_slaves[] = { static struct omap_hwmod omap2420_gpio2_hwmod = { .name = "gpio2", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap242x_gpio2_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio2_irqs), .main_clk = "gpios_fck", @@ -1701,7 +1699,6 @@ static struct omap_hwmod_ocp_if *omap2420_gpio3_slaves[] = { static struct omap_hwmod omap2420_gpio3_hwmod = { .name = "gpio3", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap242x_gpio3_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio3_irqs), .main_clk = "gpios_fck", @@ -1732,7 +1729,6 @@ static struct omap_hwmod_ocp_if *omap2420_gpio4_slaves[] = { static struct omap_hwmod omap2420_gpio4_hwmod = { .name = "gpio4", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap242x_gpio4_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio4_irqs), .main_clk = "gpios_fck", @@ -1786,7 +1782,7 @@ static struct omap_hwmod_irq_info omap2420_dma_system_irqs[] = { static struct omap_hwmod_addr_space omap2420_dma_system_addrs[] = { { .pa_start = 0x48056000, - .pa_end = 0x48056fff, + .pa_end = 0x4a0560ff, .flags = ADDR_TYPE_RT }, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 9682dd519f8d..e6e3810db77f 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -1742,7 +1742,6 @@ static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = { static struct omap_hwmod omap2430_gpio1_hwmod = { .name = "gpio1", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap243x_gpio1_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio1_irqs), .main_clk = "gpios_fck", @@ -1773,7 +1772,6 @@ static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = { static struct omap_hwmod omap2430_gpio2_hwmod = { .name = "gpio2", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap243x_gpio2_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio2_irqs), .main_clk = "gpios_fck", @@ -1804,7 +1802,6 @@ static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = { static struct omap_hwmod omap2430_gpio3_hwmod = { .name = "gpio3", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap243x_gpio3_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio3_irqs), .main_clk = "gpios_fck", @@ -1835,7 +1832,6 @@ static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = { static struct omap_hwmod omap2430_gpio4_hwmod = { .name = "gpio4", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap243x_gpio4_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio4_irqs), .main_clk = "gpios_fck", @@ -1866,7 +1862,6 @@ static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = { static struct omap_hwmod omap2430_gpio5_hwmod = { .name = "gpio5", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap243x_gpio5_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio5_irqs), .main_clk = "gpio5_fck", @@ -1920,7 +1915,7 @@ static struct omap_hwmod_irq_info omap2430_dma_system_irqs[] = { static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = { { .pa_start = 0x48056000, - .pa_end = 0x48056fff, + .pa_end = 0x4a0560ff, .flags = ADDR_TYPE_RT }, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 909a84de6682..b98e2dfcba28 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -2141,7 +2141,6 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio1_slaves[] = { static struct omap_hwmod omap3xxx_gpio1_hwmod = { .name = "gpio1", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap3xxx_gpio1_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio1_irqs), .main_clk = "gpio1_ick", @@ -2178,7 +2177,6 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio2_slaves[] = { static struct omap_hwmod omap3xxx_gpio2_hwmod = { .name = "gpio2", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap3xxx_gpio2_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio2_irqs), .main_clk = "gpio2_ick", @@ -2215,7 +2213,6 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio3_slaves[] = { static struct omap_hwmod omap3xxx_gpio3_hwmod = { .name = "gpio3", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap3xxx_gpio3_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio3_irqs), .main_clk = "gpio3_ick", @@ -2252,7 +2249,6 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio4_slaves[] = { static struct omap_hwmod omap3xxx_gpio4_hwmod = { .name = "gpio4", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap3xxx_gpio4_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio4_irqs), .main_clk = "gpio4_ick", @@ -2289,7 +2285,6 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio5_slaves[] = { static struct omap_hwmod omap3xxx_gpio5_hwmod = { .name = "gpio5", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap3xxx_gpio5_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio5_irqs), .main_clk = "gpio5_ick", @@ -2326,7 +2321,6 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio6_slaves[] = { static struct omap_hwmod omap3xxx_gpio6_hwmod = { .name = "gpio6", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap3xxx_gpio6_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio6_irqs), .main_clk = "gpio6_ick", @@ -2392,7 +2386,7 @@ static struct omap_hwmod_irq_info omap3xxx_dma_system_irqs[] = { static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = { { .pa_start = 0x48056000, - .pa_end = 0x48056fff, + .pa_end = 0x4a0560ff, .flags = ADDR_TYPE_RT }, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index abc548a0c98d..3e88dd3f8ef3 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -885,7 +885,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dma_system_masters[] = { static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = { { .pa_start = 0x4a056000, - .pa_end = 0x4a056fff, + .pa_end = 0x4a0560ff, .flags = ADDR_TYPE_RT }, }; diff --git a/trunk/arch/arm/mach-omap2/omap_l3_smx.c b/trunk/arch/arm/mach-omap2/omap_l3_smx.c index 4321e7938929..5f2da7565b68 100644 --- a/trunk/arch/arm/mach-omap2/omap_l3_smx.c +++ b/trunk/arch/arm/mach-omap2/omap_l3_smx.c @@ -196,11 +196,11 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) /* No timeout error for debug sources */ } + base = ((l3->rt) + (*(omap3_l3_bases[int_type] + err_source))); + /* identify the error source */ for (err_source = 0; !(status & (1 << err_source)); err_source++) ; - - base = l3->rt + *(omap3_l3_bases[int_type] + err_source); error = omap3_l3_readll(base, L3_ERROR_LOG); if (error) { diff --git a/trunk/arch/arm/mach-omap2/pm.c b/trunk/arch/arm/mach-omap2/pm.c index 49486f522dca..30af3351c2d6 100644 --- a/trunk/arch/arm/mach-omap2/pm.c +++ b/trunk/arch/arm/mach-omap2/pm.c @@ -89,7 +89,6 @@ static void omap2_init_processor_devices(void) if (cpu_is_omap44xx()) { _init_omap_device("l3_main_1", &l3_dev); _init_omap_device("dsp", &dsp_dev); - _init_omap_device("iva", &iva_dev); } else { _init_omap_device("l3_main", &l3_dev); } diff --git a/trunk/arch/arm/mach-omap2/voltage.c b/trunk/arch/arm/mach-omap2/voltage.c index 0c1552d9d995..6fb520999b6e 100644 --- a/trunk/arch/arm/mach-omap2/voltage.c +++ b/trunk/arch/arm/mach-omap2/voltage.c @@ -114,6 +114,7 @@ static int __init _config_common_vdd_data(struct omap_vdd_info *vdd) sys_clk_speed /= 1000; /* Generic voltage parameters */ + vdd->curr_volt = 1200000; vdd->volt_scale = vp_forceupdate_scale_voltage; vdd->vp_enabled = false; diff --git a/trunk/arch/arm/mach-pxa/hx4700.c b/trunk/arch/arm/mach-pxa/hx4700.c index 9cdcca597924..6de0ad0eea65 100644 --- a/trunk/arch/arm/mach-pxa/hx4700.c +++ b/trunk/arch/arm/mach-pxa/hx4700.c @@ -711,7 +711,7 @@ static struct regulator_consumer_supply bq24022_consumers[] = { static struct regulator_init_data bq24022_init_data = { .constraints = { .max_uA = 500000, - .valid_ops_mask = REGULATOR_CHANGE_CURRENT|REGULATOR_CHANGE_STATUS, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT, }, .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), .consumer_supplies = bq24022_consumers, diff --git a/trunk/arch/arm/mach-pxa/magician.c b/trunk/arch/arm/mach-pxa/magician.c index 9984ef70bd79..a72993dde2b3 100644 --- a/trunk/arch/arm/mach-pxa/magician.c +++ b/trunk/arch/arm/mach-pxa/magician.c @@ -599,7 +599,7 @@ static struct regulator_consumer_supply bq24022_consumers[] = { static struct regulator_init_data bq24022_init_data = { .constraints = { .max_uA = 500000, - .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT, }, .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), .consumer_supplies = bq24022_consumers, diff --git a/trunk/arch/arm/mm/proc-xscale.S b/trunk/arch/arm/mm/proc-xscale.S index 42af97664c9d..ce233bcbf506 100644 --- a/trunk/arch/arm/mm/proc-xscale.S +++ b/trunk/arch/arm/mm/proc-xscale.S @@ -395,7 +395,7 @@ ENTRY(xscale_dma_a0_map_area) teq r2, #DMA_TO_DEVICE beq xscale_dma_clean_range b xscale_dma_flush_range -ENDPROC(xscale_dma_a0_map_area) +ENDPROC(xscsale_dma_a0_map_area) /* * dma_unmap_area(start, size, dir) diff --git a/trunk/arch/arm/plat-mxc/gpio.c b/trunk/arch/arm/plat-mxc/gpio.c index 6cd6d7f686f6..7a107246fd98 100644 --- a/trunk/arch/arm/plat-mxc/gpio.c +++ b/trunk/arch/arm/plat-mxc/gpio.c @@ -295,12 +295,6 @@ static int mxc_gpio_direction_output(struct gpio_chip *chip, return 0; } -/* - * This lock class tells lockdep that GPIO irqs are in a different - * category than their parents, so it won't report false recursion. - */ -static struct lock_class_key gpio_lock_class; - int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) { int i, j; @@ -317,7 +311,6 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) __raw_writel(~0, port[i].base + GPIO_ISR); for (j = port[i].virtual_irq_start; j < port[i].virtual_irq_start + 32; j++) { - irq_set_lockdep_class(j, &gpio_lock_class); irq_set_chip_and_handler(j, &gpio_irq_chip, handle_level_irq); set_irq_flags(j, IRQF_VALID); diff --git a/trunk/arch/arm/plat-mxc/ssi-fiq.S b/trunk/arch/arm/plat-mxc/ssi-fiq.S index 8397a2dd19f2..4ddce565b353 100644 --- a/trunk/arch/arm/plat-mxc/ssi-fiq.S +++ b/trunk/arch/arm/plat-mxc/ssi-fiq.S @@ -124,8 +124,6 @@ imx_ssi_fiq_start: 1: @ return from FIQ subs pc, lr, #4 - - .align imx_ssi_fiq_base: .word 0x0 imx_ssi_fiq_rx_buffer: diff --git a/trunk/arch/m68k/mm/motorola.c b/trunk/arch/m68k/mm/motorola.c index 8b3db1c587fc..02b7a03e4226 100644 --- a/trunk/arch/m68k/mm/motorola.c +++ b/trunk/arch/m68k/mm/motorola.c @@ -300,8 +300,6 @@ void __init paging_init(void) zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT; free_area_init_node(i, zones_size, m68k_memory[i].addr >> PAGE_SHIFT, NULL); - if (node_present_pages(i)) - node_set_state(i, N_NORMAL_MEMORY); } } diff --git a/trunk/arch/parisc/mm/init.c b/trunk/arch/parisc/mm/init.c index b1d126258dee..b7ed8d7a9b33 100644 --- a/trunk/arch/parisc/mm/init.c +++ b/trunk/arch/parisc/mm/init.c @@ -266,10 +266,8 @@ static void __init setup_bootmem(void) } memset(pfnnid_map, 0xff, sizeof(pfnnid_map)); - for (i = 0; i < npmem_ranges; i++) { - node_set_state(i, N_NORMAL_MEMORY); + for (i = 0; i < npmem_ranges; i++) node_set_online(i); - } #endif /* diff --git a/trunk/arch/powerpc/include/asm/8xx_immap.h b/trunk/arch/powerpc/include/asm/8xx_immap.h index bdf0563ba423..6b6dc20b0beb 100644 --- a/trunk/arch/powerpc/include/asm/8xx_immap.h +++ b/trunk/arch/powerpc/include/asm/8xx_immap.h @@ -393,8 +393,8 @@ typedef struct fec { uint fec_addr_low; /* lower 32 bits of station address */ ushort fec_addr_high; /* upper 16 bits of station address */ ushort res1; /* reserved */ - uint fec_grp_hash_table_high; /* upper 32-bits of hash table */ - uint fec_grp_hash_table_low; /* lower 32-bits of hash table */ + uint fec_hash_table_high; /* upper 32-bits of hash table */ + uint fec_hash_table_low; /* lower 32-bits of hash table */ uint fec_r_des_start; /* beginning of Rx descriptor ring */ uint fec_x_des_start; /* beginning of Tx descriptor ring */ uint fec_r_buff_size; /* Rx buffer size */ diff --git a/trunk/arch/powerpc/include/asm/uninorth.h b/trunk/arch/powerpc/include/asm/uninorth.h index d12b11d7641e..ae9c899c8a6d 100644 --- a/trunk/arch/powerpc/include/asm/uninorth.h +++ b/trunk/arch/powerpc/include/asm/uninorth.h @@ -60,7 +60,7 @@ * * Obviously, the GART is not cache coherent and so any change to it * must be flushed to memory (or maybe just make the GART space non - * cachable). AGP memory itself doesn't seem to be cache coherent neither. + * cachable). AGP memory itself does't seem to be cache coherent neither. * * In order to invalidate the GART (which is probably necessary to inval * the bridge internal TLBs), the following sequence has to be written, diff --git a/trunk/arch/s390/crypto/prng.c b/trunk/arch/s390/crypto/prng.c index 8b16c479585b..44bca3f994b0 100644 --- a/trunk/arch/s390/crypto/prng.c +++ b/trunk/arch/s390/crypto/prng.c @@ -76,7 +76,7 @@ static void prng_seed(int nbytes) /* Add the entropy */ while (nbytes >= 8) { - *((__u64 *)parm_block) ^= *((__u64 *)(buf+i)); + *((__u64 *)parm_block) ^= *((__u64 *)buf+i); prng_add_entropy(); i += 8; nbytes -= 8; diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index ab988135e5c6..4cf85fef407c 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -543,6 +543,7 @@ static void pfault_interrupt(unsigned int ext_int_code, struct task_struct *tsk; __u16 subcode; + kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; /* * Get the external interruption subcode & pfault * initial/completion signal bit. VM stores this @@ -552,7 +553,6 @@ static void pfault_interrupt(unsigned int ext_int_code, subcode = ext_int_code >> 16; if ((subcode & 0xff00) != __SUBCODE_MASK) return; - kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; /* * Get the token (= address of the task structure of the affected task). diff --git a/trunk/arch/um/Kconfig.um b/trunk/arch/um/Kconfig.um index b5e675e370c6..90a438acbfaf 100644 --- a/trunk/arch/um/Kconfig.um +++ b/trunk/arch/um/Kconfig.um @@ -47,7 +47,7 @@ config HOSTFS config HPPFS tristate "HoneyPot ProcFS (EXPERIMENTAL)" - depends on EXPERIMENTAL && PROC_FS + depends on EXPERIMENTAL help hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc entries to be overridden, removed, or fabricated from the host. diff --git a/trunk/arch/um/include/asm/thread_info.h b/trunk/arch/um/include/asm/thread_info.h index 5bd1bad33fab..e2cf786bda0a 100644 --- a/trunk/arch/um/include/asm/thread_info.h +++ b/trunk/arch/um/include/asm/thread_info.h @@ -49,10 +49,7 @@ static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; unsigned long mask = THREAD_SIZE - 1; - void *p; - - asm volatile ("" : "=r" (p) : "0" (&ti)); - ti = (struct thread_info *) (((unsigned long)p) & ~mask); + ti = (struct thread_info *) (((unsigned long) &ti) & ~mask); return ti; } diff --git a/trunk/arch/um/sys-i386/Makefile b/trunk/arch/um/sys-i386/Makefile index b1da91c1b200..804b28dd0328 100644 --- a/trunk/arch/um/sys-i386/Makefile +++ b/trunk/arch/um/sys-i386/Makefile @@ -4,7 +4,7 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ - sys_call_table.o tls.o atomic64_cx8_32.o + sys_call_table.o tls.o obj-$(CONFIG_BINFMT_ELF) += elfcore.o diff --git a/trunk/arch/um/sys-i386/atomic64_cx8_32.S b/trunk/arch/um/sys-i386/atomic64_cx8_32.S deleted file mode 100644 index 1e901d3d4a95..000000000000 --- a/trunk/arch/um/sys-i386/atomic64_cx8_32.S +++ /dev/null @@ -1,225 +0,0 @@ -/* - * atomic64_t for 586+ - * - * Copied from arch/x86/lib/atomic64_cx8_32.S - * - * Copyright © 2010 Luca Barbieri - * - * 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. - * - */ - -#include -#include -#include - -.macro SAVE reg - pushl_cfi %\reg - CFI_REL_OFFSET \reg, 0 -.endm - -.macro RESTORE reg - popl_cfi %\reg - CFI_RESTORE \reg -.endm - -.macro read64 reg - movl %ebx, %eax - movl %ecx, %edx -/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */ - LOCK_PREFIX - cmpxchg8b (\reg) -.endm - -ENTRY(atomic64_read_cx8) - CFI_STARTPROC - - read64 %ecx - ret - CFI_ENDPROC -ENDPROC(atomic64_read_cx8) - -ENTRY(atomic64_set_cx8) - CFI_STARTPROC - -1: -/* we don't need LOCK_PREFIX since aligned 64-bit writes - * are atomic on 586 and newer */ - cmpxchg8b (%esi) - jne 1b - - ret - CFI_ENDPROC -ENDPROC(atomic64_set_cx8) - -ENTRY(atomic64_xchg_cx8) - CFI_STARTPROC - - movl %ebx, %eax - movl %ecx, %edx -1: - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - - ret - CFI_ENDPROC -ENDPROC(atomic64_xchg_cx8) - -.macro addsub_return func ins insc -ENTRY(atomic64_\func\()_return_cx8) - CFI_STARTPROC - SAVE ebp - SAVE ebx - SAVE esi - SAVE edi - - movl %eax, %esi - movl %edx, %edi - movl %ecx, %ebp - - read64 %ebp -1: - movl %eax, %ebx - movl %edx, %ecx - \ins\()l %esi, %ebx - \insc\()l %edi, %ecx - LOCK_PREFIX - cmpxchg8b (%ebp) - jne 1b - -10: - movl %ebx, %eax - movl %ecx, %edx - RESTORE edi - RESTORE esi - RESTORE ebx - RESTORE ebp - ret - CFI_ENDPROC -ENDPROC(atomic64_\func\()_return_cx8) -.endm - -addsub_return add add adc -addsub_return sub sub sbb - -.macro incdec_return func ins insc -ENTRY(atomic64_\func\()_return_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - movl %eax, %ebx - movl %edx, %ecx - \ins\()l $1, %ebx - \insc\()l $0, %ecx - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - -10: - movl %ebx, %eax - movl %ecx, %edx - RESTORE ebx - ret - CFI_ENDPROC -ENDPROC(atomic64_\func\()_return_cx8) -.endm - -incdec_return inc add adc -incdec_return dec sub sbb - -ENTRY(atomic64_dec_if_positive_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - movl %eax, %ebx - movl %edx, %ecx - subl $1, %ebx - sbb $0, %ecx - js 2f - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - -2: - movl %ebx, %eax - movl %ecx, %edx - RESTORE ebx - ret - CFI_ENDPROC -ENDPROC(atomic64_dec_if_positive_cx8) - -ENTRY(atomic64_add_unless_cx8) - CFI_STARTPROC - SAVE ebp - SAVE ebx -/* these just push these two parameters on the stack */ - SAVE edi - SAVE esi - - movl %ecx, %ebp - movl %eax, %esi - movl %edx, %edi - - read64 %ebp -1: - cmpl %eax, 0(%esp) - je 4f -2: - movl %eax, %ebx - movl %edx, %ecx - addl %esi, %ebx - adcl %edi, %ecx - LOCK_PREFIX - cmpxchg8b (%ebp) - jne 1b - - movl $1, %eax -3: - addl $8, %esp - CFI_ADJUST_CFA_OFFSET -8 - RESTORE ebx - RESTORE ebp - ret -4: - cmpl %edx, 4(%esp) - jne 2b - xorl %eax, %eax - jmp 3b - CFI_ENDPROC -ENDPROC(atomic64_add_unless_cx8) - -ENTRY(atomic64_inc_not_zero_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - testl %eax, %eax - je 4f -2: - movl %eax, %ebx - movl %edx, %ecx - addl $1, %ebx - adcl $0, %ecx - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - - movl $1, %eax -3: - RESTORE ebx - ret -4: - testl %edx, %edx - jne 2b - jmp 3b - CFI_ENDPROC -ENDPROC(atomic64_inc_not_zero_cx8) diff --git a/trunk/arch/x86/boot/memory.c b/trunk/arch/x86/boot/memory.c index db75d07c3645..cae3feb1035e 100644 --- a/trunk/arch/x86/boot/memory.c +++ b/trunk/arch/x86/boot/memory.c @@ -91,7 +91,7 @@ static int detect_memory_e801(void) if (oreg.ax > 15*1024) { return -1; /* Bogus! */ } else if (oreg.ax == 15*1024) { - boot_params.alt_mem_k = (oreg.bx << 6) + oreg.ax; + boot_params.alt_mem_k = (oreg.dx << 6) + oreg.ax; } else { /* * This ignores memory above 16MB if we have a memory diff --git a/trunk/arch/x86/include/asm/io_apic.h b/trunk/arch/x86/include/asm/io_apic.h index a97a240f67f3..c4bd267dfc50 100644 --- a/trunk/arch/x86/include/asm/io_apic.h +++ b/trunk/arch/x86/include/asm/io_apic.h @@ -150,7 +150,7 @@ void setup_IO_APIC_irq_extra(u32 gsi); extern void ioapic_and_gsi_init(void); extern void ioapic_insert_resources(void); -int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr); +int io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr); extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c index 45fd33d1fd3a..68df09bba92e 100644 --- a/trunk/arch/x86/kernel/apic/io_apic.c +++ b/trunk/arch/x86/kernel/apic/io_apic.c @@ -128,8 +128,8 @@ static int __init parse_noapic(char *str) } early_param("noapic", parse_noapic); -static int io_apic_setup_irq_pin(unsigned int irq, int node, - struct io_apic_irq_attr *attr); +static int io_apic_setup_irq_pin_once(unsigned int irq, int node, + struct io_apic_irq_attr *attr); /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ void mp_save_irq(struct mpc_intsrc *m) @@ -3570,7 +3570,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) } #endif /* CONFIG_HT_IRQ */ -static int +int io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) { struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node); @@ -3585,8 +3585,8 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) return ret; } -int io_apic_setup_irq_pin_once(unsigned int irq, int node, - struct io_apic_irq_attr *attr) +static int io_apic_setup_irq_pin_once(unsigned int irq, int node, + struct io_apic_irq_attr *attr) { unsigned int id = attr->ioapic, pin = attr->ioapic_pin; int ret; diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index bb9eb29a52dd..3532d3bf8105 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -698,7 +698,7 @@ cpu_dev_register(amd_cpu_dev); */ const int amd_erratum_400[] = - AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0x0f, 0x4, 0x2, 0xff, 0xf), + AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); EXPORT_SYMBOL_GPL(amd_erratum_400); diff --git a/trunk/arch/x86/kernel/cpu/perf_event.c b/trunk/arch/x86/kernel/cpu/perf_event.c index e638689279d3..632e5dc9c9c0 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.c +++ b/trunk/arch/x86/kernel/cpu/perf_event.c @@ -613,8 +613,8 @@ static int x86_setup_perfctr(struct perf_event *event) /* * Branch tracing: */ - if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS && - !attr->freq && hwc->sample_period == 1) { + if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && + (hwc->sample_period == 1)) { /* BTS is not supported by this architecture. */ if (!x86_pmu.bts_active) return -EOPNOTSUPP; @@ -1288,16 +1288,6 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) cpuc = &__get_cpu_var(cpu_hw_events); - /* - * Some chipsets need to unmask the LVTPC in a particular spot - * inside the nmi handler. As a result, the unmasking was pushed - * into all the nmi handlers. - * - * This generic handler doesn't seem to have any issues where the - * unmasking occurs so it was left at the top. - */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - for (idx = 0; idx < x86_pmu.num_counters; idx++) { if (!test_bit(idx, cpuc->active_mask)) { /* @@ -1384,6 +1374,8 @@ perf_event_nmi_handler(struct notifier_block *self, return NOTIFY_DONE; } + apic_write(APIC_LVTPC, APIC_DM_NMI); + handled = x86_pmu.handle_irq(args->regs); if (!handled) return NOTIFY_DONE; diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c index e61539b07d2c..43fa20b13817 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c @@ -25,7 +25,7 @@ struct intel_percore { /* * Intel PerfMon, used on Core and later. */ -static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly = +static const u64 intel_perfmon_event_map[] = { [PERF_COUNT_HW_CPU_CYCLES] = 0x003c, [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, @@ -933,16 +933,6 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) cpuc = &__get_cpu_var(cpu_hw_events); - /* - * Some chipsets need to unmask the LVTPC in a particular spot - * inside the nmi handler. As a result, the unmasking was pushed - * into all the nmi handlers. - * - * This handler doesn't seem to have any issues with the unmasking - * so it was left at the top. - */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - intel_pmu_disable_all(); handled = intel_pmu_drain_bts_buffer(); status = intel_pmu_get_status(); @@ -1008,9 +998,6 @@ intel_bts_constraints(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; unsigned int hw_event, bts_event; - if (event->attr.freq) - return NULL; - hw_event = hwc->config & INTEL_ARCH_EVENT_MASK; bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS); @@ -1318,7 +1305,7 @@ static void intel_clovertown_quirks(void) * AJ106 could possibly be worked around by not allowing LBR * usage from PEBS, including the fixup. * AJ68 could possibly be worked around by always programming - * a pebs_event_reset[0] value and coping with the lost events. + * a pebs_event_reset[0] value and coping with the lost events. * * But taken together it might just make sense to not enable PEBS on * these chips. @@ -1422,18 +1409,6 @@ static __init int intel_pmu_init(void) x86_pmu.percore_constraints = intel_nehalem_percore_constraints; x86_pmu.enable_all = intel_pmu_nhm_enable_all; x86_pmu.extra_regs = intel_nehalem_extra_regs; - - if (ebx & 0x40) { - /* - * Erratum AAJ80 detected, we work it around by using - * the BR_MISP_EXEC.ANY event. This will over-count - * branch-misses, but it's still much better than the - * architectural event which is often completely bogus: - */ - intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89; - - pr_cont("erratum AAJ80 worked around, "); - } pr_cont("Nehalem events, "); break; diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p4.c b/trunk/arch/x86/kernel/cpu/perf_event_p4.c index e93fcd55fae1..d1f77e2934a1 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_p4.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_p4.c @@ -950,20 +950,11 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) x86_pmu_stop(event, 0); } - if (handled) + if (handled) { + /* p4 quirk: unmask it again */ + apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); inc_irq_stat(apic_perf_irqs); - - /* - * When dealing with the unmasking of the LVTPC on P4 perf hw, it has - * been observed that the OVF bit flag has to be cleared first _before_ - * the LVTPC can be unmasked. - * - * The reason is the NMI line will continue to be asserted while the OVF - * bit is set. This causes a second NMI to generate if the LVTPC is - * unmasked before the OVF bit is cleared, leading to unknown NMI - * messages. - */ - apic_write(APIC_LVTPC, APIC_DM_NMI); + } return handled; } diff --git a/trunk/arch/x86/kernel/devicetree.c b/trunk/arch/x86/kernel/devicetree.c index e90f08458e6b..706a9fb46a58 100644 --- a/trunk/arch/x86/kernel/devicetree.c +++ b/trunk/arch/x86/kernel/devicetree.c @@ -391,7 +391,7 @@ static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize, set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); - return io_apic_setup_irq_pin_once(*out_hwirq, cpu_to_node(0), &attr); + return io_apic_setup_irq_pin(*out_hwirq, cpu_to_node(0), &attr); } static void __init ioapic_add_ofnode(struct device_node *np) diff --git a/trunk/arch/x86/kernel/reboot_32.S b/trunk/arch/x86/kernel/reboot_32.S index 1d5c46df0d78..29092b38d816 100644 --- a/trunk/arch/x86/kernel/reboot_32.S +++ b/trunk/arch/x86/kernel/reboot_32.S @@ -21,26 +21,26 @@ r_base = . /* Get our own relocated address */ call 1f 1: popl %ebx - subl $(1b - r_base), %ebx + subl $1b, %ebx /* Compute the equivalent real-mode segment */ movl %ebx, %ecx shrl $4, %ecx /* Patch post-real-mode segment jump */ - movw (dispatch_table - r_base)(%ebx,%eax,2),%ax - movw %ax, (101f - r_base)(%ebx) - movw %cx, (102f - r_base)(%ebx) + movw dispatch_table(%ebx,%eax,2),%ax + movw %ax, 101f(%ebx) + movw %cx, 102f(%ebx) /* Set up the IDT for real mode. */ - lidtl (machine_real_restart_idt - r_base)(%ebx) + lidtl machine_real_restart_idt(%ebx) /* * Set up a GDT from which we can load segment descriptors for real * mode. The GDT is not used in real mode; it is just needed here to * prepare the descriptors. */ - lgdtl (machine_real_restart_gdt - r_base)(%ebx) + lgdtl machine_real_restart_gdt(%ebx) /* * Load the data segment registers with 16-bit compatible values diff --git a/trunk/arch/x86/mm/numa_64.c b/trunk/arch/x86/mm/numa_64.c index 85b52fc03084..e8c00cc72033 100644 --- a/trunk/arch/x86/mm/numa_64.c +++ b/trunk/arch/x86/mm/numa_64.c @@ -306,7 +306,7 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi) bi->end = min(bi->end, high); /* and there's no empty block */ - if (bi->start >= bi->end) { + if (bi->start == bi->end) { numa_remove_memblk_from(i--, mi); continue; } diff --git a/trunk/arch/x86/platform/ce4100/falconfalls.dts b/trunk/arch/x86/platform/ce4100/falconfalls.dts index e70be38ce039..2d6d226f2b10 100644 --- a/trunk/arch/x86/platform/ce4100/falconfalls.dts +++ b/trunk/arch/x86/platform/ce4100/falconfalls.dts @@ -347,7 +347,7 @@ "pciclass0c03"; reg = <0x16800 0x0 0x0 0x0 0x0>; - interrupts = <22 1>; + interrupts = <22 3>; }; usb@d,1 { @@ -357,7 +357,7 @@ "pciclass0c03"; reg = <0x16900 0x0 0x0 0x0 0x0>; - interrupts = <22 1>; + interrupts = <22 3>; }; sata@e,0 { @@ -367,7 +367,7 @@ "pciclass0106"; reg = <0x17000 0x0 0x0 0x0 0x0>; - interrupts = <23 1>; + interrupts = <23 3>; }; flash@f,0 { diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index 55c965b38c27..aef7af92b28b 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1463,119 +1463,6 @@ static int xen_pgd_alloc(struct mm_struct *mm) return ret; } -#ifdef CONFIG_X86_64 -static __initdata u64 __last_pgt_set_rw = 0; -static __initdata u64 __pgt_buf_start = 0; -static __initdata u64 __pgt_buf_end = 0; -static __initdata u64 __pgt_buf_top = 0; -/* - * As a consequence of the commit: - * - * commit 4b239f458c229de044d6905c2b0f9fe16ed9e01e - * Author: Yinghai Lu - * Date: Fri Dec 17 16:58:28 2010 -0800 - * - * x86-64, mm: Put early page table high - * - * at some point init_memory_mapping is going to reach the pagetable pages - * area and map those pages too (mapping them as normal memory that falls - * in the range of addresses passed to init_memory_mapping as argument). - * Some of those pages are already pagetable pages (they are in the range - * pgt_buf_start-pgt_buf_end) therefore they are going to be mapped RO and - * everything is fine. - * Some of these pages are not pagetable pages yet (they fall in the range - * pgt_buf_end-pgt_buf_top; for example the page at pgt_buf_end) so they - * are going to be mapped RW. When these pages become pagetable pages and - * are hooked into the pagetable, xen will find that the guest has already - * a RW mapping of them somewhere and fail the operation. - * The reason Xen requires pagetables to be RO is that the hypervisor needs - * to verify that the pagetables are valid before using them. The validation - * operations are called "pinning". - * - * In order to fix the issue we mark all the pages in the entire range - * pgt_buf_start-pgt_buf_top as RO, however when the pagetable allocation - * is completed only the range pgt_buf_start-pgt_buf_end is reserved by - * init_memory_mapping. Hence the kernel is going to crash as soon as one - * of the pages in the range pgt_buf_end-pgt_buf_top is reused (b/c those - * ranges are RO). - * - * For this reason, 'mark_rw_past_pgt' is introduced which is called _after_ - * the init_memory_mapping has completed (in a perfect world we would - * call this function from init_memory_mapping, but lets ignore that). - * - * Because we are called _after_ init_memory_mapping the pgt_buf_[start, - * end,top] have all changed to new values (b/c init_memory_mapping - * is called and setting up another new page-table). Hence, the first time - * we enter this function, we save away the pgt_buf_start value and update - * the pgt_buf_[end,top]. - * - * When we detect that the "old" pgt_buf_start through pgt_buf_end - * PFNs have been reserved (so memblock_x86_reserve_range has been called), - * we immediately set out to RW the "old" pgt_buf_end through pgt_buf_top. - * - * And then we update those "old" pgt_buf_[end|top] with the new ones - * so that we can redo this on the next pagetable. - */ -static __init void mark_rw_past_pgt(void) { - - if (pgt_buf_end > pgt_buf_start) { - u64 addr, size; - - /* Save it away. */ - if (!__pgt_buf_start) { - __pgt_buf_start = pgt_buf_start; - __pgt_buf_end = pgt_buf_end; - __pgt_buf_top = pgt_buf_top; - return; - } - /* If we get the range that starts at __pgt_buf_end that means - * the range is reserved, and that in 'init_memory_mapping' - * the 'memblock_x86_reserve_range' has been called with the - * outdated __pgt_buf_start, __pgt_buf_end (the "new" - * pgt_buf_[start|end|top] refer now to a new pagetable. - * Note: we are called _after_ the pgt_buf_[..] have been - * updated.*/ - - addr = memblock_x86_find_in_range_size(PFN_PHYS(__pgt_buf_start), - &size, PAGE_SIZE); - - /* Still not reserved, meaning 'memblock_x86_reserve_range' - * hasn't been called yet. Update the _end and _top.*/ - if (addr == PFN_PHYS(__pgt_buf_start)) { - __pgt_buf_end = pgt_buf_end; - __pgt_buf_top = pgt_buf_top; - return; - } - - /* OK, the area is reserved, meaning it is time for us to - * set RW for the old end->top PFNs. */ - - /* ..unless we had already done this. */ - if (__pgt_buf_end == __last_pgt_set_rw) - return; - - addr = PFN_PHYS(__pgt_buf_end); - - /* set as RW the rest */ - printk(KERN_DEBUG "xen: setting RW the range %llx - %llx\n", - PFN_PHYS(__pgt_buf_end), PFN_PHYS(__pgt_buf_top)); - - while (addr < PFN_PHYS(__pgt_buf_top)) { - make_lowmem_page_readwrite(__va(addr)); - addr += PAGE_SIZE; - } - /* And update everything so that we are ready for the next - * pagetable (the one created for regions past 4GB) */ - __last_pgt_set_rw = __pgt_buf_end; - __pgt_buf_start = pgt_buf_start; - __pgt_buf_end = pgt_buf_end; - __pgt_buf_top = pgt_buf_top; - } - return; -} -#else -static __init void mark_rw_past_pgt(void) { } -#endif static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd) { #ifdef CONFIG_X86_64 @@ -1601,14 +1488,6 @@ static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) { unsigned long pfn = pte_pfn(pte); - /* - * A bit of optimization. We do not need to call the workaround - * when xen_set_pte_init is called with a PTE with 0 as PFN. - * That is b/c the pagetable at that point are just being populated - * with empty values and we can save some cycles by not calling - * the 'memblock' code.*/ - if (pfn) - mark_rw_past_pgt(); /* * If the new pfn is within the range of the newly allocated * kernel pagetable, and it isn't being mapped into an @@ -1616,7 +1495,7 @@ static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) * it is RO. */ if (((!is_early_ioremap_ptep(ptep) && - pfn >= pgt_buf_start && pfn < pgt_buf_top)) || + pfn >= pgt_buf_start && pfn < pgt_buf_end)) || (is_early_ioremap_ptep(ptep) && pfn != (pgt_buf_end - 1))) pte = pte_wrprotect(pte); @@ -2118,8 +1997,6 @@ __init void xen_ident_map_ISA(void) static __init void xen_post_allocator_init(void) { - mark_rw_past_pgt(); - #ifdef CONFIG_XEN_DEBUG pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug); #endif diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 449c556274c0..b136c9c1e531 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -943,10 +943,6 @@ static int acpi_bus_get_flags(struct acpi_device *device) if (ACPI_SUCCESS(status)) device->flags.lockable = 1; - /* Power resources cannot be power manageable. */ - if (device->device_type == ACPI_BUS_TYPE_POWER) - return 0; - /* Presence of _PS0|_PR0 indicates 'power manageable' */ status = acpi_get_handle(device->handle, "_PS0", &temp); if (ACPI_FAILURE(status)) diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index abe3ab709e87..fbc5b6e7c591 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -63,7 +63,6 @@ void device_pm_init(struct device *dev) dev->power.wakeup = NULL; spin_lock_init(&dev->power.lock); pm_runtime_init(dev); - INIT_LIST_HEAD(&dev->power.entry); } /** diff --git a/trunk/drivers/base/power/wakeup.c b/trunk/drivers/base/power/wakeup.c index abbbd33e8d8a..4573c83df6dd 100644 --- a/trunk/drivers/base/power/wakeup.c +++ b/trunk/drivers/base/power/wakeup.c @@ -258,7 +258,7 @@ void device_set_wakeup_capable(struct device *dev, bool capable) if (!!dev->power.can_wakeup == !!capable) return; - if (device_is_registered(dev) && !list_empty(&dev->power.entry)) { + if (device_is_registered(dev)) { if (capable) { if (wakeup_sysfs_add(dev)) return; diff --git a/trunk/drivers/char/agp/intel-agp.c b/trunk/drivers/char/agp/intel-agp.c index b427711be4be..b0a0dccc98c1 100644 --- a/trunk/drivers/char/agp/intel-agp.c +++ b/trunk/drivers/char/agp/intel-agp.c @@ -903,9 +903,6 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB), ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB), ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB), - ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB), - ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB), - ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB), { } }; diff --git a/trunk/drivers/char/agp/intel-agp.h b/trunk/drivers/char/agp/intel-agp.h index 999803ce10dc..5feebe2800e9 100644 --- a/trunk/drivers/char/agp/intel-agp.h +++ b/trunk/drivers/char/agp/intel-agp.h @@ -225,14 +225,6 @@ #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG 0x0126 #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */ #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A -#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB 0x0150 /* Desktop */ -#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT1_IG 0x0152 -#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT2_IG 0x0162 -#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB 0x0154 /* Mobile */ -#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT1_IG 0x0156 -#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT2_IG 0x0166 -#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB 0x0158 /* Server */ -#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT1_IG 0x015A int intel_gmch_probe(struct pci_dev *pdev, struct agp_bridge_data *bridge); diff --git a/trunk/drivers/char/agp/intel-gtt.c b/trunk/drivers/char/agp/intel-gtt.c index 85151019dde1..0d09b537bb9a 100644 --- a/trunk/drivers/char/agp/intel-gtt.c +++ b/trunk/drivers/char/agp/intel-gtt.c @@ -1420,16 +1420,6 @@ static const struct intel_gtt_driver_description { "Sandybridge", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG, "Sandybridge", &sandybridge_gtt_driver }, - { PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT1_IG, - "Ivybridge", &sandybridge_gtt_driver }, - { PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT2_IG, - "Ivybridge", &sandybridge_gtt_driver }, - { PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT1_IG, - "Ivybridge", &sandybridge_gtt_driver }, - { PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT2_IG, - "Ivybridge", &sandybridge_gtt_driver }, - { PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT1_IG, - "Ivybridge", &sandybridge_gtt_driver }, { 0, NULL, NULL } }; diff --git a/trunk/drivers/clk/clkdev.c b/trunk/drivers/clk/clkdev.c index 6db161f64ae0..0fc0a79852de 100644 --- a/trunk/drivers/clk/clkdev.c +++ b/trunk/drivers/clk/clkdev.c @@ -32,9 +32,10 @@ static DEFINE_MUTEX(clocks_mutex); * Then we take the most specific entry - with the following * order of precedence: dev+con > dev only > con only. */ -static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) +static struct clk *clk_find(const char *dev_id, const char *con_id) { - struct clk_lookup *p, *cl = NULL; + struct clk_lookup *p; + struct clk *clk = NULL; int match, best = 0; list_for_each_entry(p, &clocks, node) { @@ -51,27 +52,27 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) } if (match > best) { - cl = p; + clk = p->clk; if (match != 3) best = match; else break; } } - return cl; + return clk; } struct clk *clk_get_sys(const char *dev_id, const char *con_id) { - struct clk_lookup *cl; + struct clk *clk; mutex_lock(&clocks_mutex); - cl = clk_find(dev_id, con_id); - if (cl && !__clk_get(cl->clk)) - cl = NULL; + clk = clk_find(dev_id, con_id); + if (clk && !__clk_get(clk)) + clk = NULL; mutex_unlock(&clocks_mutex); - return cl ? cl->clk : ERR_PTR(-ENOENT); + return clk ? clk : ERR_PTR(-ENOENT); } EXPORT_SYMBOL(clk_get_sys); diff --git a/trunk/drivers/gpu/drm/drm_irq.c b/trunk/drivers/gpu/drm/drm_irq.c index 2022a5c966bb..62ced7554ba4 100644 --- a/trunk/drivers/gpu/drm/drm_irq.c +++ b/trunk/drivers/gpu/drm/drm_irq.c @@ -933,34 +933,11 @@ EXPORT_SYMBOL(drm_vblank_put); void drm_vblank_off(struct drm_device *dev, int crtc) { - struct drm_pending_vblank_event *e, *t; - struct timeval now; unsigned long irqflags; - unsigned int seq; spin_lock_irqsave(&dev->vbl_lock, irqflags); vblank_disable_and_save(dev, crtc); DRM_WAKEUP(&dev->vbl_queue[crtc]); - - /* Send any queued vblank events, lest the natives grow disquiet */ - seq = drm_vblank_count_and_time(dev, crtc, &now); - list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { - if (e->pipe != crtc) - continue; - DRM_DEBUG("Sending premature vblank event on disable: \ - wanted %d, current %d\n", - e->event.sequence, seq); - - e->event.sequence = seq; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - drm_vblank_put(dev, e->pipe); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - trace_drm_vblank_event_delivered(e->base.pid, e->pipe, - e->event.sequence); - } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } EXPORT_SYMBOL(drm_vblank_off); diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index 183eaac8980a..87c8e29465e3 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -106,12 +106,11 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj) } } -static const char *cache_level_str(int type) +static const char *agp_type_str(int type) { switch (type) { - case I915_CACHE_NONE: return " uncached"; - case I915_CACHE_LLC: return " snooped (LLC)"; - case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)"; + case 0: return " uncached"; + case 1: return " snooped"; default: return ""; } } @@ -128,7 +127,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) obj->base.write_domain, obj->last_rendering_seqno, obj->last_fenced_seqno, - cache_level_str(obj->cache_level), + agp_type_str(obj->agp_type == AGP_USER_CACHED_MEMORY), obj->dirty ? " dirty" : "", obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); if (obj->base.name) @@ -715,7 +714,7 @@ static void print_error_buffers(struct seq_file *m, dirty_flag(err->dirty), purgeable_flag(err->purgeable), ring_str(err->ring), - cache_level_str(err->cache_level)); + agp_type_str(err->agp_type)); if (err->name) seq_printf(m, " (name: %d)", err->name); @@ -853,7 +852,6 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - int ret; if (IS_GEN5(dev)) { u16 rgvswctl = I915_READ16(MEMSWCTL); @@ -875,11 +873,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) int max_freq; /* RPSTAT1 is in the GT power well */ - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - gen6_gt_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); rpstat = I915_READ(GEN6_RPSTAT1); rpupei = I915_READ(GEN6_RP_CUR_UP_EI); @@ -889,9 +883,6 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) rpcurdown = I915_READ(GEN6_RP_CUR_DOWN); rpprevdown = I915_READ(GEN6_RP_PREV_DOWN); - gen6_gt_force_wake_put(dev_priv); - mutex_unlock(&dev->struct_mutex); - seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); seq_printf(m, "RPSTAT1: 0x%08x\n", rpstat); seq_printf(m, "Render p-state ratio: %d\n", @@ -926,6 +917,8 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) max_freq = rp_state_cap & 0xff; seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", max_freq * 50); + + __gen6_gt_force_wake_put(dev_priv); } else { seq_printf(m, "no P-state info available\n"); } @@ -1193,42 +1186,6 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) return 0; } -static int i915_context_status(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - ret = mutex_lock_interruptible(&dev->mode_config.mutex); - if (ret) - return ret; - - seq_printf(m, "power context "); - describe_obj(m, dev_priv->pwrctx); - seq_printf(m, "\n"); - - seq_printf(m, "render context "); - describe_obj(m, dev_priv->renderctx); - seq_printf(m, "\n"); - - mutex_unlock(&dev->mode_config.mutex); - - return 0; -} - -static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - seq_printf(m, "forcewake count = %d\n", - atomic_read(&dev_priv->forcewake_count)); - - return 0; -} - static int i915_wedged_open(struct inode *inode, struct file *filp) @@ -1331,67 +1288,6 @@ static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) return drm_add_fake_info_node(minor, ent, &i915_wedged_fops); } -static int i915_forcewake_open(struct inode *inode, struct file *file) -{ - struct drm_device *dev = inode->i_private; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - if (!IS_GEN6(dev)) - return 0; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - gen6_gt_force_wake_get(dev_priv); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -int i915_forcewake_release(struct inode *inode, struct file *file) -{ - struct drm_device *dev = inode->i_private; - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!IS_GEN6(dev)) - return 0; - - /* - * It's bad that we can potentially hang userspace if struct_mutex gets - * forever stuck. However, if we cannot acquire this lock it means that - * almost certainly the driver has hung, is not unload-able. Therefore - * hanging here is probably a minor inconvenience not to be seen my - * almost every user. - */ - mutex_lock(&dev->struct_mutex); - gen6_gt_force_wake_put(dev_priv); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static const struct file_operations i915_forcewake_fops = { - .owner = THIS_MODULE, - .open = i915_forcewake_open, - .release = i915_forcewake_release, -}; - -static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - - ent = debugfs_create_file("i915_forcewake_user", - S_IRUSR, - root, dev, - &i915_forcewake_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); -} - static struct drm_info_list i915_debugfs_list[] = { {"i915_capabilities", i915_capabilities, 0}, {"i915_gem_objects", i915_gem_object_info, 0}, @@ -1428,8 +1324,6 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_sr_status", i915_sr_status, 0}, {"i915_opregion", i915_opregion, 0}, {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, - {"i915_context_status", i915_context_status, 0}, - {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) @@ -1441,10 +1335,6 @@ int i915_debugfs_init(struct drm_minor *minor) if (ret) return ret; - ret = i915_forcewake_create(minor->debugfs_root, minor); - if (ret) - return ret; - return drm_debugfs_create_files(i915_debugfs_list, I915_DEBUGFS_ENTRIES, minor->debugfs_root, minor); @@ -1454,8 +1344,6 @@ void i915_debugfs_cleanup(struct drm_minor *minor) { drm_debugfs_remove_files(i915_debugfs_list, I915_DEBUGFS_ENTRIES, minor); - drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops, - 1, minor); drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops, 1, minor); } diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 0239e9974bf2..12876f2795d2 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -571,7 +571,7 @@ static int i915_quiescent(struct drm_device *dev) struct intel_ring_buffer *ring = LP_RING(dev->dev_private); i915_kernel_lost_context(dev); - return intel_wait_ring_idle(ring); + return intel_wait_ring_buffer(ring, ring->size - 8); } static int i915_flush_ioctl(struct drm_device *dev, void *data, @@ -1176,11 +1176,11 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) return can_switch; } -static int i915_load_gem_init(struct drm_device *dev) +static int i915_load_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long prealloc_size, gtt_size, mappable_size; - int ret; + int ret = 0; prealloc_size = dev_priv->mm.gtt->stolen_size; gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT; @@ -1204,7 +1204,7 @@ static int i915_load_gem_init(struct drm_device *dev) ret = i915_gem_init_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); if (ret) - return ret; + goto out; /* Try to set up FBC with a reasonable compressed buffer size */ if (I915_HAS_FBC(dev) && i915_powersave) { @@ -1222,13 +1222,6 @@ static int i915_load_gem_init(struct drm_device *dev) /* Allow hardware batchbuffers unless told otherwise. */ dev_priv->allow_batchbuffer = 1; - return 0; -} - -static int i915_load_modeset_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; ret = intel_parse_bios(dev); if (ret) @@ -1243,7 +1236,7 @@ static int i915_load_modeset_init(struct drm_device *dev) */ ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); if (ret && ret != -ENODEV) - goto out; + goto cleanup_ringbuffer; intel_register_dsm_handler(); @@ -1260,39 +1253,9 @@ static int i915_load_modeset_init(struct drm_device *dev) intel_modeset_init(dev); - ret = i915_load_gem_init(dev); - if (ret) - goto cleanup_vga_switcheroo; - - intel_modeset_gem_init(dev); - - if (IS_IVYBRIDGE(dev)) { - /* Share pre & uninstall handlers with ILK/SNB */ - dev->driver->irq_handler = ivybridge_irq_handler; - dev->driver->irq_preinstall = ironlake_irq_preinstall; - dev->driver->irq_postinstall = ivybridge_irq_postinstall; - dev->driver->irq_uninstall = ironlake_irq_uninstall; - dev->driver->enable_vblank = ivybridge_enable_vblank; - dev->driver->disable_vblank = ivybridge_disable_vblank; - } else if (HAS_PCH_SPLIT(dev)) { - dev->driver->irq_handler = ironlake_irq_handler; - dev->driver->irq_preinstall = ironlake_irq_preinstall; - dev->driver->irq_postinstall = ironlake_irq_postinstall; - dev->driver->irq_uninstall = ironlake_irq_uninstall; - dev->driver->enable_vblank = ironlake_enable_vblank; - dev->driver->disable_vblank = ironlake_disable_vblank; - } else { - dev->driver->irq_preinstall = i915_driver_irq_preinstall; - dev->driver->irq_postinstall = i915_driver_irq_postinstall; - dev->driver->irq_uninstall = i915_driver_irq_uninstall; - dev->driver->irq_handler = i915_driver_irq_handler; - dev->driver->enable_vblank = i915_enable_vblank; - dev->driver->disable_vblank = i915_disable_vblank; - } - ret = drm_irq_install(dev); if (ret) - goto cleanup_gem; + goto cleanup_vga_switcheroo; /* Always safe in the mode setting case. */ /* FIXME: do pre/post-mode set stuff in core KMS code */ @@ -1311,14 +1274,14 @@ static int i915_load_modeset_init(struct drm_device *dev) cleanup_irq: drm_irq_uninstall(dev); -cleanup_gem: - mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); - mutex_unlock(&dev->struct_mutex); cleanup_vga_switcheroo: vga_switcheroo_unregister_client(dev->pdev); cleanup_vga_client: vga_client_register(dev->pdev, NULL, NULL, NULL); +cleanup_ringbuffer: + mutex_lock(&dev->struct_mutex); + i915_gem_cleanup_ringbuffer(dev); + mutex_unlock(&dev->struct_mutex); out: return ret; } @@ -2019,7 +1982,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev->driver->get_vblank_counter = i915_get_vblank_counter; dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { + if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev)) { dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ dev->driver->get_vblank_counter = gm45_get_vblank_counter; } @@ -2062,7 +2025,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->error_lock); - spin_lock_init(&dev_priv->rps_lock); if (IS_MOBILE(dev) || !IS_GEN2(dev)) dev_priv->num_pipe = 2; diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 8c4fcbb8a4cb..c34a8dd31d02 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -188,21 +188,6 @@ static const struct intel_device_info intel_sandybridge_m_info = { .has_blt_ring = 1, }; -static const struct intel_device_info intel_ivybridge_d_info = { - .is_ivybridge = 1, .gen = 7, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_bsd_ring = 1, - .has_blt_ring = 1, -}; - -static const struct intel_device_info intel_ivybridge_m_info = { - .is_ivybridge = 1, .gen = 7, .is_mobile = 1, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ - .has_bsd_ring = 1, - .has_blt_ring = 1, -}; - static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */ INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */ @@ -242,11 +227,6 @@ static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), - INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */ - INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */ - INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */ - INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */ - INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */ {0, 0, 0} }; @@ -255,9 +235,7 @@ MODULE_DEVICE_TABLE(pci, pciidlist); #endif #define INTEL_PCH_DEVICE_ID_MASK 0xff00 -#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 -#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 void intel_detect_pch (struct drm_device *dev) { @@ -276,23 +254,16 @@ void intel_detect_pch (struct drm_device *dev) int id; id = pch->device & INTEL_PCH_DEVICE_ID_MASK; - if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { - dev_priv->pch_type = PCH_IBX; - DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); - } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { + if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_CPT; DRM_DEBUG_KMS("Found CougarPoint PCH\n"); - } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { - /* PantherPoint is CPT compatible */ - dev_priv->pch_type = PCH_CPT; - DRM_DEBUG_KMS("Found PatherPoint PCH\n"); } } pci_dev_put(pch); } } -static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { int count; @@ -308,38 +279,12 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) udelay(10); } -/* - * Generally this is called implicitly by the register read function. However, - * if some sequence requires the GT to not power down then this function should - * be called at the beginning of the sequence followed by a call to - * gen6_gt_force_wake_put() at the end of the sequence. - */ -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) -{ - WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); - - /* Forcewake is atomic in case we get in here without the lock */ - if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) - __gen6_gt_force_wake_get(dev_priv); -} - -static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE, 0); POSTING_READ(FORCEWAKE); } -/* - * see gen6_gt_force_wake_get() - */ -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) -{ - WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); - - if (atomic_dec_and_test(&dev_priv->forcewake_count)) - __gen6_gt_force_wake_put(dev_priv); -} - void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) { int loop = 500; diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 3a1c27718065..1c1b27c97e5c 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -188,7 +188,7 @@ struct drm_i915_error_state { u32 dirty:1; u32 purgeable:1; u32 ring:4; - u32 cache_level:2; + u32 agp_type:1; } *active_bo, *pinned_bo; u32 active_bo_count, pinned_bo_count; struct intel_overlay_error_state *overlay; @@ -203,19 +203,12 @@ struct drm_i915_display_funcs { int (*get_display_clock_speed)(struct drm_device *dev); int (*get_fifo_size)(struct drm_device *dev, int plane); void (*update_wm)(struct drm_device *dev); - int (*crtc_mode_set)(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb); - void (*fdi_link_train)(struct drm_crtc *crtc); - void (*init_clock_gating)(struct drm_device *dev); - void (*init_pch_clock_gating)(struct drm_device *dev); /* clock updates for mode set */ /* cursor updates */ /* render clock increase/decrease */ /* display clock increase/decrease */ /* pll clock increase/decrease */ + /* clock gating init */ }; struct intel_device_info { @@ -230,7 +223,6 @@ struct intel_device_info { u8 is_pineview : 1; u8 is_broadwater : 1; u8 is_crestline : 1; - u8 is_ivybridge : 1; u8 has_fbc : 1; u8 has_pipe_cxsr : 1; u8 has_hotplug : 1; @@ -684,10 +676,6 @@ typedef struct drm_i915_private { bool mchbar_need_disable; - struct work_struct rps_work; - spinlock_t rps_lock; - u32 pm_iir; - u8 cur_delay; u8 min_delay; u8 max_delay; @@ -715,16 +703,8 @@ typedef struct drm_i915_private { struct intel_fbdev *fbdev; struct drm_property *broadcast_rgb_property; - - atomic_t forcewake_count; } drm_i915_private_t; -enum i915_cache_level { - I915_CACHE_NONE, - I915_CACHE_LLC, - I915_CACHE_LLC_MLC, /* gen6+ */ -}; - struct drm_i915_gem_object { struct drm_gem_object base; @@ -811,8 +791,6 @@ struct drm_i915_gem_object { unsigned int pending_fenced_gpu_access:1; unsigned int fenced_gpu_access:1; - unsigned int cache_level:2; - struct page **pages; /** @@ -849,6 +827,8 @@ struct drm_i915_gem_object { /** Record of address bit 17 of each page at last unbind. */ unsigned long *bit_17; + /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */ + uint32_t agp_type; /** * If present, while GEM_DOMAIN_CPU is in the read domain this array @@ -935,21 +915,13 @@ enum intel_chip_family { #define IS_G33(dev) (INTEL_INFO(dev)->is_g33) #define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) -#define IS_IVYBRIDGE(dev) (INTEL_INFO(dev)->is_ivybridge) #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) -/* - * The genX designation typically refers to the render engine, so render - * capability related checks should use IS_GEN, while display and other checks - * have their own (e.g. HAS_PCH_SPLIT for ILK+ display, IS_foo for particular - * chips, etc.). - */ #define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2) #define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3) #define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4) #define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) -#define IS_GEN7(dev) (INTEL_INFO(dev)->gen == 7) #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) @@ -976,8 +948,8 @@ enum intel_chip_family { #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) -#define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) -#define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5) +#define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev)) +#define HAS_PIPE_CONTROL(dev) (IS_GEN5(dev) || IS_GEN6(dev)) #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) @@ -1038,27 +1010,12 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); extern void i915_driver_irq_preinstall(struct drm_device * dev); extern int i915_driver_irq_postinstall(struct drm_device *dev); extern void i915_driver_irq_uninstall(struct drm_device * dev); - -extern irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS); -extern void ironlake_irq_preinstall(struct drm_device *dev); -extern int ironlake_irq_postinstall(struct drm_device *dev); -extern void ironlake_irq_uninstall(struct drm_device *dev); - -extern irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS); -extern void ivybridge_irq_preinstall(struct drm_device *dev); -extern int ivybridge_irq_postinstall(struct drm_device *dev); -extern void ivybridge_irq_uninstall(struct drm_device *dev); - extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_enable_vblank(struct drm_device *dev, int crtc); extern void i915_disable_vblank(struct drm_device *dev, int crtc); -extern int ironlake_enable_vblank(struct drm_device *dev, int crtc); -extern void ironlake_disable_vblank(struct drm_device *dev, int crtc); -extern int ivybridge_enable_vblank(struct drm_device *dev, int crtc); -extern void ivybridge_disable_vblank(struct drm_device *dev, int crtc); extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); extern int i915_vblank_swap(struct drm_device *dev, void *data, @@ -1308,7 +1265,6 @@ static inline void intel_unregister_dsm_handler(void) { return; } /* modesetting */ extern void intel_modeset_init(struct drm_device *dev); -extern void intel_modeset_gem_init(struct drm_device *dev); extern void intel_modeset_cleanup(struct drm_device *dev); extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); extern void i8xx_disable_fbc(struct drm_device *dev); @@ -1356,34 +1312,13 @@ extern void intel_display_print_error_state(struct seq_file *m, LOCK_TEST_WITH_RETURN(dev, file); \ } while (0) -/* On SNB platform, before reading ring registers forcewake bit - * must be set to prevent GT core from power down and stale values being - * returned. - */ -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); -void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); - -/* We give fast paths for the really cool registers */ -#define NEEDS_FORCE_WAKE(dev_priv, reg) \ - (((dev_priv)->info->gen >= 6) && \ - ((reg) < 0x40000) && \ - ((reg) != FORCEWAKE)) #define __i915_read(x, y) \ static inline u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ - u##x val = 0; \ - if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ - gen6_gt_force_wake_get(dev_priv); \ - val = read##y(dev_priv->regs + reg); \ - gen6_gt_force_wake_put(dev_priv); \ - } else { \ - val = read##y(dev_priv->regs + reg); \ - } \ + u##x val = read##y(dev_priv->regs + reg); \ trace_i915_reg_rw(false, reg, val, sizeof(val)); \ return val; \ } - __i915_read(8, b) __i915_read(16, w) __i915_read(32, l) @@ -1393,9 +1328,6 @@ __i915_read(64, q) #define __i915_write(x, y) \ static inline void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ trace_i915_reg_rw(true, reg, val, sizeof(val)); \ - if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ - __gen6_gt_wait_for_fifo(dev_priv); \ - } \ write##y(val, dev_priv->regs + reg); \ } __i915_write(8, b) @@ -1424,4 +1356,33 @@ __i915_write(64, q) #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) +/* On SNB platform, before reading ring registers forcewake bit + * must be set to prevent GT core from power down and stale values being + * returned. + */ +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); +void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); + +static inline u32 i915_gt_read(struct drm_i915_private *dev_priv, u32 reg) +{ + u32 val; + + if (dev_priv->info->gen >= 6) { + __gen6_gt_force_wake_get(dev_priv); + val = I915_READ(reg); + __gen6_gt_force_wake_put(dev_priv); + } else + val = I915_READ(reg); + + return val; +} + +static inline void i915_gt_write(struct drm_i915_private *dev_priv, + u32 reg, u32 val) +{ + if (dev_priv->info->gen >= 6) + __gen6_gt_wait_for_fifo(dev_priv); + I915_WRITE(reg, val); +} #endif diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index c6289034e29a..7ce3f353af33 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -2673,7 +2673,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, update: obj->tiling_changed = false; switch (INTEL_INFO(dev)->gen) { - case 7: case 6: ret = sandybridge_write_fence_reg(obj, pipelined); break; @@ -2707,7 +2706,6 @@ i915_gem_clear_fence_reg(struct drm_device *dev, uint32_t fence_reg = reg - dev_priv->fence_regs; switch (INTEL_INFO(dev)->gen) { - case 7: case 6: I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + fence_reg*8, 0); break; @@ -2880,17 +2878,6 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj) if (obj->pages == NULL) return; - /* If the GPU is snooping the contents of the CPU cache, - * we do not need to manually clear the CPU cache lines. However, - * the caches are only snooped when the render cache is - * flushed/invalidated. As we always have to emit invalidations - * and flushes when moving into and out of the RENDER domain, correct - * snooping behaviour occurs naturally as the result of our domain - * tracking. - */ - if (obj->cache_level != I915_CACHE_NONE) - return; - trace_i915_gem_object_clflush(obj); drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE); @@ -3582,7 +3569,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.read_domains = I915_GEM_DOMAIN_CPU; - obj->cache_level = I915_CACHE_NONE; + obj->agp_type = AGP_USER_MEMORY; obj->base.driver_private = NULL; obj->fence_reg = I915_FENCE_REG_NONE; INIT_LIST_HEAD(&obj->mm_list); @@ -3858,10 +3845,25 @@ i915_gem_load(struct drm_device *dev) dev_priv->num_fence_regs = 8; /* Initialize fence registers to zero */ - for (i = 0; i < dev_priv->num_fence_regs; i++) { - i915_gem_clear_fence_reg(dev, &dev_priv->fence_regs[i]); + switch (INTEL_INFO(dev)->gen) { + case 6: + for (i = 0; i < 16; i++) + I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), 0); + break; + case 5: + case 4: + for (i = 0; i < 16; i++) + I915_WRITE64(FENCE_REG_965_0 + (i * 8), 0); + break; + case 3: + if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) + for (i = 0; i < 8; i++) + I915_WRITE(FENCE_REG_945_8 + (i * 4), 0); + case 2: + for (i = 0; i < 8; i++) + I915_WRITE(FENCE_REG_830_0 + (i * 4), 0); + break; } - i915_gem_detect_bit_6_swizzle(dev); init_waitqueue_head(&dev_priv->pending_flip_queue); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c index e46b645773cf..b0abdc64aa9f 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -29,26 +29,6 @@ #include "i915_trace.h" #include "intel_drv.h" -/* XXX kill agp_type! */ -static unsigned int cache_level_to_agp_type(struct drm_device *dev, - enum i915_cache_level cache_level) -{ - switch (cache_level) { - case I915_CACHE_LLC_MLC: - if (INTEL_INFO(dev)->gen >= 6) - return AGP_USER_CACHED_MEMORY_LLC_MLC; - /* Older chipsets do not have this extra level of CPU - * cacheing, so fallthrough and request the PTE simply - * as cached. - */ - case I915_CACHE_LLC: - return AGP_USER_CACHED_MEMORY; - default: - case I915_CACHE_NONE: - return AGP_USER_MEMORY; - } -} - void i915_gem_restore_gtt_mappings(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -59,9 +39,6 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) (dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE); list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { - unsigned int agp_type = - cache_level_to_agp_type(dev, obj->cache_level); - i915_gem_clflush_object(obj); if (dev_priv->mm.gtt->needs_dmar) { @@ -69,14 +46,15 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) intel_gtt_insert_sg_entries(obj->sg_list, obj->num_sg, - obj->gtt_space->start >> PAGE_SHIFT, - agp_type); + obj->gtt_space->start + >> PAGE_SHIFT, + obj->agp_type); } else intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT, obj->base.size >> PAGE_SHIFT, obj->pages, - agp_type); + obj->agp_type); } intel_gtt_chipset_flush(); @@ -86,7 +64,6 @@ int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj) { struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - unsigned int agp_type = cache_level_to_agp_type(dev, obj->cache_level); int ret; if (dev_priv->mm.gtt->needs_dmar) { @@ -100,12 +77,12 @@ int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj) intel_gtt_insert_sg_entries(obj->sg_list, obj->num_sg, obj->gtt_space->start >> PAGE_SHIFT, - agp_type); + obj->agp_type); } else intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT, obj->base.size >> PAGE_SHIFT, obj->pages, - agp_type); + obj->agp_type); return 0; } diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c index 82d70fd9e933..281ad3d6115d 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -92,7 +92,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; - if (INTEL_INFO(dev)->gen >= 5) { + if (IS_GEN5(dev) || IS_GEN6(dev)) { /* On Ironlake whatever DRAM config, GPU always do * same swizzling setup. */ diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 349a03e48481..188b497e5076 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -367,30 +367,22 @@ static void notify_ring(struct drm_device *dev, jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); } -static void gen6_pm_rps_work(struct work_struct *work) +static void gen6_pm_irq_handler(struct drm_device *dev) { - drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, - rps_work); + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u8 new_delay = dev_priv->cur_delay; - u32 pm_iir, pm_imr; - - spin_lock_irq(&dev_priv->rps_lock); - pm_iir = dev_priv->pm_iir; - dev_priv->pm_iir = 0; - pm_imr = I915_READ(GEN6_PMIMR); - spin_unlock_irq(&dev_priv->rps_lock); + u32 pm_iir; + pm_iir = I915_READ(GEN6_PMIIR); if (!pm_iir) return; - mutex_lock(&dev_priv->dev->struct_mutex); if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { if (dev_priv->cur_delay != dev_priv->max_delay) new_delay = dev_priv->cur_delay + 1; if (new_delay > dev_priv->max_delay) new_delay = dev_priv->max_delay; } else if (pm_iir & (GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT)) { - gen6_gt_force_wake_get(dev_priv); if (dev_priv->cur_delay != dev_priv->min_delay) new_delay = dev_priv->cur_delay - 1; if (new_delay < dev_priv->min_delay) { @@ -404,19 +396,13 @@ static void gen6_pm_rps_work(struct work_struct *work) I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, I915_READ(GEN6_RP_INTERRUPT_LIMITS) & ~0x3f0000); } - gen6_gt_force_wake_put(dev_priv); + } - gen6_set_rps(dev_priv->dev, new_delay); + gen6_set_rps(dev, new_delay); dev_priv->cur_delay = new_delay; - /* - * rps_lock not held here because clearing is non-destructive. There is - * an *extremely* unlikely race with gen6_rps_enable() that is prevented - * by holding struct_mutex for the duration of the write. - */ - I915_WRITE(GEN6_PMIMR, pm_imr & ~pm_iir); - mutex_unlock(&dev_priv->dev->struct_mutex); + I915_WRITE(GEN6_PMIIR, pm_iir); } static void pch_irq_handler(struct drm_device *dev) @@ -462,97 +448,8 @@ static void pch_irq_handler(struct drm_device *dev) DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); } -irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int ret = IRQ_NONE; - u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; - struct drm_i915_master_private *master_priv; - - atomic_inc(&dev_priv->irq_received); - - /* disable master interrupt before clearing iir */ - de_ier = I915_READ(DEIER); - I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); - POSTING_READ(DEIER); - - de_iir = I915_READ(DEIIR); - gt_iir = I915_READ(GTIIR); - pch_iir = I915_READ(SDEIIR); - pm_iir = I915_READ(GEN6_PMIIR); - - if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 && pm_iir == 0) - goto done; - - ret = IRQ_HANDLED; - - if (dev->primary->master) { - master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); - } - - if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) - notify_ring(dev, &dev_priv->ring[RCS]); - if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[VCS]); - if (gt_iir & GT_BLT_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[BCS]); - - if (de_iir & DE_GSE_IVB) - intel_opregion_gse_intr(dev); - - if (de_iir & DE_PLANEA_FLIP_DONE_IVB) { - intel_prepare_page_flip(dev, 0); - intel_finish_page_flip_plane(dev, 0); - } - - if (de_iir & DE_PLANEB_FLIP_DONE_IVB) { - intel_prepare_page_flip(dev, 1); - intel_finish_page_flip_plane(dev, 1); - } - - if (de_iir & DE_PIPEA_VBLANK_IVB) - drm_handle_vblank(dev, 0); - - if (de_iir & DE_PIPEB_VBLANK_IVB); - drm_handle_vblank(dev, 1); - - /* check event from PCH */ - if (de_iir & DE_PCH_EVENT_IVB) { - if (pch_iir & SDE_HOTPLUG_MASK_CPT) - queue_work(dev_priv->wq, &dev_priv->hotplug_work); - pch_irq_handler(dev); - } - - if (pm_iir & GEN6_PM_DEFERRED_EVENTS) { - unsigned long flags; - spin_lock_irqsave(&dev_priv->rps_lock, flags); - WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); - I915_WRITE(GEN6_PMIMR, pm_iir); - dev_priv->pm_iir |= pm_iir; - spin_unlock_irqrestore(&dev_priv->rps_lock, flags); - queue_work(dev_priv->wq, &dev_priv->rps_work); - } - - /* should clear PCH hotplug event before clear CPU irq */ - I915_WRITE(SDEIIR, pch_iir); - I915_WRITE(GTIIR, gt_iir); - I915_WRITE(DEIIR, de_iir); - I915_WRITE(GEN6_PMIIR, pm_iir); - -done: - I915_WRITE(DEIER, de_ier); - POSTING_READ(DEIER); - - return ret; -} - -irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) +static irqreturn_t ironlake_irq_handler(struct drm_device *dev) { - struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret = IRQ_NONE; u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; @@ -560,8 +457,6 @@ irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) struct drm_i915_master_private *master_priv; u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; - atomic_inc(&dev_priv->irq_received); - if (IS_GEN6(dev)) bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT; @@ -631,30 +526,13 @@ irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) i915_handle_rps_change(dev); } - if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS) { - /* - * IIR bits should never already be set because IMR should - * prevent an interrupt from being shown in IIR. The warning - * displays a case where we've unsafely cleared - * dev_priv->pm_iir. Although missing an interrupt of the same - * type is not a problem, it displays a problem in the logic. - * - * The mask bit in IMR is cleared by rps_work. - */ - unsigned long flags; - spin_lock_irqsave(&dev_priv->rps_lock, flags); - WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); - I915_WRITE(GEN6_PMIMR, pm_iir); - dev_priv->pm_iir |= pm_iir; - spin_unlock_irqrestore(&dev_priv->rps_lock, flags); - queue_work(dev_priv->wq, &dev_priv->rps_work); - } + if (IS_GEN6(dev)) + gen6_pm_irq_handler(dev); /* should clear PCH hotplug event before clear CPU irq */ I915_WRITE(SDEIIR, pch_iir); I915_WRITE(GTIIR, gt_iir); I915_WRITE(DEIIR, de_iir); - I915_WRITE(GEN6_PMIIR, pm_iir); done: I915_WRITE(DEIER, de_ier); @@ -798,7 +676,7 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, err->dirty = obj->dirty; err->purgeable = obj->madv != I915_MADV_WILLNEED; err->ring = obj->ring ? obj->ring->id : 0; - err->cache_level = obj->cache_level; + err->agp_type = obj->agp_type == AGP_USER_CACHED_MEMORY; if (++i == count) break; @@ -1225,6 +1103,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) atomic_inc(&dev_priv->irq_received); + if (HAS_PCH_SPLIT(dev)) + return ironlake_irq_handler(dev); + iir = I915_READ(IIR); if (INTEL_INFO(dev)->gen >= 4) @@ -1463,7 +1344,10 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) return -EINVAL; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - if (INTEL_INFO(dev)->gen >= 4) + if (HAS_PCH_SPLIT(dev)) + ironlake_enable_display_irq(dev_priv, (pipe == 0) ? + DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); + else if (INTEL_INFO(dev)->gen >= 4) i915_enable_pipestat(dev_priv, pipe, PIPE_START_VBLANK_INTERRUPT_ENABLE); else @@ -1478,38 +1362,6 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) return 0; } -int ironlake_enable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - if (!i915_pipe_enabled(dev, pipe)) - return -EINVAL; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ironlake_enable_display_irq(dev_priv, (pipe == 0) ? - DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - - return 0; -} - -int ivybridge_enable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - if (!i915_pipe_enabled(dev, pipe)) - return -EINVAL; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ironlake_enable_display_irq(dev_priv, (pipe == 0) ? - DE_PIPEA_VBLANK_IVB : DE_PIPEB_VBLANK_IVB); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - - return 0; -} - /* Called from drm generic code, passed 'crtc' which * we use as a pipe index */ @@ -1523,31 +1375,13 @@ void i915_disable_vblank(struct drm_device *dev, int pipe) I915_WRITE(INSTPM, INSTPM_AGPBUSY_DIS << 16 | INSTPM_AGPBUSY_DIS); - i915_disable_pipestat(dev_priv, pipe, - PIPE_VBLANK_INTERRUPT_ENABLE | - PIPE_START_VBLANK_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); -} - -void ironlake_disable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ironlake_disable_display_irq(dev_priv, (pipe == 0) ? - DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); -} - -void ivybridge_disable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ironlake_disable_display_irq(dev_priv, (pipe == 0) ? - DE_PIPEA_VBLANK_IVB : DE_PIPEB_VBLANK_IVB); + if (HAS_PCH_SPLIT(dev)) + ironlake_disable_display_irq(dev_priv, (pipe == 0) ? + DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); + else + i915_disable_pipestat(dev_priv, pipe, + PIPE_VBLANK_INTERRUPT_ENABLE | + PIPE_START_VBLANK_INTERRUPT_ENABLE); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } @@ -1728,15 +1562,10 @@ void i915_hangcheck_elapsed(unsigned long data) /* drm_dma.h hooks */ -void ironlake_irq_preinstall(struct drm_device *dev) +static void ironlake_irq_preinstall(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - atomic_set(&dev_priv->irq_received, 0); - - INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); - INIT_WORK(&dev_priv->error_work, i915_error_work_func); - I915_WRITE(HWSTAM, 0xeffe); /* XXX hotplug from PCH */ @@ -1756,7 +1585,7 @@ void ironlake_irq_preinstall(struct drm_device *dev) POSTING_READ(SDEIER); } -int ironlake_irq_postinstall(struct drm_device *dev) +static int ironlake_irq_postinstall(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; /* enable kind of interrupts always enabled */ @@ -1765,13 +1594,6 @@ int ironlake_irq_postinstall(struct drm_device *dev) u32 render_irqs; u32 hotplug_mask; - DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue); - if (HAS_BSD(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue); - if (HAS_BLT(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue); - - dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; dev_priv->irq_mask = ~display_mask; /* should always can generate irq */ @@ -1828,56 +1650,6 @@ int ironlake_irq_postinstall(struct drm_device *dev) return 0; } -int ivybridge_irq_postinstall(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - /* enable kind of interrupts always enabled */ - u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | - DE_PCH_EVENT_IVB | DE_PLANEA_FLIP_DONE_IVB | - DE_PLANEB_FLIP_DONE_IVB; - u32 render_irqs; - u32 hotplug_mask; - - DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue); - if (HAS_BSD(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue); - if (HAS_BLT(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue); - - dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; - dev_priv->irq_mask = ~display_mask; - - /* should always can generate irq */ - I915_WRITE(DEIIR, I915_READ(DEIIR)); - I915_WRITE(DEIMR, dev_priv->irq_mask); - I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK_IVB | - DE_PIPEB_VBLANK_IVB); - POSTING_READ(DEIER); - - dev_priv->gt_irq_mask = ~0; - - I915_WRITE(GTIIR, I915_READ(GTIIR)); - I915_WRITE(GTIMR, dev_priv->gt_irq_mask); - - render_irqs = GT_USER_INTERRUPT | GT_GEN6_BSD_USER_INTERRUPT | - GT_BLT_USER_INTERRUPT; - I915_WRITE(GTIER, render_irqs); - POSTING_READ(GTIER); - - hotplug_mask = (SDE_CRT_HOTPLUG_CPT | - SDE_PORTB_HOTPLUG_CPT | - SDE_PORTC_HOTPLUG_CPT | - SDE_PORTD_HOTPLUG_CPT); - dev_priv->pch_irq_mask = ~hotplug_mask; - - I915_WRITE(SDEIIR, I915_READ(SDEIIR)); - I915_WRITE(SDEIMR, dev_priv->pch_irq_mask); - I915_WRITE(SDEIER, hotplug_mask); - POSTING_READ(SDEIER); - - return 0; -} - void i915_driver_irq_preinstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -1887,7 +1659,11 @@ void i915_driver_irq_preinstall(struct drm_device * dev) INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); INIT_WORK(&dev_priv->error_work, i915_error_work_func); - INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); + + if (HAS_PCH_SPLIT(dev)) { + ironlake_irq_preinstall(dev); + return; + } if (I915_HAS_HOTPLUG(dev)) { I915_WRITE(PORT_HOTPLUG_EN, 0); @@ -1912,8 +1688,17 @@ int i915_driver_irq_postinstall(struct drm_device *dev) u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; u32 error_mask; + DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue); + if (HAS_BSD(dev)) + DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue); + if (HAS_BLT(dev)) + DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue); + dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; + if (HAS_PCH_SPLIT(dev)) + return ironlake_irq_postinstall(dev); + /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX; @@ -1982,15 +1767,9 @@ int i915_driver_irq_postinstall(struct drm_device *dev) return 0; } -void ironlake_irq_uninstall(struct drm_device *dev) +static void ironlake_irq_uninstall(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - if (!dev_priv) - return; - - dev_priv->vblank_pipe = 0; - I915_WRITE(HWSTAM, 0xffffffff); I915_WRITE(DEIMR, 0xffffffff); @@ -2012,6 +1791,11 @@ void i915_driver_irq_uninstall(struct drm_device * dev) dev_priv->vblank_pipe = 0; + if (HAS_PCH_SPLIT(dev)) { + ironlake_irq_uninstall(dev); + return; + } + if (I915_HAS_HOTPLUG(dev)) { I915_WRITE(PORT_HOTPLUG_EN, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 2f967af8e62e..f39ac3a0fa93 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -291,9 +291,6 @@ #define RING_MAX_IDLE(base) ((base)+0x54) #define RING_HWS_PGA(base) ((base)+0x80) #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) -#define RENDER_HWS_PGA_GEN7 (0x04080) -#define BSD_HWS_PGA_GEN7 (0x04180) -#define BLT_HWS_PGA_GEN7 (0x04280) #define RING_ACTHD(base) ((base)+0x74) #define RING_NOPID(base) ((base)+0x94) #define RING_IMR(base) ((base)+0xa8) @@ -2781,19 +2778,6 @@ #define DE_PIPEA_VSYNC (1 << 3) #define DE_PIPEA_FIFO_UNDERRUN (1 << 0) -/* More Ivybridge lolz */ -#define DE_ERR_DEBUG_IVB (1<<30) -#define DE_GSE_IVB (1<<29) -#define DE_PCH_EVENT_IVB (1<<28) -#define DE_DP_A_HOTPLUG_IVB (1<<27) -#define DE_AUX_CHANNEL_A_IVB (1<<26) -#define DE_SPRITEB_FLIP_DONE_IVB (1<<9) -#define DE_SPRITEA_FLIP_DONE_IVB (1<<4) -#define DE_PLANEB_FLIP_DONE_IVB (1<<8) -#define DE_PLANEA_FLIP_DONE_IVB (1<<3) -#define DE_PIPEB_VBLANK_IVB (1<<5) -#define DE_PIPEA_VBLANK_IVB (1<<0) - #define DEISR 0x44000 #define DEIMR 0x44004 #define DEIIR 0x44008 @@ -2825,7 +2809,6 @@ #define ILK_eDP_A_DISABLE (1<<24) #define ILK_DESKTOP (1<<23) #define ILK_DSPCLK_GATE 0x42020 -#define IVB_VRHUNIT_CLK_GATE (1<<28) #define ILK_DPARB_CLK_GATE (1<<5) #define ILK_DPFD_CLK_GATE (1<<7) @@ -3074,9 +3057,6 @@ #define TRANS_6BPC (2<<5) #define TRANS_12BPC (3<<5) -#define SOUTH_CHICKEN2 0xc2004 -#define DPLS_EDP_PPS_FIX_DIS (1<<0) - #define _FDI_RXA_CHICKEN 0xc200c #define _FDI_RXB_CHICKEN 0xc2010 #define FDI_RX_PHASE_SYNC_POINTER_OVR (1<<1) @@ -3124,15 +3104,7 @@ #define FDI_TX_ENHANCE_FRAME_ENABLE (1<<18) /* Ironlake: hardwired to 1 */ #define FDI_TX_PLL_ENABLE (1<<14) - -/* Ivybridge has different bits for lolz */ -#define FDI_LINK_TRAIN_PATTERN_1_IVB (0<<8) -#define FDI_LINK_TRAIN_PATTERN_2_IVB (1<<8) -#define FDI_LINK_TRAIN_PATTERN_IDLE_IVB (2<<8) -#define FDI_LINK_TRAIN_NONE_IVB (3<<8) - /* both Tx and Rx */ -#define FDI_LINK_TRAIN_AUTO (1<<10) #define FDI_SCRAMBLING_ENABLE (0<<7) #define FDI_SCRAMBLING_DISABLE (1<<7) @@ -3142,8 +3114,6 @@ #define FDI_RX_CTL(pipe) _PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL) #define FDI_RX_ENABLE (1<<31) /* train, dp width same as FDI_TX */ -#define FDI_FS_ERRC_ENABLE (1<<27) -#define FDI_FE_ERRC_ENABLE (1<<26) #define FDI_DP_PORT_WIDTH_X8 (7<<19) #define FDI_8BPC (0<<16) #define FDI_10BPC (1<<16) @@ -3416,7 +3386,7 @@ #define GEN6_PMINTRMSK 0xA168 #define GEN6_PMISR 0x44020 -#define GEN6_PMIMR 0x44024 /* rps_lock */ +#define GEN6_PMIMR 0x44024 #define GEN6_PMIIR 0x44028 #define GEN6_PMIER 0x4402C #define GEN6_PM_MBOX_EVENT (1<<25) @@ -3426,9 +3396,6 @@ #define GEN6_PM_RP_DOWN_THRESHOLD (1<<4) #define GEN6_PM_RP_UP_EI_EXPIRED (1<<2) #define GEN6_PM_RP_DOWN_EI_EXPIRED (1<<1) -#define GEN6_PM_DEFERRED_EVENTS (GEN6_PM_RP_UP_THRESHOLD | \ - GEN6_PM_RP_DOWN_THRESHOLD | \ - GEN6_PM_RP_DOWN_TIMEOUT) #define GEN6_PCODE_MAILBOX 0x138124 #define GEN6_PCODE_READY (1<<31) diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index 60a94d2b5264..da474153a0a2 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -863,7 +863,8 @@ int i915_restore_state(struct drm_device *dev) I915_WRITE(IMR, dev_priv->saveIMR); } - intel_init_clock_gating(dev); + /* Clock gating state */ + intel_enable_clock_gating(dev); if (IS_IRONLAKE_M(dev)) { ironlake_enable_drps(dev); diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index e93f93cc7e78..d03fc05b39c0 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -305,11 +305,13 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) } static enum drm_connector_status -intel_crt_load_detect(struct intel_crt *crt) +intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt) { - struct drm_device *dev = crt->base.base.dev; + struct drm_encoder *encoder = &crt->base.base; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t pipe = to_intel_crtc(crt->base.base.crtc)->pipe; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint32_t pipe = intel_crtc->pipe; uint32_t save_bclrpat; uint32_t save_vtotal; uint32_t vtotal, vactive; @@ -430,6 +432,7 @@ intel_crt_detect(struct drm_connector *connector, bool force) struct drm_device *dev = connector->dev; struct intel_crt *crt = intel_attached_crt(connector); struct drm_crtc *crtc; + int dpms_mode; enum drm_connector_status status; if (I915_HAS_HOTPLUG(dev)) { @@ -451,18 +454,17 @@ intel_crt_detect(struct drm_connector *connector, bool force) /* for pre-945g platforms use load detect */ crtc = crt->base.base.crtc; if (crtc && crtc->enabled) { - status = intel_crt_load_detect(crt); + status = intel_crt_load_detect(crtc, crt); } else { - struct intel_load_detect_pipe tmp; - - if (intel_get_load_detect_pipe(&crt->base, connector, NULL, - &tmp)) { + crtc = intel_get_load_detect_pipe(&crt->base, connector, + NULL, &dpms_mode); + if (crtc) { if (intel_crt_detect_ddc(connector)) status = connector_status_connected; else - status = intel_crt_load_detect(crt); - intel_release_load_detect_pipe(&crt->base, connector, - &tmp); + status = intel_crt_load_detect(crtc, crt); + intel_release_load_detect_pipe(&crt->base, + connector, dpms_mode); } else status = connector_status_unknown; } diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 565eb2cc0042..21a7e70feacc 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -76,6 +76,255 @@ struct intel_limit { int, int, intel_clock_t *); }; +#define I8XX_DOT_MIN 25000 +#define I8XX_DOT_MAX 350000 +#define I8XX_VCO_MIN 930000 +#define I8XX_VCO_MAX 1400000 +#define I8XX_N_MIN 3 +#define I8XX_N_MAX 16 +#define I8XX_M_MIN 96 +#define I8XX_M_MAX 140 +#define I8XX_M1_MIN 18 +#define I8XX_M1_MAX 26 +#define I8XX_M2_MIN 6 +#define I8XX_M2_MAX 16 +#define I8XX_P_MIN 4 +#define I8XX_P_MAX 128 +#define I8XX_P1_MIN 2 +#define I8XX_P1_MAX 33 +#define I8XX_P1_LVDS_MIN 1 +#define I8XX_P1_LVDS_MAX 6 +#define I8XX_P2_SLOW 4 +#define I8XX_P2_FAST 2 +#define I8XX_P2_LVDS_SLOW 14 +#define I8XX_P2_LVDS_FAST 7 +#define I8XX_P2_SLOW_LIMIT 165000 + +#define I9XX_DOT_MIN 20000 +#define I9XX_DOT_MAX 400000 +#define I9XX_VCO_MIN 1400000 +#define I9XX_VCO_MAX 2800000 +#define PINEVIEW_VCO_MIN 1700000 +#define PINEVIEW_VCO_MAX 3500000 +#define I9XX_N_MIN 1 +#define I9XX_N_MAX 6 +/* Pineview's Ncounter is a ring counter */ +#define PINEVIEW_N_MIN 3 +#define PINEVIEW_N_MAX 6 +#define I9XX_M_MIN 70 +#define I9XX_M_MAX 120 +#define PINEVIEW_M_MIN 2 +#define PINEVIEW_M_MAX 256 +#define I9XX_M1_MIN 10 +#define I9XX_M1_MAX 22 +#define I9XX_M2_MIN 5 +#define I9XX_M2_MAX 9 +/* Pineview M1 is reserved, and must be 0 */ +#define PINEVIEW_M1_MIN 0 +#define PINEVIEW_M1_MAX 0 +#define PINEVIEW_M2_MIN 0 +#define PINEVIEW_M2_MAX 254 +#define I9XX_P_SDVO_DAC_MIN 5 +#define I9XX_P_SDVO_DAC_MAX 80 +#define I9XX_P_LVDS_MIN 7 +#define I9XX_P_LVDS_MAX 98 +#define PINEVIEW_P_LVDS_MIN 7 +#define PINEVIEW_P_LVDS_MAX 112 +#define I9XX_P1_MIN 1 +#define I9XX_P1_MAX 8 +#define I9XX_P2_SDVO_DAC_SLOW 10 +#define I9XX_P2_SDVO_DAC_FAST 5 +#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000 +#define I9XX_P2_LVDS_SLOW 14 +#define I9XX_P2_LVDS_FAST 7 +#define I9XX_P2_LVDS_SLOW_LIMIT 112000 + +/*The parameter is for SDVO on G4x platform*/ +#define G4X_DOT_SDVO_MIN 25000 +#define G4X_DOT_SDVO_MAX 270000 +#define G4X_VCO_MIN 1750000 +#define G4X_VCO_MAX 3500000 +#define G4X_N_SDVO_MIN 1 +#define G4X_N_SDVO_MAX 4 +#define G4X_M_SDVO_MIN 104 +#define G4X_M_SDVO_MAX 138 +#define G4X_M1_SDVO_MIN 17 +#define G4X_M1_SDVO_MAX 23 +#define G4X_M2_SDVO_MIN 5 +#define G4X_M2_SDVO_MAX 11 +#define G4X_P_SDVO_MIN 10 +#define G4X_P_SDVO_MAX 30 +#define G4X_P1_SDVO_MIN 1 +#define G4X_P1_SDVO_MAX 3 +#define G4X_P2_SDVO_SLOW 10 +#define G4X_P2_SDVO_FAST 10 +#define G4X_P2_SDVO_LIMIT 270000 + +/*The parameter is for HDMI_DAC on G4x platform*/ +#define G4X_DOT_HDMI_DAC_MIN 22000 +#define G4X_DOT_HDMI_DAC_MAX 400000 +#define G4X_N_HDMI_DAC_MIN 1 +#define G4X_N_HDMI_DAC_MAX 4 +#define G4X_M_HDMI_DAC_MIN 104 +#define G4X_M_HDMI_DAC_MAX 138 +#define G4X_M1_HDMI_DAC_MIN 16 +#define G4X_M1_HDMI_DAC_MAX 23 +#define G4X_M2_HDMI_DAC_MIN 5 +#define G4X_M2_HDMI_DAC_MAX 11 +#define G4X_P_HDMI_DAC_MIN 5 +#define G4X_P_HDMI_DAC_MAX 80 +#define G4X_P1_HDMI_DAC_MIN 1 +#define G4X_P1_HDMI_DAC_MAX 8 +#define G4X_P2_HDMI_DAC_SLOW 10 +#define G4X_P2_HDMI_DAC_FAST 5 +#define G4X_P2_HDMI_DAC_LIMIT 165000 + +/*The parameter is for SINGLE_CHANNEL_LVDS on G4x platform*/ +#define G4X_DOT_SINGLE_CHANNEL_LVDS_MIN 20000 +#define G4X_DOT_SINGLE_CHANNEL_LVDS_MAX 115000 +#define G4X_N_SINGLE_CHANNEL_LVDS_MIN 1 +#define G4X_N_SINGLE_CHANNEL_LVDS_MAX 3 +#define G4X_M_SINGLE_CHANNEL_LVDS_MIN 104 +#define G4X_M_SINGLE_CHANNEL_LVDS_MAX 138 +#define G4X_M1_SINGLE_CHANNEL_LVDS_MIN 17 +#define G4X_M1_SINGLE_CHANNEL_LVDS_MAX 23 +#define G4X_M2_SINGLE_CHANNEL_LVDS_MIN 5 +#define G4X_M2_SINGLE_CHANNEL_LVDS_MAX 11 +#define G4X_P_SINGLE_CHANNEL_LVDS_MIN 28 +#define G4X_P_SINGLE_CHANNEL_LVDS_MAX 112 +#define G4X_P1_SINGLE_CHANNEL_LVDS_MIN 2 +#define G4X_P1_SINGLE_CHANNEL_LVDS_MAX 8 +#define G4X_P2_SINGLE_CHANNEL_LVDS_SLOW 14 +#define G4X_P2_SINGLE_CHANNEL_LVDS_FAST 14 +#define G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT 0 + +/*The parameter is for DUAL_CHANNEL_LVDS on G4x platform*/ +#define G4X_DOT_DUAL_CHANNEL_LVDS_MIN 80000 +#define G4X_DOT_DUAL_CHANNEL_LVDS_MAX 224000 +#define G4X_N_DUAL_CHANNEL_LVDS_MIN 1 +#define G4X_N_DUAL_CHANNEL_LVDS_MAX 3 +#define G4X_M_DUAL_CHANNEL_LVDS_MIN 104 +#define G4X_M_DUAL_CHANNEL_LVDS_MAX 138 +#define G4X_M1_DUAL_CHANNEL_LVDS_MIN 17 +#define G4X_M1_DUAL_CHANNEL_LVDS_MAX 23 +#define G4X_M2_DUAL_CHANNEL_LVDS_MIN 5 +#define G4X_M2_DUAL_CHANNEL_LVDS_MAX 11 +#define G4X_P_DUAL_CHANNEL_LVDS_MIN 14 +#define G4X_P_DUAL_CHANNEL_LVDS_MAX 42 +#define G4X_P1_DUAL_CHANNEL_LVDS_MIN 2 +#define G4X_P1_DUAL_CHANNEL_LVDS_MAX 6 +#define G4X_P2_DUAL_CHANNEL_LVDS_SLOW 7 +#define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 +#define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 + +/*The parameter is for DISPLAY PORT on G4x platform*/ +#define G4X_DOT_DISPLAY_PORT_MIN 161670 +#define G4X_DOT_DISPLAY_PORT_MAX 227000 +#define G4X_N_DISPLAY_PORT_MIN 1 +#define G4X_N_DISPLAY_PORT_MAX 2 +#define G4X_M_DISPLAY_PORT_MIN 97 +#define G4X_M_DISPLAY_PORT_MAX 108 +#define G4X_M1_DISPLAY_PORT_MIN 0x10 +#define G4X_M1_DISPLAY_PORT_MAX 0x12 +#define G4X_M2_DISPLAY_PORT_MIN 0x05 +#define G4X_M2_DISPLAY_PORT_MAX 0x06 +#define G4X_P_DISPLAY_PORT_MIN 10 +#define G4X_P_DISPLAY_PORT_MAX 20 +#define G4X_P1_DISPLAY_PORT_MIN 1 +#define G4X_P1_DISPLAY_PORT_MAX 2 +#define G4X_P2_DISPLAY_PORT_SLOW 10 +#define G4X_P2_DISPLAY_PORT_FAST 10 +#define G4X_P2_DISPLAY_PORT_LIMIT 0 + +/* Ironlake / Sandybridge */ +/* as we calculate clock using (register_value + 2) for + N/M1/M2, so here the range value for them is (actual_value-2). + */ +#define IRONLAKE_DOT_MIN 25000 +#define IRONLAKE_DOT_MAX 350000 +#define IRONLAKE_VCO_MIN 1760000 +#define IRONLAKE_VCO_MAX 3510000 +#define IRONLAKE_M1_MIN 12 +#define IRONLAKE_M1_MAX 22 +#define IRONLAKE_M2_MIN 5 +#define IRONLAKE_M2_MAX 9 +#define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */ + +/* We have parameter ranges for different type of outputs. */ + +/* DAC & HDMI Refclk 120Mhz */ +#define IRONLAKE_DAC_N_MIN 1 +#define IRONLAKE_DAC_N_MAX 5 +#define IRONLAKE_DAC_M_MIN 79 +#define IRONLAKE_DAC_M_MAX 127 +#define IRONLAKE_DAC_P_MIN 5 +#define IRONLAKE_DAC_P_MAX 80 +#define IRONLAKE_DAC_P1_MIN 1 +#define IRONLAKE_DAC_P1_MAX 8 +#define IRONLAKE_DAC_P2_SLOW 10 +#define IRONLAKE_DAC_P2_FAST 5 + +/* LVDS single-channel 120Mhz refclk */ +#define IRONLAKE_LVDS_S_N_MIN 1 +#define IRONLAKE_LVDS_S_N_MAX 3 +#define IRONLAKE_LVDS_S_M_MIN 79 +#define IRONLAKE_LVDS_S_M_MAX 118 +#define IRONLAKE_LVDS_S_P_MIN 28 +#define IRONLAKE_LVDS_S_P_MAX 112 +#define IRONLAKE_LVDS_S_P1_MIN 2 +#define IRONLAKE_LVDS_S_P1_MAX 8 +#define IRONLAKE_LVDS_S_P2_SLOW 14 +#define IRONLAKE_LVDS_S_P2_FAST 14 + +/* LVDS dual-channel 120Mhz refclk */ +#define IRONLAKE_LVDS_D_N_MIN 1 +#define IRONLAKE_LVDS_D_N_MAX 3 +#define IRONLAKE_LVDS_D_M_MIN 79 +#define IRONLAKE_LVDS_D_M_MAX 127 +#define IRONLAKE_LVDS_D_P_MIN 14 +#define IRONLAKE_LVDS_D_P_MAX 56 +#define IRONLAKE_LVDS_D_P1_MIN 2 +#define IRONLAKE_LVDS_D_P1_MAX 8 +#define IRONLAKE_LVDS_D_P2_SLOW 7 +#define IRONLAKE_LVDS_D_P2_FAST 7 + +/* LVDS single-channel 100Mhz refclk */ +#define IRONLAKE_LVDS_S_SSC_N_MIN 1 +#define IRONLAKE_LVDS_S_SSC_N_MAX 2 +#define IRONLAKE_LVDS_S_SSC_M_MIN 79 +#define IRONLAKE_LVDS_S_SSC_M_MAX 126 +#define IRONLAKE_LVDS_S_SSC_P_MIN 28 +#define IRONLAKE_LVDS_S_SSC_P_MAX 112 +#define IRONLAKE_LVDS_S_SSC_P1_MIN 2 +#define IRONLAKE_LVDS_S_SSC_P1_MAX 8 +#define IRONLAKE_LVDS_S_SSC_P2_SLOW 14 +#define IRONLAKE_LVDS_S_SSC_P2_FAST 14 + +/* LVDS dual-channel 100Mhz refclk */ +#define IRONLAKE_LVDS_D_SSC_N_MIN 1 +#define IRONLAKE_LVDS_D_SSC_N_MAX 3 +#define IRONLAKE_LVDS_D_SSC_M_MIN 79 +#define IRONLAKE_LVDS_D_SSC_M_MAX 126 +#define IRONLAKE_LVDS_D_SSC_P_MIN 14 +#define IRONLAKE_LVDS_D_SSC_P_MAX 42 +#define IRONLAKE_LVDS_D_SSC_P1_MIN 2 +#define IRONLAKE_LVDS_D_SSC_P1_MAX 6 +#define IRONLAKE_LVDS_D_SSC_P2_SLOW 7 +#define IRONLAKE_LVDS_D_SSC_P2_FAST 7 + +/* DisplayPort */ +#define IRONLAKE_DP_N_MIN 1 +#define IRONLAKE_DP_N_MAX 2 +#define IRONLAKE_DP_M_MIN 81 +#define IRONLAKE_DP_M_MAX 90 +#define IRONLAKE_DP_P_MIN 10 +#define IRONLAKE_DP_P_MAX 20 +#define IRONLAKE_DP_P2_FAST 10 +#define IRONLAKE_DP_P2_SLOW 10 +#define IRONLAKE_DP_P2_LIMIT 0 +#define IRONLAKE_DP_P1_MIN 1 +#define IRONLAKE_DP_P1_MAX 2 + /* FDI */ #define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */ @@ -104,253 +353,292 @@ intel_fdi_link_freq(struct drm_device *dev) } static const intel_limit_t intel_limits_i8xx_dvo = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 930000, .max = 1400000 }, - .n = { .min = 3, .max = 16 }, - .m = { .min = 96, .max = 140 }, - .m1 = { .min = 18, .max = 26 }, - .m2 = { .min = 6, .max = 16 }, - .p = { .min = 4, .max = 128 }, - .p1 = { .min = 2, .max = 33 }, - .p2 = { .dot_limit = 165000, - .p2_slow = 4, .p2_fast = 2 }, + .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, + .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, + .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, + .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX }, + .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX }, + .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX }, + .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX }, + .p1 = { .min = I8XX_P1_MIN, .max = I8XX_P1_MAX }, + .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, + .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, .find_pll = intel_find_best_PLL, }; static const intel_limit_t intel_limits_i8xx_lvds = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 930000, .max = 1400000 }, - .n = { .min = 3, .max = 16 }, - .m = { .min = 96, .max = 140 }, - .m1 = { .min = 18, .max = 26 }, - .m2 = { .min = 6, .max = 16 }, - .p = { .min = 4, .max = 128 }, - .p1 = { .min = 1, .max = 6 }, - .p2 = { .dot_limit = 165000, - .p2_slow = 14, .p2_fast = 7 }, + .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, + .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, + .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, + .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX }, + .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX }, + .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX }, + .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX }, + .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX }, + .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, + .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, .find_pll = intel_find_best_PLL, }; - + static const intel_limit_t intel_limits_i9xx_sdvo = { - .dot = { .min = 20000, .max = 400000 }, - .vco = { .min = 1400000, .max = 2800000 }, - .n = { .min = 1, .max = 6 }, - .m = { .min = 70, .max = 120 }, - .m1 = { .min = 10, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 5, .max = 80 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 200000, - .p2_slow = 10, .p2_fast = 5 }, + .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, + .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, + .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, + .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX }, + .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX }, + .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX }, + .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX }, + .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, + .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, + .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, .find_pll = intel_find_best_PLL, }; static const intel_limit_t intel_limits_i9xx_lvds = { - .dot = { .min = 20000, .max = 400000 }, - .vco = { .min = 1400000, .max = 2800000 }, - .n = { .min = 1, .max = 6 }, - .m = { .min = 70, .max = 120 }, - .m1 = { .min = 10, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 7, .max = 98 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 112000, - .p2_slow = 14, .p2_fast = 7 }, + .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, + .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, + .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, + .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX }, + .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX }, + .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX }, + .p = { .min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX }, + .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, + /* The single-channel range is 25-112Mhz, and dual-channel + * is 80-224Mhz. Prefer single channel as much as possible. + */ + .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, + .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, .find_pll = intel_find_best_PLL, }; - + /* below parameter and function is for G4X Chipset Family*/ static const intel_limit_t intel_limits_g4x_sdvo = { - .dot = { .min = 25000, .max = 270000 }, - .vco = { .min = 1750000, .max = 3500000}, - .n = { .min = 1, .max = 4 }, - .m = { .min = 104, .max = 138 }, - .m1 = { .min = 17, .max = 23 }, - .m2 = { .min = 5, .max = 11 }, - .p = { .min = 10, .max = 30 }, - .p1 = { .min = 1, .max = 3}, - .p2 = { .dot_limit = 270000, - .p2_slow = 10, - .p2_fast = 10 + .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, + .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, + .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, + .m = { .min = G4X_M_SDVO_MIN, .max = G4X_M_SDVO_MAX }, + .m1 = { .min = G4X_M1_SDVO_MIN, .max = G4X_M1_SDVO_MAX }, + .m2 = { .min = G4X_M2_SDVO_MIN, .max = G4X_M2_SDVO_MAX }, + .p = { .min = G4X_P_SDVO_MIN, .max = G4X_P_SDVO_MAX }, + .p1 = { .min = G4X_P1_SDVO_MIN, .max = G4X_P1_SDVO_MAX}, + .p2 = { .dot_limit = G4X_P2_SDVO_LIMIT, + .p2_slow = G4X_P2_SDVO_SLOW, + .p2_fast = G4X_P2_SDVO_FAST }, .find_pll = intel_g4x_find_best_PLL, }; static const intel_limit_t intel_limits_g4x_hdmi = { - .dot = { .min = 22000, .max = 400000 }, - .vco = { .min = 1750000, .max = 3500000}, - .n = { .min = 1, .max = 4 }, - .m = { .min = 104, .max = 138 }, - .m1 = { .min = 16, .max = 23 }, - .m2 = { .min = 5, .max = 11 }, - .p = { .min = 5, .max = 80 }, - .p1 = { .min = 1, .max = 8}, - .p2 = { .dot_limit = 165000, - .p2_slow = 10, .p2_fast = 5 }, + .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, + .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, + .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, + .m = { .min = G4X_M_HDMI_DAC_MIN, .max = G4X_M_HDMI_DAC_MAX }, + .m1 = { .min = G4X_M1_HDMI_DAC_MIN, .max = G4X_M1_HDMI_DAC_MAX }, + .m2 = { .min = G4X_M2_HDMI_DAC_MIN, .max = G4X_M2_HDMI_DAC_MAX }, + .p = { .min = G4X_P_HDMI_DAC_MIN, .max = G4X_P_HDMI_DAC_MAX }, + .p1 = { .min = G4X_P1_HDMI_DAC_MIN, .max = G4X_P1_HDMI_DAC_MAX}, + .p2 = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT, + .p2_slow = G4X_P2_HDMI_DAC_SLOW, + .p2_fast = G4X_P2_HDMI_DAC_FAST + }, .find_pll = intel_g4x_find_best_PLL, }; static const intel_limit_t intel_limits_g4x_single_channel_lvds = { - .dot = { .min = 20000, .max = 115000 }, - .vco = { .min = 1750000, .max = 3500000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 104, .max = 138 }, - .m1 = { .min = 17, .max = 23 }, - .m2 = { .min = 5, .max = 11 }, - .p = { .min = 28, .max = 112 }, - .p1 = { .min = 2, .max = 8 }, - .p2 = { .dot_limit = 0, - .p2_slow = 14, .p2_fast = 14 + .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, + .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, + .vco = { .min = G4X_VCO_MIN, + .max = G4X_VCO_MAX }, + .n = { .min = G4X_N_SINGLE_CHANNEL_LVDS_MIN, + .max = G4X_N_SINGLE_CHANNEL_LVDS_MAX }, + .m = { .min = G4X_M_SINGLE_CHANNEL_LVDS_MIN, + .max = G4X_M_SINGLE_CHANNEL_LVDS_MAX }, + .m1 = { .min = G4X_M1_SINGLE_CHANNEL_LVDS_MIN, + .max = G4X_M1_SINGLE_CHANNEL_LVDS_MAX }, + .m2 = { .min = G4X_M2_SINGLE_CHANNEL_LVDS_MIN, + .max = G4X_M2_SINGLE_CHANNEL_LVDS_MAX }, + .p = { .min = G4X_P_SINGLE_CHANNEL_LVDS_MIN, + .max = G4X_P_SINGLE_CHANNEL_LVDS_MAX }, + .p1 = { .min = G4X_P1_SINGLE_CHANNEL_LVDS_MIN, + .max = G4X_P1_SINGLE_CHANNEL_LVDS_MAX }, + .p2 = { .dot_limit = G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT, + .p2_slow = G4X_P2_SINGLE_CHANNEL_LVDS_SLOW, + .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST }, .find_pll = intel_g4x_find_best_PLL, }; static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { - .dot = { .min = 80000, .max = 224000 }, - .vco = { .min = 1750000, .max = 3500000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 104, .max = 138 }, - .m1 = { .min = 17, .max = 23 }, - .m2 = { .min = 5, .max = 11 }, - .p = { .min = 14, .max = 42 }, - .p1 = { .min = 2, .max = 6 }, - .p2 = { .dot_limit = 0, - .p2_slow = 7, .p2_fast = 7 + .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, + .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, + .vco = { .min = G4X_VCO_MIN, + .max = G4X_VCO_MAX }, + .n = { .min = G4X_N_DUAL_CHANNEL_LVDS_MIN, + .max = G4X_N_DUAL_CHANNEL_LVDS_MAX }, + .m = { .min = G4X_M_DUAL_CHANNEL_LVDS_MIN, + .max = G4X_M_DUAL_CHANNEL_LVDS_MAX }, + .m1 = { .min = G4X_M1_DUAL_CHANNEL_LVDS_MIN, + .max = G4X_M1_DUAL_CHANNEL_LVDS_MAX }, + .m2 = { .min = G4X_M2_DUAL_CHANNEL_LVDS_MIN, + .max = G4X_M2_DUAL_CHANNEL_LVDS_MAX }, + .p = { .min = G4X_P_DUAL_CHANNEL_LVDS_MIN, + .max = G4X_P_DUAL_CHANNEL_LVDS_MAX }, + .p1 = { .min = G4X_P1_DUAL_CHANNEL_LVDS_MIN, + .max = G4X_P1_DUAL_CHANNEL_LVDS_MAX }, + .p2 = { .dot_limit = G4X_P2_DUAL_CHANNEL_LVDS_LIMIT, + .p2_slow = G4X_P2_DUAL_CHANNEL_LVDS_SLOW, + .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST }, .find_pll = intel_g4x_find_best_PLL, }; static const intel_limit_t intel_limits_g4x_display_port = { - .dot = { .min = 161670, .max = 227000 }, - .vco = { .min = 1750000, .max = 3500000}, - .n = { .min = 1, .max = 2 }, - .m = { .min = 97, .max = 108 }, - .m1 = { .min = 0x10, .max = 0x12 }, - .m2 = { .min = 0x05, .max = 0x06 }, - .p = { .min = 10, .max = 20 }, - .p1 = { .min = 1, .max = 2}, - .p2 = { .dot_limit = 0, - .p2_slow = 10, .p2_fast = 10 }, + .dot = { .min = G4X_DOT_DISPLAY_PORT_MIN, + .max = G4X_DOT_DISPLAY_PORT_MAX }, + .vco = { .min = G4X_VCO_MIN, + .max = G4X_VCO_MAX}, + .n = { .min = G4X_N_DISPLAY_PORT_MIN, + .max = G4X_N_DISPLAY_PORT_MAX }, + .m = { .min = G4X_M_DISPLAY_PORT_MIN, + .max = G4X_M_DISPLAY_PORT_MAX }, + .m1 = { .min = G4X_M1_DISPLAY_PORT_MIN, + .max = G4X_M1_DISPLAY_PORT_MAX }, + .m2 = { .min = G4X_M2_DISPLAY_PORT_MIN, + .max = G4X_M2_DISPLAY_PORT_MAX }, + .p = { .min = G4X_P_DISPLAY_PORT_MIN, + .max = G4X_P_DISPLAY_PORT_MAX }, + .p1 = { .min = G4X_P1_DISPLAY_PORT_MIN, + .max = G4X_P1_DISPLAY_PORT_MAX}, + .p2 = { .dot_limit = G4X_P2_DISPLAY_PORT_LIMIT, + .p2_slow = G4X_P2_DISPLAY_PORT_SLOW, + .p2_fast = G4X_P2_DISPLAY_PORT_FAST }, .find_pll = intel_find_pll_g4x_dp, }; static const intel_limit_t intel_limits_pineview_sdvo = { - .dot = { .min = 20000, .max = 400000}, - .vco = { .min = 1700000, .max = 3500000 }, - /* Pineview's Ncounter is a ring counter */ - .n = { .min = 3, .max = 6 }, - .m = { .min = 2, .max = 256 }, - /* Pineview only has one combined m divider, which we treat as m2. */ - .m1 = { .min = 0, .max = 0 }, - .m2 = { .min = 0, .max = 254 }, - .p = { .min = 5, .max = 80 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 200000, - .p2_slow = 10, .p2_fast = 5 }, + .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, + .vco = { .min = PINEVIEW_VCO_MIN, .max = PINEVIEW_VCO_MAX }, + .n = { .min = PINEVIEW_N_MIN, .max = PINEVIEW_N_MAX }, + .m = { .min = PINEVIEW_M_MIN, .max = PINEVIEW_M_MAX }, + .m1 = { .min = PINEVIEW_M1_MIN, .max = PINEVIEW_M1_MAX }, + .m2 = { .min = PINEVIEW_M2_MIN, .max = PINEVIEW_M2_MAX }, + .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX }, + .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, + .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, + .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, .find_pll = intel_find_best_PLL, }; static const intel_limit_t intel_limits_pineview_lvds = { - .dot = { .min = 20000, .max = 400000 }, - .vco = { .min = 1700000, .max = 3500000 }, - .n = { .min = 3, .max = 6 }, - .m = { .min = 2, .max = 256 }, - .m1 = { .min = 0, .max = 0 }, - .m2 = { .min = 0, .max = 254 }, - .p = { .min = 7, .max = 112 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 112000, - .p2_slow = 14, .p2_fast = 14 }, + .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, + .vco = { .min = PINEVIEW_VCO_MIN, .max = PINEVIEW_VCO_MAX }, + .n = { .min = PINEVIEW_N_MIN, .max = PINEVIEW_N_MAX }, + .m = { .min = PINEVIEW_M_MIN, .max = PINEVIEW_M_MAX }, + .m1 = { .min = PINEVIEW_M1_MIN, .max = PINEVIEW_M1_MAX }, + .m2 = { .min = PINEVIEW_M2_MIN, .max = PINEVIEW_M2_MAX }, + .p = { .min = PINEVIEW_P_LVDS_MIN, .max = PINEVIEW_P_LVDS_MAX }, + .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, + /* Pineview only supports single-channel mode. */ + .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, + .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, .find_pll = intel_find_best_PLL, }; -/* Ironlake / Sandybridge - * - * We calculate clock using (register_value + 2) for N/M1/M2, so here - * the range value for them is (actual_value - 2). - */ static const intel_limit_t intel_limits_ironlake_dac = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 5 }, - .m = { .min = 79, .max = 127 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 5, .max = 80 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 10, .p2_fast = 5 }, + .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, + .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, + .n = { .min = IRONLAKE_DAC_N_MIN, .max = IRONLAKE_DAC_N_MAX }, + .m = { .min = IRONLAKE_DAC_M_MIN, .max = IRONLAKE_DAC_M_MAX }, + .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, + .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, + .p = { .min = IRONLAKE_DAC_P_MIN, .max = IRONLAKE_DAC_P_MAX }, + .p1 = { .min = IRONLAKE_DAC_P1_MIN, .max = IRONLAKE_DAC_P1_MAX }, + .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, + .p2_slow = IRONLAKE_DAC_P2_SLOW, + .p2_fast = IRONLAKE_DAC_P2_FAST }, .find_pll = intel_g4x_find_best_PLL, }; static const intel_limit_t intel_limits_ironlake_single_lvds = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 79, .max = 118 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 28, .max = 112 }, - .p1 = { .min = 2, .max = 8 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 14, .p2_fast = 14 }, + .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, + .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, + .n = { .min = IRONLAKE_LVDS_S_N_MIN, .max = IRONLAKE_LVDS_S_N_MAX }, + .m = { .min = IRONLAKE_LVDS_S_M_MIN, .max = IRONLAKE_LVDS_S_M_MAX }, + .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, + .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, + .p = { .min = IRONLAKE_LVDS_S_P_MIN, .max = IRONLAKE_LVDS_S_P_MAX }, + .p1 = { .min = IRONLAKE_LVDS_S_P1_MIN, .max = IRONLAKE_LVDS_S_P1_MAX }, + .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, + .p2_slow = IRONLAKE_LVDS_S_P2_SLOW, + .p2_fast = IRONLAKE_LVDS_S_P2_FAST }, .find_pll = intel_g4x_find_best_PLL, }; static const intel_limit_t intel_limits_ironlake_dual_lvds = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 79, .max = 127 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 14, .max = 56 }, - .p1 = { .min = 2, .max = 8 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 7, .p2_fast = 7 }, + .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, + .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, + .n = { .min = IRONLAKE_LVDS_D_N_MIN, .max = IRONLAKE_LVDS_D_N_MAX }, + .m = { .min = IRONLAKE_LVDS_D_M_MIN, .max = IRONLAKE_LVDS_D_M_MAX }, + .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, + .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, + .p = { .min = IRONLAKE_LVDS_D_P_MIN, .max = IRONLAKE_LVDS_D_P_MAX }, + .p1 = { .min = IRONLAKE_LVDS_D_P1_MIN, .max = IRONLAKE_LVDS_D_P1_MAX }, + .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, + .p2_slow = IRONLAKE_LVDS_D_P2_SLOW, + .p2_fast = IRONLAKE_LVDS_D_P2_FAST }, .find_pll = intel_g4x_find_best_PLL, }; -/* LVDS 100mhz refclk limits. */ static const intel_limit_t intel_limits_ironlake_single_lvds_100m = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 2 }, - .m = { .min = 79, .max = 126 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 28, .max = 112 }, - .p1 = { .min = 2,.max = 8 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 14, .p2_fast = 14 }, + .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, + .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, + .n = { .min = IRONLAKE_LVDS_S_SSC_N_MIN, .max = IRONLAKE_LVDS_S_SSC_N_MAX }, + .m = { .min = IRONLAKE_LVDS_S_SSC_M_MIN, .max = IRONLAKE_LVDS_S_SSC_M_MAX }, + .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, + .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, + .p = { .min = IRONLAKE_LVDS_S_SSC_P_MIN, .max = IRONLAKE_LVDS_S_SSC_P_MAX }, + .p1 = { .min = IRONLAKE_LVDS_S_SSC_P1_MIN,.max = IRONLAKE_LVDS_S_SSC_P1_MAX }, + .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, + .p2_slow = IRONLAKE_LVDS_S_SSC_P2_SLOW, + .p2_fast = IRONLAKE_LVDS_S_SSC_P2_FAST }, .find_pll = intel_g4x_find_best_PLL, }; static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 79, .max = 126 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 14, .max = 42 }, - .p1 = { .min = 2,.max = 6 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 7, .p2_fast = 7 }, + .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, + .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, + .n = { .min = IRONLAKE_LVDS_D_SSC_N_MIN, .max = IRONLAKE_LVDS_D_SSC_N_MAX }, + .m = { .min = IRONLAKE_LVDS_D_SSC_M_MIN, .max = IRONLAKE_LVDS_D_SSC_M_MAX }, + .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, + .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, + .p = { .min = IRONLAKE_LVDS_D_SSC_P_MIN, .max = IRONLAKE_LVDS_D_SSC_P_MAX }, + .p1 = { .min = IRONLAKE_LVDS_D_SSC_P1_MIN,.max = IRONLAKE_LVDS_D_SSC_P1_MAX }, + .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, + .p2_slow = IRONLAKE_LVDS_D_SSC_P2_SLOW, + .p2_fast = IRONLAKE_LVDS_D_SSC_P2_FAST }, .find_pll = intel_g4x_find_best_PLL, }; static const intel_limit_t intel_limits_ironlake_display_port = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000}, - .n = { .min = 1, .max = 2 }, - .m = { .min = 81, .max = 90 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 10, .max = 20 }, - .p1 = { .min = 1, .max = 2}, - .p2 = { .dot_limit = 0, - .p2_slow = 10, .p2_fast = 10 }, + .dot = { .min = IRONLAKE_DOT_MIN, + .max = IRONLAKE_DOT_MAX }, + .vco = { .min = IRONLAKE_VCO_MIN, + .max = IRONLAKE_VCO_MAX}, + .n = { .min = IRONLAKE_DP_N_MIN, + .max = IRONLAKE_DP_N_MAX }, + .m = { .min = IRONLAKE_DP_M_MIN, + .max = IRONLAKE_DP_M_MAX }, + .m1 = { .min = IRONLAKE_M1_MIN, + .max = IRONLAKE_M1_MAX }, + .m2 = { .min = IRONLAKE_M2_MIN, + .max = IRONLAKE_M2_MAX }, + .p = { .min = IRONLAKE_DP_P_MIN, + .max = IRONLAKE_DP_P_MAX }, + .p1 = { .min = IRONLAKE_DP_P1_MIN, + .max = IRONLAKE_DP_P1_MAX}, + .p2 = { .dot_limit = IRONLAKE_DP_P2_LIMIT, + .p2_slow = IRONLAKE_DP_P2_SLOW, + .p2_fast = IRONLAKE_DP_P2_FAST }, .find_pll = intel_find_pll_ironlake_dp, }; @@ -1540,7 +1828,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev) u32 blt_ecoskpd; /* Make sure blitter notifies FBC of writes */ - gen6_gt_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD); blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY << GEN6_BLITTER_LOCK_SHIFT; @@ -1551,7 +1839,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev) GEN6_BLITTER_LOCK_SHIFT); I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); POSTING_READ(GEN6_BLITTER_ECOSKPD); - gen6_gt_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) @@ -2051,13 +2339,8 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc) /* enable normal train */ reg = FDI_TX_CTL(pipe); temp = I915_READ(reg); - if (IS_GEN6(dev)) { - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; - } else if (IS_IVYBRIDGE(dev)) { - temp &= ~FDI_LINK_TRAIN_NONE_IVB; - temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE; - } + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; I915_WRITE(reg, temp); reg = FDI_RX_CTL(pipe); @@ -2074,11 +2357,6 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc) /* wait one idle pattern time */ POSTING_READ(reg); udelay(1000); - - /* IVB wants error correction enabled */ - if (IS_IVYBRIDGE(dev)) - I915_WRITE(reg, I915_READ(reg) | FDI_FS_ERRC_ENABLE | - FDI_FE_ERRC_ENABLE); } /* The FDI link training functions for ILK/Ibexpeak. */ @@ -2306,116 +2584,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) DRM_DEBUG_KMS("FDI train done.\n"); } -/* Manual link training for Ivy Bridge A0 parts */ -static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) -{ - 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; - u32 reg, temp, i; - - /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit - for train result */ - reg = FDI_RX_IMR(pipe); - temp = I915_READ(reg); - temp &= ~FDI_RX_SYMBOL_LOCK; - temp &= ~FDI_RX_BIT_LOCK; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(150); - - /* enable CPU FDI TX and PCH FDI RX */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~(7 << 19); - temp |= (intel_crtc->fdi_lanes - 1) << 19; - temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB); - temp |= FDI_LINK_TRAIN_PATTERN_1_IVB; - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; - I915_WRITE(reg, temp | FDI_TX_ENABLE); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_AUTO; - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; - I915_WRITE(reg, temp | FDI_RX_ENABLE); - - POSTING_READ(reg); - udelay(150); - - for (i = 0; i < 4; i++ ) { - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= snb_b_fdi_train_param[i]; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(500); - - reg = FDI_RX_IIR(pipe); - temp = I915_READ(reg); - DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); - - if (temp & FDI_RX_BIT_LOCK || - (I915_READ(reg) & FDI_RX_BIT_LOCK)) { - I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); - DRM_DEBUG_KMS("FDI train 1 done.\n"); - break; - } - } - if (i == 4) - DRM_ERROR("FDI train 1 fail!\n"); - - /* Train 2 */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE_IVB; - temp |= FDI_LINK_TRAIN_PATTERN_2_IVB; - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; - I915_WRITE(reg, temp); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(150); - - for (i = 0; i < 4; i++ ) { - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= snb_b_fdi_train_param[i]; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(500); - - reg = FDI_RX_IIR(pipe); - temp = I915_READ(reg); - DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); - - if (temp & FDI_RX_SYMBOL_LOCK) { - I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); - DRM_DEBUG_KMS("FDI train 2 done.\n"); - break; - } - } - if (i == 4) - DRM_ERROR("FDI train 2 fail!\n"); - - DRM_DEBUG_KMS("FDI train done.\n"); -} - -static void ironlake_fdi_pll_enable(struct drm_crtc *crtc) +static void ironlake_fdi_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -2588,7 +2757,10 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) u32 reg, temp; /* For PCH output, training FDI link */ - dev_priv->display.fdi_link_train(crtc); + if (IS_GEN6(dev)) + gen6_fdi_link_train(crtc); + else + ironlake_fdi_link_train(crtc); intel_enable_pch_pll(dev_priv, pipe); @@ -2678,7 +2850,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) is_pch_port = intel_crtc_driving_pch(crtc); if (is_pch_port) - ironlake_fdi_pll_enable(crtc); + ironlake_fdi_enable(crtc); else ironlake_fdi_disable(crtc); @@ -2701,11 +2873,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) ironlake_pch_enable(crtc); intel_crtc_load_lut(crtc); - - mutex_lock(&dev->struct_mutex); intel_update_fbc(dev); - mutex_unlock(&dev->struct_mutex); - intel_crtc_update_cursor(crtc, true); } @@ -2801,11 +2969,8 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) intel_crtc->active = false; intel_update_watermarks(dev); - - mutex_lock(&dev->struct_mutex); intel_update_fbc(dev); intel_clear_scanline_wait(dev); - mutex_unlock(&dev->struct_mutex); } static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) @@ -4351,28 +4516,34 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) return dev_priv->lvds_use_ssc && i915_panel_use_ssc; } -static int i9xx_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) +static int intel_crtc_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) { 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; int plane = intel_crtc->plane; + u32 fp_reg, dpll_reg; int refclk, num_connectors = 0; intel_clock_t clock, reduced_clock; u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; + struct intel_encoder *has_edp_encoder = NULL; struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *encoder; const intel_limit_t *limit; int ret; - u32 temp; + struct fdi_m_n m_n = {0}; + u32 reg, temp; u32 lvds_sync = 0; + int target_clock; + + drm_vblank_pre_modeset(dev, pipe); list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { if (encoder->base.crtc != crtc) @@ -4400,6 +4571,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, case INTEL_OUTPUT_DISPLAYPORT: is_dp = true; break; + case INTEL_OUTPUT_EDP: + has_edp_encoder = encoder; + break; } num_connectors++; @@ -4411,6 +4585,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, refclk / 1000); } else if (!IS_GEN2(dev)) { refclk = 96000; + if (HAS_PCH_SPLIT(dev) && + (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base))) + refclk = 120000; /* 120Mhz refclk */ } else { refclk = 48000; } @@ -4424,6 +4601,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); + drm_vblank_post_modeset(dev, pipe); return -EINVAL; } @@ -4467,6 +4645,143 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, } } + /* FDI link */ + if (HAS_PCH_SPLIT(dev)) { + int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); + int lane = 0, link_bw, bpp; + /* CPU eDP doesn't require FDI link, so just set DP M/N + according to current link config */ + if (has_edp_encoder && !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { + target_clock = mode->clock; + intel_edp_link_config(has_edp_encoder, + &lane, &link_bw); + } else { + /* [e]DP over FDI requires target mode clock + instead of link clock */ + if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) + target_clock = mode->clock; + else + target_clock = adjusted_mode->clock; + + /* FDI is a binary signal running at ~2.7GHz, encoding + * each output octet as 10 bits. The actual frequency + * is stored as a divider into a 100MHz clock, and the + * mode pixel clock is stored in units of 1KHz. + * Hence the bw of each lane in terms of the mode signal + * is: + */ + link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; + } + + /* determine panel color depth */ + temp = I915_READ(PIPECONF(pipe)); + temp &= ~PIPE_BPC_MASK; + if (is_lvds) { + /* the BPC will be 6 if it is 18-bit LVDS panel */ + if ((I915_READ(PCH_LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) + temp |= PIPE_8BPC; + else + temp |= PIPE_6BPC; + } else if (has_edp_encoder) { + switch (dev_priv->edp.bpp/3) { + case 8: + temp |= PIPE_8BPC; + break; + case 10: + temp |= PIPE_10BPC; + break; + case 6: + temp |= PIPE_6BPC; + break; + case 12: + temp |= PIPE_12BPC; + break; + } + } else + temp |= PIPE_8BPC; + I915_WRITE(PIPECONF(pipe), temp); + + switch (temp & PIPE_BPC_MASK) { + case PIPE_8BPC: + bpp = 24; + break; + case PIPE_10BPC: + bpp = 30; + break; + case PIPE_6BPC: + bpp = 18; + break; + case PIPE_12BPC: + bpp = 36; + break; + default: + DRM_ERROR("unknown pipe bpc value\n"); + bpp = 24; + } + + if (!lane) { + /* + * Account for spread spectrum to avoid + * oversubscribing the link. Max center spread + * is 2.5%; use 5% for safety's sake. + */ + u32 bps = target_clock * bpp * 21 / 20; + lane = bps / (link_bw * 8) + 1; + } + + intel_crtc->fdi_lanes = lane; + + if (pixel_multiplier > 1) + link_bw *= pixel_multiplier; + ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); + } + + /* Ironlake: try to setup display ref clock before DPLL + * enabling. This is only under driver's control after + * PCH B stepping, previous chipset stepping should be + * ignoring this setting. + */ + if (HAS_PCH_SPLIT(dev)) { + temp = I915_READ(PCH_DREF_CONTROL); + /* Always enable nonspread source */ + temp &= ~DREF_NONSPREAD_SOURCE_MASK; + temp |= DREF_NONSPREAD_SOURCE_ENABLE; + temp &= ~DREF_SSC_SOURCE_MASK; + temp |= DREF_SSC_SOURCE_ENABLE; + I915_WRITE(PCH_DREF_CONTROL, temp); + + POSTING_READ(PCH_DREF_CONTROL); + udelay(200); + + if (has_edp_encoder) { + if (intel_panel_use_ssc(dev_priv)) { + temp |= DREF_SSC1_ENABLE; + I915_WRITE(PCH_DREF_CONTROL, temp); + + POSTING_READ(PCH_DREF_CONTROL); + udelay(200); + } + temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; + + /* Enable CPU source on CPU attached eDP */ + if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { + if (intel_panel_use_ssc(dev_priv)) + temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; + else + temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; + } else { + /* Enable SSC on PCH eDP if needed */ + if (intel_panel_use_ssc(dev_priv)) { + DRM_ERROR("enabling SSC on PCH\n"); + temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; + } + } + I915_WRITE(PCH_DREF_CONTROL, temp); + POSTING_READ(PCH_DREF_CONTROL); + udelay(200); + } + } + if (IS_PINEVIEW(dev)) { fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; if (has_reduced_clock) @@ -4479,7 +4794,25 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, reduced_clock.m2; } - dpll = DPLL_VGA_MODE_DIS; + /* Enable autotuning of the PLL clock (if permissible) */ + if (HAS_PCH_SPLIT(dev)) { + int factor = 21; + + if (is_lvds) { + if ((intel_panel_use_ssc(dev_priv) && + dev_priv->lvds_ssc_freq == 100) || + (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) + factor = 25; + } else if (is_sdvo && is_tv) + factor = 20; + + if (clock.m1 < factor * clock.n) + fp |= FP_CB_TUNE; + } + + dpll = 0; + if (!HAS_PCH_SPLIT(dev)) + dpll = DPLL_VGA_MODE_DIS; if (!IS_GEN2(dev)) { if (is_lvds) @@ -4491,10 +4824,12 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, if (pixel_multiplier > 1) { if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; + else if (HAS_PCH_SPLIT(dev)) + dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; } dpll |= DPLL_DVO_HIGH_SPEED; } - if (is_dp) + if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) dpll |= DPLL_DVO_HIGH_SPEED; /* compute bitmask from p1 value */ @@ -4502,6 +4837,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW; else { dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + /* also FPA1 */ + if (HAS_PCH_SPLIT(dev)) + dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; if (IS_G4X(dev) && has_reduced_clock) dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; } @@ -4519,7 +4857,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; break; } - if (INTEL_INFO(dev)->gen >= 4) + if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); } else { if (is_lvds) { @@ -4553,10 +4891,12 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, /* Ironlake's plane is forced to pipe, bit 24 is to enable color space conversion */ - if (pipe == 0) - dspcntr &= ~DISPPLANE_SEL_PIPE_MASK; - else - dspcntr |= DISPPLANE_SEL_PIPE_B; + if (!HAS_PCH_SPLIT(dev)) { + if (pipe == 0) + dspcntr &= ~DISPPLANE_SEL_PIPE_MASK; + else + dspcntr |= DISPPLANE_SEL_PIPE_B; + } if (pipe == 0 && INTEL_INFO(dev)->gen < 4) { /* Enable pixel doubling when the dot clock is > 90% of the (display) @@ -4572,28 +4912,74 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, pipeconf &= ~PIPECONF_DOUBLE_WIDE; } - dpll |= DPLL_VCO_ENABLE; + if (!HAS_PCH_SPLIT(dev)) + dpll |= DPLL_VCO_ENABLE; DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); drm_mode_debug_printmodeline(mode); - I915_WRITE(FP0(pipe), fp); - I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); + /* assign to Ironlake registers */ + if (HAS_PCH_SPLIT(dev)) { + fp_reg = PCH_FP0(pipe); + dpll_reg = PCH_DPLL(pipe); + } else { + fp_reg = FP0(pipe); + dpll_reg = DPLL(pipe); + } - POSTING_READ(DPLL(pipe)); - udelay(150); + /* PCH eDP needs FDI, but CPU eDP does not */ + if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { + I915_WRITE(fp_reg, fp); + I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + + POSTING_READ(dpll_reg); + udelay(150); + } + + /* enable transcoder DPLL */ + if (HAS_PCH_CPT(dev)) { + temp = I915_READ(PCH_DPLL_SEL); + switch (pipe) { + case 0: + temp |= TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL; + break; + case 1: + temp |= TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL; + break; + case 2: + /* FIXME: manage transcoder PLLs? */ + temp |= TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL; + break; + default: + BUG(); + } + I915_WRITE(PCH_DPLL_SEL, temp); + + POSTING_READ(PCH_DPLL_SEL); + udelay(150); + } /* The LVDS pin pair needs to be on before the DPLLs are enabled. * This is an exception to the general rule that mode_set doesn't turn * things on. */ if (is_lvds) { - temp = I915_READ(LVDS); + reg = LVDS; + if (HAS_PCH_SPLIT(dev)) + reg = PCH_LVDS; + + temp = I915_READ(reg); temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; if (pipe == 1) { - temp |= LVDS_PIPEB_SELECT; + if (HAS_PCH_CPT(dev)) + temp |= PORT_TRANS_B_SEL_CPT; + else + temp |= LVDS_PIPEB_SELECT; } else { - temp &= ~LVDS_PIPEB_SELECT; + if (HAS_PCH_CPT(dev)) + temp &= ~PORT_TRANS_SEL_MASK; + else + temp &= ~LVDS_PIPEB_SELECT; } /* set the corresponsding LVDS_BORDER bit */ temp |= dev_priv->lvds_border_bits; @@ -4609,8 +4995,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, * appropriately here, but we need to look more thoroughly into how * panels behave in the two modes. */ - /* set the dithering flag on LVDS as needed */ - if (INTEL_INFO(dev)->gen >= 4) { + /* set the dithering flag on non-PCH LVDS as needed */ + if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { if (dev_priv->lvds_dither) temp |= LVDS_ENABLE_DITHER; else @@ -4632,567 +5018,66 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); temp |= lvds_sync; } - I915_WRITE(LVDS, temp); + I915_WRITE(reg, temp); + } + + /* set the dithering flag and clear for anything other than a panel. */ + if (HAS_PCH_SPLIT(dev)) { + pipeconf &= ~PIPECONF_DITHER_EN; + pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; + if (dev_priv->lvds_dither && (is_lvds || has_edp_encoder)) { + pipeconf |= PIPECONF_DITHER_EN; + pipeconf |= PIPECONF_DITHER_TYPE_ST1; + } } - if (is_dp) { + if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { intel_dp_set_m_n(crtc, mode, adjusted_mode); + } else if (HAS_PCH_SPLIT(dev)) { + /* For non-DP output, clear any trans DP clock recovery setting.*/ + I915_WRITE(TRANSDATA_M1(pipe), 0); + I915_WRITE(TRANSDATA_N1(pipe), 0); + I915_WRITE(TRANSDPLINK_M1(pipe), 0); + I915_WRITE(TRANSDPLINK_N1(pipe), 0); } - I915_WRITE(DPLL(pipe), dpll); - - /* Wait for the clocks to stabilize. */ - POSTING_READ(DPLL(pipe)); - udelay(150); - - if (INTEL_INFO(dev)->gen >= 4) { - temp = 0; - if (is_sdvo) { - temp = intel_mode_get_pixel_multiplier(adjusted_mode); - if (temp > 1) - temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; - else - temp = 0; - } - I915_WRITE(DPLL_MD(pipe), temp); - } else { - /* The pixel multiplier can only be updated once the - * DPLL is enabled and the clocks are stable. - * - * So write it again. - */ - I915_WRITE(DPLL(pipe), dpll); - } - - intel_crtc->lowfreq_avail = false; - if (is_lvds && has_reduced_clock && i915_powersave) { - I915_WRITE(FP1(pipe), fp2); - intel_crtc->lowfreq_avail = true; - if (HAS_PIPE_CXSR(dev)) { - DRM_DEBUG_KMS("enabling CxSR downclocking\n"); - pipeconf |= PIPECONF_CXSR_DOWNCLOCK; - } - } else { - I915_WRITE(FP1(pipe), fp); - if (HAS_PIPE_CXSR(dev)) { - DRM_DEBUG_KMS("disabling CxSR downclocking\n"); - pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; - } - } - - if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { - pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; - /* the chip adds 2 halflines automatically */ - adjusted_mode->crtc_vdisplay -= 1; - adjusted_mode->crtc_vtotal -= 1; - adjusted_mode->crtc_vblank_start -= 1; - adjusted_mode->crtc_vblank_end -= 1; - adjusted_mode->crtc_vsync_end -= 1; - adjusted_mode->crtc_vsync_start -= 1; - } else - pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */ - - I915_WRITE(HTOTAL(pipe), - (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - I915_WRITE(HBLANK(pipe), - (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - I915_WRITE(HSYNC(pipe), - (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - - I915_WRITE(VTOTAL(pipe), - (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - I915_WRITE(VBLANK(pipe), - (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - I915_WRITE(VSYNC(pipe), - (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - - /* pipesrc and dspsize control the size that is scaled from, - * which should always be the user's requested size. - */ - I915_WRITE(DSPSIZE(plane), - ((mode->vdisplay - 1) << 16) | - (mode->hdisplay - 1)); - I915_WRITE(DSPPOS(plane), 0); - I915_WRITE(PIPESRC(pipe), - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - - I915_WRITE(PIPECONF(pipe), pipeconf); - POSTING_READ(PIPECONF(pipe)); - intel_enable_pipe(dev_priv, pipe, false); - - intel_wait_for_vblank(dev, pipe); - - I915_WRITE(DSPCNTR(plane), dspcntr); - POSTING_READ(DSPCNTR(plane)); - - ret = intel_pipe_set_base(crtc, x, y, old_fb); - - intel_update_watermarks(dev); - - return ret; -} - -static int ironlake_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - 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; - int plane = intel_crtc->plane; - int refclk, num_connectors = 0; - intel_clock_t clock, reduced_clock; - u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; - bool ok, has_reduced_clock = false, is_sdvo = false; - bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; - struct intel_encoder *has_edp_encoder = NULL; - struct drm_mode_config *mode_config = &dev->mode_config; - struct intel_encoder *encoder; - const intel_limit_t *limit; - int ret; - struct fdi_m_n m_n = {0}; - u32 temp; - u32 lvds_sync = 0; - int target_clock, pixel_multiplier, lane, link_bw, bpp, factor; - - list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { - if (encoder->base.crtc != crtc) - continue; - - switch (encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_SDVO: - case INTEL_OUTPUT_HDMI: - is_sdvo = true; - if (encoder->needs_tv_clock) - is_tv = true; - break; - case INTEL_OUTPUT_TVOUT: - is_tv = true; - break; - case INTEL_OUTPUT_ANALOG: - is_crt = true; - break; - case INTEL_OUTPUT_DISPLAYPORT: - is_dp = true; - break; - case INTEL_OUTPUT_EDP: - has_edp_encoder = encoder; - break; - } - - num_connectors++; - } - - if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { - refclk = dev_priv->lvds_ssc_freq * 1000; - DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", - refclk / 1000); - } else { - refclk = 96000; - if (!has_edp_encoder || - intel_encoder_is_pch_edp(&has_edp_encoder->base)) - refclk = 120000; /* 120Mhz refclk */ - } - - /* - * Returns a set of divisors for the desired target clock with the given - * refclk, or FALSE. The returned values represent the clock equation: - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. - */ - limit = intel_limit(crtc, refclk); - ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); - if (!ok) { - DRM_ERROR("Couldn't find PLL settings for mode!\n"); - return -EINVAL; - } - - /* Ensure that the cursor is valid for the new mode before changing... */ - intel_crtc_update_cursor(crtc, true); - - if (is_lvds && dev_priv->lvds_downclock_avail) { - has_reduced_clock = limit->find_pll(limit, crtc, - dev_priv->lvds_downclock, - refclk, - &reduced_clock); - if (has_reduced_clock && (clock.p != reduced_clock.p)) { - /* - * If the different P is found, it means that we can't - * switch the display clock by using the FP0/FP1. - * In such case we will disable the LVDS downclock - * feature. - */ - DRM_DEBUG_KMS("Different P is found for " - "LVDS clock/downclock\n"); - has_reduced_clock = 0; - } - } - /* SDVO TV has fixed PLL values depend on its clock range, - this mirrors vbios setting. */ - if (is_sdvo && is_tv) { - if (adjusted_mode->clock >= 100000 - && adjusted_mode->clock < 140500) { - clock.p1 = 2; - clock.p2 = 10; - clock.n = 3; - clock.m1 = 16; - clock.m2 = 8; - } else if (adjusted_mode->clock >= 140500 - && adjusted_mode->clock <= 200000) { - clock.p1 = 1; - clock.p2 = 10; - clock.n = 6; - clock.m1 = 12; - clock.m2 = 8; - } - } - - /* FDI link */ - pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); - lane = 0; - /* CPU eDP doesn't require FDI link, so just set DP M/N - according to current link config */ - if (has_edp_encoder && - !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - target_clock = mode->clock; - intel_edp_link_config(has_edp_encoder, - &lane, &link_bw); - } else { - /* [e]DP over FDI requires target mode clock - instead of link clock */ - if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) - target_clock = mode->clock; - else - target_clock = adjusted_mode->clock; - - /* FDI is a binary signal running at ~2.7GHz, encoding - * each output octet as 10 bits. The actual frequency - * is stored as a divider into a 100MHz clock, and the - * mode pixel clock is stored in units of 1KHz. - * Hence the bw of each lane in terms of the mode signal - * is: - */ - link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; - } - - /* determine panel color depth */ - temp = I915_READ(PIPECONF(pipe)); - temp &= ~PIPE_BPC_MASK; - if (is_lvds) { - /* the BPC will be 6 if it is 18-bit LVDS panel */ - if ((I915_READ(PCH_LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) - temp |= PIPE_8BPC; - else - temp |= PIPE_6BPC; - } else if (has_edp_encoder) { - switch (dev_priv->edp.bpp/3) { - case 8: - temp |= PIPE_8BPC; - break; - case 10: - temp |= PIPE_10BPC; - break; - case 6: - temp |= PIPE_6BPC; - break; - case 12: - temp |= PIPE_12BPC; - break; - } - } else - temp |= PIPE_8BPC; - I915_WRITE(PIPECONF(pipe), temp); - - switch (temp & PIPE_BPC_MASK) { - case PIPE_8BPC: - bpp = 24; - break; - case PIPE_10BPC: - bpp = 30; - break; - case PIPE_6BPC: - bpp = 18; - break; - case PIPE_12BPC: - bpp = 36; - break; - default: - DRM_ERROR("unknown pipe bpc value\n"); - bpp = 24; - } - - if (!lane) { - /* - * Account for spread spectrum to avoid - * oversubscribing the link. Max center spread - * is 2.5%; use 5% for safety's sake. - */ - u32 bps = target_clock * bpp * 21 / 20; - lane = bps / (link_bw * 8) + 1; - } - - intel_crtc->fdi_lanes = lane; - - if (pixel_multiplier > 1) - link_bw *= pixel_multiplier; - ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); - - /* Ironlake: try to setup display ref clock before DPLL - * enabling. This is only under driver's control after - * PCH B stepping, previous chipset stepping should be - * ignoring this setting. - */ - temp = I915_READ(PCH_DREF_CONTROL); - /* Always enable nonspread source */ - temp &= ~DREF_NONSPREAD_SOURCE_MASK; - temp |= DREF_NONSPREAD_SOURCE_ENABLE; - temp &= ~DREF_SSC_SOURCE_MASK; - temp |= DREF_SSC_SOURCE_ENABLE; - I915_WRITE(PCH_DREF_CONTROL, temp); - - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); - - if (has_edp_encoder) { - if (intel_panel_use_ssc(dev_priv)) { - temp |= DREF_SSC1_ENABLE; - I915_WRITE(PCH_DREF_CONTROL, temp); - - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); - } - temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; - - /* Enable CPU source on CPU attached eDP */ - if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - if (intel_panel_use_ssc(dev_priv)) - temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; - else - temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; - } else { - /* Enable SSC on PCH eDP if needed */ - if (intel_panel_use_ssc(dev_priv)) { - DRM_ERROR("enabling SSC on PCH\n"); - temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; - } - } - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); - } - - fp = clock.n << 16 | clock.m1 << 8 | clock.m2; - if (has_reduced_clock) - fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | - reduced_clock.m2; - - /* Enable autotuning of the PLL clock (if permissible) */ - factor = 21; - if (is_lvds) { - if ((intel_panel_use_ssc(dev_priv) && - dev_priv->lvds_ssc_freq == 100) || - (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) - factor = 25; - } else if (is_sdvo && is_tv) - factor = 20; - - if (clock.m1 < factor * clock.n) - fp |= FP_CB_TUNE; - - dpll = 0; - - if (is_lvds) - dpll |= DPLLB_MODE_LVDS; - else - dpll |= DPLLB_MODE_DAC_SERIAL; - if (is_sdvo) { - int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); - if (pixel_multiplier > 1) { - dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; - } - dpll |= DPLL_DVO_HIGH_SPEED; - } - if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) - dpll |= DPLL_DVO_HIGH_SPEED; - - /* compute bitmask from p1 value */ - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; - /* also FPA1 */ - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; - - switch (clock.p2) { - case 5: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; - break; - case 7: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7; - break; - case 10: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10; - break; - case 14: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; - break; - } - - if (is_sdvo && is_tv) - dpll |= PLL_REF_INPUT_TVCLKINBC; - else if (is_tv) - /* XXX: just matching BIOS for now */ - /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ - dpll |= 3; - else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) - dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; - else - dpll |= PLL_REF_INPUT_DREFCLK; - - /* setup pipeconf */ - pipeconf = I915_READ(PIPECONF(pipe)); - - /* Set up the display plane register */ - dspcntr = DISPPLANE_GAMMA_ENABLE; - - DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - drm_mode_debug_printmodeline(mode); - - /* PCH eDP needs FDI, but CPU eDP does not */ if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - I915_WRITE(PCH_FP0(pipe), fp); - I915_WRITE(PCH_DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); - - POSTING_READ(PCH_DPLL(pipe)); - udelay(150); - } - - /* enable transcoder DPLL */ - if (HAS_PCH_CPT(dev)) { - temp = I915_READ(PCH_DPLL_SEL); - switch (pipe) { - case 0: - temp |= TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL; - break; - case 1: - temp |= TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL; - break; - case 2: - /* FIXME: manage transcoder PLLs? */ - temp |= TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL; - break; - default: - BUG(); - } - I915_WRITE(PCH_DPLL_SEL, temp); + I915_WRITE(dpll_reg, dpll); - POSTING_READ(PCH_DPLL_SEL); + /* Wait for the clocks to stabilize. */ + POSTING_READ(dpll_reg); udelay(150); - } - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - if (is_lvds) { - temp = I915_READ(PCH_LVDS); - temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; - if (pipe == 1) { - if (HAS_PCH_CPT(dev)) - temp |= PORT_TRANS_B_SEL_CPT; - else - temp |= LVDS_PIPEB_SELECT; + if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { + temp = 0; + if (is_sdvo) { + temp = intel_mode_get_pixel_multiplier(adjusted_mode); + if (temp > 1) + temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; + else + temp = 0; + } + I915_WRITE(DPLL_MD(pipe), temp); } else { - if (HAS_PCH_CPT(dev)) - temp &= ~PORT_TRANS_SEL_MASK; - else - temp &= ~LVDS_PIPEB_SELECT; - } - /* set the corresponsding LVDS_BORDER bit */ - temp |= dev_priv->lvds_border_bits; - /* Set the B0-B3 data pairs corresponding to whether we're going to - * set the DPLLs for dual-channel mode or not. - */ - if (clock.p2 == 7) - temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - else - temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); - - /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) - * appropriately here, but we need to look more thoroughly into how - * panels behave in the two modes. - */ - if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) - lvds_sync |= LVDS_HSYNC_POLARITY; - if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) - lvds_sync |= LVDS_VSYNC_POLARITY; - if ((temp & (LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY)) - != lvds_sync) { - char flags[2] = "-+"; - DRM_INFO("Changing LVDS panel from " - "(%chsync, %cvsync) to (%chsync, %cvsync)\n", - flags[!(temp & LVDS_HSYNC_POLARITY)], - flags[!(temp & LVDS_VSYNC_POLARITY)], - flags[!(lvds_sync & LVDS_HSYNC_POLARITY)], - flags[!(lvds_sync & LVDS_VSYNC_POLARITY)]); - temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); - temp |= lvds_sync; + /* The pixel multiplier can only be updated once the + * DPLL is enabled and the clocks are stable. + * + * So write it again. + */ + I915_WRITE(dpll_reg, dpll); } - I915_WRITE(PCH_LVDS, temp); - } - - /* set the dithering flag and clear for anything other than a panel. */ - pipeconf &= ~PIPECONF_DITHER_EN; - pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; - if (dev_priv->lvds_dither && (is_lvds || has_edp_encoder)) { - pipeconf |= PIPECONF_DITHER_EN; - pipeconf |= PIPECONF_DITHER_TYPE_ST1; - } - - if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - intel_dp_set_m_n(crtc, mode, adjusted_mode); - } else { - /* For non-DP output, clear any trans DP clock recovery setting.*/ - I915_WRITE(TRANSDATA_M1(pipe), 0); - I915_WRITE(TRANSDATA_N1(pipe), 0); - I915_WRITE(TRANSDPLINK_M1(pipe), 0); - I915_WRITE(TRANSDPLINK_N1(pipe), 0); - } - - if (!has_edp_encoder || - intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - I915_WRITE(PCH_DPLL(pipe), dpll); - - /* Wait for the clocks to stabilize. */ - POSTING_READ(PCH_DPLL(pipe)); - udelay(150); - - /* The pixel multiplier can only be updated once the - * DPLL is enabled and the clocks are stable. - * - * So write it again. - */ - I915_WRITE(PCH_DPLL(pipe), dpll); } intel_crtc->lowfreq_avail = false; if (is_lvds && has_reduced_clock && i915_powersave) { - I915_WRITE(PCH_FP1(pipe), fp2); + I915_WRITE(fp_reg + 4, fp2); intel_crtc->lowfreq_avail = true; if (HAS_PIPE_CXSR(dev)) { DRM_DEBUG_KMS("enabling CxSR downclocking\n"); pipeconf |= PIPECONF_CXSR_DOWNCLOCK; } } else { - I915_WRITE(PCH_FP1(pipe), fp); + I915_WRITE(fp_reg + 4, fp); if (HAS_PIPE_CXSR(dev)) { DRM_DEBUG_KMS("disabling CxSR downclocking\n"); pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; @@ -5231,24 +5116,33 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); - /* pipesrc controls the size that is scaled from, which should - * always be the user's requested size. + /* pipesrc and dspsize control the size that is scaled from, + * which should always be the user's requested size. */ + if (!HAS_PCH_SPLIT(dev)) { + I915_WRITE(DSPSIZE(plane), + ((mode->vdisplay - 1) << 16) | + (mode->hdisplay - 1)); + I915_WRITE(DSPPOS(plane), 0); + } I915_WRITE(PIPESRC(pipe), ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m); - I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n); - I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m); - I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); + if (HAS_PCH_SPLIT(dev)) { + I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m); + I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n); + I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m); + I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); - if (has_edp_encoder && - !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - ironlake_set_pll_edp(crtc, adjusted_mode->clock); + if (has_edp_encoder && !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { + ironlake_set_pll_edp(crtc, adjusted_mode->clock); + } } I915_WRITE(PIPECONF(pipe), pipeconf); POSTING_READ(PIPECONF(pipe)); + if (!HAS_PCH_SPLIT(dev)) + intel_enable_pipe(dev_priv, pipe, false); intel_wait_for_vblank(dev, pipe); @@ -5259,31 +5153,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, } I915_WRITE(DSPCNTR(plane), dspcntr); - POSTING_READ(DSPCNTR(plane)); - - ret = intel_pipe_set_base(crtc, x, y, old_fb); - - intel_update_watermarks(dev); - - return ret; -} - -static int intel_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - 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; - int ret; + POSTING_READ(DSPCNTR(plane)); + if (!HAS_PCH_SPLIT(dev)) + intel_enable_plane(dev_priv, plane, pipe); - drm_vblank_pre_modeset(dev, pipe); + ret = intel_pipe_set_base(crtc, x, y, old_fb); - ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode, - x, y, old_fb); + intel_update_watermarks(dev); drm_vblank_post_modeset(dev, pipe); @@ -5607,140 +5483,43 @@ static struct drm_display_mode load_detect_mode = { 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), }; -static struct drm_framebuffer * -intel_framebuffer_create(struct drm_device *dev, - struct drm_mode_fb_cmd *mode_cmd, - struct drm_i915_gem_object *obj) -{ - struct intel_framebuffer *intel_fb; - int ret; - - intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); - if (!intel_fb) { - drm_gem_object_unreference_unlocked(&obj->base); - return ERR_PTR(-ENOMEM); - } - - ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); - if (ret) { - drm_gem_object_unreference_unlocked(&obj->base); - kfree(intel_fb); - return ERR_PTR(ret); - } - - return &intel_fb->base; -} - -static u32 -intel_framebuffer_pitch_for_width(int width, int bpp) -{ - u32 pitch = DIV_ROUND_UP(width * bpp, 8); - return ALIGN(pitch, 64); -} - -static u32 -intel_framebuffer_size_for_mode(struct drm_display_mode *mode, int bpp) -{ - u32 pitch = intel_framebuffer_pitch_for_width(mode->hdisplay, bpp); - return ALIGN(pitch * mode->vdisplay, PAGE_SIZE); -} - -static struct drm_framebuffer * -intel_framebuffer_create_for_mode(struct drm_device *dev, - struct drm_display_mode *mode, - int depth, int bpp) -{ - struct drm_i915_gem_object *obj; - struct drm_mode_fb_cmd mode_cmd; - - obj = i915_gem_alloc_object(dev, - intel_framebuffer_size_for_mode(mode, bpp)); - if (obj == NULL) - return ERR_PTR(-ENOMEM); - - mode_cmd.width = mode->hdisplay; - mode_cmd.height = mode->vdisplay; - mode_cmd.depth = depth; - mode_cmd.bpp = bpp; - mode_cmd.pitch = intel_framebuffer_pitch_for_width(mode_cmd.width, bpp); - - return intel_framebuffer_create(dev, &mode_cmd, obj); -} - -static struct drm_framebuffer * -mode_fits_in_fbdev(struct drm_device *dev, - struct drm_display_mode *mode) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - struct drm_framebuffer *fb; - - if (dev_priv->fbdev == NULL) - return NULL; - - obj = dev_priv->fbdev->ifb.obj; - if (obj == NULL) - return NULL; - - fb = &dev_priv->fbdev->ifb.base; - if (fb->pitch < intel_framebuffer_pitch_for_width(mode->hdisplay, - fb->bits_per_pixel)) - return NULL; - - if (obj->base.size < mode->vdisplay * fb->pitch) - return NULL; - - return fb; -} - -bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, - struct drm_connector *connector, - struct drm_display_mode *mode, - struct intel_load_detect_pipe *old) +struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, + struct drm_connector *connector, + struct drm_display_mode *mode, + int *dpms_mode) { struct intel_crtc *intel_crtc; struct drm_crtc *possible_crtc; + struct drm_crtc *supported_crtc =NULL; struct drm_encoder *encoder = &intel_encoder->base; struct drm_crtc *crtc = NULL; struct drm_device *dev = encoder->dev; - struct drm_framebuffer *old_fb; + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; + struct drm_crtc_helper_funcs *crtc_funcs; int i = -1; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", - connector->base.id, drm_get_connector_name(connector), - encoder->base.id, drm_get_encoder_name(encoder)); - /* * Algorithm gets a little messy: - * * - if the connector already has an assigned crtc, use it (but make * sure it's on first) - * * - try to find the first unused crtc that can drive this connector, * and use that if we find one + * - if there are no unused crtcs available, try to use the first + * one we found that supports the connector */ /* See if we already have a CRTC for this connector */ if (encoder->crtc) { crtc = encoder->crtc; - - intel_crtc = to_intel_crtc(crtc); - old->dpms_mode = intel_crtc->dpms_mode; - old->load_detect_temp = false; - /* Make sure the crtc and connector are running */ + intel_crtc = to_intel_crtc(crtc); + *dpms_mode = intel_crtc->dpms_mode; if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) { - struct drm_encoder_helper_funcs *encoder_funcs; - struct drm_crtc_helper_funcs *crtc_funcs; - crtc_funcs = crtc->helper_private; crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); - - encoder_funcs = encoder->helper_private; encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); } - - return true; + return crtc; } /* Find an unused one (if possible) */ @@ -5752,66 +5531,46 @@ bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, crtc = possible_crtc; break; } + if (!supported_crtc) + supported_crtc = possible_crtc; } /* * If we didn't find an unused CRTC, don't use any. */ if (!crtc) { - DRM_DEBUG_KMS("no pipe available for load-detect\n"); - return false; + return NULL; } encoder->crtc = crtc; connector->encoder = encoder; + intel_encoder->load_detect_temp = true; intel_crtc = to_intel_crtc(crtc); - old->dpms_mode = intel_crtc->dpms_mode; - old->load_detect_temp = true; - old->release_fb = NULL; - - if (!mode) - mode = &load_detect_mode; - - old_fb = crtc->fb; + *dpms_mode = intel_crtc->dpms_mode; - /* We need a framebuffer large enough to accommodate all accesses - * that the plane may generate whilst we perform load detection. - * We can not rely on the fbcon either being present (we get called - * during its initialisation to detect all boot displays, or it may - * not even exist) or that it is large enough to satisfy the - * requested mode. - */ - crtc->fb = mode_fits_in_fbdev(dev, mode); - if (crtc->fb == NULL) { - DRM_DEBUG_KMS("creating tmp fb for load-detection\n"); - crtc->fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32); - old->release_fb = crtc->fb; - } else - DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n"); - if (IS_ERR(crtc->fb)) { - DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n"); - crtc->fb = old_fb; - return false; - } + if (!crtc->enabled) { + if (!mode) + mode = &load_detect_mode; + drm_crtc_helper_set_mode(crtc, mode, 0, 0, crtc->fb); + } else { + if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) { + crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); + } - if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, old_fb)) { - DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); - if (old->release_fb) - old->release_fb->funcs->destroy(old->release_fb); - crtc->fb = old_fb; - return false; + /* Add this connector to the crtc */ + encoder_funcs->mode_set(encoder, &crtc->mode, &crtc->mode); + encoder_funcs->commit(encoder); } - /* let the connector get through one full cycle before testing */ intel_wait_for_vblank(dev, intel_crtc->pipe); - return true; + return crtc; } void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, - struct drm_connector *connector, - struct intel_load_detect_pipe *old) + struct drm_connector *connector, int dpms_mode) { struct drm_encoder *encoder = &intel_encoder->base; struct drm_device *dev = encoder->dev; @@ -5819,24 +5578,19 @@ void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", - connector->base.id, drm_get_connector_name(connector), - encoder->base.id, drm_get_encoder_name(encoder)); - - if (old->load_detect_temp) { + if (intel_encoder->load_detect_temp) { + encoder->crtc = NULL; connector->encoder = NULL; + intel_encoder->load_detect_temp = false; + crtc->enabled = drm_helper_crtc_in_use(crtc); drm_helper_disable_unused_functions(dev); - - if (old->release_fb) - old->release_fb->funcs->destroy(old->release_fb); - - return; } /* Switch crtc and encoder back off if necessary */ - if (old->dpms_mode != DRM_MODE_DPMS_ON) { - encoder_funcs->dpms(encoder, old->dpms_mode); - crtc_funcs->dpms(crtc, old->dpms_mode); + if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) { + if (encoder->crtc == crtc) + encoder_funcs->dpms(encoder, dpms_mode); + crtc_funcs->dpms(crtc, dpms_mode); } } @@ -5851,9 +5605,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) intel_clock_t clock; if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = I915_READ(FP0(pipe)); + fp = FP0(pipe); else - fp = I915_READ(FP1(pipe)); + fp = FP1(pipe); clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; if (IS_PINEVIEW(dev)) { @@ -6431,7 +6185,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, break; case 6: - case 7: OUT_RING(MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); OUT_RING(fb->pitch | obj->tiling_mode); @@ -6751,9 +6504,6 @@ static void intel_setup_outputs(struct drm_device *dev) } intel_panel_setup_backlight(dev); - - /* disable all the possible outputs/crtcs before entering KMS mode */ - drm_helper_disable_unused_functions(dev); } static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) @@ -6821,12 +6571,25 @@ intel_user_framebuffer_create(struct drm_device *dev, struct drm_mode_fb_cmd *mode_cmd) { struct drm_i915_gem_object *obj; + struct intel_framebuffer *intel_fb; + int ret; obj = to_intel_bo(drm_gem_object_lookup(dev, filp, mode_cmd->handle)); if (&obj->base == NULL) return ERR_PTR(-ENOENT); - return intel_framebuffer_create(dev, mode_cmd, obj); + intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); + if (!intel_fb) + return ERR_PTR(-ENOMEM); + + ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); + if (ret) { + drm_gem_object_unreference_unlocked(&obj->base); + kfree(intel_fb); + return ERR_PTR(ret); + } + + return &intel_fb->base; } static const struct drm_mode_config_funcs intel_mode_funcs = { @@ -6840,14 +6603,13 @@ intel_alloc_context_page(struct drm_device *dev) struct drm_i915_gem_object *ctx; int ret; - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - ctx = i915_gem_alloc_object(dev, 4096); if (!ctx) { DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); return NULL; } + mutex_lock(&dev->struct_mutex); ret = i915_gem_object_pin(ctx, 4096, true); if (ret) { DRM_ERROR("failed to pin power context: %d\n", ret); @@ -6859,6 +6621,7 @@ intel_alloc_context_page(struct drm_device *dev) DRM_ERROR("failed to set-domain on power context: %d\n", ret); goto err_unpin; } + mutex_unlock(&dev->struct_mutex); return ctx; @@ -6993,11 +6756,6 @@ void gen6_disable_rps(struct drm_device *dev) I915_WRITE(GEN6_RPNSWREQ, 1 << 31); I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); I915_WRITE(GEN6_PMIER, 0); - - spin_lock_irq(&dev_priv->rps_lock); - dev_priv->pm_iir = 0; - spin_unlock_irq(&dev_priv->rps_lock); - I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); } @@ -7091,7 +6849,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) { u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); - u32 pcu_mbox, rc6_mask = 0; + u32 pcu_mbox; int cur_freq, min_freq, max_freq; int i; @@ -7102,8 +6860,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) * userspace... */ I915_WRITE(GEN6_RC_STATE, 0); - mutex_lock(&dev_priv->dev->struct_mutex); - gen6_gt_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); /* disable the counters and set deterministic thresholds */ I915_WRITE(GEN6_RC_CONTROL, 0); @@ -7123,12 +6880,9 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ - if (i915_enable_rc6) - rc6_mask = GEN6_RC_CTL_RC6p_ENABLE | - GEN6_RC_CTL_RC6_ENABLE; - I915_WRITE(GEN6_RC_CONTROL, - rc6_mask | + GEN6_RC_CTL_RC6p_ENABLE | + GEN6_RC_CTL_RC6_ENABLE | GEN6_RC_CTL_EI_MODE(1) | GEN6_RC_CTL_HW_ENABLE); @@ -7200,237 +6954,168 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_EI_EXPIRED); - spin_lock_irq(&dev_priv->rps_lock); - WARN_ON(dev_priv->pm_iir != 0); I915_WRITE(GEN6_PMIMR, 0); - spin_unlock_irq(&dev_priv->rps_lock); /* enable all PM interrupts */ I915_WRITE(GEN6_PMINTRMSK, 0); - gen6_gt_force_wake_put(dev_priv); - mutex_unlock(&dev_priv->dev->struct_mutex); -} - -static void ironlake_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; - - /* Required for FBC */ - dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE | - DPFCRUNIT_CLOCK_GATE_DISABLE | - DPFDUNIT_CLOCK_GATE_DISABLE; - /* Required for CxSR */ - dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE; - - I915_WRITE(PCH_3DCGDIS0, - MARIUNIT_CLOCK_GATE_DISABLE | - SVSMUNIT_CLOCK_GATE_DISABLE); - I915_WRITE(PCH_3DCGDIS1, - VFMUNIT_CLOCK_GATE_DISABLE); - - I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); - - /* - * According to the spec the following bits should be set in - * order to enable memory self-refresh - * The bit 22/21 of 0x42004 - * The bit 5 of 0x42020 - * The bit 15 of 0x45000 - */ - I915_WRITE(ILK_DISPLAY_CHICKEN2, - (I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL)); - I915_WRITE(ILK_DSPCLK_GATE, - (I915_READ(ILK_DSPCLK_GATE) | - ILK_DPARB_CLK_GATE)); - I915_WRITE(DISP_ARB_CTL, - (I915_READ(DISP_ARB_CTL) | - DISP_FBC_WM_DIS)); - I915_WRITE(WM3_LP_ILK, 0); - I915_WRITE(WM2_LP_ILK, 0); - I915_WRITE(WM1_LP_ILK, 0); - - /* - * Based on the document from hardware guys the following bits - * should be set unconditionally in order to enable FBC. - * The bit 22 of 0x42000 - * The bit 22 of 0x42004 - * The bit 7,8,9 of 0x42020. - */ - if (IS_IRONLAKE_M(dev)) { - I915_WRITE(ILK_DISPLAY_CHICKEN1, - I915_READ(ILK_DISPLAY_CHICKEN1) | - ILK_FBCQ_DIS); - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE); - I915_WRITE(ILK_DSPCLK_GATE, - I915_READ(ILK_DSPCLK_GATE) | - ILK_DPFC_DIS1 | - ILK_DPFC_DIS2 | - ILK_CLK_FBC); - } - - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_ELPIN_409_SELECT); - I915_WRITE(_3D_CHICKEN2, - _3D_CHICKEN2_WM_READ_PIPELINED << 16 | - _3D_CHICKEN2_WM_READ_PIPELINED); + __gen6_gt_force_wake_put(dev_priv); } -static void gen6_init_clock_gating(struct drm_device *dev) +void intel_enable_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int pipe; - uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; - - I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); - - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_ELPIN_409_SELECT); - - I915_WRITE(WM3_LP_ILK, 0); - I915_WRITE(WM2_LP_ILK, 0); - I915_WRITE(WM1_LP_ILK, 0); /* - * According to the spec the following bits should be - * set in order to enable memory self-refresh and fbc: - * The bit21 and bit22 of 0x42000 - * The bit21 and bit22 of 0x42004 - * The bit5 and bit7 of 0x42020 - * The bit14 of 0x70180 - * The bit14 of 0x71180 + * Disable clock gating reported to work incorrectly according to the + * specs, but enable as much else as we can. */ - I915_WRITE(ILK_DISPLAY_CHICKEN1, - I915_READ(ILK_DISPLAY_CHICKEN1) | - ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL); - I915_WRITE(ILK_DSPCLK_GATE, - I915_READ(ILK_DSPCLK_GATE) | - ILK_DPARB_CLK_GATE | - ILK_DPFD_CLK_GATE); - - for_each_pipe(pipe) - I915_WRITE(DSPCNTR(pipe), - I915_READ(DSPCNTR(pipe)) | - DISPPLANE_TRICKLE_FEED_DISABLE); -} - -static void ivybridge_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; - uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; - - I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); - - I915_WRITE(WM3_LP_ILK, 0); - I915_WRITE(WM2_LP_ILK, 0); - I915_WRITE(WM1_LP_ILK, 0); - - I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); - - for_each_pipe(pipe) - I915_WRITE(DSPCNTR(pipe), - I915_READ(DSPCNTR(pipe)) | - DISPPLANE_TRICKLE_FEED_DISABLE); -} - -static void g4x_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dspclk_gate; - - I915_WRITE(RENCLK_GATE_D1, 0); - I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | - GS_UNIT_CLOCK_GATE_DISABLE | - CL_UNIT_CLOCK_GATE_DISABLE); - I915_WRITE(RAMCLK_GATE_D, 0); - dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | - OVRUNIT_CLOCK_GATE_DISABLE | - OVCUNIT_CLOCK_GATE_DISABLE; - if (IS_GM45(dev)) - dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; - I915_WRITE(DSPCLK_GATE_D, dspclk_gate); -} - -static void crestline_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); - I915_WRITE(RENCLK_GATE_D2, 0); - I915_WRITE(DSPCLK_GATE_D, 0); - I915_WRITE(RAMCLK_GATE_D, 0); - I915_WRITE16(DEUC, 0); -} - -static void broadwater_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | - I965_RCC_CLOCK_GATE_DISABLE | - I965_RCPB_CLOCK_GATE_DISABLE | - I965_ISC_CLOCK_GATE_DISABLE | - I965_FBC_CLOCK_GATE_DISABLE); - I915_WRITE(RENCLK_GATE_D2, 0); -} - -static void gen3_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 dstate = I915_READ(D_STATE); + if (HAS_PCH_SPLIT(dev)) { + uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; - dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | - DSTATE_DOT_CLOCK_GATING; - I915_WRITE(D_STATE, dstate); -} + if (IS_GEN5(dev)) { + /* Required for FBC */ + dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE | + DPFCRUNIT_CLOCK_GATE_DISABLE | + DPFDUNIT_CLOCK_GATE_DISABLE; + /* Required for CxSR */ + dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE; + + I915_WRITE(PCH_3DCGDIS0, + MARIUNIT_CLOCK_GATE_DISABLE | + SVSMUNIT_CLOCK_GATE_DISABLE); + I915_WRITE(PCH_3DCGDIS1, + VFMUNIT_CLOCK_GATE_DISABLE); + } -static void i85x_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; + I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); - I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); -} + /* + * On Ibex Peak and Cougar Point, we need to disable clock + * gating for the panel power sequencer or it will fail to + * start up when no ports are active. + */ + I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); -static void i830_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; + /* + * According to the spec the following bits should be set in + * order to enable memory self-refresh + * The bit 22/21 of 0x42004 + * The bit 5 of 0x42020 + * The bit 15 of 0x45000 + */ + if (IS_GEN5(dev)) { + I915_WRITE(ILK_DISPLAY_CHICKEN2, + (I915_READ(ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE | ILK_VSDPFD_FULL)); + I915_WRITE(ILK_DSPCLK_GATE, + (I915_READ(ILK_DSPCLK_GATE) | + ILK_DPARB_CLK_GATE)); + I915_WRITE(DISP_ARB_CTL, + (I915_READ(DISP_ARB_CTL) | + DISP_FBC_WM_DIS)); + I915_WRITE(WM3_LP_ILK, 0); + I915_WRITE(WM2_LP_ILK, 0); + I915_WRITE(WM1_LP_ILK, 0); + } + /* + * Based on the document from hardware guys the following bits + * should be set unconditionally in order to enable FBC. + * The bit 22 of 0x42000 + * The bit 22 of 0x42004 + * The bit 7,8,9 of 0x42020. + */ + if (IS_IRONLAKE_M(dev)) { + I915_WRITE(ILK_DISPLAY_CHICKEN1, + I915_READ(ILK_DISPLAY_CHICKEN1) | + ILK_FBCQ_DIS); + I915_WRITE(ILK_DISPLAY_CHICKEN2, + I915_READ(ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE); + I915_WRITE(ILK_DSPCLK_GATE, + I915_READ(ILK_DSPCLK_GATE) | + ILK_DPFC_DIS1 | + ILK_DPFC_DIS2 | + ILK_CLK_FBC); + } - I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); -} + I915_WRITE(ILK_DISPLAY_CHICKEN2, + I915_READ(ILK_DISPLAY_CHICKEN2) | + ILK_ELPIN_409_SELECT); -static void ibx_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; + if (IS_GEN5(dev)) { + I915_WRITE(_3D_CHICKEN2, + _3D_CHICKEN2_WM_READ_PIPELINED << 16 | + _3D_CHICKEN2_WM_READ_PIPELINED); + } - /* - * On Ibex Peak and Cougar Point, we need to disable clock - * gating for the panel power sequencer or it will fail to - * start up when no ports are active. - */ - I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); -} + if (IS_GEN6(dev)) { + I915_WRITE(WM3_LP_ILK, 0); + I915_WRITE(WM2_LP_ILK, 0); + I915_WRITE(WM1_LP_ILK, 0); -static void cpt_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; + /* + * According to the spec the following bits should be + * set in order to enable memory self-refresh and fbc: + * The bit21 and bit22 of 0x42000 + * The bit21 and bit22 of 0x42004 + * The bit5 and bit7 of 0x42020 + * The bit14 of 0x70180 + * The bit14 of 0x71180 + */ + I915_WRITE(ILK_DISPLAY_CHICKEN1, + I915_READ(ILK_DISPLAY_CHICKEN1) | + ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); + I915_WRITE(ILK_DISPLAY_CHICKEN2, + I915_READ(ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE | ILK_VSDPFD_FULL); + I915_WRITE(ILK_DSPCLK_GATE, + I915_READ(ILK_DSPCLK_GATE) | + ILK_DPARB_CLK_GATE | + ILK_DPFD_CLK_GATE); + + for_each_pipe(pipe) + I915_WRITE(DSPCNTR(pipe), + I915_READ(DSPCNTR(pipe)) | + DISPPLANE_TRICKLE_FEED_DISABLE); + } + } else if (IS_G4X(dev)) { + uint32_t dspclk_gate; + I915_WRITE(RENCLK_GATE_D1, 0); + I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | + GS_UNIT_CLOCK_GATE_DISABLE | + CL_UNIT_CLOCK_GATE_DISABLE); + I915_WRITE(RAMCLK_GATE_D, 0); + dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | + OVRUNIT_CLOCK_GATE_DISABLE | + OVCUNIT_CLOCK_GATE_DISABLE; + if (IS_GM45(dev)) + dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; + I915_WRITE(DSPCLK_GATE_D, dspclk_gate); + } else if (IS_CRESTLINE(dev)) { + I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); + I915_WRITE(RENCLK_GATE_D2, 0); + I915_WRITE(DSPCLK_GATE_D, 0); + I915_WRITE(RAMCLK_GATE_D, 0); + I915_WRITE16(DEUC, 0); + } else if (IS_BROADWATER(dev)) { + I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | + I965_RCC_CLOCK_GATE_DISABLE | + I965_RCPB_CLOCK_GATE_DISABLE | + I965_ISC_CLOCK_GATE_DISABLE | + I965_FBC_CLOCK_GATE_DISABLE); + I915_WRITE(RENCLK_GATE_D2, 0); + } else if (IS_GEN3(dev)) { + u32 dstate = I915_READ(D_STATE); - /* - * On Ibex Peak and Cougar Point, we need to disable clock - * gating for the panel power sequencer or it will fail to - * start up when no ports are active. - */ - I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); - I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | - DPLS_EDP_PPS_FIX_DIS); + dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | + DSTATE_DOT_CLOCK_GATING; + I915_WRITE(D_STATE, dstate); + } else if (IS_I85X(dev) || IS_I865G(dev)) { + I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); + } else if (IS_I830(dev)) { + I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); + } } static void ironlake_teardown_rc6(struct drm_device *dev) @@ -7500,12 +7185,9 @@ void ironlake_enable_rc6(struct drm_device *dev) if (!i915_enable_rc6) return; - mutex_lock(&dev->struct_mutex); ret = ironlake_setup_rc6(dev); - if (ret) { - mutex_unlock(&dev->struct_mutex); + if (ret) return; - } /* * GPU can automatically power down the render unit if given a page @@ -7514,7 +7196,6 @@ void ironlake_enable_rc6(struct drm_device *dev) ret = BEGIN_LP_RING(6); if (ret) { ironlake_teardown_rc6(dev); - mutex_unlock(&dev->struct_mutex); return; } @@ -7530,33 +7211,10 @@ void ironlake_enable_rc6(struct drm_device *dev) OUT_RING(MI_FLUSH); ADVANCE_LP_RING(); - /* - * Wait for the command parser to advance past MI_SET_CONTEXT. The HW - * does an implicit flush, combined with MI_FLUSH above, it should be - * safe to assume that renderctx is valid - */ - ret = intel_wait_ring_idle(LP_RING(dev_priv)); - if (ret) { - DRM_ERROR("failed to enable ironlake power power savings\n"); - ironlake_teardown_rc6(dev); - mutex_unlock(&dev->struct_mutex); - return; - } - I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); - mutex_unlock(&dev->struct_mutex); } -void intel_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->display.init_clock_gating(dev); - - if (dev_priv->display.init_pch_clock_gating) - dev_priv->display.init_pch_clock_gating(dev); -} /* Set up chip specific display functions */ static void intel_init_display(struct drm_device *dev) @@ -7564,13 +7222,10 @@ static void intel_init_display(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; /* We always want a DPMS function */ - if (HAS_PCH_SPLIT(dev)) { + if (HAS_PCH_SPLIT(dev)) dev_priv->display.dpms = ironlake_crtc_dpms; - dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; - } else { + else dev_priv->display.dpms = i9xx_crtc_dpms; - dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; - } if (I915_HAS_FBC(dev)) { if (HAS_PCH_SPLIT(dev)) { @@ -7614,11 +7269,6 @@ static void intel_init_display(struct drm_device *dev) /* For FIFO watermark updates */ if (HAS_PCH_SPLIT(dev)) { - if (HAS_PCH_IBX(dev)) - dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; - else if (HAS_PCH_CPT(dev)) - dev_priv->display.init_pch_clock_gating = cpt_init_clock_gating; - if (IS_GEN5(dev)) { if (I915_READ(MLTR_ILK) & ILK_SRLT_MASK) dev_priv->display.update_wm = ironlake_update_wm; @@ -7627,8 +7277,6 @@ static void intel_init_display(struct drm_device *dev) "Disable CxSR\n"); dev_priv->display.update_wm = NULL; } - dev_priv->display.fdi_link_train = ironlake_fdi_link_train; - dev_priv->display.init_clock_gating = ironlake_init_clock_gating; } else if (IS_GEN6(dev)) { if (SNB_READ_WM0_LATENCY()) { dev_priv->display.update_wm = sandybridge_update_wm; @@ -7637,20 +7285,6 @@ static void intel_init_display(struct drm_device *dev) "Disable CxSR\n"); dev_priv->display.update_wm = NULL; } - dev_priv->display.fdi_link_train = gen6_fdi_link_train; - dev_priv->display.init_clock_gating = gen6_init_clock_gating; - } else if (IS_IVYBRIDGE(dev)) { - /* FIXME: detect B0+ stepping and use auto training */ - dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; - if (SNB_READ_WM0_LATENCY()) { - dev_priv->display.update_wm = sandybridge_update_wm; - } else { - DRM_DEBUG_KMS("Failed to read display plane latency. " - "Disable CxSR\n"); - dev_priv->display.update_wm = NULL; - } - dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; - } else dev_priv->display.update_wm = NULL; } else if (IS_PINEVIEW(dev)) { @@ -7668,30 +7302,18 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.update_wm = NULL; } else dev_priv->display.update_wm = pineview_update_wm; - } else if (IS_G4X(dev)) { + } else if (IS_G4X(dev)) dev_priv->display.update_wm = g4x_update_wm; - dev_priv->display.init_clock_gating = g4x_init_clock_gating; - } else if (IS_GEN4(dev)) { + else if (IS_GEN4(dev)) dev_priv->display.update_wm = i965_update_wm; - if (IS_CRESTLINE(dev)) - dev_priv->display.init_clock_gating = crestline_init_clock_gating; - else if (IS_BROADWATER(dev)) - dev_priv->display.init_clock_gating = broadwater_init_clock_gating; - } else if (IS_GEN3(dev)) { + else if (IS_GEN3(dev)) { dev_priv->display.update_wm = i9xx_update_wm; dev_priv->display.get_fifo_size = i9xx_get_fifo_size; - dev_priv->display.init_clock_gating = gen3_init_clock_gating; - } else if (IS_I865G(dev)) { - dev_priv->display.update_wm = i830_update_wm; - dev_priv->display.init_clock_gating = i85x_init_clock_gating; - dev_priv->display.get_fifo_size = i830_get_fifo_size; } else if (IS_I85X(dev)) { dev_priv->display.update_wm = i9xx_update_wm; dev_priv->display.get_fifo_size = i85x_get_fifo_size; - dev_priv->display.init_clock_gating = i85x_init_clock_gating; } else { dev_priv->display.update_wm = i830_update_wm; - dev_priv->display.init_clock_gating = i830_init_clock_gating; if (IS_845G(dev)) dev_priv->display.get_fifo_size = i845_get_fifo_size; else @@ -7817,11 +7439,12 @@ void intel_modeset_init(struct drm_device *dev) intel_crtc_init(dev, i); } - /* Just disable it once at startup */ - i915_disable_vga(dev); intel_setup_outputs(dev); - intel_init_clock_gating(dev); + intel_enable_clock_gating(dev); + + /* Just disable it once at startup */ + i915_disable_vga(dev); if (IS_IRONLAKE_M(dev)) { ironlake_enable_drps(dev); @@ -7831,15 +7454,12 @@ void intel_modeset_init(struct drm_device *dev) if (IS_GEN6(dev)) gen6_enable_rps(dev_priv); + if (IS_IRONLAKE_M(dev)) + ironlake_enable_rc6(dev); + INIT_WORK(&dev_priv->idle_work, intel_idle_update); setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, (unsigned long)dev); -} - -void intel_modeset_gem_init(struct drm_device *dev) -{ - if (IS_IRONLAKE_M(dev)) - ironlake_enable_rc6(dev); intel_setup_overlay(dev); } diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index a4d80314e7f8..cb8578b7e443 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -1470,8 +1470,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) if (!HAS_PCH_CPT(dev) && I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { - struct drm_crtc *crtc = intel_dp->base.base.crtc; - + struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); /* Hardware workaround: leaving our transcoder select * set to transcoder B while it's off will prevent the * corresponding HDMI output on transcoder A. @@ -1486,19 +1485,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) /* Changes to enable or select take place the vblank * after being written. */ - if (crtc == NULL) { - /* We can arrive here never having been attached - * to a CRTC, for instance, due to inheriting - * random state from the BIOS. - * - * If the pipe is not running, play safe and - * wait for the clocks to stabilise before - * continuing. - */ - POSTING_READ(intel_dp->output_reg); - msleep(50); - } else - intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); + intel_wait_for_vblank(dev, intel_crtc->pipe); } I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 831d7a4a0d18..1d20712d527f 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -140,6 +140,7 @@ struct intel_fbdev { struct intel_encoder { struct drm_encoder base; int type; + bool load_detect_temp; bool needs_tv_clock; void (*hot_plug)(struct intel_encoder *); int crtc_mask; @@ -290,19 +291,13 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe); - -struct intel_load_detect_pipe { - struct drm_framebuffer *release_fb; - bool load_detect_temp; - int dpms_mode; -}; -extern bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, - struct drm_connector *connector, - struct drm_display_mode *mode, - struct intel_load_detect_pipe *old); +extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, + struct drm_connector *connector, + struct drm_display_mode *mode, + int *dpms_mode); extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, struct drm_connector *connector, - struct intel_load_detect_pipe *old); + int dpms_mode); extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); extern int intel_sdvo_supports_hotplug(struct drm_connector *connector); @@ -344,6 +339,4 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data, extern void intel_fb_output_poll_changed(struct drm_device *dev); extern void intel_fb_restore_mode(struct drm_device *dev); - -extern void intel_init_clock_gating(struct drm_device *dev); #endif /* __INTEL_DRV_H__ */ diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 67cb076d271b..a562bd2648c7 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -539,9 +539,6 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, struct drm_device *dev = dev_priv->dev; struct drm_connector *connector = dev_priv->int_lvds_connector; - if (dev->switch_power_state != DRM_SWITCH_POWER_ON) - return NOTIFY_OK; - /* * check and update the status of LVDS connector after receiving * the LID nofication event. diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 3971b5e6ad60..e9e6f71418a4 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -236,7 +236,7 @@ init_pipe_control(struct intel_ring_buffer *ring) ret = -ENOMEM; goto err; } - obj->cache_level = I915_CACHE_LLC; + obj->agp_type = AGP_USER_CACHED_MEMORY; ret = i915_gem_object_pin(obj, 4096, true); if (ret) @@ -286,7 +286,7 @@ static int init_render_ring(struct intel_ring_buffer *ring) if (INTEL_INFO(dev)->gen > 3) { int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; - if (IS_GEN6(dev) || IS_GEN7(dev)) + if (IS_GEN6(dev)) mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; I915_WRITE(MI_MODE, mode); } @@ -551,31 +551,10 @@ render_ring_put_irq(struct intel_ring_buffer *ring) void intel_ring_setup_status_page(struct intel_ring_buffer *ring) { - struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = ring->dev->dev_private; - u32 mmio = 0; - - /* The ring status page addresses are no longer next to the rest of - * the ring registers as of gen7. - */ - if (IS_GEN7(dev)) { - switch (ring->id) { - case RING_RENDER: - mmio = RENDER_HWS_PGA_GEN7; - break; - case RING_BLT: - mmio = BLT_HWS_PGA_GEN7; - break; - case RING_BSD: - mmio = BSD_HWS_PGA_GEN7; - break; - } - } else if (IS_GEN6(ring->dev)) { - mmio = RING_HWS_PGA_GEN6(ring->mmio_base); - } else { - mmio = RING_HWS_PGA(ring->mmio_base); - } - + u32 mmio = IS_GEN6(ring->dev) ? + RING_HWS_PGA_GEN6(ring->mmio_base) : + RING_HWS_PGA(ring->mmio_base); I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); POSTING_READ(mmio); } @@ -780,7 +759,7 @@ static int init_status_page(struct intel_ring_buffer *ring) ret = -ENOMEM; goto err; } - obj->cache_level = I915_CACHE_LLC; + obj->agp_type = AGP_USER_CACHED_MEMORY; ret = i915_gem_object_pin(obj, 4096, true); if (ret != 0) { @@ -821,7 +800,6 @@ int intel_init_ring_buffer(struct drm_device *dev, INIT_LIST_HEAD(&ring->request_list); INIT_LIST_HEAD(&ring->gpu_write_list); - init_waitqueue_head(&ring->irq_queue); spin_lock_init(&ring->irq_lock); ring->irq_mask = ~0; @@ -894,7 +872,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) /* Disable the ring buffer. The ring must be idle at this point */ dev_priv = ring->dev->dev_private; - ret = intel_wait_ring_idle(ring); + ret = intel_wait_ring_buffer(ring, ring->size - 8); if (ret) DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", ring->name, ret); @@ -1355,7 +1333,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring = &dev_priv->ring[VCS]; - if (IS_GEN6(dev) || IS_GEN7(dev)) + if (IS_GEN6(dev)) *ring = gen6_bsd_ring; else *ring = bsd_ring; diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h index c0e0ee63fbf4..f23cc5f037a6 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -14,24 +14,27 @@ struct intel_hw_status_page { struct drm_i915_gem_object *obj; }; -#define I915_READ_TAIL(ring) I915_READ(RING_TAIL((ring)->mmio_base)) -#define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL((ring)->mmio_base), val) +#define I915_RING_READ(reg) i915_gt_read(dev_priv, reg) +#define I915_RING_WRITE(reg, val) i915_gt_write(dev_priv, reg, val) -#define I915_READ_START(ring) I915_READ(RING_START((ring)->mmio_base)) -#define I915_WRITE_START(ring, val) I915_WRITE(RING_START((ring)->mmio_base), val) +#define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL((ring)->mmio_base)) +#define I915_WRITE_TAIL(ring, val) I915_RING_WRITE(RING_TAIL((ring)->mmio_base), val) -#define I915_READ_HEAD(ring) I915_READ(RING_HEAD((ring)->mmio_base)) -#define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD((ring)->mmio_base), val) +#define I915_READ_START(ring) I915_RING_READ(RING_START((ring)->mmio_base)) +#define I915_WRITE_START(ring, val) I915_RING_WRITE(RING_START((ring)->mmio_base), val) -#define I915_READ_CTL(ring) I915_READ(RING_CTL((ring)->mmio_base)) -#define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL((ring)->mmio_base), val) +#define I915_READ_HEAD(ring) I915_RING_READ(RING_HEAD((ring)->mmio_base)) +#define I915_WRITE_HEAD(ring, val) I915_RING_WRITE(RING_HEAD((ring)->mmio_base), val) -#define I915_READ_IMR(ring) I915_READ(RING_IMR((ring)->mmio_base)) -#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) +#define I915_READ_CTL(ring) I915_RING_READ(RING_CTL((ring)->mmio_base)) +#define I915_WRITE_CTL(ring, val) I915_RING_WRITE(RING_CTL((ring)->mmio_base), val) -#define I915_READ_NOPID(ring) I915_READ(RING_NOPID((ring)->mmio_base)) -#define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base)) -#define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) +#define I915_READ_IMR(ring) I915_RING_READ(RING_IMR((ring)->mmio_base)) +#define I915_WRITE_IMR(ring, val) I915_RING_WRITE(RING_IMR((ring)->mmio_base), val) + +#define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID((ring)->mmio_base)) +#define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0((ring)->mmio_base)) +#define I915_READ_SYNC_1(ring) I915_RING_READ(RING_SYNC_1((ring)->mmio_base)) struct intel_ring_buffer { const char *name; @@ -161,13 +164,7 @@ intel_read_status_page(struct intel_ring_buffer *ring, #define I915_BREADCRUMB_INDEX 0x21 void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); - int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); -static inline int intel_wait_ring_idle(struct intel_ring_buffer *ring) -{ - return intel_wait_ring_buffer(ring, ring->space - 8); -} - int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); static inline void intel_ring_emit(struct intel_ring_buffer *ring, diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c index 113e4e7264cd..6b22c1dcc015 100644 --- a/trunk/drivers/gpu/drm/i915/intel_tv.c +++ b/trunk/drivers/gpu/drm/i915/intel_tv.c @@ -1361,14 +1361,15 @@ intel_tv_detect(struct drm_connector *connector, bool force) if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { type = intel_tv_detect_type(intel_tv, connector); } else if (force) { - struct intel_load_detect_pipe tmp; + struct drm_crtc *crtc; + int dpms_mode; - if (intel_get_load_detect_pipe(&intel_tv->base, connector, - &mode, &tmp)) { + crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, + &mode, &dpms_mode); + if (crtc) { type = intel_tv_detect_type(intel_tv, connector); - intel_release_load_detect_pipe(&intel_tv->base, - connector, - &tmp); + intel_release_load_detect_pipe(&intel_tv->base, connector, + dpms_mode); } else return connector_status_unknown; } else diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c index 4399e2f34db4..0b1caebc6eee 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -490,6 +490,7 @@ nouveau_pm_init(struct drm_device *dev) /* determine current ("boot") performance level */ ret = nouveau_pm_perflvl_get(dev, &pm->boot); if (ret == 0) { + strncpy(pm->boot.name, "boot", 4); pm->cur = &pm->boot; nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info)); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index c20eac3379e6..e9bc135d9189 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -862,15 +862,9 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) SYSTEM_ACCESS_MODE_NOT_IN_SYS | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); - if (rdev->flags & RADEON_IS_IGP) { - WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); - WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); - WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); - } else { - WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); - } + WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); + WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); + WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); @@ -2929,6 +2923,11 @@ static int evergreen_startup(struct radeon_device *rdev) rdev->asic->copy = NULL; dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); } + /* XXX: ontario has problems blitting to gart at the moment */ + if (rdev->family == CHIP_PALM) { + rdev->asic->copy = NULL; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); + } /* allocate wb buffer */ r = radeon_wb_init(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index 94533849927e..9aaa3f0c9372 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -221,11 +221,6 @@ #define MC_VM_MD_L1_TLB0_CNTL 0x2654 #define MC_VM_MD_L1_TLB1_CNTL 0x2658 #define MC_VM_MD_L1_TLB2_CNTL 0x265C - -#define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C -#define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660 -#define FUS_MC_VM_MD_L1_TLB2_CNTL 0x2664 - #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c index f116516bfef7..f5d12fb103fa 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1599,10 +1599,9 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], fake_edid_record->ucFakeEDIDLength); - if (drm_edid_is_valid(edid)) { + if (drm_edid_is_valid(edid)) rdev->mode_info.bios_hardcoded_edid = edid; - rdev->mode_info.bios_hardcoded_edid_size = edid_size; - } else + else kfree(edid); } } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_kms.c index bd58af658581..871df0376b1c 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_kms.c @@ -234,9 +234,6 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return -EINVAL; } break; - case RADEON_INFO_FUSION_GART_WORKING: - value = 1; - break; default: DRM_DEBUG_KMS("Invalid request %d\n", info->request); return -EINVAL; diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index 50e40dbd8bb6..060ef6327876 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -110,7 +110,8 @@ config SENSORS_ADM1021 help If you say yes here you get support for Analog Devices ADM1021 and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, - Genesys Logic GL523SM, National Semiconductor LM84 and TI THMC10. + Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10, + and the XEON processor built-in sensor. This driver can also be built as a module. If so, the module will be called adm1021. @@ -617,10 +618,10 @@ config SENSORS_LM90 depends on I2C help If you say yes here you get support for National Semiconductor LM90, - LM86, LM89 and LM99, Analog Devices ADM1032, ADT7461, and ADT7461A, - Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, - MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, ON Semiconductor NCT1008, - and Winbond/Nuvoton W83L771W/G/AWG/ASG sensor chips. + LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, Maxim + MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, + MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, and Winbond/Nuvoton + W83L771W/G/AWG/ASG sensor chips. This driver can also be built as a module. If so, the module will be called lm90. diff --git a/trunk/drivers/hwmon/lm85.c b/trunk/drivers/hwmon/lm85.c index da72dc12068c..250d099ca398 100644 --- a/trunk/drivers/hwmon/lm85.c +++ b/trunk/drivers/hwmon/lm85.c @@ -1094,7 +1094,6 @@ static struct attribute *lm85_attributes_minctl[] = { &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, - NULL }; static const struct attribute_group lm85_group_minctl = { @@ -1105,7 +1104,6 @@ static struct attribute *lm85_attributes_temp_off[] = { &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, &sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr, - NULL }; static const struct attribute_group lm85_group_temp_off = { @@ -1331,11 +1329,11 @@ static int lm85_probe(struct i2c_client *client, if (data->type != emc6d103s) { err = sysfs_create_group(&client->dev.kobj, &lm85_group_minctl); if (err) - goto err_remove_files; + goto err_kfree; err = sysfs_create_group(&client->dev.kobj, &lm85_group_temp_off); if (err) - goto err_remove_files; + goto err_kfree; } /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used diff --git a/trunk/drivers/hwmon/lm90.c b/trunk/drivers/hwmon/lm90.c index 2f94f9504804..c43b4e9f96a9 100644 --- a/trunk/drivers/hwmon/lm90.c +++ b/trunk/drivers/hwmon/lm90.c @@ -49,10 +49,10 @@ * chips, but support three temperature sensors instead of two. MAX6695 * and MAX6696 only differ in the pinout so they can be treated identically. * - * This driver also supports ADT7461 and ADT7461A from Analog Devices as well as - * NCT1008 from ON Semiconductor. The chips are supported in both compatibility - * and extended mode. They are mostly compatible with LM90 except for a data - * format difference for the temperature value registers. + * This driver also supports the ADT7461 chip from Analog Devices. + * It's supported in both compatibility and extended mode. It is mostly + * compatible with LM90 except for a data format difference for the + * temperature value registers. * * Since the LM90 was the first chipset supported by this driver, most * comments will refer to this chipset, but are actually general and @@ -88,10 +88,9 @@ * Addresses to scan * Address is fully defined internally and cannot be changed except for * MAX6659, MAX6680 and MAX6681. - * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, ADT7461A, MAX6649, - * MAX6657, MAX6658, NCT1008 and W83L771 have address 0x4c. - * ADM1032-2, ADT7461-2, ADT7461A-2, LM89-1, LM99-1, MAX6646, and NCT1008D - * have address 0x4d. + * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6649, MAX6657, + * MAX6658 and W83L771 have address 0x4c. + * ADM1032-2, ADT7461-2, LM89-1, LM99-1 and MAX6646 have address 0x4d. * MAX6647 has address 0x4e. * MAX6659 can have address 0x4c, 0x4d or 0x4e. * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, @@ -175,7 +174,6 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, static const struct i2c_device_id lm90_id[] = { { "adm1032", adm1032 }, { "adt7461", adt7461 }, - { "adt7461a", adt7461 }, { "lm90", lm90 }, { "lm86", lm86 }, { "lm89", lm86 }, @@ -190,7 +188,6 @@ static const struct i2c_device_id lm90_id[] = { { "max6681", max6680 }, { "max6695", max6696 }, { "max6696", max6696 }, - { "nct1008", adt7461 }, { "w83l771", w83l771 }, { } }; @@ -1156,11 +1153,6 @@ static int lm90_detect(struct i2c_client *new_client, && (reg_config1 & 0x1B) == 0x00 && reg_convrate <= 0x0A) { name = "adt7461"; - } else - if (chip_id == 0x57 /* ADT7461A, NCT1008 */ - && (reg_config1 & 0x1B) == 0x00 - && reg_convrate <= 0x0A) { - name = "adt7461a"; } } else if (man_id == 0x4D) { /* Maxim */ diff --git a/trunk/drivers/hwmon/twl4030-madc-hwmon.c b/trunk/drivers/hwmon/twl4030-madc-hwmon.c index 57240740b161..de5819199e2e 100644 --- a/trunk/drivers/hwmon/twl4030-madc-hwmon.c +++ b/trunk/drivers/hwmon/twl4030-madc-hwmon.c @@ -98,6 +98,7 @@ static const struct attribute_group twl4030_madc_group = { static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev) { int ret; + int status; struct device *hwmon; ret = sysfs_create_group(&pdev->dev.kobj, &twl4030_madc_group); @@ -106,7 +107,7 @@ static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev) hwmon = hwmon_device_register(&pdev->dev); if (IS_ERR(hwmon)) { dev_err(&pdev->dev, "hwmon_device_register failed.\n"); - ret = PTR_ERR(hwmon); + status = PTR_ERR(hwmon); goto err_reg; } diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index 455e909bc768..72c0415f6f94 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -134,15 +134,10 @@ SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ SMBHSTSTS_INTR) -/* Older devices have their ID defined in */ -#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 -#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 -#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 -#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 struct i801_priv { struct i2c_adapter adapter; diff --git a/trunk/drivers/i2c/busses/i2c-parport.c b/trunk/drivers/i2c/busses/i2c-parport.c index 2dbba163b102..0eb1515541e7 100644 --- a/trunk/drivers/i2c/busses/i2c-parport.c +++ b/trunk/drivers/i2c/busses/i2c-parport.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------ * * i2c-parport.c I2C bus over parallel port * * ------------------------------------------------------------------------ * - Copyright (C) 2003-2011 Jean Delvare + Copyright (C) 2003-2010 Jean Delvare Based on older i2c-philips-par.c driver Copyright (C) 1995-2000 Simon G. Vogl @@ -33,8 +33,6 @@ #include #include #include -#include -#include #include "i2c-parport.h" /* ----- Device list ------------------------------------------------------ */ @@ -45,11 +43,10 @@ struct i2c_par { struct i2c_algo_bit_data algo_data; struct i2c_smbus_alert_setup alert_data; struct i2c_client *ara; - struct list_head node; + struct i2c_par *next; }; -static LIST_HEAD(adapter_list); -static DEFINE_MUTEX(adapter_list_lock); +static struct i2c_par *adapter_list; /* ----- Low-level parallel port access ----------------------------------- */ @@ -231,9 +228,8 @@ static void i2c_parport_attach (struct parport *port) } /* Add the new adapter to the list */ - mutex_lock(&adapter_list_lock); - list_add_tail(&adapter->node, &adapter_list); - mutex_unlock(&adapter_list_lock); + adapter->next = adapter_list; + adapter_list = adapter; return; ERROR1: @@ -245,11 +241,11 @@ static void i2c_parport_attach (struct parport *port) static void i2c_parport_detach (struct parport *port) { - struct i2c_par *adapter, *_n; + struct i2c_par *adapter, *prev; /* Walk the list */ - mutex_lock(&adapter_list_lock); - list_for_each_entry_safe(adapter, _n, &adapter_list, node) { + for (prev = NULL, adapter = adapter_list; adapter; + prev = adapter, adapter = adapter->next) { if (adapter->pdev->port == port) { if (adapter->ara) { parport_disable_irq(port); @@ -263,11 +259,14 @@ static void i2c_parport_detach (struct parport *port) parport_release(adapter->pdev); parport_unregister_device(adapter->pdev); - list_del(&adapter->node); + if (prev) + prev->next = adapter->next; + else + adapter_list = adapter->next; kfree(adapter); + return; } } - mutex_unlock(&adapter_list_lock); } static struct parport_driver i2c_parport_driver = { diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c index d8ca0a0b970d..7de4b7ebffc5 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c @@ -1799,7 +1799,7 @@ static int qib_6120_setup_reset(struct qib_devdata *dd) /* * Keep chip from being accessed until we are ready. Use * writeq() directly, to allow the write even though QIB_PRESENT - * isn't set. + * isn't' set. */ dd->flags &= ~(QIB_INITTED | QIB_PRESENT); dd->int_counter = 0; /* so we check interrupts work again */ diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba7220.c b/trunk/drivers/infiniband/hw/qib/qib_iba7220.c index c765a2eb04cf..74fe0360bec7 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba7220.c @@ -2111,7 +2111,7 @@ static int qib_setup_7220_reset(struct qib_devdata *dd) /* * Keep chip from being accessed until we are ready. Use * writeq() directly, to allow the write even though QIB_PRESENT - * isn't set. + * isn't' set. */ dd->flags &= ~(QIB_INITTED | QIB_PRESENT); dd->int_counter = 0; /* so we check interrupts work again */ diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba7322.c b/trunk/drivers/infiniband/hw/qib/qib_iba7322.c index 6bab3eaea70f..55de3cf3441c 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba7322.c @@ -3299,7 +3299,7 @@ static int qib_do_7322_reset(struct qib_devdata *dd) /* * Keep chip from being accessed until we are ready. Use * writeq() directly, to allow the write even though QIB_PRESENT - * isn't set. + * isn't' set. */ dd->flags &= ~(QIB_INITTED | QIB_PRESENT | QIB_BADINTR); dd->flags |= QIB_DOING_RESET; diff --git a/trunk/drivers/input/touchscreen/wm831x-ts.c b/trunk/drivers/input/touchscreen/wm831x-ts.c index 9175d49d2546..6ae054f8e0aa 100644 --- a/trunk/drivers/input/touchscreen/wm831x-ts.c +++ b/trunk/drivers/input/touchscreen/wm831x-ts.c @@ -68,23 +68,8 @@ struct wm831x_ts { unsigned int pd_irq; bool pressure; bool pen_down; - struct work_struct pd_data_work; }; -static void wm831x_pd_data_work(struct work_struct *work) -{ - struct wm831x_ts *wm831x_ts = - container_of(work, struct wm831x_ts, pd_data_work); - - if (wm831x_ts->pen_down) { - enable_irq(wm831x_ts->data_irq); - dev_dbg(wm831x_ts->wm831x->dev, "IRQ PD->DATA done\n"); - } else { - enable_irq(wm831x_ts->pd_irq); - dev_dbg(wm831x_ts->wm831x->dev, "IRQ DATA->PD done\n"); - } -} - static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) { struct wm831x_ts *wm831x_ts = irq_data; @@ -125,9 +110,6 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) } if (!wm831x_ts->pen_down) { - /* Switch from data to pen down */ - dev_dbg(wm831x->dev, "IRQ DATA->PD\n"); - disable_irq_nosync(wm831x_ts->data_irq); /* Don't need data any more */ @@ -146,10 +128,6 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) ABS_PRESSURE, 0); input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0); - - schedule_work(&wm831x_ts->pd_data_work); - } else { - input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1); } input_sync(wm831x_ts->input_dev); @@ -163,11 +141,6 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data) struct wm831x *wm831x = wm831x_ts->wm831x; int ena = 0; - if (wm831x_ts->pen_down) - return IRQ_HANDLED; - - disable_irq_nosync(wm831x_ts->pd_irq); - /* Start collecting data */ if (wm831x_ts->pressure) ena |= WM831X_TCH_Z_ENA; @@ -176,14 +149,14 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data) WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena); + input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1); + input_sync(wm831x_ts->input_dev); + wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, WM831X_TCHPD_EINT, WM831X_TCHPD_EINT); wm831x_ts->pen_down = true; - - /* Switch from pen down to data */ - dev_dbg(wm831x->dev, "IRQ PD->DATA\n"); - schedule_work(&wm831x_ts->pd_data_work); + enable_irq(wm831x_ts->data_irq); return IRQ_HANDLED; } @@ -209,28 +182,13 @@ static void wm831x_ts_input_close(struct input_dev *idev) struct wm831x_ts *wm831x_ts = input_get_drvdata(idev); struct wm831x *wm831x = wm831x_ts->wm831x; - /* Shut the controller down, disabling all other functionality too */ wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, - WM831X_TCH_ENA | WM831X_TCH_X_ENA | - WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, 0); - - /* Make sure any pending IRQs are done, the above will prevent - * new ones firing. - */ - synchronize_irq(wm831x_ts->data_irq); - synchronize_irq(wm831x_ts->pd_irq); - - /* Make sure the IRQ completion work is quiesced */ - flush_work_sync(&wm831x_ts->pd_data_work); + WM831X_TCH_ENA | WM831X_TCH_CVT_ENA | + WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | + WM831X_TCH_Z_ENA, 0); - /* If we ended up with the pen down then make sure we revert back - * to pen detection state for the next time we start up. - */ - if (wm831x_ts->pen_down) { + if (wm831x_ts->pen_down) disable_irq(wm831x_ts->data_irq); - enable_irq(wm831x_ts->pd_irq); - wm831x_ts->pen_down = false; - } } static __devinit int wm831x_ts_probe(struct platform_device *pdev) @@ -240,7 +198,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent); struct wm831x_touch_pdata *pdata = NULL; struct input_dev *input_dev; - int error, irqf; + int error; if (core_pdata) pdata = core_pdata->touch; @@ -254,7 +212,6 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) wm831x_ts->wm831x = wm831x; wm831x_ts->input_dev = input_dev; - INIT_WORK(&wm831x_ts->pd_data_work, wm831x_pd_data_work); /* * If we have a direct IRQ use it, otherwise use the interrupt @@ -313,14 +270,9 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, WM831X_TCH_RATE_MASK, 6); - if (pdata && pdata->data_irqf) - irqf = pdata->data_irqf; - else - irqf = IRQF_TRIGGER_HIGH; - error = request_threaded_irq(wm831x_ts->data_irq, NULL, wm831x_ts_data_irq, - irqf | IRQF_ONESHOT, + IRQF_ONESHOT, "Touchscreen data", wm831x_ts); if (error) { dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n", @@ -329,14 +281,9 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) } disable_irq(wm831x_ts->data_irq); - if (pdata && pdata->pd_irqf) - irqf = pdata->pd_irqf; - else - irqf = IRQF_TRIGGER_HIGH; - error = request_threaded_irq(wm831x_ts->pd_irq, NULL, wm831x_ts_pen_down_irq, - irqf | IRQF_ONESHOT, + IRQF_ONESHOT, "Touchscreen pen down", wm831x_ts); if (error) { dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n", diff --git a/trunk/drivers/media/common/tuners/tda18271-common.c b/trunk/drivers/media/common/tuners/tda18271-common.c index aae40e52af5b..5466d47db899 100644 --- a/trunk/drivers/media/common/tuners/tda18271-common.c +++ b/trunk/drivers/media/common/tuners/tda18271-common.c @@ -533,7 +533,16 @@ int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq) if (tda_fail(ret)) goto fail; - regs[R_MPD] = (0x7f & pd); + regs[R_MPD] = (0x77 & pd); + + switch (priv->mode) { + case TDA18271_ANALOG: + regs[R_MPD] &= ~0x08; + break; + case TDA18271_DIGITAL: + regs[R_MPD] |= 0x08; + break; + } div = ((d * (freq / 1000)) << 7) / 125; diff --git a/trunk/drivers/media/common/tuners/tda18271-fe.c b/trunk/drivers/media/common/tuners/tda18271-fe.c index d884f5eee73c..9ad4454a148d 100644 --- a/trunk/drivers/media/common/tuners/tda18271-fe.c +++ b/trunk/drivers/media/common/tuners/tda18271-fe.c @@ -579,8 +579,8 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) #define RF3 2 u32 rf_default[3]; u32 rf_freq[3]; - s32 prog_cal[3]; - s32 prog_tab[3]; + u8 prog_cal[3]; + u8 prog_tab[3]; i = tda18271_lookup_rf_band(fe, &freq, NULL); @@ -602,33 +602,32 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) return bcal; tda18271_calc_rf_cal(fe, &rf_freq[rf]); - prog_tab[rf] = (s32)regs[R_EB14]; + prog_tab[rf] = regs[R_EB14]; if (1 == bcal) - prog_cal[rf] = - (s32)tda18271_calibrate_rf(fe, rf_freq[rf]); + prog_cal[rf] = tda18271_calibrate_rf(fe, rf_freq[rf]); else prog_cal[rf] = prog_tab[rf]; switch (rf) { case RF1: map[i].rf_a1 = 0; - map[i].rf_b1 = (prog_cal[RF1] - prog_tab[RF1]); + map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]); map[i].rf1 = rf_freq[RF1] / 1000; break; case RF2: - dividend = (prog_cal[RF2] - prog_tab[RF2] - - prog_cal[RF1] + prog_tab[RF1]); + dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) - + (s32)(prog_cal[RF1] + prog_tab[RF1]); divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000; map[i].rf_a1 = (dividend / divisor); map[i].rf2 = rf_freq[RF2] / 1000; break; case RF3: - dividend = (prog_cal[RF3] - prog_tab[RF3] - - prog_cal[RF2] + prog_tab[RF2]); + dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) - + (s32)(prog_cal[RF2] + prog_tab[RF2]); divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000; map[i].rf_a2 = (dividend / divisor); - map[i].rf_b2 = (prog_cal[RF2] - prog_tab[RF2]); + map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]); map[i].rf3 = rf_freq[RF3] / 1000; break; default: diff --git a/trunk/drivers/media/common/tuners/tda18271-maps.c b/trunk/drivers/media/common/tuners/tda18271-maps.c index 3d5b6ab7e332..e7f84c705da8 100644 --- a/trunk/drivers/media/common/tuners/tda18271-maps.c +++ b/trunk/drivers/media/common/tuners/tda18271-maps.c @@ -229,7 +229,8 @@ static struct tda18271_map tda18271c2_km[] = { static struct tda18271_map tda18271_rf_band[] = { { .rfmax = 47900, .val = 0x00 }, { .rfmax = 61100, .val = 0x01 }, - { .rfmax = 152600, .val = 0x02 }, +/* { .rfmax = 152600, .val = 0x02 }, */ + { .rfmax = 121200, .val = 0x02 }, { .rfmax = 164700, .val = 0x03 }, { .rfmax = 203500, .val = 0x04 }, { .rfmax = 457800, .val = 0x05 }, @@ -447,7 +448,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { { .rfmax = 150000, .val = 0xb0 }, { .rfmax = 151000, .val = 0xb1 }, { .rfmax = 152000, .val = 0xb7 }, - { .rfmax = 152600, .val = 0xbd }, + { .rfmax = 153000, .val = 0xbd }, { .rfmax = 154000, .val = 0x20 }, { .rfmax = 155000, .val = 0x22 }, { .rfmax = 156000, .val = 0x24 }, @@ -458,7 +459,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { { .rfmax = 161000, .val = 0x2d }, { .rfmax = 163000, .val = 0x2e }, { .rfmax = 164000, .val = 0x2f }, - { .rfmax = 164700, .val = 0x30 }, + { .rfmax = 165000, .val = 0x30 }, { .rfmax = 166000, .val = 0x11 }, { .rfmax = 167000, .val = 0x12 }, { .rfmax = 168000, .val = 0x13 }, @@ -509,8 +510,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { { .rfmax = 236000, .val = 0x1b }, { .rfmax = 237000, .val = 0x1c }, { .rfmax = 240000, .val = 0x1d }, - { .rfmax = 242000, .val = 0x1e }, - { .rfmax = 244000, .val = 0x1f }, + { .rfmax = 242000, .val = 0x1f }, { .rfmax = 247000, .val = 0x20 }, { .rfmax = 249000, .val = 0x21 }, { .rfmax = 252000, .val = 0x22 }, @@ -624,7 +624,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { { .rfmax = 453000, .val = 0x93 }, { .rfmax = 454000, .val = 0x94 }, { .rfmax = 456000, .val = 0x96 }, - { .rfmax = 457800, .val = 0x98 }, + { .rfmax = 457000, .val = 0x98 }, { .rfmax = 461000, .val = 0x11 }, { .rfmax = 468000, .val = 0x12 }, { .rfmax = 472000, .val = 0x13 }, diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c index 03f96d6ca894..955254090a0e 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c @@ -38,7 +38,7 @@ MODULE_PARM_DESC(debug, DEBSTATUS); #define DRIVER_VERSION "0.1" -#define DRIVER_NAME "flexcop-pci" +#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" #define DRIVER_AUTHOR "Patrick Boettcher " struct flexcop_pci { diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig index ccbd39a38c46..fe4f894183ff 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Kconfig +++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig @@ -362,7 +362,7 @@ config DVB_USB_LME2510 config DVB_USB_TECHNISAT_USB2 tristate "Technisat DVB-S/S2 USB2.0 support" depends on DVB_USB - select DVB_STV090x if !DVB_FE_CUSTOMISE - select DVB_STV6110x if !DVB_FE_CUSTOMISE + select DVB_STB0899 if !DVB_FE_CUSTOMISE + select DVB_STB6100 if !DVB_FE_CUSTOMISE help Say Y here to support the Technisat USB2 DVB-S/S2 device diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c index 65214af5cd74..97af266d7f1d 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -2162,7 +2162,7 @@ struct dibx000_agc_config dib7090_agc_config[2] = { .agc1_pt3 = 98, .agc1_slope1 = 0, .agc1_slope2 = 167, - .agc2_pt1 = 98, + .agc1_pt1 = 98, .agc2_pt2 = 255, .agc2_slope1 = 104, .agc2_slope2 = 0, @@ -2440,11 +2440,11 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) dib0700_set_i2c_speed(adap->dev, 340); adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); + dib7090_slave_reset(adap->fe); + if (adap->fe == NULL) return -ENODEV; - dib7090_slave_reset(adap->fe); - return 0; } diff --git a/trunk/drivers/media/media-entity.c b/trunk/drivers/media/media-entity.c index 056138f63c7d..23640ed44d85 100644 --- a/trunk/drivers/media/media-entity.c +++ b/trunk/drivers/media/media-entity.c @@ -378,6 +378,7 @@ EXPORT_SYMBOL_GPL(media_entity_create_link); static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) { + const u32 mask = MEDIA_LNK_FL_ENABLED; int ret; /* Notify both entities. */ @@ -394,7 +395,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) return ret; } - link->flags = flags; + link->flags = (link->flags & ~mask) | (flags & mask); link->reverse->flags = link->flags; return 0; @@ -416,7 +417,6 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) */ int __media_entity_setup_link(struct media_link *link, u32 flags) { - const u32 mask = MEDIA_LNK_FL_ENABLED; struct media_device *mdev; struct media_entity *source, *sink; int ret = -EBUSY; @@ -424,10 +424,6 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) if (link == NULL) return -EINVAL; - /* The non-modifiable link flags must not be modified. */ - if ((link->flags & ~mask) != (flags & ~mask)) - return -EINVAL; - if (link->flags & MEDIA_LNK_FL_IMMUTABLE) return link->flags == flags ? 0 : -EINVAL; diff --git a/trunk/drivers/media/radio/radio-sf16fmr2.c b/trunk/drivers/media/radio/radio-sf16fmr2.c index 87bad7678d92..dc3f04c52d5e 100644 --- a/trunk/drivers/media/radio/radio-sf16fmr2.c +++ b/trunk/drivers/media/radio/radio-sf16fmr2.c @@ -170,7 +170,7 @@ static int fmr2_setfreq(struct fmr2 *dev) return 0; } -/* !!! not tested, in my card this doesn't work !!! */ +/* !!! not tested, in my card this does't work !!! */ static int fmr2_setvolume(struct fmr2 *dev) { int vol[16] = { 0x021, 0x084, 0x090, 0x104, diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index 00f51dd121f3..4498b944dec8 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -875,7 +875,7 @@ config MX3_VIDEO config VIDEO_MX3 tristate "i.MX3x Camera Sensor Interface driver" depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA - select VIDEOBUF2_DMA_CONTIG + select VIDEOBUF_DMA_CONTIG select MX3_VIDEO ---help--- This is a v4l2 driver for the i.MX3x Camera Sensor Interface diff --git a/trunk/drivers/media/video/cx18/cx18-streams.c b/trunk/drivers/media/video/cx18/cx18-streams.c index 6fbc356113c1..c6e2ca3b1149 100644 --- a/trunk/drivers/media/video/cx18/cx18-streams.c +++ b/trunk/drivers/media/video/cx18/cx18-streams.c @@ -350,17 +350,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) /* No struct video_device, but can have buffers allocated */ if (type == CX18_ENC_STREAM_TYPE_IDX) { - /* If the module params didn't inhibit IDX ... */ if (cx->stream_buffers[type] != 0) { cx->stream_buffers[type] = 0; - /* - * Before calling cx18_stream_free(), - * check if the IDX stream was actually set up. - * Needed, since the cx18_probe() error path - * exits through here as well as normal clean up - */ - if (cx->streams[type].buffers != 0) - cx18_stream_free(&cx->streams[type]); + cx18_stream_free(&cx->streams[type]); } continue; } diff --git a/trunk/drivers/media/video/cx23885/Kconfig b/trunk/drivers/media/video/cx23885/Kconfig index caab1bfb79e2..3b6e7f28568e 100644 --- a/trunk/drivers/media/video/cx23885/Kconfig +++ b/trunk/drivers/media/video/cx23885/Kconfig @@ -22,7 +22,6 @@ config VIDEO_CX23885 select DVB_CX24116 if !DVB_FE_CUSTOMISE select DVB_STV0900 if !DVB_FE_CUSTOMISE select DVB_DS3000 if !DVB_FE_CUSTOMISE - select DVB_STV0367 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE diff --git a/trunk/drivers/media/video/imx074.c b/trunk/drivers/media/video/imx074.c index 0382ea752e6f..1a1169115716 100644 --- a/trunk/drivers/media/video/imx074.c +++ b/trunk/drivers/media/video/imx074.c @@ -298,7 +298,7 @@ static unsigned long imx074_query_bus_param(struct soc_camera_device *icd) static int imx074_set_bus_param(struct soc_camera_device *icd, unsigned long flags) { - return -EINVAL; + return -1; } static struct soc_camera_ops imx074_ops = { diff --git a/trunk/drivers/media/video/omap3isp/isp.c b/trunk/drivers/media/video/omap3isp/isp.c index 472a69359e60..503bd7922bd6 100644 --- a/trunk/drivers/media/video/omap3isp/isp.c +++ b/trunk/drivers/media/video/omap3isp/isp.c @@ -215,21 +215,20 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel) } switch (xclksel) { - case ISP_XCLK_A: + case 0: isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, ISPTCTRL_CTRL_DIVA_MASK, divisor << ISPTCTRL_CTRL_DIVA_SHIFT); dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n", currentxclk); break; - case ISP_XCLK_B: + case 1: isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, ISPTCTRL_CTRL_DIVB_MASK, divisor << ISPTCTRL_CTRL_DIVB_SHIFT); dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n", currentxclk); break; - case ISP_XCLK_NONE: default: omap3isp_put(isp); dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested " @@ -238,13 +237,13 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel) } /* Do we go from stable whatever to clock? */ - if (divisor >= 2 && isp->xclk_divisor[xclksel - 1] < 2) + if (divisor >= 2 && isp->xclk_divisor[xclksel] < 2) omap3isp_get(isp); /* Stopping the clock. */ - else if (divisor < 2 && isp->xclk_divisor[xclksel - 1] >= 2) + else if (divisor < 2 && isp->xclk_divisor[xclksel] >= 2) omap3isp_put(isp); - isp->xclk_divisor[xclksel - 1] = divisor; + isp->xclk_divisor[xclksel] = divisor; omap3isp_put(isp); @@ -286,8 +285,7 @@ static void isp_power_settings(struct isp_device *isp, int idle) */ void omap3isp_configure_bridge(struct isp_device *isp, enum ccdc_input_entity input, - const struct isp_parallel_platform_data *pdata, - unsigned int shift) + const struct isp_parallel_platform_data *pdata) { u32 ispctrl_val; @@ -300,9 +298,9 @@ void omap3isp_configure_bridge(struct isp_device *isp, switch (input) { case CCDC_INPUT_PARALLEL: ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; + ispctrl_val |= pdata->data_lane_shift << ISPCTRL_SHIFT_SHIFT; ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT; ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT; - shift += pdata->data_lane_shift * 2; break; case CCDC_INPUT_CSI2A: @@ -321,8 +319,6 @@ void omap3isp_configure_bridge(struct isp_device *isp, return; } - ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK; - ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK; ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE; @@ -662,8 +658,6 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) /* Apply power change to connected non-nodes. */ ret = isp_pipeline_pm_power(entity, change); - if (ret < 0) - entity->use_count -= change; mutex_unlock(&entity->parent->graph_mutex); @@ -878,9 +872,6 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) } } - if (failure < 0) - isp->needs_reset = true; - return failure; } @@ -893,8 +884,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) * single-shot or continuous mode. * * Return 0 if successful, or the return value of the failed video::s_stream - * operation otherwise. The pipeline state is not updated when the operation - * fails, except when stopping the pipeline. + * operation otherwise. */ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, enum isp_pipeline_stream_state state) @@ -905,9 +895,7 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, ret = isp_pipeline_disable(pipe); else ret = isp_pipeline_enable(pipe, state); - - if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED) - pipe->stream_state = state; + pipe->stream_state = state; return ret; } @@ -1493,10 +1481,6 @@ void omap3isp_put(struct isp_device *isp) if (--isp->ref_count == 0) { isp_disable_interrupts(isp); isp_save_ctx(isp); - if (isp->needs_reset) { - isp_reset(isp); - isp->needs_reset = false; - } isp_disable_clocks(isp); } mutex_unlock(&isp->isp_mutex); diff --git a/trunk/drivers/media/video/omap3isp/isp.h b/trunk/drivers/media/video/omap3isp/isp.h index 2620c405f5e4..cf5214e95a92 100644 --- a/trunk/drivers/media/video/omap3isp/isp.h +++ b/trunk/drivers/media/video/omap3isp/isp.h @@ -132,6 +132,7 @@ struct isp_reg { /** * struct isp_parallel_platform_data - Parallel interface platform data + * @width: Parallel bus width in bits (8, 10, 11 or 12) * @data_lane_shift: Data lane shifter * 0 - CAMEXT[13:0] -> CAM[13:0] * 1 - CAMEXT[13:2] -> CAM[11:0] @@ -145,6 +146,7 @@ struct isp_reg { * ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian */ struct isp_parallel_platform_data { + unsigned int width; unsigned int data_lane_shift:2; unsigned int clk_pol:1; unsigned int bridge:4; @@ -260,7 +262,6 @@ struct isp_device { /* ISP Obj */ spinlock_t stat_lock; /* common lock for statistic drivers */ struct mutex isp_mutex; /* For handling ref_count field */ - bool needs_reset; int has_context; int ref_count; unsigned int autoidle; @@ -310,12 +311,11 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, enum isp_pipeline_stream_state state); void omap3isp_configure_bridge(struct isp_device *isp, enum ccdc_input_entity input, - const struct isp_parallel_platform_data *pdata, - unsigned int shift); + const struct isp_parallel_platform_data *pdata); -#define ISP_XCLK_NONE 0 -#define ISP_XCLK_A 1 -#define ISP_XCLK_B 2 +#define ISP_XCLK_NONE -1 +#define ISP_XCLK_A 0 +#define ISP_XCLK_B 1 struct isp_device *omap3isp_get(struct isp_device *isp); void omap3isp_put(struct isp_device *isp); diff --git a/trunk/drivers/media/video/omap3isp/ispccdc.c b/trunk/drivers/media/video/omap3isp/ispccdc.c index 39d501bda636..5ff9d14ce710 100644 --- a/trunk/drivers/media/video/omap3isp/ispccdc.c +++ b/trunk/drivers/media/video/omap3isp/ispccdc.c @@ -43,12 +43,6 @@ __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, static const unsigned int ccdc_fmts[] = { V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y12_1X12, - V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, @@ -1116,38 +1110,21 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) struct isp_parallel_platform_data *pdata = NULL; struct v4l2_subdev *sensor; struct v4l2_mbus_framefmt *format; - const struct isp_format_info *fmt_info; - struct v4l2_subdev_format fmt_src; - unsigned int depth_out; - unsigned int depth_in = 0; struct media_pad *pad; unsigned long flags; - unsigned int shift; u32 syn_mode; u32 ccdc_pattern; - pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]); - sensor = media_entity_to_v4l2_subdev(pad->entity); - if (ccdc->input == CCDC_INPUT_PARALLEL) + if (ccdc->input == CCDC_INPUT_PARALLEL) { + pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]); + sensor = media_entity_to_v4l2_subdev(pad->entity); pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv) ->bus.parallel; - - /* Compute shift value for lane shifter to configure the bridge. */ - fmt_src.pad = pad->index; - fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; - if (!v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt_src)) { - fmt_info = omap3isp_video_format_info(fmt_src.format.code); - depth_in = fmt_info->bpp; } - fmt_info = omap3isp_video_format_info - (isp->isp_ccdc.formats[CCDC_PAD_SINK].code); - depth_out = fmt_info->bpp; - - shift = depth_in - depth_out; - omap3isp_configure_bridge(isp, ccdc->input, pdata, shift); + omap3isp_configure_bridge(isp, ccdc->input, pdata); - ccdc->syncif.datsz = depth_out; + ccdc->syncif.datsz = pdata ? pdata->width : 10; ccdc_config_sync_if(ccdc, &ccdc->syncif); /* CCDC_PAD_SINK */ @@ -1361,7 +1338,7 @@ static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc, * @ccdc: Pointer to ISP CCDC device. * @event: Pointing which event trigger handler * - * Return 1 when the event and stopping request combination is satisfied, + * Return 1 when the event and stopping request combination is satisfyied, * zero otherwise. */ static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event) @@ -1641,7 +1618,7 @@ static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer) ccdc_set_outaddr(ccdc, buffer->isp_addr); - /* We now have a buffer queued on the output, restart the pipeline + /* We now have a buffer queued on the output, restart the pipeline in * on the next CCDC interrupt if running in continuous mode (or when * starting the stream). */ diff --git a/trunk/drivers/media/video/omap3isp/isppreview.c b/trunk/drivers/media/video/omap3isp/isppreview.c index aba537af87e4..2b16988a501d 100644 --- a/trunk/drivers/media/video/omap3isp/isppreview.c +++ b/trunk/drivers/media/video/omap3isp/isppreview.c @@ -755,7 +755,7 @@ static struct preview_update update_attrs[] = { * @configs - pointer to update config structure. * @config - return pointer to appropriate structure field. * @bit - for which feature to return pointers. - * Return size of corresponding prev_params member + * Return size of coresponding prev_params member */ static u32 __preview_get_ptrs(struct prev_params *params, void **param, diff --git a/trunk/drivers/media/video/omap3isp/ispqueue.c b/trunk/drivers/media/video/omap3isp/ispqueue.c index 9c317148205f..8fddc5806b0d 100644 --- a/trunk/drivers/media/video/omap3isp/ispqueue.c +++ b/trunk/drivers/media/video/omap3isp/ispqueue.c @@ -339,7 +339,7 @@ static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf) up_read(¤t->mm->mmap_sem); if (ret != buf->npages) { - buf->npages = ret < 0 ? 0 : ret; + buf->npages = ret; isp_video_buffer_cleanup(buf); return -EFAULT; } @@ -408,8 +408,8 @@ static int isp_video_buffer_prepare_pfnmap(struct isp_video_buffer *buf) * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address * * This function locates the VMAs for the buffer's userspace address and checks - * that their flags match. The only flag that we need to care for at the moment - * is VM_PFNMAP. + * that their flags match. The onlflag that we need to care for at the moment is + * VM_PFNMAP. * * The buffer vm_flags field is set to the first VMA flags. * diff --git a/trunk/drivers/media/video/omap3isp/ispresizer.c b/trunk/drivers/media/video/omap3isp/ispresizer.c index 0bb0f8cd36f5..653f88ba56db 100644 --- a/trunk/drivers/media/video/omap3isp/ispresizer.c +++ b/trunk/drivers/media/video/omap3isp/ispresizer.c @@ -714,50 +714,19 @@ static void resizer_print_status(struct isp_res_device *res) * iw and ih are the input width and height after cropping. Those equations need * to be satisfied exactly for the resizer to work correctly. * - * The equations can't be easily reverted, as the >> 8 operation is not linear. - * In addition, not all input sizes can be achieved for a given output size. To - * get the highest input size lower than or equal to the requested input size, - * we need to compute the highest resizing ratio that satisfies the following - * inequality (taking the 4-tap mode width equation as an example) - * - * iw >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 - 7 - * - * (where iw is the requested input width) which can be rewritten as - * - * iw - 7 >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 - * (iw - 7) << 8 >= 32 * sph + (ow - 1) * hrsz + 16 - b - * ((iw - 7) << 8) + b >= 32 * sph + (ow - 1) * hrsz + 16 - * - * where b is the value of the 8 least significant bits of the right hand side - * expression of the last inequality. The highest resizing ratio value will be - * achieved when b is equal to its maximum value of 255. That resizing ratio - * value will still satisfy the original inequality, as b will disappear when - * the expression will be shifted right by 8. - * - * The reverted the equations thus become + * Reverting the equations, we can compute the resizing ratios with * * - 8-phase, 4-tap mode - * hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1) - * vrsz = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / (oh - 1) + * hrsz = ((iw - 7) * 256 - 16 - 32 * sph) / (ow - 1) + * vrsz = ((ih - 4) * 256 - 16 - 32 * spv) / (oh - 1) * - 4-phase, 7-tap mode - * hrsz = ((iw - 7) * 256 + 255 - 32 - 64 * sph) / (ow - 1) - * vrsz = ((ih - 7) * 256 + 255 - 32 - 64 * spv) / (oh - 1) + * hrsz = ((iw - 7) * 256 - 32 - 64 * sph) / (ow - 1) + * vrsz = ((ih - 7) * 256 - 32 - 64 * spv) / (oh - 1) * - * The ratios are integer values, and are rounded down to ensure that the - * cropped input size is not bigger than the uncropped input size. - * - * As the number of phases/taps, used to select the correct equations to compute - * the ratio, depends on the ratio, we start with the 4-tap mode equations to - * compute an approximation of the ratio, and switch to the 7-tap mode equations - * if the approximation is higher than the ratio threshold. - * - * As the 7-tap mode equations will return a ratio smaller than or equal to the - * 4-tap mode equations, the resulting ratio could become lower than or equal to - * the ratio threshold. This 'equations loop' isn't an issue as long as the - * correct equations are used to compute the final input size. Starting with the - * 4-tap mode equations ensure that, in case of values resulting in a 'ratio - * loop', the smallest of the ratio values will be used, never exceeding the - * requested input size. + * The ratios are integer values, and must be rounded down to ensure that the + * cropped input size is not bigger than the uncropped input size. As the ratio + * in 7-tap mode is always smaller than the ratio in 4-tap mode, we can use the + * 7-tap mode equations to compute a ratio approximation. * * We first clamp the output size according to the hardware capabilitie to avoid * auto-cropping the input more than required to satisfy the TRM equations. The @@ -806,8 +775,6 @@ static void resizer_calc_ratios(struct isp_res_device *res, unsigned int max_width; unsigned int max_height; unsigned int width_alignment; - unsigned int width; - unsigned int height; /* * Clamp the output height based on the hardware capabilities and @@ -819,22 +786,19 @@ static void resizer_calc_ratios(struct isp_res_device *res, max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT); output->height = clamp(output->height, min_height, max_height); - ratio->vert = ((input->height - 4) * 256 + 255 - 16 - 32 * spv) + ratio->vert = ((input->height - 7) * 256 - 32 - 64 * spv) / (output->height - 1); - if (ratio->vert > MID_RESIZE_VALUE) - ratio->vert = ((input->height - 7) * 256 + 255 - 32 - 64 * spv) - / (output->height - 1); ratio->vert = clamp_t(unsigned int, ratio->vert, MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); if (ratio->vert <= MID_RESIZE_VALUE) { upscaled_height = (output->height - 1) * ratio->vert + 32 * spv + 16; - height = (upscaled_height >> 8) + 4; + input->height = (upscaled_height >> 8) + 4; } else { upscaled_height = (output->height - 1) * ratio->vert + 64 * spv + 32; - height = (upscaled_height >> 8) + 7; + input->height = (upscaled_height >> 8) + 7; } /* @@ -890,29 +854,20 @@ static void resizer_calc_ratios(struct isp_res_device *res, max_width & ~(width_alignment - 1)); output->width = ALIGN(output->width, width_alignment); - ratio->horz = ((input->width - 7) * 256 + 255 - 16 - 32 * sph) + ratio->horz = ((input->width - 7) * 256 - 32 - 64 * sph) / (output->width - 1); - if (ratio->horz > MID_RESIZE_VALUE) - ratio->horz = ((input->width - 7) * 256 + 255 - 32 - 64 * sph) - / (output->width - 1); ratio->horz = clamp_t(unsigned int, ratio->horz, MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); if (ratio->horz <= MID_RESIZE_VALUE) { upscaled_width = (output->width - 1) * ratio->horz + 32 * sph + 16; - width = (upscaled_width >> 8) + 7; + input->width = (upscaled_width >> 8) + 7; } else { upscaled_width = (output->width - 1) * ratio->horz + 64 * sph + 32; - width = (upscaled_width >> 8) + 7; + input->width = (upscaled_width >> 8) + 7; } - - /* Center the new crop rectangle. */ - input->left += (input->width - width) / 2; - input->top += (input->height - height) / 2; - input->width = width; - input->height = height; } /* diff --git a/trunk/drivers/media/video/omap3isp/ispstat.h b/trunk/drivers/media/video/omap3isp/ispstat.h index d86da94fa50d..820950c9ef46 100644 --- a/trunk/drivers/media/video/omap3isp/ispstat.h +++ b/trunk/drivers/media/video/omap3isp/ispstat.h @@ -131,9 +131,9 @@ struct ispstat { struct ispstat_generic_config { /* * Fields must be in the same order as in: - * - omap3isp_h3a_aewb_config - * - omap3isp_h3a_af_config - * - omap3isp_hist_config + * - isph3a_aewb_config + * - isph3a_af_config + * - isphist_config */ u32 buf_size; u16 config_counter; diff --git a/trunk/drivers/media/video/omap3isp/ispvideo.c b/trunk/drivers/media/video/omap3isp/ispvideo.c index 9cd8f1aa567b..208a7ec739d7 100644 --- a/trunk/drivers/media/video/omap3isp/ispvideo.c +++ b/trunk/drivers/media/video/omap3isp/ispvideo.c @@ -47,59 +47,29 @@ static struct isp_format_info formats[] = { { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, - V4L2_PIX_FMT_GREY, 8, }, - { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8, - V4L2_PIX_FMT_Y10, 10, }, - { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8, - V4L2_PIX_FMT_Y12, 12, }, - { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_PIX_FMT_SBGGR8, 8, }, - { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_PIX_FMT_SGBRG8, 8, }, - { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_PIX_FMT_SGRBG8, 8, }, - { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_PIX_FMT_SRGGB8, 8, }, + V4L2_MBUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, }, { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, - V4L2_MBUS_FMT_SGRBG10_1X10, 0, - V4L2_PIX_FMT_SGRBG10DPCM8, 8, }, + V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10DPCM8, 8, }, { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_PIX_FMT_SBGGR10, 10, }, + V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 10, }, { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_PIX_FMT_SGBRG10, 10, }, + V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 10, }, { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_PIX_FMT_SGRBG10, 10, }, + V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 10, }, { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_PIX_FMT_SRGGB10, 10, }, + V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 10, }, { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_PIX_FMT_SBGGR12, 12, }, + V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 12, }, { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_PIX_FMT_SGBRG12, 12, }, + V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 12, }, { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_PIX_FMT_SGRBG12, 12, }, + V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 12, }, { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_PIX_FMT_SRGGB12, 12, }, + V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 12, }, { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_UYVY8_1X16, 0, - V4L2_PIX_FMT_UYVY, 16, }, + V4L2_MBUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 16, }, { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, 0, - V4L2_PIX_FMT_YUYV, 16, }, + V4L2_MBUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 16, }, }; const struct isp_format_info * @@ -115,37 +85,6 @@ omap3isp_video_format_info(enum v4l2_mbus_pixelcode code) return NULL; } -/* - * Decide whether desired output pixel code can be obtained with - * the lane shifter by shifting the input pixel code. - * @in: input pixelcode to shifter - * @out: output pixelcode from shifter - * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0] - * - * return true if the combination is possible - * return false otherwise - */ -static bool isp_video_is_shiftable(enum v4l2_mbus_pixelcode in, - enum v4l2_mbus_pixelcode out, - unsigned int additional_shift) -{ - const struct isp_format_info *in_info, *out_info; - - if (in == out) - return true; - - in_info = omap3isp_video_format_info(in); - out_info = omap3isp_video_format_info(out); - - if ((in_info->flavor == 0) || (out_info->flavor == 0)) - return false; - - if (in_info->flavor != out_info->flavor) - return false; - - return in_info->bpp - out_info->bpp + additional_shift <= 6; -} - /* * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format * @video: ISP video instance @@ -296,7 +235,6 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) return -EPIPE; while (1) { - unsigned int shifter_link; /* Retrieve the sink format */ pad = &subdev->entity.pads[0]; if (!(pad->flags & MEDIA_PAD_FL_SINK)) @@ -325,10 +263,6 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) return -ENOSPC; } - /* If sink pad is on CCDC, the link has the lane shifter - * in the middle of it. */ - shifter_link = subdev == &isp->isp_ccdc.subdev; - /* Retrieve the source format */ pad = media_entity_remote_source(pad); if (pad == NULL || @@ -344,24 +278,10 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) return -EPIPE; /* Check if the two ends match */ - if (fmt_source.format.width != fmt_sink.format.width || + if (fmt_source.format.code != fmt_sink.format.code || + fmt_source.format.width != fmt_sink.format.width || fmt_source.format.height != fmt_sink.format.height) return -EPIPE; - - if (shifter_link) { - unsigned int parallel_shift = 0; - if (isp->isp_ccdc.input == CCDC_INPUT_PARALLEL) { - struct isp_parallel_platform_data *pdata = - &((struct isp_v4l2_subdevs_group *) - subdev->host_priv)->bus.parallel; - parallel_shift = pdata->data_lane_shift * 2; - } - if (!isp_video_is_shiftable(fmt_source.format.code, - fmt_sink.format.code, - parallel_shift)) - return -EPIPE; - } else if (fmt_source.format.code != fmt_sink.format.code) - return -EPIPE; } return 0; diff --git a/trunk/drivers/media/video/omap3isp/ispvideo.h b/trunk/drivers/media/video/omap3isp/ispvideo.h index 911bea64e78a..524a1acd0906 100644 --- a/trunk/drivers/media/video/omap3isp/ispvideo.h +++ b/trunk/drivers/media/video/omap3isp/ispvideo.h @@ -49,8 +49,6 @@ struct v4l2_pix_format; * bits. Identical to @code if the format is 10 bits wide or less. * @uncompressed: V4L2 media bus format code for the corresponding uncompressed * format. Identical to @code if the format is not DPCM compressed. - * @flavor: V4L2 media bus format code for the same pixel layout but - * shifted to be 8 bits per pixel. =0 if format is not shiftable. * @pixelformat: V4L2 pixel format FCC identifier * @bpp: Bits per pixel */ @@ -58,7 +56,6 @@ struct isp_format_info { enum v4l2_mbus_pixelcode code; enum v4l2_mbus_pixelcode truncated; enum v4l2_mbus_pixelcode uncompressed; - enum v4l2_mbus_pixelcode flavor; u32 pixelformat; unsigned int bpp; }; diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-capture.c b/trunk/drivers/media/video/s5p-fimc/fimc-capture.c index d142b40ea64e..95f8b4e11e46 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-capture.c @@ -527,7 +527,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv, if (ret) return ret; - if (vb2_is_busy(&fimc->vid_cap.vbq) || fimc_capture_active(fimc)) + if (vb2_is_streaming(&fimc->vid_cap.vbq) || fimc_capture_active(fimc)) return -EBUSY; frame = &ctx->d_frame; @@ -539,10 +539,8 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv, return -EINVAL; } - for (i = 0; i < frame->fmt->colplanes; i++) { - frame->payload[i] = - (pix->width * pix->height * frame->fmt->depth[i]) >> 3; - } + for (i = 0; i < frame->fmt->colplanes; i++) + frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; /* Output DMA frame pixel size and offsets. */ frame->f_width = pix->plane_fmt[0].bytesperline * 8 diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-core.c b/trunk/drivers/media/video/s5p-fimc/fimc-core.c index dc91a8511af6..6c919b38a3d8 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-core.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-core.c @@ -361,20 +361,10 @@ static void fimc_capture_irq_handler(struct fimc_dev *fimc) { struct fimc_vid_cap *cap = &fimc->vid_cap; struct fimc_vid_buffer *v_buf; - struct timeval *tv; - struct timespec ts; if (!list_empty(&cap->active_buf_q) && test_bit(ST_CAPT_RUN, &fimc->state)) { - ktime_get_real_ts(&ts); - v_buf = active_queue_pop(cap); - - tv = &v_buf->vb.v4l2_buf.timestamp; - tv->tv_sec = ts.tv_sec; - tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC; - v_buf->vb.v4l2_buf.sequence = cap->frame_count++; - vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE); } @@ -768,7 +758,7 @@ static void fimc_unlock(struct vb2_queue *vq) mutex_unlock(&ctx->fimc_dev->lock); } -static struct vb2_ops fimc_qops = { +struct vb2_ops fimc_qops = { .queue_setup = fimc_queue_setup, .buf_prepare = fimc_buf_prepare, .buf_queue = fimc_buf_queue, @@ -937,23 +927,23 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv, pix->num_planes = fmt->memplanes; pix->colorspace = V4L2_COLORSPACE_JPEG; - for (i = 0; i < pix->num_planes; ++i) { - u32 bpl = pix->plane_fmt[i].bytesperline; - u32 *sizeimage = &pix->plane_fmt[i].sizeimage; + int bpl = pix->plane_fmt[i].bytesperline; + + dbg("[%d] bpl: %d, depth: %d, w: %d, h: %d", + i, bpl, fmt->depth[i], pix->width, pix->height); - if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width)) - bpl = pix->width; /* Planar */ + if (!bpl || (bpl * 8 / fmt->depth[i]) > pix->width) + bpl = (pix->width * fmt->depth[0]) >> 3; - if (fmt->colplanes == 1 && /* Packed */ - (bpl == 0 || ((bpl * 8) / fmt->depth[i]) < pix->width)) - bpl = (pix->width * fmt->depth[0]) / 8; + if (!pix->plane_fmt[i].sizeimage) + pix->plane_fmt[i].sizeimage = pix->height * bpl; - if (i == 0) /* Same bytesperline for each plane. */ - mod_x = bpl; + pix->plane_fmt[i].bytesperline = bpl; - pix->plane_fmt[i].bytesperline = mod_x; - *sizeimage = (pix->width * pix->height * fmt->depth[i]) / 8; + dbg("[%d]: bpl: %d, sizeimage: %d", + i, pix->plane_fmt[i].bytesperline, + pix->plane_fmt[i].sizeimage); } return 0; @@ -975,7 +965,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); - if (vb2_is_busy(vq)) { + if (vb2_is_streaming(vq)) { v4l2_err(&fimc->m2m.v4l2_dev, "queue (%d) busy\n", f->type); return -EBUSY; } @@ -995,10 +985,8 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, if (!frame->fmt) return -EINVAL; - for (i = 0; i < frame->fmt->colplanes; i++) { - frame->payload[i] = - (pix->width * pix->height * frame->fmt->depth[i]) / 8; - } + for (i = 0; i < frame->fmt->colplanes; i++) + frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; frame->f_width = pix->plane_fmt[0].bytesperline * 8 / frame->fmt->depth[0]; @@ -1762,7 +1750,7 @@ static int __devexit fimc_remove(struct platform_device *pdev) } /* Image pixel limits, similar across several FIMC HW revisions. */ -static struct fimc_pix_limit s5p_pix_limit[4] = { +static struct fimc_pix_limit s5p_pix_limit[3] = { [0] = { .scaler_en_w = 3264, .scaler_dis_w = 8192, @@ -1787,14 +1775,6 @@ static struct fimc_pix_limit s5p_pix_limit[4] = { .out_rot_en_w = 1280, .out_rot_dis_w = 1920, }, - [3] = { - .scaler_en_w = 1920, - .scaler_dis_w = 8192, - .in_rot_en_h = 1366, - .in_rot_dis_w = 8192, - .out_rot_en_w = 1366, - .out_rot_dis_w = 1920, - }, }; static struct samsung_fimc_variant fimc0_variant_s5p = { @@ -1847,7 +1827,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv210 = { .pix_limit = &s5p_pix_limit[2], }; -static struct samsung_fimc_variant fimc0_variant_exynos4 = { +static struct samsung_fimc_variant fimc0_variant_s5pv310 = { .pix_hoff = 1, .has_inp_rot = 1, .has_out_rot = 1, @@ -1860,7 +1840,7 @@ static struct samsung_fimc_variant fimc0_variant_exynos4 = { .pix_limit = &s5p_pix_limit[1], }; -static struct samsung_fimc_variant fimc2_variant_exynos4 = { +static struct samsung_fimc_variant fimc2_variant_s5pv310 = { .pix_hoff = 1, .has_cistatus2 = 1, .has_mainscaler_ext = 1, @@ -1868,7 +1848,7 @@ static struct samsung_fimc_variant fimc2_variant_exynos4 = { .min_out_pixsize = 16, .hor_offs_align = 1, .out_buf_count = 32, - .pix_limit = &s5p_pix_limit[3], + .pix_limit = &s5p_pix_limit[2], }; /* S5PC100 */ @@ -1894,12 +1874,12 @@ static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = { }; /* S5PV310, S5PC210 */ -static struct samsung_fimc_driverdata fimc_drvdata_exynos4 = { +static struct samsung_fimc_driverdata fimc_drvdata_s5pv310 = { .variant = { - [0] = &fimc0_variant_exynos4, - [1] = &fimc0_variant_exynos4, - [2] = &fimc0_variant_exynos4, - [3] = &fimc2_variant_exynos4, + [0] = &fimc0_variant_s5pv310, + [1] = &fimc0_variant_s5pv310, + [2] = &fimc0_variant_s5pv310, + [3] = &fimc2_variant_s5pv310, }, .num_entities = 4, .lclk_frequency = 166000000UL, @@ -1913,8 +1893,8 @@ static struct platform_device_id fimc_driver_ids[] = { .name = "s5pv210-fimc", .driver_data = (unsigned long)&fimc_drvdata_s5pv210, }, { - .name = "exynos4-fimc", - .driver_data = (unsigned long)&fimc_drvdata_exynos4, + .name = "s5pv310-fimc", + .driver_data = (unsigned long)&fimc_drvdata_s5pv310, }, {}, }; diff --git a/trunk/drivers/media/video/sh_mobile_ceu_camera.c b/trunk/drivers/media/video/sh_mobile_ceu_camera.c index 134e86bf6d97..3fe54bf41142 100644 --- a/trunk/drivers/media/video/sh_mobile_ceu_camera.c +++ b/trunk/drivers/media/video/sh_mobile_ceu_camera.c @@ -922,7 +922,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int /* Try 2560x1920, 1280x960, 640x480, 320x240 */ mf.width = 2560 >> shift; mf.height = 1920 >> shift; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, + ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, s_mbus_fmt, &mf); if (ret < 0) return ret; @@ -1224,7 +1224,7 @@ static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_cropcap cap; int ret; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, + ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, s_mbus_fmt, mf); if (ret < 0) return ret; @@ -1254,7 +1254,7 @@ static int client_s_fmt(struct soc_camera_device *icd, tmp_h = min(2 * tmp_h, max_height); mf->width = tmp_w; mf->height = tmp_h; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, + ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, s_mbus_fmt, mf); dev_geo(dev, "Camera scaled to %ux%u\n", mf->width, mf->height); @@ -1658,7 +1658,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, mf.code = xlate->code; mf.colorspace = pix->colorspace; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, try_mbus_fmt, &mf); + ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, try_mbus_fmt, &mf); if (ret < 0) return ret; @@ -1682,7 +1682,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, */ mf.width = 2560; mf.height = 1920; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, + ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, try_mbus_fmt, &mf); if (ret < 0) { /* Shouldn't actually happen... */ diff --git a/trunk/drivers/media/video/sh_mobile_csi2.c b/trunk/drivers/media/video/sh_mobile_csi2.c index 98b87481fa94..dd1b81b1442b 100644 --- a/trunk/drivers/media/video/sh_mobile_csi2.c +++ b/trunk/drivers/media/video/sh_mobile_csi2.c @@ -38,8 +38,6 @@ struct sh_csi2 { void __iomem *base; struct platform_device *pdev; struct sh_csi2_client_config *client; - unsigned long (*query_bus_param)(struct soc_camera_device *); - int (*set_bus_param)(struct soc_camera_device *, unsigned long); }; static int sh_csi2_try_fmt(struct v4l2_subdev *sd, @@ -210,7 +208,6 @@ static int sh_csi2_notify(struct notifier_block *nb, case BUS_NOTIFY_BOUND_DRIVER: snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s%s", dev_name(v4l2_dev->dev), ".mipi-csi"); - priv->subdev.grp_id = (long)icd; ret = v4l2_device_register_subdev(v4l2_dev, &priv->subdev); dev_dbg(dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret); if (ret < 0) @@ -218,8 +215,6 @@ static int sh_csi2_notify(struct notifier_block *nb, priv->client = pdata->clients + i; - priv->set_bus_param = icd->ops->set_bus_param; - priv->query_bus_param = icd->ops->query_bus_param; icd->ops->set_bus_param = sh_csi2_set_bus_param; icd->ops->query_bus_param = sh_csi2_query_bus_param; @@ -231,10 +226,8 @@ static int sh_csi2_notify(struct notifier_block *nb, priv->client = NULL; /* Driver is about to be unbound */ - icd->ops->set_bus_param = priv->set_bus_param; - icd->ops->query_bus_param = priv->query_bus_param; - priv->set_bus_param = NULL; - priv->query_bus_param = NULL; + icd->ops->set_bus_param = NULL; + icd->ops->query_bus_param = NULL; v4l2_device_unregister_subdev(&priv->subdev); diff --git a/trunk/drivers/media/video/soc_camera.c b/trunk/drivers/media/video/soc_camera.c index 3973f9a94753..46284489e4eb 100644 --- a/trunk/drivers/media/video/soc_camera.c +++ b/trunk/drivers/media/video/soc_camera.c @@ -996,11 +996,10 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd) { struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct i2c_adapter *adap = client->adapter; dev_set_drvdata(&icd->dev, NULL); v4l2_device_unregister_subdev(i2c_get_clientdata(client)); i2c_unregister_device(client); - i2c_put_adapter(adap); + i2c_put_adapter(client->adapter); } #else #define soc_camera_init_i2c(icd, icl) (-ENODEV) @@ -1072,9 +1071,6 @@ static int soc_camera_probe(struct device *dev) } } - sd = soc_camera_to_subdev(icd); - sd->grp_id = (long)icd; - /* At this point client .probe() should have run already */ ret = soc_camera_init_user_formats(icd); if (ret < 0) @@ -1096,6 +1092,7 @@ static int soc_camera_probe(struct device *dev) goto evidstart; /* Try to improve our guess of a reasonable window format */ + sd = soc_camera_to_subdev(icd); if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { icd->user_width = mf.width; icd->user_height = mf.height; diff --git a/trunk/drivers/media/video/v4l2-dev.c b/trunk/drivers/media/video/v4l2-dev.c index 6dc7196296b3..498e6742579e 100644 --- a/trunk/drivers/media/video/v4l2-dev.c +++ b/trunk/drivers/media/video/v4l2-dev.c @@ -389,8 +389,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) video_get(vdev); mutex_unlock(&videodev_lock); #if defined(CONFIG_MEDIA_CONTROLLER) - if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) { + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) { entity = media_entity_get(&vdev->entity); if (!entity) { ret = -EBUSY; @@ -416,8 +415,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) /* decrease the refcount in case of an error */ if (ret) { #if defined(CONFIG_MEDIA_CONTROLLER) - if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) media_entity_put(entity); #endif video_put(vdev); @@ -439,8 +437,7 @@ static int v4l2_release(struct inode *inode, struct file *filp) mutex_unlock(vdev->lock); } #if defined(CONFIG_MEDIA_CONTROLLER) - if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) media_entity_put(&vdev->entity); #endif /* decrease the refcount unconditionally since the release() @@ -689,8 +686,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr, #if defined(CONFIG_MEDIA_CONTROLLER) /* Part 5: Register the entity. */ - if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) { + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) { vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; vdev->entity.name = vdev->name; vdev->entity.v4l.major = VIDEO_MAJOR; @@ -737,8 +733,7 @@ void video_unregister_device(struct video_device *vdev) return; #if defined(CONFIG_MEDIA_CONTROLLER) - if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) media_device_unregister_entity(&vdev->entity); #endif diff --git a/trunk/drivers/media/video/videobuf2-core.c b/trunk/drivers/media/video/videobuf2-core.c index 6ba1461d51ef..6698c77e0f64 100644 --- a/trunk/drivers/media/video/videobuf2-core.c +++ b/trunk/drivers/media/video/videobuf2-core.c @@ -37,9 +37,6 @@ module_param(debug, int, 0644); #define call_qop(q, op, args...) \ (((q)->ops->op) ? ((q)->ops->op(args)) : 0) -#define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \ - V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR) - /** * __vb2_buf_mem_alloc() - allocate video memory for the given buffer */ @@ -54,7 +51,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb, for (plane = 0; plane < vb->num_planes; ++plane) { mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane], plane_sizes[plane]); - if (IS_ERR_OR_NULL(mem_priv)) + if (!mem_priv) goto free; /* Associate allocator private data with this plane */ @@ -287,7 +284,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) struct vb2_queue *q = vb->vb2_queue; int ret = 0; - /* Copy back data such as timestamp, flags, input, etc. */ + /* Copy back data such as timestamp, input, etc. */ memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); b->input = vb->v4l2_buf.input; b->reserved = vb->v4l2_buf.reserved; @@ -316,10 +313,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) b->m.userptr = vb->v4l2_planes[0].m.userptr; } - /* - * Clear any buffer state related flags. - */ - b->flags &= ~V4L2_BUFFER_STATE_FLAGS; + b->flags = 0; switch (vb->state) { case VB2_BUF_STATE_QUEUED: @@ -525,7 +519,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME); memset(plane_sizes, 0, sizeof(plane_sizes)); memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); - q->memory = req->memory; /* * Ask the driver how many buffers and planes per buffer it requires. @@ -567,6 +560,8 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) ret = num_buffers; } + q->memory = req->memory; + /* * Return the number of successfully allocated buffers * to the userspace. @@ -720,8 +715,6 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, vb->v4l2_buf.field = b->field; vb->v4l2_buf.timestamp = b->timestamp; - vb->v4l2_buf.input = b->input; - vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS; return 0; } diff --git a/trunk/drivers/media/video/videobuf2-dma-contig.c b/trunk/drivers/media/video/videobuf2-dma-contig.c index a790a5f8c06f..58205d596138 100644 --- a/trunk/drivers/media/video/videobuf2-dma-contig.c +++ b/trunk/drivers/media/video/videobuf2-dma-contig.c @@ -46,7 +46,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) GFP_KERNEL); if (!buf->vaddr) { dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n", - size); + buf->size); kfree(buf); return ERR_PTR(-ENOMEM); } diff --git a/trunk/drivers/mmc/core/bus.c b/trunk/drivers/mmc/core/bus.c index d6d62fd07ee9..63667a8f140c 100644 --- a/trunk/drivers/mmc/core/bus.c +++ b/trunk/drivers/mmc/core/bus.c @@ -284,7 +284,6 @@ int mmc_add_card(struct mmc_card *card) type = "SD-combo"; if (mmc_card_blockaddr(card)) type = "SDHC-combo"; - break; default: type = "?"; break; diff --git a/trunk/drivers/mmc/core/host.c b/trunk/drivers/mmc/core/host.c index 2b200c1cfbba..461e6a17fb90 100644 --- a/trunk/drivers/mmc/core/host.c +++ b/trunk/drivers/mmc/core/host.c @@ -94,7 +94,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) spin_unlock_irqrestore(&host->clk_lock, flags); return; } - mmc_claim_host(host); + mutex_lock(&host->clk_gate_mutex); spin_lock_irqsave(&host->clk_lock, flags); if (!host->clk_requests) { spin_unlock_irqrestore(&host->clk_lock, flags); @@ -104,7 +104,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) pr_debug("%s: gated MCI clock\n", mmc_hostname(host)); } spin_unlock_irqrestore(&host->clk_lock, flags); - mmc_release_host(host); + mutex_unlock(&host->clk_gate_mutex); } /* @@ -130,7 +130,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) { unsigned long flags; - mmc_claim_host(host); + mutex_lock(&host->clk_gate_mutex); spin_lock_irqsave(&host->clk_lock, flags); if (host->clk_gated) { spin_unlock_irqrestore(&host->clk_lock, flags); @@ -140,7 +140,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) } host->clk_requests++; spin_unlock_irqrestore(&host->clk_lock, flags); - mmc_release_host(host); + mutex_unlock(&host->clk_gate_mutex); } /** @@ -215,6 +215,7 @@ static inline void mmc_host_clk_init(struct mmc_host *host) host->clk_gated = false; INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); spin_lock_init(&host->clk_lock); + mutex_init(&host->clk_gate_mutex); } /** diff --git a/trunk/drivers/mmc/host/omap.c b/trunk/drivers/mmc/host/omap.c index a6c329040140..2e032f0e8cf4 100644 --- a/trunk/drivers/mmc/host/omap.c +++ b/trunk/drivers/mmc/host/omap.c @@ -832,7 +832,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) return IRQ_HANDLED; } - if (end_command && host->cmd) + if (end_command) mmc_omap_cmd_done(host, host->cmd); if (host->data != NULL) { if (transfer_error) diff --git a/trunk/drivers/mmc/host/sdhci-pci.c b/trunk/drivers/mmc/host/sdhci-pci.c index f8b5f37007b2..a136be706347 100644 --- a/trunk/drivers/mmc/host/sdhci-pci.c +++ b/trunk/drivers/mmc/host/sdhci-pci.c @@ -957,7 +957,6 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( host->ioaddr = pci_ioremap_bar(pdev, bar); if (!host->ioaddr) { dev_err(&pdev->dev, "failed to remap registers\n"); - ret = -ENOMEM; goto release; } diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index 5d20661bc357..9e15f41f87be 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -1334,13 +1334,6 @@ static void sdhci_tasklet_finish(unsigned long param) host = (struct sdhci_host*)param; - /* - * If this tasklet gets rescheduled while running, it will - * be run again afterwards but without any active request. - */ - if (!host->mrq) - return; - spin_lock_irqsave(&host->lock, flags); del_timer(&host->timer); @@ -1352,7 +1345,7 @@ static void sdhci_tasklet_finish(unsigned long param) * upon error conditions. */ if (!(host->flags & SDHCI_DEVICE_DEAD) && - ((mrq->cmd && mrq->cmd->error) || + (mrq->cmd->error || (mrq->data && (mrq->data->error || (mrq->data->stop && mrq->data->stop->error))) || (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { diff --git a/trunk/drivers/mmc/host/tmio_mmc_pio.c b/trunk/drivers/mmc/host/tmio_mmc_pio.c index 710339a85c84..62d37de6de76 100644 --- a/trunk/drivers/mmc/host/tmio_mmc_pio.c +++ b/trunk/drivers/mmc/host/tmio_mmc_pio.c @@ -728,15 +728,15 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) tmio_mmc_set_clock(host, ios->clock); /* Power sequence - OFF -> UP -> ON */ - if (ios->power_mode == MMC_POWER_UP) { - /* power up SD bus */ - if (host->set_pwr) - host->set_pwr(host->pdev, 1); - } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { + if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { /* power down SD bus */ if (ios->power_mode == MMC_POWER_OFF && host->set_pwr) host->set_pwr(host->pdev, 0); tmio_mmc_clk_stop(host); + } else if (ios->power_mode == MMC_POWER_UP) { + /* power up SD bus */ + if (host->set_pwr) + host->set_pwr(host->pdev, 1); } else { /* start bus clock */ tmio_mmc_clk_start(host); diff --git a/trunk/drivers/mtd/nand/diskonchip.c b/trunk/drivers/mtd/nand/diskonchip.c index 657b9f4b6f9b..96c0b34ba8db 100644 --- a/trunk/drivers/mtd/nand/diskonchip.c +++ b/trunk/drivers/mtd/nand/diskonchip.c @@ -400,7 +400,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); - /* We can't use dev_ready here, but at least we wait for the + /* We can't' use dev_ready here, but at least we wait for the * command to complete */ udelay(50); diff --git a/trunk/drivers/net/amd8111e.c b/trunk/drivers/net/amd8111e.c index 241b185e6569..88495c48a81d 100644 --- a/trunk/drivers/net/amd8111e.c +++ b/trunk/drivers/net/amd8111e.c @@ -106,7 +106,7 @@ MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version "M MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl); module_param_array(speed_duplex, int, NULL, 0); -MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotiate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex"); +MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotitate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex"); module_param_array(coalesce, bool, NULL, 0); MODULE_PARM_DESC(coalesce, "Enable or Disable interrupt coalescing, 1: Enable, 0: Disable"); module_param_array(dynamic_ipg, bool, NULL, 0); diff --git a/trunk/drivers/net/atl1c/atl1c.h b/trunk/drivers/net/atl1c/atl1c.h index 925929d764ca..7cb375e0e29c 100644 --- a/trunk/drivers/net/atl1c/atl1c.h +++ b/trunk/drivers/net/atl1c/atl1c.h @@ -566,9 +566,9 @@ struct atl1c_adapter { #define __AT_TESTING 0x0001 #define __AT_RESETTING 0x0002 #define __AT_DOWN 0x0003 - unsigned long work_event; -#define ATL1C_WORK_EVENT_RESET 0 -#define ATL1C_WORK_EVENT_LINK_CHANGE 1 + u8 work_event; +#define ATL1C_WORK_EVENT_RESET 0x01 +#define ATL1C_WORK_EVENT_LINK_CHANGE 0x02 u32 msg_enable; bool have_msi; diff --git a/trunk/drivers/net/atl1c/atl1c_main.c b/trunk/drivers/net/atl1c/atl1c_main.c index a6e1c36e48e6..7d9d5067a65c 100644 --- a/trunk/drivers/net/atl1c/atl1c_main.c +++ b/trunk/drivers/net/atl1c/atl1c_main.c @@ -325,7 +325,7 @@ static void atl1c_link_chg_event(struct atl1c_adapter *adapter) } } - set_bit(ATL1C_WORK_EVENT_LINK_CHANGE, &adapter->work_event); + adapter->work_event |= ATL1C_WORK_EVENT_LINK_CHANGE; schedule_work(&adapter->common_task); } @@ -337,16 +337,20 @@ static void atl1c_common_task(struct work_struct *work) adapter = container_of(work, struct atl1c_adapter, common_task); netdev = adapter->netdev; - if (test_and_clear_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event)) { + if (adapter->work_event & ATL1C_WORK_EVENT_RESET) { + adapter->work_event &= ~ATL1C_WORK_EVENT_RESET; netif_device_detach(netdev); atl1c_down(adapter); atl1c_up(adapter); netif_device_attach(netdev); + return; } - if (test_and_clear_bit(ATL1C_WORK_EVENT_LINK_CHANGE, - &adapter->work_event)) + if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE) { + adapter->work_event &= ~ATL1C_WORK_EVENT_LINK_CHANGE; atl1c_check_link_status(adapter); + } + return; } @@ -365,7 +369,7 @@ static void atl1c_tx_timeout(struct net_device *netdev) struct atl1c_adapter *adapter = netdev_priv(netdev); /* Do the reset outside of interrupt context */ - set_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event); + adapter->work_event |= ATL1C_WORK_EVENT_RESET; schedule_work(&adapter->common_task); } diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c index 02a0443d1821..7cb5a114c733 100644 --- a/trunk/drivers/net/benet/be_main.c +++ b/trunk/drivers/net/benet/be_main.c @@ -1873,7 +1873,6 @@ static void be_worker(struct work_struct *work) be_detect_dump_ue(adapter); reschedule: - adapter->work_counter++; schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); } diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index d8383a9af9ad..8e6d618b5305 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -8413,8 +8413,6 @@ bnx2_remove_one(struct pci_dev *pdev) unregister_netdev(dev); - del_timer_sync(&bp->timer); - if (bp->mips_firmware) release_firmware(bp->mips_firmware); if (bp->rv2p_firmware) diff --git a/trunk/drivers/net/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/bnx2x/bnx2x_cmn.c index 16581df5ee4e..e83ac6dd6fc0 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/bnx2x/bnx2x_cmn.c @@ -2019,23 +2019,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, u32 *parsing_data, u32 xmit_type) { - *parsing_data |= - ((((u8 *)skb_transport_header(skb) - skb->data) >> 1) << - ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & - ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; + *parsing_data |= ((tcp_hdrlen(skb)/4) << + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; - if (xmit_type & XMIT_CSUM_TCP) { - *parsing_data |= ((tcp_hdrlen(skb) / 4) << - ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & - ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; + *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) << + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; - return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; - } else - /* We support checksum offload for TCP and UDP only. - * No need to pass the UDP header length - it's a constant. - */ - return skb_transport_header(skb) + - sizeof(struct udphdr) - skb->data; + return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; } /** @@ -2051,7 +2043,7 @@ static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, struct eth_tx_parse_bd_e1x *pbd, u32 xmit_type) { - u8 hlen = (skb_network_header(skb) - skb->data) >> 1; + u8 hlen = (skb_network_header(skb) - skb->data) / 2; /* for now NS flag is not used in Linux */ pbd->global_data = @@ -2059,15 +2051,9 @@ static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); pbd->ip_hlen_w = (skb_transport_header(skb) - - skb_network_header(skb)) >> 1; + skb_network_header(skb)) / 2; - hlen += pbd->ip_hlen_w; - - /* We support checksum offload for TCP and UDP only */ - if (xmit_type & XMIT_CSUM_TCP) - hlen += tcp_hdrlen(skb) / 2; - else - hlen += sizeof(struct udphdr) / 2; + hlen += pbd->ip_hlen_w + tcp_hdrlen(skb) / 2; pbd->total_hlen_w = cpu_to_le16(hlen); hlen = hlen*2; diff --git a/trunk/drivers/net/bonding/bond_3ad.c b/trunk/drivers/net/bonding/bond_3ad.c index 31912f17653f..494bf960442d 100644 --- a/trunk/drivers/net/bonding/bond_3ad.c +++ b/trunk/drivers/net/bonding/bond_3ad.c @@ -1482,11 +1482,8 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, static int agg_device_up(const struct aggregator *agg) { - struct port *port = agg->lag_ports; - if (!port) - return 0; - return (netif_running(port->slave->dev) && - netif_carrier_ok(port->slave->dev)); + return (netif_running(agg->slave->dev) && + netif_carrier_ok(agg->slave->dev)); } /** diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c index 53c0f04b1b23..f75d3144b8a5 100644 --- a/trunk/drivers/net/ehea/ehea_main.c +++ b/trunk/drivers/net/ehea/ehea_main.c @@ -3040,14 +3040,11 @@ static void ehea_rereg_mrs(void) if (dev->flags & IFF_UP) { mutex_lock(&port->port_lock); + port_napi_enable(port); ret = ehea_restart_qps(dev); - if (!ret) { - check_sqs(port); - port_napi_enable(port); + check_sqs(port); + if (!ret) netif_wake_queue(dev); - } else { - netdev_err(dev, "Unable to restart QPS\n"); - } mutex_unlock(&port->port_lock); } } diff --git a/trunk/drivers/net/fs_enet/mac-fec.c b/trunk/drivers/net/fs_enet/mac-fec.c index b9fbc83d64a7..61035fc5599b 100644 --- a/trunk/drivers/net/fs_enet/mac-fec.c +++ b/trunk/drivers/net/fs_enet/mac-fec.c @@ -226,8 +226,8 @@ static void set_multicast_finish(struct net_device *dev) } FC(fecp, r_cntrl, FEC_RCNTRL_PROM); - FW(fecp, grp_hash_table_high, fep->fec.hthi); - FW(fecp, grp_hash_table_low, fep->fec.htlo); + FW(fecp, hash_table_high, fep->fec.hthi); + FW(fecp, hash_table_low, fep->fec.htlo); } static void set_multicast_list(struct net_device *dev) @@ -273,8 +273,8 @@ static void restart(struct net_device *dev) /* * Reset all multicast. */ - FW(fecp, grp_hash_table_high, fep->fec.hthi); - FW(fecp, grp_hash_table_low, fep->fec.htlo); + FW(fecp, hash_table_high, fep->fec.hthi); + FW(fecp, hash_table_low, fep->fec.htlo); /* * Set maximum receive buffer size. diff --git a/trunk/drivers/net/ftmac100.c b/trunk/drivers/net/ftmac100.c index 9bd7746cbfcf..a31661948c42 100644 --- a/trunk/drivers/net/ftmac100.c +++ b/trunk/drivers/net/ftmac100.c @@ -139,11 +139,11 @@ static int ftmac100_reset(struct ftmac100 *priv) * that hardware reset completed (what the f*ck). * We still need to wait for a while. */ - udelay(500); + usleep_range(500, 1000); return 0; } - udelay(1000); + usleep_range(1000, 10000); } netdev_err(netdev, "software reset failed\n"); @@ -772,7 +772,7 @@ static int ftmac100_mdio_read(struct net_device *netdev, int phy_id, int reg) if ((phycr & FTMAC100_PHYCR_MIIRD) == 0) return phycr & FTMAC100_PHYCR_MIIRDATA; - udelay(100); + usleep_range(100, 1000); } netdev_err(netdev, "mdio read timed out\n"); @@ -801,7 +801,7 @@ static void ftmac100_mdio_write(struct net_device *netdev, int phy_id, int reg, if ((phycr & FTMAC100_PHYCR_MIIWR) == 0) return; - udelay(100); + usleep_range(100, 1000); } netdev_err(netdev, "mdio write timed out\n"); diff --git a/trunk/drivers/net/mii.c b/trunk/drivers/net/mii.c index d4fc00b1ff93..0a6c6a2e7550 100644 --- a/trunk/drivers/net/mii.c +++ b/trunk/drivers/net/mii.c @@ -49,10 +49,6 @@ static u32 mii_get_an(struct mii_if_info *mii, u16 addr) result |= ADVERTISED_100baseT_Half; if (advert & ADVERTISE_100FULL) result |= ADVERTISED_100baseT_Full; - if (advert & ADVERTISE_PAUSE_CAP) - result |= ADVERTISED_Pause; - if (advert & ADVERTISE_PAUSE_ASYM) - result |= ADVERTISED_Asym_Pause; return result; } diff --git a/trunk/drivers/net/netconsole.c b/trunk/drivers/net/netconsole.c index eb41e44921e6..dfb67eb2a94b 100644 --- a/trunk/drivers/net/netconsole.c +++ b/trunk/drivers/net/netconsole.c @@ -671,7 +671,6 @@ static int netconsole_netdev_event(struct notifier_block *this, goto done; spin_lock_irqsave(&target_list_lock, flags); -restart: list_for_each_entry(nt, &target_list, list) { netconsole_target_get(nt); if (nt->np.dev == dev) { @@ -684,16 +683,9 @@ static int netconsole_netdev_event(struct notifier_block *this, * rtnl_lock already held */ if (nt->np.dev) { - spin_unlock_irqrestore( - &target_list_lock, - flags); __netpoll_cleanup(&nt->np); - spin_lock_irqsave(&target_list_lock, - flags); dev_put(nt->np.dev); nt->np.dev = NULL; - netconsole_target_put(nt); - goto restart; } /* Fall through */ case NETDEV_GOING_DOWN: diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 397c36810a15..493b0de3848b 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -170,16 +170,6 @@ static const struct { }; #undef _R -static const struct rtl_firmware_info { - int mac_version; - const char *fw_name; -} rtl_firmware_infos[] = { - { .mac_version = RTL_GIGA_MAC_VER_25, .fw_name = FIRMWARE_8168D_1 }, - { .mac_version = RTL_GIGA_MAC_VER_26, .fw_name = FIRMWARE_8168D_2 }, - { .mac_version = RTL_GIGA_MAC_VER_29, .fw_name = FIRMWARE_8105E_1 }, - { .mac_version = RTL_GIGA_MAC_VER_30, .fw_name = FIRMWARE_8105E_1 } -}; - enum cfg_version { RTL_CFG_0 = 0x00, RTL_CFG_1, @@ -575,7 +565,6 @@ struct rtl8169_private { u32 saved_wolopts; const struct firmware *fw; -#define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN); }; MODULE_AUTHOR("Realtek and the Linux r8169 crew "); @@ -1800,26 +1789,25 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) static void rtl_release_firmware(struct rtl8169_private *tp) { - if (!IS_ERR_OR_NULL(tp->fw)) - release_firmware(tp->fw); - tp->fw = RTL_FIRMWARE_UNKNOWN; + release_firmware(tp->fw); + tp->fw = NULL; } -static void rtl_apply_firmware(struct rtl8169_private *tp) +static int rtl_apply_firmware(struct rtl8169_private *tp, const char *fw_name) { - const struct firmware *fw = tp->fw; + const struct firmware **fw = &tp->fw; + int rc = !*fw; - /* TODO: release firmware once rtl_phy_write_fw signals failures. */ - if (!IS_ERR_OR_NULL(fw)) - rtl_phy_write_fw(tp, fw); -} + if (rc) { + rc = request_firmware(fw, fw_name, &tp->pci_dev->dev); + if (rc < 0) + goto out; + } -static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) -{ - if (rtl_readphy(tp, reg) != val) - netif_warn(tp, hw, tp->dev, "chipset not ready for firmware\n"); - else - rtl_apply_firmware(tp); + /* TODO: release firmware once rtl_phy_write_fw signals failures. */ + rtl_phy_write_fw(tp, *fw); +out: + return rc; } static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) @@ -2258,8 +2246,10 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0005); rtl_writephy(tp, 0x05, 0x001b); - - rtl_apply_firmware_cond(tp, MII_EXPANSION, 0xbf00); + if ((rtl_readphy(tp, 0x06) != 0xbf00) || + (rtl_apply_firmware(tp, FIRMWARE_8168D_1) < 0)) { + netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); + } rtl_writephy(tp, 0x1f, 0x0000); } @@ -2361,8 +2351,10 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0005); rtl_writephy(tp, 0x05, 0x001b); - - rtl_apply_firmware_cond(tp, MII_EXPANSION, 0xb300); + if ((rtl_readphy(tp, 0x06) != 0xb300) || + (rtl_apply_firmware(tp, FIRMWARE_8168D_2) < 0)) { + netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); + } rtl_writephy(tp, 0x1f, 0x0000); } @@ -2482,7 +2474,8 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x18, 0x0310); msleep(100); - rtl_apply_firmware(tp); + if (rtl_apply_firmware(tp, FIRMWARE_8105E_1) < 0) + netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } @@ -3244,8 +3237,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->timer.data = (unsigned long) dev; tp->timer.function = rtl8169_phy_timer; - tp->fw = RTL_FIRMWARE_UNKNOWN; - rc = register_netdev(dev); if (rc < 0) goto err_out_msi_4; @@ -3297,10 +3288,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) cancel_delayed_work_sync(&tp->task); - unregister_netdev(dev); - rtl_release_firmware(tp); + unregister_netdev(dev); + if (pci_dev_run_wake(pdev)) pm_runtime_get_noresume(&pdev->dev); @@ -3312,37 +3303,6 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } -static void rtl_request_firmware(struct rtl8169_private *tp) -{ - int i; - - /* Return early if the firmware is already loaded / cached. */ - if (!IS_ERR(tp->fw)) - goto out; - - for (i = 0; i < ARRAY_SIZE(rtl_firmware_infos); i++) { - const struct rtl_firmware_info *info = rtl_firmware_infos + i; - - if (info->mac_version == tp->mac_version) { - const char *name = info->fw_name; - int rc; - - rc = request_firmware(&tp->fw, name, &tp->pci_dev->dev); - if (rc < 0) { - netif_warn(tp, ifup, tp->dev, "unable to load " - "firmware patch %s (%d)\n", name, rc); - goto out_disable_request_firmware; - } - goto out; - } - } - -out_disable_request_firmware: - tp->fw = NULL; -out: - return; -} - static int rtl8169_open(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3374,13 +3334,11 @@ static int rtl8169_open(struct net_device *dev) smp_mb(); - rtl_request_firmware(tp); - retval = request_irq(dev->irq, rtl8169_interrupt, (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED, dev->name, dev); if (retval < 0) - goto err_release_fw_2; + goto err_release_ring_2; napi_enable(&tp->napi); @@ -3401,8 +3359,7 @@ static int rtl8169_open(struct net_device *dev) out: return retval; -err_release_fw_2: - rtl_release_firmware(tp); +err_release_ring_2: rtl8169_rx_clear(tp); err_free_rx_1: dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 7a5daefb6f33..b8c5f35577e4 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -12327,10 +12327,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) if (val & VCPU_CFGSHDW_ASPM_DBNC) tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; if ((val & VCPU_CFGSHDW_WOL_ENABLE) && - (val & VCPU_CFGSHDW_WOL_MAGPKT)) { + (val & VCPU_CFGSHDW_WOL_MAGPKT)) tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; - device_set_wakeup_enable(&tp->pdev->dev, true); - } goto done; } @@ -12463,10 +12461,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->tg3_flags &= ~TG3_FLAG_WOL_CAP; if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) && - (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE)) { + (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE)) tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; - device_set_wakeup_enable(&tp->pdev->dev, true); - } if (cfg2 & (1 << 17)) tp->phy_flags |= TG3_PHYFLG_CAPACITIVE_COUPLING; diff --git a/trunk/drivers/net/usb/cdc_ether.c b/trunk/drivers/net/usb/cdc_ether.c index a301479ecc60..341f7056a800 100644 --- a/trunk/drivers/net/usb/cdc_ether.c +++ b/trunk/drivers/net/usb/cdc_ether.c @@ -460,7 +460,7 @@ static const struct driver_info cdc_info = { .manage_power = cdc_manage_power, }; -static const struct driver_info wwan_info = { +static const struct driver_info mbm_info = { .description = "Mobile Broadband Network Device", .flags = FLAG_WWAN, .bind = usbnet_cdc_bind, @@ -471,7 +471,6 @@ static const struct driver_info wwan_info = { /*-------------------------------------------------------------------------*/ -#define HUAWEI_VENDOR_ID 0x12D1 static const struct usb_device_id products [] = { /* @@ -588,17 +587,8 @@ static const struct usb_device_id products [] = { }, { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long)&wwan_info, + .driver_info = (unsigned long)&mbm_info, -}, { - /* Various Huawei modems with a network port like the UMG1831 */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = HUAWEI_VENDOR_ID, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = 255, - .driver_info = (unsigned long)&wwan_info, }, { }, // END }; diff --git a/trunk/drivers/net/usb/cdc_ncm.c b/trunk/drivers/net/usb/cdc_ncm.c index 1033ef6476a4..967371f04454 100644 --- a/trunk/drivers/net/usb/cdc_ncm.c +++ b/trunk/drivers/net/usb/cdc_ncm.c @@ -54,13 +54,13 @@ #include #include -#define DRIVER_VERSION "23-Apr-2011" +#define DRIVER_VERSION "7-Feb-2011" /* CDC NCM subclass 3.2.1 */ #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 /* Maximum NTB length */ -#define CDC_NCM_NTB_MAX_SIZE_TX (16384 + 4) /* bytes, must be short terminated */ +#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */ #define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */ /* Minimum value for MaxDatagramSize, ch. 6.2.9 */ diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index 48d4efdb4959..47a6c870b51f 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -730,7 +730,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) msleep(10); bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); timeout++; - } while ((bmcr & BMCR_RESET) && (timeout < 100)); + } while ((bmcr & MII_BMCR) && (timeout < 100)); if (timeout >= 100) { netdev_warn(dev->net, "timeout on PHY Reset"); diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index 009bba3d753e..069c1cf0fdf7 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -736,7 +736,6 @@ int usbnet_open (struct net_device *net) } } - set_bit(EVENT_DEV_OPEN, &dev->flags); netif_start_queue (net); netif_info(dev, ifup, dev->net, "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n", @@ -1260,9 +1259,6 @@ void usbnet_disconnect (struct usb_interface *intf) if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf); - usb_kill_urb(dev->interrupt); - usb_free_urb(dev->interrupt); - free_netdev(net); usb_put_dev (xdev); } @@ -1502,10 +1498,6 @@ int usbnet_resume (struct usb_interface *intf) int retval; if (!--dev->suspend_count) { - /* resume interrupt URBs */ - if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags)) - usb_submit_urb(dev->interrupt, GFP_NOIO); - spin_lock_irq(&dev->txq.lock); while ((res = usb_get_from_anchor(&dev->deferred))) { diff --git a/trunk/drivers/net/veth.c b/trunk/drivers/net/veth.c index 3b99f64104fd..2de9b90c5f8f 100644 --- a/trunk/drivers/net/veth.c +++ b/trunk/drivers/net/veth.c @@ -403,17 +403,6 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, if (tb[IFLA_ADDRESS] == NULL) random_ether_addr(dev->dev_addr); - if (tb[IFLA_IFNAME]) - nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ); - else - snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d"); - - if (strchr(dev->name, '%')) { - err = dev_alloc_name(dev, dev->name); - if (err < 0) - goto err_alloc_name; - } - err = register_netdevice(dev); if (err < 0) goto err_register_dev; @@ -433,7 +422,6 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, err_register_dev: /* nothing to do */ -err_alloc_name: err_configure_peer: unregister_netdevice(peer); return err; diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index b29c80def35e..dcd19bc337d1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -506,7 +506,7 @@ bool ath_stoprecv(struct ath_softc *sc) "confusing the DMA engine when we start RX up\n"); ATH_DBG_WARN_ON_ONCE(!stopped); } - return stopped && !reset; + return stopped || reset; } void ath_flushrecv(struct ath_softc *sc) diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 5af40d9170a0..d59b0168c14a 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -72,7 +72,6 @@ MODULE_FIRMWARE("b43/ucode11.fw"); MODULE_FIRMWARE("b43/ucode13.fw"); MODULE_FIRMWARE("b43/ucode14.fw"); MODULE_FIRMWARE("b43/ucode15.fw"); -MODULE_FIRMWARE("b43/ucode16_mimo.fw"); MODULE_FIRMWARE("b43/ucode5.fw"); MODULE_FIRMWARE("b43/ucode9.fw"); diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c index 79ac081832fb..5c40502f869a 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c @@ -316,18 +316,12 @@ int iwl4965_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); - /* For management frames use broadcast id to do not break aggregation */ - if (!ieee80211_is_data(fc)) - sta_id = ctx->bcast_sta_id; - else { - /* Find index into station table for destination station */ - sta_id = iwl_legacy_sta_id_or_broadcast(priv, ctx, info->control.sta); - - if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", - hdr->addr1); - goto drop_unlock; - } + /* Find index into station table for destination station */ + sta_id = iwl_legacy_sta_id_or_broadcast(priv, ctx, info->control.sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", + hdr->addr1); + goto drop_unlock; } IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); @@ -1133,16 +1127,12 @@ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) { tx_info = &txq->txb[txq->q.read_ptr]; - - if (WARN_ON_ONCE(tx_info->skb == NULL)) - continue; + iwl4965_tx_status(priv, tx_info, + txq_id >= IWL4965_FIRST_AMPDU_QUEUE); hdr = (struct ieee80211_hdr *)tx_info->skb->data; - if (ieee80211_is_data_qos(hdr->frame_control)) + if (hdr && ieee80211_is_data_qos(hdr->frame_control)) nfreed++; - - iwl4965_tx_status(priv, tx_info, - txq_id >= IWL4965_FIRST_AMPDU_QUEUE); tx_info->skb = NULL; priv->cfg->ops->lib->txq_free_tfd(priv, txq); diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-led.c b/trunk/drivers/net/wireless/iwlegacy/iwl-led.c index bda0d61b2c0d..15eb8b707157 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-led.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-led.c @@ -48,21 +48,8 @@ module_param(led_mode, int, S_IRUGO); MODULE_PARM_DESC(led_mode, "0=system default, " "1=On(RF On)/Off(RF Off), 2=blinking"); -/* Throughput OFF time(ms) ON time (ms) - * >300 25 25 - * >200 to 300 40 40 - * >100 to 200 55 55 - * >70 to 100 65 65 - * >50 to 70 75 75 - * >20 to 50 85 85 - * >10 to 20 95 95 - * >5 to 10 110 110 - * >1 to 5 130 130 - * >0 to 1 167 167 - * <=0 SOLID ON - */ static const struct ieee80211_tpt_blink iwl_blink[] = { - { .throughput = 0, .blink_time = 334 }, + { .throughput = 0 * 1024 - 1, .blink_time = 334 }, { .throughput = 1 * 1024 - 1, .blink_time = 260 }, { .throughput = 5 * 1024 - 1, .blink_time = 220 }, { .throughput = 10 * 1024 - 1, .blink_time = 190 }, @@ -114,11 +101,6 @@ static int iwl_legacy_led_cmd(struct iwl_priv *priv, if (priv->blink_on == on && priv->blink_off == off) return 0; - if (off == 0) { - /* led is SOLID_ON */ - on = IWL_LED_SOLID; - } - IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n", priv->cfg->base_params->led_compensation); led_cmd.on = iwl_legacy_blink_compensation(priv, on, diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c b/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c index a62fe24ee594..d484c3678163 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -2984,15 +2984,15 @@ static void iwl4965_bg_txpower_work(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, txpower_work); - mutex_lock(&priv->mutex); - /* If a scan happened to start before we got here * then just return; the statistics notification will * kick off another scheduled work to compensate for * any temperature delta we missed here. */ if (test_bit(STATUS_EXIT_PENDING, &priv->status) || test_bit(STATUS_SCANNING, &priv->status)) - goto out; + return; + + mutex_lock(&priv->mutex); /* Regardless of if we are associated, we must reconfigure the * TX power since frames can be sent on non-radar channels while @@ -3002,7 +3002,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work) /* Update last_temperature to keep is_calib_needed from running * when it isn't needed... */ priv->last_temperature = priv->temperature; -out: + mutex_unlock(&priv->mutex); } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index fbbde0712fa5..dfdbea6e8f99 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -335,6 +335,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) struct ieee80211_channel *channel = conf->channel; const struct iwl_channel_info *ch_info; int ret = 0; + bool ht_changed[NUM_IWL_RXON_CTX] = {}; IWL_DEBUG_MAC80211(priv, "changed %#x", changed); @@ -382,8 +383,10 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) for_each_context(priv, ctx) { /* Configure HT40 channels */ - if (ctx->ht.enabled != conf_is_ht(conf)) + if (ctx->ht.enabled != conf_is_ht(conf)) { ctx->ht.enabled = conf_is_ht(conf); + ht_changed[ctx->ctxid] = true; + } if (ctx->ht.enabled) { if (conf_is_ht40_minus(conf)) { @@ -452,6 +455,8 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) continue; iwlagn_commit_rxon(priv, ctx); + if (ht_changed[ctx->ctxid]) + iwlagn_update_qos(priv, ctx); } out: mutex_unlock(&priv->mutex); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 0712b67283a4..a709d05c5868 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -568,17 +568,12 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); - /* For management frames use broadcast id to do not break aggregation */ - if (!ieee80211_is_data(fc)) - sta_id = ctx->bcast_sta_id; - else { - /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); - if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", - hdr->addr1); - goto drop_unlock; - } + /* Find index into station table for destination station */ + sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", + hdr->addr1); + goto drop_unlock; } IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); @@ -1229,16 +1224,12 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { tx_info = &txq->txb[txq->q.read_ptr]; - - if (WARN_ON_ONCE(tx_info->skb == NULL)) - continue; + iwlagn_tx_status(priv, tx_info, + txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); hdr = (struct ieee80211_hdr *)tx_info->skb->data; - if (ieee80211_is_data_qos(hdr->frame_control)) + if (hdr && ieee80211_is_data_qos(hdr->frame_control)) nfreed++; - - iwlagn_tx_status(priv, tx_info, - txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); tx_info->skb = NULL; if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) diff --git a/trunk/drivers/pcmcia/pcmcia_resource.c b/trunk/drivers/pcmcia/pcmcia_resource.c index e8c19def1b0f..fe77e8223841 100644 --- a/trunk/drivers/pcmcia/pcmcia_resource.c +++ b/trunk/drivers/pcmcia/pcmcia_resource.c @@ -173,7 +173,7 @@ static int pcmcia_access_config(struct pcmcia_device *p_dev, c = p_dev->function_config; if (!(c->state & CONFIG_LOCKED)) { - dev_dbg(&p_dev->dev, "Configuration isn't locked\n"); + dev_dbg(&p_dev->dev, "Configuration isn't't locked\n"); mutex_unlock(&s->ops_mutex); return -EACCES; } diff --git a/trunk/drivers/rtc/rtc-max8925.c b/trunk/drivers/rtc/rtc-max8925.c index 20494b5edc3c..174036dda786 100644 --- a/trunk/drivers/rtc/rtc-max8925.c +++ b/trunk/drivers/rtc/rtc-max8925.c @@ -257,8 +257,6 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) goto out_irq; } - dev_set_drvdata(&pdev->dev, info); - info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, &max8925_rtc_ops, THIS_MODULE); ret = PTR_ERR(info->rtc_dev); @@ -267,6 +265,7 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) goto out_rtc; } + dev_set_drvdata(&pdev->dev, info); platform_set_drvdata(pdev, info); return 0; diff --git a/trunk/drivers/s390/block/dasd_diag.c b/trunk/drivers/s390/block/dasd_diag.c index 85dddb1e4126..29143eda9dd9 100644 --- a/trunk/drivers/s390/block/dasd_diag.c +++ b/trunk/drivers/s390/block/dasd_diag.c @@ -239,6 +239,7 @@ static void dasd_ext_handler(unsigned int ext_int_code, addr_t ip; int rc; + kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++; switch (ext_int_code >> 24) { case DASD_DIAG_CODE_31BIT: ip = (addr_t) param32; @@ -249,7 +250,6 @@ static void dasd_ext_handler(unsigned int ext_int_code, default: return; } - kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++; if (!ip) { /* no intparm: unsolicited interrupt */ DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited " "interrupt"); diff --git a/trunk/drivers/s390/kvm/kvm_virtio.c b/trunk/drivers/s390/kvm/kvm_virtio.c index 607998f0b7d8..414427d64a8f 100644 --- a/trunk/drivers/s390/kvm/kvm_virtio.c +++ b/trunk/drivers/s390/kvm/kvm_virtio.c @@ -381,10 +381,10 @@ static void kvm_extint_handler(unsigned int ext_int_code, u16 subcode; u32 param; + kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; subcode = ext_int_code >> 16; if ((subcode & 0xff00) != VIRTIO_SUBCODE_64) return; - kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; /* The LSB might be overloaded, we have to mask it */ vq = (struct virtqueue *)(param64 & ~1UL); diff --git a/trunk/drivers/scsi/device_handler/scsi_dh.c b/trunk/drivers/scsi/device_handler/scsi_dh.c index 0119b8147797..564e6ecd17c2 100644 --- a/trunk/drivers/scsi/device_handler/scsi_dh.c +++ b/trunk/drivers/scsi/device_handler/scsi_dh.c @@ -394,14 +394,12 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) unsigned long flags; struct scsi_device *sdev; struct scsi_device_handler *scsi_dh = NULL; - struct device *dev = NULL; spin_lock_irqsave(q->queue_lock, flags); sdev = q->queuedata; if (sdev && sdev->scsi_dh_data) scsi_dh = sdev->scsi_dh_data->scsi_dh; - dev = get_device(&sdev->sdev_gendev); - if (!scsi_dh || !dev || + if (!scsi_dh || !get_device(&sdev->sdev_gendev) || sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL) err = SCSI_DH_NOSYS; @@ -412,13 +410,12 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) if (err) { if (fn) fn(data, err); - goto out; + return err; } if (scsi_dh->activate) err = scsi_dh->activate(sdev, fn, data); -out: - put_device(dev); + put_device(&sdev->sdev_gendev); return err; } EXPORT_SYMBOL_GPL(scsi_dh_activate); diff --git a/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c index d72f1f2b1392..1c6d2b405eef 100644 --- a/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c @@ -688,13 +688,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, goto out; } - /* Check for overflow and wraparound */ - if (karg.data_sge_offset * 4 > ioc->request_sz || - karg.data_sge_offset > (UINT_MAX / 4)) { - ret = -EINVAL; - goto out; - } - /* copy in request message frame from user */ if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, @@ -1970,7 +1963,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) Mpi2DiagBufferPostReply_t *mpi_reply; int rc, i; u8 buffer_type; - unsigned long timeleft, request_size, copy_size; + unsigned long timeleft; u16 smid; u16 ioc_status; u8 issue_reset = 0; @@ -2006,8 +1999,6 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) return -ENOMEM; } - request_size = ioc->diag_buffer_sz[buffer_type]; - if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) { printk(MPT2SAS_ERR_FMT "%s: either the starting_offset " "or bytes_to_read are not 4 byte aligned\n", ioc->name, @@ -2015,23 +2006,13 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) return -EINVAL; } - if (karg.starting_offset > request_size) - return -EINVAL; - diag_data = (void *)(request_data + karg.starting_offset); dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(%p), " "offset(%d), sz(%d)\n", ioc->name, __func__, diag_data, karg.starting_offset, karg.bytes_to_read)); - /* Truncate data on requests that are too large */ - if ((diag_data + karg.bytes_to_read < diag_data) || - (diag_data + karg.bytes_to_read > request_data + request_size)) - copy_size = request_size - karg.starting_offset; - else - copy_size = karg.bytes_to_read; - if (copy_to_user((void __user *)uarg->diagnostic_data, - diag_data, copy_size)) { + diag_data, karg.bytes_to_read)) { printk(MPT2SAS_ERR_FMT "%s: Unable to write " "mpt_diag_read_buffer_t data @ %p\n", ioc->name, __func__, diag_data); diff --git a/trunk/drivers/scsi/pmcraid.c b/trunk/drivers/scsi/pmcraid.c index 7f636b118287..96d5ad0c1e42 100644 --- a/trunk/drivers/scsi/pmcraid.c +++ b/trunk/drivers/scsi/pmcraid.c @@ -3814,9 +3814,6 @@ static long pmcraid_ioctl_passthrough( rc = -EFAULT; goto out_free_buffer; } - } else if (request_size < 0) { - rc = -EINVAL; - goto out_free_buffer; } /* check if we have any additional command parameters */ diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index e63912510fb9..e44ff64233fd 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -322,8 +322,14 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) kfree(evt); } - /* NULL queue means the device can't be used */ - sdev->request_queue = NULL; + if (sdev->request_queue) { + sdev->request_queue->queuedata = NULL; + /* user context needed to free queue */ + scsi_free_queue(sdev->request_queue); + /* temporary expedient, try to catch use of queue lock + * after free of sdev */ + sdev->request_queue = NULL; + } scsi_target_reap(scsi_target(sdev)); @@ -931,12 +937,6 @@ void __scsi_remove_device(struct scsi_device *sdev) if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); transport_destroy_device(dev); - - /* cause the request function to reject all I/O requests */ - sdev->request_queue->queuedata = NULL; - - /* Freeing the queue signals to block that we're done */ - scsi_free_queue(sdev->request_queue); put_device(dev); } diff --git a/trunk/drivers/staging/rt2860/common/cmm_data_pci.c b/trunk/drivers/staging/rt2860/common/cmm_data_pci.c index f01a51c381f1..bef0bbd8cef7 100644 --- a/trunk/drivers/staging/rt2860/common/cmm_data_pci.c +++ b/trunk/drivers/staging/rt2860/common/cmm_data_pci.c @@ -444,7 +444,7 @@ int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, return (NDIS_STATUS_FAILURE); } } - /* Drop not U2M frames, can't drop here because we will drop beacon in this case */ + /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ /* I am kind of doubting the U2M bit operation */ /* if (pRxD->U2M == 0) */ /* return(NDIS_STATUS_FAILURE); */ diff --git a/trunk/drivers/staging/rt2860/common/cmm_data_usb.c b/trunk/drivers/staging/rt2860/common/cmm_data_usb.c index 83a62faa7e57..5637857ae9eb 100644 --- a/trunk/drivers/staging/rt2860/common/cmm_data_usb.c +++ b/trunk/drivers/staging/rt2860/common/cmm_data_usb.c @@ -860,7 +860,7 @@ int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); return NDIS_STATUS_FAILURE; } - /* Drop not U2M frames, can't drop here because we will drop beacon in this case */ + /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ /* I am kind of doubting the U2M bit operation */ /* if (pRxD->U2M == 0) */ /* return(NDIS_STATUS_FAILURE); */ diff --git a/trunk/drivers/staging/spectra/ffsport.c b/trunk/drivers/staging/spectra/ffsport.c index 506547b603e1..20dae73d3b78 100644 --- a/trunk/drivers/staging/spectra/ffsport.c +++ b/trunk/drivers/staging/spectra/ffsport.c @@ -653,7 +653,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which) } dev->queue->queuedata = dev; - /* As Linux block layer doesn't support >4KB hardware sector, */ + /* As Linux block layer does't support >4KB hardware sector, */ /* Here we force report 512 byte hardware sector size to Kernel */ blk_queue_logical_block_size(dev->queue, 512); diff --git a/trunk/drivers/staging/tidspbridge/dynload/cload.c b/trunk/drivers/staging/tidspbridge/dynload/cload.c index fe1ef0addb09..5cecd237e3f6 100644 --- a/trunk/drivers/staging/tidspbridge/dynload/cload.c +++ b/trunk/drivers/staging/tidspbridge/dynload/cload.c @@ -718,7 +718,7 @@ static void dload_symbols(struct dload_state *dlthis) * as a temporary for .dllview record construction. * Allocate storage for the whole table. Add 1 to the section count * in case a trampoline section is auto-generated as well as the - * size of the trampoline section name so DLLView doesn't get lost. + * size of the trampoline section name so DLLView does't get lost. */ siz = sym_count * sizeof(struct local_symbol); diff --git a/trunk/drivers/staging/tty/specialix.c b/trunk/drivers/staging/tty/specialix.c index 5c3598ec7456..cb24c6d999db 100644 --- a/trunk/drivers/staging/tty/specialix.c +++ b/trunk/drivers/staging/tty/specialix.c @@ -978,7 +978,7 @@ static void sx_change_speed(struct specialix_board *bp, spin_lock_irqsave(&bp->lock, flags); sx_out(bp, CD186x_CAR, port_No(port)); - /* The Specialix board doesn't implement the RTS lines. + /* The Specialix board does't implement the RTS lines. They are used to set the IRQ level. Don't touch them. */ if (sx_crtscts(tty)) port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 8f4b81de3ae2..2e61fe1b6b8c 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -718,7 +718,7 @@ struct btrfs_space_info { u64 total_bytes; /* total bytes in the space, this doesn't take mirrors into account */ u64 bytes_used; /* total bytes used, - this doesn't take mirrors into account */ + this does't take mirrors into account */ u64 bytes_pinned; /* total bytes pinned, will be freed when the transaction finishes */ u64 bytes_reserved; /* total bytes the allocator has reserved for diff --git a/trunk/fs/file.c b/trunk/fs/file.c index 4c6992d8f3ba..0be344755c02 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -40,17 +39,14 @@ int sysctl_nr_open_max = 1024 * 1024; /* raised later */ */ static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list); -static void *alloc_fdmem(unsigned int size) +static inline void *alloc_fdmem(unsigned int size) { - /* - * Very large allocations can stress page reclaim, so fall back to - * vmalloc() if the allocation size will be considered "large" by the VM. - */ - if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { - void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); - if (data != NULL) - return data; - } + void *data; + + data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); + if (data != NULL) + return data; + return vmalloc(size); } diff --git a/trunk/fs/logfs/super.c b/trunk/fs/logfs/super.c index ce03a182c771..33435e4b14d2 100644 --- a/trunk/fs/logfs/super.c +++ b/trunk/fs/logfs/super.c @@ -480,6 +480,10 @@ static int logfs_read_sb(struct super_block *sb, int read_only) !read_only) return -EIO; + mutex_init(&super->s_dirop_mutex); + mutex_init(&super->s_object_alias_mutex); + INIT_LIST_HEAD(&super->s_freeing_list); + ret = logfs_init_rw(sb); if (ret) return ret; @@ -597,10 +601,6 @@ static struct dentry *logfs_mount(struct file_system_type *type, int flags, if (!super) return ERR_PTR(-ENOMEM); - mutex_init(&super->s_dirop_mutex); - mutex_init(&super->s_object_alias_mutex); - INIT_LIST_HEAD(&super->s_freeing_list); - if (!devname) err = logfs_get_sb_bdev(super, type, devname); else if (strncmp(devname, "mtd", 3)) diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index 1f063bacd285..89fc160fd5b0 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -119,7 +119,7 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen) } #ifdef CONFIG_NFS_V4 -static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) +static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors, struct inode *inode) { struct gss_api_mech *mech; struct xdr_netobj oid; @@ -166,7 +166,7 @@ static int nfs_negotiate_security(const struct dentry *parent, } flavors = page_address(page); ret = secinfo(parent->d_inode, &dentry->d_name, flavors); - *flavor = nfs_find_best_sec(flavors); + *flavor = nfs_find_best_sec(flavors, dentry->d_inode); put_page(page); } diff --git a/trunk/fs/nfs/nfs4_fs.h b/trunk/fs/nfs/nfs4_fs.h index c4a69833dd0d..e1c261ddd65d 100644 --- a/trunk/fs/nfs/nfs4_fs.h +++ b/trunk/fs/nfs/nfs4_fs.h @@ -47,7 +47,6 @@ enum nfs4_client_state { NFS4CLNT_LAYOUTRECALL, NFS4CLNT_SESSION_RESET, NFS4CLNT_RECALL_SLOT, - NFS4CLNT_LEASE_CONFIRM, }; enum nfs4_session_state { diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 69c0f3c5ee7a..9bf41eab3e46 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -444,8 +443,8 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * if (res->sr_status == 1) res->sr_status = NFS_OK; - /* don't increment the sequence number if the task wasn't sent */ - if (!RPC_WAS_SENT(task)) + /* -ERESTARTSYS can result in skipping nfs41_sequence_setup */ + if (!res->sr_slot) goto out; /* Check the SEQUENCE operation status */ @@ -2186,14 +2185,9 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs4_exception exception = { }; int err; do { - err = _nfs4_lookup_root(server, fhandle, info); - switch (err) { - case 0: - case -NFS4ERR_WRONGSEC: - break; - default: - err = nfs4_handle_exception(server, err, &exception); - } + err = nfs4_handle_exception(server, + _nfs4_lookup_root(server, fhandle, info), + &exception); } while (exception.retry); return err; } @@ -2214,47 +2208,25 @@ static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandl return ret; } -static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, +/* + * get the file handle for the "/" directory on the server + */ +static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *info) { int i, len, status = 0; - rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS]; + rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS + 2]; - len = gss_mech_list_pseudoflavors(&flav_array[0]); - flav_array[len] = RPC_AUTH_NULL; - len += 1; + flav_array[0] = RPC_AUTH_UNIX; + len = gss_mech_list_pseudoflavors(&flav_array[1]); + flav_array[1+len] = RPC_AUTH_NULL; + len += 2; for (i = 0; i < len; i++) { status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); - if (status == -NFS4ERR_WRONGSEC || status == -EACCES) - continue; - break; + if (status != -EPERM) + break; } - /* - * -EACCESS could mean that the user doesn't have correct permissions - * to access the mount. It could also mean that we tried to mount - * with a gss auth flavor, but rpc.gssd isn't running. Either way, - * existing mount programs don't handle -EACCES very well so it should - * be mapped to -EPERM instead. - */ - if (status == -EACCES) - status = -EPERM; - return status; -} - -/* - * get the file handle for the "/" directory on the server - */ -static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, - struct nfs_fsinfo *info) -{ - int status = nfs4_lookup_root(server, fhandle, info); - if ((status == -NFS4ERR_WRONGSEC) && !(server->flags & NFS_MOUNT_SECFLAVOUR)) - /* - * A status of -NFS4ERR_WRONGSEC will be mapped to -EPERM - * by nfs4_map_errors() as this function exits. - */ - status = nfs4_find_root_sec(server, fhandle, info); if (status == 0) status = nfs4_server_capabilities(server, fhandle); if (status == 0) @@ -3751,20 +3723,21 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, sizeof(setclientid.sc_uaddr), "%s.%u.%u", clp->cl_ipaddr, port >> 8, port & 255); - status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); + status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); if (status != -NFS4ERR_CLID_INUSE) break; - if (loop != 0) { - ++clp->cl_id_uniquifier; + if (signalled()) break; - } - ++loop; - ssleep(clp->cl_lease_time / HZ + 1); + if (loop++ & 1) + ssleep(clp->cl_lease_time / HZ + 1); + else + if (++clp->cl_id_uniquifier == 0) + break; } return status; } -int nfs4_proc_setclientid_confirm(struct nfs_client *clp, +static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct nfs4_setclientid_res *arg, struct rpc_cred *cred) { @@ -3779,7 +3752,7 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp, int status; now = jiffies; - status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); + status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); if (status == 0) { spin_lock(&clp->cl_lock); clp->cl_lease_time = fsinfo.lease_time * HZ; @@ -3789,6 +3762,26 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp, return status; } +int nfs4_proc_setclientid_confirm(struct nfs_client *clp, + struct nfs4_setclientid_res *arg, + struct rpc_cred *cred) +{ + long timeout = 0; + int err; + do { + err = _nfs4_proc_setclientid_confirm(clp, arg, cred); + switch (err) { + case 0: + return err; + case -NFS4ERR_RESOURCE: + /* The IBM lawyers misread another document! */ + case -NFS4ERR_DELAY: + err = nfs4_delay(clp->cl_rpcclient, &timeout); + } + } while (err == 0); + return err; +} + struct nfs4_delegreturndata { struct nfs4_delegreturnargs args; struct nfs4_delegreturnres res; @@ -4793,7 +4786,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) init_utsname()->domainname, clp->cl_rpcclient->cl_auth->au_flavor); - status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); + status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); if (!status) status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); dprintk("<-- %s status= %d\n", __func__, status); @@ -4876,8 +4869,7 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo) .rpc_client = clp->cl_rpcclient, .rpc_message = &msg, .callback_ops = &nfs4_get_lease_time_ops, - .callback_data = &data, - .flags = RPC_TASK_TIMEOUT, + .callback_data = &data }; int status; @@ -5179,7 +5171,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp) nfs4_init_channel_attrs(&args); args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN); - status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); + status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0); if (!status) /* Verify the session's negotiated channel_attrs values */ @@ -5202,10 +5194,20 @@ int nfs4_proc_create_session(struct nfs_client *clp) int status; unsigned *ptr; struct nfs4_session *session = clp->cl_session; + long timeout = 0; + int err; dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); - status = _nfs4_proc_create_session(clp); + do { + status = _nfs4_proc_create_session(clp); + if (status == -NFS4ERR_DELAY) { + err = nfs4_delay(clp->cl_rpcclient, &timeout); + if (err) + status = err; + } + } while (status == -NFS4ERR_DELAY); + if (status) goto out; @@ -5246,7 +5248,7 @@ int nfs4_proc_destroy_session(struct nfs4_session *session) msg.rpc_argp = session; msg.rpc_resp = NULL; msg.rpc_cred = NULL; - status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); + status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0); if (status) printk(KERN_WARNING diff --git a/trunk/fs/nfs/nfs4state.c b/trunk/fs/nfs/nfs4state.c index 036f5adc9e1f..a6804f704d9d 100644 --- a/trunk/fs/nfs/nfs4state.c +++ b/trunk/fs/nfs/nfs4state.c @@ -64,15 +64,10 @@ static LIST_HEAD(nfs4_clientid_list); int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) { - struct nfs4_setclientid_res clid = { - .clientid = clp->cl_clientid, - .confirm = clp->cl_confirm, - }; + struct nfs4_setclientid_res clid; unsigned short port; int status; - if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state)) - goto do_confirm; port = nfs_callback_tcpport; if (clp->cl_addr.ss_family == AF_INET6) port = nfs_callback_tcpport6; @@ -80,14 +75,10 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid); if (status != 0) goto out; - clp->cl_clientid = clid.clientid; - clp->cl_confirm = clid.confirm; - set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); -do_confirm: status = nfs4_proc_setclientid_confirm(clp, &clid, cred); if (status != 0) goto out; - clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); + clp->cl_clientid = clid.clientid; nfs4_schedule_state_renewal(clp); out: return status; @@ -239,18 +230,13 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) { int status; - if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state)) - goto do_confirm; nfs4_begin_drain_session(clp); status = nfs4_proc_exchange_id(clp, cred); if (status != 0) goto out; - set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); -do_confirm: status = nfs4_proc_create_session(clp); if (status != 0) goto out; - clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); nfs41_setup_state_renewal(clp); nfs_mark_client_ready(clp, NFS_CS_READY); out: @@ -1598,23 +1584,20 @@ static int nfs4_recall_slot(struct nfs_client *clp) { return 0; } */ static void nfs4_set_lease_expired(struct nfs_client *clp, int status) { - switch (status) { - case -NFS4ERR_CLID_INUSE: - case -NFS4ERR_STALE_CLIENTID: - clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); - break; - case -NFS4ERR_DELAY: - case -ETIMEDOUT: - case -EAGAIN: - ssleep(1); - break; + if (nfs4_has_session(clp)) { + switch (status) { + case -NFS4ERR_DELAY: + case -NFS4ERR_CLID_INUSE: + case -EAGAIN: + break; - case -EKEYEXPIRED: - nfs4_warn_keyexpired(clp->cl_hostname); - case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery - * in nfs4_exchange_id */ - default: - return; + case -EKEYEXPIRED: + nfs4_warn_keyexpired(clp->cl_hostname); + case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery + * in nfs4_exchange_id */ + default: + return; + } } set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); } @@ -1624,7 +1607,7 @@ static void nfs4_state_manager(struct nfs_client *clp) int status = 0; /* Ensure exclusive access to NFSv4 state */ - do { + for(;;) { if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { /* We're going to have to re-establish a clientid */ status = nfs4_reclaim_lease(clp); @@ -1708,7 +1691,7 @@ static void nfs4_state_manager(struct nfs_client *clp) break; if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) break; - } while (atomic_read(&clp->cl_count) > 1); + } return; out_error: printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" diff --git a/trunk/fs/nfs/nfs4xdr.c b/trunk/fs/nfs/nfs4xdr.c index c3ccd2c46834..dddfb5795d7b 100644 --- a/trunk/fs/nfs/nfs4xdr.c +++ b/trunk/fs/nfs/nfs4xdr.c @@ -1452,25 +1452,26 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) { - uint32_t attrs[2] = { - FATTR4_WORD0_RDATTR_ERROR, - FATTR4_WORD1_MOUNTED_ON_FILEID, - }; + uint32_t attrs[2] = {0, 0}; uint32_t dircount = readdir->count >> 1; __be32 *p; if (readdir->plus) { attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE| - FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID; + FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE; attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER| FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV| FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS| FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; dircount >>= 1; } - /* Use mounted_on_fileid only if the server supports it */ - if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) - attrs[0] |= FATTR4_WORD0_FILEID; + attrs[0] |= FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID; + attrs[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID; + /* Switch to mounted_on_fileid if the server supports it */ + if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) + attrs[0] &= ~FATTR4_WORD0_FILEID; + else + attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20); *p++ = cpu_to_be32(OP_READDIR); @@ -3139,7 +3140,7 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma goto out_overflow; xdr_decode_hyper(p, fileid); bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; - ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID; + ret = NFS_ATTR_FATTR_FILEID; } dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); return ret; @@ -4001,6 +4002,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, { int status; umode_t fmode = 0; + uint64_t fileid; uint32_t type; status = decode_attr_type(xdr, bitmap, &type); @@ -4099,10 +4101,13 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; - status = decode_attr_mounted_on_fileid(xdr, bitmap, &fattr->mounted_on_fileid); + status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid); if (status < 0) goto xdr_error; - fattr->valid |= status; + if (status != 0 && !(fattr->valid & status)) { + fattr->fileid = fileid; + fattr->valid |= status; + } xdr_error: dprintk("%s: xdr returned %d\n", __func__, -status); @@ -4833,21 +4838,17 @@ static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) struct nfs4_secinfo_flavor *sec_flavor; int status; __be32 *p; - int i, num_flavors; + int i; status = decode_op_hdr(xdr, OP_SECINFO); - if (status) - goto out; p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) goto out_overflow; + res->flavors->num_flavors = be32_to_cpup(p); - res->flavors->num_flavors = 0; - num_flavors = be32_to_cpup(p); - - for (i = 0; i < num_flavors; i++) { + for (i = 0; i < res->flavors->num_flavors; i++) { sec_flavor = &res->flavors->flavors[i]; - if ((char *)&sec_flavor[1] - (char *)res->flavors > PAGE_SIZE) + if ((char *)&sec_flavor[1] - (char *)res > PAGE_SIZE) break; p = xdr_inline_decode(xdr, 4); @@ -4856,15 +4857,13 @@ static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) sec_flavor->flavor = be32_to_cpup(p); if (sec_flavor->flavor == RPC_AUTH_GSS) { - status = decode_secinfo_gss(xdr, sec_flavor); - if (status) - goto out; + if (decode_secinfo_gss(xdr, sec_flavor)) + break; } - res->flavors->num_flavors++; } -out: - return status; + return 0; + out_overflow: print_overflow_msg(__func__, xdr); return -EIO; @@ -6409,9 +6408,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, entry->server, 1) < 0) goto out_overflow; - if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) - entry->ino = entry->fattr->mounted_on_fileid; - else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) + if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) entry->ino = entry->fattr->fileid; entry->d_type = DT_UNKNOWN; diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index ff681ab65d31..d9ab97269ce6 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -1004,7 +1004,6 @@ pnfs_set_layoutcommit(struct nfs_write_data *wdata) { struct nfs_inode *nfsi = NFS_I(wdata->inode); loff_t end_pos = wdata->args.offset + wdata->res.count; - bool mark_as_dirty = false; spin_lock(&nfsi->vfs_inode.i_lock); if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { @@ -1012,18 +1011,13 @@ pnfs_set_layoutcommit(struct nfs_write_data *wdata) get_lseg(wdata->lseg); wdata->lseg->pls_lc_cred = get_rpccred(wdata->args.context->state->owner->so_cred); - mark_as_dirty = true; + mark_inode_dirty_sync(wdata->inode); dprintk("%s: Set layoutcommit for inode %lu ", __func__, wdata->inode->i_ino); } if (end_pos > wdata->lseg->pls_end_pos) wdata->lseg->pls_end_pos = end_pos; spin_unlock(&nfsi->vfs_inode.i_lock); - - /* if pnfs_layoutcommit_inode() runs between inode locks, the next one - * will be a noop because NFS_INO_LAYOUTCOMMIT will not be set */ - if (mark_as_dirty) - mark_inode_dirty_sync(wdata->inode); } EXPORT_SYMBOL_GPL(pnfs_set_layoutcommit); diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index e288f06d3fa7..2b8e9a5e366a 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -1004,7 +1004,6 @@ static int nfs_parse_security_flavors(char *value, return 0; } - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; return 1; } @@ -1977,15 +1976,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) if (error < 0) goto out; - /* - * noac is a special case. It implies -o sync, but that's not - * necessarily reflected in the mtab options. do_remount_sb - * will clear MS_SYNCHRONOUS if -o sync wasn't specified in the - * remount options, so we have to explicitly reset it. - */ - if (data->flags & NFS_MOUNT_NOAC) - *flags |= MS_SYNCHRONOUS; - /* compare new mount options with old ones */ error = nfs_compare_remount_data(nfss, data); out: @@ -2245,7 +2235,8 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type, if (!s->s_root) { /* initial superblock/root creation */ nfs_fill_super(s, data); - nfs_fscache_get_super_cookie(s, data->fscache_uniq, NULL); + nfs_fscache_get_super_cookie( + s, data ? data->fscache_uniq : NULL, NULL); } mntroot = nfs_get_root(s, mntfh, dev_name); diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index 3bd5d7e80f6c..e4cbc11a74ab 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -680,6 +680,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, req = nfs_setup_write_request(ctx, page, offset, count); if (IS_ERR(req)) return PTR_ERR(req); + nfs_mark_request_dirty(req); /* Update file length */ nfs_grow_file(page, offset, count); nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); @@ -1417,7 +1418,8 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) task->tk_pid, task->tk_status); /* Call the NFS version-specific code */ - NFS_PROTO(data->inode)->commit_done(task, data); + if (NFS_PROTO(data->inode)->commit_done(task, data) != 0) + return; } void nfs_commit_release_pages(struct nfs_write_data *data) diff --git a/trunk/fs/ocfs2/ocfs2_fs.h b/trunk/fs/ocfs2/ocfs2_fs.h index 938387a10d5d..b68f87a83924 100644 --- a/trunk/fs/ocfs2/ocfs2_fs.h +++ b/trunk/fs/ocfs2/ocfs2_fs.h @@ -1019,7 +1019,7 @@ struct ocfs2_xattr_entry { __le16 xe_name_offset; /* byte offset from the 1st entry in the local xattr storage(inode, xattr block or xattr bucket). */ - __u8 xe_name_len; /* xattr name len, doesn't include prefix. */ + __u8 xe_name_len; /* xattr name len, does't include prefix. */ __u8 xe_type; /* the low 7 bits indicate the name prefix * type and the highest bit indicates whether * the EA is stored in the local storage. */ diff --git a/trunk/fs/ubifs/log.c b/trunk/fs/ubifs/log.c index 40fa780ebea7..4d0cb1241460 100644 --- a/trunk/fs/ubifs/log.c +++ b/trunk/fs/ubifs/log.c @@ -174,6 +174,26 @@ void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud) spin_unlock(&c->buds_lock); } +/** + * ubifs_create_buds_lists - create journal head buds lists for remount rw. + * @c: UBIFS file-system description object + */ +void ubifs_create_buds_lists(struct ubifs_info *c) +{ + struct rb_node *p; + + spin_lock(&c->buds_lock); + p = rb_first(&c->buds); + while (p) { + struct ubifs_bud *bud = rb_entry(p, struct ubifs_bud, rb); + struct ubifs_jhead *jhead = &c->jheads[bud->jhead]; + + list_add_tail(&bud->list, &jhead->buds_list); + p = rb_next(p); + } + spin_unlock(&c->buds_lock); +} + /** * ubifs_add_bud_to_log - add a new bud to the log. * @c: UBIFS file-system description object diff --git a/trunk/fs/ubifs/replay.c b/trunk/fs/ubifs/replay.c index d3d6d365bfc1..eed0fcff8d73 100644 --- a/trunk/fs/ubifs/replay.c +++ b/trunk/fs/ubifs/replay.c @@ -59,7 +59,6 @@ enum { * @new_size: truncation new size * @free: amount of free space in a bud * @dirty: amount of dirty space in a bud from padding and deletion nodes - * @jhead: journal head number of the bud * * UBIFS journal replay must compare node sequence numbers, which means it must * build a tree of node information to insert into the TNC. @@ -81,7 +80,6 @@ struct replay_entry { struct { int free; int dirty; - int jhead; }; }; }; @@ -161,11 +159,6 @@ static int set_bud_lprops(struct ubifs_info *c, struct replay_entry *r) err = PTR_ERR(lp); goto out; } - - /* Make sure the journal head points to the latest bud */ - err = ubifs_wbuf_seek_nolock(&c->jheads[r->jhead].wbuf, r->lnum, - c->leb_size - r->free, UBI_SHORTTERM); - out: ubifs_release_lprops(c); return err; @@ -634,6 +627,10 @@ static int replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, ubifs_assert(sleb->endpt - offs >= used); ubifs_assert(sleb->endpt % c->min_io_size == 0); + if (sleb->endpt + c->min_io_size <= c->leb_size && !c->ro_mount) + err = ubifs_wbuf_seek_nolock(&c->jheads[jhead].wbuf, lnum, + sleb->endpt, UBI_SHORTTERM); + *dirty = sleb->endpt - offs - used; *free = c->leb_size - sleb->endpt; @@ -656,14 +653,12 @@ static int replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, * @sqnum: sequence number * @free: amount of free space in bud * @dirty: amount of dirty space from padding and deletion nodes - * @jhead: journal head number for the bud * * This function inserts a reference node to the replay tree and returns zero * in case of success or a negative error code in case of failure. */ static int insert_ref_node(struct ubifs_info *c, int lnum, int offs, - unsigned long long sqnum, int free, int dirty, - int jhead) + unsigned long long sqnum, int free, int dirty) { struct rb_node **p = &c->replay_tree.rb_node, *parent = NULL; struct replay_entry *r; @@ -693,7 +688,6 @@ static int insert_ref_node(struct ubifs_info *c, int lnum, int offs, r->flags = REPLAY_REF; r->free = free; r->dirty = dirty; - r->jhead = jhead; rb_link_node(&r->rb, parent, p); rb_insert_color(&r->rb, &c->replay_tree); @@ -718,7 +712,7 @@ static int replay_buds(struct ubifs_info *c) if (err) return err; err = insert_ref_node(c, b->bud->lnum, b->bud->start, b->sqnum, - free, dirty, b->bud->jhead); + free, dirty); if (err) return err; } diff --git a/trunk/fs/ubifs/super.c b/trunk/fs/ubifs/super.c index 04ad07f4fcc3..be6c7b008f38 100644 --- a/trunk/fs/ubifs/super.c +++ b/trunk/fs/ubifs/super.c @@ -1257,12 +1257,12 @@ static int mount_ubifs(struct ubifs_info *c) goto out_free; } - err = alloc_wbufs(c); - if (err) - goto out_cbuf; - sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id); if (!c->ro_mount) { + err = alloc_wbufs(c); + if (err) + goto out_cbuf; + /* Create background thread */ c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name); if (IS_ERR(c->bgt)) { @@ -1631,6 +1631,12 @@ static int ubifs_remount_rw(struct ubifs_info *c) if (err) goto out; + err = alloc_wbufs(c); + if (err) + goto out; + + ubifs_create_buds_lists(c); + /* Create background thread */ c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name); if (IS_ERR(c->bgt)) { @@ -1738,6 +1744,7 @@ static void ubifs_remount_ro(struct ubifs_info *c) if (err) ubifs_ro_mode(c, err); + free_wbufs(c); vfree(c->orph_buf); c->orph_buf = NULL; kfree(c->write_reserve_buf); diff --git a/trunk/include/drm/drm_pciids.h b/trunk/include/drm/drm_pciids.h index f04b2a3b0f49..816e30cbd968 100644 --- a/trunk/include/drm/drm_pciids.h +++ b/trunk/include/drm/drm_pciids.h @@ -155,7 +155,6 @@ {0x1002, 0x6719, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x671c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x671d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x671f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6721, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6722, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \ @@ -168,7 +167,6 @@ {0x1002, 0x6729, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6739, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x673e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6740, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6741, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6742, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ @@ -201,7 +199,6 @@ {0x1002, 0x688D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6898, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6899, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x689b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x689c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HEMLOCK|RADEON_NEW_MEMMAP}, \ {0x1002, 0x689d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HEMLOCK|RADEON_NEW_MEMMAP}, \ {0x1002, 0x689e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ @@ -212,9 +209,7 @@ {0x1002, 0x68b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x68ba, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68be, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x68bf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68c7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ diff --git a/trunk/include/drm/radeon_drm.h b/trunk/include/drm/radeon_drm.h index 787f7b6fd622..7aa5dddb2098 100644 --- a/trunk/include/drm/radeon_drm.h +++ b/trunk/include/drm/radeon_drm.h @@ -910,7 +910,6 @@ struct drm_radeon_cs { #define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x09 /* clock crystal frequency */ #define RADEON_INFO_NUM_BACKENDS 0x0a /* DB/backends for r600+ - need for OQ */ #define RADEON_INFO_NUM_TILE_PIPES 0x0b /* tile pipes for r600+ */ -#define RADEON_INFO_FUSION_GART_WORKING 0x0c /* fusion writes to GTT were broken before this */ struct drm_radeon_info { uint32_t request; diff --git a/trunk/include/linux/huge_mm.h b/trunk/include/linux/huge_mm.h index 8847c8c29791..df29c8fde36b 100644 --- a/trunk/include/linux/huge_mm.h +++ b/trunk/include/linux/huge_mm.h @@ -117,7 +117,7 @@ static inline void vma_adjust_trans_huge(struct vm_area_struct *vma, unsigned long end, long adjust_next) { - if (!vma->anon_vma || vma->vm_ops) + if (!vma->anon_vma || vma->vm_ops || vma->vm_file) return; __vma_adjust_trans_huge(vma, start, end, adjust_next); } diff --git a/trunk/include/linux/mfd/wm831x/pdata.h b/trunk/include/linux/mfd/wm831x/pdata.h index 632d1567a1b6..afe4db49402d 100644 --- a/trunk/include/linux/mfd/wm831x/pdata.h +++ b/trunk/include/linux/mfd/wm831x/pdata.h @@ -81,9 +81,7 @@ struct wm831x_touch_pdata { int rpu; /** Pen down sensitivity resistor divider */ int pressure; /** Report pressure (boolean) */ unsigned int data_irq; /** Touch data ready IRQ */ - int data_irqf; /** IRQ flags for data ready IRQ */ unsigned int pd_irq; /** Touch pendown detect IRQ */ - int pd_irqf; /** IRQ flags for pen down IRQ */ }; enum wm831x_watchdog_action { diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 2348db26bc3d..692dbae6ffa7 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -137,8 +137,7 @@ extern unsigned int kobjsize(const void *objp); #define VM_RandomReadHint(v) ((v)->vm_flags & VM_RAND_READ) /* - * Special vmas that are non-mergable, non-mlock()able. - * Note: mm/huge_memory.c VM_NO_THP depends on this definition. + * special vmas that are non-mergable, non-mlock()able */ #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP) diff --git a/trunk/include/linux/mmc/host.h b/trunk/include/linux/mmc/host.h index eb792cb6d745..bcb793ec7374 100644 --- a/trunk/include/linux/mmc/host.h +++ b/trunk/include/linux/mmc/host.h @@ -183,6 +183,7 @@ struct mmc_host { struct work_struct clk_gate_work; /* delayed clock gate */ unsigned int clk_old; /* old clock value cache */ spinlock_t clk_lock; /* lock for clk fields */ + struct mutex clk_gate_mutex; /* mutex for clock gating */ #endif /* host specific block data */ diff --git a/trunk/include/linux/nfs_fs_sb.h b/trunk/include/linux/nfs_fs_sb.h index 87694ca86914..216cea5db0aa 100644 --- a/trunk/include/linux/nfs_fs_sb.h +++ b/trunk/include/linux/nfs_fs_sb.h @@ -47,7 +47,6 @@ struct nfs_client { #ifdef CONFIG_NFS_V4 u64 cl_clientid; /* constant */ - nfs4_verifier cl_confirm; /* Clientid verifier */ unsigned long cl_state; spinlock_t cl_lock; diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index 890dce242639..78b101e487ea 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -50,7 +50,6 @@ struct nfs_fattr { } du; struct nfs_fsid fsid; __u64 fileid; - __u64 mounted_on_fileid; struct timespec atime; struct timespec mtime; struct timespec ctime; @@ -84,7 +83,6 @@ struct nfs_fattr { #define NFS_ATTR_FATTR_PRECHANGE (1U << 18) #define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */ #define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */ -#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21) #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ | NFS_ATTR_FATTR_MODE \ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 8abe8d78c4bf..4e2c9150a785 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2477,12 +2477,15 @@ #define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21 #define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 #define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310 #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX 0x231f +#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 @@ -2693,6 +2696,7 @@ #define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN 0x3b00 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX 0x3b1f +#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 diff --git a/trunk/include/linux/sunrpc/sched.h b/trunk/include/linux/sunrpc/sched.h index f73c482ec9c6..d81db8012c63 100644 --- a/trunk/include/linux/sunrpc/sched.h +++ b/trunk/include/linux/sunrpc/sched.h @@ -127,16 +127,13 @@ struct rpc_task_setup { #define RPC_TASK_KILLED 0x0100 /* task was killed */ #define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */ #define RPC_TASK_SOFTCONN 0x0400 /* Fail if can't connect */ -#define RPC_TASK_SENT 0x0800 /* message was sent */ -#define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */ #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) -#define RPC_IS_SOFT(t) ((t)->tk_flags & (RPC_TASK_SOFT|RPC_TASK_TIMEOUT)) +#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) #define RPC_IS_SOFTCONN(t) ((t)->tk_flags & RPC_TASK_SOFTCONN) -#define RPC_WAS_SENT(t) ((t)->tk_flags & RPC_TASK_SENT) #define RPC_TASK_RUNNING 0 #define RPC_TASK_QUEUED 1 diff --git a/trunk/include/linux/usb/usbnet.h b/trunk/include/linux/usb/usbnet.h index 605b0aa8d852..0e1855079fbb 100644 --- a/trunk/include/linux/usb/usbnet.h +++ b/trunk/include/linux/usb/usbnet.h @@ -68,7 +68,6 @@ struct usbnet { # define EVENT_RX_PAUSED 5 # define EVENT_DEV_WAKING 6 # define EVENT_DEV_ASLEEP 7 -# define EVENT_DEV_OPEN 8 }; static inline struct usb_driver *driver_of(struct usb_interface *intf) diff --git a/trunk/include/linux/v4l2-mediabus.h b/trunk/include/linux/v4l2-mediabus.h index de5c15921025..7054a7a8065e 100644 --- a/trunk/include/linux/v4l2-mediabus.h +++ b/trunk/include/linux/v4l2-mediabus.h @@ -47,7 +47,7 @@ enum v4l2_mbus_pixelcode { V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007, V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008, - /* YUV (including grey) - next is 0x2014 */ + /* YUV (including grey) - next is 0x2013 */ V4L2_MBUS_FMT_Y8_1X8 = 0x2001, V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002, V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003, @@ -60,7 +60,6 @@ enum v4l2_mbus_pixelcode { V4L2_MBUS_FMT_Y10_1X10 = 0x200a, V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b, V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c, - V4L2_MBUS_FMT_Y12_1X12 = 0x2013, V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f, V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010, V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, @@ -68,11 +67,9 @@ enum v4l2_mbus_pixelcode { V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, - /* Bayer - next is 0x3015 */ + /* Bayer - next is 0x3013 */ V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, - V4L2_MBUS_FMT_SGBRG8_1X8 = 0x3013, V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002, - V4L2_MBUS_FMT_SRGGB8_1X8 = 0x3014, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009, diff --git a/trunk/include/linux/videodev2.h b/trunk/include/linux/videodev2.h index be82c8ead1af..aa6c393b7ae9 100644 --- a/trunk/include/linux/videodev2.h +++ b/trunk/include/linux/videodev2.h @@ -308,7 +308,6 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ -#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ /* Palette formats */ diff --git a/trunk/include/media/v4l2-device.h b/trunk/include/media/v4l2-device.h index d61febfb1668..bd102cf509ac 100644 --- a/trunk/include/media/v4l2-device.h +++ b/trunk/include/media/v4l2-device.h @@ -163,7 +163,7 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev); ({ \ struct v4l2_subdev *__sd; \ __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o, \ - f , ##args); \ + f, args...); \ }) /* Call the specified callback for all subdevs matching grp_id (if 0, then diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index d886b1e9278e..7a71e0a9992a 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -1226,7 +1226,6 @@ config SLAB per cpu and per node queues. config SLUB - depends on BROKEN || NUMA || !DISCONTIGMEM bool "SLUB (Unqueued Allocator)" help SLUB is a slab allocator that minimizes cache line usage diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index 87fdb3f8db14..9017478c5d4c 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -81,11 +81,7 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = } }; -static int hrtimer_clock_to_base_table[MAX_CLOCKS] = { - [CLOCK_REALTIME] = HRTIMER_BASE_REALTIME, - [CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC, - [CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME, -}; +static int hrtimer_clock_to_base_table[MAX_CLOCKS]; static inline int hrtimer_clockid_to_base(clockid_t clock_id) { @@ -1726,6 +1722,10 @@ static struct notifier_block __cpuinitdata hrtimers_nb = { void __init hrtimers_init(void) { + hrtimer_clock_to_base_table[CLOCK_REALTIME] = HRTIMER_BASE_REALTIME; + hrtimer_clock_to_base_table[CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC; + hrtimer_clock_to_base_table[CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME; + hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, (void *)(long)smp_processor_id()); register_cpu_notifier(&hrtimers_nb); diff --git a/trunk/kernel/irq/proc.c b/trunk/kernel/irq/proc.c index 834899f2500f..dd201bd35103 100644 --- a/trunk/kernel/irq/proc.c +++ b/trunk/kernel/irq/proc.c @@ -419,7 +419,7 @@ int show_interrupts(struct seq_file *p, void *v) } else { seq_printf(p, " %8s", "None"); } -#ifdef CONFIG_GENERIC_IRQ_SHOW_LEVEL +#ifdef CONFIG_GENIRC_IRQ_SHOW_LEVEL seq_printf(p, " %-8s", irqd_is_level_type(&desc->irq_data) ? "Level" : "Edge"); #endif if (desc->name) diff --git a/trunk/kernel/trace/Kconfig b/trunk/kernel/trace/Kconfig index 2ad39e556cb4..61d7d59f4a1a 100644 --- a/trunk/kernel/trace/Kconfig +++ b/trunk/kernel/trace/Kconfig @@ -141,7 +141,7 @@ if FTRACE config FUNCTION_TRACER bool "Kernel Function Tracer" depends on HAVE_FUNCTION_TRACER - select FRAME_POINTER if !ARM_UNWIND && !S390 && !MICROBLAZE + select FRAME_POINTER if !ARM_UNWIND && !S390 select KALLSYMS select GENERIC_TRACER select CONTEXT_SWITCH_TRACER diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index 14733d4d156b..140dce750450 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -430,12 +430,9 @@ static int watchdog_enable(int cpu) p = kthread_create(watchdog, (void *)(unsigned long)cpu, "watchdog/%d", cpu); if (IS_ERR(p)) { printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu); - if (!err) { + if (!err) /* if hardlockup hasn't already set this */ err = PTR_ERR(p); - /* and disable the perf event */ - watchdog_nmi_disable(cpu); - } goto out; } kthread_bind(p, cpu); diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index e3378e8d3a5c..8859a41806dd 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -1291,14 +1291,8 @@ __acquires(&gcwq->lock) return true; spin_unlock_irq(&gcwq->lock); - /* - * We've raced with CPU hot[un]plug. Give it a breather - * and retry migration. cond_resched() is required here; - * otherwise, we might deadlock against cpu_stop trying to - * bring down the CPU on non-preemptive kernel. - */ + /* CPU has come up in between, retry migration */ cpu_relax(); - cond_resched(); } } diff --git a/trunk/lib/xz/xz_dec_lzma2.c b/trunk/lib/xz/xz_dec_lzma2.c index a6cdc969ea42..ea5fa4fe9d67 100644 --- a/trunk/lib/xz/xz_dec_lzma2.c +++ b/trunk/lib/xz/xz_dec_lzma2.c @@ -969,9 +969,6 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, */ tmp = b->in[b->in_pos++]; - if (tmp == 0x00) - return XZ_STREAM_END; - if (tmp >= 0xE0 || tmp == 0x01) { s->lzma2.need_props = true; s->lzma2.need_dict_reset = false; @@ -1004,6 +1001,9 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, lzma_reset(s); } } else { + if (tmp == 0x00) + return XZ_STREAM_END; + if (tmp > 0x02) return XZ_DATA_ERROR; diff --git a/trunk/mm/huge_memory.c b/trunk/mm/huge_memory.c index 83326ad66d9b..470dcda10add 100644 --- a/trunk/mm/huge_memory.c +++ b/trunk/mm/huge_memory.c @@ -1408,9 +1408,6 @@ int split_huge_page(struct page *page) return ret; } -#define VM_NO_THP (VM_SPECIAL|VM_INSERTPAGE|VM_MIXEDMAP|VM_SAO| \ - VM_HUGETLB|VM_SHARED|VM_MAYSHARE) - int hugepage_madvise(struct vm_area_struct *vma, unsigned long *vm_flags, int advice) { @@ -1419,7 +1416,11 @@ int hugepage_madvise(struct vm_area_struct *vma, /* * Be somewhat over-protective like KSM for now! */ - if (*vm_flags & (VM_HUGEPAGE | VM_NO_THP)) + if (*vm_flags & (VM_HUGEPAGE | + VM_SHARED | VM_MAYSHARE | + VM_PFNMAP | VM_IO | VM_DONTEXPAND | + VM_RESERVED | VM_HUGETLB | VM_INSERTPAGE | + VM_MIXEDMAP | VM_SAO)) return -EINVAL; *vm_flags &= ~VM_NOHUGEPAGE; *vm_flags |= VM_HUGEPAGE; @@ -1435,7 +1436,11 @@ int hugepage_madvise(struct vm_area_struct *vma, /* * Be somewhat over-protective like KSM for now! */ - if (*vm_flags & (VM_NOHUGEPAGE | VM_NO_THP)) + if (*vm_flags & (VM_NOHUGEPAGE | + VM_SHARED | VM_MAYSHARE | + VM_PFNMAP | VM_IO | VM_DONTEXPAND | + VM_RESERVED | VM_HUGETLB | VM_INSERTPAGE | + VM_MIXEDMAP | VM_SAO)) return -EINVAL; *vm_flags &= ~VM_HUGEPAGE; *vm_flags |= VM_NOHUGEPAGE; @@ -1569,14 +1574,10 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma) * page fault if needed. */ return 0; - if (vma->vm_ops) + if (vma->vm_file || vma->vm_ops) /* khugepaged not yet working on file or special mappings */ return 0; - /* - * If is_pfn_mapping() is true is_learn_pfn_mapping() must be - * true too, verify it here. - */ - VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP); + VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; hend = vma->vm_end & HPAGE_PMD_MASK; if (hstart < hend) @@ -1827,15 +1828,12 @@ static void collapse_huge_page(struct mm_struct *mm, (vma->vm_flags & VM_NOHUGEPAGE)) goto out; - if (!vma->anon_vma || vma->vm_ops) + /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ + if (!vma->anon_vma || vma->vm_ops || vma->vm_file) goto out; if (is_vma_temporary_stack(vma)) goto out; - /* - * If is_pfn_mapping() is true is_learn_pfn_mapping() must be - * true too, verify it here. - */ - VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP); + VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); pgd = pgd_offset(mm, address); if (!pgd_present(*pgd)) @@ -2068,16 +2066,13 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, progress++; continue; } - if (!vma->anon_vma || vma->vm_ops) + /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ + if (!vma->anon_vma || vma->vm_ops || vma->vm_file) goto skip; if (is_vma_temporary_stack(vma)) goto skip; - /* - * If is_pfn_mapping() is true is_learn_pfn_mapping() - * must be true too, verify it here. - */ - VM_BUG_ON(is_linear_pfn_mapping(vma) || - vma->vm_flags & VM_NO_THP); + + VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; hend = vma->vm_end & HPAGE_PMD_MASK; diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 607098d47e74..ce22a250926f 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -3396,7 +3396,7 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, * run pte_offset_map on the pmd, if an huge pmd could * materialize from under us from a different thread. */ - if (unlikely(pmd_none(*pmd)) && __pte_alloc(mm, vma, pmd, address)) + if (unlikely(__pte_alloc(mm, vma, pmd, address))) return VM_FAULT_OOM; /* if an huge pmd materialized from under us just retry later */ if (unlikely(pmd_trans_huge(*pmd))) diff --git a/trunk/mm/oom_kill.c b/trunk/mm/oom_kill.c index f52e85c80e8d..83fb72c108b7 100644 --- a/trunk/mm/oom_kill.c +++ b/trunk/mm/oom_kill.c @@ -172,13 +172,10 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, /* * The baseline for the badness score is the proportion of RAM that each - * task's rss, pagetable and swap space use. + * task's rss and swap space use. */ - points = get_mm_rss(p->mm) + p->mm->nr_ptes; - points += get_mm_counter(p->mm, MM_SWAPENTS); - - points *= 1000; - points /= totalpages; + points = (get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS)) * 1000 / + totalpages; task_unlock(p); /* diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index b5a8afc2be33..c83f618282f7 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -587,8 +587,10 @@ static int hci_dev_do_close(struct hci_dev *hdev) hci_req_cancel(hdev, ENODEV); hci_req_lock(hdev); + /* Stop timer, it might be running */ + del_timer_sync(&hdev->cmd_timer); + if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { - del_timer_sync(&hdev->cmd_timer); hci_req_unlock(hdev); return 0; } @@ -627,7 +629,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) /* Drop last sent command */ if (hdev->sent_cmd) { - del_timer_sync(&hdev->cmd_timer); kfree_skb(hdev->sent_cmd); hdev->sent_cmd = NULL; } diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index b2570159a044..cebe7588469f 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -2387,6 +2387,8 @@ static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *s if (!conn) goto unlock; + hci_conn_hold(conn); + conn->remote_cap = ev->capability; conn->remote_oob = ev->oob_data; conn->remote_auth = ev->authentication; diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index 2c8dd4494c63..ca27f3a41536 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/net/bluetooth/l2cap_core.c @@ -1051,7 +1051,6 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) tx_skb = skb_clone(skb, GFP_ATOMIC); bt_cb(skb)->retries++; control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); - control &= L2CAP_CTRL_SAR; if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { control |= L2CAP_CTRL_FINAL; diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index 94954c74f6ae..42fdffd1d76c 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -369,15 +369,6 @@ static void __sco_sock_close(struct sock *sk) case BT_CONNECTED: case BT_CONFIG: - if (sco_pi(sk)->conn) { - sk->sk_state = BT_DISCONN; - sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); - hci_conn_put(sco_pi(sk)->conn->hcon); - sco_pi(sk)->conn = NULL; - } else - sco_chan_del(sk, ECONNRESET); - break; - case BT_CONNECT: case BT_DISCONN: sco_chan_del(sk, ECONNRESET); diff --git a/trunk/net/bridge/br_input.c b/trunk/net/bridge/br_input.c index 0c7badad62af..e2160792e1bc 100644 --- a/trunk/net/bridge/br_input.c +++ b/trunk/net/bridge/br_input.c @@ -164,7 +164,7 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) goto drop; /* If STP is turned off, then forward */ - if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0) + if (p->br->stp_enabled == BR_NO_STP) goto forward; if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, diff --git a/trunk/net/can/bcm.c b/trunk/net/can/bcm.c index 8a6a05e7c3c8..57b1aed79014 100644 --- a/trunk/net/can/bcm.c +++ b/trunk/net/can/bcm.c @@ -1427,14 +1427,9 @@ static int bcm_init(struct sock *sk) static int bcm_release(struct socket *sock) { struct sock *sk = sock->sk; - struct bcm_sock *bo; + struct bcm_sock *bo = bcm_sk(sk); struct bcm_op *op, *next; - if (sk == NULL) - return 0; - - bo = bcm_sk(sk); - /* remove bcm_ops, timer, rx_unregister(), etc. */ unregister_netdevice_notifier(&bo->notifier); diff --git a/trunk/net/can/raw.c b/trunk/net/can/raw.c index 0eb39a7fdf64..649acfa7c70a 100644 --- a/trunk/net/can/raw.c +++ b/trunk/net/can/raw.c @@ -305,12 +305,7 @@ static int raw_init(struct sock *sk) static int raw_release(struct socket *sock) { struct sock *sk = sock->sk; - struct raw_sock *ro; - - if (!sk) - return 0; - - ro = raw_sk(sk); + struct raw_sock *ro = raw_sk(sk); unregister_netdevice_notifier(&ro->notifier); diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 856b6ee9a1d5..c2ac599fa0f6 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -4773,7 +4773,7 @@ static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cm * is never reached */ WARN_ON(1); - err = -ENOTTY; + err = -EINVAL; break; } @@ -5041,7 +5041,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg) /* Set the per device memory buffer space. * Not applicable in our case */ case SIOCSIFLINK: - return -ENOTTY; + return -EINVAL; /* * Unknown or private ioctl. @@ -5062,7 +5062,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg) /* Take care of Wireless Extensions */ if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) return wext_handle_ioctl(net, &ifr, cmd, arg); - return -ENOTTY; + return -EINVAL; } } diff --git a/trunk/net/dsa/Kconfig b/trunk/net/dsa/Kconfig index c53ded2a98df..87bb5f4de0e8 100644 --- a/trunk/net/dsa/Kconfig +++ b/trunk/net/dsa/Kconfig @@ -41,12 +41,12 @@ config NET_DSA_MV88E6XXX_NEED_PPU default n config NET_DSA_MV88E6131 - bool "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support" + bool "Marvell 88E6095/6095F/6131 ethernet switch chip support" select NET_DSA_MV88E6XXX select NET_DSA_MV88E6XXX_NEED_PPU select NET_DSA_TAG_DSA ---help--- - This enables support for the Marvell 88E6085/6095/6095F/6131 + This enables support for the Marvell 88E6095/6095F/6131 ethernet switch chips. config NET_DSA_MV88E6123_61_65 diff --git a/trunk/net/dsa/mv88e6131.c b/trunk/net/dsa/mv88e6131.c index 45f7411e90ba..3da418894efc 100644 --- a/trunk/net/dsa/mv88e6131.c +++ b/trunk/net/dsa/mv88e6131.c @@ -207,15 +207,8 @@ static int mv88e6131_setup_port(struct dsa_switch *ds, int p) * mode, but do not enable forwarding of unknown unicasts. */ val = 0x0433; - if (p == dsa_upstream_port(ds)) { + if (p == dsa_upstream_port(ds)) val |= 0x0104; - /* - * On 6085, unknown multicast forward is controlled - * here rather than in Port Control 2 register. - */ - if (ps->id == ID_6085) - val |= 0x0008; - } if (ds->dsa_port_mask & (1 << p)) val |= 0x0100; REG_WRITE(addr, 0x04, val); @@ -258,19 +251,10 @@ static int mv88e6131_setup_port(struct dsa_switch *ds, int p) * If this is the upstream port for this switch, enable * forwarding of unknown multicast addresses. */ - if (ps->id == ID_6085) - /* - * on 6085, bits 3:0 are reserved, bit 6 control ARP - * mirroring, and multicast forward is handled in - * Port Control register. - */ - REG_WRITE(addr, 0x08, 0x0080); - else { - val = 0x0080 | dsa_upstream_port(ds); - if (p == dsa_upstream_port(ds)) - val |= 0x0040; - REG_WRITE(addr, 0x08, val); - } + val = 0x0080 | dsa_upstream_port(ds); + if (p == dsa_upstream_port(ds)) + val |= 0x0040; + REG_WRITE(addr, 0x08, val); /* * Rate Control: disable ingress rate limiting. diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index cd9ca0811cfa..5345b0bee6df 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -1680,7 +1680,7 @@ static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf) return; cnf->sysctl = NULL; - unregister_net_sysctl_table(t->sysctl_header); + unregister_sysctl_table(t->sysctl_header); kfree(t->dev_name); kfree(t); } diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index 5fe9b8b41df3..e9013d6c1f51 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -1978,6 +1978,9 @@ struct fib_table *fib_trie_table(u32 id) t = (struct trie *) tb->tb_data; memset(t, 0, sizeof(*t)); + if (id == RT_TABLE_LOCAL) + pr_info("IPv4 FIB: Using LC-trie version %s\n", VERSION); + return tb; } diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 99e6e4bb1c72..c1acf69858fd 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -2690,12 +2690,6 @@ static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) { } -static u32 *ipv4_rt_blackhole_cow_metrics(struct dst_entry *dst, - unsigned long old) -{ - return NULL; -} - static struct dst_ops ipv4_dst_blackhole_ops = { .family = AF_INET, .protocol = cpu_to_be16(ETH_P_IP), @@ -2704,7 +2698,6 @@ static struct dst_ops ipv4_dst_blackhole_ops = { .default_mtu = ipv4_blackhole_default_mtu, .default_advmss = ipv4_default_advmss, .update_pmtu = ipv4_rt_blackhole_update_pmtu, - .cow_metrics = ipv4_rt_blackhole_cow_metrics, }; struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index a7bda0757053..1493534116df 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -4537,7 +4537,7 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p) t = p->sysctl; p->sysctl = NULL; - unregister_net_sysctl_table(t->sysctl_header); + unregister_sysctl_table(t->sysctl_header); kfree(t->dev_name); kfree(t); } diff --git a/trunk/net/ipv6/esp6.c b/trunk/net/ipv6/esp6.c index 59dccfbb5b11..5aa8ec88f194 100644 --- a/trunk/net/ipv6/esp6.c +++ b/trunk/net/ipv6/esp6.c @@ -371,7 +371,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) iv = esp_tmp_iv(aead, tmp, seqhilen); req = esp_tmp_req(aead, iv); asg = esp_req_sg(aead, req); - sg = asg + sglists; + sg = asg + 1; skb->ip_summed = CHECKSUM_NONE; diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index fd0eec6f88c6..843406f14d7b 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -153,12 +153,6 @@ static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) { } -static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst, - unsigned long old) -{ - return NULL; -} - static struct dst_ops ip6_dst_blackhole_ops = { .family = AF_INET6, .protocol = cpu_to_be16(ETH_P_IPV6), @@ -167,7 +161,6 @@ static struct dst_ops ip6_dst_blackhole_ops = { .default_mtu = ip6_blackhole_default_mtu, .default_advmss = ip6_default_advmss, .update_pmtu = ip6_rt_blackhole_update_pmtu, - .cow_metrics = ip6_rt_blackhole_cow_metrics, }; static const u32 ip6_template_metrics[RTAX_MAX] = { @@ -2019,6 +2012,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, rt->dst.output = ip6_output; rt->rt6i_dev = net->loopback_dev; rt->rt6i_idev = idev; + dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1); rt->dst.obsolete = -1; rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index 9e305d74b3d4..15c37746845e 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -1335,7 +1335,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features) skb->ip_summed = CHECKSUM_NONE; /* Check if there is enough headroom to insert fragment header. */ - if ((skb_mac_header(skb) < skb->head + frag_hdr_sz) && + if ((skb_headroom(skb) < frag_hdr_sz) && pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC)) goto out; diff --git a/trunk/net/l2tp/l2tp_ip.c b/trunk/net/l2tp/l2tp_ip.c index 5c04f3e42704..fce9bd3bd3fe 100644 --- a/trunk/net/l2tp/l2tp_ip.c +++ b/trunk/net/l2tp/l2tp_ip.c @@ -667,7 +667,7 @@ MODULE_AUTHOR("James Chapman "); MODULE_DESCRIPTION("L2TP over IP"); MODULE_VERSION("1.0"); -/* Use the value of SOCK_DGRAM (2) directory, because __stringify doesn't like +/* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like * enums */ MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP); diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 44049733c4ea..334213571ad0 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -1504,8 +1504,6 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode old_req; int err; - lockdep_assert_held(&sdata->u.mgd.mtx); - old_req = sdata->u.mgd.req_smps; sdata->u.mgd.req_smps = smps_mode; diff --git a/trunk/net/mac80211/debugfs_netdev.c b/trunk/net/mac80211/debugfs_netdev.c index 9ea7c0d0103f..dacace6b1393 100644 --- a/trunk/net/mac80211/debugfs_netdev.c +++ b/trunk/net/mac80211/debugfs_netdev.c @@ -177,9 +177,9 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, if (sdata->vif.type != NL80211_IFTYPE_STATION) return -EOPNOTSUPP; - mutex_lock(&sdata->u.mgd.mtx); + mutex_lock(&local->iflist_mtx); err = __ieee80211_request_smps(sdata, smps_mode); - mutex_unlock(&sdata->u.mgd.mtx); + mutex_unlock(&local->iflist_mtx); return err; } diff --git a/trunk/net/sctp/ulpevent.c b/trunk/net/sctp/ulpevent.c index 61b1f5ada96a..dff27d5e22fd 100644 --- a/trunk/net/sctp/ulpevent.c +++ b/trunk/net/sctp/ulpevent.c @@ -554,7 +554,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed( memcpy(&ssf->ssf_info, &chunk->sinfo, sizeof(struct sctp_sndrcvinfo)); /* Per TSVWG discussion with Randy. Allow the application to - * reassemble a fragmented message. + * resemble a fragmented message. */ ssf->ssf_info.sinfo_flags = chunk->chunk_hdr->flags; diff --git a/trunk/net/sunrpc/Kconfig b/trunk/net/sunrpc/Kconfig index b2198e65d8bb..8873fd8ddacd 100644 --- a/trunk/net/sunrpc/Kconfig +++ b/trunk/net/sunrpc/Kconfig @@ -18,13 +18,14 @@ config SUNRPC_XPRT_RDMA If unsure, say N. config RPCSEC_GSS_KRB5 - tristate "Secure RPC: Kerberos V mechanism" + tristate depends on SUNRPC && CRYPTO - depends on CRYPTO_MD5 && CRYPTO_DES && CRYPTO_CBC && CRYPTO_CTS - depends on CRYPTO_ECB && CRYPTO_HMAC && CRYPTO_SHA1 && CRYPTO_AES - depends on CRYPTO_ARC4 + prompt "Secure RPC: Kerberos V mechanism" if !(NFS_V4 || NFSD_V4) default y select SUNRPC_GSS + select CRYPTO_MD5 + select CRYPTO_DES + select CRYPTO_CBC help Choose Y here to enable Secure RPC using the Kerberos version 5 GSS-API mechanism (RFC 1964). diff --git a/trunk/net/sunrpc/auth_gss/auth_gss.c b/trunk/net/sunrpc/auth_gss/auth_gss.c index 339ba64cce1e..f3914d0c5079 100644 --- a/trunk/net/sunrpc/auth_gss/auth_gss.c +++ b/trunk/net/sunrpc/auth_gss/auth_gss.c @@ -520,7 +520,7 @@ gss_refresh_upcall(struct rpc_task *task) warn_gssd(); task->tk_timeout = 15*HZ; rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL); - return -EAGAIN; + return 0; } if (IS_ERR(gss_msg)) { err = PTR_ERR(gss_msg); @@ -563,12 +563,10 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) if (PTR_ERR(gss_msg) == -EAGAIN) { err = wait_event_interruptible_timeout(pipe_version_waitqueue, pipe_version >= 0, 15*HZ); - if (pipe_version < 0) { - warn_gssd(); - err = -EACCES; - } if (err) goto out; + if (pipe_version < 0) + warn_gssd(); goto retry; } if (IS_ERR(gss_msg)) { diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index 8d83f9d48713..e7a96e478f63 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -1508,10 +1508,7 @@ call_timeout(struct rpc_task *task) if (clnt->cl_chatty) printk(KERN_NOTICE "%s: server %s not responding, timed out\n", clnt->cl_protname, clnt->cl_server); - if (task->tk_flags & RPC_TASK_TIMEOUT) - rpc_exit(task, -ETIMEDOUT); - else - rpc_exit(task, -EIO); + rpc_exit(task, -EIO); return; } diff --git a/trunk/net/sunrpc/xprt.c b/trunk/net/sunrpc/xprt.c index ce5eb68a9664..9494c3767356 100644 --- a/trunk/net/sunrpc/xprt.c +++ b/trunk/net/sunrpc/xprt.c @@ -906,7 +906,6 @@ void xprt_transmit(struct rpc_task *task) } dprintk("RPC: %5u xmit complete\n", task->tk_pid); - task->tk_flags |= RPC_TASK_SENT; spin_lock_bh(&xprt->transport_lock); xprt->ops->set_retrans_timeout(task); diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index b1d75beb7e20..3a43a8304768 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -524,8 +524,6 @@ static int unix_dgram_connect(struct socket *, struct sockaddr *, int, int); static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, struct msghdr *, size_t); -static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, - struct msghdr *, size_t, int); static const struct proto_ops unix_stream_ops = { .family = PF_UNIX, @@ -585,7 +583,7 @@ static const struct proto_ops unix_seqpacket_ops = { .setsockopt = sock_no_setsockopt, .getsockopt = sock_no_getsockopt, .sendmsg = unix_seqpacket_sendmsg, - .recvmsg = unix_seqpacket_recvmsg, + .recvmsg = unix_dgram_recvmsg, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; @@ -1701,18 +1699,6 @@ static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock, return unix_dgram_sendmsg(kiocb, sock, msg, len); } -static int unix_seqpacket_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t size, - int flags) -{ - struct sock *sk = sock->sk; - - if (sk->sk_state != TCP_ESTABLISHED) - return -ENOTCONN; - - return unix_dgram_recvmsg(iocb, sock, msg, size, flags); -} - static void unix_copy_addr(struct msghdr *msg, struct sock *sk) { struct unix_sock *u = unix_sk(sk); diff --git a/trunk/net/xfrm/xfrm_replay.c b/trunk/net/xfrm/xfrm_replay.c index e8a781422feb..f218385950ca 100644 --- a/trunk/net/xfrm/xfrm_replay.c +++ b/trunk/net/xfrm/xfrm_replay.c @@ -532,7 +532,7 @@ int xfrm_init_replay(struct xfrm_state *x) if (replay_esn) { if (replay_esn->replay_window > - replay_esn->bmp_len * sizeof(__u32) * 8) + replay_esn->bmp_len * sizeof(__u32)) return -EINVAL; if ((x->props.flags & XFRM_STATE_ESN) && x->replay_esn) diff --git a/trunk/net/xfrm/xfrm_user.c b/trunk/net/xfrm/xfrm_user.c index c658cb3bc7c3..5d1d60d3ca83 100644 --- a/trunk/net/xfrm/xfrm_user.c +++ b/trunk/net/xfrm/xfrm_user.c @@ -124,9 +124,6 @@ static inline int verify_replay(struct xfrm_usersa_info *p, { struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL]; - if ((p->flags & XFRM_STATE_ESN) && !rt) - return -EINVAL; - if (!rt) return 0; diff --git a/trunk/sound/aoa/codecs/tas.c b/trunk/sound/aoa/codecs/tas.c index fd2188c3df2b..58804c7acfcf 100644 --- a/trunk/sound/aoa/codecs/tas.c +++ b/trunk/sound/aoa/codecs/tas.c @@ -170,7 +170,7 @@ static void tas_set_volume(struct tas *tas) /* analysing the volume and mixer tables shows * that they are similar enough when we shift * the mixer table down by 4 bits. The error - * is miniscule, in just one item the error + * is minuscule, in just one item the error * is 1, at a value of 0x07f17b (mixer table * value is 0x07f17a) */ tmp = tas_gaintable[left]; diff --git a/trunk/sound/pci/au88x0/au88x0_pcm.c b/trunk/sound/pci/au88x0/au88x0_pcm.c index 62e959120c44..33f0ba5559a7 100644 --- a/trunk/sound/pci/au88x0/au88x0_pcm.c +++ b/trunk/sound/pci/au88x0/au88x0_pcm.c @@ -44,10 +44,10 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_adb = { .channels_min = 1, .channels_max = 2, .buffer_bytes_max = 0x10000, - .period_bytes_min = 0x20, + .period_bytes_min = 0x1, .period_bytes_max = 0x1000, .periods_min = 2, - .periods_max = 1024, + .periods_max = 32, }; #ifndef CHIP_AU8820 @@ -140,9 +140,6 @@ static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) return err; - snd_pcm_hw_constraint_step(runtime, 0, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 64); - if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { #ifndef CHIP_AU8820 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) { diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index c82979a8cd09..d3bd2c10180f 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -1704,11 +1704,11 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) codec->chip_name, fix->type); break; } - if (!fix->chained) + if (!fix[id].chained) break; if (++depth > 10) break; - id = fix->chain_id; + id = fix[id].chain_id; } } @@ -5645,7 +5645,6 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, static struct snd_pci_quirk beep_white_list[] = { SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), - SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), {} }; @@ -9864,7 +9863,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), @@ -10701,6 +10699,7 @@ enum { PINFIX_LENOVO_Y530, PINFIX_PB_M5210, PINFIX_ACER_ASPIRE_7736, + PINFIX_GIGABYTE_880GM, }; static const struct alc_fixup alc882_fixups[] = { @@ -10732,6 +10731,13 @@ static const struct alc_fixup alc882_fixups[] = { .type = ALC_FIXUP_SKU, .v.sku = ALC_FIXUP_SKU_IGNORE, }, + [PINFIX_GIGABYTE_880GM] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x1114410 }, /* set as speaker */ + { } + } + }, }; static struct snd_pci_quirk alc882_fixup_tbl[] = { @@ -10739,6 +10745,7 @@ static struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM), {} }; @@ -18798,8 +18805,6 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", - ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), @@ -19473,7 +19478,7 @@ enum { ALC662_FIXUP_IDEAPAD, ALC272_FIXUP_MARIO, ALC662_FIXUP_CZC_P10T, - ALC662_FIXUP_SKU_IGNORE, + ALC662_FIXUP_GIGABYTE, }; static const struct alc_fixup alc662_fixups[] = { @@ -19502,17 +19507,20 @@ static const struct alc_fixup alc662_fixups[] = { {} } }, - [ALC662_FIXUP_SKU_IGNORE] = { - .type = ALC_FIXUP_SKU, - .v.sku = ALC_FIXUP_SKU_IGNORE, + [ALC662_FIXUP_GIGABYTE] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x1114410 }, /* set as speaker */ + { } + } }, }; static struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), - SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index 0997031c48d2..1371b57c11e8 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -1292,18 +1292,14 @@ static void notify_aa_path_ctls(struct hda_codec *codec) { int i; struct snd_ctl_elem_id id; - const char *labels[] = {"Mic", "Front Mic", "Line", "Rear Mic"}; - struct snd_kcontrol *ctl; + const char *labels[] = {"Mic", "Front Mic", "Line"}; memset(&id, 0, sizeof(id)); id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; for (i = 0; i < ARRAY_SIZE(labels); i++) { sprintf(id.name, "%s Playback Volume", labels[i]); - ctl = snd_hda_find_mixer_ctl(codec, id.name); - if (ctl) - snd_ctl_notify(codec->bus->card, - SNDRV_CTL_EVENT_MASK_VALUE, - &ctl->id); + snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE, + &id); } } diff --git a/trunk/sound/usb/format.c b/trunk/sound/usb/format.c index f079b5e2ab28..5b792d2c8061 100644 --- a/trunk/sound/usb/format.c +++ b/trunk/sound/usb/format.c @@ -176,11 +176,9 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof if (!rate) continue; /* C-Media CM6501 mislabels its 96 kHz altsetting */ - /* Terratec Aureon 7.1 USB C-Media 6206, too */ if (rate == 48000 && nr_rates == 1 && (chip->usb_id == USB_ID(0x0d8c, 0x0201) || - chip->usb_id == USB_ID(0x0d8c, 0x0102) || - chip->usb_id == USB_ID(0x0ccd, 0x00b1)) && + chip->usb_id == USB_ID(0x0d8c, 0x0102)) && fp->altsetting == 5 && fp->maxpacksize == 392) rate = 96000; /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */ diff --git a/trunk/sound/usb/quirks.c b/trunk/sound/usb/quirks.c index 1b94ec3a3368..ec07e62e53f3 100644 --- a/trunk/sound/usb/quirks.c +++ b/trunk/sound/usb/quirks.c @@ -533,7 +533,6 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, case USB_ID(0x0d8c, 0x0102): /* C-Media CM6206 / CM106-Like Sound Device */ - case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */ return snd_usb_cm6206_boot_quirk(dev); case USB_ID(0x133e, 0x0815):