Minor line offset auto-merges.
Unified · Split
| @@ -27,17 +27,17 @@ Start End Size Use · 26 unmodified lines | ||
| 27 | 27 | ----------------------------------------------------------------------- |
| 28 | 28 | 0000000000000000 0000007fffffffff 512GB user |
| 29 | 29 | |
| 30 | −ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc | |
| 30 | +ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc | |
| 31 | 31 | |
| 32 | −ffffffbbfffd0000 ffffffbcfffdffff 64KB [guard page] | |
| 32 | +ffffffbbffff0000 ffffffbbffffffff 64KB [guard page] | |
| 33 | 33 | |
| 34 | −ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O space | |
| 34 | +ffffffbc00000000 ffffffbdffffffff 8GB vmemmap | |
| 35 | 35 | |
| 36 | −ffffffbbffff0000 ffffffbcffffffff 64KB [guard page] | |
| 36 | +ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap] | |
| 37 | 37 | |
| 38 | −ffffffbc00000000 ffffffbdffffffff 8GB vmemmap | |
| 38 | +ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space | |
| 39 | 39 | |
| 40 | −ffffffbe00000000 ffffffbffbffffff ~8GB [guard, future vmmemap] | |
| 40 | +ffffffbbffff0000 ffffffbcffffffff ~2MB [guard] | |
| 41 | 41 | |
| 42 | 42 | ffffffbffc000000 ffffffbfffffffff 64MB modules |
| 43 | 43 | |
| @@ -466,6 +466,10 @@ Note: · 465 unmodified lines | ||
| 466 | 466 | 5.3 swappiness |
| 467 | 467 | |
| 468 | 468 | Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. |
| 469 | +Please note that unlike the global swappiness, memcg knob set to 0 | |
| 470 | +really prevents from any swapping even if there is a swap storage | |
| 471 | +available. This might lead to memcg OOM killer if there are no file | |
| 472 | +pages to reclaim. | |
| 469 | 473 | |
| 470 | 474 | Following cgroups' swappiness can't be changed. |
| 471 | 475 | - root cgroup (uses /proc/sys/vm/swappiness). |
| @@ -33,7 +33,7 @@ Table of Contents · 32 unmodified lines | ||
| 33 | 33 | 2 Modifying System Parameters |
| 34 | 34 | |
| 35 | 35 | 3 Per-Process Parameters |
| 36 | − 3.1 /proc/<pid>/oom_score_adj - Adjust the oom-killer | |
| 36 | + 3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj - Adjust the oom-killer | |
| 37 | 37 | score |
| 38 | 38 | 3.2 /proc/<pid>/oom_score - Display current oom-killer score |
| 39 | 39 | 3.3 /proc/<pid>/io - Display the IO accounting fields |
| @@ -1320,10 +1320,10 @@ of the kernel. · 1280 unmodified lines | ||
| 1320 | 1320 | CHAPTER 3: PER-PROCESS PARAMETERS |
| 1321 | 1321 | ------------------------------------------------------------------------------ |
| 1322 | 1322 | |
| 1323 | −3.1 /proc/<pid>/oom_score_adj- Adjust the oom-killer score | |
| 1323 | +3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj- Adjust the oom-killer score | |
| 1324 | 1324 | -------------------------------------------------------------------------------- |
| 1325 | 1325 | |
| 1326 | −This file can be used to adjust the badness heuristic used to select which | |
| 1326 | +These file can be used to adjust the badness heuristic used to select which | |
| 1327 | 1327 | process gets killed in out of memory conditions. |
| 1328 | 1328 | |
| 1329 | 1329 | The badness heuristic assigns a value to each candidate task ranging from 0 |
| @@ -1361,6 +1361,12 @@ same system, cpuset, mempolicy, or memory controller resources to use at least · 31 unmodified lines | ||
| 1361 | 1361 | equivalent to discounting 50% of the task's allowed memory from being considered |
| 1362 | 1362 | as scoring against the task. |
| 1363 | 1363 | |
| 1364 | +For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also | |
| 1365 | +be used to tune the badness score. Its acceptable values range from -16 | |
| 1366 | +(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17 | |
| 1367 | +(OOM_DISABLE) to disable oom killing entirely for that task. Its value is | |
| 1368 | +scaled linearly with /proc/<pid>/oom_score_adj. | |
| 1369 | + | |
| 1364 | 1370 | The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last |
| 1365 | 1371 | value set by a CAP_SYS_RESOURCE process. To reduce the value any lower |
| 1366 | 1372 | requires CAP_SYS_RESOURCE. |
| @@ -1375,7 +1381,9 @@ minimal amount of work. · 8 unmodified lines | ||
| 1375 | 1381 | ------------------------------------------------------------- |
| 1376 | 1382 | |
| 1377 | 1383 | This file can be used to check the current score used by the oom-killer is for |
| 1378 | −any given <pid>. | |
| 1384 | +any given <pid>. Use it together with /proc/<pid>/oom_score_adj to tune which | |
| 1385 | +process should be killed in an out-of-memory situation. | |
| 1386 | + | |
| 1379 | 1387 | |
| 1380 | 1388 | 3.3 /proc/<pid>/io - Display the IO accounting fields |
| 1381 | 1389 | ------------------------------------------------------- |
| @@ -164,4 +164,4 @@ read the CRC recorded by the NIC on receipt of the packet. · 163 unmodified lines | ||
| 164 | 164 | This requests that the NIC receive all possible frames, including errored |
| 165 | 165 | frames (such as bad FCS, etc). This can be helpful when sniffing a link with |
| 166 | 166 | bad packets on it. Some NICs may receive more packets if also put into normal |
| 167 | −PROMISC mdoe. | |
| 167 | +PROMISC mode. | |
| @@ -2507,6 +2507,7 @@ M: Joonyoung Shim <jy0922.shim@samsung.com> · 2506 unmodified lines | ||
| 2507 | 2507 | M: Seung-Woo Kim <sw0312.kim@samsung.com> |
| 2508 | 2508 | M: Kyungmin Park <kyungmin.park@samsung.com> |
| 2509 | 2509 | L: dri-devel@lists.freedesktop.org |
| 2510 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git | |
| 2510 | 2511 | S: Supported |
| 2511 | 2512 | F: drivers/gpu/drm/exynos |
| 2512 | 2513 | F: include/drm/exynos* |
| @@ -3597,6 +3598,49 @@ F: drivers/hid/hid-hyperv.c · 1084 unmodified lines | ||
| 3597 | 3598 | F: drivers/net/hyperv/ |
| 3598 | 3599 | F: drivers/staging/hv/ |
| 3599 | 3600 | |
| 3601 | +I2C OVER PARALLEL PORT | |
| 3602 | +M: Jean Delvare <khali@linux-fr.org> | |
| 3603 | +L: linux-i2c@vger.kernel.org | |
| 3604 | +S: Maintained | |
| 3605 | +F: Documentation/i2c/busses/i2c-parport | |
| 3606 | +F: Documentation/i2c/busses/i2c-parport-light | |
| 3607 | +F: drivers/i2c/busses/i2c-parport.c | |
| 3608 | +F: drivers/i2c/busses/i2c-parport-light.c | |
| 3609 | + | |
| 3610 | +I2C/SMBUS CONTROLLER DRIVERS FOR PC | |
| 3611 | +M: Jean Delvare <khali@linux-fr.org> | |
| 3612 | +L: linux-i2c@vger.kernel.org | |
| 3613 | +S: Maintained | |
| 3614 | +F: Documentation/i2c/busses/i2c-ali1535 | |
| 3615 | +F: Documentation/i2c/busses/i2c-ali1563 | |
| 3616 | +F: Documentation/i2c/busses/i2c-ali15x3 | |
| 3617 | +F: Documentation/i2c/busses/i2c-amd756 | |
| 3618 | +F: Documentation/i2c/busses/i2c-amd8111 | |
| 3619 | +F: Documentation/i2c/busses/i2c-i801 | |
| 3620 | +F: Documentation/i2c/busses/i2c-nforce2 | |
| 3621 | +F: Documentation/i2c/busses/i2c-piix4 | |
| 3622 | +F: Documentation/i2c/busses/i2c-sis5595 | |
| 3623 | +F: Documentation/i2c/busses/i2c-sis630 | |
| 3624 | +F: Documentation/i2c/busses/i2c-sis96x | |
| 3625 | +F: Documentation/i2c/busses/i2c-via | |
| 3626 | +F: Documentation/i2c/busses/i2c-viapro | |
| 3627 | +F: drivers/i2c/busses/i2c-ali1535.c | |
| 3628 | +F: drivers/i2c/busses/i2c-ali1563.c | |
| 3629 | +F: drivers/i2c/busses/i2c-ali15x3.c | |
| 3630 | +F: drivers/i2c/busses/i2c-amd756.c | |
| 3631 | +F: drivers/i2c/busses/i2c-amd756-s4882.c | |
| 3632 | +F: drivers/i2c/busses/i2c-amd8111.c | |
| 3633 | +F: drivers/i2c/busses/i2c-i801.c | |
| 3634 | +F: drivers/i2c/busses/i2c-isch.c | |
| 3635 | +F: drivers/i2c/busses/i2c-nforce2.c | |
| 3636 | +F: drivers/i2c/busses/i2c-nforce2-s4985.c | |
| 3637 | +F: drivers/i2c/busses/i2c-piix4.c | |
| 3638 | +F: drivers/i2c/busses/i2c-sis5595.c | |
| 3639 | +F: drivers/i2c/busses/i2c-sis630.c | |
| 3640 | +F: drivers/i2c/busses/i2c-sis96x.c | |
| 3641 | +F: drivers/i2c/busses/i2c-via.c | |
| 3642 | +F: drivers/i2c/busses/i2c-viapro.c | |
| 3643 | + | |
| 3600 | 3644 | I2C/SMBUS STUB DRIVER |
| 3601 | 3645 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> |
| 3602 | 3646 | L: linux-i2c@vger.kernel.org |
| @@ -3604,9 +3648,8 @@ S: Maintained · 1 unmodified line | ||
| 3604 | 3648 | F: drivers/i2c/busses/i2c-stub.c |
| 3605 | 3649 | |
| 3606 | 3650 | I2C SUBSYSTEM |
| 3607 | −M: "Jean Delvare (PC drivers, core)" <khali@linux-fr.org> | |
| 3651 | +M: Wolfram Sang <w.sang@pengutronix.de> | |
| 3608 | 3652 | M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org> |
| 3609 | −M: "Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de> | |
| 3610 | 3653 | L: linux-i2c@vger.kernel.org |
| 3611 | 3654 | W: http://i2c.wiki.kernel.org/ |
| 3612 | 3655 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ |
| @@ -3617,6 +3660,13 @@ F: drivers/i2c/ · 4 unmodified lines | ||
| 3617 | 3660 | F: include/linux/i2c.h |
| 3618 | 3661 | F: include/linux/i2c-*.h |
| 3619 | 3662 | |
| 3663 | +I2C-TAOS-EVM DRIVER | |
| 3664 | +M: Jean Delvare <khali@linux-fr.org> | |
| 3665 | +L: linux-i2c@vger.kernel.org | |
| 3666 | +S: Maintained | |
| 3667 | +F: Documentation/i2c/busses/i2c-taos-evm | |
| 3668 | +F: drivers/i2c/busses/i2c-taos-evm.c | |
| 3669 | + | |
| 3620 | 3670 | I2C-TINY-USB DRIVER |
| 3621 | 3671 | M: Till Harbaum <till@harbaum.org> |
| 3622 | 3672 | L: linux-i2c@vger.kernel.org |
| @@ -7212,6 +7262,14 @@ L: linux-xtensa@linux-xtensa.org · 3589 unmodified lines | ||
| 7212 | 7262 | S: Maintained |
| 7213 | 7263 | F: arch/xtensa/ |
| 7214 | 7264 | |
| 7265 | +THERMAL | |
| 7266 | +M: Zhang Rui <rui.zhang@intel.com> | |
| 7267 | +L: linux-pm@vger.kernel.org | |
| 7268 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git | |
| 7269 | +S: Supported | |
| 7270 | +F: drivers/thermal/ | |
| 7271 | +F: include/linux/thermal.h | |
| 7272 | + | |
| 7215 | 7273 | THINKPAD ACPI EXTRAS DRIVER |
| 7216 | 7274 | M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> |
| 7217 | 7275 | L: ibm-acpi-devel@lists.sourceforge.net |
| @@ -7895,13 +7953,6 @@ M: Roger Luethi <rl@hellgate.ch> · 677 unmodified lines | ||
| 7895 | 7953 | S: Maintained |
| 7896 | 7954 | F: drivers/net/ethernet/via/via-rhine.c |
| 7897 | 7955 | |
| 7898 | −VIAPRO SMBUS DRIVER | |
| 7899 | −M: Jean Delvare <khali@linux-fr.org> | |
| 7900 | −L: linux-i2c@vger.kernel.org | |
| 7901 | −S: Maintained | |
| 7902 | −F: Documentation/i2c/busses/i2c-viapro | |
| 7903 | −F: drivers/i2c/busses/i2c-viapro.c | |
| 7904 | − | |
| 7905 | 7956 | VIA SD/MMC CARD CONTROLLER DRIVER |
| 7906 | 7957 | M: Bruce Chang <brucechang@via.com.tw> |
| 7907 | 7958 | M: Harald Welte <HaraldWelte@viatech.com> |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | VERSION = 3 |
| 2 | 2 | PATCHLEVEL = 7 |
| 3 | 3 | SUBLEVEL = 0 |
| 4 | −EXTRAVERSION = -rc3 | |
| 4 | +EXTRAVERSION = -rc6 | |
| 5 | 5 | NAME = Terrified Chipmunk |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| @@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y) · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | $(obj)/xipImage: vmlinux FORCE |
| 35 | 35 | $(call if_changed,objcopy) |
| 36 | − $(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' | |
| 36 | + @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' | |
| 37 | 37 | |
| 38 | 38 | $(obj)/Image $(obj)/zImage: FORCE |
| 39 | 39 | @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' |
| @@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE · 8 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | $(obj)/Image: vmlinux FORCE |
| 50 | 50 | $(call if_changed,objcopy) |
| 51 | − $(kecho) ' Kernel: $@ is ready' | |
| 51 | + @$(kecho) ' Kernel: $@ is ready' | |
| 52 | 52 | |
| 53 | 53 | $(obj)/compressed/vmlinux: $(obj)/Image FORCE |
| 54 | 54 | $(Q)$(MAKE) $(build)=$(obj)/compressed $@ |
| 55 | 55 | |
| 56 | 56 | $(obj)/zImage: $(obj)/compressed/vmlinux FORCE |
| 57 | 57 | $(call if_changed,objcopy) |
| 58 | − $(kecho) ' Kernel: $@ is ready' | |
| 58 | + @$(kecho) ' Kernel: $@ is ready' | |
| 59 | 59 | |
| 60 | 60 | endif |
| 61 | 61 | |
| @@ -90,7 +90,7 @@ fi · 28 unmodified lines | ||
| 90 | 90 | $(obj)/uImage: $(obj)/zImage FORCE |
| 91 | 91 | @$(check_for_multiple_loadaddr) |
| 92 | 92 | $(call if_changed,uimage) |
| 93 | − $(kecho) ' Image $@ is ready' | |
| 93 | + @$(kecho) ' Image $@ is ready' | |
| 94 | 94 | |
| 95 | 95 | $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE |
| 96 | 96 | $(Q)$(MAKE) $(build)=$(obj)/bootp $@ |
| @@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE · 1 unmodified line | ||
| 98 | 98 | |
| 99 | 99 | $(obj)/bootpImage: $(obj)/bootp/bootp FORCE |
| 100 | 100 | $(call if_changed,objcopy) |
| 101 | − $(kecho) ' Kernel: $@ is ready' | |
| 101 | + @$(kecho) ' Kernel: $@ is ready' | |
| 102 | 102 | |
| 103 | 103 | PHONY += initrd FORCE |
| 104 | 104 | initrd: |
| @@ -73,8 +73,8 @@ · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | pinmux: pinmux { |
| 75 | 75 | compatible = "nvidia,tegra30-pinmux"; |
| 76 | − reg = <0x70000868 0xd0 /* Pad control registers */ | |
| 77 | − 0x70003000 0x3e0>; /* Mux registers */ | |
| 76 | + reg = <0x70000868 0xd4 /* Pad control registers */ | |
| 77 | + 0x70003000 0x3e4>; /* Mux registers */ | |
| 78 | 78 | }; |
| 79 | 79 | |
| 80 | 80 | serial@70006000 { |
| @@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); · 63 unmodified lines | ||
| 64 | 64 | static inline void __raw_writew(u16 val, volatile void __iomem *addr) |
| 65 | 65 | { |
| 66 | 66 | asm volatile("strh %1, %0" |
| 67 | − : "+Qo" (*(volatile u16 __force *)addr) | |
| 67 | + : "+Q" (*(volatile u16 __force *)addr) | |
| 68 | 68 | : "r" (val)); |
| 69 | 69 | } |
| 70 | 70 | |
| @@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) · 1 unmodified line | ||
| 72 | 72 | { |
| 73 | 73 | u16 val; |
| 74 | 74 | asm volatile("ldrh %1, %0" |
| 75 | − : "+Qo" (*(volatile u16 __force *)addr), | |
| 75 | + : "+Q" (*(volatile u16 __force *)addr), | |
| 76 | 76 | "=r" (val)); |
| 77 | 77 | return val; |
| 78 | 78 | } |
| @@ -10,7 +10,5 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | extern void sched_clock_postinit(void); |
| 12 | 12 | extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); |
| 13 | −extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, | |
| 14 | − unsigned long rate); | |
| 15 | 13 | |
| 16 | 14 | #endif |
| @@ -27,9 +27,9 @@ · 26 unmodified lines | ||
| 27 | 27 | #if __LINUX_ARM_ARCH__ <= 6 |
| 28 | 28 | ldr \tmp, =elf_hwcap @ may not have MVFR regs |
| 29 | 29 | ldr \tmp, [\tmp, #0] |
| 30 | − tst \tmp, #HWCAP_VFPv3D16 | |
| 31 | − ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} | |
| 32 | − addne \base, \base, #32*4 @ step over unused register space | |
| 30 | + tst \tmp, #HWCAP_VFPD32 | |
| 31 | + ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} | |
| 32 | + addeq \base, \base, #32*4 @ step over unused register space | |
| 33 | 33 | #else |
| 34 | 34 | VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 |
| 35 | 35 | and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field |
| @@ -51,9 +51,9 @@ · 15 unmodified lines | ||
| 51 | 51 | #if __LINUX_ARM_ARCH__ <= 6 |
| 52 | 52 | ldr \tmp, =elf_hwcap @ may not have MVFR regs |
| 53 | 53 | ldr \tmp, [\tmp, #0] |
| 54 | − tst \tmp, #HWCAP_VFPv3D16 | |
| 55 | − stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} | |
| 56 | − addne \base, \base, #32*4 @ step over unused register space | |
| 54 | + tst \tmp, #HWCAP_VFPD32 | |
| 55 | + stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} | |
| 56 | + addeq \base, \base, #32*4 @ step over unused register space | |
| 57 | 57 | #else |
| 58 | 58 | VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 |
| 59 | 59 | and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field |
| @@ -18,11 +18,12 @@ · 17 unmodified lines | ||
| 18 | 18 | #define HWCAP_THUMBEE (1 << 11) |
| 19 | 19 | #define HWCAP_NEON (1 << 12) |
| 20 | 20 | #define HWCAP_VFPv3 (1 << 13) |
| 21 | −#define HWCAP_VFPv3D16 (1 << 14) | |
| 21 | +#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */ | |
| 22 | 22 | #define HWCAP_TLS (1 << 15) |
| 23 | 23 | #define HWCAP_VFPv4 (1 << 16) |
| 24 | 24 | #define HWCAP_IDIVA (1 << 17) |
| 25 | 25 | #define HWCAP_IDIVT (1 << 18) |
| 26 | +#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ | |
| 26 | 27 | #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) |
| 27 | 28 | |
| 28 | 29 | |
| @@ -107,13 +107,6 @@ static void sched_clock_poll(unsigned long wrap_ticks) · 106 unmodified lines | ||
| 107 | 107 | update_sched_clock(); |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | −void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, | |
| 111 | − unsigned long rate) | |
| 112 | −{ | |
| 113 | − setup_sched_clock(read, bits, rate); | |
| 114 | − cd.needs_suspend = true; | |
| 115 | −} | |
| 116 | − | |
| 117 | 110 | void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) |
| 118 | 111 | { |
| 119 | 112 | unsigned long r, w; |
| @@ -189,18 +182,15 @@ void __init sched_clock_postinit(void) · 69 unmodified lines | ||
| 189 | 182 | static int sched_clock_suspend(void) |
| 190 | 183 | { |
| 191 | 184 | sched_clock_poll(sched_clock_timer.data); |
| 192 | − if (cd.needs_suspend) | |
| 193 | − cd.suspended = true; | |
| 185 | + cd.suspended = true; | |
| 194 | 186 | return 0; |
| 195 | 187 | } |
| 196 | 188 | |
| 197 | 189 | static void sched_clock_resume(void) |
| 198 | 190 | { |
| 199 | − if (cd.needs_suspend) { | |
| 200 | − cd.epoch_cyc = read_sched_clock(); | |
| 201 | − cd.epoch_cyc_copy = cd.epoch_cyc; | |
| 202 | − cd.suspended = false; | |
| 203 | − } | |
| 191 | + cd.epoch_cyc = read_sched_clock(); | |
| 192 | + cd.epoch_cyc_copy = cd.epoch_cyc; | |
| 193 | + cd.suspended = false; | |
| 204 | 194 | } |
| 205 | 195 | |
| 206 | 196 | static struct syscore_ops sched_clock_ops = { |
| @@ -68,7 +68,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) · 67 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | /* Enable overcurrent notification */ |
| 70 | 70 | for (i = 0; i < data->ports; i++) { |
| 71 | − if (data->overcurrent_pin[i]) | |
| 71 | + if (gpio_is_valid(data->overcurrent_pin[i])) | |
| 72 | 72 | at91_set_gpio_input(data->overcurrent_pin[i], 1); |
| 73 | 73 | } |
| 74 | 74 | |
| @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | /* Enable overcurrent notification */ |
| 74 | 74 | for (i = 0; i < data->ports; i++) { |
| 75 | − if (data->overcurrent_pin[i]) | |
| 75 | + if (gpio_is_valid(data->overcurrent_pin[i])) | |
| 76 | 76 | at91_set_gpio_input(data->overcurrent_pin[i], 1); |
| 77 | 77 | } |
| 78 | 78 | |
| @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | /* Enable overcurrent notification */ |
| 74 | 74 | for (i = 0; i < data->ports; i++) { |
| 75 | − if (data->overcurrent_pin[i]) | |
| 75 | + if (gpio_is_valid(data->overcurrent_pin[i])) | |
| 76 | 76 | at91_set_gpio_input(data->overcurrent_pin[i], 1); |
| 77 | 77 | } |
| 78 | 78 | |
| @@ -78,7 +78,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) · 77 unmodified lines | ||
| 78 | 78 | |
| 79 | 79 | /* Enable overcurrent notification */ |
| 80 | 80 | for (i = 0; i < data->ports; i++) { |
| 81 | − if (data->overcurrent_pin[i]) | |
| 81 | + if (gpio_is_valid(data->overcurrent_pin[i])) | |
| 82 | 82 | at91_set_gpio_input(data->overcurrent_pin[i], 1); |
| 83 | 83 | } |
| 84 | 84 | |
| @@ -1841,8 +1841,8 @@ static struct resource sha_resources[] = { · 1840 unmodified lines | ||
| 1841 | 1841 | .flags = IORESOURCE_MEM, |
| 1842 | 1842 | }, |
| 1843 | 1843 | [1] = { |
| 1844 | − .start = AT91SAM9G45_ID_AESTDESSHA, | |
| 1845 | − .end = AT91SAM9G45_ID_AESTDESSHA, | |
| 1844 | + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1845 | + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1846 | 1846 | .flags = IORESOURCE_IRQ, |
| 1847 | 1847 | }, |
| 1848 | 1848 | }; |
| @@ -1874,8 +1874,8 @@ static struct resource tdes_resources[] = { · 25 unmodified lines | ||
| 1874 | 1874 | .flags = IORESOURCE_MEM, |
| 1875 | 1875 | }, |
| 1876 | 1876 | [1] = { |
| 1877 | − .start = AT91SAM9G45_ID_AESTDESSHA, | |
| 1878 | − .end = AT91SAM9G45_ID_AESTDESSHA, | |
| 1877 | + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1878 | + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1879 | 1879 | .flags = IORESOURCE_IRQ, |
| 1880 | 1880 | }, |
| 1881 | 1881 | }; |
| @@ -1910,8 +1910,8 @@ static struct resource aes_resources[] = { · 28 unmodified lines | ||
| 1910 | 1910 | .flags = IORESOURCE_MEM, |
| 1911 | 1911 | }, |
| 1912 | 1912 | [1] = { |
| 1913 | − .start = AT91SAM9G45_ID_AESTDESSHA, | |
| 1914 | − .end = AT91SAM9G45_ID_AESTDESSHA, | |
| 1913 | + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1914 | + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1915 | 1915 | .flags = IORESOURCE_IRQ, |
| 1916 | 1916 | }, |
| 1917 | 1917 | }; |
| @@ -28,6 +28,7 @@ void highbank_restart(char mode, const char *cmd) · 27 unmodified lines | ||
| 28 | 28 | hignbank_set_pwr_soft_reset(); |
| 29 | 29 | |
| 30 | 30 | scu_power_mode(scu_base_addr, SCU_PM_POWEROFF); |
| 31 | − cpu_do_idle(); | |
| 31 | + while (1) | |
| 32 | + cpu_do_idle(); | |
| 32 | 33 | } |
| 33 | 34 | |
| @@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, · 111 unmodified lines | ||
| 112 | 112 | |
| 113 | 113 | clk = clk_register(dev, &gate->hw); |
| 114 | 114 | if (IS_ERR(clk)) |
| 115 | − kfree(clk); | |
| 115 | + kfree(gate); | |
| 116 | 116 | |
| 117 | 117 | return clk; |
| 118 | 118 | } |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define MX25_H1_SIC_SHIFT 21 |
| 31 | 31 | #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) |
| 32 | 32 | #define MX25_H1_PP_BIT (1 << 18) |
| 33 | −#define MX25_H1_PM_BIT (1 << 8) | |
| 33 | +#define MX25_H1_PM_BIT (1 << 16) | |
| 34 | 34 | #define MX25_H1_IPPUE_UP_BIT (1 << 7) |
| 35 | 35 | #define MX25_H1_IPPUE_DOWN_BIT (1 << 6) |
| 36 | 36 | #define MX25_H1_TLL_BIT (1 << 5) |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define MX35_H1_SIC_SHIFT 21 |
| 31 | 31 | #define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) |
| 32 | 32 | #define MX35_H1_PP_BIT (1 << 18) |
| 33 | −#define MX35_H1_PM_BIT (1 << 8) | |
| 33 | +#define MX35_H1_PM_BIT (1 << 16) | |
| 34 | 34 | #define MX35_H1_IPPUE_UP_BIT (1 << 7) |
| 35 | 35 | #define MX35_H1_IPPUE_DOWN_BIT (1 << 6) |
| 36 | 36 | #define MX35_H1_TLL_BIT (1 << 5) |
| @@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = { · 358 unmodified lines | ||
| 359 | 359 | .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, |
| 360 | 360 | .wkdep_srcs = iss_wkup_sleep_deps, |
| 361 | 361 | .sleepdep_srcs = iss_wkup_sleep_deps, |
| 362 | − .flags = CLKDM_CAN_HWSUP_SWSUP, | |
| 362 | + .flags = CLKDM_CAN_SWSUP, | |
| 363 | 363 | }; |
| 364 | 364 | |
| 365 | 365 | static struct clockdomain l3_dss_44xx_clkdm = { |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/of.h> |
| 20 | 20 | #include <linux/pinctrl/machine.h> |
| 21 | 21 | #include <linux/platform_data/omap4-keypad.h> |
| 22 | +#include <linux/platform_data/omap_ocp2scp.h> | |
| 22 | 23 | |
| 23 | 24 | #include <asm/mach-types.h> |
| 24 | 25 | #include <asm/mach/map.h> |
| @@ -613,6 +614,83 @@ static void omap_init_vout(void) · 588 unmodified lines | ||
| 613 | 614 | static inline void omap_init_vout(void) {} |
| 614 | 615 | #endif |
| 615 | 616 | |
| 617 | +#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE) | |
| 618 | +static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev) | |
| 619 | +{ | |
| 620 | + int cnt = 0; | |
| 621 | + | |
| 622 | + while (ocp2scp_dev->drv_name != NULL) { | |
| 623 | + cnt++; | |
| 624 | + ocp2scp_dev++; | |
| 625 | + } | |
| 626 | + | |
| 627 | + return cnt; | |
| 628 | +} | |
| 629 | + | |
| 630 | +static void omap_init_ocp2scp(void) | |
| 631 | +{ | |
| 632 | + struct omap_hwmod *oh; | |
| 633 | + struct platform_device *pdev; | |
| 634 | + int bus_id = -1, dev_cnt = 0, i; | |
| 635 | + struct omap_ocp2scp_dev *ocp2scp_dev; | |
| 636 | + const char *oh_name, *name; | |
| 637 | + struct omap_ocp2scp_platform_data *pdata; | |
| 638 | + | |
| 639 | + if (!cpu_is_omap44xx()) | |
| 640 | + return; | |
| 641 | + | |
| 642 | + oh_name = "ocp2scp_usb_phy"; | |
| 643 | + name = "omap-ocp2scp"; | |
| 644 | + | |
| 645 | + oh = omap_hwmod_lookup(oh_name); | |
| 646 | + if (!oh) { | |
| 647 | + pr_err("%s: could not find omap_hwmod for %s\n", __func__, | |
| 648 | + oh_name); | |
| 649 | + return; | |
| 650 | + } | |
| 651 | + | |
| 652 | + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | |
| 653 | + if (!pdata) { | |
| 654 | + pr_err("%s: No memory for ocp2scp pdata\n", __func__); | |
| 655 | + return; | |
| 656 | + } | |
| 657 | + | |
| 658 | + ocp2scp_dev = oh->dev_attr; | |
| 659 | + dev_cnt = count_ocp2scp_devices(ocp2scp_dev); | |
| 660 | + | |
| 661 | + if (!dev_cnt) { | |
| 662 | + pr_err("%s: No devices connected to ocp2scp\n", __func__); | |
| 663 | + kfree(pdata); | |
| 664 | + return; | |
| 665 | + } | |
| 666 | + | |
| 667 | + pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *) | |
| 668 | + * dev_cnt, GFP_KERNEL); | |
| 669 | + if (!pdata->devices) { | |
| 670 | + pr_err("%s: No memory for ocp2scp pdata devices\n", __func__); | |
| 671 | + kfree(pdata); | |
| 672 | + return; | |
| 673 | + } | |
| 674 | + | |
| 675 | + for (i = 0; i < dev_cnt; i++, ocp2scp_dev++) | |
| 676 | + pdata->devices[i] = ocp2scp_dev; | |
| 677 | + | |
| 678 | + pdata->dev_cnt = dev_cnt; | |
| 679 | + | |
| 680 | + pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, | |
| 681 | + 0, false); | |
| 682 | + if (IS_ERR(pdev)) { | |
| 683 | + pr_err("Could not build omap_device for %s %s\n", | |
| 684 | + name, oh_name); | |
| 685 | + kfree(pdata->devices); | |
| 686 | + kfree(pdata); | |
| 687 | + return; | |
| 688 | + } | |
| 689 | +} | |
| 690 | +#else | |
| 691 | +static inline void omap_init_ocp2scp(void) { } | |
| 692 | +#endif | |
| 693 | + | |
| 616 | 694 | /*-------------------------------------------------------------------------*/ |
| 617 | 695 | |
| 618 | 696 | static int __init omap2_init_devices(void) |
| @@ -640,6 +718,7 @@ static int __init omap2_init_devices(void) · 21 unmodified lines | ||
| 640 | 718 | omap_init_sham(); |
| 641 | 719 | omap_init_aes(); |
| 642 | 720 | omap_init_vout(); |
| 721 | + omap_init_ocp2scp(); | |
| 643 | 722 | |
| 644 | 723 | return 0; |
| 645 | 724 | } |
| @@ -421,6 +421,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) · 420 unmodified lines | ||
| 421 | 421 | return 0; |
| 422 | 422 | } |
| 423 | 423 | |
| 424 | +/** | |
| 425 | + * _wait_softreset_complete - wait for an OCP softreset to complete | |
| 426 | + * @oh: struct omap_hwmod * to wait on | |
| 427 | + * | |
| 428 | + * Wait until the IP block represented by @oh reports that its OCP | |
| 429 | + * softreset is complete. This can be triggered by software (see | |
| 430 | + * _ocp_softreset()) or by hardware upon returning from off-mode (one | |
| 431 | + * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT | |
| 432 | + * microseconds. Returns the number of microseconds waited. | |
| 433 | + */ | |
| 434 | +static int _wait_softreset_complete(struct omap_hwmod *oh) | |
| 435 | +{ | |
| 436 | + struct omap_hwmod_class_sysconfig *sysc; | |
| 437 | + u32 softrst_mask; | |
| 438 | + int c = 0; | |
| 439 | + | |
| 440 | + sysc = oh->class->sysc; | |
| 441 | + | |
| 442 | + if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) | |
| 443 | + omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) | |
| 444 | + & SYSS_RESETDONE_MASK), | |
| 445 | + MAX_MODULE_SOFTRESET_WAIT, c); | |
| 446 | + else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { | |
| 447 | + softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); | |
| 448 | + omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) | |
| 449 | + & softrst_mask), | |
| 450 | + MAX_MODULE_SOFTRESET_WAIT, c); | |
| 451 | + } | |
| 452 | + | |
| 453 | + return c; | |
| 454 | +} | |
| 455 | + | |
| 424 | 456 | /** |
| 425 | 457 | * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v |
| 426 | 458 | * @oh: struct omap_hwmod * |
| @@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh) · 855 unmodified lines | ||
| 1282 | 1314 | if (!oh->class->sysc) |
| 1283 | 1315 | return; |
| 1284 | 1316 | |
| 1317 | + /* | |
| 1318 | + * Wait until reset has completed, this is needed as the IP | |
| 1319 | + * block is reset automatically by hardware in some cases | |
| 1320 | + * (off-mode for example), and the drivers require the | |
| 1321 | + * IP to be ready when they access it | |
| 1322 | + */ | |
| 1323 | + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) | |
| 1324 | + _enable_optional_clocks(oh); | |
| 1325 | + _wait_softreset_complete(oh); | |
| 1326 | + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) | |
| 1327 | + _disable_optional_clocks(oh); | |
| 1328 | + | |
| 1285 | 1329 | v = oh->_sysc_cache; |
| 1286 | 1330 | sf = oh->class->sysc->sysc_flags; |
| 1287 | 1331 | |
| @@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) · 516 unmodified lines | ||
| 1804 | 1848 | */ |
| 1805 | 1849 | static int _ocp_softreset(struct omap_hwmod *oh) |
| 1806 | 1850 | { |
| 1807 | − u32 v, softrst_mask; | |
| 1851 | + u32 v; | |
| 1808 | 1852 | int c = 0; |
| 1809 | 1853 | int ret = 0; |
| 1810 | 1854 | |
| @@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh) · 23 unmodified lines | ||
| 1834 | 1878 | if (oh->class->sysc->srst_udelay) |
| 1835 | 1879 | udelay(oh->class->sysc->srst_udelay); |
| 1836 | 1880 | |
| 1837 | − if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) | |
| 1838 | − omap_test_timeout((omap_hwmod_read(oh, | |
| 1839 | − oh->class->sysc->syss_offs) | |
| 1840 | − & SYSS_RESETDONE_MASK), | |
| 1841 | − MAX_MODULE_SOFTRESET_WAIT, c); | |
| 1842 | − else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { | |
| 1843 | − softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); | |
| 1844 | − omap_test_timeout(!(omap_hwmod_read(oh, | |
| 1845 | − oh->class->sysc->sysc_offs) | |
| 1846 | − & softrst_mask), | |
| 1847 | − MAX_MODULE_SOFTRESET_WAIT, c); | |
| 1848 | − } | |
| 1849 | − | |
| 1881 | + c = _wait_softreset_complete(oh); | |
| 1850 | 1882 | if (c == MAX_MODULE_SOFTRESET_WAIT) |
| 1851 | 1883 | pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", |
| 1852 | 1884 | oh->name, MAX_MODULE_SOFTRESET_WAIT); |
| @@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh) · 499 unmodified lines | ||
| 2352 | 2384 | if (oh->_state != _HWMOD_STATE_INITIALIZED) |
| 2353 | 2385 | return -EINVAL; |
| 2354 | 2386 | |
| 2387 | + if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) | |
| 2388 | + return -EPERM; | |
| 2389 | + | |
| 2355 | 2390 | if (oh->rst_lines_cnt == 0) { |
| 2356 | 2391 | r = _enable(oh); |
| 2357 | 2392 | if (r) { |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/io.h> |
| 22 | 22 | #include <linux/platform_data/gpio-omap.h> |
| 23 | 23 | #include <linux/power/smartreflex.h> |
| 24 | +#include <linux/platform_data/omap_ocp2scp.h> | |
| 24 | 25 | |
| 25 | 26 | #include <plat/omap_hwmod.h> |
| 26 | 27 | #include <plat/i2c.h> |
| @@ -2125,6 +2126,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { · 2098 unmodified lines | ||
| 2125 | 2126 | .name = "mcpdm", |
| 2126 | 2127 | .class = &omap44xx_mcpdm_hwmod_class, |
| 2127 | 2128 | .clkdm_name = "abe_clkdm", |
| 2129 | + /* | |
| 2130 | + * It's suspected that the McPDM requires an off-chip main | |
| 2131 | + * functional clock, controlled via I2C. This IP block is | |
| 2132 | + * currently reset very early during boot, before I2C is | |
| 2133 | + * available, so it doesn't seem that we have any choice in | |
| 2134 | + * the kernel other than to avoid resetting it. | |
| 2135 | + */ | |
| 2136 | + .flags = HWMOD_EXT_OPT_MAIN_CLK, | |
| 2128 | 2137 | .mpu_irqs = omap44xx_mcpdm_irqs, |
| 2129 | 2138 | .sdma_reqs = omap44xx_mcpdm_sdma_reqs, |
| 2130 | 2139 | .main_clk = "mcpdm_fck", |
| @@ -2681,6 +2690,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = { · 550 unmodified lines | ||
| 2681 | 2690 | .sysc = &omap44xx_ocp2scp_sysc, |
| 2682 | 2691 | }; |
| 2683 | 2692 | |
| 2693 | +/* ocp2scp dev_attr */ | |
| 2694 | +static struct resource omap44xx_usb_phy_and_pll_addrs[] = { | |
| 2695 | + { | |
| 2696 | + .name = "usb_phy", | |
| 2697 | + .start = 0x4a0ad080, | |
| 2698 | + .end = 0x4a0ae000, | |
| 2699 | + .flags = IORESOURCE_MEM, | |
| 2700 | + }, | |
| 2701 | + { | |
| 2702 | + /* XXX: Remove this once control module driver is in place */ | |
| 2703 | + .name = "ctrl_dev", | |
| 2704 | + .start = 0x4a002300, | |
| 2705 | + .end = 0x4a002303, | |
| 2706 | + .flags = IORESOURCE_MEM, | |
| 2707 | + }, | |
| 2708 | + { } | |
| 2709 | +}; | |
| 2710 | + | |
| 2711 | +static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { | |
| 2712 | + { | |
| 2713 | + .drv_name = "omap-usb2", | |
| 2714 | + .res = omap44xx_usb_phy_and_pll_addrs, | |
| 2715 | + }, | |
| 2716 | + { } | |
| 2717 | +}; | |
| 2718 | + | |
| 2684 | 2719 | /* ocp2scp_usb_phy */ |
| 2685 | 2720 | static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { |
| 2686 | 2721 | .name = "ocp2scp_usb_phy", |
| @@ -2694,6 +2729,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { · 7 unmodified lines | ||
| 2694 | 2729 | .modulemode = MODULEMODE_HWCTRL, |
| 2695 | 2730 | }, |
| 2696 | 2731 | }, |
| 2732 | + .dev_attr = ocp2scp_dev_attr, | |
| 2697 | 2733 | }; |
| 2698 | 2734 | |
| 2699 | 2735 | /* |
| @@ -366,7 +366,7 @@ static struct regulator_init_data omap4_clk32kg_idata = { · 365 unmodified lines | ||
| 366 | 366 | }; |
| 367 | 367 | |
| 368 | 368 | static struct regulator_consumer_supply omap4_vdd1_supply[] = { |
| 369 | − REGULATOR_SUPPLY("vcc", "mpu.0"), | |
| 369 | + REGULATOR_SUPPLY("vcc", "cpu0"), | |
| 370 | 370 | }; |
| 371 | 371 | |
| 372 | 372 | static struct regulator_consumer_supply omap4_vdd2_supply[] = { |
| @@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) · 263 unmodified lines | ||
| 264 | 264 | |
| 265 | 265 | if (initialized) { |
| 266 | 266 | if (voltdm->pmic->i2c_high_speed != i2c_high_speed) |
| 267 | − pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).", | |
| 267 | + pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n", | |
| 268 | 268 | __func__, voltdm->name, i2c_high_speed); |
| 269 | 269 | return; |
| 270 | 270 | } |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/mfd/asic3.h> |
| 29 | 29 | #include <linux/mtd/physmap.h> |
| 30 | 30 | #include <linux/pda_power.h> |
| 31 | +#include <linux/pwm.h> | |
| 31 | 32 | #include <linux/pwm_backlight.h> |
| 32 | 33 | #include <linux/regulator/driver.h> |
| 33 | 34 | #include <linux/regulator/gpio-regulator.h> |
| @@ -556,7 +557,7 @@ static struct platform_device hx4700_lcd = { · 522 unmodified lines | ||
| 556 | 557 | */ |
| 557 | 558 | |
| 558 | 559 | static struct platform_pwm_backlight_data backlight_data = { |
| 559 | − .pwm_id = 1, | |
| 560 | + .pwm_id = -1, /* Superseded by pwm_lookup */ | |
| 560 | 561 | .max_brightness = 200, |
| 561 | 562 | .dft_brightness = 100, |
| 562 | 563 | .pwm_period_ns = 30923, |
| @@ -571,6 +572,10 @@ static struct platform_device backlight = { · 8 unmodified lines | ||
| 571 | 572 | }, |
| 572 | 573 | }; |
| 573 | 574 | |
| 575 | +static struct pwm_lookup hx4700_pwm_lookup[] = { | |
| 576 | + PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL), | |
| 577 | +}; | |
| 578 | + | |
| 574 | 579 | /* |
| 575 | 580 | * USB "Transceiver" |
| 576 | 581 | */ |
| @@ -872,6 +877,7 @@ static void __init hx4700_init(void) · 295 unmodified lines | ||
| 872 | 877 | pxa_set_stuart_info(NULL); |
| 873 | 878 | |
| 874 | 879 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
| 880 | + pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup)); | |
| 875 | 881 | |
| 876 | 882 | pxa_set_ficp_info(&ficp_info); |
| 877 | 883 | pxa27x_set_i2c_power_info(NULL); |
| @@ -86,10 +86,7 @@ static void spitz_discharge1(int on) · 85 unmodified lines | ||
| 86 | 86 | gpio_set_value(SPITZ_GPIO_LED_GREEN, on); |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | −static unsigned long gpio18_config[] = { | |
| 90 | − GPIO18_RDY, | |
| 91 | − GPIO18_GPIO, | |
| 92 | −}; | |
| 89 | +static unsigned long gpio18_config = GPIO18_GPIO; | |
| 93 | 90 | |
| 94 | 91 | static void spitz_presuspend(void) |
| 95 | 92 | { |
| @@ -112,7 +109,7 @@ static void spitz_presuspend(void) · 16 unmodified lines | ||
| 112 | 109 | PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; |
| 113 | 110 | PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0); |
| 114 | 111 | |
| 115 | − pxa2xx_mfp_config(&gpio18_config[0], 1); | |
| 112 | + pxa2xx_mfp_config(&gpio18_config, 1); | |
| 116 | 113 | gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown"); |
| 117 | 114 | gpio_free(18); |
| 118 | 115 | |
| @@ -131,7 +128,6 @@ static void spitz_presuspend(void) · 12 unmodified lines | ||
| 131 | 128 | |
| 132 | 129 | static void spitz_postsuspend(void) |
| 133 | 130 | { |
| 134 | − pxa2xx_mfp_config(&gpio18_config[1], 1); | |
| 135 | 131 | } |
| 136 | 132 | |
| 137 | 133 | static int spitz_should_wakeup(unsigned int resume_on_alarm) |
| @@ -745,7 +745,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, · 744 unmodified lines | ||
| 745 | 745 | static int |
| 746 | 746 | do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) |
| 747 | 747 | { |
| 748 | − union offset_union offset; | |
| 748 | + union offset_union uninitialized_var(offset); | |
| 749 | 749 | unsigned long instr = 0, instrptr; |
| 750 | 750 | int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); |
| 751 | 751 | unsigned int type; |
| @@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm { · 442 unmodified lines | ||
| 443 | 443 | * in order to complete the reset. Optional clocks will be disabled |
| 444 | 444 | * again after the reset. |
| 445 | 445 | * HWMOD_16BIT_REG: Module has 16bit registers |
| 446 | + * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for | |
| 447 | + * this IP block comes from an off-chip source and is not always | |
| 448 | + * enabled. This prevents the hwmod code from being able to | |
| 449 | + * enable and reset the IP block early. XXX Eventually it should | |
| 450 | + * be possible to query the clock framework for this information. | |
| 446 | 451 | */ |
| 447 | 452 | #define HWMOD_SWSUP_SIDLE (1 << 0) |
| 448 | 453 | #define HWMOD_SWSUP_MSTANDBY (1 << 1) |
| @@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm { · 4 unmodified lines | ||
| 453 | 458 | #define HWMOD_NO_IDLEST (1 << 6) |
| 454 | 459 | #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) |
| 455 | 460 | #define HWMOD_16BIT_REG (1 << 8) |
| 461 | +#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) | |
| 456 | 462 | |
| 457 | 463 | /* |
| 458 | 464 | * omap_hwmod._int_flags definitions |
| @@ -5,6 +5,6 @@ · 4 unmodified lines | ||
| 5 | 5 | # |
| 6 | 6 | |
| 7 | 7 | include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types |
| 8 | − $(kecho) ' Generating $@' | |
| 8 | + @$(kecho) ' Generating $@' | |
| 9 | 9 | @mkdir -p $(dir $@) |
| 10 | 10 | $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } |
| @@ -701,11 +701,14 @@ static int __init vfp_init(void) · 700 unmodified lines | ||
| 701 | 701 | elf_hwcap |= HWCAP_VFPv3; |
| 702 | 702 | |
| 703 | 703 | /* |
| 704 | − * Check for VFPv3 D16. CPUs in this configuration | |
| 705 | − * only have 16 x 64bit registers. | |
| 704 | + * Check for VFPv3 D16 and VFPv4 D16. CPUs in | |
| 705 | + * this configuration only have 16 x 64bit | |
| 706 | + * registers. | |
| 706 | 707 | */ |
| 707 | 708 | if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1) |
| 708 | − elf_hwcap |= HWCAP_VFPv3D16; | |
| 709 | + elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */ | |
| 710 | + else | |
| 711 | + elf_hwcap |= HWCAP_VFPD32; | |
| 709 | 712 | } |
| 710 | 713 | #endif |
| 711 | 714 | /* |
| @@ -166,3 +166,14 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) · 165 unmodified lines | ||
| 166 | 166 | *pages = NULL; |
| 167 | 167 | } |
| 168 | 168 | EXPORT_SYMBOL_GPL(free_xenballooned_pages); |
| 169 | + | |
| 170 | +/* In the hypervisor.S file. */ | |
| 171 | +EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); | |
| 172 | +EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); | |
| 173 | +EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version); | |
| 174 | +EXPORT_SYMBOL_GPL(HYPERVISOR_console_io); | |
| 175 | +EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op); | |
| 176 | +EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op); | |
| 177 | +EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op); | |
| 178 | +EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); | |
| 179 | +EXPORT_SYMBOL_GPL(privcmd_call); | |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | config ARM64 |
| 2 | 2 | def_bool y |
| 3 | 3 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
| 4 | + select ARCH_WANT_COMPAT_IPC_PARSE_VERSION | |
| 4 | 5 | select GENERIC_CLOCKEVENTS |
| 5 | 6 | select GENERIC_HARDIRQS_NO_DEPRECATED |
| 6 | 7 | select GENERIC_IOMAP |
| @@ -25,12 +25,10 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <asm/user.h> |
| 26 | 26 | |
| 27 | 27 | typedef unsigned long elf_greg_t; |
| 28 | −typedef unsigned long elf_freg_t[3]; | |
| 29 | 28 | |
| 30 | 29 | #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) |
| 31 | 30 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; |
| 32 | − | |
| 33 | −typedef struct user_fp elf_fpregset_t; | |
| 31 | +typedef struct user_fpsimd_state elf_fpregset_t; | |
| 34 | 32 | |
| 35 | 33 | #define EM_AARCH64 183 |
| 36 | 34 | |
| @@ -87,7 +85,6 @@ typedef struct user_fp elf_fpregset_t; · 50 unmodified lines | ||
| 87 | 85 | #define R_AARCH64_MOVW_PREL_G2_NC 292 |
| 88 | 86 | #define R_AARCH64_MOVW_PREL_G3 293 |
| 89 | 87 | |
| 90 | − | |
| 91 | 88 | /* |
| 92 | 89 | * These are used to set parameters in the core dumps. |
| 93 | 90 | */ |
| @@ -25,9 +25,8 @@ · 24 unmodified lines | ||
| 25 | 25 | * - FPSR and FPCR |
| 26 | 26 | * - 32 128-bit data registers |
| 27 | 27 | * |
| 28 | − * Note that user_fp forms a prefix of this structure, which is relied | |
| 29 | − * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must | |
| 30 | − * form a prefix of struct fpsimd_state. | |
| 28 | + * Note that user_fpsimd forms a prefix of this structure, which is | |
| 29 | + * relied upon in the ptrace FP/SIMD accessors. | |
| 31 | 30 | */ |
| 32 | 31 | struct fpsimd_state { |
| 33 | 32 | union { |
| @@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) · 113 unmodified lines | ||
| 114 | 114 | * I/O port access primitives. |
| 115 | 115 | */ |
| 116 | 116 | #define IO_SPACE_LIMIT 0xffff |
| 117 | −#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL) | |
| 117 | +#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M)) | |
| 118 | 118 | |
| 119 | 119 | static inline u8 inb(unsigned long addr) |
| 120 | 120 | { |
| @@ -222,12 +222,12 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot · 101 unmodified lines | ||
| 222 | 222 | extern void __iounmap(volatile void __iomem *addr); |
| 223 | 223 | |
| 224 | 224 | #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY) |
| 225 | −#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) | |
| 225 | +#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) | |
| 226 | 226 | #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) |
| 227 | 227 | |
| 228 | −#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) | |
| 229 | −#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) | |
| 230 | −#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC) | |
| 228 | +#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) | |
| 229 | +#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) | |
| 230 | +#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) | |
| 231 | 231 | #define iounmap __iounmap |
| 232 | 232 | |
| 233 | 233 | #define ARCH_HAS_IOREMAP_WC |
| @@ -38,7 +38,8 @@ · 37 unmodified lines | ||
| 38 | 38 | #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) |
| 39 | 39 | #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) |
| 40 | 40 | #define PMD_SECT_NG (_AT(pmdval_t, 1) << 11) |
| 41 | −#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) | |
| 41 | +#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53) | |
| 42 | +#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54) | |
| 42 | 43 | |
| 43 | 44 | /* |
| 44 | 45 | * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). |
| @@ -57,7 +58,8 @@ · 12 unmodified lines | ||
| 57 | 58 | #define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ |
| 58 | 59 | #define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ |
| 59 | 60 | #define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */ |
| 60 | −#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ | |
| 61 | +#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ | |
| 62 | +#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */ | |
| 61 | 63 | |
| 62 | 64 | /* |
| 63 | 65 | * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). |
| @@ -62,23 +62,23 @@ extern pgprot_t pgprot_default; · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | #define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) |
| 64 | 64 | |
| 65 | −#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY) | |
| 66 | −#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN) | |
| 67 | −#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG) | |
| 68 | −#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 69 | −#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) | |
| 70 | −#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 71 | −#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) | |
| 72 | −#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY) | |
| 73 | −#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY) | |
| 74 | − | |
| 75 | −#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 76 | −#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN) | |
| 77 | −#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG) | |
| 78 | −#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 79 | −#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) | |
| 80 | −#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 81 | −#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) | |
| 65 | +#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 66 | +#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) | |
| 67 | +#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) | |
| 68 | +#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 69 | +#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | |
| 70 | +#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 71 | +#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | |
| 72 | +#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) | |
| 73 | +#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) | |
| 74 | + | |
| 75 | +#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 76 | +#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) | |
| 77 | +#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) | |
| 78 | +#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 79 | +#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | |
| 80 | +#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 81 | +#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | |
| 82 | 82 | |
| 83 | 83 | #endif /* __ASSEMBLY__ */ |
| 84 | 84 | |
| @@ -130,10 +130,10 @@ extern struct page *empty_zero_page; · 45 unmodified lines | ||
| 130 | 130 | #define pte_young(pte) (pte_val(pte) & PTE_AF) |
| 131 | 131 | #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) |
| 132 | 132 | #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) |
| 133 | −#define pte_exec(pte) (!(pte_val(pte) & PTE_XN)) | |
| 133 | +#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) | |
| 134 | 134 | |
| 135 | 135 | #define pte_present_exec_user(pte) \ |
| 136 | − ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \ | |
| 136 | + ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \ | |
| 137 | 137 | (PTE_VALID | PTE_USER)) |
| 138 | 138 | |
| 139 | 139 | #define PTE_BIT_FUNC(fn,op) \ |
| @@ -262,7 +262,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) · 122 unmodified lines | ||
| 262 | 262 | |
| 263 | 263 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
| 264 | 264 | { |
| 265 | − const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY; | |
| 265 | + const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY; | |
| 266 | 266 | pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); |
| 267 | 267 | return pte; |
| 268 | 268 | } |
| @@ -43,6 +43,8 @@ · 42 unmodified lines | ||
| 43 | 43 | #else |
| 44 | 44 | #define STACK_TOP STACK_TOP_MAX |
| 45 | 45 | #endif /* CONFIG_COMPAT */ |
| 46 | + | |
| 47 | +#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK | |
| 46 | 48 | #endif /* __KERNEL__ */ |
| 47 | 49 | |
| 48 | 50 | struct debug_info { |
| @@ -14,7 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | 15 | */ |
| 16 | 16 | #ifdef CONFIG_COMPAT |
| 17 | −#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION | |
| 18 | 17 | #define __ARCH_WANT_COMPAT_STAT64 |
| 19 | 18 | #define __ARCH_WANT_SYS_GETHOSTNAME |
| 20 | 19 | #define __ARCH_WANT_SYS_PAUSE |
| @@ -613,17 +613,11 @@ enum armv8_pmuv3_perf_types { · 612 unmodified lines | ||
| 613 | 613 | ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19, |
| 614 | 614 | ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A, |
| 615 | 615 | ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D, |
| 616 | − | |
| 617 | − /* | |
| 618 | − * This isn't an architected event. | |
| 619 | − * We detect this event number and use the cycle counter instead. | |
| 620 | − */ | |
| 621 | − ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF, | |
| 622 | 616 | }; |
| 623 | 617 | |
| 624 | 618 | /* PMUv3 HW events mapping. */ |
| 625 | 619 | static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { |
| 626 | − [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, | |
| 620 | + [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES, | |
| 627 | 621 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, |
| 628 | 622 | [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, |
| 629 | 623 | [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, |
| @@ -1106,7 +1100,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, · 476 unmodified lines | ||
| 1106 | 1100 | unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT; |
| 1107 | 1101 | |
| 1108 | 1102 | /* Always place a cycle counter into the cycle counter. */ |
| 1109 | − if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { | |
| 1103 | + if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) { | |
| 1110 | 1104 | if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) |
| 1111 | 1105 | return -EAGAIN; |
| 1112 | 1106 | |
| @@ -309,24 +309,6 @@ struct task_struct *__switch_to(struct task_struct *prev, · 308 unmodified lines | ||
| 309 | 309 | return last; |
| 310 | 310 | } |
| 311 | 311 | |
| 312 | −/* | |
| 313 | − * Fill in the task's elfregs structure for a core dump. | |
| 314 | − */ | |
| 315 | −int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs) | |
| 316 | −{ | |
| 317 | − elf_core_copy_regs(elfregs, task_pt_regs(t)); | |
| 318 | − return 1; | |
| 319 | −} | |
| 320 | − | |
| 321 | −/* | |
| 322 | − * fill in the fpe structure for a core dump... | |
| 323 | − */ | |
| 324 | −int dump_fpu (struct pt_regs *regs, struct user_fp *fp) | |
| 325 | −{ | |
| 326 | − return 0; | |
| 327 | −} | |
| 328 | −EXPORT_SYMBOL(dump_fpu); | |
| 329 | − | |
| 330 | 312 | /* |
| 331 | 313 | * Shuffle the argument into the correct register before calling the |
| 332 | 314 | * thread function. x1 is the thread argument, x2 is the pointer to |
| @@ -211,8 +211,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) · 210 unmodified lines | ||
| 211 | 211 | * before we continue. |
| 212 | 212 | */ |
| 213 | 213 | set_cpu_online(cpu, true); |
| 214 | − while (!cpu_active(cpu)) | |
| 215 | − cpu_relax(); | |
| 214 | + complete(&cpu_running); | |
| 216 | 215 | |
| 217 | 216 | /* |
| 218 | 217 | * OK, it's off to the idle thread for us |
| @@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) · 79 unmodified lines | ||
| 80 | 80 | #ifdef CONFIG_ZONE_DMA32 |
| 81 | 81 | /* 4GB maximum for 32-bit only capable devices */ |
| 82 | 82 | max_dma32 = min(max, MAX_DMA32_PFN); |
| 83 | − zone_size[ZONE_DMA32] = max_dma32 - min; | |
| 83 | + zone_size[ZONE_DMA32] = max(min, max_dma32) - min; | |
| 84 | 84 | #endif |
| 85 | 85 | zone_size[ZONE_NORMAL] = max - max_dma32; |
| 86 | 86 | |
| @@ -2,7 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | #define __ARCH_H8300_CACHE_H |
| 3 | 3 | |
| 4 | 4 | /* bytes per L1 cache line */ |
| 5 | −#define L1_CACHE_BYTES 4 | |
| 5 | +#define L1_CACHE_SHIFT 2 | |
| 6 | +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | |
| 6 | 7 | |
| 7 | 8 | /* m68k-elf-gcc 2.95.2 doesn't like these */ |
| 8 | 9 | |
| @@ -637,7 +637,6 @@ mem_init (void) · 636 unmodified lines | ||
| 637 | 637 | |
| 638 | 638 | high_memory = __va(max_low_pfn * PAGE_SIZE); |
| 639 | 639 | |
| 640 | − reset_zone_present_pages(); | |
| 641 | 640 | for_each_online_pgdat(pgdat) |
| 642 | 641 | if (pgdat->bdata->node_bootmem_map) |
| 643 | 642 | totalram_pages += free_all_bootmem_node(pgdat); |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | * measurement, and debugging facilities. |
| 31 | 31 | */ |
| 32 | 32 | |
| 33 | +#include <linux/irqflags.h> | |
| 33 | 34 | #include <asm/octeon/cvmx.h> |
| 34 | 35 | #include <asm/octeon/cvmx-l2c.h> |
| 35 | 36 | #include <asm/octeon/cvmx-spinlock.h> |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | */ |
| 12 | 12 | #include <linux/init.h> |
| 13 | 13 | #include <linux/kernel.h> |
| 14 | +#include <linux/irqflags.h> | |
| 14 | 15 | |
| 15 | 16 | #include <asm/bcache.h> |
| 16 | 17 | |
| @@ -14,7 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | #endif |
| 15 | 15 | |
| 16 | 16 | #include <linux/compiler.h> |
| 17 | −#include <linux/irqflags.h> | |
| 18 | 17 | #include <linux/types.h> |
| 19 | 18 | #include <asm/barrier.h> |
| 20 | 19 | #include <asm/byteorder.h> /* sigh ... */ |
| @@ -44,6 +43,24 @@ · 23 unmodified lines | ||
| 44 | 43 | #define smp_mb__before_clear_bit() smp_mb__before_llsc() |
| 45 | 44 | #define smp_mb__after_clear_bit() smp_llsc_mb() |
| 46 | 45 | |
| 46 | + | |
| 47 | +/* | |
| 48 | + * These are the "slower" versions of the functions and are in bitops.c. | |
| 49 | + * These functions call raw_local_irq_{save,restore}(). | |
| 50 | + */ | |
| 51 | +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr); | |
| 52 | +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr); | |
| 53 | +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr); | |
| 54 | +int __mips_test_and_set_bit(unsigned long nr, | |
| 55 | + volatile unsigned long *addr); | |
| 56 | +int __mips_test_and_set_bit_lock(unsigned long nr, | |
| 57 | + volatile unsigned long *addr); | |
| 58 | +int __mips_test_and_clear_bit(unsigned long nr, | |
| 59 | + volatile unsigned long *addr); | |
| 60 | +int __mips_test_and_change_bit(unsigned long nr, | |
| 61 | + volatile unsigned long *addr); | |
| 62 | + | |
| 63 | + | |
| 47 | 64 | /* |
| 48 | 65 | * set_bit - Atomically set a bit in memory |
| 49 | 66 | * @nr: the bit to set |
| @@ -57,7 +74,7 @@ · 7 unmodified lines | ||
| 57 | 74 | static inline void set_bit(unsigned long nr, volatile unsigned long *addr) |
| 58 | 75 | { |
| 59 | 76 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| 60 | − unsigned short bit = nr & SZLONG_MASK; | |
| 77 | + int bit = nr & SZLONG_MASK; | |
| 61 | 78 | unsigned long temp; |
| 62 | 79 | |
| 63 | 80 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| @@ -92,17 +109,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) · 28 unmodified lines | ||
| 92 | 109 | : "=&r" (temp), "+m" (*m) |
| 93 | 110 | : "ir" (1UL << bit)); |
| 94 | 111 | } while (unlikely(!temp)); |
| 95 | − } else { | |
| 96 | − volatile unsigned long *a = addr; | |
| 97 | − unsigned long mask; | |
| 98 | − unsigned long flags; | |
| 99 | − | |
| 100 | − a += nr >> SZLONG_LOG; | |
| 101 | − mask = 1UL << bit; | |
| 102 | − raw_local_irq_save(flags); | |
| 103 | − *a |= mask; | |
| 104 | − raw_local_irq_restore(flags); | |
| 105 | − } | |
| 112 | + } else | |
| 113 | + __mips_set_bit(nr, addr); | |
| 106 | 114 | } |
| 107 | 115 | |
| 108 | 116 | /* |
| @@ -118,7 +126,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) · 9 unmodified lines | ||
| 118 | 126 | static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) |
| 119 | 127 | { |
| 120 | 128 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| 121 | − unsigned short bit = nr & SZLONG_MASK; | |
| 129 | + int bit = nr & SZLONG_MASK; | |
| 122 | 130 | unsigned long temp; |
| 123 | 131 | |
| 124 | 132 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| @@ -153,17 +161,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) · 28 unmodified lines | ||
| 153 | 161 | : "=&r" (temp), "+m" (*m) |
| 154 | 162 | : "ir" (~(1UL << bit))); |
| 155 | 163 | } while (unlikely(!temp)); |
| 156 | − } else { | |
| 157 | − volatile unsigned long *a = addr; | |
| 158 | − unsigned long mask; | |
| 159 | − unsigned long flags; | |
| 160 | − | |
| 161 | − a += nr >> SZLONG_LOG; | |
| 162 | − mask = 1UL << bit; | |
| 163 | − raw_local_irq_save(flags); | |
| 164 | − *a &= ~mask; | |
| 165 | − raw_local_irq_restore(flags); | |
| 166 | − } | |
| 164 | + } else | |
| 165 | + __mips_clear_bit(nr, addr); | |
| 167 | 166 | } |
| 168 | 167 | |
| 169 | 168 | /* |
| @@ -191,7 +190,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad · 21 unmodified lines | ||
| 191 | 190 | */ |
| 192 | 191 | static inline void change_bit(unsigned long nr, volatile unsigned long *addr) |
| 193 | 192 | { |
| 194 | − unsigned short bit = nr & SZLONG_MASK; | |
| 193 | + int bit = nr & SZLONG_MASK; | |
| 195 | 194 | |
| 196 | 195 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| 197 | 196 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| @@ -220,17 +219,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) · 22 unmodified lines | ||
| 220 | 219 | : "=&r" (temp), "+m" (*m) |
| 221 | 220 | : "ir" (1UL << bit)); |
| 222 | 221 | } while (unlikely(!temp)); |
| 223 | − } else { | |
| 224 | − volatile unsigned long *a = addr; | |
| 225 | − unsigned long mask; | |
| 226 | − unsigned long flags; | |
| 227 | − | |
| 228 | − a += nr >> SZLONG_LOG; | |
| 229 | − mask = 1UL << bit; | |
| 230 | − raw_local_irq_save(flags); | |
| 231 | − *a ^= mask; | |
| 232 | − raw_local_irq_restore(flags); | |
| 233 | − } | |
| 222 | + } else | |
| 223 | + __mips_change_bit(nr, addr); | |
| 234 | 224 | } |
| 235 | 225 | |
| 236 | 226 | /* |
| @@ -244,7 +234,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) · 7 unmodified lines | ||
| 244 | 234 | static inline int test_and_set_bit(unsigned long nr, |
| 245 | 235 | volatile unsigned long *addr) |
| 246 | 236 | { |
| 247 | − unsigned short bit = nr & SZLONG_MASK; | |
| 237 | + int bit = nr & SZLONG_MASK; | |
| 248 | 238 | unsigned long res; |
| 249 | 239 | |
| 250 | 240 | smp_mb__before_llsc(); |
| @@ -281,18 +271,8 @@ static inline int test_and_set_bit(unsigned long nr, · 30 unmodified lines | ||
| 281 | 271 | } while (unlikely(!res)); |
| 282 | 272 | |
| 283 | 273 | res = temp & (1UL << bit); |
| 284 | − } else { | |
| 285 | − volatile unsigned long *a = addr; | |
| 286 | − unsigned long mask; | |
| 287 | − unsigned long flags; | |
| 288 | − | |
| 289 | − a += nr >> SZLONG_LOG; | |
| 290 | − mask = 1UL << bit; | |
| 291 | − raw_local_irq_save(flags); | |
| 292 | − res = (mask & *a); | |
| 293 | − *a |= mask; | |
| 294 | − raw_local_irq_restore(flags); | |
| 295 | − } | |
| 274 | + } else | |
| 275 | + res = __mips_test_and_set_bit(nr, addr); | |
| 296 | 276 | |
| 297 | 277 | smp_llsc_mb(); |
| 298 | 278 | |
| @@ -310,7 +290,7 @@ static inline int test_and_set_bit(unsigned long nr, · 11 unmodified lines | ||
| 310 | 290 | static inline int test_and_set_bit_lock(unsigned long nr, |
| 311 | 291 | volatile unsigned long *addr) |
| 312 | 292 | { |
| 313 | − unsigned short bit = nr & SZLONG_MASK; | |
| 293 | + int bit = nr & SZLONG_MASK; | |
| 314 | 294 | unsigned long res; |
| 315 | 295 | |
| 316 | 296 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| @@ -345,18 +325,8 @@ static inline int test_and_set_bit_lock(unsigned long nr, · 28 unmodified lines | ||
| 345 | 325 | } while (unlikely(!res)); |
| 346 | 326 | |
| 347 | 327 | res = temp & (1UL << bit); |
| 348 | − } else { | |
| 349 | − volatile unsigned long *a = addr; | |
| 350 | − unsigned long mask; | |
| 351 | − unsigned long flags; | |
| 352 | − | |
| 353 | − a += nr >> SZLONG_LOG; | |
| 354 | − mask = 1UL << bit; | |
| 355 | − raw_local_irq_save(flags); | |
| 356 | − res = (mask & *a); | |
| 357 | − *a |= mask; | |
| 358 | − raw_local_irq_restore(flags); | |
| 359 | − } | |
| 328 | + } else | |
| 329 | + res = __mips_test_and_set_bit_lock(nr, addr); | |
| 360 | 330 | |
| 361 | 331 | smp_llsc_mb(); |
| 362 | 332 | |
| @@ -373,7 +343,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, · 10 unmodified lines | ||
| 373 | 343 | static inline int test_and_clear_bit(unsigned long nr, |
| 374 | 344 | volatile unsigned long *addr) |
| 375 | 345 | { |
| 376 | − unsigned short bit = nr & SZLONG_MASK; | |
| 346 | + int bit = nr & SZLONG_MASK; | |
| 377 | 347 | unsigned long res; |
| 378 | 348 | |
| 379 | 349 | smp_mb__before_llsc(); |
| @@ -428,18 +398,8 @@ static inline int test_and_clear_bit(unsigned long nr, · 48 unmodified lines | ||
| 428 | 398 | } while (unlikely(!res)); |
| 429 | 399 | |
| 430 | 400 | res = temp & (1UL << bit); |
| 431 | − } else { | |
| 432 | − volatile unsigned long *a = addr; | |
| 433 | − unsigned long mask; | |
| 434 | − unsigned long flags; | |
| 435 | − | |
| 436 | − a += nr >> SZLONG_LOG; | |
| 437 | − mask = 1UL << bit; | |
| 438 | − raw_local_irq_save(flags); | |
| 439 | − res = (mask & *a); | |
| 440 | − *a &= ~mask; | |
| 441 | − raw_local_irq_restore(flags); | |
| 442 | − } | |
| 401 | + } else | |
| 402 | + res = __mips_test_and_clear_bit(nr, addr); | |
| 443 | 403 | |
| 444 | 404 | smp_llsc_mb(); |
| 445 | 405 | |
| @@ -457,7 +417,7 @@ static inline int test_and_clear_bit(unsigned long nr, · 11 unmodified lines | ||
| 457 | 417 | static inline int test_and_change_bit(unsigned long nr, |
| 458 | 418 | volatile unsigned long *addr) |
| 459 | 419 | { |
| 460 | − unsigned short bit = nr & SZLONG_MASK; | |
| 420 | + int bit = nr & SZLONG_MASK; | |
| 461 | 421 | unsigned long res; |
| 462 | 422 | |
| 463 | 423 | smp_mb__before_llsc(); |
| @@ -494,18 +454,8 @@ static inline int test_and_change_bit(unsigned long nr, · 30 unmodified lines | ||
| 494 | 454 | } while (unlikely(!res)); |
| 495 | 455 | |
| 496 | 456 | res = temp & (1UL << bit); |
| 497 | − } else { | |
| 498 | − volatile unsigned long *a = addr; | |
| 499 | − unsigned long mask; | |
| 500 | − unsigned long flags; | |
| 501 | − | |
| 502 | − a += nr >> SZLONG_LOG; | |
| 503 | − mask = 1UL << bit; | |
| 504 | − raw_local_irq_save(flags); | |
| 505 | − res = (mask & *a); | |
| 506 | − *a ^= mask; | |
| 507 | − raw_local_irq_restore(flags); | |
| 508 | − } | |
| 457 | + } else | |
| 458 | + res = __mips_test_and_change_bit(nr, addr); | |
| 509 | 459 | |
| 510 | 460 | smp_llsc_mb(); |
| 511 | 461 | |
| @@ -290,7 +290,7 @@ struct compat_shmid64_ds { · 289 unmodified lines | ||
| 290 | 290 | |
| 291 | 291 | static inline int is_compat_task(void) |
| 292 | 292 | { |
| 293 | − return test_thread_flag(TIF_32BIT); | |
| 293 | + return test_thread_flag(TIF_32BIT_ADDR); | |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | 296 | #endif /* _ASM_COMPAT_H */ |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/compiler.h> |
| 16 | 16 | #include <linux/kernel.h> |
| 17 | 17 | #include <linux/types.h> |
| 18 | +#include <linux/irqflags.h> | |
| 18 | 19 | |
| 19 | 20 | #include <asm/addrspace.h> |
| 20 | 21 | #include <asm/bug.h> |
| @@ -16,83 +16,13 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/compiler.h> |
| 17 | 17 | #include <asm/hazards.h> |
| 18 | 18 | |
| 19 | −__asm__( | |
| 20 | − " .macro arch_local_irq_enable \n" | |
| 21 | − " .set push \n" | |
| 22 | − " .set reorder \n" | |
| 23 | − " .set noat \n" | |
| 24 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 25 | − " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" | |
| 26 | − " ori $1, 0x400 \n" | |
| 27 | − " xori $1, 0x400 \n" | |
| 28 | − " mtc0 $1, $2, 1 \n" | |
| 29 | −#elif defined(CONFIG_CPU_MIPSR2) | |
| 30 | − " ei \n" | |
| 31 | −#else | |
| 32 | − " mfc0 $1,$12 \n" | |
| 33 | − " ori $1,0x1f \n" | |
| 34 | − " xori $1,0x1e \n" | |
| 35 | − " mtc0 $1,$12 \n" | |
| 36 | −#endif | |
| 37 | − " irq_enable_hazard \n" | |
| 38 | − " .set pop \n" | |
| 39 | − " .endm"); | |
| 19 | +#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) | |
| 40 | 20 | |
| 41 | −extern void smtc_ipi_replay(void); | |
| 42 | − | |
| 43 | −static inline void arch_local_irq_enable(void) | |
| 44 | −{ | |
| 45 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 46 | − /* | |
| 47 | − * SMTC kernel needs to do a software replay of queued | |
| 48 | − * IPIs, at the cost of call overhead on each local_irq_enable() | |
| 49 | − */ | |
| 50 | − smtc_ipi_replay(); | |
| 51 | −#endif | |
| 52 | − __asm__ __volatile__( | |
| 53 | − "arch_local_irq_enable" | |
| 54 | − : /* no outputs */ | |
| 55 | − : /* no inputs */ | |
| 56 | − : "memory"); | |
| 57 | −} | |
| 58 | − | |
| 59 | − | |
| 60 | −/* | |
| 61 | − * For cli() we have to insert nops to make sure that the new value | |
| 62 | − * has actually arrived in the status register before the end of this | |
| 63 | − * macro. | |
| 64 | − * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | |
| 65 | − * no nops at all. | |
| 66 | − */ | |
| 67 | −/* | |
| 68 | − * For TX49, operating only IE bit is not enough. | |
| 69 | − * | |
| 70 | − * If mfc0 $12 follows store and the mfc0 is last instruction of a | |
| 71 | − * page and fetching the next instruction causes TLB miss, the result | |
| 72 | − * of the mfc0 might wrongly contain EXL bit. | |
| 73 | − * | |
| 74 | − * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | |
| 75 | − * | |
| 76 | − * Workaround: mask EXL bit of the result or place a nop before mfc0. | |
| 77 | − */ | |
| 78 | 21 | __asm__( |
| 79 | 22 | " .macro arch_local_irq_disable\n" |
| 80 | 23 | " .set push \n" |
| 81 | 24 | " .set noat \n" |
| 82 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 83 | − " mfc0 $1, $2, 1 \n" | |
| 84 | − " ori $1, 0x400 \n" | |
| 85 | − " .set noreorder \n" | |
| 86 | − " mtc0 $1, $2, 1 \n" | |
| 87 | −#elif defined(CONFIG_CPU_MIPSR2) | |
| 88 | 25 | " di \n" |
| 89 | −#else | |
| 90 | − " mfc0 $1,$12 \n" | |
| 91 | − " ori $1,0x1f \n" | |
| 92 | − " xori $1,0x1f \n" | |
| 93 | − " .set noreorder \n" | |
| 94 | − " mtc0 $1,$12 \n" | |
| 95 | −#endif | |
| 96 | 26 | " irq_disable_hazard \n" |
| 97 | 27 | " .set pop \n" |
| 98 | 28 | " .endm \n"); |
| @@ -106,46 +36,14 @@ static inline void arch_local_irq_disable(void) · 7 unmodified lines | ||
| 106 | 36 | : "memory"); |
| 107 | 37 | } |
| 108 | 38 | |
| 109 | −__asm__( | |
| 110 | − " .macro arch_local_save_flags flags \n" | |
| 111 | − " .set push \n" | |
| 112 | − " .set reorder \n" | |
| 113 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 114 | − " mfc0 \\flags, $2, 1 \n" | |
| 115 | −#else | |
| 116 | − " mfc0 \\flags, $12 \n" | |
| 117 | −#endif | |
| 118 | − " .set pop \n" | |
| 119 | − " .endm \n"); | |
| 120 | − | |
| 121 | −static inline unsigned long arch_local_save_flags(void) | |
| 122 | −{ | |
| 123 | − unsigned long flags; | |
| 124 | − asm volatile("arch_local_save_flags %0" : "=r" (flags)); | |
| 125 | − return flags; | |
| 126 | −} | |
| 127 | 39 | |
| 128 | 40 | __asm__( |
| 129 | 41 | " .macro arch_local_irq_save result \n" |
| 130 | 42 | " .set push \n" |
| 131 | 43 | " .set reorder \n" |
| 132 | 44 | " .set noat \n" |
| 133 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 134 | − " mfc0 \\result, $2, 1 \n" | |
| 135 | − " ori $1, \\result, 0x400 \n" | |
| 136 | − " .set noreorder \n" | |
| 137 | − " mtc0 $1, $2, 1 \n" | |
| 138 | − " andi \\result, \\result, 0x400 \n" | |
| 139 | −#elif defined(CONFIG_CPU_MIPSR2) | |
| 140 | 45 | " di \\result \n" |
| 141 | 46 | " andi \\result, 1 \n" |
| 142 | −#else | |
| 143 | − " mfc0 \\result, $12 \n" | |
| 144 | − " ori $1, \\result, 0x1f \n" | |
| 145 | − " xori $1, 0x1f \n" | |
| 146 | − " .set noreorder \n" | |
| 147 | − " mtc0 $1, $12 \n" | |
| 148 | −#endif | |
| 149 | 47 | " irq_disable_hazard \n" |
| 150 | 48 | " .set pop \n" |
| 151 | 49 | " .endm \n"); |
| @@ -160,61 +58,37 @@ static inline unsigned long arch_local_irq_save(void) · 8 unmodified lines | ||
| 160 | 58 | return flags; |
| 161 | 59 | } |
| 162 | 60 | |
| 61 | + | |
| 163 | 62 | __asm__( |
| 164 | 63 | " .macro arch_local_irq_restore flags \n" |
| 165 | 64 | " .set push \n" |
| 166 | 65 | " .set noreorder \n" |
| 167 | 66 | " .set noat \n" |
| 168 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 169 | − "mfc0 $1, $2, 1 \n" | |
| 170 | − "andi \\flags, 0x400 \n" | |
| 171 | − "ori $1, 0x400 \n" | |
| 172 | − "xori $1, 0x400 \n" | |
| 173 | − "or \\flags, $1 \n" | |
| 174 | − "mtc0 \\flags, $2, 1 \n" | |
| 175 | −#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | |
| 67 | +#if defined(CONFIG_IRQ_CPU) | |
| 176 | 68 | /* |
| 177 | 69 | * Slow, but doesn't suffer from a relatively unlikely race |
| 178 | 70 | * condition we're having since days 1. |
| 179 | 71 | */ |
| 180 | 72 | " beqz \\flags, 1f \n" |
| 181 | − " di \n" | |
| 73 | + " di \n" | |
| 182 | 74 | " ei \n" |
| 183 | 75 | "1: \n" |
| 184 | −#elif defined(CONFIG_CPU_MIPSR2) | |
| 76 | +#else | |
| 185 | 77 | /* |
| 186 | 78 | * Fast, dangerous. Life is fun, life is good. |
| 187 | 79 | */ |
| 188 | 80 | " mfc0 $1, $12 \n" |
| 189 | 81 | " ins $1, \\flags, 0, 1 \n" |
| 190 | 82 | " mtc0 $1, $12 \n" |
| 191 | −#else | |
| 192 | − " mfc0 $1, $12 \n" | |
| 193 | − " andi \\flags, 1 \n" | |
| 194 | − " ori $1, 0x1f \n" | |
| 195 | − " xori $1, 0x1f \n" | |
| 196 | − " or \\flags, $1 \n" | |
| 197 | − " mtc0 \\flags, $12 \n" | |
| 198 | 83 | #endif |
| 199 | 84 | " irq_disable_hazard \n" |
| 200 | 85 | " .set pop \n" |
| 201 | 86 | " .endm \n"); |
| 202 | 87 | |
| 203 | − | |
| 204 | 88 | static inline void arch_local_irq_restore(unsigned long flags) |
| 205 | 89 | { |
| 206 | 90 | unsigned long __tmp1; |
| 207 | 91 | |
| 208 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 209 | − /* | |
| 210 | − * SMTC kernel needs to do a software replay of queued | |
| 211 | − * IPIs, at the cost of branch and call overhead on each | |
| 212 | − * local_irq_restore() | |
| 213 | − */ | |
| 214 | − if (unlikely(!(flags & 0x0400))) | |
| 215 | − smtc_ipi_replay(); | |
| 216 | −#endif | |
| 217 | − | |
| 218 | 92 | __asm__ __volatile__( |
| 219 | 93 | "arch_local_irq_restore\t%0" |
| 220 | 94 | : "=r" (__tmp1) |
| @@ -232,6 +106,75 @@ static inline void __arch_local_irq_restore(unsigned long flags) · 11 unmodified lines | ||
| 232 | 106 | : "0" (flags) |
| 233 | 107 | : "memory"); |
| 234 | 108 | } |
| 109 | +#else | |
| 110 | +/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ | |
| 111 | +void arch_local_irq_disable(void); | |
| 112 | +unsigned long arch_local_irq_save(void); | |
| 113 | +void arch_local_irq_restore(unsigned long flags); | |
| 114 | +void __arch_local_irq_restore(unsigned long flags); | |
| 115 | +#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */ | |
| 116 | + | |
| 117 | + | |
| 118 | +__asm__( | |
| 119 | + " .macro arch_local_irq_enable \n" | |
| 120 | + " .set push \n" | |
| 121 | + " .set reorder \n" | |
| 122 | + " .set noat \n" | |
| 123 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 124 | + " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" | |
| 125 | + " ori $1, 0x400 \n" | |
| 126 | + " xori $1, 0x400 \n" | |
| 127 | + " mtc0 $1, $2, 1 \n" | |
| 128 | +#elif defined(CONFIG_CPU_MIPSR2) | |
| 129 | + " ei \n" | |
| 130 | +#else | |
| 131 | + " mfc0 $1,$12 \n" | |
| 132 | + " ori $1,0x1f \n" | |
| 133 | + " xori $1,0x1e \n" | |
| 134 | + " mtc0 $1,$12 \n" | |
| 135 | +#endif | |
| 136 | + " irq_enable_hazard \n" | |
| 137 | + " .set pop \n" | |
| 138 | + " .endm"); | |
| 139 | + | |
| 140 | +extern void smtc_ipi_replay(void); | |
| 141 | + | |
| 142 | +static inline void arch_local_irq_enable(void) | |
| 143 | +{ | |
| 144 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 145 | + /* | |
| 146 | + * SMTC kernel needs to do a software replay of queued | |
| 147 | + * IPIs, at the cost of call overhead on each local_irq_enable() | |
| 148 | + */ | |
| 149 | + smtc_ipi_replay(); | |
| 150 | +#endif | |
| 151 | + __asm__ __volatile__( | |
| 152 | + "arch_local_irq_enable" | |
| 153 | + : /* no outputs */ | |
| 154 | + : /* no inputs */ | |
| 155 | + : "memory"); | |
| 156 | +} | |
| 157 | + | |
| 158 | + | |
| 159 | +__asm__( | |
| 160 | + " .macro arch_local_save_flags flags \n" | |
| 161 | + " .set push \n" | |
| 162 | + " .set reorder \n" | |
| 163 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 164 | + " mfc0 \\flags, $2, 1 \n" | |
| 165 | +#else | |
| 166 | + " mfc0 \\flags, $12 \n" | |
| 167 | +#endif | |
| 168 | + " .set pop \n" | |
| 169 | + " .endm \n"); | |
| 170 | + | |
| 171 | +static inline unsigned long arch_local_save_flags(void) | |
| 172 | +{ | |
| 173 | + unsigned long flags; | |
| 174 | + asm volatile("arch_local_save_flags %0" : "=r" (flags)); | |
| 175 | + return flags; | |
| 176 | +} | |
| 177 | + | |
| 235 | 178 | |
| 236 | 179 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
| 237 | 180 | { |
| @@ -245,7 +188,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) · 7 unmodified lines | ||
| 245 | 188 | #endif |
| 246 | 189 | } |
| 247 | 190 | |
| 248 | −#endif | |
| 191 | +#endif /* #ifndef __ASSEMBLY__ */ | |
| 249 | 192 | |
| 250 | 193 | /* |
| 251 | 194 | * Do the CPU's IRQ-state tracing from assembly code. |
| @@ -112,12 +112,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); · 111 unmodified lines | ||
| 112 | 112 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ |
| 113 | 113 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ |
| 114 | 114 | |
| 115 | −#ifdef CONFIG_MIPS32_O32 | |
| 116 | −#define TIF_32BIT TIF_32BIT_REGS | |
| 117 | −#elif defined(CONFIG_MIPS32_N32) | |
| 118 | −#define TIF_32BIT _TIF_32BIT_ADDR | |
| 119 | −#endif /* CONFIG_MIPS32_O32 */ | |
| 120 | − | |
| 121 | 115 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
| 122 | 116 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
| 123 | 117 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
| @@ -2,8 +2,9 @@ · 1 unmodified line | ||
| 2 | 2 | # Makefile for MIPS-specific library files.. |
| 3 | 3 | # |
| 4 | 4 | |
| 5 | −lib-y += csum_partial.o delay.o memcpy.o memset.o \ | |
| 6 | − strlen_user.o strncpy_user.o strnlen_user.o uncached.o | |
| 5 | +lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ | |
| 6 | + mips-atomic.o strlen_user.o strncpy_user.o \ | |
| 7 | + strnlen_user.o uncached.o | |
| 7 | 8 | |
| 8 | 9 | obj-y += iomap.o |
| 9 | 10 | obj-$(CONFIG_PCI) += iomap-pci.o |
| @@ -0,0 +1,179 @@ | ||
| 1 | +/* | |
| 2 | + * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | + * License. See the file "COPYING" in the main directory of this archive | |
| 4 | + * for more details. | |
| 5 | + * | |
| 6 | + * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) | |
| 7 | + * Copyright (c) 1999, 2000 Silicon Graphics, Inc. | |
| 8 | + */ | |
| 9 | +#include <linux/bitops.h> | |
| 10 | +#include <linux/irqflags.h> | |
| 11 | +#include <linux/export.h> | |
| 12 | + | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * __mips_set_bit - Atomically set a bit in memory. This is called by | |
| 16 | + * set_bit() if it cannot find a faster solution. | |
| 17 | + * @nr: the bit to set | |
| 18 | + * @addr: the address to start counting from | |
| 19 | + */ | |
| 20 | +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr) | |
| 21 | +{ | |
| 22 | + volatile unsigned long *a = addr; | |
| 23 | + unsigned bit = nr & SZLONG_MASK; | |
| 24 | + unsigned long mask; | |
| 25 | + unsigned long flags; | |
| 26 | + | |
| 27 | + a += nr >> SZLONG_LOG; | |
| 28 | + mask = 1UL << bit; | |
| 29 | + raw_local_irq_save(flags); | |
| 30 | + *a |= mask; | |
| 31 | + raw_local_irq_restore(flags); | |
| 32 | +} | |
| 33 | +EXPORT_SYMBOL(__mips_set_bit); | |
| 34 | + | |
| 35 | + | |
| 36 | +/** | |
| 37 | + * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if | |
| 38 | + * it cannot find a faster solution. | |
| 39 | + * @nr: Bit to clear | |
| 40 | + * @addr: Address to start counting from | |
| 41 | + */ | |
| 42 | +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr) | |
| 43 | +{ | |
| 44 | + volatile unsigned long *a = addr; | |
| 45 | + unsigned bit = nr & SZLONG_MASK; | |
| 46 | + unsigned long mask; | |
| 47 | + unsigned long flags; | |
| 48 | + | |
| 49 | + a += nr >> SZLONG_LOG; | |
| 50 | + mask = 1UL << bit; | |
| 51 | + raw_local_irq_save(flags); | |
| 52 | + *a &= ~mask; | |
| 53 | + raw_local_irq_restore(flags); | |
| 54 | +} | |
| 55 | +EXPORT_SYMBOL(__mips_clear_bit); | |
| 56 | + | |
| 57 | + | |
| 58 | +/** | |
| 59 | + * __mips_change_bit - Toggle a bit in memory. This is called by change_bit() | |
| 60 | + * if it cannot find a faster solution. | |
| 61 | + * @nr: Bit to change | |
| 62 | + * @addr: Address to start counting from | |
| 63 | + */ | |
| 64 | +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr) | |
| 65 | +{ | |
| 66 | + volatile unsigned long *a = addr; | |
| 67 | + unsigned bit = nr & SZLONG_MASK; | |
| 68 | + unsigned long mask; | |
| 69 | + unsigned long flags; | |
| 70 | + | |
| 71 | + a += nr >> SZLONG_LOG; | |
| 72 | + mask = 1UL << bit; | |
| 73 | + raw_local_irq_save(flags); | |
| 74 | + *a ^= mask; | |
| 75 | + raw_local_irq_restore(flags); | |
| 76 | +} | |
| 77 | +EXPORT_SYMBOL(__mips_change_bit); | |
| 78 | + | |
| 79 | + | |
| 80 | +/** | |
| 81 | + * __mips_test_and_set_bit - Set a bit and return its old value. This is | |
| 82 | + * called by test_and_set_bit() if it cannot find a faster solution. | |
| 83 | + * @nr: Bit to set | |
| 84 | + * @addr: Address to count from | |
| 85 | + */ | |
| 86 | +int __mips_test_and_set_bit(unsigned long nr, | |
| 87 | + volatile unsigned long *addr) | |
| 88 | +{ | |
| 89 | + volatile unsigned long *a = addr; | |
| 90 | + unsigned bit = nr & SZLONG_MASK; | |
| 91 | + unsigned long mask; | |
| 92 | + unsigned long flags; | |
| 93 | + unsigned long res; | |
| 94 | + | |
| 95 | + a += nr >> SZLONG_LOG; | |
| 96 | + mask = 1UL << bit; | |
| 97 | + raw_local_irq_save(flags); | |
| 98 | + res = (mask & *a); | |
| 99 | + *a |= mask; | |
| 100 | + raw_local_irq_restore(flags); | |
| 101 | + return res; | |
| 102 | +} | |
| 103 | +EXPORT_SYMBOL(__mips_test_and_set_bit); | |
| 104 | + | |
| 105 | + | |
| 106 | +/** | |
| 107 | + * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is | |
| 108 | + * called by test_and_set_bit_lock() if it cannot find a faster solution. | |
| 109 | + * @nr: Bit to set | |
| 110 | + * @addr: Address to count from | |
| 111 | + */ | |
| 112 | +int __mips_test_and_set_bit_lock(unsigned long nr, | |
| 113 | + volatile unsigned long *addr) | |
| 114 | +{ | |
| 115 | + volatile unsigned long *a = addr; | |
| 116 | + unsigned bit = nr & SZLONG_MASK; | |
| 117 | + unsigned long mask; | |
| 118 | + unsigned long flags; | |
| 119 | + unsigned long res; | |
| 120 | + | |
| 121 | + a += nr >> SZLONG_LOG; | |
| 122 | + mask = 1UL << bit; | |
| 123 | + raw_local_irq_save(flags); | |
| 124 | + res = (mask & *a); | |
| 125 | + *a |= mask; | |
| 126 | + raw_local_irq_restore(flags); | |
| 127 | + return res; | |
| 128 | +} | |
| 129 | +EXPORT_SYMBOL(__mips_test_and_set_bit_lock); | |
| 130 | + | |
| 131 | + | |
| 132 | +/** | |
| 133 | + * __mips_test_and_clear_bit - Clear a bit and return its old value. This is | |
| 134 | + * called by test_and_clear_bit() if it cannot find a faster solution. | |
| 135 | + * @nr: Bit to clear | |
| 136 | + * @addr: Address to count from | |
| 137 | + */ | |
| 138 | +int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) | |
| 139 | +{ | |
| 140 | + volatile unsigned long *a = addr; | |
| 141 | + unsigned bit = nr & SZLONG_MASK; | |
| 142 | + unsigned long mask; | |
| 143 | + unsigned long flags; | |
| 144 | + unsigned long res; | |
| 145 | + | |
| 146 | + a += nr >> SZLONG_LOG; | |
| 147 | + mask = 1UL << bit; | |
| 148 | + raw_local_irq_save(flags); | |
| 149 | + res = (mask & *a); | |
| 150 | + *a &= ~mask; | |
| 151 | + raw_local_irq_restore(flags); | |
| 152 | + return res; | |
| 153 | +} | |
| 154 | +EXPORT_SYMBOL(__mips_test_and_clear_bit); | |
| 155 | + | |
| 156 | + | |
| 157 | +/** | |
| 158 | + * __mips_test_and_change_bit - Change a bit and return its old value. This is | |
| 159 | + * called by test_and_change_bit() if it cannot find a faster solution. | |
| 160 | + * @nr: Bit to change | |
| 161 | + * @addr: Address to count from | |
| 162 | + */ | |
| 163 | +int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) | |
| 164 | +{ | |
| 165 | + volatile unsigned long *a = addr; | |
| 166 | + unsigned bit = nr & SZLONG_MASK; | |
| 167 | + unsigned long mask; | |
| 168 | + unsigned long flags; | |
| 169 | + unsigned long res; | |
| 170 | + | |
| 171 | + a += nr >> SZLONG_LOG; | |
| 172 | + mask = 1UL << bit; | |
| 173 | + raw_local_irq_save(flags); | |
| 174 | + res = (mask & *a); | |
| 175 | + *a ^= mask; | |
| 176 | + raw_local_irq_restore(flags); | |
| 177 | + return res; | |
| 178 | +} | |
| 179 | +EXPORT_SYMBOL(__mips_test_and_change_bit); | |
| @@ -0,0 +1,176 @@ | ||
| 1 | +/* | |
| 2 | + * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | + * License. See the file "COPYING" in the main directory of this archive | |
| 4 | + * for more details. | |
| 5 | + * | |
| 6 | + * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle | |
| 7 | + * Copyright (C) 1996 by Paul M. Antoine | |
| 8 | + * Copyright (C) 1999 Silicon Graphics | |
| 9 | + * Copyright (C) 2000 MIPS Technologies, Inc. | |
| 10 | + */ | |
| 11 | +#include <asm/irqflags.h> | |
| 12 | +#include <asm/hazards.h> | |
| 13 | +#include <linux/compiler.h> | |
| 14 | +#include <linux/preempt.h> | |
| 15 | +#include <linux/export.h> | |
| 16 | + | |
| 17 | +#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) | |
| 18 | + | |
| 19 | +/* | |
| 20 | + * For cli() we have to insert nops to make sure that the new value | |
| 21 | + * has actually arrived in the status register before the end of this | |
| 22 | + * macro. | |
| 23 | + * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | |
| 24 | + * no nops at all. | |
| 25 | + */ | |
| 26 | +/* | |
| 27 | + * For TX49, operating only IE bit is not enough. | |
| 28 | + * | |
| 29 | + * If mfc0 $12 follows store and the mfc0 is last instruction of a | |
| 30 | + * page and fetching the next instruction causes TLB miss, the result | |
| 31 | + * of the mfc0 might wrongly contain EXL bit. | |
| 32 | + * | |
| 33 | + * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | |
| 34 | + * | |
| 35 | + * Workaround: mask EXL bit of the result or place a nop before mfc0. | |
| 36 | + */ | |
| 37 | +__asm__( | |
| 38 | + " .macro arch_local_irq_disable\n" | |
| 39 | + " .set push \n" | |
| 40 | + " .set noat \n" | |
| 41 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 42 | + " mfc0 $1, $2, 1 \n" | |
| 43 | + " ori $1, 0x400 \n" | |
| 44 | + " .set noreorder \n" | |
| 45 | + " mtc0 $1, $2, 1 \n" | |
| 46 | +#elif defined(CONFIG_CPU_MIPSR2) | |
| 47 | + /* see irqflags.h for inline function */ | |
| 48 | +#else | |
| 49 | + " mfc0 $1,$12 \n" | |
| 50 | + " ori $1,0x1f \n" | |
| 51 | + " xori $1,0x1f \n" | |
| 52 | + " .set noreorder \n" | |
| 53 | + " mtc0 $1,$12 \n" | |
| 54 | +#endif | |
| 55 | + " irq_disable_hazard \n" | |
| 56 | + " .set pop \n" | |
| 57 | + " .endm \n"); | |
| 58 | + | |
| 59 | +void arch_local_irq_disable(void) | |
| 60 | +{ | |
| 61 | + preempt_disable(); | |
| 62 | + __asm__ __volatile__( | |
| 63 | + "arch_local_irq_disable" | |
| 64 | + : /* no outputs */ | |
| 65 | + : /* no inputs */ | |
| 66 | + : "memory"); | |
| 67 | + preempt_enable(); | |
| 68 | +} | |
| 69 | +EXPORT_SYMBOL(arch_local_irq_disable); | |
| 70 | + | |
| 71 | + | |
| 72 | +__asm__( | |
| 73 | + " .macro arch_local_irq_save result \n" | |
| 74 | + " .set push \n" | |
| 75 | + " .set reorder \n" | |
| 76 | + " .set noat \n" | |
| 77 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 78 | + " mfc0 \\result, $2, 1 \n" | |
| 79 | + " ori $1, \\result, 0x400 \n" | |
| 80 | + " .set noreorder \n" | |
| 81 | + " mtc0 $1, $2, 1 \n" | |
| 82 | + " andi \\result, \\result, 0x400 \n" | |
| 83 | +#elif defined(CONFIG_CPU_MIPSR2) | |
| 84 | + /* see irqflags.h for inline function */ | |
| 85 | +#else | |
| 86 | + " mfc0 \\result, $12 \n" | |
| 87 | + " ori $1, \\result, 0x1f \n" | |
| 88 | + " xori $1, 0x1f \n" | |
| 89 | + " .set noreorder \n" | |
| 90 | + " mtc0 $1, $12 \n" | |
| 91 | +#endif | |
| 92 | + " irq_disable_hazard \n" | |
| 93 | + " .set pop \n" | |
| 94 | + " .endm \n"); | |
| 95 | + | |
| 96 | +unsigned long arch_local_irq_save(void) | |
| 97 | +{ | |
| 98 | + unsigned long flags; | |
| 99 | + preempt_disable(); | |
| 100 | + asm volatile("arch_local_irq_save\t%0" | |
| 101 | + : "=r" (flags) | |
| 102 | + : /* no inputs */ | |
| 103 | + : "memory"); | |
| 104 | + preempt_enable(); | |
| 105 | + return flags; | |
| 106 | +} | |
| 107 | +EXPORT_SYMBOL(arch_local_irq_save); | |
| 108 | + | |
| 109 | + | |
| 110 | +__asm__( | |
| 111 | + " .macro arch_local_irq_restore flags \n" | |
| 112 | + " .set push \n" | |
| 113 | + " .set noreorder \n" | |
| 114 | + " .set noat \n" | |
| 115 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 116 | + "mfc0 $1, $2, 1 \n" | |
| 117 | + "andi \\flags, 0x400 \n" | |
| 118 | + "ori $1, 0x400 \n" | |
| 119 | + "xori $1, 0x400 \n" | |
| 120 | + "or \\flags, $1 \n" | |
| 121 | + "mtc0 \\flags, $2, 1 \n" | |
| 122 | +#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | |
| 123 | + /* see irqflags.h for inline function */ | |
| 124 | +#elif defined(CONFIG_CPU_MIPSR2) | |
| 125 | + /* see irqflags.h for inline function */ | |
| 126 | +#else | |
| 127 | + " mfc0 $1, $12 \n" | |
| 128 | + " andi \\flags, 1 \n" | |
| 129 | + " ori $1, 0x1f \n" | |
| 130 | + " xori $1, 0x1f \n" | |
| 131 | + " or \\flags, $1 \n" | |
| 132 | + " mtc0 \\flags, $12 \n" | |
| 133 | +#endif | |
| 134 | + " irq_disable_hazard \n" | |
| 135 | + " .set pop \n" | |
| 136 | + " .endm \n"); | |
| 137 | + | |
| 138 | +void arch_local_irq_restore(unsigned long flags) | |
| 139 | +{ | |
| 140 | + unsigned long __tmp1; | |
| 141 | + | |
| 142 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 143 | + /* | |
| 144 | + * SMTC kernel needs to do a software replay of queued | |
| 145 | + * IPIs, at the cost of branch and call overhead on each | |
| 146 | + * local_irq_restore() | |
| 147 | + */ | |
| 148 | + if (unlikely(!(flags & 0x0400))) | |
| 149 | + smtc_ipi_replay(); | |
| 150 | +#endif | |
| 151 | + preempt_disable(); | |
| 152 | + __asm__ __volatile__( | |
| 153 | + "arch_local_irq_restore\t%0" | |
| 154 | + : "=r" (__tmp1) | |
| 155 | + : "0" (flags) | |
| 156 | + : "memory"); | |
| 157 | + preempt_enable(); | |
| 158 | +} | |
| 159 | +EXPORT_SYMBOL(arch_local_irq_restore); | |
| 160 | + | |
| 161 | + | |
| 162 | +void __arch_local_irq_restore(unsigned long flags) | |
| 163 | +{ | |
| 164 | + unsigned long __tmp1; | |
| 165 | + | |
| 166 | + preempt_disable(); | |
| 167 | + __asm__ __volatile__( | |
| 168 | + "arch_local_irq_restore\t%0" | |
| 169 | + : "=r" (__tmp1) | |
| 170 | + : "0" (flags) | |
| 171 | + : "memory"); | |
| 172 | + preempt_enable(); | |
| 173 | +} | |
| 174 | +EXPORT_SYMBOL(__arch_local_irq_restore); | |
| 175 | + | |
| 176 | +#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */ | |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/mtd/partitions.h> |
| 30 | 30 | #include <linux/mtd/physmap.h> |
| 31 | 31 | #include <linux/platform_device.h> |
| 32 | +#include <asm/mips-boards/maltaint.h> | |
| 32 | 33 | #include <mtd/mtd-abi.h> |
| 33 | 34 | |
| 34 | 35 | #define SMC_PORT(base, int) \ |
| @@ -48,7 +49,7 @@ static struct plat_serial8250_port uart8250_data[] = { · 13 unmodified lines | ||
| 48 | 49 | SMC_PORT(0x2F8, 3), |
| 49 | 50 | { |
| 50 | 51 | .mapbase = 0x1f000900, /* The CBUS UART */ |
| 51 | − .irq = MIPS_CPU_IRQ_BASE + 2, | |
| 52 | + .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, | |
| 52 | 53 | .uartclk = 3686400, /* Twice the usual clk! */ |
| 53 | 54 | .iotype = UPIO_MEM32, |
| 54 | 55 | .flags = CBUS_UART_FLAGS, |
| @@ -96,6 +96,7 @@ config S390 · 95 unmodified lines | ||
| 96 | 96 | select HAVE_MEMBLOCK_NODE_MAP |
| 97 | 97 | select HAVE_CMPXCHG_LOCAL |
| 98 | 98 | select HAVE_CMPXCHG_DOUBLE |
| 99 | + select HAVE_ALIGNED_STRUCT_PAGE if SLUB | |
| 99 | 100 | select HAVE_VIRT_CPU_ACCOUNTING |
| 100 | 101 | select VIRT_CPU_ACCOUNTING |
| 101 | 102 | select ARCH_DISCARD_MEMBLOCK |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #define LPM_ANYPATH 0xff |
| 11 | 11 | #define __MAX_CSSID 0 |
| 12 | +#define __MAX_SUBCHANNEL 65535 | |
| 13 | +#define __MAX_SSID 3 | |
| 12 | 14 | |
| 13 | 15 | #include <asm/scsw.h> |
| 14 | 16 | |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #define PSW32_MASK_CC 0x00003000UL |
| 21 | 21 | #define PSW32_MASK_PM 0x00000f00UL |
| 22 | 22 | |
| 23 | −#define PSW32_MASK_USER 0x00003F00UL | |
| 23 | +#define PSW32_MASK_USER 0x0000FF00UL | |
| 24 | 24 | |
| 25 | 25 | #define PSW32_ADDR_AMODE 0x80000000UL |
| 26 | 26 | #define PSW32_ADDR_INSN 0x7FFFFFFFUL |
| @@ -506,12 +506,15 @@ static inline int pud_bad(pud_t pud) · 505 unmodified lines | ||
| 506 | 506 | |
| 507 | 507 | static inline int pmd_present(pmd_t pmd) |
| 508 | 508 | { |
| 509 | − return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; | |
| 509 | + unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO; | |
| 510 | + return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE || | |
| 511 | + !(pmd_val(pmd) & _SEGMENT_ENTRY_INV); | |
| 510 | 512 | } |
| 511 | 513 | |
| 512 | 514 | static inline int pmd_none(pmd_t pmd) |
| 513 | 515 | { |
| 514 | − return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; | |
| 516 | + return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) && | |
| 517 | + !(pmd_val(pmd) & _SEGMENT_ENTRY_RO); | |
| 515 | 518 | } |
| 516 | 519 | |
| 517 | 520 | static inline int pmd_large(pmd_t pmd) |
| @@ -1223,6 +1226,11 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) · 705 unmodified lines | ||
| 1223 | 1226 | } |
| 1224 | 1227 | |
| 1225 | 1228 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 1229 | + | |
| 1230 | +#define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) | |
| 1231 | +#define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) | |
| 1232 | +#define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) | |
| 1233 | + | |
| 1226 | 1234 | #define __HAVE_ARCH_PGTABLE_DEPOSIT |
| 1227 | 1235 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); |
| 1228 | 1236 | |
| @@ -1242,16 +1250,15 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, · 13 unmodified lines | ||
| 1242 | 1250 | |
| 1243 | 1251 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) |
| 1244 | 1252 | { |
| 1245 | − unsigned long pgprot_pmd = 0; | |
| 1246 | − | |
| 1247 | − if (pgprot_val(pgprot) & _PAGE_INVALID) { | |
| 1248 | − if (pgprot_val(pgprot) & _PAGE_SWT) | |
| 1249 | − pgprot_pmd |= _HPAGE_TYPE_NONE; | |
| 1250 | − pgprot_pmd |= _SEGMENT_ENTRY_INV; | |
| 1251 | − } | |
| 1252 | − if (pgprot_val(pgprot) & _PAGE_RO) | |
| 1253 | − pgprot_pmd |= _SEGMENT_ENTRY_RO; | |
| 1254 | − return pgprot_pmd; | |
| 1253 | + /* | |
| 1254 | + * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx) | |
| 1255 | + * Convert to segment table entry format. | |
| 1256 | + */ | |
| 1257 | + if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) | |
| 1258 | + return pgprot_val(SEGMENT_NONE); | |
| 1259 | + if (pgprot_val(pgprot) == pgprot_val(PAGE_RO)) | |
| 1260 | + return pgprot_val(SEGMENT_RO); | |
| 1261 | + return pgprot_val(SEGMENT_RW); | |
| 1255 | 1262 | } |
| 1256 | 1263 | |
| 1257 | 1264 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) |
| @@ -1269,7 +1276,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) · 11 unmodified lines | ||
| 1269 | 1276 | |
| 1270 | 1277 | static inline pmd_t pmd_mkwrite(pmd_t pmd) |
| 1271 | 1278 | { |
| 1272 | − pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | |
| 1279 | + /* Do not clobber _HPAGE_TYPE_NONE pages! */ | |
| 1280 | + if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV)) | |
| 1281 | + pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | |
| 1273 | 1282 | return pmd; |
| 1274 | 1283 | } |
| 1275 | 1284 | |
| @@ -8,6 +8,9 @@ struct cpu; · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | #ifdef CONFIG_SCHED_BOOK |
| 10 | 10 | |
| 11 | +extern unsigned char cpu_socket_id[NR_CPUS]; | |
| 12 | +#define topology_physical_package_id(cpu) (cpu_socket_id[cpu]) | |
| 13 | + | |
| 11 | 14 | extern unsigned char cpu_core_id[NR_CPUS]; |
| 12 | 15 | extern cpumask_t cpu_core_map[NR_CPUS]; |
| 13 | 16 | |
| @@ -239,7 +239,7 @@ typedef struct · 238 unmodified lines | ||
| 239 | 239 | #define PSW_MASK_EA 0x00000000UL |
| 240 | 240 | #define PSW_MASK_BA 0x00000000UL |
| 241 | 241 | |
| 242 | −#define PSW_MASK_USER 0x00003F00UL | |
| 242 | +#define PSW_MASK_USER 0x0000FF00UL | |
| 243 | 243 | |
| 244 | 244 | #define PSW_ADDR_AMODE 0x80000000UL |
| 245 | 245 | #define PSW_ADDR_INSN 0x7FFFFFFFUL |
| @@ -269,7 +269,7 @@ typedef struct · 23 unmodified lines | ||
| 269 | 269 | #define PSW_MASK_EA 0x0000000100000000UL |
| 270 | 270 | #define PSW_MASK_BA 0x0000000080000000UL |
| 271 | 271 | |
| 272 | −#define PSW_MASK_USER 0x00003F8180000000UL | |
| 272 | +#define PSW_MASK_USER 0x0000FF8180000000UL | |
| 273 | 273 | |
| 274 | 274 | #define PSW_ADDR_AMODE 0x0000000000000000UL |
| 275 | 275 | #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL |
| @@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) · 308 unmodified lines | ||
| 309 | 309 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
| 310 | 310 | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | |
| 311 | 311 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); |
| 312 | + /* Check for invalid user address space control. */ | |
| 313 | + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) | |
| 314 | + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | | |
| 315 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 312 | 316 | regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); |
| 313 | 317 | for (i = 0; i < NUM_GPRS; i++) |
| 314 | 318 | regs->gprs[i] = (__u64) regs32.gprs[i]; |
| @@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka, · 166 unmodified lines | ||
| 481 | 485 | |
| 482 | 486 | /* Set up registers for signal handler */ |
| 483 | 487 | regs->gprs[15] = (__force __u64) frame; |
| 484 | − regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ | |
| 488 | + /* Force 31 bit amode and default user address space control. */ | |
| 489 | + regs->psw.mask = PSW_MASK_BA | | |
| 490 | + (psw_user_bits & PSW_MASK_ASC) | | |
| 491 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 485 | 492 | regs->psw.addr = (__force __u64) ka->sa.sa_handler; |
| 486 | 493 | |
| 487 | 494 | regs->gprs[2] = map_signal(sig); |
| @@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, · 61 unmodified lines | ||
| 549 | 556 | |
| 550 | 557 | /* Set up registers for signal handler */ |
| 551 | 558 | regs->gprs[15] = (__force __u64) frame; |
| 552 | − regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ | |
| 559 | + /* Force 31 bit amode and default user address space control. */ | |
| 560 | + regs->psw.mask = PSW_MASK_BA | | |
| 561 | + (psw_user_bits & PSW_MASK_ASC) | | |
| 562 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 553 | 563 | regs->psw.addr = (__u64) ka->sa.sa_handler; |
| 554 | 564 | |
| 555 | 565 | regs->gprs[2] = map_signal(sig); |
| @@ -44,6 +44,12 @@ _sclp_wait_int: · 43 unmodified lines | ||
| 44 | 44 | #endif |
| 45 | 45 | mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) |
| 46 | 46 | mvc 0(16,%r8),0(%r9) |
| 47 | +#ifdef CONFIG_64BIT | |
| 48 | + epsw %r6,%r7 # set current addressing mode | |
| 49 | + nill %r6,0x1 # in new psw (31 or 64 bit mode) | |
| 50 | + nilh %r7,0x8000 | |
| 51 | + stm %r6,%r7,0(%r8) | |
| 52 | +#endif | |
| 47 | 53 | lhi %r6,0x0200 # cr mask for ext int (cr0.54) |
| 48 | 54 | ltr %r2,%r2 |
| 49 | 55 | jz .LsetctS1 |
| @@ -87,7 +93,7 @@ _sclp_wait_int: · 37 unmodified lines | ||
| 87 | 93 | .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int |
| 88 | 94 | #ifdef CONFIG_64BIT |
| 89 | 95 | .LextpswS1_64: |
| 90 | − .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit | |
| 96 | + .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit | |
| 91 | 97 | #endif |
| 92 | 98 | .LwaitpswS1: |
| 93 | 99 | .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int |
| @@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) · 135 unmodified lines | ||
| 136 | 136 | /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ |
| 137 | 137 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
| 138 | 138 | (user_sregs.regs.psw.mask & PSW_MASK_USER); |
| 139 | + /* Check for invalid user address space control. */ | |
| 140 | + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) | |
| 141 | + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | | |
| 142 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 139 | 143 | /* Check for invalid amode */ |
| 140 | 144 | if (regs->psw.mask & PSW_MASK_EA) |
| 141 | 145 | regs->psw.mask |= PSW_MASK_BA; |
| @@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka, · 131 unmodified lines | ||
| 273 | 277 | |
| 274 | 278 | /* Set up registers for signal handler */ |
| 275 | 279 | regs->gprs[15] = (unsigned long) frame; |
| 276 | − regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ | |
| 280 | + /* Force default amode and default user address space control. */ | |
| 281 | + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | | |
| 282 | + (psw_user_bits & PSW_MASK_ASC) | | |
| 283 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 277 | 284 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; |
| 278 | 285 | |
| 279 | 286 | regs->gprs[2] = map_signal(sig); |
| @@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 66 unmodified lines | ||
| 346 | 353 | |
| 347 | 354 | /* Set up registers for signal handler */ |
| 348 | 355 | regs->gprs[15] = (unsigned long) frame; |
| 349 | − regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ | |
| 356 | + /* Force default amode and default user address space control. */ | |
| 357 | + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | | |
| 358 | + (psw_user_bits & PSW_MASK_ASC) | | |
| 359 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 350 | 360 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; |
| 351 | 361 | |
| 352 | 362 | regs->gprs[2] = map_signal(sig); |
| @@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock); · 39 unmodified lines | ||
| 40 | 40 | static struct mask_info core_info; |
| 41 | 41 | cpumask_t cpu_core_map[NR_CPUS]; |
| 42 | 42 | unsigned char cpu_core_id[NR_CPUS]; |
| 43 | +unsigned char cpu_socket_id[NR_CPUS]; | |
| 43 | 44 | |
| 44 | 45 | static struct mask_info book_info; |
| 45 | 46 | cpumask_t cpu_book_map[NR_CPUS]; |
| @@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, · 37 unmodified lines | ||
| 83 | 84 | cpumask_set_cpu(lcpu, &book->mask); |
| 84 | 85 | cpu_book_id[lcpu] = book->id; |
| 85 | 86 | cpumask_set_cpu(lcpu, &core->mask); |
| 87 | + cpu_core_id[lcpu] = rcpu; | |
| 86 | 88 | if (one_core_per_cpu) { |
| 87 | − cpu_core_id[lcpu] = rcpu; | |
| 89 | + cpu_socket_id[lcpu] = rcpu; | |
| 88 | 90 | core = core->next; |
| 89 | 91 | } else { |
| 90 | − cpu_core_id[lcpu] = core->id; | |
| 92 | + cpu_socket_id[lcpu] = core->id; | |
| 91 | 93 | } |
| 92 | 94 | smp_cpu_set_polarization(lcpu, tl_cpu->pp); |
| 93 | 95 | } |
| @@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm, · 38 unmodified lines | ||
| 39 | 39 | pmd = pmd_offset(pud, addr); |
| 40 | 40 | if (pmd_none(*pmd)) |
| 41 | 41 | return -0x10UL; |
| 42 | − if (pmd_huge(*pmd)) { | |
| 42 | + if (pmd_large(*pmd)) { | |
| 43 | 43 | if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) |
| 44 | 44 | return -0x04UL; |
| 45 | 45 | return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); |
| @@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr, · 125 unmodified lines | ||
| 126 | 126 | */ |
| 127 | 127 | if (pmd_none(pmd) || pmd_trans_splitting(pmd)) |
| 128 | 128 | return 0; |
| 129 | − if (unlikely(pmd_huge(pmd))) { | |
| 129 | + if (unlikely(pmd_large(pmd))) { | |
| 130 | 130 | if (!gup_huge_pmd(pmdp, pmd, addr, next, |
| 131 | 131 | write, pages, nr)) |
| 132 | 132 | return 0; |
| @@ -180,8 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, · 47 unmodified lines | ||
| 180 | 180 | addr = start; |
| 181 | 181 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
| 182 | 182 | end = start + len; |
| 183 | − if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, | |
| 184 | − (void __user *)start, len))) | |
| 183 | + if ((end < start) || (end > TASK_SIZE)) | |
| 185 | 184 | return 0; |
| 186 | 185 | |
| 187 | 186 | local_irq_save(flags); |
| @@ -229,7 +228,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, · 41 unmodified lines | ||
| 229 | 228 | addr = start; |
| 230 | 229 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
| 231 | 230 | end = start + len; |
| 232 | − if (end < start) | |
| 231 | + if ((end < start) || (end > TASK_SIZE)) | |
| 233 | 232 | goto slow_irqon; |
| 234 | 233 | |
| 235 | 234 | /* |
| @@ -20,6 +20,7 @@ config SPARC · 19 unmodified lines | ||
| 20 | 20 | select HAVE_ARCH_TRACEHOOK |
| 21 | 21 | select SYSCTL_EXCEPTION_TRACE |
| 22 | 22 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 23 | + select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | |
| 23 | 24 | select RTC_CLASS |
| 24 | 25 | select RTC_DRV_M48T59 |
| 25 | 26 | select HAVE_IRQ_WORK |
| @@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o |
| 15 | 15 | |
| 16 | −sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o | |
| 17 | −sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o | |
| 18 | −sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o | |
| 19 | −md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o | |
| 16 | +sha1-sparc64-y := sha1_asm.o sha1_glue.o | |
| 17 | +sha256-sparc64-y := sha256_asm.o sha256_glue.o | |
| 18 | +sha512-sparc64-y := sha512_asm.o sha512_glue.o | |
| 19 | +md5-sparc64-y := md5_asm.o md5_glue.o | |
| 20 | 20 | |
| 21 | −aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o | |
| 22 | −des-sparc64-y := des_asm.o des_glue.o crop_devid.o | |
| 23 | −camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o | |
| 21 | +aes-sparc64-y := aes_asm.o aes_glue.o | |
| 22 | +des-sparc64-y := des_asm.o des_glue.o | |
| 23 | +camellia-sparc64-y := camellia_asm.o camellia_glue.o | |
| 24 | 24 | |
| 25 | −crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o | |
| 25 | +crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o | |
| @@ -475,3 +475,5 @@ MODULE_LICENSE("GPL"); · 474 unmodified lines | ||
| 475 | 475 | MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); |
| 476 | 476 | |
| 477 | 477 | MODULE_ALIAS("aes"); |
| 478 | + | |
| 479 | +#include "crop_devid.c" | |
| @@ -320,3 +320,5 @@ MODULE_LICENSE("GPL"); · 319 unmodified lines | ||
| 320 | 320 | MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); |
| 321 | 321 | |
| 322 | 322 | MODULE_ALIAS("aes"); |
| 323 | + | |
| 324 | +#include "crop_devid.c" | |
| @@ -177,3 +177,5 @@ MODULE_LICENSE("GPL"); · 176 unmodified lines | ||
| 177 | 177 | MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); |
| 178 | 178 | |
| 179 | 179 | MODULE_ALIAS("crc32c"); |
| 180 | + | |
| 181 | +#include "crop_devid.c" | |
| @@ -527,3 +527,5 @@ MODULE_LICENSE("GPL"); · 526 unmodified lines | ||
| 527 | 527 | MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); |
| 528 | 528 | |
| 529 | 529 | MODULE_ALIAS("des"); |
| 530 | + | |
| 531 | +#include "crop_devid.c" | |
| @@ -186,3 +186,5 @@ MODULE_LICENSE("GPL"); · 185 unmodified lines | ||
| 186 | 186 | MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); |
| 187 | 187 | |
| 188 | 188 | MODULE_ALIAS("md5"); |
| 189 | + | |
| 190 | +#include "crop_devid.c" | |
| @@ -181,3 +181,5 @@ MODULE_LICENSE("GPL"); · 180 unmodified lines | ||
| 181 | 181 | MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); |
| 182 | 182 | |
| 183 | 183 | MODULE_ALIAS("sha1"); |
| 184 | + | |
| 185 | +#include "crop_devid.c" | |
| @@ -239,3 +239,5 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op · 238 unmodified lines | ||
| 239 | 239 | |
| 240 | 240 | MODULE_ALIAS("sha224"); |
| 241 | 241 | MODULE_ALIAS("sha256"); |
| 242 | + | |
| 243 | +#include "crop_devid.c" | |
| @@ -224,3 +224,5 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op · 223 unmodified lines | ||
| 224 | 224 | |
| 225 | 225 | MODULE_ALIAS("sha384"); |
| 226 | 226 | MODULE_ALIAS("sha512"); |
| 227 | + | |
| 228 | +#include "crop_devid.c" | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* atomic.h: Thankfully the V9 is at least reasonable for this |
| 2 | 2 | * stuff. |
| 3 | 3 | * |
| 4 | − * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) | |
| 4 | + * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) | |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | #ifndef __ARCH_SPARC64_ATOMIC__ |
| @@ -106,6 +106,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) · 98 unmodified lines | ||
| 106 | 106 | |
| 107 | 107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 108 | 108 | |
| 109 | +extern long atomic64_dec_if_positive(atomic64_t *v); | |
| 110 | + | |
| 109 | 111 | /* Atomic operations are already serializing */ |
| 110 | 112 | #define smp_mb__before_atomic_dec() barrier() |
| 111 | 113 | #define smp_mb__after_atomic_dec() barrier() |
| @@ -1,6 +1,46 @@ | ||
| 1 | 1 | #ifndef _SPARC64_BACKOFF_H |
| 2 | 2 | #define _SPARC64_BACKOFF_H |
| 3 | 3 | |
| 4 | +/* The macros in this file implement an exponential backoff facility | |
| 5 | + * for atomic operations. | |
| 6 | + * | |
| 7 | + * When multiple threads compete on an atomic operation, it is | |
| 8 | + * possible for one thread to be continually denied a successful | |
| 9 | + * completion of the compare-and-swap instruction. Heavily | |
| 10 | + * threaded cpu implementations like Niagara can compound this | |
| 11 | + * problem even further. | |
| 12 | + * | |
| 13 | + * When an atomic operation fails and needs to be retried, we spin a | |
| 14 | + * certain number of times. At each subsequent failure of the same | |
| 15 | + * operation we double the spin count, realizing an exponential | |
| 16 | + * backoff. | |
| 17 | + * | |
| 18 | + * When we spin, we try to use an operation that will cause the | |
| 19 | + * current cpu strand to block, and therefore make the core fully | |
| 20 | + * available to any other other runnable strands. There are two | |
| 21 | + * options, based upon cpu capabilities. | |
| 22 | + * | |
| 23 | + * On all cpus prior to SPARC-T4 we do three dummy reads of the | |
| 24 | + * condition code register. Each read blocks the strand for something | |
| 25 | + * between 40 and 50 cpu cycles. | |
| 26 | + * | |
| 27 | + * For SPARC-T4 and later we have a special "pause" instruction | |
| 28 | + * available. This is implemented using writes to register %asr27. | |
| 29 | + * The cpu will block the number of cycles written into the register, | |
| 30 | + * unless a disrupting trap happens first. SPARC-T4 specifically | |
| 31 | + * implements pause with a granularity of 8 cycles. Each strand has | |
| 32 | + * an internal pause counter which decrements every 8 cycles. So the | |
| 33 | + * chip shifts the %asr27 value down by 3 bits, and writes the result | |
| 34 | + * into the pause counter. If a value smaller than 8 is written, the | |
| 35 | + * chip blocks for 1 cycle. | |
| 36 | + * | |
| 37 | + * To achieve the same amount of backoff as the three %ccr reads give | |
| 38 | + * on earlier chips, we shift the backoff value up by 7 bits. (Three | |
| 39 | + * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the | |
| 40 | + * whole amount we want to block into the pause register, rather than | |
| 41 | + * loop writing 128 each time. | |
| 42 | + */ | |
| 43 | + | |
| 4 | 44 | #define BACKOFF_LIMIT (4 * 1024) |
| 5 | 45 | |
| 6 | 46 | #ifdef CONFIG_SMP |
| @@ -11,16 +51,25 @@ · 4 unmodified lines | ||
| 11 | 51 | #define BACKOFF_LABEL(spin_label, continue_label) \ |
| 12 | 52 | spin_label |
| 13 | 53 | |
| 14 | −#define BACKOFF_SPIN(reg, tmp, label) \ | |
| 15 | − mov reg, tmp; \ | |
| 16 | −88: brnz,pt tmp, 88b; \ | |
| 17 | − sub tmp, 1, tmp; \ | |
| 18 | − set BACKOFF_LIMIT, tmp; \ | |
| 19 | − cmp reg, tmp; \ | |
| 20 | − bg,pn %xcc, label; \ | |
| 21 | − nop; \ | |
| 22 | − ba,pt %xcc, label; \ | |
| 23 | − sllx reg, 1, reg; | |
| 54 | +#define BACKOFF_SPIN(reg, tmp, label) \ | |
| 55 | + mov reg, tmp; \ | |
| 56 | +88: rd %ccr, %g0; \ | |
| 57 | + rd %ccr, %g0; \ | |
| 58 | + rd %ccr, %g0; \ | |
| 59 | + .section .pause_3insn_patch,"ax";\ | |
| 60 | + .word 88b; \ | |
| 61 | + sllx tmp, 7, tmp; \ | |
| 62 | + wr tmp, 0, %asr27; \ | |
| 63 | + clr tmp; \ | |
| 64 | + .previous; \ | |
| 65 | + brnz,pt tmp, 88b; \ | |
| 66 | + sub tmp, 1, tmp; \ | |
| 67 | + set BACKOFF_LIMIT, tmp; \ | |
| 68 | + cmp reg, tmp; \ | |
| 69 | + bg,pn %xcc, label; \ | |
| 70 | + nop; \ | |
| 71 | + ba,pt %xcc, label; \ | |
| 72 | + sllx reg, 1, reg; | |
| 24 | 73 | |
| 25 | 74 | #else |
| 26 | 75 | |
| @@ -232,9 +232,10 @@ static inline void __user *arch_compat_alloc_user_space(long len) · 231 unmodified lines | ||
| 232 | 232 | struct pt_regs *regs = current_thread_info()->kregs; |
| 233 | 233 | unsigned long usp = regs->u_regs[UREG_I6]; |
| 234 | 234 | |
| 235 | − if (!(test_thread_flag(TIF_32BIT))) | |
| 235 | + if (test_thread_64bit_stack(usp)) | |
| 236 | 236 | usp += STACK_BIAS; |
| 237 | − else | |
| 237 | + | |
| 238 | + if (test_thread_flag(TIF_32BIT)) | |
| 238 | 239 | usp &= 0xffffffffUL; |
| 239 | 240 | |
| 240 | 241 | usp -= len; |
| @@ -196,7 +196,22 @@ extern unsigned long get_wchan(struct task_struct *task); · 195 unmodified lines | ||
| 196 | 196 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) |
| 197 | 197 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) |
| 198 | 198 | |
| 199 | −#define cpu_relax() barrier() | |
| 199 | +/* Please see the commentary in asm/backoff.h for a description of | |
| 200 | + * what these instructions are doing and how they have been choosen. | |
| 201 | + * To make a long story short, we are trying to yield the current cpu | |
| 202 | + * strand during busy loops. | |
| 203 | + */ | |
| 204 | +#define cpu_relax() asm volatile("\n99:\n\t" \ | |
| 205 | + "rd %%ccr, %%g0\n\t" \ | |
| 206 | + "rd %%ccr, %%g0\n\t" \ | |
| 207 | + "rd %%ccr, %%g0\n\t" \ | |
| 208 | + ".section .pause_3insn_patch,\"ax\"\n\t"\ | |
| 209 | + ".word 99b\n\t" \ | |
| 210 | + "wr %%g0, 128, %%asr27\n\t" \ | |
| 211 | + "nop\n\t" \ | |
| 212 | + "nop\n\t" \ | |
| 213 | + ".previous" \ | |
| 214 | + ::: "memory") | |
| 200 | 215 | |
| 201 | 216 | /* Prefetch support. This is tuned for UltraSPARC-III and later. |
| 202 | 217 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has |
| @@ -63,5 +63,10 @@ extern char *of_console_options; · 62 unmodified lines | ||
| 63 | 63 | extern void irq_trans_init(struct device_node *dp); |
| 64 | 64 | extern char *build_path_component(struct device_node *dp); |
| 65 | 65 | |
| 66 | +/* SPARC has a local implementation */ | |
| 67 | +extern int of_address_to_resource(struct device_node *dev, int index, | |
| 68 | + struct resource *r); | |
| 69 | +#define of_address_to_resource of_address_to_resource | |
| 70 | + | |
| 66 | 71 | #endif /* __KERNEL__ */ |
| 67 | 72 | #endif /* _SPARC_PROM_H */ |
| @@ -259,6 +259,11 @@ static inline bool test_and_clear_restore_sigmask(void) · 258 unmodified lines | ||
| 259 | 259 | |
| 260 | 260 | #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) |
| 261 | 261 | |
| 262 | +#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) | |
| 263 | +#define test_thread_64bit_stack(__SP) \ | |
| 264 | + ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ | |
| 265 | + false : true) | |
| 266 | + | |
| 262 | 267 | #endif /* !__ASSEMBLY__ */ |
| 263 | 268 | |
| 264 | 269 | #endif /* __KERNEL__ */ |
| @@ -372,7 +372,9 @@ etrap_spill_fixup_64bit: \ · 371 unmodified lines | ||
| 372 | 372 | |
| 373 | 373 | /* Normal 32bit spill */ |
| 374 | 374 | #define SPILL_2_GENERIC(ASI) \ |
| 375 | − srl %sp, 0, %sp; \ | |
| 375 | + and %sp, 1, %g3; \ | |
| 376 | + brnz,pn %g3, (. - (128 + 4)); \ | |
| 377 | + srl %sp, 0, %sp; \ | |
| 376 | 378 | stwa %l0, [%sp + %g0] ASI; \ |
| 377 | 379 | mov 0x04, %g3; \ |
| 378 | 380 | stwa %l1, [%sp + %g3] ASI; \ |
| @@ -398,14 +400,16 @@ etrap_spill_fixup_64bit: \ · 19 unmodified lines | ||
| 398 | 400 | stwa %i6, [%g1 + %g0] ASI; \ |
| 399 | 401 | stwa %i7, [%g1 + %g3] ASI; \ |
| 400 | 402 | saved; \ |
| 401 | − retry; nop; nop; \ | |
| 403 | + retry; \ | |
| 402 | 404 | b,a,pt %xcc, spill_fixup_dax; \ |
| 403 | 405 | b,a,pt %xcc, spill_fixup_mna; \ |
| 404 | 406 | b,a,pt %xcc, spill_fixup; |
| 405 | 407 | |
| 406 | 408 | #define SPILL_2_GENERIC_ETRAP \ |
| 407 | 409 | etrap_user_spill_32bit: \ |
| 408 | − srl %sp, 0, %sp; \ | |
| 410 | + and %sp, 1, %g3; \ | |
| 411 | + brnz,pn %g3, etrap_user_spill_64bit; \ | |
| 412 | + srl %sp, 0, %sp; \ | |
| 409 | 413 | stwa %l0, [%sp + 0x00] %asi; \ |
| 410 | 414 | stwa %l1, [%sp + 0x04] %asi; \ |
| 411 | 415 | stwa %l2, [%sp + 0x08] %asi; \ |
| @@ -427,7 +431,7 @@ etrap_user_spill_32bit: \ · 15 unmodified lines | ||
| 427 | 431 | ba,pt %xcc, etrap_save; \ |
| 428 | 432 | wrpr %g1, %cwp; \ |
| 429 | 433 | nop; nop; nop; nop; \ |
| 430 | − nop; nop; nop; nop; \ | |
| 434 | + nop; nop; \ | |
| 431 | 435 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
| 432 | 436 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
| 433 | 437 | ba,a,pt %xcc, etrap_spill_fixup_32bit; |
| @@ -592,7 +596,9 @@ user_rtt_fill_64bit: \ · 158 unmodified lines | ||
| 592 | 596 | |
| 593 | 597 | /* Normal 32bit fill */ |
| 594 | 598 | #define FILL_2_GENERIC(ASI) \ |
| 595 | − srl %sp, 0, %sp; \ | |
| 599 | + and %sp, 1, %g3; \ | |
| 600 | + brnz,pn %g3, (. - (128 + 4)); \ | |
| 601 | + srl %sp, 0, %sp; \ | |
| 596 | 602 | lduwa [%sp + %g0] ASI, %l0; \ |
| 597 | 603 | mov 0x04, %g2; \ |
| 598 | 604 | mov 0x08, %g3; \ |
| @@ -616,14 +622,16 @@ user_rtt_fill_64bit: \ · 17 unmodified lines | ||
| 616 | 622 | lduwa [%g1 + %g3] ASI, %i6; \ |
| 617 | 623 | lduwa [%g1 + %g5] ASI, %i7; \ |
| 618 | 624 | restored; \ |
| 619 | − retry; nop; nop; nop; nop; \ | |
| 625 | + retry; nop; nop; \ | |
| 620 | 626 | b,a,pt %xcc, fill_fixup_dax; \ |
| 621 | 627 | b,a,pt %xcc, fill_fixup_mna; \ |
| 622 | 628 | b,a,pt %xcc, fill_fixup; |
| 623 | 629 | |
| 624 | 630 | #define FILL_2_GENERIC_RTRAP \ |
| 625 | 631 | user_rtt_fill_32bit: \ |
| 626 | − srl %sp, 0, %sp; \ | |
| 632 | + and %sp, 1, %g3; \ | |
| 633 | + brnz,pn %g3, user_rtt_fill_64bit; \ | |
| 634 | + srl %sp, 0, %sp; \ | |
| 627 | 635 | lduwa [%sp + 0x00] %asi, %l0; \ |
| 628 | 636 | lduwa [%sp + 0x04] %asi, %l1; \ |
| 629 | 637 | lduwa [%sp + 0x08] %asi, %l2; \ |
| @@ -643,7 +651,7 @@ user_rtt_fill_32bit: \ · 13 unmodified lines | ||
| 643 | 651 | ba,pt %xcc, user_rtt_pre_restore; \ |
| 644 | 652 | restored; \ |
| 645 | 653 | nop; nop; nop; nop; nop; \ |
| 646 | − nop; nop; nop; nop; nop; \ | |
| 654 | + nop; nop; nop; \ | |
| 647 | 655 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
| 648 | 656 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
| 649 | 657 | ba,a,pt %xcc, user_rtt_fill_fixup; |
| @@ -405,8 +405,13 @@ · 404 unmodified lines | ||
| 405 | 405 | #define __NR_setns 337 |
| 406 | 406 | #define __NR_process_vm_readv 338 |
| 407 | 407 | #define __NR_process_vm_writev 339 |
| 408 | +#define __NR_kern_features 340 | |
| 409 | +#define __NR_kcmp 341 | |
| 408 | 410 | |
| 409 | −#define NR_syscalls 340 | |
| 411 | +#define NR_syscalls 342 | |
| 412 | + | |
| 413 | +/* Bitmask values returned from kern_features system call. */ | |
| 414 | +#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 | |
| 410 | 415 | |
| 411 | 416 | #ifdef __32bit_syscall_numbers__ |
| 412 | 417 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, |
| @@ -59,6 +59,13 @@ struct popc_6insn_patch_entry { · 58 unmodified lines | ||
| 59 | 59 | extern struct popc_6insn_patch_entry __popc_6insn_patch, |
| 60 | 60 | __popc_6insn_patch_end; |
| 61 | 61 | |
| 62 | +struct pause_patch_entry { | |
| 63 | + unsigned int addr; | |
| 64 | + unsigned int insns[3]; | |
| 65 | +}; | |
| 66 | +extern struct pause_patch_entry __pause_3insn_patch, | |
| 67 | + __pause_3insn_patch_end; | |
| 68 | + | |
| 62 | 69 | extern void __init per_cpu_patch(void); |
| 63 | 70 | extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, |
| 64 | 71 | struct sun4v_1insn_patch_entry *); |
| @@ -56,11 +56,13 @@ static inline unsigned int leon_eirq_get(int cpu) · 55 unmodified lines | ||
| 56 | 56 | static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) |
| 57 | 57 | { |
| 58 | 58 | unsigned int eirq; |
| 59 | + struct irq_bucket *p; | |
| 59 | 60 | int cpu = sparc_leon3_cpuid(); |
| 60 | 61 | |
| 61 | 62 | eirq = leon_eirq_get(cpu); |
| 62 | − if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ | |
| 63 | − generic_handle_irq(irq_map[eirq]->irq); | |
| 63 | + p = irq_map[eirq]; | |
| 64 | + if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ | |
| 65 | + generic_handle_irq(p->irq); | |
| 64 | 66 | } |
| 65 | 67 | |
| 66 | 68 | /* The extended IRQ controller has been found, this function registers it */ |
| @@ -1762,15 +1762,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, · 1761 unmodified lines | ||
| 1762 | 1762 | |
| 1763 | 1763 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; |
| 1764 | 1764 | do { |
| 1765 | − struct sparc_stackf32 *usf, sf; | |
| 1766 | 1765 | unsigned long pc; |
| 1767 | 1766 | |
| 1768 | − usf = (struct sparc_stackf32 *) ufp; | |
| 1769 | − if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | |
| 1770 | − break; | |
| 1767 | + if (thread32_stack_is_64bit(ufp)) { | |
| 1768 | + struct sparc_stackf *usf, sf; | |
| 1771 | 1769 | |
| 1772 | − pc = sf.callers_pc; | |
| 1773 | − ufp = (unsigned long)sf.fp; | |
| 1770 | + ufp += STACK_BIAS; | |
| 1771 | + usf = (struct sparc_stackf *) ufp; | |
| 1772 | + if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | |
| 1773 | + break; | |
| 1774 | + pc = sf.callers_pc & 0xffffffff; | |
| 1775 | + ufp = ((unsigned long) sf.fp) & 0xffffffff; | |
| 1776 | + } else { | |
| 1777 | + struct sparc_stackf32 *usf, sf; | |
| 1778 | + usf = (struct sparc_stackf32 *) ufp; | |
| 1779 | + if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | |
| 1780 | + break; | |
| 1781 | + pc = sf.callers_pc; | |
| 1782 | + ufp = (unsigned long)sf.fp; | |
| 1783 | + } | |
| 1774 | 1784 | perf_callchain_store(entry, pc); |
| 1775 | 1785 | } while (entry->nr < PERF_MAX_STACK_DEPTH); |
| 1776 | 1786 | } |
| @@ -452,13 +452,16 @@ void flush_thread(void) · 451 unmodified lines | ||
| 452 | 452 | /* It's a bit more tricky when 64-bit tasks are involved... */ |
| 453 | 453 | static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) |
| 454 | 454 | { |
| 455 | + bool stack_64bit = test_thread_64bit_stack(psp); | |
| 455 | 456 | unsigned long fp, distance, rval; |
| 456 | 457 | |
| 457 | − if (!(test_thread_flag(TIF_32BIT))) { | |
| 458 | + if (stack_64bit) { | |
| 458 | 459 | csp += STACK_BIAS; |
| 459 | 460 | psp += STACK_BIAS; |
| 460 | 461 | __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); |
| 461 | 462 | fp += STACK_BIAS; |
| 463 | + if (test_thread_flag(TIF_32BIT)) | |
| 464 | + fp &= 0xffffffff; | |
| 462 | 465 | } else |
| 463 | 466 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); |
| 464 | 467 | |
| @@ -472,7 +475,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) · 7 unmodified lines | ||
| 472 | 475 | rval = (csp - distance); |
| 473 | 476 | if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) |
| 474 | 477 | rval = 0; |
| 475 | − else if (test_thread_flag(TIF_32BIT)) { | |
| 478 | + else if (!stack_64bit) { | |
| 476 | 479 | if (put_user(((u32)csp), |
| 477 | 480 | &(((struct reg_window32 __user *)rval)->ins[6]))) |
| 478 | 481 | rval = 0; |
| @@ -507,18 +510,18 @@ void synchronize_user_stack(void) · 28 unmodified lines | ||
| 507 | 510 | |
| 508 | 511 | flush_user_windows(); |
| 509 | 512 | if ((window = get_thread_wsaved()) != 0) { |
| 510 | − int winsize = sizeof(struct reg_window); | |
| 511 | − int bias = 0; | |
| 512 | − | |
| 513 | − if (test_thread_flag(TIF_32BIT)) | |
| 514 | − winsize = sizeof(struct reg_window32); | |
| 515 | − else | |
| 516 | − bias = STACK_BIAS; | |
| 517 | − | |
| 518 | 513 | window -= 1; |
| 519 | 514 | do { |
| 520 | − unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | |
| 521 | 515 | struct reg_window *rwin = &t->reg_window[window]; |
| 516 | + int winsize = sizeof(struct reg_window); | |
| 517 | + unsigned long sp; | |
| 518 | + | |
| 519 | + sp = t->rwbuf_stkptrs[window]; | |
| 520 | + | |
| 521 | + if (test_thread_64bit_stack(sp)) | |
| 522 | + sp += STACK_BIAS; | |
| 523 | + else | |
| 524 | + winsize = sizeof(struct reg_window32); | |
| 522 | 525 | |
| 523 | 526 | if (!copy_to_user((char __user *)sp, rwin, winsize)) { |
| 524 | 527 | shift_window_buffer(window, get_thread_wsaved() - 1, t); |
| @@ -544,13 +547,6 @@ void fault_in_user_windows(void) · 19 unmodified lines | ||
| 544 | 547 | { |
| 545 | 548 | struct thread_info *t = current_thread_info(); |
| 546 | 549 | unsigned long window; |
| 547 | − int winsize = sizeof(struct reg_window); | |
| 548 | − int bias = 0; | |
| 549 | − | |
| 550 | − if (test_thread_flag(TIF_32BIT)) | |
| 551 | − winsize = sizeof(struct reg_window32); | |
| 552 | − else | |
| 553 | − bias = STACK_BIAS; | |
| 554 | 550 | |
| 555 | 551 | flush_user_windows(); |
| 556 | 552 | window = get_thread_wsaved(); |
| @@ -558,8 +554,16 @@ void fault_in_user_windows(void) · 1 unmodified line | ||
| 558 | 554 | if (likely(window != 0)) { |
| 559 | 555 | window -= 1; |
| 560 | 556 | do { |
| 561 | − unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | |
| 562 | 557 | struct reg_window *rwin = &t->reg_window[window]; |
| 558 | + int winsize = sizeof(struct reg_window); | |
| 559 | + unsigned long sp; | |
| 560 | + | |
| 561 | + sp = t->rwbuf_stkptrs[window]; | |
| 562 | + | |
| 563 | + if (test_thread_64bit_stack(sp)) | |
| 564 | + sp += STACK_BIAS; | |
| 565 | + else | |
| 566 | + winsize = sizeof(struct reg_window32); | |
| 563 | 567 | |
| 564 | 568 | if (unlikely(sp & 0x7UL)) |
| 565 | 569 | stack_unaligned(sp); |
| @@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target, · 150 unmodified lines | ||
| 151 | 151 | { |
| 152 | 152 | unsigned long rw_addr = regs->u_regs[UREG_I6]; |
| 153 | 153 | |
| 154 | − if (test_tsk_thread_flag(current, TIF_32BIT)) { | |
| 154 | + if (!test_thread_64bit_stack(rw_addr)) { | |
| 155 | 155 | struct reg_window32 win32; |
| 156 | 156 | int i; |
| 157 | 157 | |
| @@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target, · 18 unmodified lines | ||
| 176 | 176 | { |
| 177 | 177 | unsigned long rw_addr = regs->u_regs[UREG_I6]; |
| 178 | 178 | |
| 179 | − if (test_tsk_thread_flag(current, TIF_32BIT)) { | |
| 179 | + if (!test_thread_64bit_stack(rw_addr)) { | |
| 180 | 180 | struct reg_window32 win32; |
| 181 | 181 | int i; |
| 182 | 182 | |
| @@ -316,6 +316,25 @@ static void __init popc_patch(void) · 315 unmodified lines | ||
| 316 | 316 | } |
| 317 | 317 | } |
| 318 | 318 | |
| 319 | +static void __init pause_patch(void) | |
| 320 | +{ | |
| 321 | + struct pause_patch_entry *p; | |
| 322 | + | |
| 323 | + p = &__pause_3insn_patch; | |
| 324 | + while (p < &__pause_3insn_patch_end) { | |
| 325 | + unsigned long i, addr = p->addr; | |
| 326 | + | |
| 327 | + for (i = 0; i < 3; i++) { | |
| 328 | + *(unsigned int *) (addr + (i * 4)) = p->insns[i]; | |
| 329 | + wmb(); | |
| 330 | + __asm__ __volatile__("flush %0" | |
| 331 | + : : "r" (addr + (i * 4))); | |
| 332 | + } | |
| 333 | + | |
| 334 | + p++; | |
| 335 | + } | |
| 336 | +} | |
| 337 | + | |
| 319 | 338 | #ifdef CONFIG_SMP |
| 320 | 339 | void __init boot_cpu_id_too_large(int cpu) |
| 321 | 340 | { |
| @@ -528,6 +547,8 @@ static void __init init_sparc64_elf_hwcap(void) · 206 unmodified lines | ||
| 528 | 547 | |
| 529 | 548 | if (sparc64_elf_hwcap & AV_SPARC_POPC) |
| 530 | 549 | popc_patch(); |
| 550 | + if (sparc64_elf_hwcap & AV_SPARC_PAUSE) | |
| 551 | + pause_patch(); | |
| 531 | 552 | } |
| 532 | 553 | |
| 533 | 554 | void __init setup_arch(char **cmdline_p) |
| @@ -751,3 +751,8 @@ int kernel_execve(const char *filename, · 750 unmodified lines | ||
| 751 | 751 | : "cc"); |
| 752 | 752 | return __res; |
| 753 | 753 | } |
| 754 | + | |
| 755 | +asmlinkage long sys_kern_features(void) | |
| 756 | +{ | |
| 757 | + return KERN_FEATURE_MIXED_MODE_STACK; | |
| 758 | +} | |
| @@ -85,3 +85,4 @@ sys_call_table: · 84 unmodified lines | ||
| 85 | 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
| 86 | 86 | /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
| 87 | 87 | /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev |
| 88 | +/*340*/ .long sys_ni_syscall, sys_kcmp | |
| @@ -86,6 +86,7 @@ sys_call_table32: · 85 unmodified lines | ||
| 86 | 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init |
| 87 | 87 | /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime |
| 88 | 88 | .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev |
| 89 | +/*340*/ .word sys_kern_features, sys_kcmp | |
| 89 | 90 | |
| 90 | 91 | #endif /* CONFIG_COMPAT */ |
| 91 | 92 | |
| @@ -163,3 +164,4 @@ sys_call_table: · 71 unmodified lines | ||
| 163 | 164 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
| 164 | 165 | /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
| 165 | 166 | .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev |
| 167 | +/*340*/ .word sys_kern_features, sys_kcmp | |
| @@ -113,21 +113,24 @@ static inline long sign_extend_imm13(long imm) · 112 unmodified lines | ||
| 113 | 113 | |
| 114 | 114 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) |
| 115 | 115 | { |
| 116 | − unsigned long value; | |
| 116 | + unsigned long value, fp; | |
| 117 | 117 | |
| 118 | 118 | if (reg < 16) |
| 119 | 119 | return (!reg ? 0 : regs->u_regs[reg]); |
| 120 | + | |
| 121 | + fp = regs->u_regs[UREG_FP]; | |
| 122 | + | |
| 120 | 123 | if (regs->tstate & TSTATE_PRIV) { |
| 121 | 124 | struct reg_window *win; |
| 122 | − win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 125 | + win = (struct reg_window *)(fp + STACK_BIAS); | |
| 123 | 126 | value = win->locals[reg - 16]; |
| 124 | − } else if (test_thread_flag(TIF_32BIT)) { | |
| 127 | + } else if (!test_thread_64bit_stack(fp)) { | |
| 125 | 128 | struct reg_window32 __user *win32; |
| 126 | − win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 129 | + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); | |
| 127 | 130 | get_user(value, &win32->locals[reg - 16]); |
| 128 | 131 | } else { |
| 129 | 132 | struct reg_window __user *win; |
| 130 | − win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 133 | + win = (struct reg_window __user *)(fp + STACK_BIAS); | |
| 131 | 134 | get_user(value, &win->locals[reg - 16]); |
| 132 | 135 | } |
| 133 | 136 | return value; |
| @@ -135,19 +138,24 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) · 1 unmodified line | ||
| 135 | 138 | |
| 136 | 139 | static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) |
| 137 | 140 | { |
| 141 | + unsigned long fp; | |
| 142 | + | |
| 138 | 143 | if (reg < 16) |
| 139 | 144 | return ®s->u_regs[reg]; |
| 145 | + | |
| 146 | + fp = regs->u_regs[UREG_FP]; | |
| 147 | + | |
| 140 | 148 | if (regs->tstate & TSTATE_PRIV) { |
| 141 | 149 | struct reg_window *win; |
| 142 | − win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 150 | + win = (struct reg_window *)(fp + STACK_BIAS); | |
| 143 | 151 | return &win->locals[reg - 16]; |
| 144 | − } else if (test_thread_flag(TIF_32BIT)) { | |
| 152 | + } else if (!test_thread_64bit_stack(fp)) { | |
| 145 | 153 | struct reg_window32 *win32; |
| 146 | − win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 154 | + win32 = (struct reg_window32 *)((unsigned long)((u32)fp)); | |
| 147 | 155 | return (unsigned long *)&win32->locals[reg - 16]; |
| 148 | 156 | } else { |
| 149 | 157 | struct reg_window *win; |
| 150 | − win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 158 | + win = (struct reg_window *)(fp + STACK_BIAS); | |
| 151 | 159 | return &win->locals[reg - 16]; |
| 152 | 160 | } |
| 153 | 161 | } |
| @@ -392,13 +400,15 @@ int handle_popc(u32 insn, struct pt_regs *regs) · 238 unmodified lines | ||
| 392 | 400 | if (rd) |
| 393 | 401 | regs->u_regs[rd] = ret; |
| 394 | 402 | } else { |
| 395 | − if (test_thread_flag(TIF_32BIT)) { | |
| 403 | + unsigned long fp = regs->u_regs[UREG_FP]; | |
| 404 | + | |
| 405 | + if (!test_thread_64bit_stack(fp)) { | |
| 396 | 406 | struct reg_window32 __user *win32; |
| 397 | − win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 407 | + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); | |
| 398 | 408 | put_user(ret, &win32->locals[rd - 16]); |
| 399 | 409 | } else { |
| 400 | 410 | struct reg_window __user *win; |
| 401 | − win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 411 | + win = (struct reg_window __user *)(fp + STACK_BIAS); | |
| 402 | 412 | put_user(ret, &win->locals[rd - 16]); |
| 403 | 413 | } |
| 404 | 414 | } |
| @@ -554,7 +564,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) · 149 unmodified lines | ||
| 554 | 564 | reg[0] = 0; |
| 555 | 565 | if ((insn & 0x780000) == 0x180000) |
| 556 | 566 | reg[1] = 0; |
| 557 | − } else if (test_thread_flag(TIF_32BIT)) { | |
| 567 | + } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { | |
| 558 | 568 | put_user(0, (int __user *) reg); |
| 559 | 569 | if ((insn & 0x780000) == 0x180000) |
| 560 | 570 | put_user(0, ((int __user *) reg) + 1); |
| @@ -149,21 +149,24 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, · 148 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) |
| 151 | 151 | { |
| 152 | − unsigned long value; | |
| 152 | + unsigned long value, fp; | |
| 153 | 153 | |
| 154 | 154 | if (reg < 16) |
| 155 | 155 | return (!reg ? 0 : regs->u_regs[reg]); |
| 156 | + | |
| 157 | + fp = regs->u_regs[UREG_FP]; | |
| 158 | + | |
| 156 | 159 | if (regs->tstate & TSTATE_PRIV) { |
| 157 | 160 | struct reg_window *win; |
| 158 | − win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 161 | + win = (struct reg_window *)(fp + STACK_BIAS); | |
| 159 | 162 | value = win->locals[reg - 16]; |
| 160 | − } else if (test_thread_flag(TIF_32BIT)) { | |
| 163 | + } else if (!test_thread_64bit_stack(fp)) { | |
| 161 | 164 | struct reg_window32 __user *win32; |
| 162 | − win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 165 | + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); | |
| 163 | 166 | get_user(value, &win32->locals[reg - 16]); |
| 164 | 167 | } else { |
| 165 | 168 | struct reg_window __user *win; |
| 166 | − win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 169 | + win = (struct reg_window __user *)(fp + STACK_BIAS); | |
| 167 | 170 | get_user(value, &win->locals[reg - 16]); |
| 168 | 171 | } |
| 169 | 172 | return value; |
| @@ -172,16 +175,18 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) · 2 unmodified lines | ||
| 172 | 175 | static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, |
| 173 | 176 | struct pt_regs *regs) |
| 174 | 177 | { |
| 178 | + unsigned long fp = regs->u_regs[UREG_FP]; | |
| 179 | + | |
| 175 | 180 | BUG_ON(reg < 16); |
| 176 | 181 | BUG_ON(regs->tstate & TSTATE_PRIV); |
| 177 | 182 | |
| 178 | − if (test_thread_flag(TIF_32BIT)) { | |
| 183 | + if (!test_thread_64bit_stack(fp)) { | |
| 179 | 184 | struct reg_window32 __user *win32; |
| 180 | − win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 185 | + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); | |
| 181 | 186 | return (unsigned long __user *)&win32->locals[reg - 16]; |
| 182 | 187 | } else { |
| 183 | 188 | struct reg_window __user *win; |
| 184 | − win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 189 | + win = (struct reg_window __user *)(fp + STACK_BIAS); | |
| 185 | 190 | return &win->locals[reg - 16]; |
| 186 | 191 | } |
| 187 | 192 | } |
| @@ -204,7 +209,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd) · 16 unmodified lines | ||
| 204 | 209 | } else { |
| 205 | 210 | unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); |
| 206 | 211 | |
| 207 | − if (test_thread_flag(TIF_32BIT)) | |
| 212 | + if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) | |
| 208 | 213 | __put_user((u32)val, (u32 __user *)rd_user); |
| 209 | 214 | else |
| 210 | 215 | __put_user(val, rd_user); |
| @@ -132,6 +132,11 @@ SECTIONS · 131 unmodified lines | ||
| 132 | 132 | *(.popc_6insn_patch) |
| 133 | 133 | __popc_6insn_patch_end = .; |
| 134 | 134 | } |
| 135 | + .pause_3insn_patch : { | |
| 136 | + __pause_3insn_patch = .; | |
| 137 | + *(.pause_3insn_patch) | |
| 138 | + __pause_3insn_patch_end = .; | |
| 139 | + } | |
| 135 | 140 | PERCPU_SECTION(SMP_CACHE_BYTES) |
| 136 | 141 | |
| 137 | 142 | . = ALIGN(PAGE_SIZE); |
| @@ -43,6 +43,8 @@ spill_fixup_mna: · 42 unmodified lines | ||
| 43 | 43 | spill_fixup_dax: |
| 44 | 44 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
| 45 | 45 | ldx [%g6 + TI_FLAGS], %g1 |
| 46 | + andcc %sp, 0x1, %g0 | |
| 47 | + movne %icc, 0, %g1 | |
| 46 | 48 | andcc %g1, _TIF_32BIT, %g0 |
| 47 | 49 | ldub [%g6 + TI_WSAVED], %g1 |
| 48 | 50 | sll %g1, 3, %g3 |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* atomic.S: These things are too big to do inline. |
| 2 | 2 | * |
| 3 | − * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) | |
| 3 | + * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) | |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | #include <linux/linkage.h> |
| @@ -117,3 +117,17 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ · 110 unmodified lines | ||
| 117 | 117 | sub %g1, %o0, %o0 |
| 118 | 118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
| 119 | 119 | ENDPROC(atomic64_sub_ret) |
| 120 | + | |
| 121 | +ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ | |
| 122 | + BACKOFF_SETUP(%o2) | |
| 123 | +1: ldx [%o0], %g1 | |
| 124 | + brlez,pn %g1, 3f | |
| 125 | + sub %g1, 1, %g7 | |
| 126 | + casx [%o0], %g1, %g7 | |
| 127 | + cmp %g1, %g7 | |
| 128 | + bne,pn %xcc, BACKOFF_LABEL(2f, 1b) | |
| 129 | + nop | |
| 130 | +3: retl | |
| 131 | + sub %g1, 1, %o0 | |
| 132 | +2: BACKOFF_SPIN(%o2, %o3, 1b) | |
| 133 | +ENDPROC(atomic64_dec_if_positive) | |
| @@ -116,6 +116,7 @@ EXPORT_SYMBOL(atomic64_add); · 115 unmodified lines | ||
| 116 | 116 | EXPORT_SYMBOL(atomic64_add_ret); |
| 117 | 117 | EXPORT_SYMBOL(atomic64_sub); |
| 118 | 118 | EXPORT_SYMBOL(atomic64_sub_ret); |
| 119 | +EXPORT_SYMBOL(atomic64_dec_if_positive); | |
| 119 | 120 | |
| 120 | 121 | /* Atomic bit operations. */ |
| 121 | 122 | EXPORT_SYMBOL(test_and_set_bit); |
| @@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) · 319 unmodified lines | ||
| 320 | 320 | XR = 0; |
| 321 | 321 | else if (freg < 16) |
| 322 | 322 | XR = regs->u_regs[freg]; |
| 323 | − else if (test_thread_flag(TIF_32BIT)) { | |
| 323 | + else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { | |
| 324 | 324 | struct reg_window32 __user *win32; |
| 325 | 325 | flushw_user (); |
| 326 | 326 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); |
| @@ -16,6 +16,8 @@ config UNICORE32 · 15 unmodified lines | ||
| 16 | 16 | select ARCH_WANT_FRAME_POINTERS |
| 17 | 17 | select GENERIC_IOMAP |
| 18 | 18 | select MODULES_USE_ELF_REL |
| 19 | + select GENERIC_KERNEL_THREAD | |
| 20 | + select GENERIC_KERNEL_EXECVE | |
| 19 | 21 | help |
| 20 | 22 | UniCore-32 is 32-bit Instruction Set Architecture, |
| 21 | 23 | including a series of low-power-consumption RISC chip |
| @@ -64,6 +66,9 @@ config GENERIC_CALIBRATE_DELAY · 42 unmodified lines | ||
| 64 | 66 | config ARCH_MAY_HAVE_PC_FDC |
| 65 | 67 | bool |
| 66 | 68 | |
| 69 | +config ZONE_DMA | |
| 70 | + def_bool y | |
| 71 | + | |
| 67 | 72 | config NEED_DMA_MAP_STATE |
| 68 | 73 | def_bool y |
| 69 | 74 | |
| @@ -216,7 +221,7 @@ config PUV3_GPIO · 146 unmodified lines | ||
| 216 | 221 | bool |
| 217 | 222 | depends on !ARCH_FPGA |
| 218 | 223 | select GENERIC_GPIO |
| 219 | − select GPIO_SYSFS if EXPERIMENTAL | |
| 224 | + select GPIO_SYSFS | |
| 220 | 225 | default y |
| 221 | 226 | |
| 222 | 227 | if PUV3_NB0916 |
| @@ -1,4 +1,3 @@ | ||
| 1 | −include include/asm-generic/Kbuild.asm | |
| 2 | 1 | |
| 3 | 2 | generic-y += atomic.h |
| 4 | 3 | generic-y += auxvec.h |
| @@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err); · 18 unmodified lines | ||
| 19 | 19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, |
| 20 | 20 | struct siginfo *info, unsigned long err, unsigned long trap); |
| 21 | 21 | |
| 22 | −extern asmlinkage void __backtrace(void); | |
| 23 | −extern asmlinkage void c_backtrace(unsigned long fp, int pmode); | |
| 24 | − | |
| 25 | −extern void __show_regs(struct pt_regs *); | |
| 26 | − | |
| 27 | 22 | #endif /* __UNICORE_BUG_H__ */ |
| @@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, · 34 unmodified lines | ||
| 35 | 35 | : "memory", "cc"); |
| 36 | 36 | break; |
| 37 | 37 | default: |
| 38 | − ret = __xchg_bad_pointer(); | |
| 38 | + __xchg_bad_pointer(); | |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | return ret; |
| @@ -1 +0,0 @@ | ||
| 1 | −#include <asm-generic/kvm_para.h> | |
| @@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p); · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | #define cpu_relax() barrier() |
| 74 | 74 | |
| 75 | −/* | |
| 76 | − * Create a new kernel thread | |
| 77 | − */ | |
| 78 | −extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | |
| 79 | − | |
| 80 | 75 | #define task_pt_regs(p) \ |
| 81 | 76 | ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) |
| 82 | 77 | |
| @@ -12,80 +12,10 @@ · 11 unmodified lines | ||
| 12 | 12 | #ifndef __UNICORE_PTRACE_H__ |
| 13 | 13 | #define __UNICORE_PTRACE_H__ |
| 14 | 14 | |
| 15 | −#define PTRACE_GET_THREAD_AREA 22 | |
| 16 | − | |
| 17 | −/* | |
| 18 | − * PSR bits | |
| 19 | − */ | |
| 20 | −#define USER_MODE 0x00000010 | |
| 21 | −#define REAL_MODE 0x00000011 | |
| 22 | −#define INTR_MODE 0x00000012 | |
| 23 | −#define PRIV_MODE 0x00000013 | |
| 24 | −#define ABRT_MODE 0x00000017 | |
| 25 | −#define EXTN_MODE 0x0000001b | |
| 26 | −#define SUSR_MODE 0x0000001f | |
| 27 | −#define MODE_MASK 0x0000001f | |
| 28 | −#define PSR_R_BIT 0x00000040 | |
| 29 | −#define PSR_I_BIT 0x00000080 | |
| 30 | −#define PSR_V_BIT 0x10000000 | |
| 31 | −#define PSR_C_BIT 0x20000000 | |
| 32 | −#define PSR_Z_BIT 0x40000000 | |
| 33 | −#define PSR_S_BIT 0x80000000 | |
| 34 | − | |
| 35 | −/* | |
| 36 | − * Groups of PSR bits | |
| 37 | − */ | |
| 38 | −#define PSR_f 0xff000000 /* Flags */ | |
| 39 | −#define PSR_c 0x000000ff /* Control */ | |
| 15 | +#include <uapi/asm/ptrace.h> | |
| 40 | 16 | |
| 41 | 17 | #ifndef __ASSEMBLY__ |
| 42 | 18 | |
| 43 | −/* | |
| 44 | − * This struct defines the way the registers are stored on the | |
| 45 | − * stack during a system call. Note that sizeof(struct pt_regs) | |
| 46 | − * has to be a multiple of 8. | |
| 47 | − */ | |
| 48 | −struct pt_regs { | |
| 49 | − unsigned long uregs[34]; | |
| 50 | −}; | |
| 51 | − | |
| 52 | −#define UCreg_asr uregs[32] | |
| 53 | −#define UCreg_pc uregs[31] | |
| 54 | −#define UCreg_lr uregs[30] | |
| 55 | −#define UCreg_sp uregs[29] | |
| 56 | −#define UCreg_ip uregs[28] | |
| 57 | −#define UCreg_fp uregs[27] | |
| 58 | −#define UCreg_26 uregs[26] | |
| 59 | −#define UCreg_25 uregs[25] | |
| 60 | −#define UCreg_24 uregs[24] | |
| 61 | −#define UCreg_23 uregs[23] | |
| 62 | −#define UCreg_22 uregs[22] | |
| 63 | −#define UCreg_21 uregs[21] | |
| 64 | −#define UCreg_20 uregs[20] | |
| 65 | −#define UCreg_19 uregs[19] | |
| 66 | −#define UCreg_18 uregs[18] | |
| 67 | −#define UCreg_17 uregs[17] | |
| 68 | −#define UCreg_16 uregs[16] | |
| 69 | −#define UCreg_15 uregs[15] | |
| 70 | −#define UCreg_14 uregs[14] | |
| 71 | −#define UCreg_13 uregs[13] | |
| 72 | −#define UCreg_12 uregs[12] | |
| 73 | −#define UCreg_11 uregs[11] | |
| 74 | −#define UCreg_10 uregs[10] | |
| 75 | −#define UCreg_09 uregs[9] | |
| 76 | −#define UCreg_08 uregs[8] | |
| 77 | −#define UCreg_07 uregs[7] | |
| 78 | −#define UCreg_06 uregs[6] | |
| 79 | −#define UCreg_05 uregs[5] | |
| 80 | −#define UCreg_04 uregs[4] | |
| 81 | −#define UCreg_03 uregs[3] | |
| 82 | −#define UCreg_02 uregs[2] | |
| 83 | −#define UCreg_01 uregs[1] | |
| 84 | −#define UCreg_00 uregs[0] | |
| 85 | −#define UCreg_ORIG_00 uregs[33] | |
| 86 | − | |
| 87 | −#ifdef __KERNEL__ | |
| 88 | − | |
| 89 | 19 | #define user_mode(regs) \ |
| 90 | 20 | (processor_mode(regs) == USER_MODE) |
| 91 | 21 | |
| @@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs) · 33 unmodified lines | ||
| 125 | 55 | |
| 126 | 56 | #define instruction_pointer(regs) ((regs)->UCreg_pc) |
| 127 | 57 | |
| 128 | −#endif /* __KERNEL__ */ | |
| 129 | − | |
| 130 | 58 | #endif /* __ASSEMBLY__ */ |
| 131 | − | |
| 132 | 59 | #endif |
| 133 | − | |
| @@ -1,3 +1,10 @@ | ||
| 1 | 1 | # UAPI Header export list |
| 2 | 2 | include include/uapi/asm-generic/Kbuild.asm |
| 3 | 3 | |
| 4 | +header-y += byteorder.h | |
| 5 | +header-y += kvm_para.h | |
| 6 | +header-y += ptrace.h | |
| 7 | +header-y += sigcontext.h | |
| 8 | +header-y += unistd.h | |
| 9 | + | |
| 10 | +generic-y += kvm_para.h | |
File renamed without changes.
| @@ -0,0 +1,90 @@ | ||
| 1 | +/* | |
| 2 | + * linux/arch/unicore32/include/asm/ptrace.h | |
| 3 | + * | |
| 4 | + * Code specific to PKUnity SoC and UniCore ISA | |
| 5 | + * | |
| 6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
| 7 | + * | |
| 8 | + * This program is free software; you can redistribute it and/or modify | |
| 9 | + * it under the terms of the GNU General Public License version 2 as | |
| 10 | + * published by the Free Software Foundation. | |
| 11 | + */ | |
| 12 | +#ifndef _UAPI__UNICORE_PTRACE_H__ | |
| 13 | +#define _UAPI__UNICORE_PTRACE_H__ | |
| 14 | + | |
| 15 | +#define PTRACE_GET_THREAD_AREA 22 | |
| 16 | + | |
| 17 | +/* | |
| 18 | + * PSR bits | |
| 19 | + */ | |
| 20 | +#define USER_MODE 0x00000010 | |
| 21 | +#define REAL_MODE 0x00000011 | |
| 22 | +#define INTR_MODE 0x00000012 | |
| 23 | +#define PRIV_MODE 0x00000013 | |
| 24 | +#define ABRT_MODE 0x00000017 | |
| 25 | +#define EXTN_MODE 0x0000001b | |
| 26 | +#define SUSR_MODE 0x0000001f | |
| 27 | +#define MODE_MASK 0x0000001f | |
| 28 | +#define PSR_R_BIT 0x00000040 | |
| 29 | +#define PSR_I_BIT 0x00000080 | |
| 30 | +#define PSR_V_BIT 0x10000000 | |
| 31 | +#define PSR_C_BIT 0x20000000 | |
| 32 | +#define PSR_Z_BIT 0x40000000 | |
| 33 | +#define PSR_S_BIT 0x80000000 | |
| 34 | + | |
| 35 | +/* | |
| 36 | + * Groups of PSR bits | |
| 37 | + */ | |
| 38 | +#define PSR_f 0xff000000 /* Flags */ | |
| 39 | +#define PSR_c 0x000000ff /* Control */ | |
| 40 | + | |
| 41 | +#ifndef __ASSEMBLY__ | |
| 42 | + | |
| 43 | +/* | |
| 44 | + * This struct defines the way the registers are stored on the | |
| 45 | + * stack during a system call. Note that sizeof(struct pt_regs) | |
| 46 | + * has to be a multiple of 8. | |
| 47 | + */ | |
| 48 | +struct pt_regs { | |
| 49 | + unsigned long uregs[34]; | |
| 50 | +}; | |
| 51 | + | |
| 52 | +#define UCreg_asr uregs[32] | |
| 53 | +#define UCreg_pc uregs[31] | |
| 54 | +#define UCreg_lr uregs[30] | |
| 55 | +#define UCreg_sp uregs[29] | |
| 56 | +#define UCreg_ip uregs[28] | |
| 57 | +#define UCreg_fp uregs[27] | |
| 58 | +#define UCreg_26 uregs[26] | |
| 59 | +#define UCreg_25 uregs[25] | |
| 60 | +#define UCreg_24 uregs[24] | |
| 61 | +#define UCreg_23 uregs[23] | |
| 62 | +#define UCreg_22 uregs[22] | |
| 63 | +#define UCreg_21 uregs[21] | |
| 64 | +#define UCreg_20 uregs[20] | |
| 65 | +#define UCreg_19 uregs[19] | |
| 66 | +#define UCreg_18 uregs[18] | |
| 67 | +#define UCreg_17 uregs[17] | |
| 68 | +#define UCreg_16 uregs[16] | |
| 69 | +#define UCreg_15 uregs[15] | |
| 70 | +#define UCreg_14 uregs[14] | |
| 71 | +#define UCreg_13 uregs[13] | |
| 72 | +#define UCreg_12 uregs[12] | |
| 73 | +#define UCreg_11 uregs[11] | |
| 74 | +#define UCreg_10 uregs[10] | |
| 75 | +#define UCreg_09 uregs[9] | |
| 76 | +#define UCreg_08 uregs[8] | |
| 77 | +#define UCreg_07 uregs[7] | |
| 78 | +#define UCreg_06 uregs[6] | |
| 79 | +#define UCreg_05 uregs[5] | |
| 80 | +#define UCreg_04 uregs[4] | |
| 81 | +#define UCreg_03 uregs[3] | |
| 82 | +#define UCreg_02 uregs[2] | |
| 83 | +#define UCreg_01 uregs[1] | |
| 84 | +#define UCreg_00 uregs[0] | |
| 85 | +#define UCreg_ORIG_00 uregs[33] | |
| 86 | + | |
| 87 | + | |
| 88 | +#endif /* __ASSEMBLY__ */ | |
| 89 | + | |
| 90 | +#endif /* _UAPI__UNICORE_PTRACE_H__ */ | |
File renamed without changes.
| @@ -12,3 +12,4 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | /* Use the standard ABI for syscalls. */ |
| 14 | 14 | #include <asm-generic/unistd.h> |
| 15 | +#define __ARCH_WANT_SYS_EXECVE | |
| @@ -573,17 +573,16 @@ ENDPROC(ret_to_user) · 572 unmodified lines | ||
| 573 | 573 | */ |
| 574 | 574 | ENTRY(ret_from_fork) |
| 575 | 575 | b.l schedule_tail |
| 576 | − get_thread_info tsk | |
| 577 | − ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing | |
| 578 | − mov why, #1 | |
| 579 | − cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? | |
| 580 | − beq ret_slow_syscall | |
| 581 | − mov r1, sp | |
| 582 | − mov r0, #1 @ trace exit [IP = 1] | |
| 583 | − b.l syscall_trace | |
| 584 | 576 | b ret_slow_syscall |
| 585 | 577 | ENDPROC(ret_from_fork) |
| 586 | 578 | |
| 579 | +ENTRY(ret_from_kernel_thread) | |
| 580 | + b.l schedule_tail | |
| 581 | + mov r0, r5 | |
| 582 | + adr lr, ret_slow_syscall | |
| 583 | + mov pc, r4 | |
| 584 | +ENDPROC(ret_from_kernel_thread) | |
| 585 | + | |
| 587 | 586 | /*============================================================================= |
| 588 | 587 | * SWI handler |
| 589 | 588 | *----------------------------------------------------------------------------- |
| @@ -669,11 +668,6 @@ __cr_alignment: · 79 unmodified lines | ||
| 669 | 668 | #endif |
| 670 | 669 | .ltorg |
| 671 | 670 | |
| 672 | −ENTRY(sys_execve) | |
| 673 | − add r3, sp, #S_OFF | |
| 674 | − b __sys_execve | |
| 675 | −ENDPROC(sys_execve) | |
| 676 | − | |
| 677 | 671 | ENTRY(sys_clone) |
| 678 | 672 | add ip, sp, #S_OFF |
| 679 | 673 | stw ip, [sp+], #4 |
| @@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task) · 257 unmodified lines | ||
| 258 | 258 | } |
| 259 | 259 | |
| 260 | 260 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
| 261 | +asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); | |
| 261 | 262 | |
| 262 | 263 | int |
| 263 | 264 | copy_thread(unsigned long clone_flags, unsigned long stack_start, |
| @@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, · 2 unmodified lines | ||
| 266 | 267 | struct thread_info *thread = task_thread_info(p); |
| 267 | 268 | struct pt_regs *childregs = task_pt_regs(p); |
| 268 | 269 | |
| 269 | − *childregs = *regs; | |
| 270 | − childregs->UCreg_00 = 0; | |
| 271 | − childregs->UCreg_sp = stack_start; | |
| 272 | − | |
| 273 | 270 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); |
| 274 | 271 | thread->cpu_context.sp = (unsigned long)childregs; |
| 275 | − thread->cpu_context.pc = (unsigned long)ret_from_fork; | |
| 276 | − | |
| 277 | − if (clone_flags & CLONE_SETTLS) | |
| 278 | − childregs->UCreg_16 = regs->UCreg_03; | |
| 272 | + if (unlikely(!regs)) { | |
| 273 | + thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; | |
| 274 | + thread->cpu_context.r4 = stack_start; | |
| 275 | + thread->cpu_context.r5 = stk_sz; | |
| 276 | + memset(childregs, 0, sizeof(struct pt_regs)); | |
| 277 | + } else { | |
| 278 | + thread->cpu_context.pc = (unsigned long)ret_from_fork; | |
| 279 | + *childregs = *regs; | |
| 280 | + childregs->UCreg_00 = 0; | |
| 281 | + childregs->UCreg_sp = stack_start; | |
| 279 | 282 | |
| 283 | + if (clone_flags & CLONE_SETTLS) | |
| 284 | + childregs->UCreg_16 = regs->UCreg_03; | |
| 285 | + } | |
| 280 | 286 | return 0; |
| 281 | 287 | } |
| 282 | 288 | |
| @@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) · 22 unmodified lines | ||
| 305 | 311 | } |
| 306 | 312 | EXPORT_SYMBOL(dump_fpu); |
| 307 | 313 | |
| 308 | −/* | |
| 309 | − * Shuffle the argument into the correct register before calling the | |
| 310 | − * thread function. r1 is the thread argument, r2 is the pointer to | |
| 311 | − * the thread function, and r3 points to the exit function. | |
| 312 | − */ | |
| 313 | −asm(".pushsection .text\n" | |
| 314 | −" .align\n" | |
| 315 | −" .type kernel_thread_helper, #function\n" | |
| 316 | −"kernel_thread_helper:\n" | |
| 317 | −" mov.a asr, r7\n" | |
| 318 | −" mov r0, r4\n" | |
| 319 | −" mov lr, r6\n" | |
| 320 | −" mov pc, r5\n" | |
| 321 | −" .size kernel_thread_helper, . - kernel_thread_helper\n" | |
| 322 | −" .popsection"); | |
| 323 | − | |
| 324 | −/* | |
| 325 | − * Create a kernel thread. | |
| 326 | − */ | |
| 327 | −pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | |
| 328 | −{ | |
| 329 | − struct pt_regs regs; | |
| 330 | − | |
| 331 | − memset(®s, 0, sizeof(regs)); | |
| 332 | − | |
| 333 | − regs.UCreg_04 = (unsigned long)arg; | |
| 334 | − regs.UCreg_05 = (unsigned long)fn; | |
| 335 | − regs.UCreg_06 = (unsigned long)do_exit; | |
| 336 | − regs.UCreg_07 = PRIV_MODE; | |
| 337 | − regs.UCreg_pc = (unsigned long)kernel_thread_helper; | |
| 338 | − regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; | |
| 339 | − | |
| 340 | − return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | |
| 341 | −} | |
| 342 | −EXPORT_SYMBOL(kernel_thread); | |
| 343 | − | |
| 344 | 314 | unsigned long get_wchan(struct task_struct *p) |
| 345 | 315 | { |
| 346 | 316 | struct stackframe frame; |
| @@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[]; · 29 unmodified lines | ||
| 30 | 30 | extern void kernel_thread_helper(void); |
| 31 | 31 | |
| 32 | 32 | extern void __init early_signal_init(void); |
| 33 | + | |
| 34 | +extern asmlinkage void __backtrace(void); | |
| 35 | +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); | |
| 36 | + | |
| 37 | +extern void __show_regs(struct pt_regs *); | |
| 38 | + | |
| 33 | 39 | #endif |
| @@ -42,69 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, · 41 unmodified lines | ||
| 42 | 42 | parent_tid, child_tid); |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | −/* sys_execve() executes a new program. | |
| 46 | − * This is called indirectly via a small wrapper | |
| 47 | − */ | |
| 48 | −asmlinkage long __sys_execve(const char __user *filename, | |
| 49 | − const char __user *const __user *argv, | |
| 50 | − const char __user *const __user *envp, | |
| 51 | − struct pt_regs *regs) | |
| 52 | −{ | |
| 53 | − int error; | |
| 54 | − struct filename *fn; | |
| 55 | − | |
| 56 | − fn = getname(filename); | |
| 57 | − error = PTR_ERR(fn); | |
| 58 | − if (IS_ERR(fn)) | |
| 59 | − goto out; | |
| 60 | − error = do_execve(fn->name, argv, envp, regs); | |
| 61 | − putname(fn); | |
| 62 | −out: | |
| 63 | − return error; | |
| 64 | −} | |
| 65 | − | |
| 66 | −int kernel_execve(const char *filename, | |
| 67 | − const char *const argv[], | |
| 68 | − const char *const envp[]) | |
| 69 | −{ | |
| 70 | − struct pt_regs regs; | |
| 71 | − int ret; | |
| 72 | − | |
| 73 | − memset(®s, 0, sizeof(struct pt_regs)); | |
| 74 | − ret = do_execve(filename, | |
| 75 | − (const char __user *const __user *)argv, | |
| 76 | − (const char __user *const __user *)envp, ®s); | |
| 77 | − if (ret < 0) | |
| 78 | − goto out; | |
| 79 | − | |
| 80 | − /* | |
| 81 | − * Save argc to the register structure for userspace. | |
| 82 | − */ | |
| 83 | − regs.UCreg_00 = ret; | |
| 84 | − | |
| 85 | − /* | |
| 86 | − * We were successful. We won't be returning to our caller, but | |
| 87 | − * instead to user space by manipulating the kernel stack. | |
| 88 | − */ | |
| 89 | − asm("add r0, %0, %1\n\t" | |
| 90 | − "mov r1, %2\n\t" | |
| 91 | − "mov r2, %3\n\t" | |
| 92 | − "mov r22, #0\n\t" /* not a syscall */ | |
| 93 | − "mov r23, %0\n\t" /* thread structure */ | |
| 94 | − "b.l memmove\n\t" /* copy regs to top of stack */ | |
| 95 | − "mov sp, r0\n\t" /* reposition stack pointer */ | |
| 96 | − "b ret_to_user" | |
| 97 | − : | |
| 98 | − : "r" (current_thread_info()), | |
| 99 | − "Ir" (THREAD_START_SP - sizeof(regs)), | |
| 100 | − "r" (®s), | |
| 101 | − "Ir" (sizeof(regs)) | |
| 102 | − : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); | |
| 103 | − | |
| 104 | − out: | |
| 105 | − return ret; | |
| 106 | −} | |
| 107 | − | |
| 108 | 45 | /* Note: used by the compat code even in 64-bit Linux. */ |
| 109 | 46 | SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, |
| 110 | 47 | unsigned long, prot, unsigned long, flags, |
| @@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) · 167 unmodified lines | ||
| 168 | 168 | } |
| 169 | 169 | |
| 170 | 170 | static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, |
| 171 | − struct task_struct *tsk) | |
| 171 | + unsigned int flags, struct task_struct *tsk) | |
| 172 | 172 | { |
| 173 | 173 | struct vm_area_struct *vma; |
| 174 | 174 | int fault; |
| @@ -194,14 +194,7 @@ good_area: · 19 unmodified lines | ||
| 194 | 194 | * If for any reason at all we couldn't handle the fault, make |
| 195 | 195 | * sure we exit gracefully rather than endlessly redo the fault. |
| 196 | 196 | */ |
| 197 | − fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, | |
| 198 | − (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); | |
| 199 | − if (unlikely(fault & VM_FAULT_ERROR)) | |
| 200 | − return fault; | |
| 201 | − if (fault & VM_FAULT_MAJOR) | |
| 202 | − tsk->maj_flt++; | |
| 203 | − else | |
| 204 | − tsk->min_flt++; | |
| 197 | + fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); | |
| 205 | 198 | return fault; |
| 206 | 199 | |
| 207 | 200 | check_stack: |
| @@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) · 8 unmodified lines | ||
| 216 | 209 | struct task_struct *tsk; |
| 217 | 210 | struct mm_struct *mm; |
| 218 | 211 | int fault, sig, code; |
| 212 | + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | | |
| 213 | + ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); | |
| 219 | 214 | |
| 220 | 215 | tsk = current; |
| 221 | 216 | mm = tsk->mm; |
| @@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) · 14 unmodified lines | ||
| 236 | 231 | if (!user_mode(regs) |
| 237 | 232 | && !search_exception_tables(regs->UCreg_pc)) |
| 238 | 233 | goto no_context; |
| 234 | +retry: | |
| 239 | 235 | down_read(&mm->mmap_sem); |
| 240 | 236 | } else { |
| 241 | 237 | /* |
| @@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) · 9 unmodified lines | ||
| 251 | 247 | #endif |
| 252 | 248 | } |
| 253 | 249 | |
| 254 | − fault = __do_pf(mm, addr, fsr, tsk); | |
| 250 | + fault = __do_pf(mm, addr, fsr, flags, tsk); | |
| 251 | + | |
| 252 | + /* If we need to retry but a fatal signal is pending, handle the | |
| 253 | + * signal first. We do not need to release the mmap_sem because | |
| 254 | + * it would already be released in __lock_page_or_retry in | |
| 255 | + * mm/filemap.c. */ | |
| 256 | + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | |
| 257 | + return 0; | |
| 258 | + | |
| 259 | + if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) { | |
| 260 | + if (fault & VM_FAULT_MAJOR) | |
| 261 | + tsk->maj_flt++; | |
| 262 | + else | |
| 263 | + tsk->min_flt++; | |
| 264 | + if (fault & VM_FAULT_RETRY) { | |
| 265 | + /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk | |
| 266 | + * of starvation. */ | |
| 267 | + flags &= ~FAULT_FLAG_ALLOW_RETRY; | |
| 268 | + goto retry; | |
| 269 | + } | |
| 270 | + } | |
| 271 | + | |
| 255 | 272 | up_read(&mm->mmap_sem); |
| 256 | 273 | |
| 257 | 274 | /* |
| @@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val, · 358 unmodified lines | ||
| 359 | 359 | return _hypercall4(int, update_va_mapping, va, |
| 360 | 360 | new_val.pte, new_val.pte >> 32, flags); |
| 361 | 361 | } |
| 362 | +extern int __must_check xen_event_channel_op_compat(int, void *); | |
| 362 | 363 | |
| 363 | 364 | static inline int |
| 364 | 365 | HYPERVISOR_event_channel_op(int cmd, void *arg) |
| 365 | 366 | { |
| 366 | 367 | int rc = _hypercall2(int, event_channel_op, cmd, arg); |
| 367 | − if (unlikely(rc == -ENOSYS)) { | |
| 368 | − struct evtchn_op op; | |
| 369 | − op.cmd = cmd; | |
| 370 | − memcpy(&op.u, arg, sizeof(op.u)); | |
| 371 | − rc = _hypercall1(int, event_channel_op_compat, &op); | |
| 372 | − memcpy(arg, &op.u, sizeof(op.u)); | |
| 373 | − } | |
| 368 | + if (unlikely(rc == -ENOSYS)) | |
| 369 | + rc = xen_event_channel_op_compat(cmd, arg); | |
| 374 | 370 | return rc; |
| 375 | 371 | } |
| 376 | 372 | |
| @@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str) · 9 unmodified lines | ||
| 386 | 382 | return _hypercall3(int, console_io, cmd, count, str); |
| 387 | 383 | } |
| 388 | 384 | |
| 385 | +extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); | |
| 386 | + | |
| 389 | 387 | static inline int |
| 390 | 388 | HYPERVISOR_physdev_op(int cmd, void *arg) |
| 391 | 389 | { |
| 392 | 390 | int rc = _hypercall2(int, physdev_op, cmd, arg); |
| 393 | − if (unlikely(rc == -ENOSYS)) { | |
| 394 | − struct physdev_op op; | |
| 395 | − op.cmd = cmd; | |
| 396 | − memcpy(&op.u, arg, sizeof(op.u)); | |
| 397 | − rc = _hypercall1(int, physdev_op_compat, &op); | |
| 398 | − memcpy(arg, &op.u, sizeof(op.u)); | |
| 399 | − } | |
| 391 | + if (unlikely(rc == -ENOSYS)) | |
| 392 | + rc = HYPERVISOR_physdev_op_compat(cmd, arg); | |
| 400 | 393 | return rc; |
| 401 | 394 | } |
| 402 | 395 | |
| @@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) · 23 unmodified lines | ||
| 24 | 24 | { |
| 25 | 25 | struct kvm_cpuid_entry2 *best; |
| 26 | 26 | |
| 27 | + if (!static_cpu_has(X86_FEATURE_XSAVE)) | |
| 28 | + return 0; | |
| 29 | + | |
| 27 | 30 | best = kvm_find_cpuid_entry(vcpu, 1, 0); |
| 28 | 31 | return best && (best->ecx & bit(X86_FEATURE_XSAVE)); |
| 29 | 32 | } |
| @@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) · 6548 unmodified lines | ||
| 6549 | 6549 | } |
| 6550 | 6550 | } |
| 6551 | 6551 | |
| 6552 | − exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | |
| 6553 | 6552 | /* Exposing INVPCID only when PCID is exposed */ |
| 6554 | 6553 | best = kvm_find_cpuid_entry(vcpu, 0x7, 0); |
| 6555 | 6554 | if (vmx_invpcid_supported() && |
| 6556 | 6555 | best && (best->ebx & bit(X86_FEATURE_INVPCID)) && |
| 6557 | 6556 | guest_cpuid_has_pcid(vcpu)) { |
| 6557 | + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | |
| 6558 | 6558 | exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; |
| 6559 | 6559 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, |
| 6560 | 6560 | exec_control); |
| 6561 | 6561 | } else { |
| 6562 | − exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; | |
| 6563 | − vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | |
| 6564 | − exec_control); | |
| 6562 | + if (cpu_has_secondary_exec_ctrls()) { | |
| 6563 | + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | |
| 6564 | + exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; | |
| 6565 | + vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | |
| 6566 | + exec_control); | |
| 6567 | + } | |
| 6565 | 6568 | if (best) |
| 6566 | 6569 | best->ebx &= ~bit(X86_FEATURE_INVPCID); |
| 6567 | 6570 | } |
| @@ -5781,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, · 5780 unmodified lines | ||
| 5781 | 5781 | int pending_vec, max_bits, idx; |
| 5782 | 5782 | struct desc_ptr dt; |
| 5783 | 5783 | |
| 5784 | + if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) | |
| 5785 | + return -EINVAL; | |
| 5786 | + | |
| 5784 | 5787 | dt.size = sregs->idt.limit; |
| 5785 | 5788 | dt.address = sregs->idt.base; |
| 5786 | 5789 | kvm_x86_ops->set_idt(vcpu, &dt); |
| @@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work) · 136 unmodified lines | ||
| 137 | 137 | struct crypto_async_request *req, *backlog; |
| 138 | 138 | |
| 139 | 139 | cpu_queue = container_of(work, struct cryptd_cpu_queue, work); |
| 140 | − /* Only handle one request at a time to avoid hogging crypto | |
| 141 | − * workqueue. preempt_disable/enable is used to prevent | |
| 142 | − * being preempted by cryptd_enqueue_request() */ | |
| 140 | + /* | |
| 141 | + * Only handle one request at a time to avoid hogging crypto workqueue. | |
| 142 | + * preempt_disable/enable is used to prevent being preempted by | |
| 143 | + * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent | |
| 144 | + * cryptd_enqueue_request() being accessed from software interrupts. | |
| 145 | + */ | |
| 146 | + local_bh_disable(); | |
| 143 | 147 | preempt_disable(); |
| 144 | 148 | backlog = crypto_get_backlog(&cpu_queue->queue); |
| 145 | 149 | req = crypto_dequeue_request(&cpu_queue->queue); |
| 146 | 150 | preempt_enable(); |
| 151 | + local_bh_enable(); | |
| 147 | 152 | |
| 148 | 153 | if (!req) |
| 149 | 154 | return; |
| @@ -1345,12 +1345,15 @@ static int · 1344 unmodified lines | ||
| 1345 | 1345 | acpi_video_bus_get_devices(struct acpi_video_bus *video, |
| 1346 | 1346 | struct acpi_device *device) |
| 1347 | 1347 | { |
| 1348 | − int status; | |
| 1348 | + int status = 0; | |
| 1349 | 1349 | struct acpi_device *dev; |
| 1350 | 1350 | |
| 1351 | − status = acpi_video_device_enumerate(video); | |
| 1352 | − if (status) | |
| 1353 | − return status; | |
| 1351 | + /* | |
| 1352 | + * There are systems where video module known to work fine regardless | |
| 1353 | + * of broken _DOD and ignoring returned value here doesn't cause | |
| 1354 | + * any issues later. | |
| 1355 | + */ | |
| 1356 | + acpi_video_device_enumerate(video); | |
| 1354 | 1357 | |
| 1355 | 1358 | list_for_each_entry(dev, &device->children, node) { |
| 1356 | 1359 | |
| @@ -83,9 +83,16 @@ EXPORT_SYMBOL_GPL(platform_get_resource); · 82 unmodified lines | ||
| 83 | 83 | */ |
| 84 | 84 | int platform_get_irq(struct platform_device *dev, unsigned int num) |
| 85 | 85 | { |
| 86 | +#ifdef CONFIG_SPARC | |
| 87 | + /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ | |
| 88 | + if (!dev || num >= dev->archdata.num_irqs) | |
| 89 | + return -ENXIO; | |
| 90 | + return dev->archdata.irqs[num]; | |
| 91 | +#else | |
| 86 | 92 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); |
| 87 | 93 | |
| 88 | 94 | return r ? r->start : -ENXIO; |
| 95 | +#endif | |
| 89 | 96 | } |
| 90 | 97 | EXPORT_SYMBOL_GPL(platform_get_irq); |
| 91 | 98 | |
| @@ -67,6 +67,7 @@ static struct usb_device_id ath3k_table[] = { · 66 unmodified lines | ||
| 67 | 67 | { USB_DEVICE(0x13d3, 0x3304) }, |
| 68 | 68 | { USB_DEVICE(0x0930, 0x0215) }, |
| 69 | 69 | { USB_DEVICE(0x0489, 0xE03D) }, |
| 70 | + { USB_DEVICE(0x0489, 0xE027) }, | |
| 70 | 71 | |
| 71 | 72 | /* Atheros AR9285 Malbec with sflash firmware */ |
| 72 | 73 | { USB_DEVICE(0x03F0, 0x311D) }, |
| @@ -124,6 +124,7 @@ static struct usb_device_id blacklist_table[] = { · 123 unmodified lines | ||
| 124 | 124 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, |
| 125 | 125 | { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, |
| 126 | 126 | { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, |
| 127 | + { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, | |
| 127 | 128 | |
| 128 | 129 | /* Atheros AR9285 Malbec with sflash firmware */ |
| 129 | 130 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, |
| @@ -22,6 +22,26 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/pm_runtime.h> |
| 23 | 23 | #include <linux/of.h> |
| 24 | 24 | #include <linux/of_platform.h> |
| 25 | +#include <linux/platform_data/omap_ocp2scp.h> | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * _count_resources - count for the number of resources | |
| 29 | + * @res: struct resource * | |
| 30 | + * | |
| 31 | + * Count and return the number of resources populated for the device that is | |
| 32 | + * connected to ocp2scp. | |
| 33 | + */ | |
| 34 | +static unsigned _count_resources(struct resource *res) | |
| 35 | +{ | |
| 36 | + int cnt = 0; | |
| 37 | + | |
| 38 | + while (res->start != res->end) { | |
| 39 | + cnt++; | |
| 40 | + res++; | |
| 41 | + } | |
| 42 | + | |
| 43 | + return cnt; | |
| 44 | +} | |
| 25 | 45 | |
| 26 | 46 | static int ocp2scp_remove_devices(struct device *dev, void *c) |
| 27 | 47 | { |
| @@ -34,20 +54,62 @@ static int ocp2scp_remove_devices(struct device *dev, void *c) · 6 unmodified lines | ||
| 34 | 54 | |
| 35 | 55 | static int __devinit omap_ocp2scp_probe(struct platform_device *pdev) |
| 36 | 56 | { |
| 37 | − int ret; | |
| 38 | − struct device_node *np = pdev->dev.of_node; | |
| 57 | + int ret; | |
| 58 | + unsigned res_cnt, i; | |
| 59 | + struct device_node *np = pdev->dev.of_node; | |
| 60 | + struct platform_device *pdev_child; | |
| 61 | + struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data; | |
| 62 | + struct omap_ocp2scp_dev *dev; | |
| 39 | 63 | |
| 40 | 64 | if (np) { |
| 41 | 65 | ret = of_platform_populate(np, NULL, NULL, &pdev->dev); |
| 42 | 66 | if (ret) { |
| 43 | − dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n"); | |
| 67 | + dev_err(&pdev->dev, | |
| 68 | + "failed to add resources for ocp2scp child\n"); | |
| 44 | 69 | goto err0; |
| 45 | 70 | } |
| 71 | + } else if (pdata) { | |
| 72 | + for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++, | |
| 73 | + dev++) { | |
| 74 | + res_cnt = _count_resources(dev->res); | |
| 75 | + | |
| 76 | + pdev_child = platform_device_alloc(dev->drv_name, | |
| 77 | + PLATFORM_DEVID_AUTO); | |
| 78 | + if (!pdev_child) { | |
| 79 | + dev_err(&pdev->dev, | |
| 80 | + "failed to allocate mem for ocp2scp child\n"); | |
| 81 | + goto err0; | |
| 82 | + } | |
| 83 | + | |
| 84 | + ret = platform_device_add_resources(pdev_child, | |
| 85 | + dev->res, res_cnt); | |
| 86 | + if (ret) { | |
| 87 | + dev_err(&pdev->dev, | |
| 88 | + "failed to add resources for ocp2scp child\n"); | |
| 89 | + goto err1; | |
| 90 | + } | |
| 91 | + | |
| 92 | + pdev_child->dev.parent = &pdev->dev; | |
| 93 | + | |
| 94 | + ret = platform_device_add(pdev_child); | |
| 95 | + if (ret) { | |
| 96 | + dev_err(&pdev->dev, | |
| 97 | + "failed to register ocp2scp child device\n"); | |
| 98 | + goto err1; | |
| 99 | + } | |
| 100 | + } | |
| 101 | + } else { | |
| 102 | + dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n"); | |
| 103 | + return -EINVAL; | |
| 46 | 104 | } |
| 105 | + | |
| 47 | 106 | pm_runtime_enable(&pdev->dev); |
| 48 | 107 | |
| 49 | 108 | return 0; |
| 50 | 109 | |
| 110 | +err1: | |
| 111 | + platform_device_put(pdev_child); | |
| 112 | + | |
| 51 | 113 | err0: |
| 52 | 114 | device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices); |
| 53 | 115 | |
| @@ -40,7 +40,7 @@ void u8500_clk_init(void) · 39 unmodified lines | ||
| 40 | 40 | CLK_IS_ROOT|CLK_IGNORE_UNUSED, |
| 41 | 41 | 32768); |
| 42 | 42 | clk_register_clkdev(clk, "clk32k", NULL); |
| 43 | − clk_register_clkdev(clk, NULL, "rtc-pl031"); | |
| 43 | + clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); | |
| 44 | 44 | |
| 45 | 45 | /* PRCMU clocks */ |
| 46 | 46 | fw_version = prcmu_get_fw_version(); |
| @@ -228,10 +228,17 @@ void u8500_clk_init(void) · 181 unmodified lines | ||
| 228 | 228 | |
| 229 | 229 | clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, |
| 230 | 230 | BIT(2), 0); |
| 231 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); | |
| 232 | + | |
| 231 | 233 | clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, |
| 232 | 234 | BIT(3), 0); |
| 235 | + clk_register_clkdev(clk, "apb_pclk", "msp0"); | |
| 236 | + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0"); | |
| 237 | + | |
| 233 | 238 | clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, |
| 234 | 239 | BIT(4), 0); |
| 240 | + clk_register_clkdev(clk, "apb_pclk", "msp1"); | |
| 241 | + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1"); | |
| 235 | 242 | |
| 236 | 243 | clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, |
| 237 | 244 | BIT(5), 0); |
| @@ -239,6 +246,7 @@ void u8500_clk_init(void) · 1 unmodified line | ||
| 239 | 246 | |
| 240 | 247 | clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, |
| 241 | 248 | BIT(6), 0); |
| 249 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); | |
| 242 | 250 | |
| 243 | 251 | clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, |
| 244 | 252 | BIT(7), 0); |
| @@ -246,6 +254,7 @@ void u8500_clk_init(void) · 1 unmodified line | ||
| 246 | 254 | |
| 247 | 255 | clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, |
| 248 | 256 | BIT(8), 0); |
| 257 | + clk_register_clkdev(clk, "apb_pclk", "slimbus0"); | |
| 249 | 258 | |
| 250 | 259 | clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, |
| 251 | 260 | BIT(9), 0); |
| @@ -255,11 +264,16 @@ void u8500_clk_init(void) · 3 unmodified lines | ||
| 255 | 264 | |
| 256 | 265 | clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, |
| 257 | 266 | BIT(10), 0); |
| 267 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); | |
| 268 | + | |
| 258 | 269 | clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, |
| 259 | 270 | BIT(11), 0); |
| 271 | + clk_register_clkdev(clk, "apb_pclk", "msp3"); | |
| 272 | + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3"); | |
| 260 | 273 | |
| 261 | 274 | clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, |
| 262 | 275 | BIT(0), 0); |
| 276 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); | |
| 263 | 277 | |
| 264 | 278 | clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, |
| 265 | 279 | BIT(1), 0); |
| @@ -279,12 +293,13 @@ void u8500_clk_init(void) · 13 unmodified lines | ||
| 279 | 293 | |
| 280 | 294 | clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, |
| 281 | 295 | BIT(5), 0); |
| 296 | + clk_register_clkdev(clk, "apb_pclk", "msp2"); | |
| 297 | + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2"); | |
| 282 | 298 | |
| 283 | 299 | clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, |
| 284 | 300 | BIT(6), 0); |
| 285 | 301 | clk_register_clkdev(clk, "apb_pclk", "sdi1"); |
| 286 | 302 | |
| 287 | − | |
| 288 | 303 | clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, |
| 289 | 304 | BIT(7), 0); |
| 290 | 305 | clk_register_clkdev(clk, "apb_pclk", "sdi3"); |
| @@ -316,10 +331,15 @@ void u8500_clk_init(void) · 25 unmodified lines | ||
| 316 | 331 | |
| 317 | 332 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, |
| 318 | 333 | BIT(1), 0); |
| 334 | + clk_register_clkdev(clk, "apb_pclk", "ssp0"); | |
| 335 | + | |
| 319 | 336 | clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, |
| 320 | 337 | BIT(2), 0); |
| 338 | + clk_register_clkdev(clk, "apb_pclk", "ssp1"); | |
| 339 | + | |
| 321 | 340 | clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, |
| 322 | 341 | BIT(3), 0); |
| 342 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); | |
| 323 | 343 | |
| 324 | 344 | clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, |
| 325 | 345 | BIT(4), 0); |
| @@ -401,10 +421,17 @@ void u8500_clk_init(void) · 75 unmodified lines | ||
| 401 | 421 | |
| 402 | 422 | clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", |
| 403 | 423 | U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); |
| 424 | + clk_register_clkdev(clk, NULL, "nmk-i2c.1"); | |
| 425 | + | |
| 404 | 426 | clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", |
| 405 | 427 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 428 | + clk_register_clkdev(clk, NULL, "msp0"); | |
| 429 | + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0"); | |
| 430 | + | |
| 406 | 431 | clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", |
| 407 | 432 | U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); |
| 433 | + clk_register_clkdev(clk, NULL, "msp1"); | |
| 434 | + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1"); | |
| 408 | 435 | |
| 409 | 436 | clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", |
| 410 | 437 | U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); |
| @@ -412,17 +439,25 @@ void u8500_clk_init(void) · 1 unmodified line | ||
| 412 | 439 | |
| 413 | 440 | clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", |
| 414 | 441 | U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); |
| 442 | + clk_register_clkdev(clk, NULL, "nmk-i2c.2"); | |
| 443 | + | |
| 415 | 444 | clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", |
| 416 | − U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); | |
| 417 | − /* FIXME: Redefinition of BIT(3). */ | |
| 445 | + U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE); | |
| 446 | + clk_register_clkdev(clk, NULL, "slimbus0"); | |
| 447 | + | |
| 418 | 448 | clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", |
| 419 | 449 | U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); |
| 450 | + clk_register_clkdev(clk, NULL, "nmk-i2c.4"); | |
| 451 | + | |
| 420 | 452 | clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", |
| 421 | 453 | U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); |
| 454 | + clk_register_clkdev(clk, NULL, "msp3"); | |
| 455 | + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3"); | |
| 422 | 456 | |
| 423 | 457 | /* Periph2 */ |
| 424 | 458 | clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", |
| 425 | 459 | U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); |
| 460 | + clk_register_clkdev(clk, NULL, "nmk-i2c.3"); | |
| 426 | 461 | |
| 427 | 462 | clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", |
| 428 | 463 | U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); |
| @@ -430,6 +465,8 @@ void u8500_clk_init(void) · 1 unmodified line | ||
| 430 | 465 | |
| 431 | 466 | clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", |
| 432 | 467 | U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 468 | + clk_register_clkdev(clk, NULL, "msp2"); | |
| 469 | + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2"); | |
| 433 | 470 | |
| 434 | 471 | clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", |
| 435 | 472 | U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); |
| @@ -450,10 +487,15 @@ void u8500_clk_init(void) · 14 unmodified lines | ||
| 450 | 487 | /* Periph3 */ |
| 451 | 488 | clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", |
| 452 | 489 | U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); |
| 490 | + clk_register_clkdev(clk, NULL, "ssp0"); | |
| 491 | + | |
| 453 | 492 | clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", |
| 454 | 493 | U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); |
| 494 | + clk_register_clkdev(clk, NULL, "ssp1"); | |
| 495 | + | |
| 455 | 496 | clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", |
| 456 | 497 | U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 498 | + clk_register_clkdev(clk, NULL, "nmk-i2c.0"); | |
| 457 | 499 | |
| 458 | 500 | clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", |
| 459 | 501 | U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); |
| @@ -47,7 +47,7 @@ if GPIOLIB · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | config OF_GPIO |
| 49 | 49 | def_bool y |
| 50 | − depends on OF && !SPARC | |
| 50 | + depends on OF | |
| 51 | 51 | |
| 52 | 52 | config DEBUG_GPIO |
| 53 | 53 | bool "Debug GPIO calls" |
| @@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp) · 120 unmodified lines | ||
| 121 | 121 | int minor_id = iminor(inode); |
| 122 | 122 | struct drm_minor *minor; |
| 123 | 123 | int retcode = 0; |
| 124 | + int need_setup = 0; | |
| 125 | + struct address_space *old_mapping; | |
| 124 | 126 | |
| 125 | 127 | minor = idr_find(&drm_minors_idr, minor_id); |
| 126 | 128 | if (!minor) |
| @@ -132,23 +134,37 @@ int drm_open(struct inode *inode, struct file *filp) · 5 unmodified lines | ||
| 132 | 134 | if (drm_device_is_unplugged(dev)) |
| 133 | 135 | return -ENODEV; |
| 134 | 136 | |
| 137 | + if (!dev->open_count++) | |
| 138 | + need_setup = 1; | |
| 139 | + mutex_lock(&dev->struct_mutex); | |
| 140 | + old_mapping = dev->dev_mapping; | |
| 141 | + if (old_mapping == NULL) | |
| 142 | + dev->dev_mapping = &inode->i_data; | |
| 143 | + /* ihold ensures nobody can remove inode with our i_data */ | |
| 144 | + ihold(container_of(dev->dev_mapping, struct inode, i_data)); | |
| 145 | + inode->i_mapping = dev->dev_mapping; | |
| 146 | + filp->f_mapping = dev->dev_mapping; | |
| 147 | + mutex_unlock(&dev->struct_mutex); | |
| 148 | + | |
| 135 | 149 | retcode = drm_open_helper(inode, filp, dev); |
| 136 | − if (!retcode) { | |
| 137 | − atomic_inc(&dev->counts[_DRM_STAT_OPENS]); | |
| 138 | − if (!dev->open_count++) | |
| 139 | − retcode = drm_setup(dev); | |
| 140 | − } | |
| 141 | − if (!retcode) { | |
| 142 | − mutex_lock(&dev->struct_mutex); | |
| 143 | − if (dev->dev_mapping == NULL) | |
| 144 | − dev->dev_mapping = &inode->i_data; | |
| 145 | − /* ihold ensures nobody can remove inode with our i_data */ | |
| 146 | − ihold(container_of(dev->dev_mapping, struct inode, i_data)); | |
| 147 | − inode->i_mapping = dev->dev_mapping; | |
| 148 | − filp->f_mapping = dev->dev_mapping; | |
| 149 | − mutex_unlock(&dev->struct_mutex); | |
| 150 | + if (retcode) | |
| 151 | + goto err_undo; | |
| 152 | + atomic_inc(&dev->counts[_DRM_STAT_OPENS]); | |
| 153 | + if (need_setup) { | |
| 154 | + retcode = drm_setup(dev); | |
| 155 | + if (retcode) | |
| 156 | + goto err_undo; | |
| 150 | 157 | } |
| 158 | + return 0; | |
| 151 | 159 | |
| 160 | +err_undo: | |
| 161 | + mutex_lock(&dev->struct_mutex); | |
| 162 | + filp->f_mapping = old_mapping; | |
| 163 | + inode->i_mapping = old_mapping; | |
| 164 | + iput(container_of(dev->dev_mapping, struct inode, i_data)); | |
| 165 | + dev->dev_mapping = old_mapping; | |
| 166 | + mutex_unlock(&dev->struct_mutex); | |
| 167 | + dev->open_count--; | |
| 152 | 168 | return retcode; |
| 153 | 169 | } |
| 154 | 170 | EXPORT_SYMBOL(drm_open); |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | config DRM_EXYNOS |
| 2 | 2 | tristate "DRM Support for Samsung SoC EXYNOS Series" |
| 3 | − depends on DRM && PLAT_SAMSUNG | |
| 3 | + depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM) | |
| 4 | 4 | select DRM_KMS_HELPER |
| 5 | 5 | select FB_CFB_FILLRECT |
| 6 | 6 | select FB_CFB_COPYAREA |
| @@ -374,6 +374,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, · 373 unmodified lines | ||
| 374 | 374 | exynos_connector->encoder_id = encoder->base.id; |
| 375 | 375 | exynos_connector->manager = manager; |
| 376 | 376 | exynos_connector->dpms = DRM_MODE_DPMS_OFF; |
| 377 | + connector->dpms = DRM_MODE_DPMS_OFF; | |
| 377 | 378 | connector->encoder = encoder; |
| 378 | 379 | |
| 379 | 380 | err = drm_mode_connector_attach_encoder(connector, encoder); |
| @@ -43,12 +43,14 @@ · 42 unmodified lines | ||
| 43 | 43 | * @manager: specific encoder has its own manager to control a hardware |
| 44 | 44 | * appropriately and we can access a hardware drawing on this manager. |
| 45 | 45 | * @dpms: store the encoder dpms value. |
| 46 | + * @updated: indicate whether overlay data updating is needed or not. | |
| 46 | 47 | */ |
| 47 | 48 | struct exynos_drm_encoder { |
| 48 | 49 | struct drm_crtc *old_crtc; |
| 49 | 50 | struct drm_encoder drm_encoder; |
| 50 | 51 | struct exynos_drm_manager *manager; |
| 51 | − int dpms; | |
| 52 | + int dpms; | |
| 53 | + bool updated; | |
| 52 | 54 | }; |
| 53 | 55 | |
| 54 | 56 | static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) |
| @@ -85,7 +87,9 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) · 30 unmodified lines | ||
| 85 | 87 | switch (mode) { |
| 86 | 88 | case DRM_MODE_DPMS_ON: |
| 87 | 89 | if (manager_ops && manager_ops->apply) |
| 88 | − manager_ops->apply(manager->dev); | |
| 90 | + if (!exynos_encoder->updated) | |
| 91 | + manager_ops->apply(manager->dev); | |
| 92 | + | |
| 89 | 93 | exynos_drm_connector_power(encoder, mode); |
| 90 | 94 | exynos_encoder->dpms = mode; |
| 91 | 95 | break; |
| @@ -94,6 +98,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) · 2 unmodified lines | ||
| 94 | 98 | case DRM_MODE_DPMS_OFF: |
| 95 | 99 | exynos_drm_connector_power(encoder, mode); |
| 96 | 100 | exynos_encoder->dpms = mode; |
| 101 | + exynos_encoder->updated = false; | |
| 97 | 102 | break; |
| 98 | 103 | default: |
| 99 | 104 | DRM_ERROR("unspecified mode %d\n", mode); |
| @@ -205,13 +210,22 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) · 105 unmodified lines | ||
| 205 | 210 | |
| 206 | 211 | static void exynos_drm_encoder_commit(struct drm_encoder *encoder) |
| 207 | 212 | { |
| 208 | − struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | |
| 213 | + struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); | |
| 214 | + struct exynos_drm_manager *manager = exynos_encoder->manager; | |
| 209 | 215 | struct exynos_drm_manager_ops *manager_ops = manager->ops; |
| 210 | 216 | |
| 211 | 217 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 212 | 218 | |
| 213 | 219 | if (manager_ops && manager_ops->commit) |
| 214 | 220 | manager_ops->commit(manager->dev); |
| 221 | + | |
| 222 | + /* | |
| 223 | + * this will avoid one issue that overlay data is updated to | |
| 224 | + * real hardware two times. | |
| 225 | + * And this variable will be used to check if the data was | |
| 226 | + * already updated or not by exynos_drm_encoder_dpms function. | |
| 227 | + */ | |
| 228 | + exynos_encoder->updated = true; | |
| 215 | 229 | } |
| 216 | 230 | |
| 217 | 231 | static void exynos_drm_encoder_disable(struct drm_encoder *encoder) |
| @@ -400,19 +414,6 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) · 182 unmodified lines | ||
| 400 | 414 | if (manager_ops && manager_ops->dpms) |
| 401 | 415 | manager_ops->dpms(manager->dev, mode); |
| 402 | 416 | |
| 403 | − /* | |
| 404 | − * set current mode to new one so that data aren't updated into | |
| 405 | − * registers by drm_helper_connector_dpms two times. | |
| 406 | − * | |
| 407 | − * in case that drm_crtc_helper_set_mode() is called, | |
| 408 | − * overlay_ops->commit() and manager_ops->commit() callbacks | |
| 409 | − * can be called two times, first at drm_crtc_helper_set_mode() | |
| 410 | − * and second at drm_helper_connector_dpms(). | |
| 411 | − * so with this setting, when drm_helper_connector_dpms() is called | |
| 412 | − * encoder->funcs->dpms() will be ignored. | |
| 413 | − */ | |
| 414 | − exynos_encoder->dpms = mode; | |
| 415 | − | |
| 416 | 417 | /* |
| 417 | 418 | * if this condition is ok then it means that the crtc is already |
| 418 | 419 | * detached from encoder and last function for detaching is properly |
| @@ -1142,7 +1142,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) · 1141 unmodified lines | ||
| 1142 | 1142 | const struct of_device_id *match; |
| 1143 | 1143 | match = of_match_node(of_match_ptr(mixer_match_types), |
| 1144 | 1144 | pdev->dev.of_node); |
| 1145 | − drv = match->data; | |
| 1145 | + drv = (struct mixer_drv_data *)match->data; | |
| 1146 | 1146 | } else { |
| 1147 | 1147 | drv = (struct mixer_drv_data *) |
| 1148 | 1148 | platform_get_device_id(pdev)->driver_data; |
| @@ -1505,7 +1505,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) · 1504 unmodified lines | ||
| 1505 | 1505 | goto put_gmch; |
| 1506 | 1506 | } |
| 1507 | 1507 | |
| 1508 | − i915_kick_out_firmware_fb(dev_priv); | |
| 1508 | + if (drm_core_check_feature(dev, DRIVER_MODESET)) | |
| 1509 | + i915_kick_out_firmware_fb(dev_priv); | |
| 1509 | 1510 | |
| 1510 | 1511 | pci_set_master(dev->pdev); |
| 1511 | 1512 | |
| @@ -143,7 +143,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode) · 142 unmodified lines | ||
| 143 | 143 | int old_dpms; |
| 144 | 144 | |
| 145 | 145 | /* PCH platforms and VLV only support on/off. */ |
| 146 | − if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON) | |
| 146 | + if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON) | |
| 147 | 147 | mode = DRM_MODE_DPMS_OFF; |
| 148 | 148 | |
| 149 | 149 | if (mode == connector->dpms) |
| @@ -729,7 +729,7 @@ void intel_crt_init(struct drm_device *dev) · 579 unmodified lines | ||
| 729 | 729 | |
| 730 | 730 | crt->base.type = INTEL_OUTPUT_ANALOG; |
| 731 | 731 | crt->base.cloneable = true; |
| 732 | − if (IS_HASWELL(dev)) | |
| 732 | + if (IS_HASWELL(dev) || IS_I830(dev)) | |
| 733 | 733 | crt->base.crtc_mask = (1 << 0); |
| 734 | 734 | else |
| 735 | 735 | crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
| @@ -3841,6 +3841,17 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, · 3840 unmodified lines | ||
| 3841 | 3841 | } |
| 3842 | 3842 | } |
| 3843 | 3843 | |
| 3844 | + if (intel_encoder->type == INTEL_OUTPUT_EDP) { | |
| 3845 | + /* Use VBT settings if we have an eDP panel */ | |
| 3846 | + unsigned int edp_bpc = dev_priv->edp.bpp / 3; | |
| 3847 | + | |
| 3848 | + if (edp_bpc < display_bpc) { | |
| 3849 | + DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | |
| 3850 | + display_bpc = edp_bpc; | |
| 3851 | + } | |
| 3852 | + continue; | |
| 3853 | + } | |
| 3854 | + | |
| 3844 | 3855 | /* |
| 3845 | 3856 | * HDMI is either 12 or 8, so if the display lets 10bpc sneak |
| 3846 | 3857 | * through, clamp it down. (Note: >12bpc will be caught below.) |
| @@ -341,9 +341,17 @@ static int intel_overlay_off(struct intel_overlay *overlay) · 340 unmodified lines | ||
| 341 | 341 | intel_ring_emit(ring, flip_addr); |
| 342 | 342 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
| 343 | 343 | /* turn overlay off */ |
| 344 | − intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | |
| 345 | − intel_ring_emit(ring, flip_addr); | |
| 346 | − intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | |
| 344 | + if (IS_I830(dev)) { | |
| 345 | + /* Workaround: Don't disable the overlay fully, since otherwise | |
| 346 | + * it dies on the next OVERLAY_ON cmd. */ | |
| 347 | + intel_ring_emit(ring, MI_NOOP); | |
| 348 | + intel_ring_emit(ring, MI_NOOP); | |
| 349 | + intel_ring_emit(ring, MI_NOOP); | |
| 350 | + } else { | |
| 351 | + intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | |
| 352 | + intel_ring_emit(ring, flip_addr); | |
| 353 | + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | |
| 354 | + } | |
| 347 | 355 | intel_ring_advance(ring); |
| 348 | 356 | |
| 349 | 357 | return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); |
| @@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev) · 434 unmodified lines | ||
| 435 | 435 | props.type = BACKLIGHT_RAW; |
| 436 | 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); |
| 437 | 437 | if (props.max_brightness == 0) { |
| 438 | − DRM_ERROR("Failed to get maximum backlight value\n"); | |
| 438 | + DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); | |
| 439 | 439 | return -ENODEV; |
| 440 | 440 | } |
| 441 | 441 | dev_priv->backlight = |
| @@ -894,6 +894,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) · 893 unmodified lines | ||
| 894 | 894 | } |
| 895 | 895 | #endif |
| 896 | 896 | |
| 897 | +static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, | |
| 898 | + unsigned if_index, uint8_t tx_rate, | |
| 899 | + uint8_t *data, unsigned length) | |
| 900 | +{ | |
| 901 | + uint8_t set_buf_index[2] = { if_index, 0 }; | |
| 902 | + uint8_t hbuf_size, tmp[8]; | |
| 903 | + int i; | |
| 904 | + | |
| 905 | + if (!intel_sdvo_set_value(intel_sdvo, | |
| 906 | + SDVO_CMD_SET_HBUF_INDEX, | |
| 907 | + set_buf_index, 2)) | |
| 908 | + return false; | |
| 909 | + | |
| 910 | + if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, | |
| 911 | + &hbuf_size, 1)) | |
| 912 | + return false; | |
| 913 | + | |
| 914 | + /* Buffer size is 0 based, hooray! */ | |
| 915 | + hbuf_size++; | |
| 916 | + | |
| 917 | + DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", | |
| 918 | + if_index, length, hbuf_size); | |
| 919 | + | |
| 920 | + for (i = 0; i < hbuf_size; i += 8) { | |
| 921 | + memset(tmp, 0, 8); | |
| 922 | + if (i < length) | |
| 923 | + memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); | |
| 924 | + | |
| 925 | + if (!intel_sdvo_set_value(intel_sdvo, | |
| 926 | + SDVO_CMD_SET_HBUF_DATA, | |
| 927 | + tmp, 8)) | |
| 928 | + return false; | |
| 929 | + } | |
| 930 | + | |
| 931 | + return intel_sdvo_set_value(intel_sdvo, | |
| 932 | + SDVO_CMD_SET_HBUF_TXRATE, | |
| 933 | + &tx_rate, 1); | |
| 934 | +} | |
| 935 | + | |
| 897 | 936 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) |
| 898 | 937 | { |
| 899 | 938 | struct dip_infoframe avi_if = { |
| @@ -901,11 +940,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) · 1 unmodified line | ||
| 901 | 940 | .ver = DIP_VERSION_AVI, |
| 902 | 941 | .len = DIP_LEN_AVI, |
| 903 | 942 | }; |
| 904 | − uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; | |
| 905 | − uint8_t set_buf_index[2] = { 1, 0 }; | |
| 906 | 943 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; |
| 907 | − uint64_t *data = (uint64_t *)sdvo_data; | |
| 908 | − unsigned i; | |
| 909 | 944 | |
| 910 | 945 | intel_dip_infoframe_csum(&avi_if); |
| 911 | 946 | |
| @@ -915,22 +950,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) · 3 unmodified lines | ||
| 915 | 950 | sdvo_data[3] = avi_if.checksum; |
| 916 | 951 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); |
| 917 | 952 | |
| 918 | − if (!intel_sdvo_set_value(intel_sdvo, | |
| 919 | − SDVO_CMD_SET_HBUF_INDEX, | |
| 920 | − set_buf_index, 2)) | |
| 921 | − return false; | |
| 922 | − | |
| 923 | − for (i = 0; i < sizeof(sdvo_data); i += 8) { | |
| 924 | − if (!intel_sdvo_set_value(intel_sdvo, | |
| 925 | − SDVO_CMD_SET_HBUF_DATA, | |
| 926 | − data, 8)) | |
| 927 | − return false; | |
| 928 | − data++; | |
| 929 | − } | |
| 930 | − | |
| 931 | − return intel_sdvo_set_value(intel_sdvo, | |
| 932 | − SDVO_CMD_SET_HBUF_TXRATE, | |
| 933 | − &tx_rate, 1); | |
| 953 | + return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, | |
| 954 | + SDVO_HBUF_TX_VSYNC, | |
| 955 | + sdvo_data, sizeof(sdvo_data)); | |
| 934 | 956 | } |
| 935 | 957 | |
| 936 | 958 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
| @@ -2360,6 +2382,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) · 1423 unmodified lines | ||
| 2360 | 2382 | return true; |
| 2361 | 2383 | } |
| 2362 | 2384 | |
| 2385 | +static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo) | |
| 2386 | +{ | |
| 2387 | + struct drm_device *dev = intel_sdvo->base.base.dev; | |
| 2388 | + struct drm_connector *connector, *tmp; | |
| 2389 | + | |
| 2390 | + list_for_each_entry_safe(connector, tmp, | |
| 2391 | + &dev->mode_config.connector_list, head) { | |
| 2392 | + if (intel_attached_encoder(connector) == &intel_sdvo->base) | |
| 2393 | + intel_sdvo_destroy(connector); | |
| 2394 | + } | |
| 2395 | +} | |
| 2396 | + | |
| 2363 | 2397 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
| 2364 | 2398 | struct intel_sdvo_connector *intel_sdvo_connector, |
| 2365 | 2399 | int type) |
| @@ -2683,7 +2717,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) · 317 unmodified lines | ||
| 2683 | 2717 | intel_sdvo->caps.output_flags) != true) { |
| 2684 | 2718 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", |
| 2685 | 2719 | SDVO_NAME(intel_sdvo)); |
| 2686 | − goto err; | |
| 2720 | + /* Output_setup can leave behind connectors! */ | |
| 2721 | + goto err_output; | |
| 2687 | 2722 | } |
| 2688 | 2723 | |
| 2689 | 2724 | /* Only enable the hotplug irq if we need it, to work around noisy |
| @@ -2696,12 +2731,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) · 6 unmodified lines | ||
| 2696 | 2731 | |
| 2697 | 2732 | /* Set the input timing to the screen. Assume always input 0. */ |
| 2698 | 2733 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 2699 | − goto err; | |
| 2734 | + goto err_output; | |
| 2700 | 2735 | |
| 2701 | 2736 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, |
| 2702 | 2737 | &intel_sdvo->pixel_clock_min, |
| 2703 | 2738 | &intel_sdvo->pixel_clock_max)) |
| 2704 | − goto err; | |
| 2739 | + goto err_output; | |
| 2705 | 2740 | |
| 2706 | 2741 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
| 2707 | 2742 | "clock range %dMHz - %dMHz, " |
| @@ -2721,6 +2756,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) · 13 unmodified lines | ||
| 2721 | 2756 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
| 2722 | 2757 | return true; |
| 2723 | 2758 | |
| 2759 | +err_output: | |
| 2760 | + intel_sdvo_output_cleanup(intel_sdvo); | |
| 2761 | + | |
| 2724 | 2762 | err: |
| 2725 | 2763 | drm_encoder_cleanup(&intel_encoder->base); |
| 2726 | 2764 | i2c_del_adapter(&intel_sdvo->ddc); |
| @@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg { · 707 unmodified lines | ||
| 708 | 708 | #define SDVO_CMD_SET_AUDIO_STAT 0x91 |
| 709 | 709 | #define SDVO_CMD_GET_AUDIO_STAT 0x92 |
| 710 | 710 | #define SDVO_CMD_SET_HBUF_INDEX 0x93 |
| 711 | + #define SDVO_HBUF_INDEX_ELD 0 | |
| 712 | + #define SDVO_HBUF_INDEX_AVI_IF 1 | |
| 711 | 713 | #define SDVO_CMD_GET_HBUF_INDEX 0x94 |
| 712 | 714 | #define SDVO_CMD_GET_HBUF_INFO 0x95 |
| 713 | 715 | #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 |
| @@ -22,6 +22,8 @@ · 21 unmodified lines | ||
| 22 | 22 | * Authors: Ben Skeggs |
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | +#include <subdev/bar.h> | |
| 26 | + | |
| 25 | 27 | #include <engine/software.h> |
| 26 | 28 | #include <engine/disp.h> |
| 27 | 29 | |
| @@ -37,6 +39,7 @@ nv50_disp_sclass[] = { · 9 unmodified lines | ||
| 37 | 39 | static void |
| 38 | 40 | nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) |
| 39 | 41 | { |
| 42 | + struct nouveau_bar *bar = nouveau_bar(priv); | |
| 40 | 43 | struct nouveau_disp *disp = &priv->base; |
| 41 | 44 | struct nouveau_software_chan *chan, *temp; |
| 42 | 45 | unsigned long flags; |
| @@ -46,18 +49,19 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) · 3 unmodified lines | ||
| 46 | 49 | if (chan->vblank.crtc != crtc) |
| 47 | 50 | continue; |
| 48 | 51 | |
| 49 | − nv_wr32(priv, 0x001704, chan->vblank.channel); | |
| 50 | − nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); | |
| 51 | − | |
| 52 | 52 | if (nv_device(priv)->chipset == 0x50) { |
| 53 | + nv_wr32(priv, 0x001704, chan->vblank.channel); | |
| 54 | + nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); | |
| 55 | + bar->flush(bar); | |
| 53 | 56 | nv_wr32(priv, 0x001570, chan->vblank.offset); |
| 54 | 57 | nv_wr32(priv, 0x001574, chan->vblank.value); |
| 55 | 58 | } else { |
| 56 | − if (nv_device(priv)->chipset >= 0xc0) { | |
| 57 | − nv_wr32(priv, 0x06000c, | |
| 58 | − upper_32_bits(chan->vblank.offset)); | |
| 59 | − } | |
| 60 | − nv_wr32(priv, 0x060010, chan->vblank.offset); | |
| 59 | + nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); | |
| 60 | + bar->flush(bar); | |
| 61 | + nv_wr32(priv, 0x06000c, | |
| 62 | + upper_32_bits(chan->vblank.offset)); | |
| 63 | + nv_wr32(priv, 0x060010, | |
| 64 | + lower_32_bits(chan->vblank.offset)); | |
| 61 | 65 | nv_wr32(priv, 0x060014, chan->vblank.value); |
| 62 | 66 | } |
| 63 | 67 | |
| @@ -156,8 +156,8 @@ nv40_graph_context_ctor(struct nouveau_object *parent, · 155 unmodified lines | ||
| 156 | 156 | static int |
| 157 | 157 | nv40_graph_context_fini(struct nouveau_object *object, bool suspend) |
| 158 | 158 | { |
| 159 | − struct nv04_graph_priv *priv = (void *)object->engine; | |
| 160 | − struct nv04_graph_chan *chan = (void *)object; | |
| 159 | + struct nv40_graph_priv *priv = (void *)object->engine; | |
| 160 | + struct nv40_graph_chan *chan = (void *)object; | |
| 161 | 161 | u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4; |
| 162 | 162 | int ret = 0; |
| 163 | 163 | |
| @@ -38,7 +38,7 @@ struct nv40_mpeg_priv { · 37 unmodified lines | ||
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | 40 | struct nv40_mpeg_chan { |
| 41 | − struct nouveau_mpeg base; | |
| 41 | + struct nouveau_mpeg_chan base; | |
| 42 | 42 | }; |
| 43 | 43 | |
| 44 | 44 | /******************************************************************************* |
| @@ -67,7 +67,7 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) · 66 unmodified lines | ||
| 67 | 67 | static void |
| 68 | 68 | nv41_vm_flush(struct nouveau_vm *vm) |
| 69 | 69 | { |
| 70 | − struct nv04_vm_priv *priv = (void *)vm->vmm; | |
| 70 | + struct nv04_vmmgr_priv *priv = (void *)vm->vmm; | |
| 71 | 71 | |
| 72 | 72 | mutex_lock(&nv_subdev(priv)->mutex); |
| 73 | 73 | nv_wr32(priv, 0x100810, 0x00000022); |
| @@ -355,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) · 354 unmodified lines | ||
| 355 | 355 | * valid - it's not (rh#613284) |
| 356 | 356 | */ |
| 357 | 357 | if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { |
| 358 | − if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) { | |
| 358 | + if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) { | |
| 359 | 359 | status = connector_status_connected; |
| 360 | 360 | goto out; |
| 361 | 361 | } |
| @@ -1696,35 +1696,43 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) · 1695 unmodified lines | ||
| 1696 | 1696 | return ATOM_PPLL2; |
| 1697 | 1697 | DRM_ERROR("unable to allocate a PPLL\n"); |
| 1698 | 1698 | return ATOM_PPLL_INVALID; |
| 1699 | − } else { | |
| 1700 | − if (ASIC_IS_AVIVO(rdev)) { | |
| 1701 | − /* in DP mode, the DP ref clock can come from either PPLL | |
| 1702 | − * depending on the asic: | |
| 1703 | − * DCE3: PPLL1 or PPLL2 | |
| 1704 | − */ | |
| 1705 | − if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { | |
| 1706 | − /* use the same PPLL for all DP monitors */ | |
| 1707 | − pll = radeon_get_shared_dp_ppll(crtc); | |
| 1708 | − if (pll != ATOM_PPLL_INVALID) | |
| 1709 | − return pll; | |
| 1710 | − } else { | |
| 1711 | − /* use the same PPLL for all monitors with the same clock */ | |
| 1712 | − pll = radeon_get_shared_nondp_ppll(crtc); | |
| 1713 | − if (pll != ATOM_PPLL_INVALID) | |
| 1714 | − return pll; | |
| 1715 | − } | |
| 1716 | − /* all other cases */ | |
| 1717 | − pll_in_use = radeon_get_pll_use_mask(crtc); | |
| 1699 | + } else if (ASIC_IS_AVIVO(rdev)) { | |
| 1700 | + /* in DP mode, the DP ref clock can come from either PPLL | |
| 1701 | + * depending on the asic: | |
| 1702 | + * DCE3: PPLL1 or PPLL2 | |
| 1703 | + */ | |
| 1704 | + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { | |
| 1705 | + /* use the same PPLL for all DP monitors */ | |
| 1706 | + pll = radeon_get_shared_dp_ppll(crtc); | |
| 1707 | + if (pll != ATOM_PPLL_INVALID) | |
| 1708 | + return pll; | |
| 1709 | + } else { | |
| 1710 | + /* use the same PPLL for all monitors with the same clock */ | |
| 1711 | + pll = radeon_get_shared_nondp_ppll(crtc); | |
| 1712 | + if (pll != ATOM_PPLL_INVALID) | |
| 1713 | + return pll; | |
| 1714 | + } | |
| 1715 | + /* all other cases */ | |
| 1716 | + pll_in_use = radeon_get_pll_use_mask(crtc); | |
| 1717 | + /* the order shouldn't matter here, but we probably | |
| 1718 | + * need this until we have atomic modeset | |
| 1719 | + */ | |
| 1720 | + if (rdev->flags & RADEON_IS_IGP) { | |
| 1718 | 1721 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
| 1719 | 1722 | return ATOM_PPLL1; |
| 1720 | 1723 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
| 1721 | 1724 | return ATOM_PPLL2; |
| 1722 | − DRM_ERROR("unable to allocate a PPLL\n"); | |
| 1723 | − return ATOM_PPLL_INVALID; | |
| 1724 | 1725 | } else { |
| 1725 | − /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ | |
| 1726 | − return radeon_crtc->crtc_id; | |
| 1726 | + if (!(pll_in_use & (1 << ATOM_PPLL2))) | |
| 1727 | + return ATOM_PPLL2; | |
| 1728 | + if (!(pll_in_use & (1 << ATOM_PPLL1))) | |
| 1729 | + return ATOM_PPLL1; | |
| 1727 | 1730 | } |
| 1731 | + DRM_ERROR("unable to allocate a PPLL\n"); | |
| 1732 | + return ATOM_PPLL_INVALID; | |
| 1733 | + } else { | |
| 1734 | + /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ | |
| 1735 | + return radeon_crtc->crtc_id; | |
| 1728 | 1736 | } |
| 1729 | 1737 | } |
| 1730 | 1738 | |
| @@ -1625,7 +1625,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) · 1624 unmodified lines | ||
| 1625 | 1625 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); |
| 1626 | 1626 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
| 1627 | 1627 | /* some early dce3.2 boards have a bug in their transmitter control table */ |
| 1628 | − if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) | |
| 1628 | + if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) | |
| 1629 | 1629 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
| 1630 | 1630 | } |
| 1631 | 1631 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
| @@ -1372,7 +1372,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s · 1371 unmodified lines | ||
| 1372 | 1372 | WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); |
| 1373 | 1373 | |
| 1374 | 1374 | for (i = 0; i < rdev->num_crtc; i++) { |
| 1375 | − if (save->crtc_enabled) { | |
| 1375 | + if (save->crtc_enabled[i]) { | |
| 1376 | 1376 | if (ASIC_IS_DCE6(rdev)) { |
| 1377 | 1377 | tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); |
| 1378 | 1378 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; |
| @@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, · 263 unmodified lines | ||
| 264 | 264 | /* macro tile width & height */ |
| 265 | 265 | palign = (8 * surf->bankw * track->npipes) * surf->mtilea; |
| 266 | 266 | halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; |
| 267 | − mtileb = (palign / 8) * (halign / 8) * tileb;; | |
| 267 | + mtileb = (palign / 8) * (halign / 8) * tileb; | |
| 268 | 268 | mtile_pr = surf->nbx / palign; |
| 269 | 269 | mtile_ps = (mtile_pr * surf->nby) / halign; |
| 270 | 270 | surf->layer_size = mtile_ps * mtileb * slice_pt; |
| @@ -2725,6 +2725,9 @@ static bool evergreen_vm_reg_valid(u32 reg) · 2454 unmodified lines | ||
| 2725 | 2725 | /* check config regs */ |
| 2726 | 2726 | switch (reg) { |
| 2727 | 2727 | case GRBM_GFX_INDEX: |
| 2728 | + case CP_STRMOUT_CNTL: | |
| 2729 | + case CP_COHER_CNTL: | |
| 2730 | + case CP_COHER_SIZE: | |
| 2728 | 2731 | case VGT_VTX_VECT_EJECT_REG: |
| 2729 | 2732 | case VGT_CACHE_INVALIDATION: |
| 2730 | 2733 | case VGT_GS_VERTEX_REUSE: |
| @@ -91,6 +91,10 @@ · 90 unmodified lines | ||
| 91 | 91 | #define FB_READ_EN (1 << 0) |
| 92 | 92 | #define FB_WRITE_EN (1 << 1) |
| 93 | 93 | |
| 94 | +#define CP_STRMOUT_CNTL 0x84FC | |
| 95 | + | |
| 96 | +#define CP_COHER_CNTL 0x85F0 | |
| 97 | +#define CP_COHER_SIZE 0x85F4 | |
| 94 | 98 | #define CP_COHER_BASE 0x85F8 |
| 95 | 99 | #define CP_STALLED_STAT1 0x8674 |
| 96 | 100 | #define CP_STALLED_STAT2 0x8678 |
| @@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) · 351 unmodified lines | ||
| 352 | 352 | } |
| 353 | 353 | |
| 354 | 354 | /** |
| 355 | − * radeon_atpx_switchto - switch to the requested GPU | |
| 355 | + * radeon_atpx_power_state - power down/up the requested GPU | |
| 356 | 356 | * |
| 357 | − * @id: GPU to switch to | |
| 357 | + * @id: GPU to power down/up | |
| 358 | 358 | * @state: requested power state (0 = off, 1 = on) |
| 359 | 359 | * |
| 360 | 360 | * Execute the necessary ATPX function to power down/up the discrete GPU |
| @@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) · 940 unmodified lines | ||
| 941 | 941 | struct drm_mode_object *obj; |
| 942 | 942 | int i; |
| 943 | 943 | enum drm_connector_status ret = connector_status_disconnected; |
| 944 | − bool dret = false; | |
| 944 | + bool dret = false, broken_edid = false; | |
| 945 | 945 | |
| 946 | 946 | if (!force && radeon_check_hpd_status_unchanged(connector)) |
| 947 | 947 | return connector->status; |
| @@ -965,6 +965,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) · 17 unmodified lines | ||
| 965 | 965 | ret = connector_status_disconnected; |
| 966 | 966 | DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); |
| 967 | 967 | radeon_connector->ddc_bus = NULL; |
| 968 | + } else { | |
| 969 | + ret = connector_status_connected; | |
| 970 | + broken_edid = true; /* defer use_digital to later */ | |
| 968 | 971 | } |
| 969 | 972 | } else { |
| 970 | 973 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
| @@ -1047,13 +1050,24 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) · 76 unmodified lines | ||
| 1047 | 1050 | |
| 1048 | 1051 | encoder_funcs = encoder->helper_private; |
| 1049 | 1052 | if (encoder_funcs->detect) { |
| 1050 | − if (ret != connector_status_connected) { | |
| 1051 | − ret = encoder_funcs->detect(encoder, connector); | |
| 1052 | − if (ret == connector_status_connected) { | |
| 1053 | − radeon_connector->use_digital = false; | |
| 1053 | + if (!broken_edid) { | |
| 1054 | + if (ret != connector_status_connected) { | |
| 1055 | + /* deal with analog monitors without DDC */ | |
| 1056 | + ret = encoder_funcs->detect(encoder, connector); | |
| 1057 | + if (ret == connector_status_connected) { | |
| 1058 | + radeon_connector->use_digital = false; | |
| 1059 | + } | |
| 1060 | + if (ret != connector_status_disconnected) | |
| 1061 | + radeon_connector->detected_by_load = true; | |
| 1054 | 1062 | } |
| 1055 | − if (ret != connector_status_disconnected) | |
| 1056 | − radeon_connector->detected_by_load = true; | |
| 1063 | + } else { | |
| 1064 | + enum drm_connector_status lret; | |
| 1065 | + /* assume digital unless load detected otherwise */ | |
| 1066 | + radeon_connector->use_digital = true; | |
| 1067 | + lret = encoder_funcs->detect(encoder, connector); | |
| 1068 | + DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret); | |
| 1069 | + if (lret == connector_status_connected) | |
| 1070 | + radeon_connector->use_digital = false; | |
| 1057 | 1071 | } |
| 1058 | 1072 | break; |
| 1059 | 1073 | } |
| @@ -295,6 +295,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) · 294 unmodified lines | ||
| 295 | 295 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 296 | 296 | struct drm_device *dev = crtc->dev; |
| 297 | 297 | struct radeon_device *rdev = dev->dev_private; |
| 298 | + uint32_t crtc_ext_cntl = 0; | |
| 298 | 299 | uint32_t mask; |
| 299 | 300 | |
| 300 | 301 | if (radeon_crtc->crtc_id) |
| @@ -307,6 +308,16 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) · 6 unmodified lines | ||
| 307 | 308 | RADEON_CRTC_VSYNC_DIS | |
| 308 | 309 | RADEON_CRTC_HSYNC_DIS); |
| 309 | 310 | |
| 311 | + /* | |
| 312 | + * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC. | |
| 313 | + * Therefore it is set in the DAC DMPS function. | |
| 314 | + * This is different for GPU's with a single CRTC but a primary and a | |
| 315 | + * TV DAC: here it controls the single CRTC no matter where it is | |
| 316 | + * routed. Therefore we set it here. | |
| 317 | + */ | |
| 318 | + if (rdev->flags & RADEON_SINGLE_CRTC) | |
| 319 | + crtc_ext_cntl = RADEON_CRTC_CRT_ON; | |
| 320 | + | |
| 310 | 321 | switch (mode) { |
| 311 | 322 | case DRM_MODE_DPMS_ON: |
| 312 | 323 | radeon_crtc->enabled = true; |
| @@ -317,7 +328,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) · 4 unmodified lines | ||
| 317 | 328 | else { |
| 318 | 329 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | |
| 319 | 330 | RADEON_CRTC_DISP_REQ_EN_B)); |
| 320 | − WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); | |
| 331 | + WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); | |
| 321 | 332 | } |
| 322 | 333 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); |
| 323 | 334 | radeon_crtc_load_lut(crtc); |
| @@ -331,7 +342,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) · 7 unmodified lines | ||
| 331 | 342 | else { |
| 332 | 343 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | |
| 333 | 344 | RADEON_CRTC_DISP_REQ_EN_B)); |
| 334 | − WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); | |
| 345 | + WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl)); | |
| 335 | 346 | } |
| 336 | 347 | radeon_crtc->enabled = false; |
| 337 | 348 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
| @@ -537,7 +537,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode · 536 unmodified lines | ||
| 537 | 537 | break; |
| 538 | 538 | } |
| 539 | 539 | |
| 540 | − WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | |
| 540 | + /* handled in radeon_crtc_dpms() */ | |
| 541 | + if (!(rdev->flags & RADEON_SINGLE_CRTC)) | |
| 542 | + WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | |
| 541 | 543 | WREG32(RADEON_DAC_CNTL, dac_cntl); |
| 542 | 544 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); |
| 543 | 545 | |
| @@ -662,6 +664,8 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc · 118 unmodified lines | ||
| 662 | 664 | |
| 663 | 665 | if (ASIC_IS_R300(rdev)) |
| 664 | 666 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); |
| 667 | + else if (ASIC_IS_RV100(rdev)) | |
| 668 | + tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT); | |
| 665 | 669 | else |
| 666 | 670 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); |
| 667 | 671 | |
| @@ -671,6 +675,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc · 3 unmodified lines | ||
| 671 | 675 | tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; |
| 672 | 676 | WREG32(RADEON_DAC_CNTL, tmp); |
| 673 | 677 | |
| 678 | + tmp = dac_macro_cntl; | |
| 674 | 679 | tmp &= ~(RADEON_DAC_PDWN_R | |
| 675 | 680 | RADEON_DAC_PDWN_G | |
| 676 | 681 | RADEON_DAC_PDWN_B); |
| @@ -1092,7 +1097,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) · 415 unmodified lines | ||
| 1092 | 1097 | } else { |
| 1093 | 1098 | if (is_tv) |
| 1094 | 1099 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); |
| 1095 | − else | |
| 1100 | + /* handled in radeon_crtc_dpms() */ | |
| 1101 | + else if (!(rdev->flags & RADEON_SINGLE_CRTC)) | |
| 1096 | 1102 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
| 1097 | 1103 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
| 1098 | 1104 | } |
| @@ -1416,13 +1422,104 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, · 317 unmodified lines | ||
| 1416 | 1422 | return found; |
| 1417 | 1423 | } |
| 1418 | 1424 | |
| 1425 | +static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, | |
| 1426 | + struct drm_connector *connector) | |
| 1427 | +{ | |
| 1428 | + struct drm_device *dev = encoder->dev; | |
| 1429 | + struct radeon_device *rdev = dev->dev_private; | |
| 1430 | + uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; | |
| 1431 | + uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; | |
| 1432 | + uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; | |
| 1433 | + uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; | |
| 1434 | + uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; | |
| 1435 | + bool found = false; | |
| 1436 | + int i; | |
| 1437 | + | |
| 1438 | + /* save the regs we need */ | |
| 1439 | + gpio_monid = RREG32(RADEON_GPIO_MONID); | |
| 1440 | + fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); | |
| 1441 | + disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | |
| 1442 | + crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | |
| 1443 | + disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); | |
| 1444 | + disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); | |
| 1445 | + disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); | |
| 1446 | + disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); | |
| 1447 | + disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); | |
| 1448 | + disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); | |
| 1449 | + crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); | |
| 1450 | + crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); | |
| 1451 | + crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); | |
| 1452 | + crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); | |
| 1453 | + | |
| 1454 | + tmp = RREG32(RADEON_GPIO_MONID); | |
| 1455 | + tmp &= ~RADEON_GPIO_A_0; | |
| 1456 | + WREG32(RADEON_GPIO_MONID, tmp); | |
| 1457 | + | |
| 1458 | + WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | | |
| 1459 | + RADEON_FP2_PANEL_FORMAT | | |
| 1460 | + R200_FP2_SOURCE_SEL_TRANS_UNIT | | |
| 1461 | + RADEON_FP2_DVO_EN | | |
| 1462 | + R200_FP2_DVO_RATE_SEL_SDR)); | |
| 1463 | + | |
| 1464 | + WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | | |
| 1465 | + RADEON_DISP_TRANS_MATRIX_GRAPHICS)); | |
| 1466 | + | |
| 1467 | + WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | | |
| 1468 | + RADEON_CRTC2_DISP_REQ_EN_B)); | |
| 1469 | + | |
| 1470 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); | |
| 1471 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); | |
| 1472 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); | |
| 1473 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); | |
| 1474 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); | |
| 1475 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); | |
| 1476 | + | |
| 1477 | + WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); | |
| 1478 | + WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); | |
| 1479 | + WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); | |
| 1480 | + WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); | |
| 1481 | + | |
| 1482 | + for (i = 0; i < 200; i++) { | |
| 1483 | + tmp = RREG32(RADEON_GPIO_MONID); | |
| 1484 | + if (tmp & RADEON_GPIO_Y_0) | |
| 1485 | + found = true; | |
| 1486 | + | |
| 1487 | + if (found) | |
| 1488 | + break; | |
| 1489 | + | |
| 1490 | + if (!drm_can_sleep()) | |
| 1491 | + mdelay(1); | |
| 1492 | + else | |
| 1493 | + msleep(1); | |
| 1494 | + } | |
| 1495 | + | |
| 1496 | + /* restore the regs we used */ | |
| 1497 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); | |
| 1498 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); | |
| 1499 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); | |
| 1500 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); | |
| 1501 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); | |
| 1502 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); | |
| 1503 | + WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); | |
| 1504 | + WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); | |
| 1505 | + WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); | |
| 1506 | + WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); | |
| 1507 | + WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | |
| 1508 | + WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | |
| 1509 | + WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); | |
| 1510 | + WREG32(RADEON_GPIO_MONID, gpio_monid); | |
| 1511 | + | |
| 1512 | + return found; | |
| 1513 | +} | |
| 1514 | + | |
| 1419 | 1515 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, |
| 1420 | 1516 | struct drm_connector *connector) |
| 1421 | 1517 | { |
| 1422 | 1518 | struct drm_device *dev = encoder->dev; |
| 1423 | 1519 | struct radeon_device *rdev = dev->dev_private; |
| 1424 | − uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | |
| 1425 | − uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; | |
| 1520 | + uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | |
| 1521 | + uint32_t gpiopad_a = 0, pixclks_cntl, tmp; | |
| 1522 | + uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; | |
| 1426 | 1523 | enum drm_connector_status found = connector_status_disconnected; |
| 1427 | 1524 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1428 | 1525 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; |
| @@ -1459,12 +1556,27 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder · 30 unmodified lines | ||
| 1459 | 1556 | return connector_status_disconnected; |
| 1460 | 1557 | } |
| 1461 | 1558 | |
| 1559 | + /* R200 uses an external DAC for secondary DAC */ | |
| 1560 | + if (rdev->family == CHIP_R200) { | |
| 1561 | + if (radeon_legacy_ext_dac_detect(encoder, connector)) | |
| 1562 | + found = connector_status_connected; | |
| 1563 | + return found; | |
| 1564 | + } | |
| 1565 | + | |
| 1462 | 1566 | /* save the regs we need */ |
| 1463 | 1567 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
| 1464 | − gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0; | |
| 1465 | − disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0; | |
| 1466 | − disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG); | |
| 1467 | − crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | |
| 1568 | + | |
| 1569 | + if (rdev->flags & RADEON_SINGLE_CRTC) { | |
| 1570 | + crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); | |
| 1571 | + } else { | |
| 1572 | + if (ASIC_IS_R300(rdev)) { | |
| 1573 | + gpiopad_a = RREG32(RADEON_GPIOPAD_A); | |
| 1574 | + disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | |
| 1575 | + } else { | |
| 1576 | + disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); | |
| 1577 | + } | |
| 1578 | + crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | |
| 1579 | + } | |
| 1468 | 1580 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); |
| 1469 | 1581 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); |
| 1470 | 1582 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); |
| @@ -1473,22 +1585,24 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder · 2 unmodified lines | ||
| 1473 | 1585 | | RADEON_PIX2CLK_DAC_ALWAYS_ONb); |
| 1474 | 1586 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); |
| 1475 | 1587 | |
| 1476 | − if (ASIC_IS_R300(rdev)) | |
| 1477 | − WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | |
| 1478 | − | |
| 1479 | − tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; | |
| 1480 | − tmp |= RADEON_CRTC2_CRT2_ON | | |
| 1481 | − (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | |
| 1482 | − | |
| 1483 | − WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | |
| 1484 | − | |
| 1485 | − if (ASIC_IS_R300(rdev)) { | |
| 1486 | − tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | |
| 1487 | − tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | |
| 1488 | − WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | |
| 1588 | + if (rdev->flags & RADEON_SINGLE_CRTC) { | |
| 1589 | + tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; | |
| 1590 | + WREG32(RADEON_CRTC_EXT_CNTL, tmp); | |
| 1489 | 1591 | } else { |
| 1490 | − tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | |
| 1491 | − WREG32(RADEON_DISP_HW_DEBUG, tmp); | |
| 1592 | + tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; | |
| 1593 | + tmp |= RADEON_CRTC2_CRT2_ON | | |
| 1594 | + (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | |
| 1595 | + WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | |
| 1596 | + | |
| 1597 | + if (ASIC_IS_R300(rdev)) { | |
| 1598 | + WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | |
| 1599 | + tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | |
| 1600 | + tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | |
| 1601 | + WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | |
| 1602 | + } else { | |
| 1603 | + tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | |
| 1604 | + WREG32(RADEON_DISP_HW_DEBUG, tmp); | |
| 1605 | + } | |
| 1492 | 1606 | } |
| 1493 | 1607 | |
| 1494 | 1608 | tmp = RADEON_TV_DAC_NBLANK | |
| @@ -1530,14 +1644,19 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder · 35 unmodified lines | ||
| 1530 | 1644 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); |
| 1531 | 1645 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); |
| 1532 | 1646 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
| 1533 | − WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | |
| 1534 | 1647 | |
| 1535 | − if (ASIC_IS_R300(rdev)) { | |
| 1536 | − WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | |
| 1537 | − WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | |
| 1648 | + if (rdev->flags & RADEON_SINGLE_CRTC) { | |
| 1649 | + WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | |
| 1538 | 1650 | } else { |
| 1539 | − WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | |
| 1651 | + WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | |
| 1652 | + if (ASIC_IS_R300(rdev)) { | |
| 1653 | + WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | |
| 1654 | + WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | |
| 1655 | + } else { | |
| 1656 | + WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | |
| 1657 | + } | |
| 1540 | 1658 | } |
| 1659 | + | |
| 1541 | 1660 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
| 1542 | 1661 | |
| 1543 | 1662 | return found; |
| @@ -2474,6 +2474,7 @@ static bool si_vm_reg_valid(u32 reg) · 2473 unmodified lines | ||
| 2474 | 2474 | /* check config regs */ |
| 2475 | 2475 | switch (reg) { |
| 2476 | 2476 | case GRBM_GFX_INDEX: |
| 2477 | + case CP_STRMOUT_CNTL: | |
| 2477 | 2478 | case VGT_VTX_VECT_EJECT_REG: |
| 2478 | 2479 | case VGT_CACHE_INVALIDATION: |
| 2479 | 2480 | case VGT_ESGS_RING_SIZE: |
| @@ -424,6 +424,7 @@ · 423 unmodified lines | ||
| 424 | 424 | # define RDERR_INT_ENABLE (1 << 0) |
| 425 | 425 | # define GUI_IDLE_INT_ENABLE (1 << 19) |
| 426 | 426 | |
| 427 | +#define CP_STRMOUT_CNTL 0x84FC | |
| 427 | 428 | #define SCRATCH_REG0 0x8500 |
| 428 | 429 | #define SCRATCH_REG1 0x8504 |
| 429 | 430 | #define SCRATCH_REG2 0x8508 |
| @@ -749,7 +749,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, · 748 unmodified lines | ||
| 749 | 749 | /* clear the pages coming from the pool if requested */ |
| 750 | 750 | if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { |
| 751 | 751 | list_for_each_entry(p, &plist, lru) { |
| 752 | − clear_page(page_address(p)); | |
| 752 | + if (PageHighMem(p)) | |
| 753 | + clear_highpage(p); | |
| 754 | + else | |
| 755 | + clear_page(page_address(p)); | |
| 753 | 756 | } |
| 754 | 757 | } |
| 755 | 758 | |
| @@ -308,9 +308,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm) · 307 unmodified lines | ||
| 308 | 308 | if (unlikely(to_page == NULL)) |
| 309 | 309 | goto out_err; |
| 310 | 310 | |
| 311 | − preempt_disable(); | |
| 312 | 311 | copy_highpage(to_page, from_page); |
| 313 | − preempt_enable(); | |
| 314 | 312 | page_cache_release(from_page); |
| 315 | 313 | } |
| 316 | 314 | |
| @@ -358,9 +356,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) · 41 unmodified lines | ||
| 358 | 356 | ret = PTR_ERR(to_page); |
| 359 | 357 | goto out_err; |
| 360 | 358 | } |
| 361 | − preempt_disable(); | |
| 362 | 359 | copy_highpage(to_page, from_page); |
| 363 | − preempt_enable(); | |
| 364 | 360 | set_page_dirty(to_page); |
| 365 | 361 | mark_page_accessed(to_page); |
| 366 | 362 | page_cache_release(to_page); |
| @@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev, · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, |
| 106 | 106 | const char *front, char **urb_buf_ptr, |
| 107 | − u32 byte_offset, u32 byte_width, | |
| 107 | + u32 byte_offset, u32 device_byte_offset, u32 byte_width, | |
| 108 | 108 | int *ident_ptr, int *sent_ptr); |
| 109 | 109 | |
| 110 | 110 | int udl_dumb_create(struct drm_file *file_priv, |
| @@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(struct fb_info *info, · 113 unmodified lines | ||
| 114 | 114 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { |
| 115 | 115 | |
| 116 | 116 | if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), |
| 117 | − &urb, (char *) info->fix.smem_start, | |
| 118 | − &cmd, cur->index << PAGE_SHIFT, | |
| 119 | − PAGE_SIZE, &bytes_identical, &bytes_sent)) | |
| 117 | + &urb, (char *) info->fix.smem_start, | |
| 118 | + &cmd, cur->index << PAGE_SHIFT, | |
| 119 | + cur->index << PAGE_SHIFT, | |
| 120 | + PAGE_SIZE, &bytes_identical, &bytes_sent)) | |
| 120 | 121 | goto error; |
| 121 | 122 | bytes_rendered += PAGE_SIZE; |
| 122 | 123 | } |
| @@ -187,10 +188,11 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, · 64 unmodified lines | ||
| 187 | 188 | for (i = y; i < y + height ; i++) { |
| 188 | 189 | const int line_offset = fb->base.pitches[0] * i; |
| 189 | 190 | const int byte_offset = line_offset + (x * bpp); |
| 190 | − | |
| 191 | + const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp); | |
| 191 | 192 | if (udl_render_hline(dev, bpp, &urb, |
| 192 | 193 | (char *) fb->obj->vmapping, |
| 193 | − &cmd, byte_offset, width * bpp, | |
| 194 | + &cmd, byte_offset, dev_byte_offset, | |
| 195 | + width * bpp, | |
| 194 | 196 | &bytes_identical, &bytes_sent)) |
| 195 | 197 | goto error; |
| 196 | 198 | } |
| @@ -213,11 +213,12 @@ static void udl_compress_hline16( · 212 unmodified lines | ||
| 213 | 213 | */ |
| 214 | 214 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, |
| 215 | 215 | const char *front, char **urb_buf_ptr, |
| 216 | − u32 byte_offset, u32 byte_width, | |
| 216 | + u32 byte_offset, u32 device_byte_offset, | |
| 217 | + u32 byte_width, | |
| 217 | 218 | int *ident_ptr, int *sent_ptr) |
| 218 | 219 | { |
| 219 | 220 | const u8 *line_start, *line_end, *next_pixel; |
| 220 | − u32 base16 = 0 + (byte_offset / bpp) * 2; | |
| 221 | + u32 base16 = 0 + (device_byte_offset / bpp) * 2; | |
| 221 | 222 | struct urb *urb = *urb_ptr; |
| 222 | 223 | u8 *cmd = *urb_buf_ptr; |
| 223 | 224 | u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; |
| @@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) · 305 unmodified lines | ||
| 306 | 306 | |
| 307 | 307 | BUG_ON(!atomic_read(&bo->reserved)); |
| 308 | 308 | BUG_ON(old_mem_type != TTM_PL_VRAM && |
| 309 | − old_mem_type != VMW_PL_FLAG_GMR); | |
| 309 | + old_mem_type != VMW_PL_GMR); | |
| 310 | 310 | |
| 311 | 311 | pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; |
| 312 | 312 | if (pin) |
| @@ -1098,6 +1098,11 @@ static void vmw_pm_complete(struct device *kdev) · 1097 unmodified lines | ||
| 1098 | 1098 | struct drm_device *dev = pci_get_drvdata(pdev); |
| 1099 | 1099 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1100 | 1100 | |
| 1101 | + mutex_lock(&dev_priv->hw_mutex); | |
| 1102 | + vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | |
| 1103 | + (void) vmw_read(dev_priv, SVGA_REG_ID); | |
| 1104 | + mutex_unlock(&dev_priv->hw_mutex); | |
| 1105 | + | |
| 1101 | 1106 | /** |
| 1102 | 1107 | * Reclaim 3d reference held by fbdev and potentially |
| 1103 | 1108 | * start fifo. |
| @@ -110,6 +110,8 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, · 109 unmodified lines | ||
| 110 | 110 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); |
| 111 | 111 | |
| 112 | 112 | ret = copy_to_user(buffer, bounce, size); |
| 113 | + if (ret) | |
| 114 | + ret = -EFAULT; | |
| 113 | 115 | vfree(bounce); |
| 114 | 116 | |
| 115 | 117 | if (unlikely(ret != 0)) |
| @@ -46,9 +46,9 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, · 45 unmodified lines | ||
| 46 | 46 | rdesc[559] = 0x45; |
| 47 | 47 | } |
| 48 | 48 | /* the same as above (s/usage/physical/) */ |
| 49 | − if ((quirks & MS_RDESC_3K) && *rsize == 106 && | |
| 50 | − !memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, | |
| 51 | − &rdesc[94], 4)) { | |
| 49 | + if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 && | |
| 50 | + rdesc[95] == 0x00 && rdesc[96] == 0x29 && | |
| 51 | + rdesc[97] == 0xff) { | |
| 52 | 52 | rdesc[94] = 0x35; |
| 53 | 53 | rdesc[96] = 0x45; |
| 54 | 54 | } |
| @@ -42,7 +42,6 @@ static struct cdev hidraw_cdev; · 41 unmodified lines | ||
| 42 | 42 | static struct class *hidraw_class; |
| 43 | 43 | static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; |
| 44 | 44 | static DEFINE_MUTEX(minors_lock); |
| 45 | −static void drop_ref(struct hidraw *hid, int exists_bit); | |
| 46 | 45 | |
| 47 | 46 | static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
| 48 | 47 | { |
| @@ -114,7 +113,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, · 65 unmodified lines | ||
| 114 | 113 | __u8 *buf; |
| 115 | 114 | int ret = 0; |
| 116 | 115 | |
| 117 | − if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { | |
| 116 | + if (!hidraw_table[minor]) { | |
| 118 | 117 | ret = -ENODEV; |
| 119 | 118 | goto out; |
| 120 | 119 | } |
| @@ -262,7 +261,7 @@ static int hidraw_open(struct inode *inode, struct file *file) · 141 unmodified lines | ||
| 262 | 261 | } |
| 263 | 262 | |
| 264 | 263 | mutex_lock(&minors_lock); |
| 265 | − if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { | |
| 264 | + if (!hidraw_table[minor]) { | |
| 266 | 265 | err = -ENODEV; |
| 267 | 266 | goto out_unlock; |
| 268 | 267 | } |
| @@ -299,12 +298,36 @@ out: · 30 unmodified lines | ||
| 299 | 298 | static int hidraw_release(struct inode * inode, struct file * file) |
| 300 | 299 | { |
| 301 | 300 | unsigned int minor = iminor(inode); |
| 301 | + struct hidraw *dev; | |
| 302 | 302 | struct hidraw_list *list = file->private_data; |
| 303 | + int ret; | |
| 304 | + int i; | |
| 305 | + | |
| 306 | + mutex_lock(&minors_lock); | |
| 307 | + if (!hidraw_table[minor]) { | |
| 308 | + ret = -ENODEV; | |
| 309 | + goto unlock; | |
| 310 | + } | |
| 303 | 311 | |
| 304 | − drop_ref(hidraw_table[minor], 0); | |
| 305 | 312 | list_del(&list->node); |
| 313 | + dev = hidraw_table[minor]; | |
| 314 | + if (!--dev->open) { | |
| 315 | + if (list->hidraw->exist) { | |
| 316 | + hid_hw_power(dev->hid, PM_HINT_NORMAL); | |
| 317 | + hid_hw_close(dev->hid); | |
| 318 | + } else { | |
| 319 | + kfree(list->hidraw); | |
| 320 | + } | |
| 321 | + } | |
| 322 | + | |
| 323 | + for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i) | |
| 324 | + kfree(list->buffer[i].value); | |
| 306 | 325 | kfree(list); |
| 307 | − return 0; | |
| 326 | + ret = 0; | |
| 327 | +unlock: | |
| 328 | + mutex_unlock(&minors_lock); | |
| 329 | + | |
| 330 | + return ret; | |
| 308 | 331 | } |
| 309 | 332 | |
| 310 | 333 | static long hidraw_ioctl(struct file *file, unsigned int cmd, |
| @@ -506,7 +529,21 @@ EXPORT_SYMBOL_GPL(hidraw_connect); · 195 unmodified lines | ||
| 506 | 529 | void hidraw_disconnect(struct hid_device *hid) |
| 507 | 530 | { |
| 508 | 531 | struct hidraw *hidraw = hid->hidraw; |
| 509 | − drop_ref(hidraw, 1); | |
| 532 | + | |
| 533 | + mutex_lock(&minors_lock); | |
| 534 | + hidraw->exist = 0; | |
| 535 | + | |
| 536 | + device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | |
| 537 | + | |
| 538 | + hidraw_table[hidraw->minor] = NULL; | |
| 539 | + | |
| 540 | + if (hidraw->open) { | |
| 541 | + hid_hw_close(hid); | |
| 542 | + wake_up_interruptible(&hidraw->wait); | |
| 543 | + } else { | |
| 544 | + kfree(hidraw); | |
| 545 | + } | |
| 546 | + mutex_unlock(&minors_lock); | |
| 510 | 547 | } |
| 511 | 548 | EXPORT_SYMBOL_GPL(hidraw_disconnect); |
| 512 | 549 | |
| @@ -555,23 +592,3 @@ void hidraw_exit(void) · 42 unmodified lines | ||
| 555 | 592 | unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); |
| 556 | 593 | |
| 557 | 594 | } |
| 558 | − | |
| 559 | −static void drop_ref(struct hidraw *hidraw, int exists_bit) | |
| 560 | −{ | |
| 561 | − mutex_lock(&minors_lock); | |
| 562 | − if (exists_bit) { | |
| 563 | − hid_hw_close(hidraw->hid); | |
| 564 | − hidraw->exist = 0; | |
| 565 | − if (hidraw->open) | |
| 566 | − wake_up_interruptible(&hidraw->wait); | |
| 567 | − } else { | |
| 568 | − --hidraw->open; | |
| 569 | − } | |
| 570 | − | |
| 571 | − if (!hidraw->open && !hidraw->exist) { | |
| 572 | − device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | |
| 573 | − hidraw_table[hidraw->minor] = NULL; | |
| 574 | − kfree(hidraw); | |
| 575 | − } | |
| 576 | − mutex_unlock(&minors_lock); | |
| 577 | −} | |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | * ASB100-A supports pwm1, while plain ASB100 does not. There is no known |
| 33 | 33 | * way for the driver to tell which one is there. |
| 34 | 34 | * |
| 35 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 35 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 36 | 36 | * asb100 7 3 1 4 0x31 0x0694 yes no |
| 37 | 37 | */ |
| 38 | 38 | |
| @@ -2083,6 +2083,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) · 2082 unmodified lines | ||
| 2083 | 2083 | mutex_init(&data->lock); |
| 2084 | 2084 | mutex_init(&data->update_lock); |
| 2085 | 2085 | data->name = w83627ehf_device_names[sio_data->kind]; |
| 2086 | + data->bank = 0xff; /* Force initial bank selection */ | |
| 2086 | 2087 | platform_set_drvdata(pdev, data); |
| 2087 | 2088 | |
| 2088 | 2089 | /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | /* |
| 26 | 26 | * Supports following chips: |
| 27 | 27 | * |
| 28 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 28 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 29 | 29 | * w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) |
| 30 | 30 | * w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) |
| 31 | 31 | * w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | /* |
| 25 | 25 | * Supports following chips: |
| 26 | 26 | * |
| 27 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 27 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 28 | 28 | * as99127f 7 3 0 3 0x31 0x12c3 yes no |
| 29 | 29 | * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no |
| 30 | 30 | * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | /* |
| 23 | 23 | * Supports following chips: |
| 24 | 24 | * |
| 25 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 25 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 26 | 26 | * w83791d 10 5 5 3 0x71 0x5ca3 yes no |
| 27 | 27 | * |
| 28 | 28 | * The w83791d chip appears to be part way between the 83781d and the |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | /* |
| 32 | 32 | * Supports following chips: |
| 33 | 33 | * |
| 34 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 34 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 35 | 35 | * w83792d 9 7 7 3 0x7a 0x5ca3 yes no |
| 36 | 36 | */ |
| 37 | 37 | |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | /* |
| 21 | 21 | * Supports following chips: |
| 22 | 22 | * |
| 23 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 23 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 24 | 24 | * w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no |
| 25 | 25 | */ |
| 26 | 26 | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * Freescale MXS I2C bus driver |
| 3 | 3 | * |
| 4 | − * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. | |
| 4 | + * Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K. | |
| 5 | 5 | * |
| 6 | 6 | * based on a (non-working) driver which was: |
| 7 | 7 | * |
| @@ -35,10 +35,6 @@ · 27 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | #define DRIVER_NAME "mxs-i2c" |
| 37 | 37 | |
| 38 | −static bool use_pioqueue; | |
| 39 | −module_param(use_pioqueue, bool, 0); | |
| 40 | −MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); | |
| 41 | − | |
| 42 | 38 | #define MXS_I2C_CTRL0 (0x00) |
| 43 | 39 | #define MXS_I2C_CTRL0_SET (0x04) |
| 44 | 40 | |
| @@ -75,23 +71,6 @@ MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); · 30 unmodified lines | ||
| 75 | 71 | MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \ |
| 76 | 72 | MXS_I2C_CTRL1_SLAVE_IRQ) |
| 77 | 73 | |
| 78 | −#define MXS_I2C_QUEUECTRL (0x60) | |
| 79 | −#define MXS_I2C_QUEUECTRL_SET (0x64) | |
| 80 | −#define MXS_I2C_QUEUECTRL_CLR (0x68) | |
| 81 | − | |
| 82 | −#define MXS_I2C_QUEUECTRL_QUEUE_RUN 0x20 | |
| 83 | −#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE 0x04 | |
| 84 | − | |
| 85 | −#define MXS_I2C_QUEUESTAT (0x70) | |
| 86 | −#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 | |
| 87 | −#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F | |
| 88 | − | |
| 89 | −#define MXS_I2C_QUEUECMD (0x80) | |
| 90 | − | |
| 91 | −#define MXS_I2C_QUEUEDATA (0x90) | |
| 92 | − | |
| 93 | −#define MXS_I2C_DATA (0xa0) | |
| 94 | − | |
| 95 | 74 | |
| 96 | 75 | #define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \ |
| 97 | 76 | MXS_I2C_CTRL0_PRE_SEND_START | \ |
| @@ -153,7 +132,6 @@ struct mxs_i2c_dev { · 55 unmodified lines | ||
| 153 | 132 | const struct mxs_i2c_speed_config *speed; |
| 154 | 133 | |
| 155 | 134 | /* DMA support components */ |
| 156 | − bool dma_mode; | |
| 157 | 135 | int dma_channel; |
| 158 | 136 | struct dma_chan *dmach; |
| 159 | 137 | struct mxs_dma_data dma_data; |
| @@ -172,99 +150,6 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c) · 12 unmodified lines | ||
| 172 | 150 | writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2); |
| 173 | 151 | |
| 174 | 152 | writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); |
| 175 | − if (i2c->dma_mode) | |
| 176 | − writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, | |
| 177 | − i2c->regs + MXS_I2C_QUEUECTRL_CLR); | |
| 178 | − else | |
| 179 | − writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, | |
| 180 | − i2c->regs + MXS_I2C_QUEUECTRL_SET); | |
| 181 | −} | |
| 182 | − | |
| 183 | −static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len, | |
| 184 | − int flags) | |
| 185 | −{ | |
| 186 | − u32 data; | |
| 187 | − | |
| 188 | − writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD); | |
| 189 | − | |
| 190 | − data = (addr << 1) | I2C_SMBUS_READ; | |
| 191 | − writel(data, i2c->regs + MXS_I2C_DATA); | |
| 192 | − | |
| 193 | − data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags; | |
| 194 | − writel(data, i2c->regs + MXS_I2C_QUEUECMD); | |
| 195 | −} | |
| 196 | − | |
| 197 | −static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c, | |
| 198 | − u8 addr, u8 *buf, int len, int flags) | |
| 199 | −{ | |
| 200 | − u32 data; | |
| 201 | − int i, shifts_left; | |
| 202 | − | |
| 203 | − data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags; | |
| 204 | − writel(data, i2c->regs + MXS_I2C_QUEUECMD); | |
| 205 | − | |
| 206 | − /* | |
| 207 | − * We have to copy the slave address (u8) and buffer (arbitrary number | |
| 208 | − * of u8) into the data register (u32). To achieve that, the u8 are put | |
| 209 | − * into the MSBs of 'data' which is then shifted for the next u8. When | |
| 210 | − * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32 | |
| 211 | − * looks like this: | |
| 212 | − * | |
| 213 | − * 3 2 1 0 | |
| 214 | − * 10987654|32109876|54321098|76543210 | |
| 215 | − * --------+--------+--------+-------- | |
| 216 | − * buffer+2|buffer+1|buffer+0|slave_addr | |
| 217 | − */ | |
| 218 | − | |
| 219 | − data = ((addr << 1) | I2C_SMBUS_WRITE) << 24; | |
| 220 | − | |
| 221 | − for (i = 0; i < len; i++) { | |
| 222 | − data >>= 8; | |
| 223 | − data |= buf[i] << 24; | |
| 224 | − if ((i & 3) == 2) | |
| 225 | − writel(data, i2c->regs + MXS_I2C_DATA); | |
| 226 | − } | |
| 227 | − | |
| 228 | − /* Write out the remaining bytes if any */ | |
| 229 | − shifts_left = 24 - (i & 3) * 8; | |
| 230 | − if (shifts_left) | |
| 231 | − writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA); | |
| 232 | −} | |
| 233 | − | |
| 234 | −/* | |
| 235 | − * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the | |
| 236 | − * rd_threshold to 1). Couldn't get this to work, though. | |
| 237 | − */ | |
| 238 | −static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c) | |
| 239 | −{ | |
| 240 | − unsigned long timeout = jiffies + msecs_to_jiffies(1000); | |
| 241 | − | |
| 242 | − while (readl(i2c->regs + MXS_I2C_QUEUESTAT) | |
| 243 | − & MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) { | |
| 244 | − if (time_after(jiffies, timeout)) | |
| 245 | − return -ETIMEDOUT; | |
| 246 | − cond_resched(); | |
| 247 | − } | |
| 248 | − | |
| 249 | − return 0; | |
| 250 | −} | |
| 251 | − | |
| 252 | −static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len) | |
| 253 | −{ | |
| 254 | − u32 uninitialized_var(data); | |
| 255 | − int i; | |
| 256 | − | |
| 257 | − for (i = 0; i < len; i++) { | |
| 258 | − if ((i & 3) == 0) { | |
| 259 | − if (mxs_i2c_wait_for_data(i2c)) | |
| 260 | − return -ETIMEDOUT; | |
| 261 | − data = readl(i2c->regs + MXS_I2C_QUEUEDATA); | |
| 262 | − } | |
| 263 | − buf[i] = data & 0xff; | |
| 264 | − data >>= 8; | |
| 265 | − } | |
| 266 | − | |
| 267 | − return 0; | |
| 268 | 153 | } |
| 269 | 154 | |
| 270 | 155 | static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c) |
| @@ -432,39 +317,17 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, · 161 unmodified lines | ||
| 432 | 317 | init_completion(&i2c->cmd_complete); |
| 433 | 318 | i2c->cmd_err = 0; |
| 434 | 319 | |
| 435 | − if (i2c->dma_mode) { | |
| 436 | − ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); | |
| 437 | − if (ret) | |
| 438 | − return ret; | |
| 439 | − } else { | |
| 440 | − if (msg->flags & I2C_M_RD) { | |
| 441 | − mxs_i2c_pioq_setup_read(i2c, msg->addr, | |
| 442 | − msg->len, flags); | |
| 443 | − } else { | |
| 444 | − mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, | |
| 445 | − msg->len, flags); | |
| 446 | − } | |
| 447 | − | |
| 448 | − writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, | |
| 449 | − i2c->regs + MXS_I2C_QUEUECTRL_SET); | |
| 450 | − } | |
| 320 | + ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); | |
| 321 | + if (ret) | |
| 322 | + return ret; | |
| 451 | 323 | |
| 452 | 324 | ret = wait_for_completion_timeout(&i2c->cmd_complete, |
| 453 | 325 | msecs_to_jiffies(1000)); |
| 454 | 326 | if (ret == 0) |
| 455 | 327 | goto timeout; |
| 456 | 328 | |
| 457 | − if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) { | |
| 458 | − ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len); | |
| 459 | − if (ret) | |
| 460 | − goto timeout; | |
| 461 | − } | |
| 462 | − | |
| 463 | 329 | if (i2c->cmd_err == -ENXIO) |
| 464 | 330 | mxs_i2c_reset(i2c); |
| 465 | − else | |
| 466 | − writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, | |
| 467 | − i2c->regs + MXS_I2C_QUEUECTRL_CLR); | |
| 468 | 331 | |
| 469 | 332 | dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); |
| 470 | 333 | |
| @@ -472,8 +335,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, · 1 unmodified line | ||
| 472 | 335 | |
| 473 | 336 | timeout: |
| 474 | 337 | dev_dbg(i2c->dev, "Timeout!\n"); |
| 475 | − if (i2c->dma_mode) | |
| 476 | − mxs_i2c_dma_finish(i2c); | |
| 338 | + mxs_i2c_dma_finish(i2c); | |
| 477 | 339 | mxs_i2c_reset(i2c); |
| 478 | 340 | return -ETIMEDOUT; |
| 479 | 341 | } |
| @@ -502,7 +364,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) · 22 unmodified lines | ||
| 502 | 364 | { |
| 503 | 365 | struct mxs_i2c_dev *i2c = dev_id; |
| 504 | 366 | u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; |
| 505 | − bool is_last_cmd; | |
| 506 | 367 | |
| 507 | 368 | if (!stat) |
| 508 | 369 | return IRQ_NONE; |
| @@ -515,14 +376,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) · 6 unmodified lines | ||
| 515 | 376 | /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ |
| 516 | 377 | i2c->cmd_err = -EIO; |
| 517 | 378 | |
| 518 | − if (!i2c->dma_mode) { | |
| 519 | − is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & | |
| 520 | − MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; | |
| 521 | − | |
| 522 | − if (is_last_cmd || i2c->cmd_err) | |
| 523 | − complete(&i2c->cmd_complete); | |
| 524 | − } | |
| 525 | − | |
| 526 | 379 | writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); |
| 527 | 380 | |
| 528 | 381 | return IRQ_HANDLED; |
| @@ -555,15 +408,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) · 26 unmodified lines | ||
| 555 | 408 | struct device_node *node = dev->of_node; |
| 556 | 409 | int ret; |
| 557 | 410 | |
| 558 | − /* | |
| 559 | − * The MXS I2C DMA mode is prefered and enabled by default. | |
| 560 | − * The PIO mode is still supported, but should be used only | |
| 561 | − * for debuging purposes etc. | |
| 562 | − */ | |
| 563 | − i2c->dma_mode = !use_pioqueue; | |
| 564 | − if (!i2c->dma_mode) | |
| 565 | − dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n"); | |
| 566 | − | |
| 567 | 411 | /* |
| 568 | 412 | * TODO: This is a temporary solution and should be changed |
| 569 | 413 | * to use generic DMA binding later when the helpers get in. |
| @@ -571,8 +415,8 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) · 1 unmodified line | ||
| 571 | 415 | ret = of_property_read_u32(node, "fsl,i2c-dma-channel", |
| 572 | 416 | &i2c->dma_channel); |
| 573 | 417 | if (ret) { |
| 574 | − dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n"); | |
| 575 | − i2c->dma_mode = 0; | |
| 418 | + dev_err(dev, "Failed to get DMA channel!\n"); | |
| 419 | + return -ENODEV; | |
| 576 | 420 | } |
| 577 | 421 | |
| 578 | 422 | ret = of_property_read_u32(node, "clock-frequency", &speed); |
| @@ -634,15 +478,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) · 55 unmodified lines | ||
| 634 | 478 | } |
| 635 | 479 | |
| 636 | 480 | /* Setup the DMA */ |
| 637 | − if (i2c->dma_mode) { | |
| 638 | − dma_cap_zero(mask); | |
| 639 | − dma_cap_set(DMA_SLAVE, mask); | |
| 640 | − i2c->dma_data.chan_irq = dmairq; | |
| 641 | − i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); | |
| 642 | − if (!i2c->dmach) { | |
| 643 | − dev_err(dev, "Failed to request dma\n"); | |
| 644 | − return -ENODEV; | |
| 645 | − } | |
| 481 | + dma_cap_zero(mask); | |
| 482 | + dma_cap_set(DMA_SLAVE, mask); | |
| 483 | + i2c->dma_data.chan_irq = dmairq; | |
| 484 | + i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); | |
| 485 | + if (!i2c->dmach) { | |
| 486 | + dev_err(dev, "Failed to request dma\n"); | |
| 487 | + return -ENODEV; | |
| 646 | 488 | } |
| 647 | 489 | |
| 648 | 490 | platform_set_drvdata(pdev, i2c); |
| @@ -644,7 +644,11 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, · 643 unmodified lines | ||
| 644 | 644 | |
| 645 | 645 | pm_runtime_get_sync(&dev->adev->dev); |
| 646 | 646 | |
| 647 | − clk_enable(dev->clk); | |
| 647 | + status = clk_prepare_enable(dev->clk); | |
| 648 | + if (status) { | |
| 649 | + dev_err(&dev->adev->dev, "can't prepare_enable clock\n"); | |
| 650 | + goto out_clk; | |
| 651 | + } | |
| 648 | 652 | |
| 649 | 653 | status = init_hw(dev); |
| 650 | 654 | if (status) |
| @@ -671,7 +675,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, · 20 unmodified lines | ||
| 671 | 675 | } |
| 672 | 676 | |
| 673 | 677 | out: |
| 674 | − clk_disable(dev->clk); | |
| 678 | + clk_disable_unprepare(dev->clk); | |
| 679 | +out_clk: | |
| 675 | 680 | pm_runtime_put_sync(&dev->adev->dev); |
| 676 | 681 | |
| 677 | 682 | dev->busy = false; |
| @@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev) · 741 unmodified lines | ||
| 742 | 742 | } |
| 743 | 743 | |
| 744 | 744 | ret = devm_request_irq(&pdev->dev, i2c_dev->irq, |
| 745 | − tegra_i2c_isr, 0, pdev->name, i2c_dev); | |
| 745 | + tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev); | |
| 746 | 746 | if (ret) { |
| 747 | 747 | dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq); |
| 748 | 748 | return ret; |
| @@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev) · 168 unmodified lines | ||
| 169 | 169 | mux->busses = devm_kzalloc(&pdev->dev, |
| 170 | 170 | sizeof(mux->busses) * mux->pdata->bus_count, |
| 171 | 171 | GFP_KERNEL); |
| 172 | − if (!mux->states) { | |
| 172 | + if (!mux->busses) { | |
| 173 | 173 | dev_err(&pdev->dev, "Cannot allocate busses\n"); |
| 174 | 174 | ret = -ENOMEM; |
| 175 | 175 | goto err; |
| @@ -168,7 +168,8 @@ static int __init armctrl_of_init(struct device_node *node, · 167 unmodified lines | ||
| 168 | 168 | } |
| 169 | 169 | |
| 170 | 170 | static struct of_device_id irq_of_match[] __initconst = { |
| 171 | − { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init } | |
| 171 | + { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }, | |
| 172 | + { } | |
| 172 | 173 | }; |
| 173 | 174 | |
| 174 | 175 | void __init bcm2835_init_irq(void) |
| @@ -33,8 +33,6 @@ · 32 unmodified lines | ||
| 33 | 33 | struct led_trigger_cpu { |
| 34 | 34 | char name[MAX_NAME_LEN]; |
| 35 | 35 | struct led_trigger *_trig; |
| 36 | − struct mutex lock; | |
| 37 | − int lock_is_inited; | |
| 38 | 36 | }; |
| 39 | 37 | |
| 40 | 38 | static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); |
| @@ -50,12 +48,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) · 9 unmodified lines | ||
| 50 | 48 | { |
| 51 | 49 | struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); |
| 52 | 50 | |
| 53 | − /* mutex lock should be initialized before calling mutex_call() */ | |
| 54 | − if (!trig->lock_is_inited) | |
| 55 | − return; | |
| 56 | − | |
| 57 | − mutex_lock(&trig->lock); | |
| 58 | − | |
| 59 | 51 | /* Locate the correct CPU LED */ |
| 60 | 52 | switch (ledevt) { |
| 61 | 53 | case CPU_LED_IDLE_END: |
| @@ -75,8 +67,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) · 13 unmodified lines | ||
| 75 | 67 | /* Will leave the LED as it is */ |
| 76 | 68 | break; |
| 77 | 69 | } |
| 78 | − | |
| 79 | − mutex_unlock(&trig->lock); | |
| 80 | 70 | } |
| 81 | 71 | EXPORT_SYMBOL(ledtrig_cpu); |
| 82 | 72 | |
| @@ -117,14 +107,9 @@ static int __init ledtrig_cpu_init(void) · 34 unmodified lines | ||
| 117 | 107 | for_each_possible_cpu(cpu) { |
| 118 | 108 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); |
| 119 | 109 | |
| 120 | − mutex_init(&trig->lock); | |
| 121 | − | |
| 122 | 110 | snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); |
| 123 | 111 | |
| 124 | − mutex_lock(&trig->lock); | |
| 125 | 112 | led_trigger_register_simple(trig->name, &trig->_trig); |
| 126 | − trig->lock_is_inited = 1; | |
| 127 | − mutex_unlock(&trig->lock); | |
| 128 | 113 | } |
| 129 | 114 | |
| 130 | 115 | register_syscore_ops(&ledtrig_cpu_syscore_ops); |
| @@ -142,15 +127,9 @@ static void __exit ledtrig_cpu_exit(void) · 11 unmodified lines | ||
| 142 | 127 | for_each_possible_cpu(cpu) { |
| 143 | 128 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); |
| 144 | 129 | |
| 145 | − mutex_lock(&trig->lock); | |
| 146 | − | |
| 147 | 130 | led_trigger_unregister_simple(trig->_trig); |
| 148 | 131 | trig->_trig = NULL; |
| 149 | 132 | memset(trig->name, 0, MAX_NAME_LEN); |
| 150 | − trig->lock_is_inited = 0; | |
| 151 | − | |
| 152 | − mutex_unlock(&trig->lock); | |
| 153 | − mutex_destroy(&trig->lock); | |
| 154 | 133 | } |
| 155 | 134 | |
| 156 | 135 | unregister_syscore_ops(&ledtrig_cpu_syscore_ops); |
| @@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = { · 207 unmodified lines | ||
| 208 | 208 | MMC_CAP_CMD23, |
| 209 | 209 | }; |
| 210 | 210 | |
| 211 | −static struct dw_mci_drv_data exynos5250_drv_data = { | |
| 211 | +static const struct dw_mci_drv_data exynos5250_drv_data = { | |
| 212 | 212 | .caps = exynos5250_dwmmc_caps, |
| 213 | 213 | .init = dw_mci_exynos_priv_init, |
| 214 | 214 | .setup_clock = dw_mci_exynos_setup_clock, |
| @@ -220,14 +220,14 @@ static struct dw_mci_drv_data exynos5250_drv_data = { · 5 unmodified lines | ||
| 220 | 220 | |
| 221 | 221 | static const struct of_device_id dw_mci_exynos_match[] = { |
| 222 | 222 | { .compatible = "samsung,exynos5250-dw-mshc", |
| 223 | − .data = (void *)&exynos5250_drv_data, }, | |
| 223 | + .data = &exynos5250_drv_data, }, | |
| 224 | 224 | {}, |
| 225 | 225 | }; |
| 226 | −MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); | |
| 226 | +MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); | |
| 227 | 227 | |
| 228 | 228 | int dw_mci_exynos_probe(struct platform_device *pdev) |
| 229 | 229 | { |
| 230 | − struct dw_mci_drv_data *drv_data; | |
| 230 | + const struct dw_mci_drv_data *drv_data; | |
| 231 | 231 | const struct of_device_id *match; |
| 232 | 232 | |
| 233 | 233 | match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #include "dw_mmc.h" |
| 25 | 25 | |
| 26 | 26 | int dw_mci_pltfm_register(struct platform_device *pdev, |
| 27 | − struct dw_mci_drv_data *drv_data) | |
| 27 | + const struct dw_mci_drv_data *drv_data) | |
| 28 | 28 | { |
| 29 | 29 | struct dw_mci *host; |
| 30 | 30 | struct resource *regs; |
| @@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev, · 19 unmodified lines | ||
| 50 | 50 | if (!host->regs) |
| 51 | 51 | return -ENOMEM; |
| 52 | 52 | |
| 53 | − if (host->drv_data->init) { | |
| 54 | − ret = host->drv_data->init(host); | |
| 53 | + if (drv_data && drv_data->init) { | |
| 54 | + ret = drv_data->init(host); | |
| 55 | 55 | if (ret) |
| 56 | 56 | return ret; |
| 57 | 57 | } |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #define _DW_MMC_PLTFM_H_ |
| 14 | 14 | |
| 15 | 15 | extern int dw_mci_pltfm_register(struct platform_device *pdev, |
| 16 | − struct dw_mci_drv_data *drv_data); | |
| 16 | + const struct dw_mci_drv_data *drv_data); | |
| 17 | 17 | extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); |
| 18 | 18 | extern const struct dev_pm_ops dw_mci_pltfm_pmops; |
| 19 | 19 | |
| @@ -232,6 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · 231 unmodified lines | ||
| 232 | 232 | { |
| 233 | 233 | struct mmc_data *data; |
| 234 | 234 | struct dw_mci_slot *slot = mmc_priv(mmc); |
| 235 | + struct dw_mci_drv_data *drv_data = slot->host->drv_data; | |
| 235 | 236 | u32 cmdr; |
| 236 | 237 | cmd->error = -EINPROGRESS; |
| 237 | 238 | |
| @@ -261,8 +262,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · 23 unmodified lines | ||
| 261 | 262 | cmdr |= SDMMC_CMD_DAT_WR; |
| 262 | 263 | } |
| 263 | 264 | |
| 264 | − if (slot->host->drv_data->prepare_command) | |
| 265 | − slot->host->drv_data->prepare_command(slot->host, &cmdr); | |
| 265 | + if (drv_data && drv_data->prepare_command) | |
| 266 | + drv_data->prepare_command(slot->host, &cmdr); | |
| 266 | 267 | |
| 267 | 268 | return cmdr; |
| 268 | 269 | } |
| @@ -434,7 +435,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) · 165 unmodified lines | ||
| 434 | 435 | return 0; |
| 435 | 436 | } |
| 436 | 437 | |
| 437 | −static struct dw_mci_dma_ops dw_mci_idmac_ops = { | |
| 438 | +static const struct dw_mci_dma_ops dw_mci_idmac_ops = { | |
| 438 | 439 | .init = dw_mci_idmac_init, |
| 439 | 440 | .start = dw_mci_idmac_start_dma, |
| 440 | 441 | .stop = dw_mci_idmac_stop_dma, |
| @@ -772,6 +773,7 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) · 331 unmodified lines | ||
| 772 | 773 | static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| 773 | 774 | { |
| 774 | 775 | struct dw_mci_slot *slot = mmc_priv(mmc); |
| 776 | + struct dw_mci_drv_data *drv_data = slot->host->drv_data; | |
| 775 | 777 | u32 regs; |
| 776 | 778 | |
| 777 | 779 | /* set default 1 bit mode */ |
| @@ -807,8 +809,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 29 unmodified lines | ||
| 807 | 809 | slot->clock = ios->clock; |
| 808 | 810 | } |
| 809 | 811 | |
| 810 | − if (slot->host->drv_data->set_ios) | |
| 811 | − slot->host->drv_data->set_ios(slot->host, ios); | |
| 812 | + if (drv_data && drv_data->set_ios) | |
| 813 | + drv_data->set_ios(slot->host, ios); | |
| 812 | 814 | |
| 813 | 815 | switch (ios->power_mode) { |
| 814 | 816 | case MMC_POWER_UP: |
| @@ -1815,6 +1817,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) · 1000 unmodified lines | ||
| 1815 | 1817 | { |
| 1816 | 1818 | struct mmc_host *mmc; |
| 1817 | 1819 | struct dw_mci_slot *slot; |
| 1820 | + struct dw_mci_drv_data *drv_data = host->drv_data; | |
| 1818 | 1821 | int ctrl_id, ret; |
| 1819 | 1822 | u8 bus_width; |
| 1820 | 1823 | |
| @@ -1854,8 +1857,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) · 33 unmodified lines | ||
| 1854 | 1857 | } else { |
| 1855 | 1858 | ctrl_id = to_platform_device(host->dev)->id; |
| 1856 | 1859 | } |
| 1857 | − if (host->drv_data && host->drv_data->caps) | |
| 1858 | − mmc->caps |= host->drv_data->caps[ctrl_id]; | |
| 1860 | + if (drv_data && drv_data->caps) | |
| 1861 | + mmc->caps |= drv_data->caps[ctrl_id]; | |
| 1859 | 1862 | |
| 1860 | 1863 | if (host->pdata->caps2) |
| 1861 | 1864 | mmc->caps2 = host->pdata->caps2; |
| @@ -1867,10 +1870,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) · 5 unmodified lines | ||
| 1867 | 1870 | else |
| 1868 | 1871 | bus_width = 1; |
| 1869 | 1872 | |
| 1870 | − if (host->drv_data->setup_bus) { | |
| 1873 | + if (drv_data && drv_data->setup_bus) { | |
| 1871 | 1874 | struct device_node *slot_np; |
| 1872 | 1875 | slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); |
| 1873 | − ret = host->drv_data->setup_bus(host, slot_np, bus_width); | |
| 1876 | + ret = drv_data->setup_bus(host, slot_np, bus_width); | |
| 1874 | 1877 | if (ret) |
| 1875 | 1878 | goto err_setup_bus; |
| 1876 | 1879 | } |
| @@ -1968,7 +1971,7 @@ static void dw_mci_init_dma(struct dw_mci *host) · 91 unmodified lines | ||
| 1968 | 1971 | /* Determine which DMA interface to use */ |
| 1969 | 1972 | #ifdef CONFIG_MMC_DW_IDMAC |
| 1970 | 1973 | host->dma_ops = &dw_mci_idmac_ops; |
| 1971 | − dev_info(&host->dev, "Using internal DMA controller.\n"); | |
| 1974 | + dev_info(host->dev, "Using internal DMA controller.\n"); | |
| 1972 | 1975 | #endif |
| 1973 | 1976 | |
| 1974 | 1977 | if (!host->dma_ops) |
| @@ -2035,6 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) · 60 unmodified lines | ||
| 2035 | 2038 | struct dw_mci_board *pdata; |
| 2036 | 2039 | struct device *dev = host->dev; |
| 2037 | 2040 | struct device_node *np = dev->of_node; |
| 2041 | + struct dw_mci_drv_data *drv_data = host->drv_data; | |
| 2038 | 2042 | int idx, ret; |
| 2039 | 2043 | |
| 2040 | 2044 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
| @@ -2062,8 +2066,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) · 21 unmodified lines | ||
| 2062 | 2066 | |
| 2063 | 2067 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); |
| 2064 | 2068 | |
| 2065 | − if (host->drv_data->parse_dt) { | |
| 2066 | − ret = host->drv_data->parse_dt(host); | |
| 2069 | + if (drv_data && drv_data->parse_dt) { | |
| 2070 | + ret = drv_data->parse_dt(host); | |
| 2067 | 2071 | if (ret) |
| 2068 | 2072 | return ERR_PTR(ret); |
| 2069 | 2073 | } |
| @@ -2080,6 +2084,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) · 10 unmodified lines | ||
| 2080 | 2084 | |
| 2081 | 2085 | int dw_mci_probe(struct dw_mci *host) |
| 2082 | 2086 | { |
| 2087 | + struct dw_mci_drv_data *drv_data = host->drv_data; | |
| 2083 | 2088 | int width, i, ret = 0; |
| 2084 | 2089 | u32 fifo_size; |
| 2085 | 2090 | int init_slots = 0; |
| @@ -2127,8 +2132,8 @@ int dw_mci_probe(struct dw_mci *host) · 41 unmodified lines | ||
| 2127 | 2132 | else |
| 2128 | 2133 | host->bus_hz = clk_get_rate(host->ciu_clk); |
| 2129 | 2134 | |
| 2130 | − if (host->drv_data->setup_clock) { | |
| 2131 | − ret = host->drv_data->setup_clock(host); | |
| 2135 | + if (drv_data && drv_data->setup_clock) { | |
| 2136 | + ret = drv_data->setup_clock(host); | |
| 2132 | 2137 | if (ret) { |
| 2133 | 2138 | dev_err(host->dev, |
| 2134 | 2139 | "implementation specific clock setup failed\n"); |
| @@ -2228,6 +2233,21 @@ int dw_mci_probe(struct dw_mci *host) · 93 unmodified lines | ||
| 2228 | 2233 | else |
| 2229 | 2234 | host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; |
| 2230 | 2235 | |
| 2236 | + /* | |
| 2237 | + * Enable interrupts for command done, data over, data empty, card det, | |
| 2238 | + * receive ready and error such as transmit, receive timeout, crc error | |
| 2239 | + */ | |
| 2240 | + mci_writel(host, RINTSTS, 0xFFFFFFFF); | |
| 2241 | + mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | |
| 2242 | + SDMMC_INT_TXDR | SDMMC_INT_RXDR | | |
| 2243 | + DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | |
| 2244 | + mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | |
| 2245 | + | |
| 2246 | + dev_info(host->dev, "DW MMC controller at irq %d, " | |
| 2247 | + "%d bit host data width, " | |
| 2248 | + "%u deep fifo\n", | |
| 2249 | + host->irq, width, fifo_size); | |
| 2250 | + | |
| 2231 | 2251 | /* We need at least one slot to succeed */ |
| 2232 | 2252 | for (i = 0; i < host->num_slots; i++) { |
| 2233 | 2253 | ret = dw_mci_init_slot(host, i); |
| @@ -2257,20 +2277,6 @@ int dw_mci_probe(struct dw_mci *host) · 23 unmodified lines | ||
| 2257 | 2277 | else |
| 2258 | 2278 | host->data_offset = DATA_240A_OFFSET; |
| 2259 | 2279 | |
| 2260 | − /* | |
| 2261 | − * Enable interrupts for command done, data over, data empty, card det, | |
| 2262 | − * receive ready and error such as transmit, receive timeout, crc error | |
| 2263 | − */ | |
| 2264 | − mci_writel(host, RINTSTS, 0xFFFFFFFF); | |
| 2265 | − mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | |
| 2266 | − SDMMC_INT_TXDR | SDMMC_INT_RXDR | | |
| 2267 | − DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | |
| 2268 | − mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | |
| 2269 | − | |
| 2270 | − dev_info(host->dev, "DW MMC controller at irq %d, " | |
| 2271 | − "%d bit host data width, " | |
| 2272 | − "%u deep fifo\n", | |
| 2273 | − host->irq, width, fifo_size); | |
| 2274 | 2280 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) |
| 2275 | 2281 | dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); |
| 2276 | 2282 | |
| @@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver); · 1133 unmodified lines | ||
| 1134 | 1134 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); |
| 1135 | 1135 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); |
| 1136 | 1136 | MODULE_LICENSE("GPL"); |
| 1137 | −MODULE_ALIAS("platform:imx-mmc"); | |
| 1137 | +MODULE_ALIAS("platform:mxc-mmc"); | |
| @@ -178,7 +178,8 @@ struct omap_hsmmc_host { · 177 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | static int omap_hsmmc_card_detect(struct device *dev, int slot) |
| 180 | 180 | { |
| 181 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 181 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 182 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 182 | 183 | |
| 183 | 184 | /* NOTE: assumes card detect signal is active-low */ |
| 184 | 185 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); |
| @@ -186,7 +187,8 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot) · 1 unmodified line | ||
| 186 | 187 | |
| 187 | 188 | static int omap_hsmmc_get_wp(struct device *dev, int slot) |
| 188 | 189 | { |
| 189 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 190 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 191 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 190 | 192 | |
| 191 | 193 | /* NOTE: assumes write protect signal is active-high */ |
| 192 | 194 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); |
| @@ -194,7 +196,8 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot) · 1 unmodified line | ||
| 194 | 196 | |
| 195 | 197 | static int omap_hsmmc_get_cover_state(struct device *dev, int slot) |
| 196 | 198 | { |
| 197 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 199 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 200 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 198 | 201 | |
| 199 | 202 | /* NOTE: assumes card detect signal is active-low */ |
| 200 | 203 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); |
| @@ -204,7 +207,8 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot) · 3 unmodified lines | ||
| 204 | 207 | |
| 205 | 208 | static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) |
| 206 | 209 | { |
| 207 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 210 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 211 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 208 | 212 | |
| 209 | 213 | disable_irq(mmc->slots[0].card_detect_irq); |
| 210 | 214 | return 0; |
| @@ -212,7 +216,8 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) · 1 unmodified line | ||
| 212 | 216 | |
| 213 | 217 | static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) |
| 214 | 218 | { |
| 215 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 219 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 220 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 216 | 221 | |
| 217 | 222 | enable_irq(mmc->slots[0].card_detect_irq); |
| 218 | 223 | return 0; |
| @@ -2009,9 +2014,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) · 1790 unmodified lines | ||
| 2009 | 2014 | clk_put(host->dbclk); |
| 2010 | 2015 | } |
| 2011 | 2016 | |
| 2012 | − mmc_free_host(host->mmc); | |
| 2017 | + omap_hsmmc_gpio_free(host->pdata); | |
| 2013 | 2018 | iounmap(host->base); |
| 2014 | − omap_hsmmc_gpio_free(pdev->dev.platform_data); | |
| 2019 | + mmc_free_host(host->mmc); | |
| 2015 | 2020 | |
| 2016 | 2021 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2017 | 2022 | if (res) |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | +#include <linux/err.h> | |
| 22 | 23 | #include <linux/io.h> |
| 23 | 24 | #include <linux/clk.h> |
| 24 | 25 | #include <linux/err.h> |
| @@ -84,30 +85,32 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) · 59 unmodified lines | ||
| 84 | 85 | struct sdhci_dove_priv *priv; |
| 85 | 86 | int ret; |
| 86 | 87 | |
| 87 | − ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); | |
| 88 | − if (ret) | |
| 89 | − goto sdhci_dove_register_fail; | |
| 90 | − | |
| 91 | 88 | priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), |
| 92 | 89 | GFP_KERNEL); |
| 93 | 90 | if (!priv) { |
| 94 | 91 | dev_err(&pdev->dev, "unable to allocate private data"); |
| 95 | − ret = -ENOMEM; | |
| 96 | − goto sdhci_dove_allocate_fail; | |
| 92 | + return -ENOMEM; | |
| 97 | 93 | } |
| 98 | 94 | |
| 95 | + priv->clk = clk_get(&pdev->dev, NULL); | |
| 96 | + if (!IS_ERR(priv->clk)) | |
| 97 | + clk_prepare_enable(priv->clk); | |
| 98 | + | |
| 99 | + ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); | |
| 100 | + if (ret) | |
| 101 | + goto sdhci_dove_register_fail; | |
| 102 | + | |
| 99 | 103 | host = platform_get_drvdata(pdev); |
| 100 | 104 | pltfm_host = sdhci_priv(host); |
| 101 | 105 | pltfm_host->priv = priv; |
| 102 | 106 | |
| 103 | − priv->clk = clk_get(&pdev->dev, NULL); | |
| 104 | − if (!IS_ERR(priv->clk)) | |
| 105 | − clk_prepare_enable(priv->clk); | |
| 106 | 107 | return 0; |
| 107 | 108 | |
| 108 | −sdhci_dove_allocate_fail: | |
| 109 | − sdhci_pltfm_unregister(pdev); | |
| 110 | 109 | sdhci_dove_register_fail: |
| 110 | + if (!IS_ERR(priv->clk)) { | |
| 111 | + clk_disable_unprepare(priv->clk); | |
| 112 | + clk_put(priv->clk); | |
| 113 | + } | |
| 111 | 114 | return ret; |
| 112 | 115 | } |
| 113 | 116 | |
| @@ -117,14 +120,13 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev) · 3 unmodified lines | ||
| 117 | 120 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 118 | 121 | struct sdhci_dove_priv *priv = pltfm_host->priv; |
| 119 | 122 | |
| 120 | − if (priv->clk) { | |
| 121 | − if (!IS_ERR(priv->clk)) { | |
| 122 | − clk_disable_unprepare(priv->clk); | |
| 123 | − clk_put(priv->clk); | |
| 124 | − } | |
| 125 | − devm_kfree(&pdev->dev, priv->clk); | |
| 123 | + sdhci_pltfm_unregister(pdev); | |
| 124 | + | |
| 125 | + if (!IS_ERR(priv->clk)) { | |
| 126 | + clk_disable_unprepare(priv->clk); | |
| 127 | + clk_put(priv->clk); | |
| 126 | 128 | } |
| 127 | − return sdhci_pltfm_unregister(pdev); | |
| 129 | + return 0; | |
| 128 | 130 | } |
| 129 | 131 | |
| 130 | 132 | static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { |
| @@ -169,6 +169,16 @@ static void esdhc_of_resume(struct sdhci_host *host) · 168 unmodified lines | ||
| 169 | 169 | } |
| 170 | 170 | #endif |
| 171 | 171 | |
| 172 | +static void esdhc_of_platform_init(struct sdhci_host *host) | |
| 173 | +{ | |
| 174 | + u32 vvn; | |
| 175 | + | |
| 176 | + vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); | |
| 177 | + vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; | |
| 178 | + if (vvn == VENDOR_V_22) | |
| 179 | + host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; | |
| 180 | +} | |
| 181 | + | |
| 172 | 182 | static struct sdhci_ops sdhci_esdhc_ops = { |
| 173 | 183 | .read_l = esdhc_readl, |
| 174 | 184 | .read_w = esdhc_readw, |
| @@ -180,6 +190,7 @@ static struct sdhci_ops sdhci_esdhc_ops = { · 5 unmodified lines | ||
| 180 | 190 | .enable_dma = esdhc_of_enable_dma, |
| 181 | 191 | .get_max_clock = esdhc_of_get_max_clock, |
| 182 | 192 | .get_min_clock = esdhc_of_get_min_clock, |
| 193 | + .platform_init = esdhc_of_platform_init, | |
| 183 | 194 | #ifdef CONFIG_PM |
| 184 | 195 | .platform_suspend = esdhc_of_suspend, |
| 185 | 196 | .platform_resume = esdhc_of_resume, |
| @@ -1196,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( · 1195 unmodified lines | ||
| 1196 | 1196 | return ERR_PTR(-ENODEV); |
| 1197 | 1197 | } |
| 1198 | 1198 | |
| 1199 | − if (pci_resource_len(pdev, bar) != 0x100) { | |
| 1199 | + if (pci_resource_len(pdev, bar) < 0x100) { | |
| 1200 | 1200 | dev_err(&pdev->dev, "Invalid iomem size. You may " |
| 1201 | 1201 | "experience problems.\n"); |
| 1202 | 1202 | } |
| @@ -150,6 +150,13 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, · 149 unmodified lines | ||
| 150 | 150 | goto err_remap; |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | + /* | |
| 154 | + * Some platforms need to probe the controller to be able to | |
| 155 | + * determine which caps should be used. | |
| 156 | + */ | |
| 157 | + if (host->ops && host->ops->platform_init) | |
| 158 | + host->ops->platform_init(host); | |
| 159 | + | |
| 153 | 160 | platform_set_drvdata(pdev, host); |
| 154 | 161 | |
| 155 | 162 | return host; |
| @@ -211,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) · 210 unmodified lines | ||
| 211 | 211 | if (ourhost->cur_clk != best_src) { |
| 212 | 212 | struct clk *clk = ourhost->clk_bus[best_src]; |
| 213 | 213 | |
| 214 | − clk_enable(clk); | |
| 215 | − clk_disable(ourhost->clk_bus[ourhost->cur_clk]); | |
| 214 | + clk_prepare_enable(clk); | |
| 215 | + clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); | |
| 216 | 216 | |
| 217 | 217 | /* turn clock off to card before changing clock source */ |
| 218 | 218 | writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); |
| @@ -607,7 +607,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) · 388 unmodified lines | ||
| 607 | 607 | } |
| 608 | 608 | |
| 609 | 609 | /* enable the local io clock and keep it running for the moment. */ |
| 610 | − clk_enable(sc->clk_io); | |
| 610 | + clk_prepare_enable(sc->clk_io); | |
| 611 | 611 | |
| 612 | 612 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 613 | 613 | struct clk *clk; |
| @@ -638,7 +638,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) · 24 unmodified lines | ||
| 638 | 638 | } |
| 639 | 639 | |
| 640 | 640 | #ifndef CONFIG_PM_RUNTIME |
| 641 | − clk_enable(sc->clk_bus[sc->cur_clk]); | |
| 641 | + clk_prepare_enable(sc->clk_bus[sc->cur_clk]); | |
| 642 | 642 | #endif |
| 643 | 643 | |
| 644 | 644 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -747,13 +747,14 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) · 102 unmodified lines | ||
| 747 | 747 | sdhci_s3c_setup_card_detect_gpio(sc); |
| 748 | 748 | |
| 749 | 749 | #ifdef CONFIG_PM_RUNTIME |
| 750 | − clk_disable(sc->clk_io); | |
| 750 | + if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) | |
| 751 | + clk_disable_unprepare(sc->clk_io); | |
| 751 | 752 | #endif |
| 752 | 753 | return 0; |
| 753 | 754 | |
| 754 | 755 | err_req_regs: |
| 755 | 756 | #ifndef CONFIG_PM_RUNTIME |
| 756 | − clk_disable(sc->clk_bus[sc->cur_clk]); | |
| 757 | + clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); | |
| 757 | 758 | #endif |
| 758 | 759 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 759 | 760 | if (sc->clk_bus[ptr]) { |
| @@ -762,7 +763,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 762 | 763 | } |
| 763 | 764 | |
| 764 | 765 | err_no_busclks: |
| 765 | − clk_disable(sc->clk_io); | |
| 766 | + clk_disable_unprepare(sc->clk_io); | |
| 766 | 767 | clk_put(sc->clk_io); |
| 767 | 768 | |
| 768 | 769 | err_io_clk: |
| @@ -794,7 +795,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) · 25 unmodified lines | ||
| 794 | 795 | gpio_free(sc->ext_cd_gpio); |
| 795 | 796 | |
| 796 | 797 | #ifdef CONFIG_PM_RUNTIME |
| 797 | − clk_enable(sc->clk_io); | |
| 798 | + if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) | |
| 799 | + clk_prepare_enable(sc->clk_io); | |
| 798 | 800 | #endif |
| 799 | 801 | sdhci_remove_host(host, 1); |
| 800 | 802 | |
| @@ -802,14 +804,14 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) · 1 unmodified line | ||
| 802 | 804 | pm_runtime_disable(&pdev->dev); |
| 803 | 805 | |
| 804 | 806 | #ifndef CONFIG_PM_RUNTIME |
| 805 | − clk_disable(sc->clk_bus[sc->cur_clk]); | |
| 807 | + clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); | |
| 806 | 808 | #endif |
| 807 | 809 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 808 | 810 | if (sc->clk_bus[ptr]) { |
| 809 | 811 | clk_put(sc->clk_bus[ptr]); |
| 810 | 812 | } |
| 811 | 813 | } |
| 812 | − clk_disable(sc->clk_io); | |
| 814 | + clk_disable_unprepare(sc->clk_io); | |
| 813 | 815 | clk_put(sc->clk_io); |
| 814 | 816 | |
| 815 | 817 | if (pdev->dev.of_node) { |
| @@ -849,8 +851,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev) · 33 unmodified lines | ||
| 849 | 851 | |
| 850 | 852 | ret = sdhci_runtime_suspend_host(host); |
| 851 | 853 | |
| 852 | − clk_disable(ourhost->clk_bus[ourhost->cur_clk]); | |
| 853 | − clk_disable(busclk); | |
| 854 | + clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); | |
| 855 | + clk_disable_unprepare(busclk); | |
| 854 | 856 | return ret; |
| 855 | 857 | } |
| 856 | 858 | |
| @@ -861,8 +863,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev) · 4 unmodified lines | ||
| 861 | 863 | struct clk *busclk = ourhost->clk_io; |
| 862 | 864 | int ret; |
| 863 | 865 | |
| 864 | − clk_enable(busclk); | |
| 865 | − clk_enable(ourhost->clk_bus[ourhost->cur_clk]); | |
| 866 | + clk_prepare_enable(busclk); | |
| 867 | + clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); | |
| 866 | 868 | ret = sdhci_runtime_resume_host(host); |
| 867 | 869 | return ret; |
| 868 | 870 | } |
| @@ -1315,16 +1315,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) · 1314 unmodified lines | ||
| 1315 | 1315 | */ |
| 1316 | 1316 | if ((host->flags & SDHCI_NEEDS_RETUNING) && |
| 1317 | 1317 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { |
| 1318 | − /* eMMC uses cmd21 while sd and sdio use cmd19 */ | |
| 1319 | − tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? | |
| 1320 | − MMC_SEND_TUNING_BLOCK_HS200 : | |
| 1321 | − MMC_SEND_TUNING_BLOCK; | |
| 1322 | − spin_unlock_irqrestore(&host->lock, flags); | |
| 1323 | − sdhci_execute_tuning(mmc, tuning_opcode); | |
| 1324 | − spin_lock_irqsave(&host->lock, flags); | |
| 1325 | − | |
| 1326 | − /* Restore original mmc_request structure */ | |
| 1327 | − host->mrq = mrq; | |
| 1318 | + if (mmc->card) { | |
| 1319 | + /* eMMC uses cmd21 but sd and sdio use cmd19 */ | |
| 1320 | + tuning_opcode = | |
| 1321 | + mmc->card->type == MMC_TYPE_MMC ? | |
| 1322 | + MMC_SEND_TUNING_BLOCK_HS200 : | |
| 1323 | + MMC_SEND_TUNING_BLOCK; | |
| 1324 | + spin_unlock_irqrestore(&host->lock, flags); | |
| 1325 | + sdhci_execute_tuning(mmc, tuning_opcode); | |
| 1326 | + spin_lock_irqsave(&host->lock, flags); | |
| 1327 | + | |
| 1328 | + /* Restore original mmc_request structure */ | |
| 1329 | + host->mrq = mrq; | |
| 1330 | + } | |
| 1328 | 1331 | } |
| 1329 | 1332 | |
| 1330 | 1333 | if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) |
| @@ -2837,6 +2840,9 @@ int sdhci_add_host(struct sdhci_host *host) · 1506 unmodified lines | ||
| 2837 | 2840 | if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) |
| 2838 | 2841 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
| 2839 | 2842 | |
| 2843 | + if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23) | |
| 2844 | + mmc->caps &= ~MMC_CAP_CMD23; | |
| 2845 | + | |
| 2840 | 2846 | if (caps[0] & SDHCI_CAN_DO_HISPD) |
| 2841 | 2847 | mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; |
| 2842 | 2848 | |
| @@ -2846,9 +2852,12 @@ int sdhci_add_host(struct sdhci_host *host) · 3 unmodified lines | ||
| 2846 | 2852 | |
| 2847 | 2853 | /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ |
| 2848 | 2854 | host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); |
| 2849 | − if (IS_ERR(host->vqmmc)) { | |
| 2850 | − pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc)); | |
| 2851 | − host->vqmmc = NULL; | |
| 2855 | + if (IS_ERR_OR_NULL(host->vqmmc)) { | |
| 2856 | + if (PTR_ERR(host->vqmmc) < 0) { | |
| 2857 | + pr_info("%s: no vqmmc regulator found\n", | |
| 2858 | + mmc_hostname(mmc)); | |
| 2859 | + host->vqmmc = NULL; | |
| 2860 | + } | |
| 2852 | 2861 | } |
| 2853 | 2862 | else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) |
| 2854 | 2863 | regulator_enable(host->vqmmc); |
| @@ -2904,9 +2913,12 @@ int sdhci_add_host(struct sdhci_host *host) · 49 unmodified lines | ||
| 2904 | 2913 | ocr_avail = 0; |
| 2905 | 2914 | |
| 2906 | 2915 | host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); |
| 2907 | − if (IS_ERR(host->vmmc)) { | |
| 2908 | − pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); | |
| 2909 | − host->vmmc = NULL; | |
| 2916 | + if (IS_ERR_OR_NULL(host->vmmc)) { | |
| 2917 | + if (PTR_ERR(host->vmmc) < 0) { | |
| 2918 | + pr_info("%s: no vmmc regulator found\n", | |
| 2919 | + mmc_hostname(mmc)); | |
| 2920 | + host->vmmc = NULL; | |
| 2921 | + } | |
| 2910 | 2922 | } else |
| 2911 | 2923 | regulator_enable(host->vmmc); |
| 2912 | 2924 | |
| @@ -278,6 +278,7 @@ struct sdhci_ops { · 277 unmodified lines | ||
| 278 | 278 | void (*hw_reset)(struct sdhci_host *host); |
| 279 | 279 | void (*platform_suspend)(struct sdhci_host *host); |
| 280 | 280 | void (*platform_resume)(struct sdhci_host *host); |
| 281 | + void (*platform_init)(struct sdhci_host *host); | |
| 281 | 282 | }; |
| 282 | 283 | |
| 283 | 284 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS |
| @@ -1466,9 +1466,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) · 1465 unmodified lines | ||
| 1466 | 1466 | |
| 1467 | 1467 | platform_set_drvdata(pdev, NULL); |
| 1468 | 1468 | |
| 1469 | + clk_disable(host->hclk); | |
| 1469 | 1470 | mmc_free_host(host->mmc); |
| 1470 | 1471 | pm_runtime_put_sync(&pdev->dev); |
| 1471 | − clk_disable(host->hclk); | |
| 1472 | 1472 | pm_runtime_disable(&pdev->dev); |
| 1473 | 1473 | |
| 1474 | 1474 | return 0; |
| @@ -1860,10 +1860,14 @@ jme_open(struct net_device *netdev) · 1859 unmodified lines | ||
| 1860 | 1860 | jme_clear_pm(jme); |
| 1861 | 1861 | JME_NAPI_ENABLE(jme); |
| 1862 | 1862 | |
| 1863 | − tasklet_enable(&jme->linkch_task); | |
| 1864 | − tasklet_enable(&jme->txclean_task); | |
| 1865 | − tasklet_hi_enable(&jme->rxclean_task); | |
| 1866 | − tasklet_hi_enable(&jme->rxempty_task); | |
| 1863 | + tasklet_init(&jme->linkch_task, jme_link_change_tasklet, | |
| 1864 | + (unsigned long) jme); | |
| 1865 | + tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet, | |
| 1866 | + (unsigned long) jme); | |
| 1867 | + tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet, | |
| 1868 | + (unsigned long) jme); | |
| 1869 | + tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet, | |
| 1870 | + (unsigned long) jme); | |
| 1867 | 1871 | |
| 1868 | 1872 | rc = jme_request_irq(jme); |
| 1869 | 1873 | if (rc) |
| @@ -3079,22 +3083,6 @@ jme_init_one(struct pci_dev *pdev, · 1209 unmodified lines | ||
| 3079 | 3083 | tasklet_init(&jme->pcc_task, |
| 3080 | 3084 | jme_pcc_tasklet, |
| 3081 | 3085 | (unsigned long) jme); |
| 3082 | − tasklet_init(&jme->linkch_task, | |
| 3083 | − jme_link_change_tasklet, | |
| 3084 | − (unsigned long) jme); | |
| 3085 | − tasklet_init(&jme->txclean_task, | |
| 3086 | − jme_tx_clean_tasklet, | |
| 3087 | − (unsigned long) jme); | |
| 3088 | − tasklet_init(&jme->rxclean_task, | |
| 3089 | − jme_rx_clean_tasklet, | |
| 3090 | − (unsigned long) jme); | |
| 3091 | − tasklet_init(&jme->rxempty_task, | |
| 3092 | − jme_rx_empty_tasklet, | |
| 3093 | − (unsigned long) jme); | |
| 3094 | − tasklet_disable_nosync(&jme->linkch_task); | |
| 3095 | − tasklet_disable_nosync(&jme->txclean_task); | |
| 3096 | − tasklet_disable_nosync(&jme->rxclean_task); | |
| 3097 | − tasklet_disable_nosync(&jme->rxempty_task); | |
| 3098 | 3086 | jme->dpi.cur = PCC_P1; |
| 3099 | 3087 | |
| 3100 | 3088 | jme->reg_ghc = 0; |
| @@ -5459,8 +5459,10 @@ static int prepare_hardware(struct net_device *dev) · 5458 unmodified lines | ||
| 5459 | 5459 | rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); |
| 5460 | 5460 | if (rc) |
| 5461 | 5461 | return rc; |
| 5462 | − tasklet_enable(&hw_priv->rx_tasklet); | |
| 5463 | − tasklet_enable(&hw_priv->tx_tasklet); | |
| 5462 | + tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, | |
| 5463 | + (unsigned long) hw_priv); | |
| 5464 | + tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, | |
| 5465 | + (unsigned long) hw_priv); | |
| 5464 | 5466 | |
| 5465 | 5467 | hw->promiscuous = 0; |
| 5466 | 5468 | hw->all_multi = 0; |
| @@ -7033,16 +7035,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev, · 1566 unmodified lines | ||
| 7033 | 7035 | spin_lock_init(&hw_priv->hwlock); |
| 7034 | 7036 | mutex_init(&hw_priv->lock); |
| 7035 | 7037 | |
| 7036 | − /* tasklet is enabled. */ | |
| 7037 | − tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, | |
| 7038 | − (unsigned long) hw_priv); | |
| 7039 | − tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, | |
| 7040 | − (unsigned long) hw_priv); | |
| 7041 | − | |
| 7042 | − /* tasklet_enable will decrement the atomic counter. */ | |
| 7043 | − tasklet_disable(&hw_priv->rx_tasklet); | |
| 7044 | − tasklet_disable(&hw_priv->tx_tasklet); | |
| 7045 | − | |
| 7046 | 7038 | for (i = 0; i < TOTAL_PORT_NUM; i++) |
| 7047 | 7039 | init_waitqueue_head(&hw_priv->counter[i].counter); |
| 7048 | 7040 | |
| @@ -2110,7 +2110,7 @@ static void __devinit smsc911x_read_mac_address(struct net_device *dev) · 2109 unmodified lines | ||
| 2110 | 2110 | static int __devinit smsc911x_init(struct net_device *dev) |
| 2111 | 2111 | { |
| 2112 | 2112 | struct smsc911x_data *pdata = netdev_priv(dev); |
| 2113 | − unsigned int byte_test; | |
| 2113 | + unsigned int byte_test, mask; | |
| 2114 | 2114 | unsigned int to = 100; |
| 2115 | 2115 | |
| 2116 | 2116 | SMSC_TRACE(pdata, probe, "Driver Parameters:"); |
| @@ -2130,9 +2130,22 @@ static int __devinit smsc911x_init(struct net_device *dev) · 13 unmodified lines | ||
| 2130 | 2130 | /* |
| 2131 | 2131 | * poll the READY bit in PMT_CTRL. Any other access to the device is |
| 2132 | 2132 | * forbidden while this bit isn't set. Try for 100ms |
| 2133 | + * | |
| 2134 | + * Note that this test is done before the WORD_SWAP register is | |
| 2135 | + * programmed. So in some configurations the READY bit is at 16 before | |
| 2136 | + * WORD_SWAP is written to. This issue is worked around by waiting | |
| 2137 | + * until either bit 0 or bit 16 gets set in PMT_CTRL. | |
| 2138 | + * | |
| 2139 | + * SMSC has confirmed that checking bit 16 (marked as reserved in | |
| 2140 | + * the datasheet) is fine since these bits "will either never be set | |
| 2141 | + * or can only go high after READY does (so also indicate the device | |
| 2142 | + * is ready)". | |
| 2133 | 2143 | */ |
| 2134 | − while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) | |
| 2144 | + | |
| 2145 | + mask = PMT_CTRL_READY_ | swahw32(PMT_CTRL_READY_); | |
| 2146 | + while (!(smsc911x_reg_read(pdata, PMT_CTRL) & mask) && --to) | |
| 2135 | 2147 | udelay(1000); |
| 2148 | + | |
| 2136 | 2149 | if (to == 0) { |
| 2137 | 2150 | pr_err("Device not READY in 100ms aborting\n"); |
| 2138 | 2151 | return -ENODEV; |
| @@ -917,7 +917,7 @@ static int tile_net_setup_interrupts(struct net_device *dev) · 916 unmodified lines | ||
| 917 | 917 | ingress_irq = rc; |
| 918 | 918 | tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU); |
| 919 | 919 | rc = request_irq(ingress_irq, tile_net_handle_ingress_irq, |
| 920 | − 0, NULL, NULL); | |
| 920 | + 0, "tile_net", NULL); | |
| 921 | 921 | if (rc != 0) { |
| 922 | 922 | netdev_err(dev, "request_irq failed: %d\n", rc); |
| 923 | 923 | destroy_irq(ingress_irq); |
| @@ -942,6 +942,10 @@ static int axienet_open(struct net_device *ndev) · 941 unmodified lines | ||
| 942 | 942 | phy_start(lp->phy_dev); |
| 943 | 943 | } |
| 944 | 944 | |
| 945 | + /* Enable tasklets for Axi DMA error handling */ | |
| 946 | + tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, | |
| 947 | + (unsigned long) lp); | |
| 948 | + | |
| 945 | 949 | /* Enable interrupts for Axi DMA Tx */ |
| 946 | 950 | ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev); |
| 947 | 951 | if (ret) |
| @@ -950,8 +954,7 @@ static int axienet_open(struct net_device *ndev) · 2 unmodified lines | ||
| 950 | 954 | ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev); |
| 951 | 955 | if (ret) |
| 952 | 956 | goto err_rx_irq; |
| 953 | − /* Enable tasklets for Axi DMA error handling */ | |
| 954 | − tasklet_enable(&lp->dma_err_tasklet); | |
| 957 | + | |
| 955 | 958 | return 0; |
| 956 | 959 | |
| 957 | 960 | err_rx_irq: |
| @@ -960,6 +963,7 @@ err_tx_irq: · 2 unmodified lines | ||
| 960 | 963 | if (lp->phy_dev) |
| 961 | 964 | phy_disconnect(lp->phy_dev); |
| 962 | 965 | lp->phy_dev = NULL; |
| 966 | + tasklet_kill(&lp->dma_err_tasklet); | |
| 963 | 967 | dev_err(lp->dev, "request_irq() failed\n"); |
| 964 | 968 | return ret; |
| 965 | 969 | } |
| @@ -1613,10 +1617,6 @@ static int __devinit axienet_of_probe(struct platform_device *op) · 647 unmodified lines | ||
| 1613 | 1617 | goto err_iounmap_2; |
| 1614 | 1618 | } |
| 1615 | 1619 | |
| 1616 | − tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, | |
| 1617 | − (unsigned long) lp); | |
| 1618 | − tasklet_disable(&lp->dma_err_tasklet); | |
| 1619 | − | |
| 1620 | 1620 | return 0; |
| 1621 | 1621 | |
| 1622 | 1622 | err_iounmap_2: |
| @@ -234,7 +234,6 @@ void free_mdio_bitbang(struct mii_bus *bus) · 233 unmodified lines | ||
| 234 | 234 | struct mdiobb_ctrl *ctrl = bus->priv; |
| 235 | 235 | |
| 236 | 236 | module_put(ctrl->ops->owner); |
| 237 | − mdiobus_unregister(bus); | |
| 238 | 237 | mdiobus_free(bus); |
| 239 | 238 | } |
| 240 | 239 | EXPORT_SYMBOL(free_mdio_bitbang); |
| @@ -440,10 +440,12 @@ advance: · 439 unmodified lines | ||
| 440 | 440 | ((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf)))) |
| 441 | 441 | goto error; |
| 442 | 442 | |
| 443 | − /* claim interfaces, if any */ | |
| 444 | − temp = usb_driver_claim_interface(driver, ctx->data, dev); | |
| 445 | − if (temp) | |
| 446 | − goto error; | |
| 443 | + /* claim data interface, if different from control */ | |
| 444 | + if (ctx->data != ctx->control) { | |
| 445 | + temp = usb_driver_claim_interface(driver, ctx->data, dev); | |
| 446 | + if (temp) | |
| 447 | + goto error; | |
| 448 | + } | |
| 447 | 449 | |
| 448 | 450 | iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; |
| 449 | 451 | |
| @@ -519,6 +521,10 @@ void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) · 69 unmodified lines | ||
| 519 | 521 | |
| 520 | 522 | tasklet_kill(&ctx->bh); |
| 521 | 523 | |
| 524 | + /* handle devices with combined control and data interface */ | |
| 525 | + if (ctx->control == ctx->data) | |
| 526 | + ctx->data = NULL; | |
| 527 | + | |
| 522 | 528 | /* disconnect master --> disconnect slave */ |
| 523 | 529 | if (intf == ctx->control && ctx->data) { |
| 524 | 530 | usb_set_intfdata(ctx->data, NULL); |
| @@ -1186,6 +1192,14 @@ static const struct usb_device_id cdc_devs[] = { · 661 unmodified lines | ||
| 1186 | 1192 | .driver_info = (unsigned long) &wwan_info, |
| 1187 | 1193 | }, |
| 1188 | 1194 | |
| 1195 | + /* Huawei NCM devices disguised as vendor specific */ | |
| 1196 | + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16), | |
| 1197 | + .driver_info = (unsigned long)&wwan_info, | |
| 1198 | + }, | |
| 1199 | + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), | |
| 1200 | + .driver_info = (unsigned long)&wwan_info, | |
| 1201 | + }, | |
| 1202 | + | |
| 1189 | 1203 | /* Generic CDC-NCM devices */ |
| 1190 | 1204 | { USB_INTERFACE_INFO(USB_CLASS_COMM, |
| 1191 | 1205 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), |
| @@ -203,7 +203,7 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) · 202 unmodified lines | ||
| 203 | 203 | /* set the address, index & direction (read from PHY) */ |
| 204 | 204 | phy_id &= dev->mii.phy_id_mask; |
| 205 | 205 | idx &= dev->mii.reg_num_mask; |
| 206 | − addr = (phy_id << 11) | (idx << 6) | MII_READ_; | |
| 206 | + addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_; | |
| 207 | 207 | ret = smsc95xx_write_reg(dev, MII_ADDR, addr); |
| 208 | 208 | check_warn_goto_done(ret, "Error writing MII_ADDR"); |
| 209 | 209 | |
| @@ -240,7 +240,7 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx, · 30 unmodified lines | ||
| 240 | 240 | /* set the address, index & direction (write to PHY) */ |
| 241 | 241 | phy_id &= dev->mii.phy_id_mask; |
| 242 | 242 | idx &= dev->mii.reg_num_mask; |
| 243 | − addr = (phy_id << 11) | (idx << 6) | MII_WRITE_; | |
| 243 | + addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_; | |
| 244 | 244 | ret = smsc95xx_write_reg(dev, MII_ADDR, addr); |
| 245 | 245 | check_warn_goto_done(ret, "Error writing MII_ADDR"); |
| 246 | 246 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | − * VXLAN: Virtual eXtensiable Local Area Network | |
| 2 | + * VXLAN: Virtual eXtensible Local Area Network | |
| 3 | 3 | * |
| 4 | 4 | * Copyright (c) 2012 Vyatta Inc. |
| 5 | 5 | * |
| @@ -50,8 +50,8 @@ · 44 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | #define VXLAN_N_VID (1u << 24) |
| 52 | 52 | #define VXLAN_VID_MASK (VXLAN_N_VID - 1) |
| 53 | −/* VLAN + IP header + UDP + VXLAN */ | |
| 54 | −#define VXLAN_HEADROOM (4 + 20 + 8 + 8) | |
| 53 | +/* IP header + UDP + VXLAN + Ethernet header */ | |
| 54 | +#define VXLAN_HEADROOM (20 + 8 + 8 + 14) | |
| 55 | 55 | |
| 56 | 56 | #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ |
| 57 | 57 | |
| @@ -1102,6 +1102,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, · 1044 unmodified lines | ||
| 1102 | 1102 | |
| 1103 | 1103 | if (!tb[IFLA_MTU]) |
| 1104 | 1104 | dev->mtu = lowerdev->mtu - VXLAN_HEADROOM; |
| 1105 | + | |
| 1106 | + /* update header length based on lower device */ | |
| 1107 | + dev->hard_header_len = lowerdev->hard_header_len + | |
| 1108 | + VXLAN_HEADROOM; | |
| 1105 | 1109 | } |
| 1106 | 1110 | |
| 1107 | 1111 | if (data[IFLA_VXLAN_TOS]) |
| @@ -4197,7 +4197,7 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode) · 4196 unmodified lines | ||
| 4197 | 4197 | |
| 4198 | 4198 | static void brcmf_wiphy_pno_params(struct wiphy *wiphy) |
| 4199 | 4199 | { |
| 4200 | −#ifndef CONFIG_BRCMFISCAN | |
| 4200 | +#ifndef CONFIG_BRCMISCAN | |
| 4201 | 4201 | /* scheduled scan settings */ |
| 4202 | 4202 | wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; |
| 4203 | 4203 | wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; |
| @@ -521,7 +521,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, · 520 unmodified lines | ||
| 521 | 521 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); |
| 522 | 522 | |
| 523 | 523 | if (iwlagn_tx_skb(priv, control->sta, skb)) |
| 524 | − dev_kfree_skb_any(skb); | |
| 524 | + ieee80211_free_txskb(hw, skb); | |
| 525 | 525 | } |
| 526 | 526 | |
| 527 | 527 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, |
| @@ -2113,7 +2113,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) · 2112 unmodified lines | ||
| 2113 | 2113 | |
| 2114 | 2114 | info = IEEE80211_SKB_CB(skb); |
| 2115 | 2115 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); |
| 2116 | − dev_kfree_skb_any(skb); | |
| 2116 | + ieee80211_free_txskb(priv->hw, skb); | |
| 2117 | 2117 | } |
| 2118 | 2118 | |
| 2119 | 2119 | static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) |
| @@ -321,6 +321,14 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) · 320 unmodified lines | ||
| 321 | 321 | dma_map_page(trans->dev, page, 0, |
| 322 | 322 | PAGE_SIZE << trans_pcie->rx_page_order, |
| 323 | 323 | DMA_FROM_DEVICE); |
| 324 | + if (dma_mapping_error(trans->dev, rxb->page_dma)) { | |
| 325 | + rxb->page = NULL; | |
| 326 | + spin_lock_irqsave(&rxq->lock, flags); | |
| 327 | + list_add(&rxb->list, &rxq->rx_used); | |
| 328 | + spin_unlock_irqrestore(&rxq->lock, flags); | |
| 329 | + __free_pages(page, trans_pcie->rx_page_order); | |
| 330 | + return; | |
| 331 | + } | |
| 324 | 332 | /* dma address must be no more than 36 bits */ |
| 325 | 333 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); |
| 326 | 334 | /* and also 256 byte aligned! */ |
| @@ -489,8 +497,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, · 162 unmodified lines | ||
| 489 | 497 | dma_map_page(trans->dev, rxb->page, 0, |
| 490 | 498 | PAGE_SIZE << trans_pcie->rx_page_order, |
| 491 | 499 | DMA_FROM_DEVICE); |
| 492 | − list_add_tail(&rxb->list, &rxq->rx_free); | |
| 493 | − rxq->free_count++; | |
| 500 | + if (dma_mapping_error(trans->dev, rxb->page_dma)) { | |
| 501 | + /* | |
| 502 | + * free the page(s) as well to not break | |
| 503 | + * the invariant that the items on the used | |
| 504 | + * list have no page(s) | |
| 505 | + */ | |
| 506 | + __free_pages(rxb->page, trans_pcie->rx_page_order); | |
| 507 | + rxb->page = NULL; | |
| 508 | + list_add_tail(&rxb->list, &rxq->rx_used); | |
| 509 | + } else { | |
| 510 | + list_add_tail(&rxb->list, &rxq->rx_free); | |
| 511 | + rxq->free_count++; | |
| 512 | + } | |
| 494 | 513 | } else |
| 495 | 514 | list_add_tail(&rxb->list, &rxq->rx_used); |
| 496 | 515 | spin_unlock_irqrestore(&rxq->lock, flags); |
| @@ -320,10 +320,7 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), · 319 unmodified lines | ||
| 320 | 320 | } else |
| 321 | 321 | next = dev->bus_list.next; |
| 322 | 322 | |
| 323 | − /* Run device routines with the device locked */ | |
| 324 | − device_lock(&dev->dev); | |
| 325 | 323 | retval = cb(dev, userdata); |
| 326 | − device_unlock(&dev->dev); | |
| 327 | 324 | if (retval) |
| 328 | 325 | break; |
| 329 | 326 | } |
| @@ -398,6 +398,8 @@ static void pci_device_shutdown(struct device *dev) · 397 unmodified lines | ||
| 398 | 398 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 399 | 399 | struct pci_driver *drv = pci_dev->driver; |
| 400 | 400 | |
| 401 | + pm_runtime_resume(dev); | |
| 402 | + | |
| 401 | 403 | if (drv && drv->shutdown) |
| 402 | 404 | drv->shutdown(pci_dev); |
| 403 | 405 | pci_msi_shutdown(pci_dev); |
| @@ -408,16 +410,6 @@ static void pci_device_shutdown(struct device *dev) · 4 unmodified lines | ||
| 408 | 410 | * continue to do DMA |
| 409 | 411 | */ |
| 410 | 412 | pci_disable_device(pci_dev); |
| 411 | − | |
| 412 | − /* | |
| 413 | − * Devices may be enabled to wake up by runtime PM, but they need not | |
| 414 | − * be supposed to wake up the system from its "power off" state (e.g. | |
| 415 | − * ACPI S5). Therefore disable wakeup for all devices that aren't | |
| 416 | − * supposed to wake up the system at this point. The state argument | |
| 417 | − * will be ignored by pci_enable_wake(). | |
| 418 | − */ | |
| 419 | − if (!device_may_wakeup(dev)) | |
| 420 | − pci_enable_wake(pci_dev, PCI_UNKNOWN, false); | |
| 421 | 413 | } |
| 422 | 414 | |
| 423 | 415 | #ifdef CONFIG_PM |
| @@ -458,40 +458,6 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) · 457 unmodified lines | ||
| 458 | 458 | } |
| 459 | 459 | struct device_attribute vga_attr = __ATTR_RO(boot_vga); |
| 460 | 460 | |
| 461 | −static void | |
| 462 | −pci_config_pm_runtime_get(struct pci_dev *pdev) | |
| 463 | −{ | |
| 464 | − struct device *dev = &pdev->dev; | |
| 465 | − struct device *parent = dev->parent; | |
| 466 | − | |
| 467 | − if (parent) | |
| 468 | − pm_runtime_get_sync(parent); | |
| 469 | − pm_runtime_get_noresume(dev); | |
| 470 | − /* | |
| 471 | − * pdev->current_state is set to PCI_D3cold during suspending, | |
| 472 | − * so wait until suspending completes | |
| 473 | − */ | |
| 474 | − pm_runtime_barrier(dev); | |
| 475 | − /* | |
| 476 | − * Only need to resume devices in D3cold, because config | |
| 477 | − * registers are still accessible for devices suspended but | |
| 478 | − * not in D3cold. | |
| 479 | − */ | |
| 480 | − if (pdev->current_state == PCI_D3cold) | |
| 481 | − pm_runtime_resume(dev); | |
| 482 | −} | |
| 483 | − | |
| 484 | −static void | |
| 485 | −pci_config_pm_runtime_put(struct pci_dev *pdev) | |
| 486 | −{ | |
| 487 | − struct device *dev = &pdev->dev; | |
| 488 | − struct device *parent = dev->parent; | |
| 489 | − | |
| 490 | − pm_runtime_put(dev); | |
| 491 | − if (parent) | |
| 492 | − pm_runtime_put_sync(parent); | |
| 493 | −} | |
| 494 | − | |
| 495 | 461 | static ssize_t |
| 496 | 462 | pci_read_config(struct file *filp, struct kobject *kobj, |
| 497 | 463 | struct bin_attribute *bin_attr, |
| @@ -1858,6 +1858,38 @@ bool pci_dev_run_wake(struct pci_dev *dev) · 1857 unmodified lines | ||
| 1858 | 1858 | } |
| 1859 | 1859 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); |
| 1860 | 1860 | |
| 1861 | +void pci_config_pm_runtime_get(struct pci_dev *pdev) | |
| 1862 | +{ | |
| 1863 | + struct device *dev = &pdev->dev; | |
| 1864 | + struct device *parent = dev->parent; | |
| 1865 | + | |
| 1866 | + if (parent) | |
| 1867 | + pm_runtime_get_sync(parent); | |
| 1868 | + pm_runtime_get_noresume(dev); | |
| 1869 | + /* | |
| 1870 | + * pdev->current_state is set to PCI_D3cold during suspending, | |
| 1871 | + * so wait until suspending completes | |
| 1872 | + */ | |
| 1873 | + pm_runtime_barrier(dev); | |
| 1874 | + /* | |
| 1875 | + * Only need to resume devices in D3cold, because config | |
| 1876 | + * registers are still accessible for devices suspended but | |
| 1877 | + * not in D3cold. | |
| 1878 | + */ | |
| 1879 | + if (pdev->current_state == PCI_D3cold) | |
| 1880 | + pm_runtime_resume(dev); | |
| 1881 | +} | |
| 1882 | + | |
| 1883 | +void pci_config_pm_runtime_put(struct pci_dev *pdev) | |
| 1884 | +{ | |
| 1885 | + struct device *dev = &pdev->dev; | |
| 1886 | + struct device *parent = dev->parent; | |
| 1887 | + | |
| 1888 | + pm_runtime_put(dev); | |
| 1889 | + if (parent) | |
| 1890 | + pm_runtime_put_sync(parent); | |
| 1891 | +} | |
| 1892 | + | |
| 1861 | 1893 | /** |
| 1862 | 1894 | * pci_pm_init - Initialize PM functions of given PCI device |
| 1863 | 1895 | * @dev: PCI device to handle. |
| @@ -72,6 +72,8 @@ extern void pci_disable_enabled_device(struct pci_dev *dev); · 71 unmodified lines | ||
| 72 | 72 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); |
| 73 | 73 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); |
| 74 | 74 | extern void pci_wakeup_bus(struct pci_bus *bus); |
| 75 | +extern void pci_config_pm_runtime_get(struct pci_dev *dev); | |
| 76 | +extern void pci_config_pm_runtime_put(struct pci_dev *dev); | |
| 75 | 77 | extern void pci_pm_init(struct pci_dev *dev); |
| 76 | 78 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
| 77 | 79 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
| @@ -213,6 +213,7 @@ static int report_error_detected(struct pci_dev *dev, void *data) · 212 unmodified lines | ||
| 213 | 213 | struct aer_broadcast_data *result_data; |
| 214 | 214 | result_data = (struct aer_broadcast_data *) data; |
| 215 | 215 | |
| 216 | + device_lock(&dev->dev); | |
| 216 | 217 | dev->error_state = result_data->state; |
| 217 | 218 | |
| 218 | 219 | if (!dev->driver || |
| @@ -231,12 +232,14 @@ static int report_error_detected(struct pci_dev *dev, void *data) · 12 unmodified lines | ||
| 231 | 232 | dev->driver ? |
| 232 | 233 | "no AER-aware driver" : "no driver"); |
| 233 | 234 | } |
| 234 | − return 0; | |
| 235 | + goto out; | |
| 235 | 236 | } |
| 236 | 237 | |
| 237 | 238 | err_handler = dev->driver->err_handler; |
| 238 | 239 | vote = err_handler->error_detected(dev, result_data->state); |
| 239 | 240 | result_data->result = merge_result(result_data->result, vote); |
| 241 | +out: | |
| 242 | + device_unlock(&dev->dev); | |
| 240 | 243 | return 0; |
| 241 | 244 | } |
| 242 | 245 | |
| @@ -247,14 +250,17 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data) · 4 unmodified lines | ||
| 247 | 250 | struct aer_broadcast_data *result_data; |
| 248 | 251 | result_data = (struct aer_broadcast_data *) data; |
| 249 | 252 | |
| 253 | + device_lock(&dev->dev); | |
| 250 | 254 | if (!dev->driver || |
| 251 | 255 | !dev->driver->err_handler || |
| 252 | 256 | !dev->driver->err_handler->mmio_enabled) |
| 253 | − return 0; | |
| 257 | + goto out; | |
| 254 | 258 | |
| 255 | 259 | err_handler = dev->driver->err_handler; |
| 256 | 260 | vote = err_handler->mmio_enabled(dev); |
| 257 | 261 | result_data->result = merge_result(result_data->result, vote); |
| 262 | +out: | |
| 263 | + device_unlock(&dev->dev); | |
| 258 | 264 | return 0; |
| 259 | 265 | } |
| 260 | 266 | |
| @@ -265,14 +271,17 @@ static int report_slot_reset(struct pci_dev *dev, void *data) · 4 unmodified lines | ||
| 265 | 271 | struct aer_broadcast_data *result_data; |
| 266 | 272 | result_data = (struct aer_broadcast_data *) data; |
| 267 | 273 | |
| 274 | + device_lock(&dev->dev); | |
| 268 | 275 | if (!dev->driver || |
| 269 | 276 | !dev->driver->err_handler || |
| 270 | 277 | !dev->driver->err_handler->slot_reset) |
| 271 | − return 0; | |
| 278 | + goto out; | |
| 272 | 279 | |
| 273 | 280 | err_handler = dev->driver->err_handler; |
| 274 | 281 | vote = err_handler->slot_reset(dev); |
| 275 | 282 | result_data->result = merge_result(result_data->result, vote); |
| 283 | +out: | |
| 284 | + device_unlock(&dev->dev); | |
| 276 | 285 | return 0; |
| 277 | 286 | } |
| 278 | 287 | |
| @@ -280,15 +289,18 @@ static int report_resume(struct pci_dev *dev, void *data) · 1 unmodified line | ||
| 280 | 289 | { |
| 281 | 290 | const struct pci_error_handlers *err_handler; |
| 282 | 291 | |
| 292 | + device_lock(&dev->dev); | |
| 283 | 293 | dev->error_state = pci_channel_io_normal; |
| 284 | 294 | |
| 285 | 295 | if (!dev->driver || |
| 286 | 296 | !dev->driver->err_handler || |
| 287 | 297 | !dev->driver->err_handler->resume) |
| 288 | − return 0; | |
| 298 | + goto out; | |
| 289 | 299 | |
| 290 | 300 | err_handler = dev->driver->err_handler; |
| 291 | 301 | err_handler->resume(dev); |
| 302 | +out: | |
| 303 | + device_unlock(&dev->dev); | |
| 292 | 304 | return 0; |
| 293 | 305 | } |
| 294 | 306 | |
| @@ -272,7 +272,8 @@ static int get_port_device_capability(struct pci_dev *dev) · 271 unmodified lines | ||
| 272 | 272 | } |
| 273 | 273 | |
| 274 | 274 | /* Hot-Plug Capable */ |
| 275 | − if (cap_mask & PCIE_PORT_SERVICE_HP) { | |
| 275 | + if ((cap_mask & PCIE_PORT_SERVICE_HP) && | |
| 276 | + dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) { | |
| 276 | 277 | pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); |
| 277 | 278 | if (reg32 & PCI_EXP_SLTCAP_HPC) { |
| 278 | 279 | services |= PCIE_PORT_SERVICE_HP; |
| @@ -76,6 +76,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp · 75 unmodified lines | ||
| 76 | 76 | if (!access_ok(VERIFY_WRITE, buf, cnt)) |
| 77 | 77 | return -EINVAL; |
| 78 | 78 | |
| 79 | + pci_config_pm_runtime_get(dev); | |
| 80 | + | |
| 79 | 81 | if ((pos & 1) && cnt) { |
| 80 | 82 | unsigned char val; |
| 81 | 83 | pci_user_read_config_byte(dev, pos, &val); |
| @@ -121,6 +123,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp · 39 unmodified lines | ||
| 121 | 123 | cnt--; |
| 122 | 124 | } |
| 123 | 125 | |
| 126 | + pci_config_pm_runtime_put(dev); | |
| 127 | + | |
| 124 | 128 | *ppos = pos; |
| 125 | 129 | return nbytes; |
| 126 | 130 | } |
| @@ -146,6 +150,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof · 19 unmodified lines | ||
| 146 | 150 | if (!access_ok(VERIFY_READ, buf, cnt)) |
| 147 | 151 | return -EINVAL; |
| 148 | 152 | |
| 153 | + pci_config_pm_runtime_get(dev); | |
| 154 | + | |
| 149 | 155 | if ((pos & 1) && cnt) { |
| 150 | 156 | unsigned char val; |
| 151 | 157 | __get_user(val, buf); |
| @@ -191,6 +197,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof · 39 unmodified lines | ||
| 191 | 197 | cnt--; |
| 192 | 198 | } |
| 193 | 199 | |
| 200 | + pci_config_pm_runtime_put(dev); | |
| 201 | + | |
| 194 | 202 | *ppos = pos; |
| 195 | 203 | i_size_write(ino, dp->size); |
| 196 | 204 | return nbytes; |
| @@ -179,11 +179,13 @@ config PINCTRL_COH901 · 178 unmodified lines | ||
| 179 | 179 | |
| 180 | 180 | config PINCTRL_SAMSUNG |
| 181 | 181 | bool "Samsung pinctrl driver" |
| 182 | + depends on OF && GPIOLIB | |
| 182 | 183 | select PINMUX |
| 183 | 184 | select PINCONF |
| 184 | 185 | |
| 185 | 186 | config PINCTRL_EXYNOS4 |
| 186 | 187 | bool "Pinctrl driver data for Exynos4 SoC" |
| 188 | + depends on OF && GPIOLIB | |
| 187 | 189 | select PINCTRL_SAMSUNG |
| 188 | 190 | |
| 189 | 191 | config PINCTRL_MVEBU |
| @@ -244,7 +244,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, · 243 unmodified lines | ||
| 244 | 244 | else |
| 245 | 245 | temp = ~muxreg->val; |
| 246 | 246 | |
| 247 | − val |= temp; | |
| 247 | + val |= muxreg->mask & temp; | |
| 248 | 248 | pmx_writel(pmx, val, muxreg->reg); |
| 249 | 249 | } |
| 250 | 250 | } |
| @@ -25,8 +25,8 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { · 24 unmodified lines | ||
| 25 | 25 | }; |
| 26 | 26 | |
| 27 | 27 | /* registers */ |
| 28 | −#define PERIP_CFG 0x32C | |
| 29 | − #define MCIF_SEL_SHIFT 3 | |
| 28 | +#define PERIP_CFG 0x3B0 | |
| 29 | + #define MCIF_SEL_SHIFT 5 | |
| 30 | 30 | #define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT) |
| 31 | 31 | #define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT) |
| 32 | 32 | #define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT) |
| @@ -164,6 +164,10 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { · 131 unmodified lines | ||
| 164 | 164 | #define PMX_SSP0_CS0_MASK (1 << 29) |
| 165 | 165 | #define PMX_SSP0_CS1_2_MASK (1 << 30) |
| 166 | 166 | |
| 167 | +#define PAD_DIRECTION_SEL_0 0x65C | |
| 168 | +#define PAD_DIRECTION_SEL_1 0x660 | |
| 169 | +#define PAD_DIRECTION_SEL_2 0x664 | |
| 170 | + | |
| 167 | 171 | /* combined macros */ |
| 168 | 172 | #define PMX_GMII_MASK (PMX_GMIICLK_MASK | \ |
| 169 | 173 | PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \ |
| @@ -237,6 +241,10 @@ static struct spear_muxreg i2c0_muxreg[] = { · 67 unmodified lines | ||
| 237 | 241 | .reg = PAD_FUNCTION_EN_0, |
| 238 | 242 | .mask = PMX_I2C0_MASK, |
| 239 | 243 | .val = PMX_I2C0_MASK, |
| 244 | + }, { | |
| 245 | + .reg = PAD_DIRECTION_SEL_0, | |
| 246 | + .mask = PMX_I2C0_MASK, | |
| 247 | + .val = PMX_I2C0_MASK, | |
| 240 | 248 | }, |
| 241 | 249 | }; |
| 242 | 250 | |
| @@ -269,6 +277,10 @@ static struct spear_muxreg ssp0_muxreg[] = { · 26 unmodified lines | ||
| 269 | 277 | .reg = PAD_FUNCTION_EN_0, |
| 270 | 278 | .mask = PMX_SSP0_MASK, |
| 271 | 279 | .val = PMX_SSP0_MASK, |
| 280 | + }, { | |
| 281 | + .reg = PAD_DIRECTION_SEL_0, | |
| 282 | + .mask = PMX_SSP0_MASK, | |
| 283 | + .val = PMX_SSP0_MASK, | |
| 272 | 284 | }, |
| 273 | 285 | }; |
| 274 | 286 | |
| @@ -294,6 +306,10 @@ static struct spear_muxreg ssp0_cs0_muxreg[] = { · 19 unmodified lines | ||
| 294 | 306 | .reg = PAD_FUNCTION_EN_2, |
| 295 | 307 | .mask = PMX_SSP0_CS0_MASK, |
| 296 | 308 | .val = PMX_SSP0_CS0_MASK, |
| 309 | + }, { | |
| 310 | + .reg = PAD_DIRECTION_SEL_2, | |
| 311 | + .mask = PMX_SSP0_CS0_MASK, | |
| 312 | + .val = PMX_SSP0_CS0_MASK, | |
| 297 | 313 | }, |
| 298 | 314 | }; |
| 299 | 315 | |
| @@ -319,6 +335,10 @@ static struct spear_muxreg ssp0_cs1_2_muxreg[] = { · 19 unmodified lines | ||
| 319 | 335 | .reg = PAD_FUNCTION_EN_2, |
| 320 | 336 | .mask = PMX_SSP0_CS1_2_MASK, |
| 321 | 337 | .val = PMX_SSP0_CS1_2_MASK, |
| 338 | + }, { | |
| 339 | + .reg = PAD_DIRECTION_SEL_2, | |
| 340 | + .mask = PMX_SSP0_CS1_2_MASK, | |
| 341 | + .val = PMX_SSP0_CS1_2_MASK, | |
| 322 | 342 | }, |
| 323 | 343 | }; |
| 324 | 344 | |
| @@ -352,6 +372,10 @@ static struct spear_muxreg i2s0_muxreg[] = { · 27 unmodified lines | ||
| 352 | 372 | .reg = PAD_FUNCTION_EN_0, |
| 353 | 373 | .mask = PMX_I2S0_MASK, |
| 354 | 374 | .val = PMX_I2S0_MASK, |
| 375 | + }, { | |
| 376 | + .reg = PAD_DIRECTION_SEL_0, | |
| 377 | + .mask = PMX_I2S0_MASK, | |
| 378 | + .val = PMX_I2S0_MASK, | |
| 355 | 379 | }, |
| 356 | 380 | }; |
| 357 | 381 | |
| @@ -384,6 +408,10 @@ static struct spear_muxreg i2s1_muxreg[] = { · 26 unmodified lines | ||
| 384 | 408 | .reg = PAD_FUNCTION_EN_1, |
| 385 | 409 | .mask = PMX_I2S1_MASK, |
| 386 | 410 | .val = PMX_I2S1_MASK, |
| 411 | + }, { | |
| 412 | + .reg = PAD_DIRECTION_SEL_1, | |
| 413 | + .mask = PMX_I2S1_MASK, | |
| 414 | + .val = PMX_I2S1_MASK, | |
| 387 | 415 | }, |
| 388 | 416 | }; |
| 389 | 417 | |
| @@ -418,6 +446,10 @@ static struct spear_muxreg clcd_muxreg[] = { · 28 unmodified lines | ||
| 418 | 446 | .reg = PAD_FUNCTION_EN_0, |
| 419 | 447 | .mask = PMX_CLCD1_MASK, |
| 420 | 448 | .val = PMX_CLCD1_MASK, |
| 449 | + }, { | |
| 450 | + .reg = PAD_DIRECTION_SEL_0, | |
| 451 | + .mask = PMX_CLCD1_MASK, | |
| 452 | + .val = PMX_CLCD1_MASK, | |
| 421 | 453 | }, |
| 422 | 454 | }; |
| 423 | 455 | |
| @@ -443,6 +475,10 @@ static struct spear_muxreg clcd_high_res_muxreg[] = { · 19 unmodified lines | ||
| 443 | 475 | .reg = PAD_FUNCTION_EN_1, |
| 444 | 476 | .mask = PMX_CLCD2_MASK, |
| 445 | 477 | .val = PMX_CLCD2_MASK, |
| 478 | + }, { | |
| 479 | + .reg = PAD_DIRECTION_SEL_1, | |
| 480 | + .mask = PMX_CLCD2_MASK, | |
| 481 | + .val = PMX_CLCD2_MASK, | |
| 446 | 482 | }, |
| 447 | 483 | }; |
| 448 | 484 | |
| @@ -461,7 +497,7 @@ static struct spear_pingroup clcd_high_res_pingroup = { · 12 unmodified lines | ||
| 461 | 497 | .nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux), |
| 462 | 498 | }; |
| 463 | 499 | |
| 464 | −static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" }; | |
| 500 | +static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res_grp" }; | |
| 465 | 501 | static struct spear_function clcd_function = { |
| 466 | 502 | .name = "clcd", |
| 467 | 503 | .groups = clcd_grps, |
| @@ -479,6 +515,14 @@ static struct spear_muxreg arm_gpio_muxreg[] = { · 11 unmodified lines | ||
| 479 | 515 | .reg = PAD_FUNCTION_EN_1, |
| 480 | 516 | .mask = PMX_EGPIO_1_GRP_MASK, |
| 481 | 517 | .val = PMX_EGPIO_1_GRP_MASK, |
| 518 | + }, { | |
| 519 | + .reg = PAD_DIRECTION_SEL_0, | |
| 520 | + .mask = PMX_EGPIO_0_GRP_MASK, | |
| 521 | + .val = PMX_EGPIO_0_GRP_MASK, | |
| 522 | + }, { | |
| 523 | + .reg = PAD_DIRECTION_SEL_1, | |
| 524 | + .mask = PMX_EGPIO_1_GRP_MASK, | |
| 525 | + .val = PMX_EGPIO_1_GRP_MASK, | |
| 482 | 526 | }, |
| 483 | 527 | }; |
| 484 | 528 | |
| @@ -511,6 +555,10 @@ static struct spear_muxreg smi_2_chips_muxreg[] = { · 26 unmodified lines | ||
| 511 | 555 | .reg = PAD_FUNCTION_EN_0, |
| 512 | 556 | .mask = PMX_SMI_MASK, |
| 513 | 557 | .val = PMX_SMI_MASK, |
| 558 | + }, { | |
| 559 | + .reg = PAD_DIRECTION_SEL_0, | |
| 560 | + .mask = PMX_SMI_MASK, | |
| 561 | + .val = PMX_SMI_MASK, | |
| 514 | 562 | }, |
| 515 | 563 | }; |
| 516 | 564 | |
| @@ -539,6 +587,14 @@ static struct spear_muxreg smi_4_chips_muxreg[] = { · 22 unmodified lines | ||
| 539 | 587 | .reg = PAD_FUNCTION_EN_1, |
| 540 | 588 | .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, |
| 541 | 589 | .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, |
| 590 | + }, { | |
| 591 | + .reg = PAD_DIRECTION_SEL_0, | |
| 592 | + .mask = PMX_SMI_MASK, | |
| 593 | + .val = PMX_SMI_MASK, | |
| 594 | + }, { | |
| 595 | + .reg = PAD_DIRECTION_SEL_1, | |
| 596 | + .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | |
| 597 | + .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | |
| 542 | 598 | }, |
| 543 | 599 | }; |
| 544 | 600 | |
| @@ -573,6 +629,10 @@ static struct spear_muxreg gmii_muxreg[] = { · 28 unmodified lines | ||
| 573 | 629 | .reg = PAD_FUNCTION_EN_0, |
| 574 | 630 | .mask = PMX_GMII_MASK, |
| 575 | 631 | .val = PMX_GMII_MASK, |
| 632 | + }, { | |
| 633 | + .reg = PAD_DIRECTION_SEL_0, | |
| 634 | + .mask = PMX_GMII_MASK, | |
| 635 | + .val = PMX_GMII_MASK, | |
| 576 | 636 | }, |
| 577 | 637 | }; |
| 578 | 638 | |
| @@ -615,6 +675,18 @@ static struct spear_muxreg rgmii_muxreg[] = { · 36 unmodified lines | ||
| 615 | 675 | .reg = PAD_FUNCTION_EN_2, |
| 616 | 676 | .mask = PMX_RGMII_REG2_MASK, |
| 617 | 677 | .val = 0, |
| 678 | + }, { | |
| 679 | + .reg = PAD_DIRECTION_SEL_0, | |
| 680 | + .mask = PMX_RGMII_REG0_MASK, | |
| 681 | + .val = PMX_RGMII_REG0_MASK, | |
| 682 | + }, { | |
| 683 | + .reg = PAD_DIRECTION_SEL_1, | |
| 684 | + .mask = PMX_RGMII_REG1_MASK, | |
| 685 | + .val = PMX_RGMII_REG1_MASK, | |
| 686 | + }, { | |
| 687 | + .reg = PAD_DIRECTION_SEL_2, | |
| 688 | + .mask = PMX_RGMII_REG2_MASK, | |
| 689 | + .val = PMX_RGMII_REG2_MASK, | |
| 618 | 690 | }, |
| 619 | 691 | }; |
| 620 | 692 | |
| @@ -649,6 +721,10 @@ static struct spear_muxreg smii_0_1_2_muxreg[] = { · 28 unmodified lines | ||
| 649 | 721 | .reg = PAD_FUNCTION_EN_1, |
| 650 | 722 | .mask = PMX_SMII_0_1_2_MASK, |
| 651 | 723 | .val = 0, |
| 724 | + }, { | |
| 725 | + .reg = PAD_DIRECTION_SEL_1, | |
| 726 | + .mask = PMX_SMII_0_1_2_MASK, | |
| 727 | + .val = PMX_SMII_0_1_2_MASK, | |
| 652 | 728 | }, |
| 653 | 729 | }; |
| 654 | 730 | |
| @@ -681,6 +757,10 @@ static struct spear_muxreg ras_mii_txclk_muxreg[] = { · 26 unmodified lines | ||
| 681 | 757 | .reg = PAD_FUNCTION_EN_1, |
| 682 | 758 | .mask = PMX_NFCE2_MASK, |
| 683 | 759 | .val = 0, |
| 760 | + }, { | |
| 761 | + .reg = PAD_DIRECTION_SEL_1, | |
| 762 | + .mask = PMX_NFCE2_MASK, | |
| 763 | + .val = PMX_NFCE2_MASK, | |
| 684 | 764 | }, |
| 685 | 765 | }; |
| 686 | 766 | |
| @@ -721,6 +801,14 @@ static struct spear_muxreg nand_8bit_muxreg[] = { · 34 unmodified lines | ||
| 721 | 801 | .reg = PAD_FUNCTION_EN_1, |
| 722 | 802 | .mask = PMX_NAND8BIT_1_MASK, |
| 723 | 803 | .val = PMX_NAND8BIT_1_MASK, |
| 804 | + }, { | |
| 805 | + .reg = PAD_DIRECTION_SEL_0, | |
| 806 | + .mask = PMX_NAND8BIT_0_MASK, | |
| 807 | + .val = PMX_NAND8BIT_0_MASK, | |
| 808 | + }, { | |
| 809 | + .reg = PAD_DIRECTION_SEL_1, | |
| 810 | + .mask = PMX_NAND8BIT_1_MASK, | |
| 811 | + .val = PMX_NAND8BIT_1_MASK, | |
| 724 | 812 | }, |
| 725 | 813 | }; |
| 726 | 814 | |
| @@ -747,6 +835,10 @@ static struct spear_muxreg nand_16bit_muxreg[] = { · 20 unmodified lines | ||
| 747 | 835 | .reg = PAD_FUNCTION_EN_1, |
| 748 | 836 | .mask = PMX_NAND16BIT_1_MASK, |
| 749 | 837 | .val = PMX_NAND16BIT_1_MASK, |
| 838 | + }, { | |
| 839 | + .reg = PAD_DIRECTION_SEL_1, | |
| 840 | + .mask = PMX_NAND16BIT_1_MASK, | |
| 841 | + .val = PMX_NAND16BIT_1_MASK, | |
| 750 | 842 | }, |
| 751 | 843 | }; |
| 752 | 844 | |
| @@ -772,6 +864,10 @@ static struct spear_muxreg nand_4_chips_muxreg[] = { · 19 unmodified lines | ||
| 772 | 864 | .reg = PAD_FUNCTION_EN_1, |
| 773 | 865 | .mask = PMX_NAND_4CHIPS_MASK, |
| 774 | 866 | .val = PMX_NAND_4CHIPS_MASK, |
| 867 | + }, { | |
| 868 | + .reg = PAD_DIRECTION_SEL_1, | |
| 869 | + .mask = PMX_NAND_4CHIPS_MASK, | |
| 870 | + .val = PMX_NAND_4CHIPS_MASK, | |
| 775 | 871 | }, |
| 776 | 872 | }; |
| 777 | 873 | |
| @@ -833,6 +929,10 @@ static struct spear_muxreg keyboard_rowcol6_8_muxreg[] = { · 55 unmodified lines | ||
| 833 | 929 | .reg = PAD_FUNCTION_EN_1, |
| 834 | 930 | .mask = PMX_KBD_ROWCOL68_MASK, |
| 835 | 931 | .val = PMX_KBD_ROWCOL68_MASK, |
| 932 | + }, { | |
| 933 | + .reg = PAD_DIRECTION_SEL_1, | |
| 934 | + .mask = PMX_KBD_ROWCOL68_MASK, | |
| 935 | + .val = PMX_KBD_ROWCOL68_MASK, | |
| 836 | 936 | }, |
| 837 | 937 | }; |
| 838 | 938 | |
| @@ -866,6 +966,10 @@ static struct spear_muxreg uart0_muxreg[] = { · 27 unmodified lines | ||
| 866 | 966 | .reg = PAD_FUNCTION_EN_0, |
| 867 | 967 | .mask = PMX_UART0_MASK, |
| 868 | 968 | .val = PMX_UART0_MASK, |
| 969 | + }, { | |
| 970 | + .reg = PAD_DIRECTION_SEL_0, | |
| 971 | + .mask = PMX_UART0_MASK, | |
| 972 | + .val = PMX_UART0_MASK, | |
| 869 | 973 | }, |
| 870 | 974 | }; |
| 871 | 975 | |
| @@ -891,6 +995,10 @@ static struct spear_muxreg uart0_modem_muxreg[] = { · 19 unmodified lines | ||
| 891 | 995 | .reg = PAD_FUNCTION_EN_1, |
| 892 | 996 | .mask = PMX_UART0_MODEM_MASK, |
| 893 | 997 | .val = PMX_UART0_MODEM_MASK, |
| 998 | + }, { | |
| 999 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1000 | + .mask = PMX_UART0_MODEM_MASK, | |
| 1001 | + .val = PMX_UART0_MODEM_MASK, | |
| 894 | 1002 | }, |
| 895 | 1003 | }; |
| 896 | 1004 | |
| @@ -923,6 +1031,10 @@ static struct spear_muxreg gpt0_tmr0_muxreg[] = { · 26 unmodified lines | ||
| 923 | 1031 | .reg = PAD_FUNCTION_EN_1, |
| 924 | 1032 | .mask = PMX_GPT0_TMR0_MASK, |
| 925 | 1033 | .val = PMX_GPT0_TMR0_MASK, |
| 1034 | + }, { | |
| 1035 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1036 | + .mask = PMX_GPT0_TMR0_MASK, | |
| 1037 | + .val = PMX_GPT0_TMR0_MASK, | |
| 926 | 1038 | }, |
| 927 | 1039 | }; |
| 928 | 1040 | |
| @@ -948,6 +1060,10 @@ static struct spear_muxreg gpt0_tmr1_muxreg[] = { · 19 unmodified lines | ||
| 948 | 1060 | .reg = PAD_FUNCTION_EN_1, |
| 949 | 1061 | .mask = PMX_GPT0_TMR1_MASK, |
| 950 | 1062 | .val = PMX_GPT0_TMR1_MASK, |
| 1063 | + }, { | |
| 1064 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1065 | + .mask = PMX_GPT0_TMR1_MASK, | |
| 1066 | + .val = PMX_GPT0_TMR1_MASK, | |
| 951 | 1067 | }, |
| 952 | 1068 | }; |
| 953 | 1069 | |
| @@ -980,6 +1096,10 @@ static struct spear_muxreg gpt1_tmr0_muxreg[] = { · 26 unmodified lines | ||
| 980 | 1096 | .reg = PAD_FUNCTION_EN_1, |
| 981 | 1097 | .mask = PMX_GPT1_TMR0_MASK, |
| 982 | 1098 | .val = PMX_GPT1_TMR0_MASK, |
| 1099 | + }, { | |
| 1100 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1101 | + .mask = PMX_GPT1_TMR0_MASK, | |
| 1102 | + .val = PMX_GPT1_TMR0_MASK, | |
| 983 | 1103 | }, |
| 984 | 1104 | }; |
| 985 | 1105 | |
| @@ -1005,6 +1125,10 @@ static struct spear_muxreg gpt1_tmr1_muxreg[] = { · 19 unmodified lines | ||
| 1005 | 1125 | .reg = PAD_FUNCTION_EN_1, |
| 1006 | 1126 | .mask = PMX_GPT1_TMR1_MASK, |
| 1007 | 1127 | .val = PMX_GPT1_TMR1_MASK, |
| 1128 | + }, { | |
| 1129 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1130 | + .mask = PMX_GPT1_TMR1_MASK, | |
| 1131 | + .val = PMX_GPT1_TMR1_MASK, | |
| 1008 | 1132 | }, |
| 1009 | 1133 | }; |
| 1010 | 1134 | |
| @@ -1049,6 +1173,20 @@ static const unsigned mcif_pins[] = { 86, 87, 88, 89, 90, 91, 92, 93, 213, 214, · 38 unmodified lines | ||
| 1049 | 1173 | .reg = PAD_FUNCTION_EN_2, \ |
| 1050 | 1174 | .mask = PMX_MCIFALL_2_MASK, \ |
| 1051 | 1175 | .val = PMX_MCIFALL_2_MASK, \ |
| 1176 | + }, { \ | |
| 1177 | + .reg = PAD_DIRECTION_SEL_0, \ | |
| 1178 | + .mask = PMX_MCI_DATA8_15_MASK, \ | |
| 1179 | + .val = PMX_MCI_DATA8_15_MASK, \ | |
| 1180 | + }, { \ | |
| 1181 | + .reg = PAD_DIRECTION_SEL_1, \ | |
| 1182 | + .mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ | |
| 1183 | + PMX_NFWPRT2_MASK, \ | |
| 1184 | + .val = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ | |
| 1185 | + PMX_NFWPRT2_MASK, \ | |
| 1186 | + }, { \ | |
| 1187 | + .reg = PAD_DIRECTION_SEL_2, \ | |
| 1188 | + .mask = PMX_MCIFALL_2_MASK, \ | |
| 1189 | + .val = PMX_MCIFALL_2_MASK, \ | |
| 1052 | 1190 | } |
| 1053 | 1191 | |
| 1054 | 1192 | /* sdhci device */ |
| @@ -1154,6 +1292,10 @@ static struct spear_muxreg touch_xy_muxreg[] = { · 99 unmodified lines | ||
| 1154 | 1292 | .reg = PAD_FUNCTION_EN_2, |
| 1155 | 1293 | .mask = PMX_TOUCH_XY_MASK, |
| 1156 | 1294 | .val = PMX_TOUCH_XY_MASK, |
| 1295 | + }, { | |
| 1296 | + .reg = PAD_DIRECTION_SEL_2, | |
| 1297 | + .mask = PMX_TOUCH_XY_MASK, | |
| 1298 | + .val = PMX_TOUCH_XY_MASK, | |
| 1157 | 1299 | }, |
| 1158 | 1300 | }; |
| 1159 | 1301 | |
| @@ -1187,6 +1329,10 @@ static struct spear_muxreg uart1_dis_i2c_muxreg[] = { · 27 unmodified lines | ||
| 1187 | 1329 | .reg = PAD_FUNCTION_EN_0, |
| 1188 | 1330 | .mask = PMX_I2C0_MASK, |
| 1189 | 1331 | .val = 0, |
| 1332 | + }, { | |
| 1333 | + .reg = PAD_DIRECTION_SEL_0, | |
| 1334 | + .mask = PMX_I2C0_MASK, | |
| 1335 | + .val = PMX_I2C0_MASK, | |
| 1190 | 1336 | }, |
| 1191 | 1337 | }; |
| 1192 | 1338 | |
| @@ -1213,6 +1359,12 @@ static struct spear_muxreg uart1_dis_sd_muxreg[] = { · 20 unmodified lines | ||
| 1213 | 1359 | .mask = PMX_MCIDATA1_MASK | |
| 1214 | 1360 | PMX_MCIDATA2_MASK, |
| 1215 | 1361 | .val = 0, |
| 1362 | + }, { | |
| 1363 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1364 | + .mask = PMX_MCIDATA1_MASK | | |
| 1365 | + PMX_MCIDATA2_MASK, | |
| 1366 | + .val = PMX_MCIDATA1_MASK | | |
| 1367 | + PMX_MCIDATA2_MASK, | |
| 1216 | 1368 | }, |
| 1217 | 1369 | }; |
| 1218 | 1370 | |
| @@ -1246,6 +1398,10 @@ static struct spear_muxreg uart2_3_muxreg[] = { · 27 unmodified lines | ||
| 1246 | 1398 | .reg = PAD_FUNCTION_EN_0, |
| 1247 | 1399 | .mask = PMX_I2S0_MASK, |
| 1248 | 1400 | .val = 0, |
| 1401 | + }, { | |
| 1402 | + .reg = PAD_DIRECTION_SEL_0, | |
| 1403 | + .mask = PMX_I2S0_MASK, | |
| 1404 | + .val = PMX_I2S0_MASK, | |
| 1249 | 1405 | }, |
| 1250 | 1406 | }; |
| 1251 | 1407 | |
| @@ -1278,6 +1434,10 @@ static struct spear_muxreg uart4_muxreg[] = { · 26 unmodified lines | ||
| 1278 | 1434 | .reg = PAD_FUNCTION_EN_0, |
| 1279 | 1435 | .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, |
| 1280 | 1436 | .val = 0, |
| 1437 | + }, { | |
| 1438 | + .reg = PAD_DIRECTION_SEL_0, | |
| 1439 | + .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, | |
| 1440 | + .val = PMX_I2S0_MASK | PMX_CLCD1_MASK, | |
| 1281 | 1441 | }, |
| 1282 | 1442 | }; |
| 1283 | 1443 | |
| @@ -1310,6 +1470,10 @@ static struct spear_muxreg uart5_muxreg[] = { · 26 unmodified lines | ||
| 1310 | 1470 | .reg = PAD_FUNCTION_EN_0, |
| 1311 | 1471 | .mask = PMX_CLCD1_MASK, |
| 1312 | 1472 | .val = 0, |
| 1473 | + }, { | |
| 1474 | + .reg = PAD_DIRECTION_SEL_0, | |
| 1475 | + .mask = PMX_CLCD1_MASK, | |
| 1476 | + .val = PMX_CLCD1_MASK, | |
| 1313 | 1477 | }, |
| 1314 | 1478 | }; |
| 1315 | 1479 | |
| @@ -1344,6 +1508,10 @@ static struct spear_muxreg rs485_0_1_tdm_0_1_muxreg[] = { · 28 unmodified lines | ||
| 1344 | 1508 | .reg = PAD_FUNCTION_EN_0, |
| 1345 | 1509 | .mask = PMX_CLCD1_MASK, |
| 1346 | 1510 | .val = 0, |
| 1511 | + }, { | |
| 1512 | + .reg = PAD_DIRECTION_SEL_0, | |
| 1513 | + .mask = PMX_CLCD1_MASK, | |
| 1514 | + .val = PMX_CLCD1_MASK, | |
| 1347 | 1515 | }, |
| 1348 | 1516 | }; |
| 1349 | 1517 | |
| @@ -1376,6 +1544,10 @@ static struct spear_muxreg i2c_1_2_muxreg[] = { · 26 unmodified lines | ||
| 1376 | 1544 | .reg = PAD_FUNCTION_EN_0, |
| 1377 | 1545 | .mask = PMX_CLCD1_MASK, |
| 1378 | 1546 | .val = 0, |
| 1547 | + }, { | |
| 1548 | + .reg = PAD_DIRECTION_SEL_0, | |
| 1549 | + .mask = PMX_CLCD1_MASK, | |
| 1550 | + .val = PMX_CLCD1_MASK, | |
| 1379 | 1551 | }, |
| 1380 | 1552 | }; |
| 1381 | 1553 | |
| @@ -1409,6 +1581,10 @@ static struct spear_muxreg i2c3_dis_smi_clcd_muxreg[] = { · 27 unmodified lines | ||
| 1409 | 1581 | .reg = PAD_FUNCTION_EN_0, |
| 1410 | 1582 | .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, |
| 1411 | 1583 | .val = 0, |
| 1584 | + }, { | |
| 1585 | + .reg = PAD_DIRECTION_SEL_0, | |
| 1586 | + .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, | |
| 1587 | + .val = PMX_CLCD1_MASK | PMX_SMI_MASK, | |
| 1412 | 1588 | }, |
| 1413 | 1589 | }; |
| 1414 | 1590 | |
| @@ -1435,6 +1611,10 @@ static struct spear_muxreg i2c3_dis_sd_i2s0_muxreg[] = { · 20 unmodified lines | ||
| 1435 | 1611 | .reg = PAD_FUNCTION_EN_1, |
| 1436 | 1612 | .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, |
| 1437 | 1613 | .val = 0, |
| 1614 | + }, { | |
| 1615 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1616 | + .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, | |
| 1617 | + .val = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, | |
| 1438 | 1618 | }, |
| 1439 | 1619 | }; |
| 1440 | 1620 | |
| @@ -1469,6 +1649,10 @@ static struct spear_muxreg i2c_4_5_dis_smi_muxreg[] = { · 28 unmodified lines | ||
| 1469 | 1649 | .reg = PAD_FUNCTION_EN_0, |
| 1470 | 1650 | .mask = PMX_SMI_MASK, |
| 1471 | 1651 | .val = 0, |
| 1652 | + }, { | |
| 1653 | + .reg = PAD_DIRECTION_SEL_0, | |
| 1654 | + .mask = PMX_SMI_MASK, | |
| 1655 | + .val = PMX_SMI_MASK, | |
| 1472 | 1656 | }, |
| 1473 | 1657 | }; |
| 1474 | 1658 | |
| @@ -1499,6 +1683,14 @@ static struct spear_muxreg i2c4_dis_sd_muxreg[] = { · 24 unmodified lines | ||
| 1499 | 1683 | .reg = PAD_FUNCTION_EN_2, |
| 1500 | 1684 | .mask = PMX_MCIDATA5_MASK, |
| 1501 | 1685 | .val = 0, |
| 1686 | + }, { | |
| 1687 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1688 | + .mask = PMX_MCIDATA4_MASK, | |
| 1689 | + .val = PMX_MCIDATA4_MASK, | |
| 1690 | + }, { | |
| 1691 | + .reg = PAD_DIRECTION_SEL_2, | |
| 1692 | + .mask = PMX_MCIDATA5_MASK, | |
| 1693 | + .val = PMX_MCIDATA5_MASK, | |
| 1502 | 1694 | }, |
| 1503 | 1695 | }; |
| 1504 | 1696 | |
| @@ -1526,6 +1718,12 @@ static struct spear_muxreg i2c5_dis_sd_muxreg[] = { · 21 unmodified lines | ||
| 1526 | 1718 | .mask = PMX_MCIDATA6_MASK | |
| 1527 | 1719 | PMX_MCIDATA7_MASK, |
| 1528 | 1720 | .val = 0, |
| 1721 | + }, { | |
| 1722 | + .reg = PAD_DIRECTION_SEL_2, | |
| 1723 | + .mask = PMX_MCIDATA6_MASK | | |
| 1724 | + PMX_MCIDATA7_MASK, | |
| 1725 | + .val = PMX_MCIDATA6_MASK | | |
| 1726 | + PMX_MCIDATA7_MASK, | |
| 1529 | 1727 | }, |
| 1530 | 1728 | }; |
| 1531 | 1729 | |
| @@ -1560,6 +1758,10 @@ static struct spear_muxreg i2c_6_7_dis_kbd_muxreg[] = { · 28 unmodified lines | ||
| 1560 | 1758 | .reg = PAD_FUNCTION_EN_1, |
| 1561 | 1759 | .mask = PMX_KBD_ROWCOL25_MASK, |
| 1562 | 1760 | .val = 0, |
| 1761 | + }, { | |
| 1762 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1763 | + .mask = PMX_KBD_ROWCOL25_MASK, | |
| 1764 | + .val = PMX_KBD_ROWCOL25_MASK, | |
| 1563 | 1765 | }, |
| 1564 | 1766 | }; |
| 1565 | 1767 | |
| @@ -1587,6 +1789,12 @@ static struct spear_muxreg i2c6_dis_sd_muxreg[] = { · 21 unmodified lines | ||
| 1587 | 1789 | .mask = PMX_MCIIORDRE_MASK | |
| 1588 | 1790 | PMX_MCIIOWRWE_MASK, |
| 1589 | 1791 | .val = 0, |
| 1792 | + }, { | |
| 1793 | + .reg = PAD_DIRECTION_SEL_2, | |
| 1794 | + .mask = PMX_MCIIORDRE_MASK | | |
| 1795 | + PMX_MCIIOWRWE_MASK, | |
| 1796 | + .val = PMX_MCIIORDRE_MASK | | |
| 1797 | + PMX_MCIIOWRWE_MASK, | |
| 1590 | 1798 | }, |
| 1591 | 1799 | }; |
| 1592 | 1800 | |
| @@ -1613,6 +1821,12 @@ static struct spear_muxreg i2c7_dis_sd_muxreg[] = { · 20 unmodified lines | ||
| 1613 | 1821 | .mask = PMX_MCIRESETCF_MASK | |
| 1614 | 1822 | PMX_MCICS0CE_MASK, |
| 1615 | 1823 | .val = 0, |
| 1824 | + }, { | |
| 1825 | + .reg = PAD_DIRECTION_SEL_2, | |
| 1826 | + .mask = PMX_MCIRESETCF_MASK | | |
| 1827 | + PMX_MCICS0CE_MASK, | |
| 1828 | + .val = PMX_MCIRESETCF_MASK | | |
| 1829 | + PMX_MCICS0CE_MASK, | |
| 1616 | 1830 | }, |
| 1617 | 1831 | }; |
| 1618 | 1832 | |
| @@ -1651,6 +1865,14 @@ static struct spear_muxreg can0_dis_nor_muxreg[] = { · 32 unmodified lines | ||
| 1651 | 1865 | .reg = PAD_FUNCTION_EN_1, |
| 1652 | 1866 | .mask = PMX_NFRSTPWDWN3_MASK, |
| 1653 | 1867 | .val = 0, |
| 1868 | + }, { | |
| 1869 | + .reg = PAD_DIRECTION_SEL_0, | |
| 1870 | + .mask = PMX_NFRSTPWDWN2_MASK, | |
| 1871 | + .val = PMX_NFRSTPWDWN2_MASK, | |
| 1872 | + }, { | |
| 1873 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1874 | + .mask = PMX_NFRSTPWDWN3_MASK, | |
| 1875 | + .val = PMX_NFRSTPWDWN3_MASK, | |
| 1654 | 1876 | }, |
| 1655 | 1877 | }; |
| 1656 | 1878 | |
| @@ -1677,6 +1899,10 @@ static struct spear_muxreg can0_dis_sd_muxreg[] = { · 20 unmodified lines | ||
| 1677 | 1899 | .reg = PAD_FUNCTION_EN_2, |
| 1678 | 1900 | .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, |
| 1679 | 1901 | .val = 0, |
| 1902 | + }, { | |
| 1903 | + .reg = PAD_DIRECTION_SEL_2, | |
| 1904 | + .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, | |
| 1905 | + .val = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, | |
| 1680 | 1906 | }, |
| 1681 | 1907 | }; |
| 1682 | 1908 | |
| @@ -1711,6 +1937,10 @@ static struct spear_muxreg can1_dis_sd_muxreg[] = { · 28 unmodified lines | ||
| 1711 | 1937 | .reg = PAD_FUNCTION_EN_2, |
| 1712 | 1938 | .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, |
| 1713 | 1939 | .val = 0, |
| 1940 | + }, { | |
| 1941 | + .reg = PAD_DIRECTION_SEL_2, | |
| 1942 | + .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, | |
| 1943 | + .val = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, | |
| 1714 | 1944 | }, |
| 1715 | 1945 | }; |
| 1716 | 1946 | |
| @@ -1737,6 +1967,10 @@ static struct spear_muxreg can1_dis_kbd_muxreg[] = { · 20 unmodified lines | ||
| 1737 | 1967 | .reg = PAD_FUNCTION_EN_1, |
| 1738 | 1968 | .mask = PMX_KBD_ROWCOL25_MASK, |
| 1739 | 1969 | .val = 0, |
| 1970 | + }, { | |
| 1971 | + .reg = PAD_DIRECTION_SEL_1, | |
| 1972 | + .mask = PMX_KBD_ROWCOL25_MASK, | |
| 1973 | + .val = PMX_KBD_ROWCOL25_MASK, | |
| 1740 | 1974 | }, |
| 1741 | 1975 | }; |
| 1742 | 1976 | |
| @@ -1763,29 +1997,64 @@ static struct spear_function can1_function = { · 20 unmodified lines | ||
| 1763 | 1997 | .ngroups = ARRAY_SIZE(can1_grps), |
| 1764 | 1998 | }; |
| 1765 | 1999 | |
| 1766 | −/* Pad multiplexing for pci device */ | |
| 1767 | −static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, | |
| 2000 | +/* Pad multiplexing for (ras-ip) pci device */ | |
| 2001 | +static const unsigned pci_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, | |
| 1768 | 2002 | 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, |
| 1769 | 2003 | 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, |
| 1770 | 2004 | 55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }; |
| 1771 | −#define PCI_SATA_MUXREG \ | |
| 1772 | − { \ | |
| 1773 | − .reg = PAD_FUNCTION_EN_0, \ | |
| 1774 | − .mask = PMX_MCI_DATA8_15_MASK, \ | |
| 1775 | − .val = 0, \ | |
| 1776 | − }, { \ | |
| 1777 | − .reg = PAD_FUNCTION_EN_1, \ | |
| 1778 | − .mask = PMX_PCI_REG1_MASK, \ | |
| 1779 | − .val = 0, \ | |
| 1780 | − }, { \ | |
| 1781 | − .reg = PAD_FUNCTION_EN_2, \ | |
| 1782 | − .mask = PMX_PCI_REG2_MASK, \ | |
| 1783 | − .val = 0, \ | |
| 1784 | − } | |
| 1785 | 2005 | |
| 1786 | −/* pad multiplexing for pcie0 device */ | |
| 2006 | +static struct spear_muxreg pci_muxreg[] = { | |
| 2007 | + { | |
| 2008 | + .reg = PAD_FUNCTION_EN_0, | |
| 2009 | + .mask = PMX_MCI_DATA8_15_MASK, | |
| 2010 | + .val = 0, | |
| 2011 | + }, { | |
| 2012 | + .reg = PAD_FUNCTION_EN_1, | |
| 2013 | + .mask = PMX_PCI_REG1_MASK, | |
| 2014 | + .val = 0, | |
| 2015 | + }, { | |
| 2016 | + .reg = PAD_FUNCTION_EN_2, | |
| 2017 | + .mask = PMX_PCI_REG2_MASK, | |
| 2018 | + .val = 0, | |
| 2019 | + }, { | |
| 2020 | + .reg = PAD_DIRECTION_SEL_0, | |
| 2021 | + .mask = PMX_MCI_DATA8_15_MASK, | |
| 2022 | + .val = PMX_MCI_DATA8_15_MASK, | |
| 2023 | + }, { | |
| 2024 | + .reg = PAD_DIRECTION_SEL_1, | |
| 2025 | + .mask = PMX_PCI_REG1_MASK, | |
| 2026 | + .val = PMX_PCI_REG1_MASK, | |
| 2027 | + }, { | |
| 2028 | + .reg = PAD_DIRECTION_SEL_2, | |
| 2029 | + .mask = PMX_PCI_REG2_MASK, | |
| 2030 | + .val = PMX_PCI_REG2_MASK, | |
| 2031 | + }, | |
| 2032 | +}; | |
| 2033 | + | |
| 2034 | +static struct spear_modemux pci_modemux[] = { | |
| 2035 | + { | |
| 2036 | + .muxregs = pci_muxreg, | |
| 2037 | + .nmuxregs = ARRAY_SIZE(pci_muxreg), | |
| 2038 | + }, | |
| 2039 | +}; | |
| 2040 | + | |
| 2041 | +static struct spear_pingroup pci_pingroup = { | |
| 2042 | + .name = "pci_grp", | |
| 2043 | + .pins = pci_pins, | |
| 2044 | + .npins = ARRAY_SIZE(pci_pins), | |
| 2045 | + .modemuxs = pci_modemux, | |
| 2046 | + .nmodemuxs = ARRAY_SIZE(pci_modemux), | |
| 2047 | +}; | |
| 2048 | + | |
| 2049 | +static const char *const pci_grps[] = { "pci_grp" }; | |
| 2050 | +static struct spear_function pci_function = { | |
| 2051 | + .name = "pci", | |
| 2052 | + .groups = pci_grps, | |
| 2053 | + .ngroups = ARRAY_SIZE(pci_grps), | |
| 2054 | +}; | |
| 2055 | + | |
| 2056 | +/* pad multiplexing for (fix-part) pcie0 device */ | |
| 1787 | 2057 | static struct spear_muxreg pcie0_muxreg[] = { |
| 1788 | − PCI_SATA_MUXREG, | |
| 1789 | 2058 | { |
| 1790 | 2059 | .reg = PCIE_SATA_CFG, |
| 1791 | 2060 | .mask = PCIE_CFG_VAL(0), |
| @@ -1802,15 +2071,12 @@ static struct spear_modemux pcie0_modemux[] = { · 10 unmodified lines | ||
| 1802 | 2071 | |
| 1803 | 2072 | static struct spear_pingroup pcie0_pingroup = { |
| 1804 | 2073 | .name = "pcie0_grp", |
| 1805 | − .pins = pci_sata_pins, | |
| 1806 | − .npins = ARRAY_SIZE(pci_sata_pins), | |
| 1807 | 2074 | .modemuxs = pcie0_modemux, |
| 1808 | 2075 | .nmodemuxs = ARRAY_SIZE(pcie0_modemux), |
| 1809 | 2076 | }; |
| 1810 | 2077 | |
| 1811 | −/* pad multiplexing for pcie1 device */ | |
| 2078 | +/* pad multiplexing for (fix-part) pcie1 device */ | |
| 1812 | 2079 | static struct spear_muxreg pcie1_muxreg[] = { |
| 1813 | − PCI_SATA_MUXREG, | |
| 1814 | 2080 | { |
| 1815 | 2081 | .reg = PCIE_SATA_CFG, |
| 1816 | 2082 | .mask = PCIE_CFG_VAL(1), |
| @@ -1827,15 +2093,12 @@ static struct spear_modemux pcie1_modemux[] = { · 10 unmodified lines | ||
| 1827 | 2093 | |
| 1828 | 2094 | static struct spear_pingroup pcie1_pingroup = { |
| 1829 | 2095 | .name = "pcie1_grp", |
| 1830 | − .pins = pci_sata_pins, | |
| 1831 | − .npins = ARRAY_SIZE(pci_sata_pins), | |
| 1832 | 2096 | .modemuxs = pcie1_modemux, |
| 1833 | 2097 | .nmodemuxs = ARRAY_SIZE(pcie1_modemux), |
| 1834 | 2098 | }; |
| 1835 | 2099 | |
| 1836 | −/* pad multiplexing for pcie2 device */ | |
| 2100 | +/* pad multiplexing for (fix-part) pcie2 device */ | |
| 1837 | 2101 | static struct spear_muxreg pcie2_muxreg[] = { |
| 1838 | − PCI_SATA_MUXREG, | |
| 1839 | 2102 | { |
| 1840 | 2103 | .reg = PCIE_SATA_CFG, |
| 1841 | 2104 | .mask = PCIE_CFG_VAL(2), |
| @@ -1852,22 +2115,20 @@ static struct spear_modemux pcie2_modemux[] = { · 10 unmodified lines | ||
| 1852 | 2115 | |
| 1853 | 2116 | static struct spear_pingroup pcie2_pingroup = { |
| 1854 | 2117 | .name = "pcie2_grp", |
| 1855 | − .pins = pci_sata_pins, | |
| 1856 | − .npins = ARRAY_SIZE(pci_sata_pins), | |
| 1857 | 2118 | .modemuxs = pcie2_modemux, |
| 1858 | 2119 | .nmodemuxs = ARRAY_SIZE(pcie2_modemux), |
| 1859 | 2120 | }; |
| 1860 | 2121 | |
| 1861 | −static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" }; | |
| 1862 | −static struct spear_function pci_function = { | |
| 1863 | − .name = "pci", | |
| 1864 | − .groups = pci_grps, | |
| 1865 | − .ngroups = ARRAY_SIZE(pci_grps), | |
| 2122 | +static const char *const pcie_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" | |
| 2123 | +}; | |
| 2124 | +static struct spear_function pcie_function = { | |
| 2125 | + .name = "pci_express", | |
| 2126 | + .groups = pcie_grps, | |
| 2127 | + .ngroups = ARRAY_SIZE(pcie_grps), | |
| 1866 | 2128 | }; |
| 1867 | 2129 | |
| 1868 | 2130 | /* pad multiplexing for sata0 device */ |
| 1869 | 2131 | static struct spear_muxreg sata0_muxreg[] = { |
| 1870 | − PCI_SATA_MUXREG, | |
| 1871 | 2132 | { |
| 1872 | 2133 | .reg = PCIE_SATA_CFG, |
| 1873 | 2134 | .mask = SATA_CFG_VAL(0), |
| @@ -1884,15 +2145,12 @@ static struct spear_modemux sata0_modemux[] = { · 10 unmodified lines | ||
| 1884 | 2145 | |
| 1885 | 2146 | static struct spear_pingroup sata0_pingroup = { |
| 1886 | 2147 | .name = "sata0_grp", |
| 1887 | − .pins = pci_sata_pins, | |
| 1888 | − .npins = ARRAY_SIZE(pci_sata_pins), | |
| 1889 | 2148 | .modemuxs = sata0_modemux, |
| 1890 | 2149 | .nmodemuxs = ARRAY_SIZE(sata0_modemux), |
| 1891 | 2150 | }; |
| 1892 | 2151 | |
| 1893 | 2152 | /* pad multiplexing for sata1 device */ |
| 1894 | 2153 | static struct spear_muxreg sata1_muxreg[] = { |
| 1895 | − PCI_SATA_MUXREG, | |
| 1896 | 2154 | { |
| 1897 | 2155 | .reg = PCIE_SATA_CFG, |
| 1898 | 2156 | .mask = SATA_CFG_VAL(1), |
| @@ -1909,15 +2167,12 @@ static struct spear_modemux sata1_modemux[] = { · 10 unmodified lines | ||
| 1909 | 2167 | |
| 1910 | 2168 | static struct spear_pingroup sata1_pingroup = { |
| 1911 | 2169 | .name = "sata1_grp", |
| 1912 | − .pins = pci_sata_pins, | |
| 1913 | − .npins = ARRAY_SIZE(pci_sata_pins), | |
| 1914 | 2170 | .modemuxs = sata1_modemux, |
| 1915 | 2171 | .nmodemuxs = ARRAY_SIZE(sata1_modemux), |
| 1916 | 2172 | }; |
| 1917 | 2173 | |
| 1918 | 2174 | /* pad multiplexing for sata2 device */ |
| 1919 | 2175 | static struct spear_muxreg sata2_muxreg[] = { |
| 1920 | − PCI_SATA_MUXREG, | |
| 1921 | 2176 | { |
| 1922 | 2177 | .reg = PCIE_SATA_CFG, |
| 1923 | 2178 | .mask = SATA_CFG_VAL(2), |
| @@ -1934,8 +2189,6 @@ static struct spear_modemux sata2_modemux[] = { · 10 unmodified lines | ||
| 1934 | 2189 | |
| 1935 | 2190 | static struct spear_pingroup sata2_pingroup = { |
| 1936 | 2191 | .name = "sata2_grp", |
| 1937 | − .pins = pci_sata_pins, | |
| 1938 | − .npins = ARRAY_SIZE(pci_sata_pins), | |
| 1939 | 2192 | .modemuxs = sata2_modemux, |
| 1940 | 2193 | .nmodemuxs = ARRAY_SIZE(sata2_modemux), |
| 1941 | 2194 | }; |
| @@ -1957,6 +2210,14 @@ static struct spear_muxreg ssp1_dis_kbd_muxreg[] = { · 15 unmodified lines | ||
| 1957 | 2210 | PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | |
| 1958 | 2211 | PMX_NFCE2_MASK, |
| 1959 | 2212 | .val = 0, |
| 2213 | + }, { | |
| 2214 | + .reg = PAD_DIRECTION_SEL_1, | |
| 2215 | + .mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | | |
| 2216 | + PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | | |
| 2217 | + PMX_NFCE2_MASK, | |
| 2218 | + .val = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | | |
| 2219 | + PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | | |
| 2220 | + PMX_NFCE2_MASK, | |
| 1960 | 2221 | }, |
| 1961 | 2222 | }; |
| 1962 | 2223 | |
| @@ -1983,6 +2244,12 @@ static struct spear_muxreg ssp1_dis_sd_muxreg[] = { · 20 unmodified lines | ||
| 1983 | 2244 | .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | |
| 1984 | 2245 | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, |
| 1985 | 2246 | .val = 0, |
| 2247 | + }, { | |
| 2248 | + .reg = PAD_DIRECTION_SEL_2, | |
| 2249 | + .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | | |
| 2250 | + PMX_MCICECF_MASK | PMX_MCICEXD_MASK, | |
| 2251 | + .val = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | | |
| 2252 | + PMX_MCICECF_MASK | PMX_MCICEXD_MASK, | |
| 1986 | 2253 | }, |
| 1987 | 2254 | }; |
| 1988 | 2255 | |
| @@ -2017,6 +2284,12 @@ static struct spear_muxreg gpt64_muxreg[] = { · 28 unmodified lines | ||
| 2017 | 2284 | .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK |
| 2018 | 2285 | | PMX_MCILEDS_MASK, |
| 2019 | 2286 | .val = 0, |
| 2287 | + }, { | |
| 2288 | + .reg = PAD_DIRECTION_SEL_2, | |
| 2289 | + .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | |
| 2290 | + | PMX_MCILEDS_MASK, | |
| 2291 | + .val = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | |
| 2292 | + | PMX_MCILEDS_MASK, | |
| 2020 | 2293 | }, |
| 2021 | 2294 | }; |
| 2022 | 2295 | |
| @@ -2093,6 +2366,7 @@ static struct spear_pingroup *spear1310_pingroups[] = { · 70 unmodified lines | ||
| 2093 | 2366 | &can0_dis_sd_pingroup, |
| 2094 | 2367 | &can1_dis_sd_pingroup, |
| 2095 | 2368 | &can1_dis_kbd_pingroup, |
| 2369 | + &pci_pingroup, | |
| 2096 | 2370 | &pcie0_pingroup, |
| 2097 | 2371 | &pcie1_pingroup, |
| 2098 | 2372 | &pcie2_pingroup, |
| @@ -2138,6 +2412,7 @@ static struct spear_function *spear1310_functions[] = { · 39 unmodified lines | ||
| 2138 | 2412 | &can0_function, |
| 2139 | 2413 | &can1_function, |
| 2140 | 2414 | &pci_function, |
| 2415 | + &pcie_function, | |
| 2141 | 2416 | &sata_function, |
| 2142 | 2417 | &ssp1_function, |
| 2143 | 2418 | &gpt64_function, |
| @@ -213,7 +213,7 @@ static const struct pinctrl_pin_desc spear1340_pins[] = { · 212 unmodified lines | ||
| 213 | 213 | * Pad multiplexing for making all pads as gpio's. This is done to override the |
| 214 | 214 | * values passed from bootloader and start from scratch. |
| 215 | 215 | */ |
| 216 | −static const unsigned pads_as_gpio_pins[] = { 251 }; | |
| 216 | +static const unsigned pads_as_gpio_pins[] = { 12, 88, 89, 251 }; | |
| 217 | 217 | static struct spear_muxreg pads_as_gpio_muxreg[] = { |
| 218 | 218 | { |
| 219 | 219 | .reg = PAD_FUNCTION_EN_1, |
| @@ -1692,7 +1692,43 @@ static struct spear_pingroup clcd_pingroup = { · 1472 unmodified lines | ||
| 1692 | 1692 | .nmodemuxs = ARRAY_SIZE(clcd_modemux), |
| 1693 | 1693 | }; |
| 1694 | 1694 | |
| 1695 | −static const char *const clcd_grps[] = { "clcd_grp" }; | |
| 1695 | +/* Disable cld runtime to save panel damage */ | |
| 1696 | +static struct spear_muxreg clcd_sleep_muxreg[] = { | |
| 1697 | + { | |
| 1698 | + .reg = PAD_SHARED_IP_EN_1, | |
| 1699 | + .mask = ARM_TRACE_MASK | MIPHY_DBG_MASK, | |
| 1700 | + .val = 0, | |
| 1701 | + }, { | |
| 1702 | + .reg = PAD_FUNCTION_EN_5, | |
| 1703 | + .mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK, | |
| 1704 | + .val = 0x0, | |
| 1705 | + }, { | |
| 1706 | + .reg = PAD_FUNCTION_EN_6, | |
| 1707 | + .mask = CLCD_AND_ARM_TRACE_REG5_MASK, | |
| 1708 | + .val = 0x0, | |
| 1709 | + }, { | |
| 1710 | + .reg = PAD_FUNCTION_EN_7, | |
| 1711 | + .mask = CLCD_AND_ARM_TRACE_REG6_MASK, | |
| 1712 | + .val = 0x0, | |
| 1713 | + }, | |
| 1714 | +}; | |
| 1715 | + | |
| 1716 | +static struct spear_modemux clcd_sleep_modemux[] = { | |
| 1717 | + { | |
| 1718 | + .muxregs = clcd_sleep_muxreg, | |
| 1719 | + .nmuxregs = ARRAY_SIZE(clcd_sleep_muxreg), | |
| 1720 | + }, | |
| 1721 | +}; | |
| 1722 | + | |
| 1723 | +static struct spear_pingroup clcd_sleep_pingroup = { | |
| 1724 | + .name = "clcd_sleep_grp", | |
| 1725 | + .pins = clcd_pins, | |
| 1726 | + .npins = ARRAY_SIZE(clcd_pins), | |
| 1727 | + .modemuxs = clcd_sleep_modemux, | |
| 1728 | + .nmodemuxs = ARRAY_SIZE(clcd_sleep_modemux), | |
| 1729 | +}; | |
| 1730 | + | |
| 1731 | +static const char *const clcd_grps[] = { "clcd_grp", "clcd_sleep_grp" }; | |
| 1696 | 1732 | static struct spear_function clcd_function = { |
| 1697 | 1733 | .name = "clcd", |
| 1698 | 1734 | .groups = clcd_grps, |
| @@ -1893,6 +1929,7 @@ static struct spear_pingroup *spear1340_pingroups[] = { · 194 unmodified lines | ||
| 1893 | 1929 | &sdhci_pingroup, |
| 1894 | 1930 | &cf_pingroup, |
| 1895 | 1931 | &xd_pingroup, |
| 1932 | + &clcd_sleep_pingroup, | |
| 1896 | 1933 | &clcd_pingroup, |
| 1897 | 1934 | &arm_trace_pingroup, |
| 1898 | 1935 | &miphy_dbg_pingroup, |
| @@ -2239,6 +2239,10 @@ static struct spear_muxreg pwm2_pin_34_muxreg[] = { · 2238 unmodified lines | ||
| 2239 | 2239 | .reg = PMX_CONFIG_REG, |
| 2240 | 2240 | .mask = PMX_SSP_CS_MASK, |
| 2241 | 2241 | .val = 0, |
| 2242 | + }, { | |
| 2243 | + .reg = MODE_CONFIG_REG, | |
| 2244 | + .mask = PMX_PWM_MASK, | |
| 2245 | + .val = PMX_PWM_MASK, | |
| 2242 | 2246 | }, { |
| 2243 | 2247 | .reg = IP_SEL_PAD_30_39_REG, |
| 2244 | 2248 | .mask = PMX_PL_34_MASK, |
| @@ -2956,9 +2960,9 @@ static struct spear_function mii2_function = { · 711 unmodified lines | ||
| 2956 | 2960 | }; |
| 2957 | 2961 | |
| 2958 | 2962 | /* Pad multiplexing for cadence mii 1_2 as smii or rmii device */ |
| 2959 | −static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, | |
| 2963 | +static const unsigned rmii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, | |
| 2960 | 2964 | 21, 22, 23, 24, 25, 26, 27 }; |
| 2961 | −static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; | |
| 2965 | +static const unsigned smii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; | |
| 2962 | 2966 | static struct spear_muxreg mii0_1_muxreg[] = { |
| 2963 | 2967 | { |
| 2964 | 2968 | .reg = PMX_CONFIG_REG, |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include "pinctrl-spear.h" |
| 16 | 16 | |
| 17 | 17 | /* pad mux declarations */ |
| 18 | +#define PMX_PWM_MASK (1 << 16) | |
| 18 | 19 | #define PMX_FIRDA_MASK (1 << 14) |
| 19 | 20 | #define PMX_I2C_MASK (1 << 13) |
| 20 | 21 | #define PMX_SSP_CS_MASK (1 << 12) |
| @@ -401,7 +401,7 @@ EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); · 400 unmodified lines | ||
| 401 | 401 | /** |
| 402 | 402 | * rio_map_inb_region -- Map inbound memory region. |
| 403 | 403 | * @mport: Master port. |
| 404 | − * @lstart: physical address of memory region to be mapped | |
| 404 | + * @local: physical address of memory region to be mapped | |
| 405 | 405 | * @rbase: RIO base address assigned to this window |
| 406 | 406 | * @size: Size of the memory region |
| 407 | 407 | * @rflags: Flags for mapping. |
| @@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) · 1380 unmodified lines | ||
| 1381 | 1381 | } |
| 1382 | 1382 | EXPORT_SYMBOL_GPL(regulator_get_exclusive); |
| 1383 | 1383 | |
| 1384 | −/** | |
| 1385 | − * regulator_put - "free" the regulator source | |
| 1386 | − * @regulator: regulator source | |
| 1387 | − * | |
| 1388 | − * Note: drivers must ensure that all regulator_enable calls made on this | |
| 1389 | − * regulator source are balanced by regulator_disable calls prior to calling | |
| 1390 | − * this function. | |
| 1391 | − */ | |
| 1392 | −void regulator_put(struct regulator *regulator) | |
| 1384 | +/* Locks held by regulator_put() */ | |
| 1385 | +static void _regulator_put(struct regulator *regulator) | |
| 1393 | 1386 | { |
| 1394 | 1387 | struct regulator_dev *rdev; |
| 1395 | 1388 | |
| 1396 | 1389 | if (regulator == NULL || IS_ERR(regulator)) |
| 1397 | 1390 | return; |
| 1398 | 1391 | |
| 1399 | − mutex_lock(®ulator_list_mutex); | |
| 1400 | 1392 | rdev = regulator->rdev; |
| 1401 | 1393 | |
| 1402 | 1394 | debugfs_remove_recursive(regulator->debugfs); |
| @@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator) · 9 unmodified lines | ||
| 1412 | 1404 | rdev->exclusive = 0; |
| 1413 | 1405 | |
| 1414 | 1406 | module_put(rdev->owner); |
| 1407 | +} | |
| 1408 | + | |
| 1409 | +/** | |
| 1410 | + * regulator_put - "free" the regulator source | |
| 1411 | + * @regulator: regulator source | |
| 1412 | + * | |
| 1413 | + * Note: drivers must ensure that all regulator_enable calls made on this | |
| 1414 | + * regulator source are balanced by regulator_disable calls prior to calling | |
| 1415 | + * this function. | |
| 1416 | + */ | |
| 1417 | +void regulator_put(struct regulator *regulator) | |
| 1418 | +{ | |
| 1419 | + mutex_lock(®ulator_list_mutex); | |
| 1420 | + _regulator_put(regulator); | |
| 1415 | 1421 | mutex_unlock(®ulator_list_mutex); |
| 1416 | 1422 | } |
| 1417 | 1423 | EXPORT_SYMBOL_GPL(regulator_put); |
| @@ -1974,7 +1980,7 @@ int regulator_is_supported_voltage(struct regulator *regulator, · 556 unmodified lines | ||
| 1974 | 1980 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { |
| 1975 | 1981 | ret = regulator_get_voltage(regulator); |
| 1976 | 1982 | if (ret >= 0) |
| 1977 | − return (min_uV >= ret && ret <= max_uV); | |
| 1983 | + return (min_uV <= ret && ret <= max_uV); | |
| 1978 | 1984 | else |
| 1979 | 1985 | return ret; |
| 1980 | 1986 | } |
| @@ -3365,7 +3371,7 @@ regulator_register(const struct regulator_desc *regulator_desc, · 1384 unmodified lines | ||
| 3365 | 3371 | if (ret != 0) { |
| 3366 | 3372 | rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", |
| 3367 | 3373 | config->ena_gpio, ret); |
| 3368 | − goto clean; | |
| 3374 | + goto wash; | |
| 3369 | 3375 | } |
| 3370 | 3376 | |
| 3371 | 3377 | rdev->ena_gpio = config->ena_gpio; |
| @@ -3445,10 +3451,11 @@ unset_supplies: · 73 unmodified lines | ||
| 3445 | 3451 | |
| 3446 | 3452 | scrub: |
| 3447 | 3453 | if (rdev->supply) |
| 3448 | − regulator_put(rdev->supply); | |
| 3454 | + _regulator_put(rdev->supply); | |
| 3449 | 3455 | if (rdev->ena_gpio) |
| 3450 | 3456 | gpio_free(rdev->ena_gpio); |
| 3451 | 3457 | kfree(rdev->constraints); |
| 3458 | +wash: | |
| 3452 | 3459 | device_unregister(&rdev->dev); |
| 3453 | 3460 | /* device core frees rdev */ |
| 3454 | 3461 | rdev = ERR_PTR(ret); |
| @@ -44,7 +44,6 @@ · 43 unmodified lines | ||
| 44 | 44 | #define RAW3215_NR_CCWS 3 |
| 45 | 45 | #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ |
| 46 | 46 | |
| 47 | −#define RAW3215_FIXED 1 /* 3215 console device is not be freed */ | |
| 48 | 47 | #define RAW3215_WORKING 4 /* set if a request is being worked on */ |
| 49 | 48 | #define RAW3215_THROTTLED 8 /* set if reading is disabled */ |
| 50 | 49 | #define RAW3215_STOPPED 16 /* set if writing is disabled */ |
| @@ -339,8 +338,10 @@ static void raw3215_wakeup(unsigned long data) · 288 unmodified lines | ||
| 339 | 338 | struct tty_struct *tty; |
| 340 | 339 | |
| 341 | 340 | tty = tty_port_tty_get(&raw->port); |
| 342 | − tty_wakeup(tty); | |
| 343 | − tty_kref_put(tty); | |
| 341 | + if (tty) { | |
| 342 | + tty_wakeup(tty); | |
| 343 | + tty_kref_put(tty); | |
| 344 | + } | |
| 344 | 345 | } |
| 345 | 346 | |
| 346 | 347 | /* |
| @@ -629,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) · 282 unmodified lines | ||
| 629 | 630 | DECLARE_WAITQUEUE(wait, current); |
| 630 | 631 | unsigned long flags; |
| 631 | 632 | |
| 632 | − if (!(raw->port.flags & ASYNC_INITIALIZED) || | |
| 633 | − (raw->flags & RAW3215_FIXED)) | |
| 633 | + if (!(raw->port.flags & ASYNC_INITIALIZED)) | |
| 634 | 634 | return; |
| 635 | 635 | /* Wait for outstanding requests, then free irq */ |
| 636 | 636 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
| @@ -926,8 +926,6 @@ static int __init con3215_init(void) · 289 unmodified lines | ||
| 926 | 926 | dev_set_drvdata(&cdev->dev, raw); |
| 927 | 927 | cdev->handler = raw3215_irq; |
| 928 | 928 | |
| 929 | − raw->flags |= RAW3215_FIXED; | |
| 930 | − | |
| 931 | 929 | /* Request the console irq */ |
| 932 | 930 | if (raw3215_startup(raw) != 0) { |
| 933 | 931 | raw3215_free_info(raw); |
| @@ -112,9 +112,6 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); · 111 unmodified lines | ||
| 112 | 112 | extern void css_reiterate_subchannels(void); |
| 113 | 113 | void css_update_ssd_info(struct subchannel *sch); |
| 114 | 114 | |
| 115 | −#define __MAX_SUBCHANNEL 65535 | |
| 116 | −#define __MAX_SSID 3 | |
| 117 | − | |
| 118 | 115 | struct channel_subsystem { |
| 119 | 116 | u8 cssid; |
| 120 | 117 | int valid; |
| @@ -1424,7 +1424,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch) · 1423 unmodified lines | ||
| 1424 | 1424 | } |
| 1425 | 1425 | if (device_is_disconnected(cdev)) |
| 1426 | 1426 | return IO_SCH_REPROBE; |
| 1427 | − if (cdev->online) | |
| 1427 | + if (cdev->online && !cdev->private->flags.resuming) | |
| 1428 | 1428 | return IO_SCH_VERIFY; |
| 1429 | 1429 | if (cdev->private->state == DEV_STATE_NOT_OPER) |
| 1430 | 1430 | return IO_SCH_UNREG_ATTACH; |
| @@ -1469,12 +1469,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) · 38 unmodified lines | ||
| 1469 | 1469 | rc = 0; |
| 1470 | 1470 | goto out_unlock; |
| 1471 | 1471 | case IO_SCH_VERIFY: |
| 1472 | − if (cdev->private->flags.resuming == 1) { | |
| 1473 | − if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) { | |
| 1474 | − ccw_device_set_notoper(cdev); | |
| 1475 | − break; | |
| 1476 | − } | |
| 1477 | − } | |
| 1478 | 1472 | /* Trigger path verification. */ |
| 1479 | 1473 | io_subchannel_verify(sch); |
| 1480 | 1474 | rc = 0; |
| @@ -125,8 +125,7 @@ int idset_is_empty(struct idset *set) · 124 unmodified lines | ||
| 125 | 125 | |
| 126 | 126 | void idset_add_set(struct idset *to, struct idset *from) |
| 127 | 127 | { |
| 128 | − int len = min(__BITOPS_WORDS(to->num_ssid * to->num_id), | |
| 129 | − __BITOPS_WORDS(from->num_ssid * from->num_id)); | |
| 128 | + int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id); | |
| 130 | 129 | |
| 131 | 130 | bitmap_or(to->bitmap, to->bitmap, from->bitmap, len); |
| 132 | 131 | } |
| @@ -2942,13 +2942,33 @@ static int qeth_query_ipassists_cb(struct qeth_card *card, · 2941 unmodified lines | ||
| 2942 | 2942 | QETH_DBF_TEXT(SETUP, 2, "qipasscb"); |
| 2943 | 2943 | |
| 2944 | 2944 | cmd = (struct qeth_ipa_cmd *) data; |
| 2945 | + | |
| 2946 | + switch (cmd->hdr.return_code) { | |
| 2947 | + case IPA_RC_NOTSUPP: | |
| 2948 | + case IPA_RC_L2_UNSUPPORTED_CMD: | |
| 2949 | + QETH_DBF_TEXT(SETUP, 2, "ipaunsup"); | |
| 2950 | + card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS; | |
| 2951 | + card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS; | |
| 2952 | + return -0; | |
| 2953 | + default: | |
| 2954 | + if (cmd->hdr.return_code) { | |
| 2955 | + QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Unhandled " | |
| 2956 | + "rc=%d\n", | |
| 2957 | + dev_name(&card->gdev->dev), | |
| 2958 | + cmd->hdr.return_code); | |
| 2959 | + return 0; | |
| 2960 | + } | |
| 2961 | + } | |
| 2962 | + | |
| 2945 | 2963 | if (cmd->hdr.prot_version == QETH_PROT_IPV4) { |
| 2946 | 2964 | card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported; |
| 2947 | 2965 | card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; |
| 2948 | − } else { | |
| 2966 | + } else if (cmd->hdr.prot_version == QETH_PROT_IPV6) { | |
| 2949 | 2967 | card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported; |
| 2950 | 2968 | card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled; |
| 2951 | − } | |
| 2969 | + } else | |
| 2970 | + QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Flawed LIC detected" | |
| 2971 | + "\n", dev_name(&card->gdev->dev)); | |
| 2952 | 2972 | QETH_DBF_TEXT(SETUP, 2, "suppenbl"); |
| 2953 | 2973 | QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported); |
| 2954 | 2974 | QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled); |
| @@ -626,10 +626,13 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) · 625 unmodified lines | ||
| 626 | 626 | QETH_DBF_TEXT(SETUP, 2, "doL2init"); |
| 627 | 627 | QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card)); |
| 628 | 628 | |
| 629 | − rc = qeth_query_setadapterparms(card); | |
| 630 | − if (rc) { | |
| 631 | − QETH_DBF_MESSAGE(2, "could not query adapter parameters on " | |
| 632 | − "device %s: x%x\n", CARD_BUS_ID(card), rc); | |
| 629 | + if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { | |
| 630 | + rc = qeth_query_setadapterparms(card); | |
| 631 | + if (rc) { | |
| 632 | + QETH_DBF_MESSAGE(2, "could not query adapter " | |
| 633 | + "parameters on device %s: x%x\n", | |
| 634 | + CARD_BUS_ID(card), rc); | |
| 635 | + } | |
| 633 | 636 | } |
| 634 | 637 | |
| 635 | 638 | if (card->info.type == QETH_CARD_TYPE_IQD || |
| @@ -676,7 +679,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) · 40 unmodified lines | ||
| 676 | 679 | return -ERESTARTSYS; |
| 677 | 680 | } |
| 678 | 681 | rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); |
| 679 | − if (!rc) | |
| 682 | + if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) | |
| 680 | 683 | rc = qeth_l2_send_setmac(card, addr->sa_data); |
| 681 | 684 | return rc ? -EINVAL : 0; |
| 682 | 685 | } |
| @@ -1294,26 +1294,19 @@ static struct scsi_host_template qpti_template = { · 1293 unmodified lines | ||
| 1294 | 1294 | static const struct of_device_id qpti_match[]; |
| 1295 | 1295 | static int __devinit qpti_sbus_probe(struct platform_device *op) |
| 1296 | 1296 | { |
| 1297 | − const struct of_device_id *match; | |
| 1298 | − struct scsi_host_template *tpnt; | |
| 1299 | 1297 | struct device_node *dp = op->dev.of_node; |
| 1300 | 1298 | struct Scsi_Host *host; |
| 1301 | 1299 | struct qlogicpti *qpti; |
| 1302 | 1300 | static int nqptis; |
| 1303 | 1301 | const char *fcode; |
| 1304 | 1302 | |
| 1305 | − match = of_match_device(qpti_match, &op->dev); | |
| 1306 | − if (!match) | |
| 1307 | − return -EINVAL; | |
| 1308 | − tpnt = match->data; | |
| 1309 | − | |
| 1310 | 1303 | /* Sometimes Antares cards come up not completely |
| 1311 | 1304 | * setup, and we get a report of a zero IRQ. |
| 1312 | 1305 | */ |
| 1313 | 1306 | if (op->archdata.irqs[0] == 0) |
| 1314 | 1307 | return -ENODEV; |
| 1315 | 1308 | |
| 1316 | − host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti)); | |
| 1309 | + host = scsi_host_alloc(&qpti_template, sizeof(struct qlogicpti)); | |
| 1317 | 1310 | if (!host) |
| 1318 | 1311 | return -ENOMEM; |
| 1319 | 1312 | |
| @@ -1445,19 +1438,15 @@ static int __devexit qpti_sbus_remove(struct platform_device *op) · 125 unmodified lines | ||
| 1445 | 1438 | static const struct of_device_id qpti_match[] = { |
| 1446 | 1439 | { |
| 1447 | 1440 | .name = "ptisp", |
| 1448 | − .data = &qpti_template, | |
| 1449 | 1441 | }, |
| 1450 | 1442 | { |
| 1451 | 1443 | .name = "PTI,ptisp", |
| 1452 | − .data = &qpti_template, | |
| 1453 | 1444 | }, |
| 1454 | 1445 | { |
| 1455 | 1446 | .name = "QLGC,isp", |
| 1456 | − .data = &qpti_template, | |
| 1457 | 1447 | }, |
| 1458 | 1448 | { |
| 1459 | 1449 | .name = "SUNW,isp", |
| 1460 | − .data = &qpti_template, | |
| 1461 | 1450 | }, |
| 1462 | 1451 | {}, |
| 1463 | 1452 | }; |
| @@ -51,12 +51,10 @@ enum android_alarm_return_flags { · 50 unmodified lines | ||
| 51 | 51 | #define ANDROID_ALARM_WAIT _IO('a', 1) |
| 52 | 52 | |
| 53 | 53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) |
| 54 | −#define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size) | |
| 55 | − | |
| 56 | 54 | /* Set alarm */ |
| 57 | 55 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) |
| 58 | 56 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) |
| 59 | −#define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec) | |
| 57 | +#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) | |
| 60 | 58 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) |
| 61 | 59 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) |
| 62 | 60 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) |
| @@ -815,7 +815,7 @@ static struct platform_device_id exynos_tmu_driver_ids[] = { · 814 unmodified lines | ||
| 815 | 815 | }, |
| 816 | 816 | { }, |
| 817 | 817 | }; |
| 818 | −MODULE_DEVICE_TABLE(platform, exynos4_tmu_driver_ids); | |
| 818 | +MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids); | |
| 819 | 819 | |
| 820 | 820 | static inline struct exynos_tmu_platform_data *exynos_get_driver_data( |
| 821 | 821 | struct platform_device *pdev) |
| @@ -210,7 +210,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) · 209 unmodified lines | ||
| 210 | 210 | goto error_free_priv; |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | − zone = thermal_zone_device_register("rcar_thermal", 0, priv, | |
| 213 | + zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv, | |
| 214 | 214 | &rcar_thermal_zone_ops, 0, 0); |
| 215 | 215 | if (IS_ERR(zone)) { |
| 216 | 216 | dev_err(&pdev->dev, "thermal zone device is NULL\n"); |
| @@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty) · 423 unmodified lines | ||
| 424 | 424 | { |
| 425 | 425 | struct hvc_struct *hp = tty->driver_data; |
| 426 | 426 | unsigned long flags; |
| 427 | − int temp_open_count; | |
| 428 | 427 | |
| 429 | 428 | if (!hp) |
| 430 | 429 | return; |
| @@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty) · 13 unmodified lines | ||
| 444 | 443 | return; |
| 445 | 444 | } |
| 446 | 445 | |
| 447 | − temp_open_count = hp->port.count; | |
| 448 | 446 | hp->port.count = 0; |
| 449 | 447 | spin_unlock_irqrestore(&hp->port.lock, flags); |
| 450 | 448 | tty_port_tty_set(&hp->port, NULL); |
| @@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty) · 2 unmodified lines | ||
| 453 | 451 | |
| 454 | 452 | if (hp->ops->notifier_hangup) |
| 455 | 453 | hp->ops->notifier_hangup(hp, hp->data); |
| 456 | − | |
| 457 | − while(temp_open_count) { | |
| 458 | − --temp_open_count; | |
| 459 | − tty_port_put(&hp->port); | |
| 460 | − } | |
| 461 | 454 | } |
| 462 | 455 | |
| 463 | 456 | /* |
| @@ -1239,6 +1239,7 @@ static int __devexit max310x_remove(struct spi_device *spi) · 1238 unmodified lines | ||
| 1239 | 1239 | static const struct spi_device_id max310x_id_table[] = { |
| 1240 | 1240 | { "max3107", MAX310X_TYPE_MAX3107 }, |
| 1241 | 1241 | { "max3108", MAX310X_TYPE_MAX3108 }, |
| 1242 | + { } | |
| 1242 | 1243 | }; |
| 1243 | 1244 | MODULE_DEVICE_TABLE(spi, max310x_id_table); |
| 1244 | 1245 | |
| @@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); · 2150 unmodified lines | ||
| 2151 | 2151 | irqreturn_t usb_hcd_irq (int irq, void *__hcd) |
| 2152 | 2152 | { |
| 2153 | 2153 | struct usb_hcd *hcd = __hcd; |
| 2154 | + unsigned long flags; | |
| 2154 | 2155 | irqreturn_t rc; |
| 2155 | 2156 | |
| 2157 | + /* IRQF_DISABLED doesn't work correctly with shared IRQs | |
| 2158 | + * when the first handler doesn't use it. So let's just | |
| 2159 | + * assume it's never used. | |
| 2160 | + */ | |
| 2161 | + local_irq_save(flags); | |
| 2162 | + | |
| 2156 | 2163 | if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) |
| 2157 | 2164 | rc = IRQ_NONE; |
| 2158 | 2165 | else if (hcd->driver->irq(hcd) == IRQ_NONE) |
| @@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) · 1 unmodified line | ||
| 2160 | 2167 | else |
| 2161 | 2168 | rc = IRQ_HANDLED; |
| 2162 | 2169 | |
| 2170 | + local_irq_restore(flags); | |
| 2163 | 2171 | return rc; |
| 2164 | 2172 | } |
| 2165 | 2173 | EXPORT_SYMBOL_GPL(usb_hcd_irq); |
| @@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, · 181 unmodified lines | ||
| 2347 | 2355 | int retval; |
| 2348 | 2356 | |
| 2349 | 2357 | if (hcd->driver->irq) { |
| 2358 | + | |
| 2359 | + /* IRQF_DISABLED doesn't work as advertised when used together | |
| 2360 | + * with IRQF_SHARED. As usb_hcd_irq() will always disable | |
| 2361 | + * interrupts we can remove it here. | |
| 2362 | + */ | |
| 2363 | + if (irqflags & IRQF_SHARED) | |
| 2364 | + irqflags &= ~IRQF_DISABLED; | |
| 2365 | + | |
| 2350 | 2366 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", |
| 2351 | 2367 | hcd->driver->description, hcd->self.busnum); |
| 2352 | 2368 | retval = request_irq(irqnum, &usb_hcd_irq, irqflags, |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/usb/ehci_def.h> |
| 21 | 21 | #include <linux/delay.h> |
| 22 | 22 | #include <linux/serial_core.h> |
| 23 | +#include <linux/kconfig.h> | |
| 23 | 24 | #include <linux/kgdb.h> |
| 24 | 25 | #include <linux/kthread.h> |
| 25 | 26 | #include <asm/io.h> |
| @@ -614,12 +615,6 @@ err: · 588 unmodified lines | ||
| 614 | 615 | return -ENODEV; |
| 615 | 616 | } |
| 616 | 617 | |
| 617 | −int dbgp_external_startup(struct usb_hcd *hcd) | |
| 618 | −{ | |
| 619 | − return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); | |
| 620 | −} | |
| 621 | −EXPORT_SYMBOL_GPL(dbgp_external_startup); | |
| 622 | − | |
| 623 | 618 | static int ehci_reset_port(int port) |
| 624 | 619 | { |
| 625 | 620 | u32 portsc; |
| @@ -979,6 +974,7 @@ struct console early_dbgp_console = { · 353 unmodified lines | ||
| 979 | 974 | .index = -1, |
| 980 | 975 | }; |
| 981 | 976 | |
| 977 | +#if IS_ENABLED(CONFIG_USB_EHCI_HCD) | |
| 982 | 978 | int dbgp_reset_prep(struct usb_hcd *hcd) |
| 983 | 979 | { |
| 984 | 980 | int ret = xen_dbgp_reset_prep(hcd); |
| @@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd) · 22 unmodified lines | ||
| 1007 | 1003 | } |
| 1008 | 1004 | EXPORT_SYMBOL_GPL(dbgp_reset_prep); |
| 1009 | 1005 | |
| 1006 | +int dbgp_external_startup(struct usb_hcd *hcd) | |
| 1007 | +{ | |
| 1008 | + return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); | |
| 1009 | +} | |
| 1010 | +EXPORT_SYMBOL_GPL(dbgp_external_startup); | |
| 1011 | +#endif /* USB_EHCI_HCD */ | |
| 1012 | + | |
| 1010 | 1013 | #ifdef CONFIG_KGDB |
| 1011 | 1014 | |
| 1012 | 1015 | static char kgdbdbgp_buf[DBGP_MAX_PACKET]; |
| @@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev) · 112 unmodified lines | ||
| 113 | 113 | goto err_put_hcd; |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | − ret = usb_add_hcd(hcd, irq, IRQF_SHARED); | |
| 116 | + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | |
| 117 | 117 | if (ret) |
| 118 | 118 | goto err_put_hcd; |
| 119 | 119 | |
| @@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver, · 55 unmodified lines | ||
| 56 | 56 | goto err3; |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | − retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | |
| 59 | + retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | |
| 60 | 60 | if (retval != 0) |
| 61 | 61 | goto err4; |
| 62 | 62 | return retval; |
| @@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req) · 706 unmodified lines | ||
| 707 | 707 | fifo_count = musb_readw(epio, MUSB_RXCOUNT); |
| 708 | 708 | |
| 709 | 709 | /* |
| 710 | − * use mode 1 only if we expect data of at least ep packet_sz | |
| 711 | − * and have not yet received a short packet | |
| 710 | + * Enable Mode 1 on RX transfers only when short_not_ok flag | |
| 711 | + * is set. Currently short_not_ok flag is set only from | |
| 712 | + * file_storage and f_mass_storage drivers | |
| 712 | 713 | */ |
| 713 | − if ((request->length - request->actual >= musb_ep->packet_sz) && | |
| 714 | − (fifo_count >= musb_ep->packet_sz)) | |
| 714 | + | |
| 715 | + if (request->short_not_ok && fifo_count == musb_ep->packet_sz) | |
| 715 | 716 | use_mode_1 = 1; |
| 716 | 717 | else |
| 717 | 718 | use_mode_1 = 0; |
| @@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req) · 9 unmodified lines | ||
| 727 | 728 | c = musb->dma_controller; |
| 728 | 729 | channel = musb_ep->dma; |
| 729 | 730 | |
| 731 | + /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in | |
| 732 | + * mode 0 only. So we do not get endpoint interrupts due to DMA | |
| 733 | + * completion. We only get interrupts from DMA controller. | |
| 734 | + * | |
| 735 | + * We could operate in DMA mode 1 if we knew the size of the tranfer | |
| 736 | + * in advance. For mass storage class, request->length = what the host | |
| 737 | + * sends, so that'd work. But for pretty much everything else, | |
| 738 | + * request->length is routinely more than what the host sends. For | |
| 739 | + * most these gadgets, end of is signified either by a short packet, | |
| 740 | + * or filling the last byte of the buffer. (Sending extra data in | |
| 741 | + * that last pckate should trigger an overflow fault.) But in mode 1, | |
| 742 | + * we don't get DMA completion interrupt for short packets. | |
| 743 | + * | |
| 744 | + * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1), | |
| 745 | + * to get endpoint interrupt on every DMA req, but that didn't seem | |
| 746 | + * to work reliably. | |
| 747 | + * | |
| 748 | + * REVISIT an updated g_file_storage can set req->short_not_ok, which | |
| 749 | + * then becomes usable as a runtime "use mode 1" hint... | |
| 750 | + */ | |
| 751 | + | |
| 730 | 752 | /* Experimental: Mode1 works with mass storage use cases */ |
| 731 | 753 | if (use_mode_1) { |
| 732 | 754 | csr |= MUSB_RXCSR_AUTOCLEAR; |
| @@ -65,7 +65,7 @@ static int __devinit ux500_probe(struct platform_device *pdev) · 64 unmodified lines | ||
| 65 | 65 | struct platform_device *musb; |
| 66 | 66 | struct ux500_glue *glue; |
| 67 | 67 | struct clk *clk; |
| 68 | − | |
| 68 | + int musbid; | |
| 69 | 69 | int ret = -ENOMEM; |
| 70 | 70 | |
| 71 | 71 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); |
| @@ -58,7 +58,7 @@ config USB_ULPI_VIEWPORT · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | config TWL4030_USB |
| 60 | 60 | tristate "TWL4030 USB Transceiver Driver" |
| 61 | − depends on TWL4030_CORE && REGULATOR_TWL4030 | |
| 61 | + depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS | |
| 62 | 62 | select USB_OTG_UTILS |
| 63 | 63 | help |
| 64 | 64 | Enable this to support the USB OTG transceiver on TWL4030 |
| @@ -68,7 +68,7 @@ config TWL4030_USB · 3 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | config TWL6030_USB |
| 70 | 70 | tristate "TWL6030 USB Transceiver Driver" |
| 71 | − depends on TWL4030_CORE && OMAP_USB2 | |
| 71 | + depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS | |
| 72 | 72 | select USB_OTG_UTILS |
| 73 | 73 | help |
| 74 | 74 | Enable this to support the USB OTG transceiver on TWL6030 |
| @@ -2430,7 +2430,7 @@ static void keyspan_release(struct usb_serial *serial) · 2429 unmodified lines | ||
| 2430 | 2430 | static int keyspan_port_probe(struct usb_serial_port *port) |
| 2431 | 2431 | { |
| 2432 | 2432 | struct usb_serial *serial = port->serial; |
| 2433 | − struct keyspan_port_private *s_priv; | |
| 2433 | + struct keyspan_serial_private *s_priv; | |
| 2434 | 2434 | struct keyspan_port_private *p_priv; |
| 2435 | 2435 | const struct keyspan_device_details *d_details; |
| 2436 | 2436 | struct callbacks *cback; |
| @@ -2445,7 +2445,6 @@ static int keyspan_port_probe(struct usb_serial_port *port) · 8 unmodified lines | ||
| 2445 | 2445 | if (!p_priv) |
| 2446 | 2446 | return -ENOMEM; |
| 2447 | 2447 | |
| 2448 | − s_priv = usb_get_serial_data(port->serial); | |
| 2449 | 2448 | p_priv->device_details = d_details; |
| 2450 | 2449 | |
| 2451 | 2450 | /* Setup values for the various callback routines */ |
| @@ -158,6 +158,7 @@ static void option_instat_callback(struct urb *urb); · 157 unmodified lines | ||
| 158 | 158 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 |
| 159 | 159 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 |
| 160 | 160 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 |
| 161 | +#define NOVATELWIRELESS_PRODUCT_E362 0x9010 | |
| 161 | 162 | #define NOVATELWIRELESS_PRODUCT_G1 0xA001 |
| 162 | 163 | #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 |
| 163 | 164 | #define NOVATELWIRELESS_PRODUCT_G2 0xA010 |
| @@ -193,6 +194,9 @@ static void option_instat_callback(struct urb *urb); · 29 unmodified lines | ||
| 193 | 194 | #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 |
| 194 | 195 | #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 |
| 195 | 196 | |
| 197 | +#define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ | |
| 198 | +#define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ | |
| 199 | + | |
| 196 | 200 | #define KYOCERA_VENDOR_ID 0x0c88 |
| 197 | 201 | #define KYOCERA_PRODUCT_KPC650 0x17da |
| 198 | 202 | #define KYOCERA_PRODUCT_KPC680 0x180a |
| @@ -283,6 +287,7 @@ static void option_instat_callback(struct urb *urb); · 84 unmodified lines | ||
| 283 | 287 | /* ALCATEL PRODUCTS */ |
| 284 | 288 | #define ALCATEL_VENDOR_ID 0x1bbb |
| 285 | 289 | #define ALCATEL_PRODUCT_X060S_X200 0x0000 |
| 290 | +#define ALCATEL_PRODUCT_X220_X500D 0x0017 | |
| 286 | 291 | |
| 287 | 292 | #define PIRELLI_VENDOR_ID 0x1266 |
| 288 | 293 | #define PIRELLI_PRODUCT_C100_1 0x1002 |
| @@ -706,6 +711,7 @@ static const struct usb_device_id option_ids[] = { · 417 unmodified lines | ||
| 706 | 711 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, |
| 707 | 712 | /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ |
| 708 | 713 | { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, |
| 714 | + { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) }, | |
| 709 | 715 | |
| 710 | 716 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, |
| 711 | 717 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, |
| @@ -728,6 +734,8 @@ static const struct usb_device_id option_ids[] = { · 16 unmodified lines | ||
| 728 | 734 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ |
| 729 | 735 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ |
| 730 | 736 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ |
| 737 | + { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, | |
| 738 | + { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, | |
| 731 | 739 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ |
| 732 | 740 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
| 733 | 741 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, |
| @@ -1157,6 +1165,7 @@ static const struct usb_device_id option_ids[] = { · 423 unmodified lines | ||
| 1157 | 1165 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), |
| 1158 | 1166 | .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist |
| 1159 | 1167 | }, |
| 1168 | + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, | |
| 1160 | 1169 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, |
| 1161 | 1170 | { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, |
| 1162 | 1171 | { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), |
| @@ -455,9 +455,6 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, · 454 unmodified lines | ||
| 455 | 455 | struct usb_serial *serial = port->serial; |
| 456 | 456 | struct urb *urb; |
| 457 | 457 | |
| 458 | − if (endpoint == -1) | |
| 459 | − return NULL; /* endpoint not needed */ | |
| 460 | − | |
| 461 | 458 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ |
| 462 | 459 | if (urb == NULL) { |
| 463 | 460 | dev_dbg(&serial->interface->dev, |
| @@ -489,6 +486,9 @@ int usb_wwan_port_probe(struct usb_serial_port *port) · 25 unmodified lines | ||
| 489 | 486 | init_usb_anchor(&portdata->delayed); |
| 490 | 487 | |
| 491 | 488 | for (i = 0; i < N_IN_URB; i++) { |
| 489 | + if (!port->bulk_in_size) | |
| 490 | + break; | |
| 491 | + | |
| 492 | 492 | buffer = (u8 *)__get_free_page(GFP_KERNEL); |
| 493 | 493 | if (!buffer) |
| 494 | 494 | goto bail_out_error; |
| @@ -502,8 +502,8 @@ int usb_wwan_port_probe(struct usb_serial_port *port) · 7 unmodified lines | ||
| 502 | 502 | } |
| 503 | 503 | |
| 504 | 504 | for (i = 0; i < N_OUT_URB; i++) { |
| 505 | − if (port->bulk_out_endpointAddress == -1) | |
| 506 | − continue; | |
| 505 | + if (!port->bulk_out_size) | |
| 506 | + break; | |
| 507 | 507 | |
| 508 | 508 | buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); |
| 509 | 509 | if (!buffer) |
| @@ -225,8 +225,10 @@ EXPORT_SYMBOL_GPL(register_virtio_device); · 224 unmodified lines | ||
| 225 | 225 | |
| 226 | 226 | void unregister_virtio_device(struct virtio_device *dev) |
| 227 | 227 | { |
| 228 | + int index = dev->index; /* save for after device release */ | |
| 229 | + | |
| 228 | 230 | device_unregister(&dev->dev); |
| 229 | − ida_simple_remove(&virtio_index_ida, dev->index); | |
| 231 | + ida_simple_remove(&virtio_index_ida, index); | |
| 230 | 232 | } |
| 231 | 233 | EXPORT_SYMBOL_GPL(unregister_virtio_device); |
| 232 | 234 | |
| @@ -2,6 +2,7 @@ ifneq ($(CONFIG_ARM),y) · 1 unmodified line | ||
| 2 | 2 | obj-y += manage.o balloon.o |
| 3 | 3 | obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o |
| 4 | 4 | endif |
| 5 | +obj-$(CONFIG_X86) += fallback.o | |
| 5 | 6 | obj-y += grant-table.o features.o events.o |
| 6 | 7 | obj-y += xenbus/ |
| 7 | 8 | |
| @@ -1395,10 +1395,10 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) · 1394 unmodified lines | ||
| 1395 | 1395 | { |
| 1396 | 1396 | struct pt_regs *old_regs = set_irq_regs(regs); |
| 1397 | 1397 | |
| 1398 | + irq_enter(); | |
| 1398 | 1399 | #ifdef CONFIG_X86 |
| 1399 | 1400 | exit_idle(); |
| 1400 | 1401 | #endif |
| 1401 | − irq_enter(); | |
| 1402 | 1402 | |
| 1403 | 1403 | __xen_evtchn_do_upcall(); |
| 1404 | 1404 | |
| @@ -0,0 +1,80 @@ | ||
| 1 | +#include <linux/kernel.h> | |
| 2 | +#include <linux/string.h> | |
| 3 | +#include <linux/bug.h> | |
| 4 | +#include <linux/export.h> | |
| 5 | +#include <asm/hypervisor.h> | |
| 6 | +#include <asm/xen/hypercall.h> | |
| 7 | + | |
| 8 | +int xen_event_channel_op_compat(int cmd, void *arg) | |
| 9 | +{ | |
| 10 | + struct evtchn_op op; | |
| 11 | + int rc; | |
| 12 | + | |
| 13 | + op.cmd = cmd; | |
| 14 | + memcpy(&op.u, arg, sizeof(op.u)); | |
| 15 | + rc = _hypercall1(int, event_channel_op_compat, &op); | |
| 16 | + | |
| 17 | + switch (cmd) { | |
| 18 | + case EVTCHNOP_close: | |
| 19 | + case EVTCHNOP_send: | |
| 20 | + case EVTCHNOP_bind_vcpu: | |
| 21 | + case EVTCHNOP_unmask: | |
| 22 | + /* no output */ | |
| 23 | + break; | |
| 24 | + | |
| 25 | +#define COPY_BACK(eop) \ | |
| 26 | + case EVTCHNOP_##eop: \ | |
| 27 | + memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \ | |
| 28 | + break | |
| 29 | + | |
| 30 | + COPY_BACK(bind_interdomain); | |
| 31 | + COPY_BACK(bind_virq); | |
| 32 | + COPY_BACK(bind_pirq); | |
| 33 | + COPY_BACK(status); | |
| 34 | + COPY_BACK(alloc_unbound); | |
| 35 | + COPY_BACK(bind_ipi); | |
| 36 | +#undef COPY_BACK | |
| 37 | + | |
| 38 | + default: | |
| 39 | + WARN_ON(rc != -ENOSYS); | |
| 40 | + break; | |
| 41 | + } | |
| 42 | + | |
| 43 | + return rc; | |
| 44 | +} | |
| 45 | +EXPORT_SYMBOL_GPL(xen_event_channel_op_compat); | |
| 46 | + | |
| 47 | +int HYPERVISOR_physdev_op_compat(int cmd, void *arg) | |
| 48 | +{ | |
| 49 | + struct physdev_op op; | |
| 50 | + int rc; | |
| 51 | + | |
| 52 | + op.cmd = cmd; | |
| 53 | + memcpy(&op.u, arg, sizeof(op.u)); | |
| 54 | + rc = _hypercall1(int, physdev_op_compat, &op); | |
| 55 | + | |
| 56 | + switch (cmd) { | |
| 57 | + case PHYSDEVOP_IRQ_UNMASK_NOTIFY: | |
| 58 | + case PHYSDEVOP_set_iopl: | |
| 59 | + case PHYSDEVOP_set_iobitmap: | |
| 60 | + case PHYSDEVOP_apic_write: | |
| 61 | + /* no output */ | |
| 62 | + break; | |
| 63 | + | |
| 64 | +#define COPY_BACK(pop, fld) \ | |
| 65 | + case PHYSDEVOP_##pop: \ | |
| 66 | + memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \ | |
| 67 | + break | |
| 68 | + | |
| 69 | + COPY_BACK(irq_status_query, irq_status_query); | |
| 70 | + COPY_BACK(apic_read, apic_op); | |
| 71 | + COPY_BACK(ASSIGN_VECTOR, irq_op); | |
| 72 | +#undef COPY_BACK | |
| 73 | + | |
| 74 | + default: | |
| 75 | + WARN_ON(rc != -ENOSYS); | |
| 76 | + break; | |
| 77 | + } | |
| 78 | + | |
| 79 | + return rc; | |
| 80 | +} | |
| @@ -224,6 +224,13 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr) · 223 unmodified lines | ||
| 224 | 224 | } |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | +static void | |
| 228 | +cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) | |
| 229 | +{ | |
| 230 | + memcpy(dst, src, sizeof(*dst)); | |
| 231 | + dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS); | |
| 232 | +} | |
| 233 | + | |
| 227 | 234 | static void |
| 228 | 235 | id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, |
| 229 | 236 | struct cifs_sid_id **psidid, char *typestr) |
| @@ -248,7 +255,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, · 18 unmodified lines | ||
| 248 | 255 | } |
| 249 | 256 | } |
| 250 | 257 | |
| 251 | − memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid)); | |
| 258 | + cifs_copy_sid(&(*psidid)->sid, sidptr); | |
| 252 | 259 | (*psidid)->time = jiffies - (SID_MAP_RETRY + 1); |
| 253 | 260 | (*psidid)->refcount = 0; |
| 254 | 261 | |
| @@ -354,7 +361,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) · 99 unmodified lines | ||
| 354 | 361 | * any fields of the node after a reference is put . |
| 355 | 362 | */ |
| 356 | 363 | if (test_bit(SID_ID_MAPPED, &psidid->state)) { |
| 357 | − memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); | |
| 364 | + cifs_copy_sid(ssid, &psidid->sid); | |
| 358 | 365 | psidid->time = jiffies; /* update ts for accessing */ |
| 359 | 366 | goto id_sid_out; |
| 360 | 367 | } |
| @@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) · 9 unmodified lines | ||
| 370 | 377 | if (IS_ERR(sidkey)) { |
| 371 | 378 | rc = -EINVAL; |
| 372 | 379 | cFYI(1, "%s: Can't map and id to a SID", __func__); |
| 380 | + } else if (sidkey->datalen < sizeof(struct cifs_sid)) { | |
| 381 | + rc = -EIO; | |
| 382 | + cFYI(1, "%s: Downcall contained malformed key " | |
| 383 | + "(datalen=%hu)", __func__, sidkey->datalen); | |
| 373 | 384 | } else { |
| 374 | 385 | lsid = (struct cifs_sid *)sidkey->payload.data; |
| 375 | − memcpy(&psidid->sid, lsid, | |
| 376 | − sidkey->datalen < sizeof(struct cifs_sid) ? | |
| 377 | − sidkey->datalen : sizeof(struct cifs_sid)); | |
| 378 | − memcpy(ssid, &psidid->sid, | |
| 379 | − sidkey->datalen < sizeof(struct cifs_sid) ? | |
| 380 | − sidkey->datalen : sizeof(struct cifs_sid)); | |
| 386 | + cifs_copy_sid(&psidid->sid, lsid); | |
| 387 | + cifs_copy_sid(ssid, &psidid->sid); | |
| 381 | 388 | set_bit(SID_ID_MAPPED, &psidid->state); |
| 382 | 389 | key_put(sidkey); |
| 383 | 390 | kfree(psidid->sidstr); |
| @@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) · 12 unmodified lines | ||
| 396 | 403 | return rc; |
| 397 | 404 | } |
| 398 | 405 | if (test_bit(SID_ID_MAPPED, &psidid->state)) |
| 399 | − memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); | |
| 406 | + cifs_copy_sid(ssid, &psidid->sid); | |
| 400 | 407 | else |
| 401 | 408 | rc = -EINVAL; |
| 402 | 409 | } |
| @@ -675,8 +682,6 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) · 272 unmodified lines | ||
| 675 | 682 | static void copy_sec_desc(const struct cifs_ntsd *pntsd, |
| 676 | 683 | struct cifs_ntsd *pnntsd, __u32 sidsoffset) |
| 677 | 684 | { |
| 678 | − int i; | |
| 679 | − | |
| 680 | 685 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; |
| 681 | 686 | struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; |
| 682 | 687 | |
| @@ -692,26 +697,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd, · 9 unmodified lines | ||
| 692 | 697 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
| 693 | 698 | le32_to_cpu(pntsd->osidoffset)); |
| 694 | 699 | nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); |
| 695 | − | |
| 696 | − nowner_sid_ptr->revision = owner_sid_ptr->revision; | |
| 697 | − nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth; | |
| 698 | − for (i = 0; i < 6; i++) | |
| 699 | − nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i]; | |
| 700 | − for (i = 0; i < 5; i++) | |
| 701 | − nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i]; | |
| 700 | + cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr); | |
| 702 | 701 | |
| 703 | 702 | /* copy group sid */ |
| 704 | 703 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
| 705 | 704 | le32_to_cpu(pntsd->gsidoffset)); |
| 706 | 705 | ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + |
| 707 | 706 | sizeof(struct cifs_sid)); |
| 708 | − | |
| 709 | − ngroup_sid_ptr->revision = group_sid_ptr->revision; | |
| 710 | − ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth; | |
| 711 | − for (i = 0; i < 6; i++) | |
| 712 | − ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i]; | |
| 713 | − for (i = 0; i < 5; i++) | |
| 714 | − ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i]; | |
| 707 | + cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr); | |
| 715 | 708 | |
| 716 | 709 | return; |
| 717 | 710 | } |
| @@ -1120,8 +1113,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, · 402 unmodified lines | ||
| 1120 | 1113 | kfree(nowner_sid_ptr); |
| 1121 | 1114 | return rc; |
| 1122 | 1115 | } |
| 1123 | − memcpy(owner_sid_ptr, nowner_sid_ptr, | |
| 1124 | − sizeof(struct cifs_sid)); | |
| 1116 | + cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); | |
| 1125 | 1117 | kfree(nowner_sid_ptr); |
| 1126 | 1118 | *aclflag = CIFS_ACL_OWNER; |
| 1127 | 1119 | } |
| @@ -1139,8 +1131,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, · 11 unmodified lines | ||
| 1139 | 1131 | kfree(ngroup_sid_ptr); |
| 1140 | 1132 | return rc; |
| 1141 | 1133 | } |
| 1142 | − memcpy(group_sid_ptr, ngroup_sid_ptr, | |
| 1143 | − sizeof(struct cifs_sid)); | |
| 1134 | + cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); | |
| 1144 | 1135 | kfree(ngroup_sid_ptr); |
| 1145 | 1136 | *aclflag = CIFS_ACL_GROUP; |
| 1146 | 1137 | } |
| @@ -398,7 +398,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, · 397 unmodified lines | ||
| 398 | 398 | * in network traffic in the other paths. |
| 399 | 399 | */ |
| 400 | 400 | if (!(oflags & O_CREAT)) { |
| 401 | − struct dentry *res = cifs_lookup(inode, direntry, 0); | |
| 401 | + struct dentry *res; | |
| 402 | + | |
| 403 | + /* | |
| 404 | + * Check for hashed negative dentry. We have already revalidated | |
| 405 | + * the dentry and it is fine. No need to perform another lookup. | |
| 406 | + */ | |
| 407 | + if (!d_unhashed(direntry)) | |
| 408 | + return -ENOENT; | |
| 409 | + | |
| 410 | + res = cifs_lookup(inode, direntry, 0); | |
| 402 | 411 | if (IS_ERR(res)) |
| 403 | 412 | return PTR_ERR(res); |
| 404 | 413 | |
| @@ -346,7 +346,7 @@ static inline struct epitem *ep_item_from_epqueue(poll_table *p) · 345 unmodified lines | ||
| 346 | 346 | /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */ |
| 347 | 347 | static inline int ep_op_has_event(int op) |
| 348 | 348 | { |
| 349 | − return op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD; | |
| 349 | + return op != EPOLL_CTL_DEL; | |
| 350 | 350 | } |
| 351 | 351 | |
| 352 | 352 | /* Initialize the poll safe wake up structure */ |
| @@ -676,34 +676,6 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) · 323 unmodified lines | ||
| 676 | 676 | return 0; |
| 677 | 677 | } |
| 678 | 678 | |
| 679 | −/* | |
| 680 | − * Disables a "struct epitem" in the eventpoll set. Returns -EBUSY if the item | |
| 681 | − * had no event flags set, indicating that another thread may be currently | |
| 682 | − * handling that item's events (in the case that EPOLLONESHOT was being | |
| 683 | − * used). Otherwise a zero result indicates that the item has been disabled | |
| 684 | − * from receiving events. A disabled item may be re-enabled via | |
| 685 | − * EPOLL_CTL_MOD. Must be called with "mtx" held. | |
| 686 | − */ | |
| 687 | −static int ep_disable(struct eventpoll *ep, struct epitem *epi) | |
| 688 | −{ | |
| 689 | − int result = 0; | |
| 690 | − unsigned long flags; | |
| 691 | − | |
| 692 | − spin_lock_irqsave(&ep->lock, flags); | |
| 693 | − if (epi->event.events & ~EP_PRIVATE_BITS) { | |
| 694 | − if (ep_is_linked(&epi->rdllink)) | |
| 695 | − list_del_init(&epi->rdllink); | |
| 696 | − /* Ensure ep_poll_callback will not add epi back onto ready | |
| 697 | − list: */ | |
| 698 | − epi->event.events &= EP_PRIVATE_BITS; | |
| 699 | − } | |
| 700 | − else | |
| 701 | − result = -EBUSY; | |
| 702 | − spin_unlock_irqrestore(&ep->lock, flags); | |
| 703 | − | |
| 704 | − return result; | |
| 705 | −} | |
| 706 | − | |
| 707 | 679 | static void ep_free(struct eventpoll *ep) |
| 708 | 680 | { |
| 709 | 681 | struct rb_node *rbp; |
| @@ -1048,6 +1020,8 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi) · 338 unmodified lines | ||
| 1048 | 1020 | rb_insert_color(&epi->rbn, &ep->rbr); |
| 1049 | 1021 | } |
| 1050 | 1022 | |
| 1023 | + | |
| 1024 | + | |
| 1051 | 1025 | #define PATH_ARR_SIZE 5 |
| 1052 | 1026 | /* |
| 1053 | 1027 | * These are the number paths of length 1 to 5, that we are allowing to emanate |
| @@ -1813,12 +1787,6 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, · 759 unmodified lines | ||
| 1813 | 1787 | } else |
| 1814 | 1788 | error = -ENOENT; |
| 1815 | 1789 | break; |
| 1816 | − case EPOLL_CTL_DISABLE: | |
| 1817 | − if (epi) | |
| 1818 | − error = ep_disable(ep, epi); | |
| 1819 | − else | |
| 1820 | − error = -ENOENT; | |
| 1821 | − break; | |
| 1822 | 1790 | } |
| 1823 | 1791 | mutex_unlock(&ep->mtx); |
| 1824 | 1792 | |
| @@ -516,15 +516,13 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) · 515 unmodified lines | ||
| 516 | 516 | struct gfs2_holder i_gh; |
| 517 | 517 | int error; |
| 518 | 518 | |
| 519 | − gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | |
| 520 | − error = gfs2_glock_nq(&i_gh); | |
| 521 | − if (error == 0) { | |
| 522 | − file_accessed(file); | |
| 523 | − gfs2_glock_dq(&i_gh); | |
| 524 | − } | |
| 525 | − gfs2_holder_uninit(&i_gh); | |
| 519 | + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, | |
| 520 | + &i_gh); | |
| 526 | 521 | if (error) |
| 527 | 522 | return error; |
| 523 | + /* grab lock to update inode */ | |
| 524 | + gfs2_glock_dq_uninit(&i_gh); | |
| 525 | + file_accessed(file); | |
| 528 | 526 | } |
| 529 | 527 | vma->vm_ops = &gfs2_vm_ops; |
| 530 | 528 | |
| @@ -677,10 +675,8 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, · 146 unmodified lines | ||
| 677 | 675 | size_t writesize = iov_length(iov, nr_segs); |
| 678 | 676 | struct dentry *dentry = file->f_dentry; |
| 679 | 677 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); |
| 680 | − struct gfs2_sbd *sdp; | |
| 681 | 678 | int ret; |
| 682 | 679 | |
| 683 | − sdp = GFS2_SB(file->f_mapping->host); | |
| 684 | 680 | ret = gfs2_rs_alloc(ip); |
| 685 | 681 | if (ret) |
| 686 | 682 | return ret; |
| @@ -393,12 +393,10 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) · 392 unmodified lines | ||
| 393 | 393 | struct gfs2_meta_header *mh; |
| 394 | 394 | struct gfs2_trans *tr; |
| 395 | 395 | |
| 396 | − lock_buffer(bd->bd_bh); | |
| 397 | − gfs2_log_lock(sdp); | |
| 398 | 396 | tr = current->journal_info; |
| 399 | 397 | tr->tr_touched = 1; |
| 400 | 398 | if (!list_empty(&bd->bd_list)) |
| 401 | − goto out; | |
| 399 | + return; | |
| 402 | 400 | set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); |
| 403 | 401 | set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); |
| 404 | 402 | mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; |
| @@ -414,9 +412,6 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) · 9 unmodified lines | ||
| 414 | 412 | sdp->sd_log_num_buf++; |
| 415 | 413 | list_add(&bd->bd_list, &sdp->sd_log_le_buf); |
| 416 | 414 | tr->tr_num_buf_new++; |
| 417 | −out: | |
| 418 | − gfs2_log_unlock(sdp); | |
| 419 | − unlock_buffer(bd->bd_bh); | |
| 420 | 415 | } |
| 421 | 416 | |
| 422 | 417 | static void gfs2_check_magic(struct buffer_head *bh) |
| @@ -621,7 +616,6 @@ static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) · 198 unmodified lines | ||
| 621 | 616 | |
| 622 | 617 | static void revoke_lo_before_commit(struct gfs2_sbd *sdp) |
| 623 | 618 | { |
| 624 | − struct gfs2_log_descriptor *ld; | |
| 625 | 619 | struct gfs2_meta_header *mh; |
| 626 | 620 | unsigned int offset; |
| 627 | 621 | struct list_head *head = &sdp->sd_log_le_revoke; |
| @@ -634,7 +628,6 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) · 6 unmodified lines | ||
| 634 | 628 | |
| 635 | 629 | length = gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, sizeof(u64)); |
| 636 | 630 | page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp->sd_log_num_revoke); |
| 637 | − ld = page_address(page); | |
| 638 | 631 | offset = sizeof(struct gfs2_log_descriptor); |
| 639 | 632 | |
| 640 | 633 | list_for_each_entry(bd, head, bd_list) { |
| @@ -777,12 +770,10 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) · 136 unmodified lines | ||
| 777 | 770 | struct address_space *mapping = bd->bd_bh->b_page->mapping; |
| 778 | 771 | struct gfs2_inode *ip = GFS2_I(mapping->host); |
| 779 | 772 | |
| 780 | − lock_buffer(bd->bd_bh); | |
| 781 | − gfs2_log_lock(sdp); | |
| 782 | 773 | if (tr) |
| 783 | 774 | tr->tr_touched = 1; |
| 784 | 775 | if (!list_empty(&bd->bd_list)) |
| 785 | − goto out; | |
| 776 | + return; | |
| 786 | 777 | set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); |
| 787 | 778 | set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); |
| 788 | 779 | if (gfs2_is_jdata(ip)) { |
| @@ -793,9 +784,6 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) · 4 unmodified lines | ||
| 793 | 784 | } else { |
| 794 | 785 | list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered); |
| 795 | 786 | } |
| 796 | −out: | |
| 797 | − gfs2_log_unlock(sdp); | |
| 798 | − unlock_buffer(bd->bd_bh); | |
| 799 | 787 | } |
| 800 | 788 | |
| 801 | 789 | /** |
| @@ -497,8 +497,11 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) · 496 unmodified lines | ||
| 497 | 497 | struct gfs2_quota_data **qd; |
| 498 | 498 | int error; |
| 499 | 499 | |
| 500 | − if (ip->i_res == NULL) | |
| 501 | − gfs2_rs_alloc(ip); | |
| 500 | + if (ip->i_res == NULL) { | |
| 501 | + error = gfs2_rs_alloc(ip); | |
| 502 | + if (error) | |
| 503 | + return error; | |
| 504 | + } | |
| 502 | 505 | |
| 503 | 506 | qd = ip->i_res->rs_qa_qd; |
| 504 | 507 | |
| @@ -553,7 +553,6 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) · 552 unmodified lines | ||
| 553 | 553 | */ |
| 554 | 554 | int gfs2_rs_alloc(struct gfs2_inode *ip) |
| 555 | 555 | { |
| 556 | − int error = 0; | |
| 557 | 556 | struct gfs2_blkreserv *res; |
| 558 | 557 | |
| 559 | 558 | if (ip->i_res) |
| @@ -561,7 +560,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) · 1 unmodified line | ||
| 561 | 560 | |
| 562 | 561 | res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); |
| 563 | 562 | if (!res) |
| 564 | − error = -ENOMEM; | |
| 563 | + return -ENOMEM; | |
| 565 | 564 | |
| 566 | 565 | RB_CLEAR_NODE(&res->rs_node); |
| 567 | 566 | |
| @@ -571,7 +570,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) · 3 unmodified lines | ||
| 571 | 570 | else |
| 572 | 571 | ip->i_res = res; |
| 573 | 572 | up_write(&ip->i_rw_mutex); |
| 574 | − return error; | |
| 573 | + return 0; | |
| 575 | 574 | } |
| 576 | 575 | |
| 577 | 576 | static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) |
| @@ -1263,7 +1262,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp) · 685 unmodified lines | ||
| 1263 | 1262 | int ret = 0; |
| 1264 | 1263 | u64 amt; |
| 1265 | 1264 | u64 trimmed = 0; |
| 1265 | + u64 start, end, minlen; | |
| 1266 | 1266 | unsigned int x; |
| 1267 | + unsigned bs_shift = sdp->sd_sb.sb_bsize_shift; | |
| 1267 | 1268 | |
| 1268 | 1269 | if (!capable(CAP_SYS_ADMIN)) |
| 1269 | 1270 | return -EPERM; |
| @@ -1271,19 +1272,25 @@ int gfs2_fitrim(struct file *filp, void __user *argp) · 1 unmodified line | ||
| 1271 | 1272 | if (!blk_queue_discard(q)) |
| 1272 | 1273 | return -EOPNOTSUPP; |
| 1273 | 1274 | |
| 1274 | − if (argp == NULL) { | |
| 1275 | − r.start = 0; | |
| 1276 | − r.len = ULLONG_MAX; | |
| 1277 | − r.minlen = 0; | |
| 1278 | − } else if (copy_from_user(&r, argp, sizeof(r))) | |
| 1275 | + if (copy_from_user(&r, argp, sizeof(r))) | |
| 1279 | 1276 | return -EFAULT; |
| 1280 | 1277 | |
| 1281 | 1278 | ret = gfs2_rindex_update(sdp); |
| 1282 | 1279 | if (ret) |
| 1283 | 1280 | return ret; |
| 1284 | 1281 | |
| 1285 | − rgd = gfs2_blk2rgrpd(sdp, r.start, 0); | |
| 1286 | − rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0); | |
| 1282 | + start = r.start >> bs_shift; | |
| 1283 | + end = start + (r.len >> bs_shift); | |
| 1284 | + minlen = max_t(u64, r.minlen, | |
| 1285 | + q->limits.discard_granularity) >> bs_shift; | |
| 1286 | + | |
| 1287 | + rgd = gfs2_blk2rgrpd(sdp, start, 0); | |
| 1288 | + rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0); | |
| 1289 | + | |
| 1290 | + if (end <= start || | |
| 1291 | + minlen > sdp->sd_max_rg_data || | |
| 1292 | + start > rgd_end->rd_data0 + rgd_end->rd_data) | |
| 1293 | + return -EINVAL; | |
| 1287 | 1294 | |
| 1288 | 1295 | while (1) { |
| 1289 | 1296 | |
| @@ -1295,7 +1302,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp) · 5 unmodified lines | ||
| 1295 | 1302 | /* Trim each bitmap in the rgrp */ |
| 1296 | 1303 | for (x = 0; x < rgd->rd_length; x++) { |
| 1297 | 1304 | struct gfs2_bitmap *bi = rgd->rd_bits + x; |
| 1298 | − ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt); | |
| 1305 | + ret = gfs2_rgrp_send_discards(sdp, | |
| 1306 | + rgd->rd_data0, NULL, bi, minlen, | |
| 1307 | + &amt); | |
| 1299 | 1308 | if (ret) { |
| 1300 | 1309 | gfs2_glock_dq_uninit(&gh); |
| 1301 | 1310 | goto out; |
| @@ -1324,7 +1333,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) · 22 unmodified lines | ||
| 1324 | 1333 | |
| 1325 | 1334 | out: |
| 1326 | 1335 | r.len = trimmed << 9; |
| 1327 | − if (argp && copy_to_user(argp, &r, sizeof(r))) | |
| 1336 | + if (copy_to_user(argp, &r, sizeof(r))) | |
| 1328 | 1337 | return -EFAULT; |
| 1329 | 1338 | |
| 1330 | 1339 | return ret; |
| @@ -810,7 +810,8 @@ static void gfs2_dirty_inode(struct inode *inode, int flags) · 809 unmodified lines | ||
| 810 | 810 | return; |
| 811 | 811 | } |
| 812 | 812 | need_unlock = 1; |
| 813 | − } | |
| 813 | + } else if (WARN_ON_ONCE(ip->i_gl->gl_state != LM_ST_EXCLUSIVE)) | |
| 814 | + return; | |
| 814 | 815 | |
| 815 | 816 | if (current->journal_info == NULL) { |
| 816 | 817 | ret = gfs2_trans_begin(sdp, RES_DINODE, 0); |
| @@ -155,14 +155,22 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta) · 154 unmodified lines | ||
| 155 | 155 | struct gfs2_sbd *sdp = gl->gl_sbd; |
| 156 | 156 | struct gfs2_bufdata *bd; |
| 157 | 157 | |
| 158 | + lock_buffer(bh); | |
| 159 | + gfs2_log_lock(sdp); | |
| 158 | 160 | bd = bh->b_private; |
| 159 | 161 | if (bd) |
| 160 | 162 | gfs2_assert(sdp, bd->bd_gl == gl); |
| 161 | 163 | else { |
| 164 | + gfs2_log_unlock(sdp); | |
| 165 | + unlock_buffer(bh); | |
| 162 | 166 | gfs2_attach_bufdata(gl, bh, meta); |
| 163 | 167 | bd = bh->b_private; |
| 168 | + lock_buffer(bh); | |
| 169 | + gfs2_log_lock(sdp); | |
| 164 | 170 | } |
| 165 | 171 | lops_add(sdp, bd); |
| 172 | + gfs2_log_unlock(sdp); | |
| 173 | + unlock_buffer(bh); | |
| 166 | 174 | } |
| 167 | 175 | |
| 168 | 176 | void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) |
| @@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) · 216 unmodified lines | ||
| 217 | 217 | { |
| 218 | 218 | char buf1[NFS_DNS_HOSTNAME_MAXLEN+1]; |
| 219 | 219 | struct nfs_dns_ent key, *item; |
| 220 | − unsigned long ttl; | |
| 220 | + unsigned int ttl; | |
| 221 | 221 | ssize_t len; |
| 222 | 222 | int ret = -EINVAL; |
| 223 | 223 | |
| @@ -240,7 +240,8 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) · 16 unmodified lines | ||
| 240 | 240 | key.namelen = len; |
| 241 | 241 | memset(&key.h, 0, sizeof(key.h)); |
| 242 | 242 | |
| 243 | − ttl = get_expiry(&buf); | |
| 243 | + if (get_uint(&buf, &ttl) < 0) | |
| 244 | + goto out; | |
| 244 | 245 | if (ttl == 0) |
| 245 | 246 | goto out; |
| 246 | 247 | key.h.expiry_time = ttl + seconds_since_boot(); |
| @@ -685,7 +685,10 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) · 684 unmodified lines | ||
| 685 | 685 | if (ctx->cred != NULL) |
| 686 | 686 | put_rpccred(ctx->cred); |
| 687 | 687 | dput(ctx->dentry); |
| 688 | − nfs_sb_deactive(sb); | |
| 688 | + if (is_sync) | |
| 689 | + nfs_sb_deactive(sb); | |
| 690 | + else | |
| 691 | + nfs_sb_deactive_async(sb); | |
| 689 | 692 | kfree(ctx->mdsthreshold); |
| 690 | 693 | kfree(ctx); |
| 691 | 694 | } |
| @@ -351,10 +351,12 @@ extern int __init register_nfs_fs(void); · 350 unmodified lines | ||
| 351 | 351 | extern void __exit unregister_nfs_fs(void); |
| 352 | 352 | extern void nfs_sb_active(struct super_block *sb); |
| 353 | 353 | extern void nfs_sb_deactive(struct super_block *sb); |
| 354 | +extern void nfs_sb_deactive_async(struct super_block *sb); | |
| 354 | 355 | |
| 355 | 356 | /* namespace.c */ |
| 357 | +#define NFS_PATH_CANONICAL 1 | |
| 356 | 358 | extern char *nfs_path(char **p, struct dentry *dentry, |
| 357 | − char *buffer, ssize_t buflen); | |
| 359 | + char *buffer, ssize_t buflen, unsigned flags); | |
| 358 | 360 | extern struct vfsmount *nfs_d_automount(struct path *path); |
| 359 | 361 | struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *, |
| 360 | 362 | struct nfs_fh *, struct nfs_fattr *); |
| @@ -498,7 +500,7 @@ static inline char *nfs_devname(struct dentry *dentry, · 137 unmodified lines | ||
| 498 | 500 | char *buffer, ssize_t buflen) |
| 499 | 501 | { |
| 500 | 502 | char *dummy; |
| 501 | − return nfs_path(&dummy, dentry, buffer, buflen); | |
| 503 | + return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL); | |
| 502 | 504 | } |
| 503 | 505 | |
| 504 | 506 | /* |
| @@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info) · 180 unmodified lines | ||
| 181 | 181 | else |
| 182 | 182 | msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT]; |
| 183 | 183 | |
| 184 | − status = rpc_call_sync(mnt_clnt, &msg, 0); | |
| 184 | + status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT); | |
| 185 | 185 | rpc_shutdown_client(mnt_clnt); |
| 186 | 186 | |
| 187 | 187 | if (status < 0) |
| @@ -33,6 +33,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; · 32 unmodified lines | ||
| 33 | 33 | * @dentry - pointer to dentry |
| 34 | 34 | * @buffer - result buffer |
| 35 | 35 | * @buflen - length of buffer |
| 36 | + * @flags - options (see below) | |
| 36 | 37 | * |
| 37 | 38 | * Helper function for constructing the server pathname |
| 38 | 39 | * by arbitrary hashed dentry. |
| @@ -40,8 +41,14 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; · 1 unmodified line | ||
| 40 | 41 | * This is mainly for use in figuring out the path on the |
| 41 | 42 | * server side when automounting on top of an existing partition |
| 42 | 43 | * and in generating /proc/mounts and friends. |
| 44 | + * | |
| 45 | + * Supported flags: | |
| 46 | + * NFS_PATH_CANONICAL: ensure there is exactly one slash after | |
| 47 | + * the original device (export) name | |
| 48 | + * (if unset, the original name is returned verbatim) | |
| 43 | 49 | */ |
| 44 | −char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen) | |
| 50 | +char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, | |
| 51 | + unsigned flags) | |
| 45 | 52 | { |
| 46 | 53 | char *end; |
| 47 | 54 | int namelen; |
| @@ -74,7 +81,7 @@ rename_retry: · 26 unmodified lines | ||
| 74 | 81 | rcu_read_unlock(); |
| 75 | 82 | goto rename_retry; |
| 76 | 83 | } |
| 77 | − if (*end != '/') { | |
| 84 | + if ((flags & NFS_PATH_CANONICAL) && *end != '/') { | |
| 78 | 85 | if (--buflen < 0) { |
| 79 | 86 | spin_unlock(&dentry->d_lock); |
| 80 | 87 | rcu_read_unlock(); |
| @@ -91,9 +98,11 @@ rename_retry: · 10 unmodified lines | ||
| 91 | 98 | return end; |
| 92 | 99 | } |
| 93 | 100 | namelen = strlen(base); |
| 94 | − /* Strip off excess slashes in base string */ | |
| 95 | − while (namelen > 0 && base[namelen - 1] == '/') | |
| 96 | − namelen--; | |
| 101 | + if (flags & NFS_PATH_CANONICAL) { | |
| 102 | + /* Strip off excess slashes in base string */ | |
| 103 | + while (namelen > 0 && base[namelen - 1] == '/') | |
| 104 | + namelen--; | |
| 105 | + } | |
| 97 | 106 | buflen -= namelen; |
| 98 | 107 | if (buflen < 0) { |
| 99 | 108 | spin_unlock(&dentry->d_lock); |
| @@ -81,7 +81,8 @@ static char *nfs_path_component(const char *nfspath, const char *end) · 80 unmodified lines | ||
| 81 | 81 | static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) |
| 82 | 82 | { |
| 83 | 83 | char *limit; |
| 84 | − char *path = nfs_path(&limit, dentry, buffer, buflen); | |
| 84 | + char *path = nfs_path(&limit, dentry, buffer, buflen, | |
| 85 | + NFS_PATH_CANONICAL); | |
| 85 | 86 | if (!IS_ERR(path)) { |
| 86 | 87 | char *path_component = nfs_path_component(path, limit); |
| 87 | 88 | if (path_component) |
| @@ -339,8 +339,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc · 338 unmodified lines | ||
| 339 | 339 | dprintk("%s ERROR: %d Reset session\n", __func__, |
| 340 | 340 | errorcode); |
| 341 | 341 | nfs4_schedule_session_recovery(clp->cl_session, errorcode); |
| 342 | − exception->retry = 1; | |
| 343 | − break; | |
| 342 | + goto wait_on_recovery; | |
| 344 | 343 | #endif /* defined(CONFIG_NFS_V4_1) */ |
| 345 | 344 | case -NFS4ERR_FILE_OPEN: |
| 346 | 345 | if (exception->timeout > HZ) { |
| @@ -1572,9 +1571,11 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) · 1225 unmodified lines | ||
| 1572 | 1571 | data->timestamp = jiffies; |
| 1573 | 1572 | if (nfs4_setup_sequence(data->o_arg.server, |
| 1574 | 1573 | &data->o_arg.seq_args, |
| 1575 | − &data->o_res.seq_res, task)) | |
| 1576 | − return; | |
| 1577 | − rpc_call_start(task); | |
| 1574 | + &data->o_res.seq_res, | |
| 1575 | + task) != 0) | |
| 1576 | + nfs_release_seqid(data->o_arg.seqid); | |
| 1577 | + else | |
| 1578 | + rpc_call_start(task); | |
| 1578 | 1579 | return; |
| 1579 | 1580 | unlock_no_action: |
| 1580 | 1581 | rcu_read_unlock(); |
| @@ -1748,7 +1749,7 @@ static int nfs4_opendata_access(struct rpc_cred *cred, · 167 unmodified lines | ||
| 1748 | 1749 | |
| 1749 | 1750 | /* even though OPEN succeeded, access is denied. Close the file */ |
| 1750 | 1751 | nfs4_close_state(state, fmode); |
| 1751 | − return -NFS4ERR_ACCESS; | |
| 1752 | + return -EACCES; | |
| 1752 | 1753 | } |
| 1753 | 1754 | |
| 1754 | 1755 | /* |
| @@ -2196,7 +2197,7 @@ static void nfs4_free_closedata(void *data) · 441 unmodified lines | ||
| 2196 | 2197 | nfs4_put_open_state(calldata->state); |
| 2197 | 2198 | nfs_free_seqid(calldata->arg.seqid); |
| 2198 | 2199 | nfs4_put_state_owner(sp); |
| 2199 | − nfs_sb_deactive(sb); | |
| 2200 | + nfs_sb_deactive_async(sb); | |
| 2200 | 2201 | kfree(calldata); |
| 2201 | 2202 | } |
| 2202 | 2203 | |
| @@ -2296,9 +2297,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) · 93 unmodified lines | ||
| 2296 | 2297 | if (nfs4_setup_sequence(NFS_SERVER(inode), |
| 2297 | 2298 | &calldata->arg.seq_args, |
| 2298 | 2299 | &calldata->res.seq_res, |
| 2299 | − task)) | |
| 2300 | − goto out; | |
| 2301 | − rpc_call_start(task); | |
| 2300 | + task) != 0) | |
| 2301 | + nfs_release_seqid(calldata->arg.seqid); | |
| 2302 | + else | |
| 2303 | + rpc_call_start(task); | |
| 2302 | 2304 | out: |
| 2303 | 2305 | dprintk("%s: done!\n", __func__); |
| 2304 | 2306 | } |
| @@ -4529,6 +4531,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) · 2224 unmodified lines | ||
| 4529 | 4531 | if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) |
| 4530 | 4532 | rpc_restart_call_prepare(task); |
| 4531 | 4533 | } |
| 4534 | + nfs_release_seqid(calldata->arg.seqid); | |
| 4532 | 4535 | } |
| 4533 | 4536 | |
| 4534 | 4537 | static void nfs4_locku_prepare(struct rpc_task *task, void *data) |
| @@ -4545,9 +4548,11 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data) · 10 unmodified lines | ||
| 4545 | 4548 | calldata->timestamp = jiffies; |
| 4546 | 4549 | if (nfs4_setup_sequence(calldata->server, |
| 4547 | 4550 | &calldata->arg.seq_args, |
| 4548 | − &calldata->res.seq_res, task)) | |
| 4549 | − return; | |
| 4550 | − rpc_call_start(task); | |
| 4551 | + &calldata->res.seq_res, | |
| 4552 | + task) != 0) | |
| 4553 | + nfs_release_seqid(calldata->arg.seqid); | |
| 4554 | + else | |
| 4555 | + rpc_call_start(task); | |
| 4551 | 4556 | } |
| 4552 | 4557 | |
| 4553 | 4558 | static const struct rpc_call_ops nfs4_locku_ops = { |
| @@ -4692,7 +4697,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) · 138 unmodified lines | ||
| 4692 | 4697 | /* Do we need to do an open_to_lock_owner? */ |
| 4693 | 4698 | if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { |
| 4694 | 4699 | if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) |
| 4695 | − return; | |
| 4700 | + goto out_release_lock_seqid; | |
| 4696 | 4701 | data->arg.open_stateid = &state->stateid; |
| 4697 | 4702 | data->arg.new_lock_owner = 1; |
| 4698 | 4703 | data->res.open_seqid = data->arg.open_seqid; |
| @@ -4701,10 +4706,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) · 2 unmodified lines | ||
| 4701 | 4706 | data->timestamp = jiffies; |
| 4702 | 4707 | if (nfs4_setup_sequence(data->server, |
| 4703 | 4708 | &data->arg.seq_args, |
| 4704 | − &data->res.seq_res, task)) | |
| 4709 | + &data->res.seq_res, | |
| 4710 | + task) == 0) { | |
| 4711 | + rpc_call_start(task); | |
| 4705 | 4712 | return; |
| 4706 | − rpc_call_start(task); | |
| 4707 | − dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); | |
| 4713 | + } | |
| 4714 | + nfs_release_seqid(data->arg.open_seqid); | |
| 4715 | +out_release_lock_seqid: | |
| 4716 | + nfs_release_seqid(data->arg.lock_seqid); | |
| 4717 | + dprintk("%s: done!, ret = %d\n", __func__, task->tk_status); | |
| 4708 | 4718 | } |
| 4709 | 4719 | |
| 4710 | 4720 | static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata) |
| @@ -5667,7 +5677,7 @@ static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl, · 956 unmodified lines | ||
| 5667 | 5677 | tbl->slots = new; |
| 5668 | 5678 | tbl->max_slots = max_slots; |
| 5669 | 5679 | } |
| 5670 | − tbl->highest_used_slotid = -1; /* no slot is currently used */ | |
| 5680 | + tbl->highest_used_slotid = NFS4_NO_SLOT; | |
| 5671 | 5681 | for (i = 0; i < tbl->max_slots; i++) |
| 5672 | 5682 | tbl->slots[i].seq_nr = ivalue; |
| 5673 | 5683 | spin_unlock(&tbl->slot_tbl_lock); |
| @@ -925,8 +925,8 @@ pnfs_find_alloc_layout(struct inode *ino, · 924 unmodified lines | ||
| 925 | 925 | if (likely(nfsi->layout == NULL)) { /* Won the race? */ |
| 926 | 926 | nfsi->layout = new; |
| 927 | 927 | return new; |
| 928 | − } | |
| 929 | − pnfs_free_layout_hdr(new); | |
| 928 | + } else if (new != NULL) | |
| 929 | + pnfs_free_layout_hdr(new); | |
| 930 | 930 | out_existing: |
| 931 | 931 | pnfs_get_layout_hdr(nfsi->layout); |
| 932 | 932 | return nfsi->layout; |
| @@ -54,6 +54,7 @@ · 53 unmodified lines | ||
| 54 | 54 | #include <linux/parser.h> |
| 55 | 55 | #include <linux/nsproxy.h> |
| 56 | 56 | #include <linux/rcupdate.h> |
| 57 | +#include <linux/kthread.h> | |
| 57 | 58 | |
| 58 | 59 | #include <asm/uaccess.h> |
| 59 | 60 | |
| @@ -415,6 +416,54 @@ void nfs_sb_deactive(struct super_block *sb) · 355 unmodified lines | ||
| 415 | 416 | } |
| 416 | 417 | EXPORT_SYMBOL_GPL(nfs_sb_deactive); |
| 417 | 418 | |
| 419 | +static int nfs_deactivate_super_async_work(void *ptr) | |
| 420 | +{ | |
| 421 | + struct super_block *sb = ptr; | |
| 422 | + | |
| 423 | + deactivate_super(sb); | |
| 424 | + module_put_and_exit(0); | |
| 425 | + return 0; | |
| 426 | +} | |
| 427 | + | |
| 428 | +/* | |
| 429 | + * same effect as deactivate_super, but will do final unmount in kthread | |
| 430 | + * context | |
| 431 | + */ | |
| 432 | +static void nfs_deactivate_super_async(struct super_block *sb) | |
| 433 | +{ | |
| 434 | + struct task_struct *task; | |
| 435 | + char buf[INET6_ADDRSTRLEN + 1]; | |
| 436 | + struct nfs_server *server = NFS_SB(sb); | |
| 437 | + struct nfs_client *clp = server->nfs_client; | |
| 438 | + | |
| 439 | + if (!atomic_add_unless(&sb->s_active, -1, 1)) { | |
| 440 | + rcu_read_lock(); | |
| 441 | + snprintf(buf, sizeof(buf), | |
| 442 | + rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR)); | |
| 443 | + rcu_read_unlock(); | |
| 444 | + | |
| 445 | + __module_get(THIS_MODULE); | |
| 446 | + task = kthread_run(nfs_deactivate_super_async_work, sb, | |
| 447 | + "%s-deactivate-super", buf); | |
| 448 | + if (IS_ERR(task)) { | |
| 449 | + pr_err("%s: kthread_run: %ld\n", | |
| 450 | + __func__, PTR_ERR(task)); | |
| 451 | + /* make synchronous call and hope for the best */ | |
| 452 | + deactivate_super(sb); | |
| 453 | + module_put(THIS_MODULE); | |
| 454 | + } | |
| 455 | + } | |
| 456 | +} | |
| 457 | + | |
| 458 | +void nfs_sb_deactive_async(struct super_block *sb) | |
| 459 | +{ | |
| 460 | + struct nfs_server *server = NFS_SB(sb); | |
| 461 | + | |
| 462 | + if (atomic_dec_and_test(&server->active)) | |
| 463 | + nfs_deactivate_super_async(sb); | |
| 464 | +} | |
| 465 | +EXPORT_SYMBOL_GPL(nfs_sb_deactive_async); | |
| 466 | + | |
| 418 | 467 | /* |
| 419 | 468 | * Deliver file system statistics to userspace |
| 420 | 469 | */ |
| @@ -771,7 +820,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root) · 350 unmodified lines | ||
| 771 | 820 | int err = 0; |
| 772 | 821 | if (!page) |
| 773 | 822 | return -ENOMEM; |
| 774 | − devname = nfs_path(&dummy, root, page, PAGE_SIZE); | |
| 823 | + devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0); | |
| 775 | 824 | if (IS_ERR(devname)) |
| 776 | 825 | err = PTR_ERR(devname); |
| 777 | 826 | else |
| @@ -95,7 +95,7 @@ static void nfs_async_unlink_release(void *calldata) · 94 unmodified lines | ||
| 95 | 95 | |
| 96 | 96 | nfs_dec_sillycount(data->dir); |
| 97 | 97 | nfs_free_unlinkdata(data); |
| 98 | − nfs_sb_deactive(sb); | |
| 98 | + nfs_sb_deactive_async(sb); | |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | 101 | static void nfs_unlink_prepare(struct rpc_task *task, void *calldata) |
| @@ -21,6 +21,7 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new) · 20 unmodified lines | ||
| 21 | 21 | if ((old->path.mnt == new->path.mnt) && |
| 22 | 22 | (old->path.dentry == new->path.dentry)) |
| 23 | 23 | return true; |
| 24 | + break; | |
| 24 | 25 | case (FSNOTIFY_EVENT_NONE): |
| 25 | 26 | return true; |
| 26 | 27 | default: |
| @@ -873,6 +873,113 @@ static const struct file_operations proc_environ_operations = { · 872 unmodified lines | ||
| 873 | 873 | .release = mem_release, |
| 874 | 874 | }; |
| 875 | 875 | |
| 876 | +static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count, | |
| 877 | + loff_t *ppos) | |
| 878 | +{ | |
| 879 | + struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); | |
| 880 | + char buffer[PROC_NUMBUF]; | |
| 881 | + int oom_adj = OOM_ADJUST_MIN; | |
| 882 | + size_t len; | |
| 883 | + unsigned long flags; | |
| 884 | + | |
| 885 | + if (!task) | |
| 886 | + return -ESRCH; | |
| 887 | + if (lock_task_sighand(task, &flags)) { | |
| 888 | + if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX) | |
| 889 | + oom_adj = OOM_ADJUST_MAX; | |
| 890 | + else | |
| 891 | + oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) / | |
| 892 | + OOM_SCORE_ADJ_MAX; | |
| 893 | + unlock_task_sighand(task, &flags); | |
| 894 | + } | |
| 895 | + put_task_struct(task); | |
| 896 | + len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj); | |
| 897 | + return simple_read_from_buffer(buf, count, ppos, buffer, len); | |
| 898 | +} | |
| 899 | + | |
| 900 | +static ssize_t oom_adj_write(struct file *file, const char __user *buf, | |
| 901 | + size_t count, loff_t *ppos) | |
| 902 | +{ | |
| 903 | + struct task_struct *task; | |
| 904 | + char buffer[PROC_NUMBUF]; | |
| 905 | + int oom_adj; | |
| 906 | + unsigned long flags; | |
| 907 | + int err; | |
| 908 | + | |
| 909 | + memset(buffer, 0, sizeof(buffer)); | |
| 910 | + if (count > sizeof(buffer) - 1) | |
| 911 | + count = sizeof(buffer) - 1; | |
| 912 | + if (copy_from_user(buffer, buf, count)) { | |
| 913 | + err = -EFAULT; | |
| 914 | + goto out; | |
| 915 | + } | |
| 916 | + | |
| 917 | + err = kstrtoint(strstrip(buffer), 0, &oom_adj); | |
| 918 | + if (err) | |
| 919 | + goto out; | |
| 920 | + if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) && | |
| 921 | + oom_adj != OOM_DISABLE) { | |
| 922 | + err = -EINVAL; | |
| 923 | + goto out; | |
| 924 | + } | |
| 925 | + | |
| 926 | + task = get_proc_task(file->f_path.dentry->d_inode); | |
| 927 | + if (!task) { | |
| 928 | + err = -ESRCH; | |
| 929 | + goto out; | |
| 930 | + } | |
| 931 | + | |
| 932 | + task_lock(task); | |
| 933 | + if (!task->mm) { | |
| 934 | + err = -EINVAL; | |
| 935 | + goto err_task_lock; | |
| 936 | + } | |
| 937 | + | |
| 938 | + if (!lock_task_sighand(task, &flags)) { | |
| 939 | + err = -ESRCH; | |
| 940 | + goto err_task_lock; | |
| 941 | + } | |
| 942 | + | |
| 943 | + /* | |
| 944 | + * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum | |
| 945 | + * value is always attainable. | |
| 946 | + */ | |
| 947 | + if (oom_adj == OOM_ADJUST_MAX) | |
| 948 | + oom_adj = OOM_SCORE_ADJ_MAX; | |
| 949 | + else | |
| 950 | + oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE; | |
| 951 | + | |
| 952 | + if (oom_adj < task->signal->oom_score_adj && | |
| 953 | + !capable(CAP_SYS_RESOURCE)) { | |
| 954 | + err = -EACCES; | |
| 955 | + goto err_sighand; | |
| 956 | + } | |
| 957 | + | |
| 958 | + /* | |
| 959 | + * /proc/pid/oom_adj is provided for legacy purposes, ask users to use | |
| 960 | + * /proc/pid/oom_score_adj instead. | |
| 961 | + */ | |
| 962 | + printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n", | |
| 963 | + current->comm, task_pid_nr(current), task_pid_nr(task), | |
| 964 | + task_pid_nr(task)); | |
| 965 | + | |
| 966 | + task->signal->oom_score_adj = oom_adj; | |
| 967 | + trace_oom_score_adj_update(task); | |
| 968 | +err_sighand: | |
| 969 | + unlock_task_sighand(task, &flags); | |
| 970 | +err_task_lock: | |
| 971 | + task_unlock(task); | |
| 972 | + put_task_struct(task); | |
| 973 | +out: | |
| 974 | + return err < 0 ? err : count; | |
| 975 | +} | |
| 976 | + | |
| 977 | +static const struct file_operations proc_oom_adj_operations = { | |
| 978 | + .read = oom_adj_read, | |
| 979 | + .write = oom_adj_write, | |
| 980 | + .llseek = generic_file_llseek, | |
| 981 | +}; | |
| 982 | + | |
| 876 | 983 | static ssize_t oom_score_adj_read(struct file *file, char __user *buf, |
| 877 | 984 | size_t count, loff_t *ppos) |
| 878 | 985 | { |
| @@ -2598,6 +2705,7 @@ static const struct pid_entry tgid_base_stuff[] = { · 1719 unmodified lines | ||
| 2598 | 2705 | REG("cgroup", S_IRUGO, proc_cgroup_operations), |
| 2599 | 2706 | #endif |
| 2600 | 2707 | INF("oom_score", S_IRUGO, proc_oom_score), |
| 2708 | + REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), | |
| 2601 | 2709 | REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), |
| 2602 | 2710 | #ifdef CONFIG_AUDITSYSCALL |
| 2603 | 2711 | REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), |
| @@ -2964,6 +3072,7 @@ static const struct pid_entry tid_base_stuff[] = { · 360 unmodified lines | ||
| 2964 | 3072 | REG("cgroup", S_IRUGO, proc_cgroup_operations), |
| 2965 | 3073 | #endif |
| 2966 | 3074 | INF("oom_score", S_IRUGO, proc_oom_score), |
| 3075 | + REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), | |
| 2967 | 3076 | REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), |
| 2968 | 3077 | #ifdef CONFIG_AUDITSYSCALL |
| 2969 | 3078 | REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), |
| @@ -161,6 +161,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) · 160 unmodified lines | ||
| 161 | 161 | |
| 162 | 162 | while (s < e) { |
| 163 | 163 | unsigned long flags; |
| 164 | + u64 id; | |
| 164 | 165 | |
| 165 | 166 | if (c > psinfo->bufsize) |
| 166 | 167 | c = psinfo->bufsize; |
| @@ -172,7 +173,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) · 5 unmodified lines | ||
| 172 | 173 | spin_lock_irqsave(&psinfo->buf_lock, flags); |
| 173 | 174 | } |
| 174 | 175 | memcpy(psinfo->buf, s, c); |
| 175 | − psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo); | |
| 176 | + psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo); | |
| 176 | 177 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); |
| 177 | 178 | s += c; |
| 178 | 179 | c = e - s; |
| @@ -681,8 +681,16 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c) · 680 unmodified lines | ||
| 681 | 681 | if (!lprops) { |
| 682 | 682 | lprops = ubifs_fast_find_freeable(c); |
| 683 | 683 | if (!lprops) { |
| 684 | − ubifs_assert(c->freeable_cnt == 0); | |
| 685 | − if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { | |
| 684 | + /* | |
| 685 | + * The first condition means the following: go scan the | |
| 686 | + * LPT if there are uncategorized lprops, which means | |
| 687 | + * there may be freeable LEBs there (UBIFS does not | |
| 688 | + * store the information about freeable LEBs in the | |
| 689 | + * master node). | |
| 690 | + */ | |
| 691 | + if (c->in_a_category_cnt != c->main_lebs || | |
| 692 | + c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { | |
| 693 | + ubifs_assert(c->freeable_cnt == 0); | |
| 686 | 694 | lprops = scan_for_leb_for_idx(c); |
| 687 | 695 | if (IS_ERR(lprops)) { |
| 688 | 696 | err = PTR_ERR(lprops); |
| @@ -300,8 +300,11 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, · 299 unmodified lines | ||
| 300 | 300 | default: |
| 301 | 301 | ubifs_assert(0); |
| 302 | 302 | } |
| 303 | + | |
| 303 | 304 | lprops->flags &= ~LPROPS_CAT_MASK; |
| 304 | 305 | lprops->flags |= cat; |
| 306 | + c->in_a_category_cnt += 1; | |
| 307 | + ubifs_assert(c->in_a_category_cnt <= c->main_lebs); | |
| 305 | 308 | } |
| 306 | 309 | |
| 307 | 310 | /** |
| @@ -334,6 +337,9 @@ static void ubifs_remove_from_cat(struct ubifs_info *c, · 26 unmodified lines | ||
| 334 | 337 | default: |
| 335 | 338 | ubifs_assert(0); |
| 336 | 339 | } |
| 340 | + | |
| 341 | + c->in_a_category_cnt -= 1; | |
| 342 | + ubifs_assert(c->in_a_category_cnt >= 0); | |
| 337 | 343 | } |
| 338 | 344 | |
| 339 | 345 | /** |
| @@ -1183,6 +1183,8 @@ struct ubifs_debug_info; · 1182 unmodified lines | ||
| 1183 | 1183 | * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size) |
| 1184 | 1184 | * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size) |
| 1185 | 1185 | * @freeable_cnt: number of freeable LEBs in @freeable_list |
| 1186 | + * @in_a_category_cnt: count of lprops which are in a certain category, which | |
| 1187 | + * basically meants that they were loaded from the flash | |
| 1186 | 1188 | * |
| 1187 | 1189 | * @ltab_lnum: LEB number of LPT's own lprops table |
| 1188 | 1190 | * @ltab_offs: offset of LPT's own lprops table |
| @@ -1412,6 +1414,7 @@ struct ubifs_info { · 223 unmodified lines | ||
| 1412 | 1414 | struct list_head freeable_list; |
| 1413 | 1415 | struct list_head frdi_idx_list; |
| 1414 | 1416 | int freeable_cnt; |
| 1417 | + int in_a_category_cnt; | |
| 1415 | 1418 | |
| 1416 | 1419 | int ltab_lnum; |
| 1417 | 1420 | int ltab_offs; |
| @@ -1866,6 +1866,7 @@ xfs_alloc_fix_freelist( · 1865 unmodified lines | ||
| 1866 | 1866 | /* |
| 1867 | 1867 | * Initialize the args structure. |
| 1868 | 1868 | */ |
| 1869 | + memset(&targs, 0, sizeof(targs)); | |
| 1869 | 1870 | targs.tp = tp; |
| 1870 | 1871 | targs.mp = mp; |
| 1871 | 1872 | targs.agbp = agbp; |
| @@ -2207,7 +2208,7 @@ xfs_alloc_read_agf( · 335 unmodified lines | ||
| 2207 | 2208 | * group or loop over the allocation groups to find the result. |
| 2208 | 2209 | */ |
| 2209 | 2210 | int /* error */ |
| 2210 | −__xfs_alloc_vextent( | |
| 2211 | +xfs_alloc_vextent( | |
| 2211 | 2212 | xfs_alloc_arg_t *args) /* allocation argument structure */ |
| 2212 | 2213 | { |
| 2213 | 2214 | xfs_agblock_t agsize; /* allocation group size */ |
| @@ -2417,46 +2418,6 @@ error0: · 203 unmodified lines | ||
| 2417 | 2418 | return error; |
| 2418 | 2419 | } |
| 2419 | 2420 | |
| 2420 | −static void | |
| 2421 | −xfs_alloc_vextent_worker( | |
| 2422 | − struct work_struct *work) | |
| 2423 | −{ | |
| 2424 | − struct xfs_alloc_arg *args = container_of(work, | |
| 2425 | − struct xfs_alloc_arg, work); | |
| 2426 | − unsigned long pflags; | |
| 2427 | − | |
| 2428 | − /* we are in a transaction context here */ | |
| 2429 | − current_set_flags_nested(&pflags, PF_FSTRANS); | |
| 2430 | − | |
| 2431 | − args->result = __xfs_alloc_vextent(args); | |
| 2432 | − complete(args->done); | |
| 2433 | − | |
| 2434 | − current_restore_flags_nested(&pflags, PF_FSTRANS); | |
| 2435 | −} | |
| 2436 | − | |
| 2437 | −/* | |
| 2438 | − * Data allocation requests often come in with little stack to work on. Push | |
| 2439 | − * them off to a worker thread so there is lots of stack to use. Metadata | |
| 2440 | − * requests, OTOH, are generally from low stack usage paths, so avoid the | |
| 2441 | − * context switch overhead here. | |
| 2442 | − */ | |
| 2443 | −int | |
| 2444 | −xfs_alloc_vextent( | |
| 2445 | − struct xfs_alloc_arg *args) | |
| 2446 | −{ | |
| 2447 | − DECLARE_COMPLETION_ONSTACK(done); | |
| 2448 | − | |
| 2449 | − if (!args->userdata) | |
| 2450 | − return __xfs_alloc_vextent(args); | |
| 2451 | − | |
| 2452 | − | |
| 2453 | − args->done = &done; | |
| 2454 | − INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker); | |
| 2455 | − queue_work(xfs_alloc_wq, &args->work); | |
| 2456 | − wait_for_completion(&done); | |
| 2457 | − return args->result; | |
| 2458 | −} | |
| 2459 | − | |
| 2460 | 2421 | /* |
| 2461 | 2422 | * Free an extent. |
| 2462 | 2423 | * Just break up the extent address and hand off to xfs_free_ag_extent |
| @@ -120,9 +120,6 @@ typedef struct xfs_alloc_arg { · 119 unmodified lines | ||
| 120 | 120 | char isfl; /* set if is freelist blocks - !acctg */ |
| 121 | 121 | char userdata; /* set if this is user data */ |
| 122 | 122 | xfs_fsblock_t firstblock; /* io first block allocated */ |
| 123 | − struct completion *done; | |
| 124 | − struct work_struct work; | |
| 125 | − int result; | |
| 126 | 123 | } xfs_alloc_arg_t; |
| 127 | 124 | |
| 128 | 125 | /* |
| @@ -121,6 +121,8 @@ xfs_allocbt_free_block( · 120 unmodified lines | ||
| 121 | 121 | xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, |
| 122 | 122 | XFS_EXTENT_BUSY_SKIP_DISCARD); |
| 123 | 123 | xfs_trans_agbtree_delta(cur->bc_tp, -1); |
| 124 | + | |
| 125 | + xfs_trans_binval(cur->bc_tp, bp); | |
| 124 | 126 | return 0; |
| 125 | 127 | } |
| 126 | 128 | |
| @@ -2437,6 +2437,7 @@ xfs_bmap_btalloc( · 2436 unmodified lines | ||
| 2437 | 2437 | * Normal allocation, done through xfs_alloc_vextent. |
| 2438 | 2438 | */ |
| 2439 | 2439 | tryagain = isaligned = 0; |
| 2440 | + memset(&args, 0, sizeof(args)); | |
| 2440 | 2441 | args.tp = ap->tp; |
| 2441 | 2442 | args.mp = mp; |
| 2442 | 2443 | args.fsbno = ap->blkno; |
| @@ -3082,6 +3083,7 @@ xfs_bmap_extents_to_btree( · 639 unmodified lines | ||
| 3082 | 3083 | * Convert to a btree with two levels, one record in root. |
| 3083 | 3084 | */ |
| 3084 | 3085 | XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); |
| 3086 | + memset(&args, 0, sizeof(args)); | |
| 3085 | 3087 | args.tp = tp; |
| 3086 | 3088 | args.mp = mp; |
| 3087 | 3089 | args.firstblock = *firstblock; |
| @@ -3237,6 +3239,7 @@ xfs_bmap_local_to_extents( · 149 unmodified lines | ||
| 3237 | 3239 | xfs_buf_t *bp; /* buffer for extent block */ |
| 3238 | 3240 | xfs_bmbt_rec_host_t *ep;/* extent record pointer */ |
| 3239 | 3241 | |
| 3242 | + memset(&args, 0, sizeof(args)); | |
| 3240 | 3243 | args.tp = tp; |
| 3241 | 3244 | args.mp = ip->i_mount; |
| 3242 | 3245 | args.firstblock = *firstblock; |
| @@ -4616,12 +4619,11 @@ xfs_bmapi_delay( · 1373 unmodified lines | ||
| 4616 | 4619 | |
| 4617 | 4620 | |
| 4618 | 4621 | STATIC int |
| 4619 | −xfs_bmapi_allocate( | |
| 4620 | − struct xfs_bmalloca *bma, | |
| 4621 | − int flags) | |
| 4622 | +__xfs_bmapi_allocate( | |
| 4623 | + struct xfs_bmalloca *bma) | |
| 4622 | 4624 | { |
| 4623 | 4625 | struct xfs_mount *mp = bma->ip->i_mount; |
| 4624 | − int whichfork = (flags & XFS_BMAPI_ATTRFORK) ? | |
| 4626 | + int whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ? | |
| 4625 | 4627 | XFS_ATTR_FORK : XFS_DATA_FORK; |
| 4626 | 4628 | struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); |
| 4627 | 4629 | int tmp_logflags = 0; |
| @@ -4654,24 +4656,27 @@ xfs_bmapi_allocate( · 26 unmodified lines | ||
| 4654 | 4656 | * Indicate if this is the first user data in the file, or just any |
| 4655 | 4657 | * user data. |
| 4656 | 4658 | */ |
| 4657 | − if (!(flags & XFS_BMAPI_METADATA)) { | |
| 4659 | + if (!(bma->flags & XFS_BMAPI_METADATA)) { | |
| 4658 | 4660 | bma->userdata = (bma->offset == 0) ? |
| 4659 | 4661 | XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; |
| 4660 | 4662 | } |
| 4661 | 4663 | |
| 4662 | − bma->minlen = (flags & XFS_BMAPI_CONTIG) ? bma->length : 1; | |
| 4664 | + bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; | |
| 4663 | 4665 | |
| 4664 | 4666 | /* |
| 4665 | 4667 | * Only want to do the alignment at the eof if it is userdata and |
| 4666 | 4668 | * allocation length is larger than a stripe unit. |
| 4667 | 4669 | */ |
| 4668 | 4670 | if (mp->m_dalign && bma->length >= mp->m_dalign && |
| 4669 | − !(flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { | |
| 4671 | + !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { | |
| 4670 | 4672 | error = xfs_bmap_isaeof(bma, whichfork); |
| 4671 | 4673 | if (error) |
| 4672 | 4674 | return error; |
| 4673 | 4675 | } |
| 4674 | 4676 | |
| 4677 | + if (bma->flags & XFS_BMAPI_STACK_SWITCH) | |
| 4678 | + bma->stack_switch = 1; | |
| 4679 | + | |
| 4675 | 4680 | error = xfs_bmap_alloc(bma); |
| 4676 | 4681 | if (error) |
| 4677 | 4682 | return error; |
| @@ -4706,7 +4711,7 @@ xfs_bmapi_allocate( · 28 unmodified lines | ||
| 4706 | 4711 | * A wasdelay extent has been initialized, so shouldn't be flagged |
| 4707 | 4712 | * as unwritten. |
| 4708 | 4713 | */ |
| 4709 | − if (!bma->wasdel && (flags & XFS_BMAPI_PREALLOC) && | |
| 4714 | + if (!bma->wasdel && (bma->flags & XFS_BMAPI_PREALLOC) && | |
| 4710 | 4715 | xfs_sb_version_hasextflgbit(&mp->m_sb)) |
| 4711 | 4716 | bma->got.br_state = XFS_EXT_UNWRITTEN; |
| 4712 | 4717 | |
| @@ -4734,6 +4739,45 @@ xfs_bmapi_allocate( · 21 unmodified lines | ||
| 4734 | 4739 | return 0; |
| 4735 | 4740 | } |
| 4736 | 4741 | |
| 4742 | +static void | |
| 4743 | +xfs_bmapi_allocate_worker( | |
| 4744 | + struct work_struct *work) | |
| 4745 | +{ | |
| 4746 | + struct xfs_bmalloca *args = container_of(work, | |
| 4747 | + struct xfs_bmalloca, work); | |
| 4748 | + unsigned long pflags; | |
| 4749 | + | |
| 4750 | + /* we are in a transaction context here */ | |
| 4751 | + current_set_flags_nested(&pflags, PF_FSTRANS); | |
| 4752 | + | |
| 4753 | + args->result = __xfs_bmapi_allocate(args); | |
| 4754 | + complete(args->done); | |
| 4755 | + | |
| 4756 | + current_restore_flags_nested(&pflags, PF_FSTRANS); | |
| 4757 | +} | |
| 4758 | + | |
| 4759 | +/* | |
| 4760 | + * Some allocation requests often come in with little stack to work on. Push | |
| 4761 | + * them off to a worker thread so there is lots of stack to use. Otherwise just | |
| 4762 | + * call directly to avoid the context switch overhead here. | |
| 4763 | + */ | |
| 4764 | +int | |
| 4765 | +xfs_bmapi_allocate( | |
| 4766 | + struct xfs_bmalloca *args) | |
| 4767 | +{ | |
| 4768 | + DECLARE_COMPLETION_ONSTACK(done); | |
| 4769 | + | |
| 4770 | + if (!args->stack_switch) | |
| 4771 | + return __xfs_bmapi_allocate(args); | |
| 4772 | + | |
| 4773 | + | |
| 4774 | + args->done = &done; | |
| 4775 | + INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker); | |
| 4776 | + queue_work(xfs_alloc_wq, &args->work); | |
| 4777 | + wait_for_completion(&done); | |
| 4778 | + return args->result; | |
| 4779 | +} | |
| 4780 | + | |
| 4737 | 4781 | STATIC int |
| 4738 | 4782 | xfs_bmapi_convert_unwritten( |
| 4739 | 4783 | struct xfs_bmalloca *bma, |
| @@ -4919,6 +4963,7 @@ xfs_bmapi_write( · 179 unmodified lines | ||
| 4919 | 4963 | bma.conv = !!(flags & XFS_BMAPI_CONVERT); |
| 4920 | 4964 | bma.wasdel = wasdelay; |
| 4921 | 4965 | bma.offset = bno; |
| 4966 | + bma.flags = flags; | |
| 4922 | 4967 | |
| 4923 | 4968 | /* |
| 4924 | 4969 | * There's a 32/64 bit type mismatch between the |
| @@ -4934,7 +4979,7 @@ xfs_bmapi_write( · 9 unmodified lines | ||
| 4934 | 4979 | |
| 4935 | 4980 | ASSERT(len > 0); |
| 4936 | 4981 | ASSERT(bma.length > 0); |
| 4937 | − error = xfs_bmapi_allocate(&bma, flags); | |
| 4982 | + error = xfs_bmapi_allocate(&bma); | |
| 4938 | 4983 | if (error) |
| 4939 | 4984 | goto error0; |
| 4940 | 4985 | if (bma.blkno == NULLFSBLOCK) |
| @@ -77,6 +77,7 @@ typedef struct xfs_bmap_free · 76 unmodified lines | ||
| 77 | 77 | * from written to unwritten, otherwise convert from unwritten to written. |
| 78 | 78 | */ |
| 79 | 79 | #define XFS_BMAPI_CONVERT 0x040 |
| 80 | +#define XFS_BMAPI_STACK_SWITCH 0x080 | |
| 80 | 81 | |
| 81 | 82 | #define XFS_BMAPI_FLAGS \ |
| 82 | 83 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ |
| @@ -85,7 +86,8 @@ typedef struct xfs_bmap_free · 2 unmodified lines | ||
| 85 | 86 | { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ |
| 86 | 87 | { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ |
| 87 | 88 | { XFS_BMAPI_CONTIG, "CONTIG" }, \ |
| 88 | − { XFS_BMAPI_CONVERT, "CONVERT" } | |
| 89 | + { XFS_BMAPI_CONVERT, "CONVERT" }, \ | |
| 90 | + { XFS_BMAPI_STACK_SWITCH, "STACK_SWITCH" } | |
| 89 | 91 | |
| 90 | 92 | |
| 91 | 93 | static inline int xfs_bmapi_aflag(int w) |
| @@ -133,6 +135,11 @@ typedef struct xfs_bmalloca { · 41 unmodified lines | ||
| 133 | 135 | char userdata;/* set if is user data */ |
| 134 | 136 | char aeof; /* allocated space at eof */ |
| 135 | 137 | char conv; /* overwriting unwritten extents */ |
| 138 | + char stack_switch; | |
| 139 | + int flags; | |
| 140 | + struct completion *done; | |
| 141 | + struct work_struct work; | |
| 142 | + int result; | |
| 136 | 143 | } xfs_bmalloca_t; |
| 137 | 144 | |
| 138 | 145 | /* |
| @@ -526,7 +526,25 @@ xfs_buf_item_unpin( · 525 unmodified lines | ||
| 526 | 526 | } |
| 527 | 527 | xfs_buf_relse(bp); |
| 528 | 528 | } else if (freed && remove) { |
| 529 | + /* | |
| 530 | + * There are currently two references to the buffer - the active | |
| 531 | + * LRU reference and the buf log item. What we are about to do | |
| 532 | + * here - simulate a failed IO completion - requires 3 | |
| 533 | + * references. | |
| 534 | + * | |
| 535 | + * The LRU reference is removed by the xfs_buf_stale() call. The | |
| 536 | + * buf item reference is removed by the xfs_buf_iodone() | |
| 537 | + * callback that is run by xfs_buf_do_callbacks() during ioend | |
| 538 | + * processing (via the bp->b_iodone callback), and then finally | |
| 539 | + * the ioend processing will drop the IO reference if the buffer | |
| 540 | + * is marked XBF_ASYNC. | |
| 541 | + * | |
| 542 | + * Hence we need to take an additional reference here so that IO | |
| 543 | + * completion processing doesn't free the buffer prematurely. | |
| 544 | + */ | |
| 529 | 545 | xfs_buf_lock(bp); |
| 546 | + xfs_buf_hold(bp); | |
| 547 | + bp->b_flags |= XBF_ASYNC; | |
| 530 | 548 | xfs_buf_ioerror(bp, EIO); |
| 531 | 549 | XFS_BUF_UNDONE(bp); |
| 532 | 550 | xfs_buf_stale(bp); |
| @@ -399,9 +399,26 @@ xfs_growfs_data_private( · 398 unmodified lines | ||
| 399 | 399 | |
| 400 | 400 | /* update secondary superblocks. */ |
| 401 | 401 | for (agno = 1; agno < nagcount; agno++) { |
| 402 | − error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, | |
| 402 | + error = 0; | |
| 403 | + /* | |
| 404 | + * new secondary superblocks need to be zeroed, not read from | |
| 405 | + * disk as the contents of the new area we are growing into is | |
| 406 | + * completely unknown. | |
| 407 | + */ | |
| 408 | + if (agno < oagcount) { | |
| 409 | + error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, | |
| 403 | 410 | XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), |
| 404 | 411 | XFS_FSS_TO_BB(mp, 1), 0, &bp); |
| 412 | + } else { | |
| 413 | + bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp, | |
| 414 | + XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), | |
| 415 | + XFS_FSS_TO_BB(mp, 1), 0); | |
| 416 | + if (bp) | |
| 417 | + xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); | |
| 418 | + else | |
| 419 | + error = ENOMEM; | |
| 420 | + } | |
| 421 | + | |
| 405 | 422 | if (error) { |
| 406 | 423 | xfs_warn(mp, |
| 407 | 424 | "error %d reading secondary superblock for ag %d", |
| @@ -423,7 +440,7 @@ xfs_growfs_data_private( · 15 unmodified lines | ||
| 423 | 440 | break; /* no point in continuing */ |
| 424 | 441 | } |
| 425 | 442 | } |
| 426 | − return 0; | |
| 443 | + return error; | |
| 427 | 444 | |
| 428 | 445 | error0: |
| 429 | 446 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); |
| @@ -250,6 +250,7 @@ xfs_ialloc_ag_alloc( · 249 unmodified lines | ||
| 250 | 250 | /* boundary */ |
| 251 | 251 | struct xfs_perag *pag; |
| 252 | 252 | |
| 253 | + memset(&args, 0, sizeof(args)); | |
| 253 | 254 | args.tp = tp; |
| 254 | 255 | args.mp = tp->t_mountp; |
| 255 | 256 | |
| @@ -1509,7 +1509,8 @@ xfs_ifree_cluster( · 1508 unmodified lines | ||
| 1509 | 1509 | * to mark all the active inodes on the buffer stale. |
| 1510 | 1510 | */ |
| 1511 | 1511 | bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, |
| 1512 | − mp->m_bsize * blks_per_cluster, 0); | |
| 1512 | + mp->m_bsize * blks_per_cluster, | |
| 1513 | + XBF_UNMAPPED); | |
| 1513 | 1514 | |
| 1514 | 1515 | if (!bp) |
| 1515 | 1516 | return ENOMEM; |
| @@ -70,7 +70,7 @@ xfs_find_handle( · 69 unmodified lines | ||
| 70 | 70 | int hsize; |
| 71 | 71 | xfs_handle_t handle; |
| 72 | 72 | struct inode *inode; |
| 73 | − struct fd f; | |
| 73 | + struct fd f = {0}; | |
| 74 | 74 | struct path path; |
| 75 | 75 | int error; |
| 76 | 76 | struct xfs_inode *ip; |
| @@ -584,7 +584,9 @@ xfs_iomap_write_allocate( · 583 unmodified lines | ||
| 584 | 584 | * pointer that the caller gave to us. |
| 585 | 585 | */ |
| 586 | 586 | error = xfs_bmapi_write(tp, ip, map_start_fsb, |
| 587 | − count_fsb, 0, &first_block, 1, | |
| 587 | + count_fsb, | |
| 588 | + XFS_BMAPI_STACK_SWITCH, | |
| 589 | + &first_block, 1, | |
| 588 | 590 | imap, &nimaps, &free_list); |
| 589 | 591 | if (error) |
| 590 | 592 | goto trans_cancel; |
| @@ -2387,14 +2387,27 @@ xlog_state_do_callback( · 2386 unmodified lines | ||
| 2387 | 2387 | |
| 2388 | 2388 | |
| 2389 | 2389 | /* |
| 2390 | − * update the last_sync_lsn before we drop the | |
| 2390 | + * Completion of a iclog IO does not imply that | |
| 2391 | + * a transaction has completed, as transactions | |
| 2392 | + * can be large enough to span many iclogs. We | |
| 2393 | + * cannot change the tail of the log half way | |
| 2394 | + * through a transaction as this may be the only | |
| 2395 | + * transaction in the log and moving th etail to | |
| 2396 | + * point to the middle of it will prevent | |
| 2397 | + * recovery from finding the start of the | |
| 2398 | + * transaction. Hence we should only update the | |
| 2399 | + * last_sync_lsn if this iclog contains | |
| 2400 | + * transaction completion callbacks on it. | |
| 2401 | + * | |
| 2402 | + * We have to do this before we drop the | |
| 2391 | 2403 | * icloglock to ensure we are the only one that |
| 2392 | 2404 | * can update it. |
| 2393 | 2405 | */ |
| 2394 | 2406 | ASSERT(XFS_LSN_CMP(atomic64_read(&log->l_last_sync_lsn), |
| 2395 | 2407 | be64_to_cpu(iclog->ic_header.h_lsn)) <= 0); |
| 2396 | − atomic64_set(&log->l_last_sync_lsn, | |
| 2397 | − be64_to_cpu(iclog->ic_header.h_lsn)); | |
| 2408 | + if (iclog->ic_callback) | |
| 2409 | + atomic64_set(&log->l_last_sync_lsn, | |
| 2410 | + be64_to_cpu(iclog->ic_header.h_lsn)); | |
| 2398 | 2411 | |
| 2399 | 2412 | } else |
| 2400 | 2413 | ioerrors++; |
| @@ -3541,7 +3541,7 @@ xlog_do_recovery_pass( · 3540 unmodified lines | ||
| 3541 | 3541 | * - order is important. |
| 3542 | 3542 | */ |
| 3543 | 3543 | error = xlog_bread_offset(log, 0, |
| 3544 | − bblks - split_bblks, hbp, | |
| 3544 | + bblks - split_bblks, dbp, | |
| 3545 | 3545 | offset + BBTOB(split_bblks)); |
| 3546 | 3546 | if (error) |
| 3547 | 3547 | goto bread_err2; |
| @@ -335,8 +335,8 @@ const char *__clk_get_name(struct clk *clk); · 334 unmodified lines | ||
| 335 | 335 | struct clk_hw *__clk_get_hw(struct clk *clk); |
| 336 | 336 | u8 __clk_get_num_parents(struct clk *clk); |
| 337 | 337 | struct clk *__clk_get_parent(struct clk *clk); |
| 338 | −inline int __clk_get_enable_count(struct clk *clk); | |
| 339 | −inline int __clk_get_prepare_count(struct clk *clk); | |
| 338 | +int __clk_get_enable_count(struct clk *clk); | |
| 339 | +int __clk_get_prepare_count(struct clk *clk); | |
| 340 | 340 | unsigned long __clk_get_rate(struct clk *clk); |
| 341 | 341 | unsigned long __clk_get_flags(struct clk *clk); |
| 342 | 342 | int __clk_is_enabled(struct clk *clk); |
| @@ -1684,9 +1684,5 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; } · 1683 unmodified lines | ||
| 1684 | 1684 | static inline bool page_is_guard(struct page *page) { return false; } |
| 1685 | 1685 | #endif /* CONFIG_DEBUG_PAGEALLOC */ |
| 1686 | 1686 | |
| 1687 | −extern void reset_zone_present_pages(void); | |
| 1688 | −extern void fixup_zone_present_pages(int nid, unsigned long start_pfn, | |
| 1689 | − unsigned long end_pfn); | |
| 1690 | − | |
| 1691 | 1687 | #endif /* __KERNEL__ */ |
| 1692 | 1688 | #endif /* _LINUX_MM_H */ |
| @@ -137,7 +137,7 @@ struct dw_mci { · 136 unmodified lines | ||
| 137 | 137 | |
| 138 | 138 | dma_addr_t sg_dma; |
| 139 | 139 | void *sg_cpu; |
| 140 | − struct dw_mci_dma_ops *dma_ops; | |
| 140 | + const struct dw_mci_dma_ops *dma_ops; | |
| 141 | 141 | #ifdef CONFIG_MMC_DW_IDMAC |
| 142 | 142 | unsigned int ring_size; |
| 143 | 143 | #else |
| @@ -162,7 +162,7 @@ struct dw_mci { · 18 unmodified lines | ||
| 162 | 162 | u16 data_offset; |
| 163 | 163 | struct device *dev; |
| 164 | 164 | struct dw_mci_board *pdata; |
| 165 | − struct dw_mci_drv_data *drv_data; | |
| 165 | + const struct dw_mci_drv_data *drv_data; | |
| 166 | 166 | void *priv; |
| 167 | 167 | struct clk *biu_clk; |
| 168 | 168 | struct clk *ciu_clk; |
| @@ -186,7 +186,7 @@ struct dw_mci { · 17 unmodified lines | ||
| 186 | 186 | |
| 187 | 187 | struct regulator *vmmc; /* Power regulator */ |
| 188 | 188 | unsigned long irq_flags; /* IRQ flags */ |
| 189 | − unsigned int irq; | |
| 189 | + int irq; | |
| 190 | 190 | }; |
| 191 | 191 | |
| 192 | 192 | /* DMA ops for Internal/External DMAC interface */ |
| @@ -91,6 +91,7 @@ struct sdhci_host { · 90 unmodified lines | ||
| 91 | 91 | unsigned int quirks2; /* More deviations from spec. */ |
| 92 | 92 | |
| 93 | 93 | #define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0) |
| 94 | +#define SDHCI_QUIRK2_HOST_NO_CMD23 (1<<1) | |
| 94 | 95 | |
| 95 | 96 | int irq; /* Device IRQ */ |
| 96 | 97 | void __iomem *ioaddr; /* Mapped address */ |
| @@ -752,7 +752,7 @@ extern int init_currently_empty_zone(struct zone *zone, unsigned long start_pfn, · 751 unmodified lines | ||
| 752 | 752 | unsigned long size, |
| 753 | 753 | enum memmap_context context); |
| 754 | 754 | |
| 755 | −extern void lruvec_init(struct lruvec *lruvec, struct zone *zone); | |
| 755 | +extern void lruvec_init(struct lruvec *lruvec); | |
| 756 | 756 | |
| 757 | 757 | static inline struct zone *lruvec_zone(struct lruvec *lruvec) |
| 758 | 758 | { |
| @@ -28,11 +28,13 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } · 27 unmodified lines | ||
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | 30 | #else /* CONFIG_OF_ADDRESS */ |
| 31 | +#ifndef of_address_to_resource | |
| 31 | 32 | static inline int of_address_to_resource(struct device_node *dev, int index, |
| 32 | 33 | struct resource *r) |
| 33 | 34 | { |
| 34 | 35 | return -EINVAL; |
| 35 | 36 | } |
| 37 | +#endif | |
| 36 | 38 | static inline struct device_node *of_find_matching_node_by_address( |
| 37 | 39 | struct device_node *from, |
| 38 | 40 | const struct of_device_id *matches, |
| @@ -0,0 +1,31 @@ | ||
| 1 | +/* | |
| 2 | + * omap_ocp2scp.h -- ocp2scp header file | |
| 3 | + * | |
| 4 | + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License as published by | |
| 7 | + * the Free Software Foundation; either version 2 of the License, or | |
| 8 | + * (at your option) any later version. | |
| 9 | + * | |
| 10 | + * Author: Kishon Vijay Abraham I <kishon@ti.com> | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + */ | |
| 18 | + | |
| 19 | +#ifndef __DRIVERS_OMAP_OCP2SCP_H | |
| 20 | +#define __DRIVERS_OMAP_OCP2SCP_H | |
| 21 | + | |
| 22 | +struct omap_ocp2scp_dev { | |
| 23 | + const char *drv_name; | |
| 24 | + struct resource *res; | |
| 25 | +}; | |
| 26 | + | |
| 27 | +struct omap_ocp2scp_platform_data { | |
| 28 | + int dev_cnt; | |
| 29 | + struct omap_ocp2scp_dev **devices; | |
| 30 | +}; | |
| 31 | +#endif /* __DRIVERS_OMAP_OCP2SCP_H */ | |
| @@ -275,9 +275,11 @@ struct rio_id_table { · 274 unmodified lines | ||
| 275 | 275 | * struct rio_net - RIO network info |
| 276 | 276 | * @node: Node in global list of RIO networks |
| 277 | 277 | * @devices: List of devices in this network |
| 278 | + * @switches: List of switches in this netowrk | |
| 278 | 279 | * @mports: List of master ports accessing this network |
| 279 | 280 | * @hport: Default port for accessing this network |
| 280 | 281 | * @id: RIO network ID |
| 282 | + * @destid_table: destID allocation table | |
| 281 | 283 | */ |
| 282 | 284 | struct rio_net { |
| 283 | 285 | struct list_head node; /* node in list of networks */ |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | ||
| 25 | 25 | #define EPOLL_CTL_ADD 1 |
| 26 | 26 | #define EPOLL_CTL_DEL 2 |
| 27 | 27 | #define EPOLL_CTL_MOD 3 |
| 28 | −#define EPOLL_CTL_DISABLE 4 | |
| 29 | 28 | |
| 30 | 29 | /* |
| 31 | 30 | * Request the handling of system wakeup events so as to prevent system suspends |
| @@ -8,4 +8,13 @@ · 7 unmodified lines | ||
| 8 | 8 | #define OOM_SCORE_ADJ_MIN (-1000) |
| 9 | 9 | #define OOM_SCORE_ADJ_MAX 1000 |
| 10 | 10 | |
| 11 | +/* | |
| 12 | + * /proc/<pid>/oom_adj set to -17 protects from the oom killer for legacy | |
| 13 | + * purposes. | |
| 14 | + */ | |
| 15 | +#define OOM_DISABLE (-17) | |
| 16 | +/* inclusive */ | |
| 17 | +#define OOM_ADJUST_MIN (-16) | |
| 18 | +#define OOM_ADJUST_MAX 15 | |
| 19 | + | |
| 11 | 20 | #endif /* _UAPI__INCLUDE_LINUX_OOM_H */ |
| @@ -5,6 +5,36 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <xen/interface/hvm/params.h> |
| 6 | 6 | #include <asm/xen/hypercall.h> |
| 7 | 7 | |
| 8 | +static const char *param_name(int op) | |
| 9 | +{ | |
| 10 | +#define PARAM(x) [HVM_PARAM_##x] = #x | |
| 11 | + static const char *const names[] = { | |
| 12 | + PARAM(CALLBACK_IRQ), | |
| 13 | + PARAM(STORE_PFN), | |
| 14 | + PARAM(STORE_EVTCHN), | |
| 15 | + PARAM(PAE_ENABLED), | |
| 16 | + PARAM(IOREQ_PFN), | |
| 17 | + PARAM(BUFIOREQ_PFN), | |
| 18 | + PARAM(TIMER_MODE), | |
| 19 | + PARAM(HPET_ENABLED), | |
| 20 | + PARAM(IDENT_PT), | |
| 21 | + PARAM(DM_DOMAIN), | |
| 22 | + PARAM(ACPI_S_STATE), | |
| 23 | + PARAM(VM86_TSS), | |
| 24 | + PARAM(VPT_ALIGN), | |
| 25 | + PARAM(CONSOLE_PFN), | |
| 26 | + PARAM(CONSOLE_EVTCHN), | |
| 27 | + }; | |
| 28 | +#undef PARAM | |
| 29 | + | |
| 30 | + if (op >= ARRAY_SIZE(names)) | |
| 31 | + return "unknown"; | |
| 32 | + | |
| 33 | + if (!names[op]) | |
| 34 | + return "reserved"; | |
| 35 | + | |
| 36 | + return names[op]; | |
| 37 | +} | |
| 8 | 38 | static inline int hvm_get_parameter(int idx, uint64_t *value) |
| 9 | 39 | { |
| 10 | 40 | struct xen_hvm_param xhv; |
| @@ -14,8 +44,8 @@ static inline int hvm_get_parameter(int idx, uint64_t *value) · 3 unmodified lines | ||
| 14 | 44 | xhv.index = idx; |
| 15 | 45 | r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); |
| 16 | 46 | if (r < 0) { |
| 17 | − printk(KERN_ERR "Cannot get hvm parameter %d: %d!\n", | |
| 18 | − idx, r); | |
| 47 | + printk(KERN_ERR "Cannot get hvm parameter %s (%d): %d!\n", | |
| 48 | + param_name(idx), idx, r); | |
| 19 | 49 | return r; |
| 20 | 50 | } |
| 21 | 51 | *value = xhv.value; |
| @@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, · 715 unmodified lines | ||
| 716 | 716 | struct futex_pi_state **ps, |
| 717 | 717 | struct task_struct *task, int set_waiters) |
| 718 | 718 | { |
| 719 | − int lock_taken, ret, ownerdied = 0; | |
| 719 | + int lock_taken, ret, force_take = 0; | |
| 720 | 720 | u32 uval, newval, curval, vpid = task_pid_vnr(task); |
| 721 | 721 | |
| 722 | 722 | retry: |
| @@ -755,17 +755,15 @@ retry: · 32 unmodified lines | ||
| 755 | 755 | newval = curval | FUTEX_WAITERS; |
| 756 | 756 | |
| 757 | 757 | /* |
| 758 | − * There are two cases, where a futex might have no owner (the | |
| 759 | − * owner TID is 0): OWNER_DIED. We take over the futex in this | |
| 760 | − * case. We also do an unconditional take over, when the owner | |
| 761 | − * of the futex died. | |
| 762 | − * | |
| 763 | − * This is safe as we are protected by the hash bucket lock ! | |
| 758 | + * Should we force take the futex? See below. | |
| 764 | 759 | */ |
| 765 | − if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { | |
| 766 | − /* Keep the OWNER_DIED bit */ | |
| 760 | + if (unlikely(force_take)) { | |
| 761 | + /* | |
| 762 | + * Keep the OWNER_DIED and the WAITERS bit and set the | |
| 763 | + * new TID value. | |
| 764 | + */ | |
| 767 | 765 | newval = (curval & ~FUTEX_TID_MASK) | vpid; |
| 768 | − ownerdied = 0; | |
| 766 | + force_take = 0; | |
| 769 | 767 | lock_taken = 1; |
| 770 | 768 | } |
| 771 | 769 | |
| @@ -775,7 +773,7 @@ retry: · 3 unmodified lines | ||
| 775 | 773 | goto retry; |
| 776 | 774 | |
| 777 | 775 | /* |
| 778 | − * We took the lock due to owner died take over. | |
| 776 | + * We took the lock due to forced take over. | |
| 779 | 777 | */ |
| 780 | 778 | if (unlikely(lock_taken)) |
| 781 | 779 | return 1; |
| @@ -790,20 +788,25 @@ retry: · 8 unmodified lines | ||
| 790 | 788 | switch (ret) { |
| 791 | 789 | case -ESRCH: |
| 792 | 790 | /* |
| 793 | − * No owner found for this futex. Check if the | |
| 794 | − * OWNER_DIED bit is set to figure out whether | |
| 795 | − * this is a robust futex or not. | |
| 791 | + * We failed to find an owner for this | |
| 792 | + * futex. So we have no pi_state to block | |
| 793 | + * on. This can happen in two cases: | |
| 794 | + * | |
| 795 | + * 1) The owner died | |
| 796 | + * 2) A stale FUTEX_WAITERS bit | |
| 797 | + * | |
| 798 | + * Re-read the futex value. | |
| 796 | 799 | */ |
| 797 | 800 | if (get_futex_value_locked(&curval, uaddr)) |
| 798 | 801 | return -EFAULT; |
| 799 | 802 | |
| 800 | 803 | /* |
| 801 | − * We simply start over in case of a robust | |
| 802 | − * futex. The code above will take the futex | |
| 803 | − * and return happy. | |
| 804 | + * If the owner died or we have a stale | |
| 805 | + * WAITERS bit the owner TID in the user space | |
| 806 | + * futex is 0. | |
| 804 | 807 | */ |
| 805 | − if (curval & FUTEX_OWNER_DIED) { | |
| 806 | − ownerdied = 1; | |
| 808 | + if (!(curval & FUTEX_TID_MASK)) { | |
| 809 | + force_take = 1; | |
| 807 | 810 | goto retry; |
| 808 | 811 | } |
| 809 | 812 | default: |
| @@ -2293,12 +2293,17 @@ static void layout_symtab(struct module *mod, struct load_info *info) · 2292 unmodified lines | ||
| 2293 | 2293 | src = (void *)info->hdr + symsect->sh_offset; |
| 2294 | 2294 | nsrc = symsect->sh_size / sizeof(*src); |
| 2295 | 2295 | |
| 2296 | + /* strtab always starts with a nul, so offset 0 is the empty string. */ | |
| 2297 | + strtab_size = 1; | |
| 2298 | + | |
| 2296 | 2299 | /* Compute total space required for the core symbols' strtab. */ |
| 2297 | − for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src) | |
| 2298 | − if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) { | |
| 2299 | − strtab_size += strlen(&info->strtab[src->st_name]) + 1; | |
| 2300 | + for (ndst = i = 0; i < nsrc; i++) { | |
| 2301 | + if (i == 0 || | |
| 2302 | + is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { | |
| 2303 | + strtab_size += strlen(&info->strtab[src[i].st_name])+1; | |
| 2300 | 2304 | ndst++; |
| 2301 | 2305 | } |
| 2306 | + } | |
| 2302 | 2307 | |
| 2303 | 2308 | /* Append room for core symbols at end of core part. */ |
| 2304 | 2309 | info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); |
| @@ -2332,15 +2337,15 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) · 27 unmodified lines | ||
| 2332 | 2337 | mod->core_symtab = dst = mod->module_core + info->symoffs; |
| 2333 | 2338 | mod->core_strtab = s = mod->module_core + info->stroffs; |
| 2334 | 2339 | src = mod->symtab; |
| 2335 | − *dst = *src; | |
| 2336 | 2340 | *s++ = 0; |
| 2337 | − for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { | |
| 2338 | − if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) | |
| 2339 | − continue; | |
| 2340 | − | |
| 2341 | − dst[ndst] = *src; | |
| 2342 | − dst[ndst++].st_name = s - mod->core_strtab; | |
| 2343 | − s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1; | |
| 2341 | + for (ndst = i = 0; i < mod->num_symtab; i++) { | |
| 2342 | + if (i == 0 || | |
| 2343 | + is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { | |
| 2344 | + dst[ndst] = src[i]; | |
| 2345 | + dst[ndst++].st_name = s - mod->core_strtab; | |
| 2346 | + s += strlcpy(s, &mod->strtab[src[i].st_name], | |
| 2347 | + KSYM_NAME_LEN) + 1; | |
| 2348 | + } | |
| 2344 | 2349 | } |
| 2345 | 2350 | mod->core_num_syms = ndst; |
| 2346 | 2351 | } |
| @@ -198,8 +198,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) · 197 unmodified lines | ||
| 198 | 198 | int order = ilog2(BITS_PER_LONG); |
| 199 | 199 | |
| 200 | 200 | __free_pages_bootmem(pfn_to_page(start), order); |
| 201 | − fixup_zone_present_pages(page_to_nid(pfn_to_page(start)), | |
| 202 | − start, start + BITS_PER_LONG); | |
| 203 | 201 | count += BITS_PER_LONG; |
| 204 | 202 | start += BITS_PER_LONG; |
| 205 | 203 | } else { |
| @@ -210,9 +208,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) · 4 unmodified lines | ||
| 210 | 208 | if (vec & 1) { |
| 211 | 209 | page = pfn_to_page(start + off); |
| 212 | 210 | __free_pages_bootmem(page, 0); |
| 213 | − fixup_zone_present_pages( | |
| 214 | − page_to_nid(page), | |
| 215 | − start + off, start + off + 1); | |
| 216 | 211 | count++; |
| 217 | 212 | } |
| 218 | 213 | vec >>= 1; |
| @@ -226,11 +221,8 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) · 7 unmodified lines | ||
| 226 | 221 | pages = bdata->node_low_pfn - bdata->node_min_pfn; |
| 227 | 222 | pages = bootmem_bootmap_pages(pages); |
| 228 | 223 | count += pages; |
| 229 | − while (pages--) { | |
| 230 | − fixup_zone_present_pages(page_to_nid(page), | |
| 231 | − page_to_pfn(page), page_to_pfn(page) + 1); | |
| 224 | + while (pages--) | |
| 232 | 225 | __free_pages_bootmem(page++, 0); |
| 233 | − } | |
| 234 | 226 | |
| 235 | 227 | bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count); |
| 236 | 228 | |
| @@ -98,7 +98,7 @@ struct page *kmap_to_page(void *vaddr) · 97 unmodified lines | ||
| 98 | 98 | { |
| 99 | 99 | unsigned long addr = (unsigned long)vaddr; |
| 100 | 100 | |
| 101 | − if (addr >= PKMAP_ADDR(0) && addr <= PKMAP_ADDR(LAST_PKMAP)) { | |
| 101 | + if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) { | |
| 102 | 102 | int i = (addr - PKMAP_ADDR(0)) >> PAGE_SHIFT; |
| 103 | 103 | return pte_page(pkmap_page_table[i]); |
| 104 | 104 | } |
| @@ -1055,12 +1055,24 @@ struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone, · 1054 unmodified lines | ||
| 1055 | 1055 | struct mem_cgroup *memcg) |
| 1056 | 1056 | { |
| 1057 | 1057 | struct mem_cgroup_per_zone *mz; |
| 1058 | + struct lruvec *lruvec; | |
| 1058 | 1059 | |
| 1059 | − if (mem_cgroup_disabled()) | |
| 1060 | − return &zone->lruvec; | |
| 1060 | + if (mem_cgroup_disabled()) { | |
| 1061 | + lruvec = &zone->lruvec; | |
| 1062 | + goto out; | |
| 1063 | + } | |
| 1061 | 1064 | |
| 1062 | 1065 | mz = mem_cgroup_zoneinfo(memcg, zone_to_nid(zone), zone_idx(zone)); |
| 1063 | − return &mz->lruvec; | |
| 1066 | + lruvec = &mz->lruvec; | |
| 1067 | +out: | |
| 1068 | + /* | |
| 1069 | + * Since a node can be onlined after the mem_cgroup was created, | |
| 1070 | + * we have to be prepared to initialize lruvec->zone here; | |
| 1071 | + * and if offlined then reonlined, we need to reinitialize it. | |
| 1072 | + */ | |
| 1073 | + if (unlikely(lruvec->zone != zone)) | |
| 1074 | + lruvec->zone = zone; | |
| 1075 | + return lruvec; | |
| 1064 | 1076 | } |
| 1065 | 1077 | |
| 1066 | 1078 | /* |
| @@ -1087,9 +1099,12 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone) · 20 unmodified lines | ||
| 1087 | 1099 | struct mem_cgroup_per_zone *mz; |
| 1088 | 1100 | struct mem_cgroup *memcg; |
| 1089 | 1101 | struct page_cgroup *pc; |
| 1102 | + struct lruvec *lruvec; | |
| 1090 | 1103 | |
| 1091 | − if (mem_cgroup_disabled()) | |
| 1092 | − return &zone->lruvec; | |
| 1104 | + if (mem_cgroup_disabled()) { | |
| 1105 | + lruvec = &zone->lruvec; | |
| 1106 | + goto out; | |
| 1107 | + } | |
| 1093 | 1108 | |
| 1094 | 1109 | pc = lookup_page_cgroup(page); |
| 1095 | 1110 | memcg = pc->mem_cgroup; |
| @@ -1107,7 +1122,16 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone) · 11 unmodified lines | ||
| 1107 | 1122 | pc->mem_cgroup = memcg = root_mem_cgroup; |
| 1108 | 1123 | |
| 1109 | 1124 | mz = page_cgroup_zoneinfo(memcg, page); |
| 1110 | − return &mz->lruvec; | |
| 1125 | + lruvec = &mz->lruvec; | |
| 1126 | +out: | |
| 1127 | + /* | |
| 1128 | + * Since a node can be onlined after the mem_cgroup was created, | |
| 1129 | + * we have to be prepared to initialize lruvec->zone here; | |
| 1130 | + * and if offlined then reonlined, we need to reinitialize it. | |
| 1131 | + */ | |
| 1132 | + if (unlikely(lruvec->zone != zone)) | |
| 1133 | + lruvec->zone = zone; | |
| 1134 | + return lruvec; | |
| 1111 | 1135 | } |
| 1112 | 1136 | |
| 1113 | 1137 | /** |
| @@ -1452,17 +1476,26 @@ static int mem_cgroup_count_children(struct mem_cgroup *memcg) · 338 unmodified lines | ||
| 1452 | 1476 | static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg) |
| 1453 | 1477 | { |
| 1454 | 1478 | u64 limit; |
| 1455 | − u64 memsw; | |
| 1456 | 1479 | |
| 1457 | 1480 | limit = res_counter_read_u64(&memcg->res, RES_LIMIT); |
| 1458 | − limit += total_swap_pages << PAGE_SHIFT; | |
| 1459 | 1481 | |
| 1460 | − memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT); | |
| 1461 | 1482 | /* |
| 1462 | − * If memsw is finite and limits the amount of swap space available | |
| 1463 | − * to this memcg, return that limit. | |
| 1483 | + * Do not consider swap space if we cannot swap due to swappiness | |
| 1464 | 1484 | */ |
| 1465 | − return min(limit, memsw); | |
| 1485 | + if (mem_cgroup_swappiness(memcg)) { | |
| 1486 | + u64 memsw; | |
| 1487 | + | |
| 1488 | + limit += total_swap_pages << PAGE_SHIFT; | |
| 1489 | + memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT); | |
| 1490 | + | |
| 1491 | + /* | |
| 1492 | + * If memsw is finite and limits the amount of swap space | |
| 1493 | + * available to this memcg, return that limit. | |
| 1494 | + */ | |
| 1495 | + limit = min(limit, memsw); | |
| 1496 | + } | |
| 1497 | + | |
| 1498 | + return limit; | |
| 1466 | 1499 | } |
| 1467 | 1500 | |
| 1468 | 1501 | void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, |
| @@ -3688,17 +3721,17 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, · 2219 unmodified lines | ||
| 3688 | 3721 | static bool mem_cgroup_force_empty_list(struct mem_cgroup *memcg, |
| 3689 | 3722 | int node, int zid, enum lru_list lru) |
| 3690 | 3723 | { |
| 3691 | − struct mem_cgroup_per_zone *mz; | |
| 3724 | + struct lruvec *lruvec; | |
| 3692 | 3725 | unsigned long flags, loop; |
| 3693 | 3726 | struct list_head *list; |
| 3694 | 3727 | struct page *busy; |
| 3695 | 3728 | struct zone *zone; |
| 3696 | 3729 | |
| 3697 | 3730 | zone = &NODE_DATA(node)->node_zones[zid]; |
| 3698 | − mz = mem_cgroup_zoneinfo(memcg, node, zid); | |
| 3699 | − list = &mz->lruvec.lists[lru]; | |
| 3731 | + lruvec = mem_cgroup_zone_lruvec(zone, memcg); | |
| 3732 | + list = &lruvec->lists[lru]; | |
| 3700 | 3733 | |
| 3701 | − loop = mz->lru_size[lru]; | |
| 3734 | + loop = mem_cgroup_get_lru_size(lruvec, lru); | |
| 3702 | 3735 | /* give some margin against EBUSY etc...*/ |
| 3703 | 3736 | loop += 256; |
| 3704 | 3737 | busy = NULL; |
| @@ -4736,7 +4769,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) · 1031 unmodified lines | ||
| 4736 | 4769 | |
| 4737 | 4770 | for (zone = 0; zone < MAX_NR_ZONES; zone++) { |
| 4738 | 4771 | mz = &pn->zoneinfo[zone]; |
| 4739 | − lruvec_init(&mz->lruvec, &NODE_DATA(node)->node_zones[zone]); | |
| 4772 | + lruvec_init(&mz->lruvec); | |
| 4740 | 4773 | mz->usage_in_excess = 0; |
| 4741 | 4774 | mz->on_tree = false; |
| 4742 | 4775 | mz->memcg = memcg; |
| @@ -2527,9 +2527,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, · 2526 unmodified lines | ||
| 2527 | 2527 | int ret = 0; |
| 2528 | 2528 | int page_mkwrite = 0; |
| 2529 | 2529 | struct page *dirty_page = NULL; |
| 2530 | − unsigned long mmun_start; /* For mmu_notifiers */ | |
| 2531 | − unsigned long mmun_end; /* For mmu_notifiers */ | |
| 2532 | − bool mmun_called = false; /* For mmu_notifiers */ | |
| 2530 | + unsigned long mmun_start = 0; /* For mmu_notifiers */ | |
| 2531 | + unsigned long mmun_end = 0; /* For mmu_notifiers */ | |
| 2533 | 2532 | |
| 2534 | 2533 | old_page = vm_normal_page(vma, address, orig_pte); |
| 2535 | 2534 | if (!old_page) { |
| @@ -2708,8 +2707,7 @@ gotten: · 172 unmodified lines | ||
| 2708 | 2707 | goto oom_free_new; |
| 2709 | 2708 | |
| 2710 | 2709 | mmun_start = address & PAGE_MASK; |
| 2711 | − mmun_end = (address & PAGE_MASK) + PAGE_SIZE; | |
| 2712 | − mmun_called = true; | |
| 2710 | + mmun_end = mmun_start + PAGE_SIZE; | |
| 2713 | 2711 | mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end); |
| 2714 | 2712 | |
| 2715 | 2713 | /* |
| @@ -2778,7 +2776,7 @@ gotten: · 62 unmodified lines | ||
| 2778 | 2776 | page_cache_release(new_page); |
| 2779 | 2777 | unlock: |
| 2780 | 2778 | pte_unmap_unlock(page_table, ptl); |
| 2781 | − if (mmun_called) | |
| 2779 | + if (mmun_end > mmun_start) | |
| 2782 | 2780 | mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); |
| 2783 | 2781 | if (old_page) { |
| 2784 | 2782 | /* |
| @@ -106,7 +106,6 @@ static void get_page_bootmem(unsigned long info, struct page *page, · 105 unmodified lines | ||
| 106 | 106 | void __ref put_page_bootmem(struct page *page) |
| 107 | 107 | { |
| 108 | 108 | unsigned long type; |
| 109 | − struct zone *zone; | |
| 110 | 109 | |
| 111 | 110 | type = (unsigned long) page->lru.next; |
| 112 | 111 | BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE || |
| @@ -117,12 +116,6 @@ void __ref put_page_bootmem(struct page *page) · 4 unmodified lines | ||
| 117 | 116 | set_page_private(page, 0); |
| 118 | 117 | INIT_LIST_HEAD(&page->lru); |
| 119 | 118 | __free_pages_bootmem(page, 0); |
| 120 | − | |
| 121 | − zone = page_zone(page); | |
| 122 | − zone_span_writelock(zone); | |
| 123 | − zone->present_pages++; | |
| 124 | − zone_span_writeunlock(zone); | |
| 125 | − totalram_pages++; | |
| 126 | 119 | } |
| 127 | 120 | |
| 128 | 121 | } |
| @@ -334,8 +334,10 @@ void validate_mm(struct mm_struct *mm) · 333 unmodified lines | ||
| 334 | 334 | struct vm_area_struct *vma = mm->mmap; |
| 335 | 335 | while (vma) { |
| 336 | 336 | struct anon_vma_chain *avc; |
| 337 | + vma_lock_anon_vma(vma); | |
| 337 | 338 | list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) |
| 338 | 339 | anon_vma_interval_tree_verify(avc); |
| 340 | + vma_unlock_anon_vma(vma); | |
| 339 | 341 | vma = vma->vm_next; |
| 340 | 342 | i++; |
| 341 | 343 | } |
| @@ -87,7 +87,7 @@ int memmap_valid_within(unsigned long pfn, · 86 unmodified lines | ||
| 87 | 87 | } |
| 88 | 88 | #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ |
| 89 | 89 | |
| 90 | −void lruvec_init(struct lruvec *lruvec, struct zone *zone) | |
| 90 | +void lruvec_init(struct lruvec *lruvec) | |
| 91 | 91 | { |
| 92 | 92 | enum lru_list lru; |
| 93 | 93 | |
| @@ -95,8 +95,4 @@ void lruvec_init(struct lruvec *lruvec, struct zone *zone) · 1 unmodified line | ||
| 95 | 95 | |
| 96 | 96 | for_each_lru(lru) |
| 97 | 97 | INIT_LIST_HEAD(&lruvec->lists[lru]); |
| 98 | − | |
| 99 | −#ifdef CONFIG_MEMCG | |
| 100 | − lruvec->zone = zone; | |
| 101 | −#endif | |
| 102 | 98 | } |
| @@ -116,8 +116,6 @@ static unsigned long __init __free_memory_core(phys_addr_t start, · 115 unmodified lines | ||
| 116 | 116 | return 0; |
| 117 | 117 | |
| 118 | 118 | __free_pages_memory(start_pfn, end_pfn); |
| 119 | − fixup_zone_present_pages(pfn_to_nid(start >> PAGE_SHIFT), | |
| 120 | − start_pfn, end_pfn); | |
| 121 | 119 | |
| 122 | 120 | return end_pfn - start_pfn; |
| 123 | 121 | } |
| @@ -128,7 +126,6 @@ unsigned long __init free_low_memory_core_early(int nodeid) · 4 unmodified lines | ||
| 128 | 126 | phys_addr_t start, end, size; |
| 129 | 127 | u64 i; |
| 130 | 128 | |
| 131 | − reset_zone_present_pages(); | |
| 132 | 129 | for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL) |
| 133 | 130 | count += __free_memory_core(start, end); |
| 134 | 131 | |
| @@ -4505,7 +4505,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, · 4504 unmodified lines | ||
| 4505 | 4505 | zone->zone_pgdat = pgdat; |
| 4506 | 4506 | |
| 4507 | 4507 | zone_pcp_init(zone); |
| 4508 | − lruvec_init(&zone->lruvec, zone); | |
| 4508 | + lruvec_init(&zone->lruvec); | |
| 4509 | 4509 | if (!size) |
| 4510 | 4510 | continue; |
| 4511 | 4511 | |
| @@ -6098,37 +6098,3 @@ void dump_page(struct page *page) · 1586 unmodified lines | ||
| 6098 | 6098 | dump_page_flags(page->flags); |
| 6099 | 6099 | mem_cgroup_print_bad_page(page); |
| 6100 | 6100 | } |
| 6101 | − | |
| 6102 | −/* reset zone->present_pages */ | |
| 6103 | −void reset_zone_present_pages(void) | |
| 6104 | −{ | |
| 6105 | − struct zone *z; | |
| 6106 | − int i, nid; | |
| 6107 | − | |
| 6108 | − for_each_node_state(nid, N_HIGH_MEMORY) { | |
| 6109 | − for (i = 0; i < MAX_NR_ZONES; i++) { | |
| 6110 | − z = NODE_DATA(nid)->node_zones + i; | |
| 6111 | − z->present_pages = 0; | |
| 6112 | − } | |
| 6113 | − } | |
| 6114 | −} | |
| 6115 | − | |
| 6116 | −/* calculate zone's present pages in buddy system */ | |
| 6117 | −void fixup_zone_present_pages(int nid, unsigned long start_pfn, | |
| 6118 | − unsigned long end_pfn) | |
| 6119 | −{ | |
| 6120 | − struct zone *z; | |
| 6121 | − unsigned long zone_start_pfn, zone_end_pfn; | |
| 6122 | − int i; | |
| 6123 | − | |
| 6124 | − for (i = 0; i < MAX_NR_ZONES; i++) { | |
| 6125 | − z = NODE_DATA(nid)->node_zones + i; | |
| 6126 | − zone_start_pfn = z->zone_start_pfn; | |
| 6127 | − zone_end_pfn = zone_start_pfn + z->spanned_pages; | |
| 6128 | − | |
| 6129 | − /* if the two regions intersect */ | |
| 6130 | − if (!(zone_start_pfn >= end_pfn || zone_end_pfn <= start_pfn)) | |
| 6131 | − z->present_pages += min(end_pfn, zone_end_pfn) - | |
| 6132 | − max(start_pfn, zone_start_pfn); | |
| 6133 | − } | |
| 6134 | −} | |
| @@ -643,7 +643,7 @@ static void shmem_evict_inode(struct inode *inode) · 642 unmodified lines | ||
| 643 | 643 | kfree(info->symlink); |
| 644 | 644 | |
| 645 | 645 | simple_xattrs_free(&info->xattrs); |
| 646 | − BUG_ON(inode->i_blocks); | |
| 646 | + WARN_ON(inode->i_blocks); | |
| 647 | 647 | shmem_free_inode(inode->i_sb); |
| 648 | 648 | clear_inode(inode); |
| 649 | 649 | } |
| @@ -1145,8 +1145,20 @@ repeat: · 495 unmodified lines | ||
| 1145 | 1145 | if (!error) { |
| 1146 | 1146 | error = shmem_add_to_page_cache(page, mapping, index, |
| 1147 | 1147 | gfp, swp_to_radix_entry(swap)); |
| 1148 | − /* We already confirmed swap, and make no allocation */ | |
| 1149 | − VM_BUG_ON(error); | |
| 1148 | + /* | |
| 1149 | + * We already confirmed swap under page lock, and make | |
| 1150 | + * no memory allocation here, so usually no possibility | |
| 1151 | + * of error; but free_swap_and_cache() only trylocks a | |
| 1152 | + * page, so it is just possible that the entry has been | |
| 1153 | + * truncated or holepunched since swap was confirmed. | |
| 1154 | + * shmem_undo_range() will have done some of the | |
| 1155 | + * unaccounting, now delete_from_swap_cache() will do | |
| 1156 | + * the rest (including mem_cgroup_uncharge_swapcache). | |
| 1157 | + * Reset swap.val? No, leave it so "failed" goes back to | |
| 1158 | + * "repeat": reading a hole and writing should succeed. | |
| 1159 | + */ | |
| 1160 | + if (error) | |
| 1161 | + delete_from_swap_cache(page); | |
| 1150 | 1162 | } |
| 1151 | 1163 | if (error) |
| 1152 | 1164 | goto failed; |
| @@ -1494,9 +1494,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) · 1493 unmodified lines | ||
| 1494 | 1494 | BUG_ON(!current->mm); |
| 1495 | 1495 | |
| 1496 | 1496 | pathname = getname(specialfile); |
| 1497 | − err = PTR_ERR(pathname); | |
| 1498 | 1497 | if (IS_ERR(pathname)) |
| 1499 | − goto out; | |
| 1498 | + return PTR_ERR(pathname); | |
| 1500 | 1499 | |
| 1501 | 1500 | victim = file_open_name(pathname, O_RDWR|O_LARGEFILE, 0); |
| 1502 | 1501 | err = PTR_ERR(victim); |
| @@ -1608,6 +1607,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) · 105 unmodified lines | ||
| 1608 | 1607 | out_dput: |
| 1609 | 1608 | filp_close(victim, NULL); |
| 1610 | 1609 | out: |
| 1610 | + putname(pathname); | |
| 1611 | 1611 | return err; |
| 1612 | 1612 | } |
| 1613 | 1613 | |
| @@ -1760,28 +1760,6 @@ static bool in_reclaim_compaction(struct scan_control *sc) · 1759 unmodified lines | ||
| 1760 | 1760 | return false; |
| 1761 | 1761 | } |
| 1762 | 1762 | |
| 1763 | −#ifdef CONFIG_COMPACTION | |
| 1764 | −/* | |
| 1765 | − * If compaction is deferred for sc->order then scale the number of pages | |
| 1766 | − * reclaimed based on the number of consecutive allocation failures | |
| 1767 | − */ | |
| 1768 | −static unsigned long scale_for_compaction(unsigned long pages_for_compaction, | |
| 1769 | − struct lruvec *lruvec, struct scan_control *sc) | |
| 1770 | −{ | |
| 1771 | − struct zone *zone = lruvec_zone(lruvec); | |
| 1772 | − | |
| 1773 | − if (zone->compact_order_failed <= sc->order) | |
| 1774 | − pages_for_compaction <<= zone->compact_defer_shift; | |
| 1775 | − return pages_for_compaction; | |
| 1776 | −} | |
| 1777 | −#else | |
| 1778 | −static unsigned long scale_for_compaction(unsigned long pages_for_compaction, | |
| 1779 | − struct lruvec *lruvec, struct scan_control *sc) | |
| 1780 | −{ | |
| 1781 | − return pages_for_compaction; | |
| 1782 | −} | |
| 1783 | −#endif | |
| 1784 | − | |
| 1785 | 1763 | /* |
| 1786 | 1764 | * Reclaim/compaction is used for high-order allocation requests. It reclaims |
| 1787 | 1765 | * order-0 pages before compacting the zone. should_continue_reclaim() returns |
| @@ -1829,9 +1807,6 @@ static inline bool should_continue_reclaim(struct lruvec *lruvec, · 41 unmodified lines | ||
| 1829 | 1807 | * inactive lists are large enough, continue reclaiming |
| 1830 | 1808 | */ |
| 1831 | 1809 | pages_for_compaction = (2UL << sc->order); |
| 1832 | − | |
| 1833 | − pages_for_compaction = scale_for_compaction(pages_for_compaction, | |
| 1834 | − lruvec, sc); | |
| 1835 | 1810 | inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE); |
| 1836 | 1811 | if (nr_swap_pages > 0) |
| 1837 | 1812 | inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON); |
| @@ -3017,6 +2992,8 @@ static int kswapd(void *p) · 1179 unmodified lines | ||
| 3017 | 2992 | &balanced_classzone_idx); |
| 3018 | 2993 | } |
| 3019 | 2994 | } |
| 2995 | + | |
| 2996 | + current->reclaim_state = NULL; | |
| 3020 | 2997 | return 0; |
| 3021 | 2998 | } |
| 3022 | 2999 | |
| @@ -347,6 +347,12 @@ void batadv_interface_rx(struct net_device *soft_iface, · 346 unmodified lines | ||
| 347 | 347 | |
| 348 | 348 | soft_iface->last_rx = jiffies; |
| 349 | 349 | |
| 350 | + /* Let the bridge loop avoidance check the packet. If will | |
| 351 | + * not handle it, we can safely push it up. | |
| 352 | + */ | |
| 353 | + if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) | |
| 354 | + goto out; | |
| 355 | + | |
| 350 | 356 | if (orig_node) |
| 351 | 357 | batadv_tt_add_temporary_global_entry(bat_priv, orig_node, |
| 352 | 358 | ethhdr->h_source); |
| @@ -354,12 +360,6 @@ void batadv_interface_rx(struct net_device *soft_iface, · 1 unmodified line | ||
| 354 | 360 | if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) |
| 355 | 361 | goto dropped; |
| 356 | 362 | |
| 357 | − /* Let the bridge loop avoidance check the packet. If will | |
| 358 | − * not handle it, we can safely push it up. | |
| 359 | − */ | |
| 360 | − if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) | |
| 361 | − goto out; | |
| 362 | − | |
| 363 | 363 | netif_rx(skb); |
| 364 | 364 | goto out; |
| 365 | 365 | |
| @@ -861,6 +861,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, · 860 unmodified lines | ||
| 861 | 861 | */ |
| 862 | 862 | common->flags &= ~BATADV_TT_CLIENT_TEMP; |
| 863 | 863 | |
| 864 | + /* the change can carry possible "attribute" flags like the | |
| 865 | + * TT_CLIENT_WIFI, therefore they have to be copied in the | |
| 866 | + * client entry | |
| 867 | + */ | |
| 868 | + tt_global_entry->common.flags |= flags; | |
| 869 | + | |
| 864 | 870 | /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only |
| 865 | 871 | * one originator left in the list and we previously received a |
| 866 | 872 | * delete + roaming change for this originator. |
| @@ -1574,7 +1580,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, · 707 unmodified lines | ||
| 1574 | 1580 | |
| 1575 | 1581 | memcpy(tt_change->addr, tt_common_entry->addr, |
| 1576 | 1582 | ETH_ALEN); |
| 1577 | − tt_change->flags = BATADV_NO_FLAGS; | |
| 1583 | + tt_change->flags = tt_common_entry->flags; | |
| 1578 | 1584 | |
| 1579 | 1585 | tt_count++; |
| 1580 | 1586 | tt_change++; |
| @@ -2545,6 +2551,13 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, · 964 unmodified lines | ||
| 2545 | 2551 | { |
| 2546 | 2552 | bool ret = false; |
| 2547 | 2553 | |
| 2554 | + /* if the originator is a backbone node (meaning it belongs to the same | |
| 2555 | + * LAN of this node) the temporary client must not be added because to | |
| 2556 | + * reach such destination the node must use the LAN instead of the mesh | |
| 2557 | + */ | |
| 2558 | + if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) | |
| 2559 | + goto out; | |
| 2560 | + | |
| 2548 | 2561 | if (!batadv_tt_global_add(bat_priv, orig_node, addr, |
| 2549 | 2562 | BATADV_TT_CLIENT_TEMP, |
| 2550 | 2563 | atomic_read(&orig_node->last_ttvn))) |
| @@ -1754,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev) · 1753 unmodified lines | ||
| 1754 | 1754 | if (hdev->dev_type != HCI_AMP) |
| 1755 | 1755 | set_bit(HCI_AUTO_OFF, &hdev->dev_flags); |
| 1756 | 1756 | |
| 1757 | − schedule_work(&hdev->power_on); | |
| 1758 | − | |
| 1759 | 1757 | hci_notify(hdev, HCI_DEV_REG); |
| 1760 | 1758 | hci_dev_hold(hdev); |
| 1761 | 1759 | |
| 1760 | + schedule_work(&hdev->power_on); | |
| 1761 | + | |
| 1762 | 1762 | return id; |
| 1763 | 1763 | |
| 1764 | 1764 | err_wqueue: |
| @@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, · 325 unmodified lines | ||
| 326 | 326 | struct hci_dev *d; |
| 327 | 327 | size_t rp_len; |
| 328 | 328 | u16 count; |
| 329 | − int i, err; | |
| 329 | + int err; | |
| 330 | 330 | |
| 331 | 331 | BT_DBG("sock %p", sk); |
| 332 | 332 | |
| @@ -347,9 +347,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, · 14 unmodified lines | ||
| 347 | 347 | return -ENOMEM; |
| 348 | 348 | } |
| 349 | 349 | |
| 350 | − rp->num_controllers = cpu_to_le16(count); | |
| 351 | − | |
| 352 | − i = 0; | |
| 350 | + count = 0; | |
| 353 | 351 | list_for_each_entry(d, &hci_dev_list, list) { |
| 354 | 352 | if (test_bit(HCI_SETUP, &d->dev_flags)) |
| 355 | 353 | continue; |
| @@ -357,10 +355,13 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, · 1 unmodified line | ||
| 357 | 355 | if (!mgmt_valid_hdev(d)) |
| 358 | 356 | continue; |
| 359 | 357 | |
| 360 | − rp->index[i++] = cpu_to_le16(d->id); | |
| 358 | + rp->index[count++] = cpu_to_le16(d->id); | |
| 361 | 359 | BT_DBG("Added hci%u", d->id); |
| 362 | 360 | } |
| 363 | 361 | |
| 362 | + rp->num_controllers = cpu_to_le16(count); | |
| 363 | + rp_len = sizeof(*rp) + (2 * count); | |
| 364 | + | |
| 364 | 365 | read_unlock(&hci_dev_list_lock); |
| 365 | 366 | |
| 366 | 367 | err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, |
| @@ -1366,6 +1367,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, · 999 unmodified lines | ||
| 1366 | 1367 | continue; |
| 1367 | 1368 | |
| 1368 | 1369 | list_del(&match->list); |
| 1370 | + kfree(match); | |
| 1369 | 1371 | found++; |
| 1370 | 1372 | } |
| 1371 | 1373 | |
| @@ -267,7 +267,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) · 266 unmodified lines | ||
| 267 | 267 | |
| 268 | 268 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); |
| 269 | 269 | mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, |
| 270 | − hcon->dst_type, reason); | |
| 270 | + hcon->dst_type, HCI_ERROR_AUTH_FAILURE); | |
| 271 | 271 | |
| 272 | 272 | cancel_delayed_work_sync(&conn->security_timer); |
| 273 | 273 | |
| @@ -2895,8 +2895,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, · 2894 unmodified lines | ||
| 2895 | 2895 | if (unlikely(tcpu != next_cpu) && |
| 2896 | 2896 | (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || |
| 2897 | 2897 | ((int)(per_cpu(softnet_data, tcpu).input_queue_head - |
| 2898 | − rflow->last_qtail)) >= 0)) | |
| 2898 | + rflow->last_qtail)) >= 0)) { | |
| 2899 | + tcpu = next_cpu; | |
| 2899 | 2900 | rflow = set_rps_cpu(dev, skb, rflow, next_cpu); |
| 2901 | + } | |
| 2900 | 2902 | |
| 2901 | 2903 | if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { |
| 2902 | 2904 | *rflowp = rflow; |
| @@ -319,7 +319,8 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, · 318 unmodified lines | ||
| 319 | 319 | */ |
| 320 | 320 | ha = list_first_entry(&dev->dev_addrs.list, |
| 321 | 321 | struct netdev_hw_addr, list); |
| 322 | − if (ha->addr == dev->dev_addr && ha->refcount == 1) | |
| 322 | + if (!memcmp(ha->addr, addr, dev->addr_len) && | |
| 323 | + ha->type == addr_type && ha->refcount == 1) | |
| 323 | 324 | return -ENOENT; |
| 324 | 325 | |
| 325 | 326 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, |
| @@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level, · 456 unmodified lines | ||
| 457 | 457 | struct inet_sock *inet = inet_sk(sk); |
| 458 | 458 | int val = 0, err; |
| 459 | 459 | |
| 460 | − if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) | | |
| 461 | − (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) | | |
| 462 | − (1<<IP_RETOPTS) | (1<<IP_TOS) | | |
| 463 | − (1<<IP_TTL) | (1<<IP_HDRINCL) | | |
| 464 | − (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | | |
| 465 | − (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | | |
| 466 | − (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) | | |
| 467 | − (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) || | |
| 468 | − optname == IP_UNICAST_IF || | |
| 469 | − optname == IP_MULTICAST_TTL || | |
| 470 | − optname == IP_MULTICAST_ALL || | |
| 471 | − optname == IP_MULTICAST_LOOP || | |
| 472 | − optname == IP_RECVORIGDSTADDR) { | |
| 460 | + switch (optname) { | |
| 461 | + case IP_PKTINFO: | |
| 462 | + case IP_RECVTTL: | |
| 463 | + case IP_RECVOPTS: | |
| 464 | + case IP_RECVTOS: | |
| 465 | + case IP_RETOPTS: | |
| 466 | + case IP_TOS: | |
| 467 | + case IP_TTL: | |
| 468 | + case IP_HDRINCL: | |
| 469 | + case IP_MTU_DISCOVER: | |
| 470 | + case IP_RECVERR: | |
| 471 | + case IP_ROUTER_ALERT: | |
| 472 | + case IP_FREEBIND: | |
| 473 | + case IP_PASSSEC: | |
| 474 | + case IP_TRANSPARENT: | |
| 475 | + case IP_MINTTL: | |
| 476 | + case IP_NODEFRAG: | |
| 477 | + case IP_UNICAST_IF: | |
| 478 | + case IP_MULTICAST_TTL: | |
| 479 | + case IP_MULTICAST_ALL: | |
| 480 | + case IP_MULTICAST_LOOP: | |
| 481 | + case IP_RECVORIGDSTADDR: | |
| 473 | 482 | if (optlen >= sizeof(int)) { |
| 474 | 483 | if (get_user(val, (int __user *) optval)) |
| 475 | 484 | return -EFAULT; |
| @@ -324,12 +324,17 @@ static int vti_rcv(struct sk_buff *skb) · 323 unmodified lines | ||
| 324 | 324 | if (tunnel != NULL) { |
| 325 | 325 | struct pcpu_tstats *tstats; |
| 326 | 326 | |
| 327 | + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) | |
| 328 | + return -1; | |
| 329 | + | |
| 327 | 330 | tstats = this_cpu_ptr(tunnel->dev->tstats); |
| 328 | 331 | u64_stats_update_begin(&tstats->syncp); |
| 329 | 332 | tstats->rx_packets++; |
| 330 | 333 | tstats->rx_bytes += skb->len; |
| 331 | 334 | u64_stats_update_end(&tstats->syncp); |
| 332 | 335 | |
| 336 | + skb->mark = 0; | |
| 337 | + secpath_reset(skb); | |
| 333 | 338 | skb->dev = tunnel->dev; |
| 334 | 339 | return 1; |
| 335 | 340 | } |
| @@ -1213,7 +1213,7 @@ new_segment: · 1212 unmodified lines | ||
| 1213 | 1213 | wait_for_sndbuf: |
| 1214 | 1214 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
| 1215 | 1215 | wait_for_memory: |
| 1216 | − if (copied && likely(!tp->repair)) | |
| 1216 | + if (copied) | |
| 1217 | 1217 | tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); |
| 1218 | 1218 | |
| 1219 | 1219 | if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) |
| @@ -1224,7 +1224,7 @@ wait_for_memory: · 4 unmodified lines | ||
| 1224 | 1224 | } |
| 1225 | 1225 | |
| 1226 | 1226 | out: |
| 1227 | − if (copied && likely(!tp->repair)) | |
| 1227 | + if (copied) | |
| 1228 | 1228 | tcp_push(sk, flags, mss_now, tp->nonagle); |
| 1229 | 1229 | release_sock(sk); |
| 1230 | 1230 | return copied + copied_syn; |
| @@ -5320,11 +5320,6 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, · 5319 unmodified lines | ||
| 5320 | 5320 | goto discard; |
| 5321 | 5321 | } |
| 5322 | 5322 | |
| 5323 | − /* ts_recent update must be made after we are sure that the packet | |
| 5324 | − * is in window. | |
| 5325 | − */ | |
| 5326 | − tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | |
| 5327 | − | |
| 5328 | 5323 | /* step 3: check security and precedence [ignored] */ |
| 5329 | 5324 | |
| 5330 | 5325 | /* step 4: Check for a SYN |
| @@ -5559,6 +5554,11 @@ step5: · 228 unmodified lines | ||
| 5559 | 5554 | if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) |
| 5560 | 5555 | goto discard; |
| 5561 | 5556 | |
| 5557 | + /* ts_recent update must be made after we are sure that the packet | |
| 5558 | + * is in window. | |
| 5559 | + */ | |
| 5560 | + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | |
| 5561 | + | |
| 5562 | 5562 | tcp_rcv_rtt_measure_ts(sk, skb); |
| 5563 | 5563 | |
| 5564 | 5564 | /* Process urgent data. */ |
| @@ -6137,6 +6137,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, · 572 unmodified lines | ||
| 6137 | 6137 | } else |
| 6138 | 6138 | goto discard; |
| 6139 | 6139 | |
| 6140 | + /* ts_recent update must be made after we are sure that the packet | |
| 6141 | + * is in window. | |
| 6142 | + */ | |
| 6143 | + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | |
| 6144 | + | |
| 6140 | 6145 | /* step 6: check the URG bit */ |
| 6141 | 6146 | tcp_urg(sk, skb, th); |
| 6142 | 6147 | |
| @@ -1,7 +1,6 @@ | ||
| 1 | 1 | #include <linux/rcupdate.h> |
| 2 | 2 | #include <linux/spinlock.h> |
| 3 | 3 | #include <linux/jiffies.h> |
| 4 | −#include <linux/bootmem.h> | |
| 5 | 4 | #include <linux/module.h> |
| 6 | 5 | #include <linux/cache.h> |
| 7 | 6 | #include <linux/slab.h> |
| @@ -9,6 +8,7 @@ · 1 unmodified line | ||
| 9 | 8 | #include <linux/tcp.h> |
| 10 | 9 | #include <linux/hash.h> |
| 11 | 10 | #include <linux/tcp_metrics.h> |
| 11 | +#include <linux/vmalloc.h> | |
| 12 | 12 | |
| 13 | 13 | #include <net/inet_connection_sock.h> |
| 14 | 14 | #include <net/net_namespace.h> |
| @@ -1034,7 +1034,10 @@ static int __net_init tcp_net_metrics_init(struct net *net) · 1019 unmodified lines | ||
| 1034 | 1034 | net->ipv4.tcp_metrics_hash_log = order_base_2(slots); |
| 1035 | 1035 | size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log; |
| 1036 | 1036 | |
| 1037 | − net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL); | |
| 1037 | + net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); | |
| 1038 | + if (!net->ipv4.tcp_metrics_hash) | |
| 1039 | + net->ipv4.tcp_metrics_hash = vzalloc(size); | |
| 1040 | + | |
| 1038 | 1041 | if (!net->ipv4.tcp_metrics_hash) |
| 1039 | 1042 | return -ENOMEM; |
| 1040 | 1043 | |
| @@ -1055,7 +1058,10 @@ static void __net_exit tcp_net_metrics_exit(struct net *net) · 14 unmodified lines | ||
| 1055 | 1058 | tm = next; |
| 1056 | 1059 | } |
| 1057 | 1060 | } |
| 1058 | − kfree(net->ipv4.tcp_metrics_hash); | |
| 1061 | + if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash)) | |
| 1062 | + vfree(net->ipv4.tcp_metrics_hash); | |
| 1063 | + else | |
| 1064 | + kfree(net->ipv4.tcp_metrics_hash); | |
| 1059 | 1065 | } |
| 1060 | 1066 | |
| 1061 | 1067 | static __net_initdata struct pernet_operations tcp_net_metrics_ops = { |
| @@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, · 1985 unmodified lines | ||
| 1986 | 1986 | tso_segs = tcp_init_tso_segs(sk, skb, mss_now); |
| 1987 | 1987 | BUG_ON(!tso_segs); |
| 1988 | 1988 | |
| 1989 | + if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE) | |
| 1990 | + goto repair; /* Skip network transmission */ | |
| 1991 | + | |
| 1989 | 1992 | cwnd_quota = tcp_cwnd_test(tp, skb); |
| 1990 | 1993 | if (!cwnd_quota) |
| 1991 | 1994 | break; |
| @@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, · 34 unmodified lines | ||
| 2026 | 2029 | if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) |
| 2027 | 2030 | break; |
| 2028 | 2031 | |
| 2032 | +repair: | |
| 2029 | 2033 | /* Advance the send_head. This one is sent out. |
| 2030 | 2034 | * This call will increment packets_out. |
| 2031 | 2035 | */ |
| @@ -827,6 +827,7 @@ pref_skip_coa: · 826 unmodified lines | ||
| 827 | 827 | if (val < 0 || val > 255) |
| 828 | 828 | goto e_inval; |
| 829 | 829 | np->min_hopcount = val; |
| 830 | + retv = 0; | |
| 830 | 831 | break; |
| 831 | 832 | case IPV6_DONTFRAG: |
| 832 | 833 | np->dontfrag = valbool; |
| @@ -2613,6 +2613,9 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, · 2612 unmodified lines | ||
| 2613 | 2613 | else |
| 2614 | 2614 | local->probe_req_reg--; |
| 2615 | 2615 | |
| 2616 | + if (!local->open_count) | |
| 2617 | + break; | |
| 2618 | + | |
| 2616 | 2619 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); |
| 2617 | 2620 | break; |
| 2618 | 2621 | default: |
| @@ -1377,6 +1377,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, · 1376 unmodified lines | ||
| 1377 | 1377 | struct net_device *dev); |
| 1378 | 1378 | netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, |
| 1379 | 1379 | struct net_device *dev); |
| 1380 | +void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, | |
| 1381 | + struct sk_buff_head *skbs); | |
| 1380 | 1382 | |
| 1381 | 1383 | /* HT */ |
| 1382 | 1384 | void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, |
| @@ -920,8 +920,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) · 919 unmodified lines | ||
| 920 | 920 | local->hw.wiphy->cipher_suites, |
| 921 | 921 | sizeof(u32) * local->hw.wiphy->n_cipher_suites, |
| 922 | 922 | GFP_KERNEL); |
| 923 | − if (!suites) | |
| 924 | − return -ENOMEM; | |
| 923 | + if (!suites) { | |
| 924 | + result = -ENOMEM; | |
| 925 | + goto fail_wiphy_register; | |
| 926 | + } | |
| 925 | 927 | for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { |
| 926 | 928 | u32 suite = local->hw.wiphy->cipher_suites[r]; |
| 927 | 929 | if (suite == WLAN_CIPHER_SUITE_WEP40 || |
| @@ -934,7 +934,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, · 933 unmodified lines | ||
| 934 | 934 | struct cfg80211_sched_scan_request *req) |
| 935 | 935 | { |
| 936 | 936 | struct ieee80211_local *local = sdata->local; |
| 937 | − struct ieee80211_sched_scan_ies sched_scan_ies; | |
| 937 | + struct ieee80211_sched_scan_ies sched_scan_ies = {}; | |
| 938 | 938 | int ret, i; |
| 939 | 939 | |
| 940 | 940 | mutex_lock(&local->mtx); |
| @@ -122,8 +122,8 @@ static void free_sta_work(struct work_struct *wk) · 121 unmodified lines | ||
| 122 | 122 | |
| 123 | 123 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
| 124 | 124 | local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); |
| 125 | − __skb_queue_purge(&sta->ps_tx_buf[ac]); | |
| 126 | − __skb_queue_purge(&sta->tx_filtered[ac]); | |
| 125 | + ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]); | |
| 126 | + ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); | |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | 129 | #ifdef CONFIG_MAC80211_MESH |
| @@ -146,7 +146,7 @@ static void free_sta_work(struct work_struct *wk) · 16 unmodified lines | ||
| 146 | 146 | tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); |
| 147 | 147 | if (!tid_tx) |
| 148 | 148 | continue; |
| 149 | − __skb_queue_purge(&tid_tx->pending); | |
| 149 | + ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); | |
| 150 | 150 | kfree(tid_tx); |
| 151 | 151 | } |
| 152 | 152 | |
| @@ -982,6 +982,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) · 829 unmodified lines | ||
| 982 | 982 | struct ieee80211_local *local = sdata->local; |
| 983 | 983 | struct sk_buff_head pending; |
| 984 | 984 | int filtered = 0, buffered = 0, ac; |
| 985 | + unsigned long flags; | |
| 985 | 986 | |
| 986 | 987 | clear_sta_flag(sta, WLAN_STA_SP); |
| 987 | 988 | |
| @@ -997,12 +998,16 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) · 9 unmodified lines | ||
| 997 | 998 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
| 998 | 999 | int count = skb_queue_len(&pending), tmp; |
| 999 | 1000 | |
| 1001 | + spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); | |
| 1000 | 1002 | skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); |
| 1003 | + spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); | |
| 1001 | 1004 | tmp = skb_queue_len(&pending); |
| 1002 | 1005 | filtered += tmp - count; |
| 1003 | 1006 | count = tmp; |
| 1004 | 1007 | |
| 1008 | + spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); | |
| 1005 | 1009 | skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); |
| 1010 | + spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); | |
| 1006 | 1011 | tmp = skb_queue_len(&pending); |
| 1007 | 1012 | buffered += tmp - count; |
| 1008 | 1013 | } |
| @@ -669,3 +669,12 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) · 668 unmodified lines | ||
| 669 | 669 | dev_kfree_skb_any(skb); |
| 670 | 670 | } |
| 671 | 671 | EXPORT_SYMBOL(ieee80211_free_txskb); |
| 672 | + | |
| 673 | +void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, | |
| 674 | + struct sk_buff_head *skbs) | |
| 675 | +{ | |
| 676 | + struct sk_buff *skb; | |
| 677 | + | |
| 678 | + while ((skb = __skb_dequeue(skbs))) | |
| 679 | + ieee80211_free_txskb(hw, skb); | |
| 680 | +} | |
| @@ -1361,7 +1361,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) · 1360 unmodified lines | ||
| 1361 | 1361 | if (tx->skb) |
| 1362 | 1362 | ieee80211_free_txskb(&tx->local->hw, tx->skb); |
| 1363 | 1363 | else |
| 1364 | − __skb_queue_purge(&tx->skbs); | |
| 1364 | + ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs); | |
| 1365 | 1365 | return -1; |
| 1366 | 1366 | } else if (unlikely(res == TX_QUEUED)) { |
| 1367 | 1367 | I802_DEBUG_INC(tx->local->tx_handlers_queued); |
| @@ -2160,10 +2160,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, · 792 unmodified lines | ||
| 2160 | 2160 | */ |
| 2161 | 2161 | void ieee80211_clear_tx_pending(struct ieee80211_local *local) |
| 2162 | 2162 | { |
| 2163 | + struct sk_buff *skb; | |
| 2163 | 2164 | int i; |
| 2164 | 2165 | |
| 2165 | − for (i = 0; i < local->hw.queues; i++) | |
| 2166 | − skb_queue_purge(&local->pending[i]); | |
| 2166 | + for (i = 0; i < local->hw.queues; i++) { | |
| 2167 | + while ((skb = skb_dequeue(&local->pending[i])) != NULL) | |
| 2168 | + ieee80211_free_txskb(&local->hw, skb); | |
| 2169 | + } | |
| 2167 | 2170 | } |
| 2168 | 2171 | |
| 2169 | 2172 | /* |
| @@ -1534,6 +1534,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) · 1533 unmodified lines | ||
| 1534 | 1534 | list_for_each_entry(sdata, &local->interfaces, list) { |
| 1535 | 1535 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
| 1536 | 1536 | continue; |
| 1537 | + if (!sdata->u.mgd.associated) | |
| 1538 | + continue; | |
| 1537 | 1539 | |
| 1538 | 1540 | ieee80211_send_nullfunc(local, sdata, 0); |
| 1539 | 1541 | } |
| @@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = { · 101 unmodified lines | ||
| 102 | 102 | .open = sctp_snmp_seq_open, |
| 103 | 103 | .read = seq_read, |
| 104 | 104 | .llseek = seq_lseek, |
| 105 | − .release = single_release, | |
| 105 | + .release = single_release_net, | |
| 106 | 106 | }; |
| 107 | 107 | |
| 108 | 108 | /* Set up the proc fs entry for 'snmp' object. */ |
| @@ -251,7 +251,7 @@ static const struct file_operations sctp_eps_seq_fops = { · 142 unmodified lines | ||
| 251 | 251 | .open = sctp_eps_seq_open, |
| 252 | 252 | .read = seq_read, |
| 253 | 253 | .llseek = seq_lseek, |
| 254 | − .release = seq_release, | |
| 254 | + .release = seq_release_net, | |
| 255 | 255 | }; |
| 256 | 256 | |
| 257 | 257 | /* Set up the proc fs entry for 'eps' object. */ |
| @@ -372,7 +372,7 @@ static const struct file_operations sctp_assocs_seq_fops = { · 114 unmodified lines | ||
| 372 | 372 | .open = sctp_assocs_seq_open, |
| 373 | 373 | .read = seq_read, |
| 374 | 374 | .llseek = seq_lseek, |
| 375 | − .release = seq_release, | |
| 375 | + .release = seq_release_net, | |
| 376 | 376 | }; |
| 377 | 377 | |
| 378 | 378 | /* Set up the proc fs entry for 'assocs' object. */ |
| @@ -517,7 +517,7 @@ static const struct file_operations sctp_remaddr_seq_fops = { · 138 unmodified lines | ||
| 517 | 517 | .open = sctp_remaddr_seq_open, |
| 518 | 518 | .read = seq_read, |
| 519 | 519 | .llseek = seq_lseek, |
| 520 | − .release = seq_release, | |
| 520 | + .release = seq_release_net, | |
| 521 | 521 | }; |
| 522 | 522 | |
| 523 | 523 | int __net_init sctp_remaddr_proc_init(struct net *net) |
| @@ -172,7 +172,7 @@ out_free: · 171 unmodified lines | ||
| 172 | 172 | xprt_free_allocation(req); |
| 173 | 173 | |
| 174 | 174 | dprintk("RPC: setup backchannel transport failed\n"); |
| 175 | − return -1; | |
| 175 | + return -ENOMEM; | |
| 176 | 176 | } |
| 177 | 177 | EXPORT_SYMBOL_GPL(xprt_setup_backchannel); |
| 178 | 178 | |
| @@ -141,9 +141,8 @@ static const struct ieee80211_regdomain world_regdom = { · 140 unmodified lines | ||
| 141 | 141 | .reg_rules = { |
| 142 | 142 | /* IEEE 802.11b/g, channels 1..11 */ |
| 143 | 143 | REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), |
| 144 | − /* IEEE 802.11b/g, channels 12..13. No HT40 | |
| 145 | − * channel fits here. */ | |
| 146 | − REG_RULE(2467-10, 2472+10, 20, 6, 20, | |
| 144 | + /* IEEE 802.11b/g, channels 12..13. */ | |
| 145 | + REG_RULE(2467-10, 2472+10, 40, 6, 20, | |
| 147 | 146 | NL80211_RRF_PASSIVE_SCAN | |
| 148 | 147 | NL80211_RRF_NO_IBSS), |
| 149 | 148 | /* IEEE 802.11 channel 14 - Only JP enables |
| @@ -16,8 +16,9 @@ PHONY += $(modules) · 15 unmodified lines | ||
| 16 | 16 | __modinst: $(modules) |
| 17 | 17 | @: |
| 18 | 18 | |
| 19 | +# Don't stop modules_install if we can't sign external modules. | |
| 19 | 20 | quiet_cmd_modules_install = INSTALL $@ |
| 20 | − cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) | |
| 21 | + cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) | |
| 21 | 22 | |
| 22 | 23 | # Modules built outside the kernel source tree go into extra by default |
| 23 | 24 | INSTALL_MOD_DIR ?= extra |
| @@ -1890,8 +1890,10 @@ sub process { · 1889 unmodified lines | ||
| 1890 | 1890 | } |
| 1891 | 1891 | |
| 1892 | 1892 | if ($realfile =~ m@^(drivers/net/|net/)@ && |
| 1893 | − $rawline !~ m@^\+[ \t]*(\/\*|\*\/)@ && | |
| 1894 | − $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { | |
| 1893 | + $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ | |
| 1894 | + $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ | |
| 1895 | + $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ | |
| 1896 | + $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ | |
| 1895 | 1897 | WARN("NETWORKING_BLOCK_COMMENT_STYLE", |
| 1896 | 1898 | "networking block comments put the trailing */ on a separate line\n" . $herecurr); |
| 1897 | 1899 | } |
| @@ -12,7 +12,7 @@ extern "C" { · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | #include <assert.h> |
| 14 | 14 | #include <stdio.h> |
| 15 | −#include <sys/queue.h> | |
| 15 | +#include "list.h" | |
| 16 | 16 | #ifndef __cplusplus |
| 17 | 17 | #include <stdbool.h> |
| 18 | 18 | #endif |
| @@ -175,12 +175,11 @@ struct menu { · 156 unmodified lines | ||
| 175 | 175 | #define MENU_ROOT 0x0002 |
| 176 | 176 | |
| 177 | 177 | struct jump_key { |
| 178 | − CIRCLEQ_ENTRY(jump_key) entries; | |
| 178 | + struct list_head entries; | |
| 179 | 179 | size_t offset; |
| 180 | 180 | struct menu *target; |
| 181 | 181 | int index; |
| 182 | 182 | }; |
| 183 | −CIRCLEQ_HEAD(jk_head, jump_key); | |
| 184 | 183 | |
| 185 | 184 | #define JUMP_NB 9 |
| 186 | 185 | |
| @@ -0,0 +1,91 @@ | ||
| 1 | +#ifndef LIST_H | |
| 2 | +#define LIST_H | |
| 3 | + | |
| 4 | +/* | |
| 5 | + * Copied from include/linux/... | |
| 6 | + */ | |
| 7 | + | |
| 8 | +#undef offsetof | |
| 9 | +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * container_of - cast a member of a structure out to the containing structure | |
| 13 | + * @ptr: the pointer to the member. | |
| 14 | + * @type: the type of the container struct this is embedded in. | |
| 15 | + * @member: the name of the member within the struct. | |
| 16 | + * | |
| 17 | + */ | |
| 18 | +#define container_of(ptr, type, member) ({ \ | |
| 19 | + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ | |
| 20 | + (type *)( (char *)__mptr - offsetof(type,member) );}) | |
| 21 | + | |
| 22 | + | |
| 23 | +struct list_head { | |
| 24 | + struct list_head *next, *prev; | |
| 25 | +}; | |
| 26 | + | |
| 27 | + | |
| 28 | +#define LIST_HEAD_INIT(name) { &(name), &(name) } | |
| 29 | + | |
| 30 | +#define LIST_HEAD(name) \ | |
| 31 | + struct list_head name = LIST_HEAD_INIT(name) | |
| 32 | + | |
| 33 | +/** | |
| 34 | + * list_entry - get the struct for this entry | |
| 35 | + * @ptr: the &struct list_head pointer. | |
| 36 | + * @type: the type of the struct this is embedded in. | |
| 37 | + * @member: the name of the list_struct within the struct. | |
| 38 | + */ | |
| 39 | +#define list_entry(ptr, type, member) \ | |
| 40 | + container_of(ptr, type, member) | |
| 41 | + | |
| 42 | +/** | |
| 43 | + * list_for_each_entry - iterate over list of given type | |
| 44 | + * @pos: the type * to use as a loop cursor. | |
| 45 | + * @head: the head for your list. | |
| 46 | + * @member: the name of the list_struct within the struct. | |
| 47 | + */ | |
| 48 | +#define list_for_each_entry(pos, head, member) \ | |
| 49 | + for (pos = list_entry((head)->next, typeof(*pos), member); \ | |
| 50 | + &pos->member != (head); \ | |
| 51 | + pos = list_entry(pos->member.next, typeof(*pos), member)) | |
| 52 | + | |
| 53 | +/** | |
| 54 | + * list_empty - tests whether a list is empty | |
| 55 | + * @head: the list to test. | |
| 56 | + */ | |
| 57 | +static inline int list_empty(const struct list_head *head) | |
| 58 | +{ | |
| 59 | + return head->next == head; | |
| 60 | +} | |
| 61 | + | |
| 62 | +/* | |
| 63 | + * Insert a new entry between two known consecutive entries. | |
| 64 | + * | |
| 65 | + * This is only for internal list manipulation where we know | |
| 66 | + * the prev/next entries already! | |
| 67 | + */ | |
| 68 | +static inline void __list_add(struct list_head *_new, | |
| 69 | + struct list_head *prev, | |
| 70 | + struct list_head *next) | |
| 71 | +{ | |
| 72 | + next->prev = _new; | |
| 73 | + _new->next = next; | |
| 74 | + _new->prev = prev; | |
| 75 | + prev->next = _new; | |
| 76 | +} | |
| 77 | + | |
| 78 | +/** | |
| 79 | + * list_add_tail - add a new entry | |
| 80 | + * @new: new entry to be added | |
| 81 | + * @head: list head to add it before | |
| 82 | + * | |
| 83 | + * Insert a new entry before the specified head. | |
| 84 | + * This is useful for implementing queues. | |
| 85 | + */ | |
| 86 | +static inline void list_add_tail(struct list_head *_new, struct list_head *head) | |
| 87 | +{ | |
| 88 | + __list_add(_new, head->prev, head); | |
| 89 | +} | |
| 90 | + | |
| 91 | +#endif | |
| @@ -21,9 +21,9 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu)); · 20 unmodified lines | ||
| 21 | 21 | P(menu_get_parent_menu,struct menu *,(struct menu *menu)); |
| 22 | 22 | P(menu_has_help,bool,(struct menu *menu)); |
| 23 | 23 | P(menu_get_help,const char *,(struct menu *menu)); |
| 24 | −P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head | |
| 24 | +P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head | |
| 25 | 25 | *head)); |
| 26 | −P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head | |
| 26 | +P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head | |
| 27 | 27 | *head)); |
| 28 | 28 | P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); |
| 29 | 29 | |
| @@ -312,7 +312,7 @@ static void set_config_filename(const char *config_filename) · 311 unmodified lines | ||
| 312 | 312 | |
| 313 | 313 | |
| 314 | 314 | struct search_data { |
| 315 | − struct jk_head *head; | |
| 315 | + struct list_head *head; | |
| 316 | 316 | struct menu **targets; |
| 317 | 317 | int *keys; |
| 318 | 318 | }; |
| @@ -323,7 +323,7 @@ static void update_text(char *buf, size_t start, size_t end, void *_data) · 4 unmodified lines | ||
| 323 | 323 | struct jump_key *pos; |
| 324 | 324 | int k = 0; |
| 325 | 325 | |
| 326 | − CIRCLEQ_FOREACH(pos, data->head, entries) { | |
| 326 | + list_for_each_entry(pos, data->head, entries) { | |
| 327 | 327 | if (pos->offset >= start && pos->offset < end) { |
| 328 | 328 | char header[4]; |
| 329 | 329 | |
| @@ -375,7 +375,7 @@ again: · 45 unmodified lines | ||
| 375 | 375 | |
| 376 | 376 | sym_arr = sym_re_search(dialog_input); |
| 377 | 377 | do { |
| 378 | − struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head); | |
| 378 | + LIST_HEAD(head); | |
| 379 | 379 | struct menu *targets[JUMP_NB]; |
| 380 | 380 | int keys[JUMP_NB + 1], i; |
| 381 | 381 | struct search_data data = { |
| @@ -508,7 +508,7 @@ const char *menu_get_help(struct menu *menu) · 507 unmodified lines | ||
| 508 | 508 | } |
| 509 | 509 | |
| 510 | 510 | static void get_prompt_str(struct gstr *r, struct property *prop, |
| 511 | − struct jk_head *head) | |
| 511 | + struct list_head *head) | |
| 512 | 512 | { |
| 513 | 513 | int i, j; |
| 514 | 514 | struct menu *submenu[8], *menu, *location = NULL; |
| @@ -544,12 +544,13 @@ static void get_prompt_str(struct gstr *r, struct property *prop, · 29 unmodified lines | ||
| 544 | 544 | } else |
| 545 | 545 | jump->target = location; |
| 546 | 546 | |
| 547 | − if (CIRCLEQ_EMPTY(head)) | |
| 547 | + if (list_empty(head)) | |
| 548 | 548 | jump->index = 0; |
| 549 | 549 | else |
| 550 | − jump->index = CIRCLEQ_LAST(head)->index + 1; | |
| 550 | + jump->index = list_entry(head->prev, struct jump_key, | |
| 551 | + entries)->index + 1; | |
| 551 | 552 | |
| 552 | − CIRCLEQ_INSERT_TAIL(head, jump, entries); | |
| 553 | + list_add_tail(&jump->entries, head); | |
| 553 | 554 | } |
| 554 | 555 | |
| 555 | 556 | if (i > 0) { |
| @@ -573,7 +574,8 @@ static void get_prompt_str(struct gstr *r, struct property *prop, · 17 unmodified lines | ||
| 573 | 574 | /* |
| 574 | 575 | * head is optional and may be NULL |
| 575 | 576 | */ |
| 576 | −void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) | |
| 577 | +void get_symbol_str(struct gstr *r, struct symbol *sym, | |
| 578 | + struct list_head *head) | |
| 577 | 579 | { |
| 578 | 580 | bool hit; |
| 579 | 581 | struct property *prop; |
| @@ -612,7 +614,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) · 32 unmodified lines | ||
| 612 | 614 | str_append(r, "\n\n"); |
| 613 | 615 | } |
| 614 | 616 | |
| 615 | −struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head) | |
| 617 | +struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) | |
| 616 | 618 | { |
| 617 | 619 | struct symbol *sym; |
| 618 | 620 | struct gstr res = str_new(); |
| @@ -164,8 +164,8 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup) · 163 unmodified lines | ||
| 164 | 164 | struct dev_exception_item *ex, *tmp; |
| 165 | 165 | |
| 166 | 166 | list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) { |
| 167 | − list_del(&ex->list); | |
| 168 | − kfree(ex); | |
| 167 | + list_del_rcu(&ex->list); | |
| 168 | + kfree_rcu(ex, rcu); | |
| 169 | 169 | } |
| 170 | 170 | } |
| 171 | 171 | |
| @@ -298,7 +298,7 @@ static int may_access(struct dev_cgroup *dev_cgroup, · 126 unmodified lines | ||
| 298 | 298 | struct dev_exception_item *ex; |
| 299 | 299 | bool match = false; |
| 300 | 300 | |
| 301 | − list_for_each_entry(ex, &dev_cgroup->exceptions, list) { | |
| 301 | + list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) { | |
| 302 | 302 | if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) |
| 303 | 303 | continue; |
| 304 | 304 | if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR)) |
| @@ -352,6 +352,8 @@ static int parent_has_perm(struct dev_cgroup *childcg, · 47 unmodified lines | ||
| 352 | 352 | */ |
| 353 | 353 | static inline int may_allow_all(struct dev_cgroup *parent) |
| 354 | 354 | { |
| 355 | + if (!parent) | |
| 356 | + return 1; | |
| 355 | 357 | return parent->behavior == DEVCG_DEFAULT_ALLOW; |
| 356 | 358 | } |
| 357 | 359 | |
| @@ -376,11 +378,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, · 18 unmodified lines | ||
| 376 | 378 | int count, rc; |
| 377 | 379 | struct dev_exception_item ex; |
| 378 | 380 | struct cgroup *p = devcgroup->css.cgroup; |
| 379 | − struct dev_cgroup *parent = cgroup_to_devcgroup(p->parent); | |
| 381 | + struct dev_cgroup *parent = NULL; | |
| 380 | 382 | |
| 381 | 383 | if (!capable(CAP_SYS_ADMIN)) |
| 382 | 384 | return -EPERM; |
| 383 | 385 | |
| 386 | + if (p->parent) | |
| 387 | + parent = cgroup_to_devcgroup(p->parent); | |
| 388 | + | |
| 384 | 389 | memset(&ex, 0, sizeof(ex)); |
| 385 | 390 | b = buffer; |
| 386 | 391 | |
| @@ -391,11 +396,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, · 4 unmodified lines | ||
| 391 | 396 | if (!may_allow_all(parent)) |
| 392 | 397 | return -EPERM; |
| 393 | 398 | dev_exception_clean(devcgroup); |
| 399 | + devcgroup->behavior = DEVCG_DEFAULT_ALLOW; | |
| 400 | + if (!parent) | |
| 401 | + break; | |
| 402 | + | |
| 394 | 403 | rc = dev_exceptions_copy(&devcgroup->exceptions, |
| 395 | 404 | &parent->exceptions); |
| 396 | 405 | if (rc) |
| 397 | 406 | return rc; |
| 398 | − devcgroup->behavior = DEVCG_DEFAULT_ALLOW; | |
| 399 | 407 | break; |
| 400 | 408 | case DEVCG_DENY: |
| 401 | 409 | dev_exception_clean(devcgroup); |
| @@ -76,6 +76,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) · 75 unmodified lines | ||
| 76 | 76 | snd_card_unref(card); |
| 77 | 77 | return -EFAULT; |
| 78 | 78 | } |
| 79 | + snd_card_unref(card); | |
| 79 | 80 | return 0; |
| 80 | 81 | } |
| 81 | 82 | |
| @@ -2454,6 +2454,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) · 2453 unmodified lines | ||
| 2454 | 2454 | mutex_unlock(&pcm->open_mutex); |
| 2455 | 2455 | if (err < 0) |
| 2456 | 2456 | goto __error; |
| 2457 | + snd_card_unref(pcm->card); | |
| 2457 | 2458 | return err; |
| 2458 | 2459 | |
| 2459 | 2460 | __error: |
| @@ -2122,7 +2122,8 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file) · 2121 unmodified lines | ||
| 2122 | 2122 | pcm = snd_lookup_minor_data(iminor(inode), |
| 2123 | 2123 | SNDRV_DEVICE_TYPE_PCM_PLAYBACK); |
| 2124 | 2124 | err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); |
| 2125 | − snd_card_unref(pcm->card); | |
| 2125 | + if (pcm) | |
| 2126 | + snd_card_unref(pcm->card); | |
| 2126 | 2127 | return err; |
| 2127 | 2128 | } |
| 2128 | 2129 | |
| @@ -2135,7 +2136,8 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file) · 6 unmodified lines | ||
| 2135 | 2136 | pcm = snd_lookup_minor_data(iminor(inode), |
| 2136 | 2137 | SNDRV_DEVICE_TYPE_PCM_CAPTURE); |
| 2137 | 2138 | err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); |
| 2138 | − snd_card_unref(pcm->card); | |
| 2139 | + if (pcm) | |
| 2140 | + snd_card_unref(pcm->card); | |
| 2139 | 2141 | return err; |
| 2140 | 2142 | } |
| 2141 | 2143 | |
| @@ -114,7 +114,7 @@ void *snd_lookup_minor_data(unsigned int minor, int type) · 113 unmodified lines | ||
| 114 | 114 | mreg = snd_minors[minor]; |
| 115 | 115 | if (mreg && mreg->type == type) { |
| 116 | 116 | private_data = mreg->private_data; |
| 117 | − if (mreg->card_ptr) | |
| 117 | + if (private_data && mreg->card_ptr) | |
| 118 | 118 | atomic_inc(&mreg->card_ptr->refcount); |
| 119 | 119 | } else |
| 120 | 120 | private_data = NULL; |
| @@ -54,7 +54,7 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) · 53 unmodified lines | ||
| 54 | 54 | mreg = snd_oss_minors[minor]; |
| 55 | 55 | if (mreg && mreg->type == type) { |
| 56 | 56 | private_data = mreg->private_data; |
| 57 | − if (mreg->card_ptr) | |
| 57 | + if (private_data && mreg->card_ptr) | |
| 58 | 58 | atomic_inc(&mreg->card_ptr->refcount); |
| 59 | 59 | } else |
| 60 | 60 | private_data = NULL; |
| @@ -426,7 +426,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { · 425 unmodified lines | ||
| 426 | 426 | }, |
| 427 | 427 | { |
| 428 | 428 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 429 | − .name = "IEC958 Preample Capture Default", | |
| 429 | + .name = "IEC958 Preamble Capture Default", | |
| 430 | 430 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
| 431 | 431 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
| 432 | 432 | .info = snd_ak4113_spdif_pinfo, |
| @@ -401,7 +401,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { · 400 unmodified lines | ||
| 401 | 401 | }, |
| 402 | 402 | { |
| 403 | 403 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 404 | − .name = "IEC958 Preample Capture Default", | |
| 404 | + .name = "IEC958 Preamble Capture Default", | |
| 405 | 405 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
| 406 | 406 | .info = snd_ak4114_spdif_pinfo, |
| 407 | 407 | .get = snd_ak4114_spdif_pget, |
| @@ -380,7 +380,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { · 379 unmodified lines | ||
| 380 | 380 | }, |
| 381 | 381 | { |
| 382 | 382 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 383 | − .name = "IEC958 Preample Capture Default", | |
| 383 | + .name = "IEC958 Preamble Capture Default", | |
| 384 | 384 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
| 385 | 385 | .info = snd_ak4117_spdif_pinfo, |
| 386 | 386 | .get = snd_ak4117_spdif_pget, |
| @@ -2581,9 +2581,14 @@ static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea) · 2580 unmodified lines | ||
| 2581 | 2581 | struct es1968 *chip = tea->private_data; |
| 2582 | 2582 | unsigned long io = chip->io_port + GPIO_DATA; |
| 2583 | 2583 | u16 val = inw(io); |
| 2584 | + u8 ret; | |
| 2584 | 2585 | |
| 2585 | − return (val & STR_DATA) ? TEA575X_DATA : 0 | | |
| 2586 | − (val & STR_MOST) ? TEA575X_MOST : 0; | |
| 2586 | + ret = 0; | |
| 2587 | + if (val & STR_DATA) | |
| 2588 | + ret |= TEA575X_DATA; | |
| 2589 | + if (val & STR_MOST) | |
| 2590 | + ret |= TEA575X_MOST; | |
| 2591 | + return ret; | |
| 2587 | 2592 | } |
| 2588 | 2593 | |
| 2589 | 2594 | static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output) |
| @@ -2655,6 +2660,8 @@ static struct ess_device_list pm_whitelist[] __devinitdata = { · 65 unmodified lines | ||
| 2655 | 2660 | { TYPE_MAESTRO2E, 0x1179 }, |
| 2656 | 2661 | { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */ |
| 2657 | 2662 | { TYPE_MAESTRO2E, 0x1558 }, |
| 2663 | + { TYPE_MAESTRO2E, 0x125d }, /* a PCI card, e.g. Terratec DMX */ | |
| 2664 | + { TYPE_MAESTRO2, 0x125d }, /* a PCI card, e.g. SF64-PCE2 */ | |
| 2658 | 2665 | }; |
| 2659 | 2666 | |
| 2660 | 2667 | static struct ess_device_list mpu_blacklist[] __devinitdata = { |
| @@ -767,9 +767,14 @@ static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) · 766 unmodified lines | ||
| 767 | 767 | struct fm801 *chip = tea->private_data; |
| 768 | 768 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
| 769 | 769 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); |
| 770 | − | |
| 771 | − return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | | |
| 772 | − (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; | |
| 770 | + u8 ret; | |
| 771 | + | |
| 772 | + ret = 0; | |
| 773 | + if (reg & FM801_GPIO_GP(gpio.data)) | |
| 774 | + ret |= TEA575X_DATA; | |
| 775 | + if (reg & FM801_GPIO_GP(gpio.most)) | |
| 776 | + ret |= TEA575X_MOST; | |
| 777 | + return ret; | |
| 773 | 778 | } |
| 774 | 779 | |
| 775 | 780 | static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) |
| @@ -3563,6 +3563,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { · 3562 unmodified lines | ||
| 3563 | 3563 | /* Teradici */ |
| 3564 | 3564 | { PCI_DEVICE(0x6549, 0x1200), |
| 3565 | 3565 | .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, |
| 3566 | + { PCI_DEVICE(0x6549, 0x2200), | |
| 3567 | + .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, | |
| 3566 | 3568 | /* Creative X-Fi (CA0110-IBG) */ |
| 3567 | 3569 | /* CTHDA chips */ |
| 3568 | 3570 | { PCI_DEVICE(0x1102, 0x0010), |
| @@ -545,6 +545,7 @@ static int ad198x_build_pcms(struct hda_codec *codec) · 544 unmodified lines | ||
| 545 | 545 | if (spec->multiout.dig_out_nid) { |
| 546 | 546 | info++; |
| 547 | 547 | codec->num_pcms++; |
| 548 | + codec->spdif_status_reset = 1; | |
| 548 | 549 | info->name = "AD198x Digital"; |
| 549 | 550 | info->pcm_type = HDA_PCM_TYPE_SPDIF; |
| 550 | 551 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; |
| @@ -101,8 +101,8 @@ enum { · 100 unmodified lines | ||
| 101 | 101 | #define CS420X_VENDOR_NID 0x11 |
| 102 | 102 | #define CS_DIG_OUT1_PIN_NID 0x10 |
| 103 | 103 | #define CS_DIG_OUT2_PIN_NID 0x15 |
| 104 | −#define CS_DMIC1_PIN_NID 0x12 | |
| 105 | −#define CS_DMIC2_PIN_NID 0x0e | |
| 104 | +#define CS_DMIC1_PIN_NID 0x0e | |
| 105 | +#define CS_DMIC2_PIN_NID 0x12 | |
| 106 | 106 | |
| 107 | 107 | /* coef indices */ |
| 108 | 108 | #define IDX_SPDIF_STAT 0x0000 |
| @@ -1079,14 +1079,18 @@ static void init_input(struct hda_codec *codec) · 970 unmodified lines | ||
| 1079 | 1079 | cs_automic(codec, NULL); |
| 1080 | 1080 | |
| 1081 | 1081 | coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ |
| 1082 | + cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); | |
| 1083 | + | |
| 1084 | + coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); | |
| 1082 | 1085 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) |
| 1083 | − coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */ | |
| 1086 | + coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ | |
| 1084 | 1087 | if (is_active_pin(codec, CS_DMIC1_PIN_NID)) |
| 1085 | − coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off | |
| 1088 | + coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off | |
| 1086 | 1089 | * No effect if SPDIF_OUT2 is |
| 1087 | 1090 | * selected in IDX_SPDIF_CTL. |
| 1088 | 1091 | */ |
| 1089 | − cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); | |
| 1092 | + | |
| 1093 | + cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); | |
| 1090 | 1094 | } else { |
| 1091 | 1095 | if (spec->mic_detect) |
| 1092 | 1096 | cs_automic(codec, NULL); |
| @@ -1107,7 +1111,7 @@ static const struct hda_verb cs_coef_init_verbs[] = { · 14 unmodified lines | ||
| 1107 | 1111 | | 0x0400 /* Disable Coefficient Auto increment */ |
| 1108 | 1112 | )}, |
| 1109 | 1113 | /* Beep */ |
| 1110 | − {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, | |
| 1114 | + {0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG}, | |
| 1111 | 1115 | {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ |
| 1112 | 1116 | |
| 1113 | 1117 | {} /* terminator */ |
| @@ -1728,8 +1732,7 @@ static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol, · 614 unmodified lines | ||
| 1728 | 1732 | |
| 1729 | 1733 | } |
| 1730 | 1734 | |
| 1731 | −static struct snd_kcontrol_new cs421x_capture_source = { | |
| 1732 | − | |
| 1735 | +static const struct snd_kcontrol_new cs421x_capture_source = { | |
| 1733 | 1736 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 1734 | 1737 | .name = "Capture Source", |
| 1735 | 1738 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
| @@ -1946,7 +1949,7 @@ static int cs421x_suspend(struct hda_codec *codec) · 210 unmodified lines | ||
| 1946 | 1949 | } |
| 1947 | 1950 | #endif |
| 1948 | 1951 | |
| 1949 | −static struct hda_codec_ops cs421x_patch_ops = { | |
| 1952 | +static const struct hda_codec_ops cs421x_patch_ops = { | |
| 1950 | 1953 | .build_controls = cs421x_build_controls, |
| 1951 | 1954 | .build_pcms = cs_build_pcms, |
| 1952 | 1955 | .init = cs421x_init, |
| @@ -5407,6 +5407,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { · 5406 unmodified lines | ||
| 5407 | 5407 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), |
| 5408 | 5408 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), |
| 5409 | 5409 | SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), |
| 5410 | + SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), | |
| 5410 | 5411 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), |
| 5411 | 5412 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), |
| 5412 | 5413 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), |
| @@ -5840,7 +5841,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) · 427 unmodified lines | ||
| 5840 | 5841 | return alc_parse_auto_config(codec, alc269_ignore, ssids); |
| 5841 | 5842 | } |
| 5842 | 5843 | |
| 5843 | −static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) | |
| 5844 | +static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) | |
| 5844 | 5845 | { |
| 5845 | 5846 | int val = alc_read_coef_idx(codec, 0x04); |
| 5846 | 5847 | if (power_up) |
| @@ -5857,10 +5858,10 @@ static void alc269_shutup(struct hda_codec *codec) · 10 unmodified lines | ||
| 5857 | 5858 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) |
| 5858 | 5859 | return; |
| 5859 | 5860 | |
| 5860 | − if ((alc_get_coef0(codec) & 0x00ff) == 0x017) | |
| 5861 | − alc269_toggle_power_output(codec, 0); | |
| 5862 | − if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { | |
| 5863 | − alc269_toggle_power_output(codec, 0); | |
| 5861 | + if (spec->codec_variant == ALC269_TYPE_ALC269VB) | |
| 5862 | + alc269vb_toggle_power_output(codec, 0); | |
| 5863 | + if (spec->codec_variant == ALC269_TYPE_ALC269VB && | |
| 5864 | + (alc_get_coef0(codec) & 0x00ff) == 0x018) { | |
| 5864 | 5865 | msleep(150); |
| 5865 | 5866 | } |
| 5866 | 5867 | } |
| @@ -5870,24 +5871,22 @@ static int alc269_resume(struct hda_codec *codec) · 3 unmodified lines | ||
| 5870 | 5871 | { |
| 5871 | 5872 | struct alc_spec *spec = codec->spec; |
| 5872 | 5873 | |
| 5873 | − if (spec->codec_variant == ALC269_TYPE_ALC269VB || | |
| 5874 | + if (spec->codec_variant == ALC269_TYPE_ALC269VB) | |
| 5875 | + alc269vb_toggle_power_output(codec, 0); | |
| 5876 | + if (spec->codec_variant == ALC269_TYPE_ALC269VB && | |
| 5874 | 5877 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { |
| 5875 | − alc269_toggle_power_output(codec, 0); | |
| 5876 | 5878 | msleep(150); |
| 5877 | 5879 | } |
| 5878 | 5880 | |
| 5879 | 5881 | codec->patch_ops.init(codec); |
| 5880 | 5882 | |
| 5881 | − if (spec->codec_variant == ALC269_TYPE_ALC269VB || | |
| 5883 | + if (spec->codec_variant == ALC269_TYPE_ALC269VB) | |
| 5884 | + alc269vb_toggle_power_output(codec, 1); | |
| 5885 | + if (spec->codec_variant == ALC269_TYPE_ALC269VB && | |
| 5882 | 5886 | (alc_get_coef0(codec) & 0x00ff) == 0x017) { |
| 5883 | − alc269_toggle_power_output(codec, 1); | |
| 5884 | 5887 | msleep(200); |
| 5885 | 5888 | } |
| 5886 | 5889 | |
| 5887 | − if (spec->codec_variant == ALC269_TYPE_ALC269VB || | |
| 5888 | − (alc_get_coef0(codec) & 0x00ff) == 0x018) | |
| 5889 | − alc269_toggle_power_output(codec, 1); | |
| 5890 | − | |
| 5891 | 5890 | snd_hda_codec_resume_amp(codec); |
| 5892 | 5891 | snd_hda_codec_resume_cache(codec); |
| 5893 | 5892 | hda_call_check_power_status(codec, 0x01); |
| @@ -7079,6 +7078,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { · 1185 unmodified lines | ||
| 7079 | 7078 | .patch = patch_alc662 }, |
| 7080 | 7079 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
| 7081 | 7080 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, |
| 7081 | + { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, | |
| 7082 | 7082 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, |
| 7083 | 7083 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, |
| 7084 | 7084 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
| @@ -7096,6 +7096,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { · 11 unmodified lines | ||
| 7096 | 7096 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
| 7097 | 7097 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, |
| 7098 | 7098 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, |
| 7099 | + { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, | |
| 7099 | 7100 | {} /* terminator */ |
| 7100 | 7101 | }; |
| 7101 | 7102 | |
| @@ -1809,11 +1809,11 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) · 1808 unmodified lines | ||
| 1809 | 1809 | { |
| 1810 | 1810 | struct via_spec *spec = codec->spec; |
| 1811 | 1811 | const struct auto_pin_cfg *cfg = &spec->autocfg; |
| 1812 | − int i, dac_num; | |
| 1812 | + int i; | |
| 1813 | 1813 | hda_nid_t nid; |
| 1814 | 1814 | |
| 1815 | + spec->multiout.num_dacs = 0; | |
| 1815 | 1816 | spec->multiout.dac_nids = spec->private_dac_nids; |
| 1816 | − dac_num = 0; | |
| 1817 | 1817 | for (i = 0; i < cfg->line_outs; i++) { |
| 1818 | 1818 | hda_nid_t dac = 0; |
| 1819 | 1819 | nid = cfg->line_out_pins[i]; |
| @@ -1824,16 +1824,13 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) · 4 unmodified lines | ||
| 1824 | 1824 | if (!i && parse_output_path(codec, nid, dac, 1, |
| 1825 | 1825 | &spec->out_mix_path)) |
| 1826 | 1826 | dac = spec->out_mix_path.path[0]; |
| 1827 | − if (dac) { | |
| 1828 | − spec->private_dac_nids[i] = dac; | |
| 1829 | − dac_num++; | |
| 1830 | − } | |
| 1827 | + if (dac) | |
| 1828 | + spec->private_dac_nids[spec->multiout.num_dacs++] = dac; | |
| 1831 | 1829 | } |
| 1832 | 1830 | if (!spec->out_path[0].depth && spec->out_mix_path.depth) { |
| 1833 | 1831 | spec->out_path[0] = spec->out_mix_path; |
| 1834 | 1832 | spec->out_mix_path.depth = 0; |
| 1835 | 1833 | } |
| 1836 | − spec->multiout.num_dacs = dac_num; | |
| 1837 | 1834 | return 0; |
| 1838 | 1835 | } |
| 1839 | 1836 | |
| @@ -3628,6 +3625,7 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) · 1788 unmodified lines | ||
| 3628 | 3625 | */ |
| 3629 | 3626 | enum { |
| 3630 | 3627 | VIA_FIXUP_INTMIC_BOOST, |
| 3628 | + VIA_FIXUP_ASUS_G75, | |
| 3631 | 3629 | }; |
| 3632 | 3630 | |
| 3633 | 3631 | static void via_fixup_intmic_boost(struct hda_codec *codec, |
| @@ -3642,13 +3640,35 @@ static const struct hda_fixup via_fixups[] = { · 8 unmodified lines | ||
| 3642 | 3640 | .type = HDA_FIXUP_FUNC, |
| 3643 | 3641 | .v.func = via_fixup_intmic_boost, |
| 3644 | 3642 | }, |
| 3643 | + [VIA_FIXUP_ASUS_G75] = { | |
| 3644 | + .type = HDA_FIXUP_PINS, | |
| 3645 | + .v.pins = (const struct hda_pintbl[]) { | |
| 3646 | + /* set 0x24 and 0x33 as speakers */ | |
| 3647 | + { 0x24, 0x991301f0 }, | |
| 3648 | + { 0x33, 0x991301f1 }, /* subwoofer */ | |
| 3649 | + { } | |
| 3650 | + } | |
| 3651 | + }, | |
| 3645 | 3652 | }; |
| 3646 | 3653 | |
| 3647 | 3654 | static const struct snd_pci_quirk vt2002p_fixups[] = { |
| 3655 | + SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75), | |
| 3648 | 3656 | SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), |
| 3649 | 3657 | {} |
| 3650 | 3658 | }; |
| 3651 | 3659 | |
| 3660 | +/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e | |
| 3661 | + * Replace this with mixer NID 0x1c | |
| 3662 | + */ | |
| 3663 | +static void fix_vt1802_connections(struct hda_codec *codec) | |
| 3664 | +{ | |
| 3665 | + static hda_nid_t conn_24[] = { 0x14, 0x1c }; | |
| 3666 | + static hda_nid_t conn_33[] = { 0x1c }; | |
| 3667 | + | |
| 3668 | + snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24); | |
| 3669 | + snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33); | |
| 3670 | +} | |
| 3671 | + | |
| 3652 | 3672 | /* patch for vt2002P */ |
| 3653 | 3673 | static int patch_vt2002P(struct hda_codec *codec) |
| 3654 | 3674 | { |
| @@ -3663,6 +3683,8 @@ static int patch_vt2002P(struct hda_codec *codec) · 8 unmodified lines | ||
| 3663 | 3683 | spec->aa_mix_nid = 0x21; |
| 3664 | 3684 | override_mic_boost(codec, 0x2b, 0, 3, 40); |
| 3665 | 3685 | override_mic_boost(codec, 0x29, 0, 3, 40); |
| 3686 | + if (spec->codec_type == VT1802) | |
| 3687 | + fix_vt1802_connections(codec); | |
| 3666 | 3688 | add_secret_dac_path(codec); |
| 3667 | 3689 | |
| 3668 | 3690 | snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups); |
| @@ -3979,7 +3979,8 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, · 3978 unmodified lines | ||
| 3979 | 3979 | case 8: /* SYNC IN */ |
| 3980 | 3980 | val = hdspm_sync_in_sync_check(hdspm); break; |
| 3981 | 3981 | default: |
| 3982 | − val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); | |
| 3982 | + val = hdspm_s1_sync_check(hdspm, | |
| 3983 | + kcontrol->private_value-1); | |
| 3983 | 3984 | } |
| 3984 | 3985 | break; |
| 3985 | 3986 | |
| @@ -4899,7 +4900,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, · 913 unmodified lines | ||
| 4899 | 4900 | insel = "Coaxial"; |
| 4900 | 4901 | break; |
| 4901 | 4902 | default: |
| 4902 | − insel = "Unkown"; | |
| 4903 | + insel = "Unknown"; | |
| 4903 | 4904 | } |
| 4904 | 4905 | |
| 4905 | 4906 | snd_iprintf(buffer, |
| @@ -763,7 +763,7 @@ static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai, · 762 unmodified lines | ||
| 763 | 763 | if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) { |
| 764 | 764 | cs42l52->sysclk = freq; |
| 765 | 765 | } else { |
| 766 | − dev_err(codec->dev, "Invalid freq paramter\n"); | |
| 766 | + dev_err(codec->dev, "Invalid freq parameter\n"); | |
| 767 | 767 | return -EINVAL; |
| 768 | 768 | } |
| 769 | 769 | return 0; |
| @@ -773,7 +773,6 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) · 3 unmodified lines | ||
| 773 | 773 | { |
| 774 | 774 | struct snd_soc_codec *codec = codec_dai->codec; |
| 775 | 775 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); |
| 776 | − int ret = 0; | |
| 777 | 776 | u8 iface = 0; |
| 778 | 777 | |
| 779 | 778 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
| @@ -822,7 +821,7 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) · 42 unmodified lines | ||
| 822 | 821 | case SND_SOC_DAIFMT_NB_IF: |
| 823 | 822 | break; |
| 824 | 823 | default: |
| 825 | − ret = -EINVAL; | |
| 824 | + return -EINVAL; | |
| 826 | 825 | } |
| 827 | 826 | cs42l52->config.format = iface; |
| 828 | 827 | snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format); |
| @@ -42,6 +42,556 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); · 41 unmodified lines | ||
| 42 | 42 | static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); |
| 43 | 43 | static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); |
| 44 | 44 | |
| 45 | +static const struct reg_default wm5102_sysclk_reva_patch[] = { | |
| 46 | + { 0x3000, 0x2225 }, | |
| 47 | + { 0x3001, 0x3a03 }, | |
| 48 | + { 0x3002, 0x0225 }, | |
| 49 | + { 0x3003, 0x0801 }, | |
| 50 | + { 0x3004, 0x6249 }, | |
| 51 | + { 0x3005, 0x0c04 }, | |
| 52 | + { 0x3006, 0x0225 }, | |
| 53 | + { 0x3007, 0x5901 }, | |
| 54 | + { 0x3008, 0xe249 }, | |
| 55 | + { 0x3009, 0x030d }, | |
| 56 | + { 0x300a, 0x0249 }, | |
| 57 | + { 0x300b, 0x2c01 }, | |
| 58 | + { 0x300c, 0xe249 }, | |
| 59 | + { 0x300d, 0x4342 }, | |
| 60 | + { 0x300e, 0xe249 }, | |
| 61 | + { 0x300f, 0x73c0 }, | |
| 62 | + { 0x3010, 0x4249 }, | |
| 63 | + { 0x3011, 0x0c00 }, | |
| 64 | + { 0x3012, 0x0225 }, | |
| 65 | + { 0x3013, 0x1f01 }, | |
| 66 | + { 0x3014, 0x0225 }, | |
| 67 | + { 0x3015, 0x1e01 }, | |
| 68 | + { 0x3016, 0x0225 }, | |
| 69 | + { 0x3017, 0xfa00 }, | |
| 70 | + { 0x3018, 0x0000 }, | |
| 71 | + { 0x3019, 0xf000 }, | |
| 72 | + { 0x301a, 0x0000 }, | |
| 73 | + { 0x301b, 0xf000 }, | |
| 74 | + { 0x301c, 0x0000 }, | |
| 75 | + { 0x301d, 0xf000 }, | |
| 76 | + { 0x301e, 0x0000 }, | |
| 77 | + { 0x301f, 0xf000 }, | |
| 78 | + { 0x3020, 0x0000 }, | |
| 79 | + { 0x3021, 0xf000 }, | |
| 80 | + { 0x3022, 0x0000 }, | |
| 81 | + { 0x3023, 0xf000 }, | |
| 82 | + { 0x3024, 0x0000 }, | |
| 83 | + { 0x3025, 0xf000 }, | |
| 84 | + { 0x3026, 0x0000 }, | |
| 85 | + { 0x3027, 0xf000 }, | |
| 86 | + { 0x3028, 0x0000 }, | |
| 87 | + { 0x3029, 0xf000 }, | |
| 88 | + { 0x302a, 0x0000 }, | |
| 89 | + { 0x302b, 0xf000 }, | |
| 90 | + { 0x302c, 0x0000 }, | |
| 91 | + { 0x302d, 0xf000 }, | |
| 92 | + { 0x302e, 0x0000 }, | |
| 93 | + { 0x302f, 0xf000 }, | |
| 94 | + { 0x3030, 0x0225 }, | |
| 95 | + { 0x3031, 0x1a01 }, | |
| 96 | + { 0x3032, 0x0225 }, | |
| 97 | + { 0x3033, 0x1e00 }, | |
| 98 | + { 0x3034, 0x0225 }, | |
| 99 | + { 0x3035, 0x1f00 }, | |
| 100 | + { 0x3036, 0x6225 }, | |
| 101 | + { 0x3037, 0xf800 }, | |
| 102 | + { 0x3038, 0x0000 }, | |
| 103 | + { 0x3039, 0xf000 }, | |
| 104 | + { 0x303a, 0x0000 }, | |
| 105 | + { 0x303b, 0xf000 }, | |
| 106 | + { 0x303c, 0x0000 }, | |
| 107 | + { 0x303d, 0xf000 }, | |
| 108 | + { 0x303e, 0x0000 }, | |
| 109 | + { 0x303f, 0xf000 }, | |
| 110 | + { 0x3040, 0x2226 }, | |
| 111 | + { 0x3041, 0x3a03 }, | |
| 112 | + { 0x3042, 0x0226 }, | |
| 113 | + { 0x3043, 0x0801 }, | |
| 114 | + { 0x3044, 0x6249 }, | |
| 115 | + { 0x3045, 0x0c06 }, | |
| 116 | + { 0x3046, 0x0226 }, | |
| 117 | + { 0x3047, 0x5901 }, | |
| 118 | + { 0x3048, 0xe249 }, | |
| 119 | + { 0x3049, 0x030d }, | |
| 120 | + { 0x304a, 0x0249 }, | |
| 121 | + { 0x304b, 0x2c01 }, | |
| 122 | + { 0x304c, 0xe249 }, | |
| 123 | + { 0x304d, 0x4342 }, | |
| 124 | + { 0x304e, 0xe249 }, | |
| 125 | + { 0x304f, 0x73c0 }, | |
| 126 | + { 0x3050, 0x4249 }, | |
| 127 | + { 0x3051, 0x0c00 }, | |
| 128 | + { 0x3052, 0x0226 }, | |
| 129 | + { 0x3053, 0x1f01 }, | |
| 130 | + { 0x3054, 0x0226 }, | |
| 131 | + { 0x3055, 0x1e01 }, | |
| 132 | + { 0x3056, 0x0226 }, | |
| 133 | + { 0x3057, 0xfa00 }, | |
| 134 | + { 0x3058, 0x0000 }, | |
| 135 | + { 0x3059, 0xf000 }, | |
| 136 | + { 0x305a, 0x0000 }, | |
| 137 | + { 0x305b, 0xf000 }, | |
| 138 | + { 0x305c, 0x0000 }, | |
| 139 | + { 0x305d, 0xf000 }, | |
| 140 | + { 0x305e, 0x0000 }, | |
| 141 | + { 0x305f, 0xf000 }, | |
| 142 | + { 0x3060, 0x0000 }, | |
| 143 | + { 0x3061, 0xf000 }, | |
| 144 | + { 0x3062, 0x0000 }, | |
| 145 | + { 0x3063, 0xf000 }, | |
| 146 | + { 0x3064, 0x0000 }, | |
| 147 | + { 0x3065, 0xf000 }, | |
| 148 | + { 0x3066, 0x0000 }, | |
| 149 | + { 0x3067, 0xf000 }, | |
| 150 | + { 0x3068, 0x0000 }, | |
| 151 | + { 0x3069, 0xf000 }, | |
| 152 | + { 0x306a, 0x0000 }, | |
| 153 | + { 0x306b, 0xf000 }, | |
| 154 | + { 0x306c, 0x0000 }, | |
| 155 | + { 0x306d, 0xf000 }, | |
| 156 | + { 0x306e, 0x0000 }, | |
| 157 | + { 0x306f, 0xf000 }, | |
| 158 | + { 0x3070, 0x0226 }, | |
| 159 | + { 0x3071, 0x1a01 }, | |
| 160 | + { 0x3072, 0x0226 }, | |
| 161 | + { 0x3073, 0x1e00 }, | |
| 162 | + { 0x3074, 0x0226 }, | |
| 163 | + { 0x3075, 0x1f00 }, | |
| 164 | + { 0x3076, 0x6226 }, | |
| 165 | + { 0x3077, 0xf800 }, | |
| 166 | + { 0x3078, 0x0000 }, | |
| 167 | + { 0x3079, 0xf000 }, | |
| 168 | + { 0x307a, 0x0000 }, | |
| 169 | + { 0x307b, 0xf000 }, | |
| 170 | + { 0x307c, 0x0000 }, | |
| 171 | + { 0x307d, 0xf000 }, | |
| 172 | + { 0x307e, 0x0000 }, | |
| 173 | + { 0x307f, 0xf000 }, | |
| 174 | + { 0x3080, 0x2227 }, | |
| 175 | + { 0x3081, 0x3a03 }, | |
| 176 | + { 0x3082, 0x0227 }, | |
| 177 | + { 0x3083, 0x0801 }, | |
| 178 | + { 0x3084, 0x6255 }, | |
| 179 | + { 0x3085, 0x0c04 }, | |
| 180 | + { 0x3086, 0x0227 }, | |
| 181 | + { 0x3087, 0x5901 }, | |
| 182 | + { 0x3088, 0xe255 }, | |
| 183 | + { 0x3089, 0x030d }, | |
| 184 | + { 0x308a, 0x0255 }, | |
| 185 | + { 0x308b, 0x2c01 }, | |
| 186 | + { 0x308c, 0xe255 }, | |
| 187 | + { 0x308d, 0x4342 }, | |
| 188 | + { 0x308e, 0xe255 }, | |
| 189 | + { 0x308f, 0x73c0 }, | |
| 190 | + { 0x3090, 0x4255 }, | |
| 191 | + { 0x3091, 0x0c00 }, | |
| 192 | + { 0x3092, 0x0227 }, | |
| 193 | + { 0x3093, 0x1f01 }, | |
| 194 | + { 0x3094, 0x0227 }, | |
| 195 | + { 0x3095, 0x1e01 }, | |
| 196 | + { 0x3096, 0x0227 }, | |
| 197 | + { 0x3097, 0xfa00 }, | |
| 198 | + { 0x3098, 0x0000 }, | |
| 199 | + { 0x3099, 0xf000 }, | |
| 200 | + { 0x309a, 0x0000 }, | |
| 201 | + { 0x309b, 0xf000 }, | |
| 202 | + { 0x309c, 0x0000 }, | |
| 203 | + { 0x309d, 0xf000 }, | |
| 204 | + { 0x309e, 0x0000 }, | |
| 205 | + { 0x309f, 0xf000 }, | |
| 206 | + { 0x30a0, 0x0000 }, | |
| 207 | + { 0x30a1, 0xf000 }, | |
| 208 | + { 0x30a2, 0x0000 }, | |
| 209 | + { 0x30a3, 0xf000 }, | |
| 210 | + { 0x30a4, 0x0000 }, | |
| 211 | + { 0x30a5, 0xf000 }, | |
| 212 | + { 0x30a6, 0x0000 }, | |
| 213 | + { 0x30a7, 0xf000 }, | |
| 214 | + { 0x30a8, 0x0000 }, | |
| 215 | + { 0x30a9, 0xf000 }, | |
| 216 | + { 0x30aa, 0x0000 }, | |
| 217 | + { 0x30ab, 0xf000 }, | |
| 218 | + { 0x30ac, 0x0000 }, | |
| 219 | + { 0x30ad, 0xf000 }, | |
| 220 | + { 0x30ae, 0x0000 }, | |
| 221 | + { 0x30af, 0xf000 }, | |
| 222 | + { 0x30b0, 0x0227 }, | |
| 223 | + { 0x30b1, 0x1a01 }, | |
| 224 | + { 0x30b2, 0x0227 }, | |
| 225 | + { 0x30b3, 0x1e00 }, | |
| 226 | + { 0x30b4, 0x0227 }, | |
| 227 | + { 0x30b5, 0x1f00 }, | |
| 228 | + { 0x30b6, 0x6227 }, | |
| 229 | + { 0x30b7, 0xf800 }, | |
| 230 | + { 0x30b8, 0x0000 }, | |
| 231 | + { 0x30b9, 0xf000 }, | |
| 232 | + { 0x30ba, 0x0000 }, | |
| 233 | + { 0x30bb, 0xf000 }, | |
| 234 | + { 0x30bc, 0x0000 }, | |
| 235 | + { 0x30bd, 0xf000 }, | |
| 236 | + { 0x30be, 0x0000 }, | |
| 237 | + { 0x30bf, 0xf000 }, | |
| 238 | + { 0x30c0, 0x2228 }, | |
| 239 | + { 0x30c1, 0x3a03 }, | |
| 240 | + { 0x30c2, 0x0228 }, | |
| 241 | + { 0x30c3, 0x0801 }, | |
| 242 | + { 0x30c4, 0x6255 }, | |
| 243 | + { 0x30c5, 0x0c06 }, | |
| 244 | + { 0x30c6, 0x0228 }, | |
| 245 | + { 0x30c7, 0x5901 }, | |
| 246 | + { 0x30c8, 0xe255 }, | |
| 247 | + { 0x30c9, 0x030d }, | |
| 248 | + { 0x30ca, 0x0255 }, | |
| 249 | + { 0x30cb, 0x2c01 }, | |
| 250 | + { 0x30cc, 0xe255 }, | |
| 251 | + { 0x30cd, 0x4342 }, | |
| 252 | + { 0x30ce, 0xe255 }, | |
| 253 | + { 0x30cf, 0x73c0 }, | |
| 254 | + { 0x30d0, 0x4255 }, | |
| 255 | + { 0x30d1, 0x0c00 }, | |
| 256 | + { 0x30d2, 0x0228 }, | |
| 257 | + { 0x30d3, 0x1f01 }, | |
| 258 | + { 0x30d4, 0x0228 }, | |
| 259 | + { 0x30d5, 0x1e01 }, | |
| 260 | + { 0x30d6, 0x0228 }, | |
| 261 | + { 0x30d7, 0xfa00 }, | |
| 262 | + { 0x30d8, 0x0000 }, | |
| 263 | + { 0x30d9, 0xf000 }, | |
| 264 | + { 0x30da, 0x0000 }, | |
| 265 | + { 0x30db, 0xf000 }, | |
| 266 | + { 0x30dc, 0x0000 }, | |
| 267 | + { 0x30dd, 0xf000 }, | |
| 268 | + { 0x30de, 0x0000 }, | |
| 269 | + { 0x30df, 0xf000 }, | |
| 270 | + { 0x30e0, 0x0000 }, | |
| 271 | + { 0x30e1, 0xf000 }, | |
| 272 | + { 0x30e2, 0x0000 }, | |
| 273 | + { 0x30e3, 0xf000 }, | |
| 274 | + { 0x30e4, 0x0000 }, | |
| 275 | + { 0x30e5, 0xf000 }, | |
| 276 | + { 0x30e6, 0x0000 }, | |
| 277 | + { 0x30e7, 0xf000 }, | |
| 278 | + { 0x30e8, 0x0000 }, | |
| 279 | + { 0x30e9, 0xf000 }, | |
| 280 | + { 0x30ea, 0x0000 }, | |
| 281 | + { 0x30eb, 0xf000 }, | |
| 282 | + { 0x30ec, 0x0000 }, | |
| 283 | + { 0x30ed, 0xf000 }, | |
| 284 | + { 0x30ee, 0x0000 }, | |
| 285 | + { 0x30ef, 0xf000 }, | |
| 286 | + { 0x30f0, 0x0228 }, | |
| 287 | + { 0x30f1, 0x1a01 }, | |
| 288 | + { 0x30f2, 0x0228 }, | |
| 289 | + { 0x30f3, 0x1e00 }, | |
| 290 | + { 0x30f4, 0x0228 }, | |
| 291 | + { 0x30f5, 0x1f00 }, | |
| 292 | + { 0x30f6, 0x6228 }, | |
| 293 | + { 0x30f7, 0xf800 }, | |
| 294 | + { 0x30f8, 0x0000 }, | |
| 295 | + { 0x30f9, 0xf000 }, | |
| 296 | + { 0x30fa, 0x0000 }, | |
| 297 | + { 0x30fb, 0xf000 }, | |
| 298 | + { 0x30fc, 0x0000 }, | |
| 299 | + { 0x30fd, 0xf000 }, | |
| 300 | + { 0x30fe, 0x0000 }, | |
| 301 | + { 0x30ff, 0xf000 }, | |
| 302 | + { 0x3100, 0x222b }, | |
| 303 | + { 0x3101, 0x3a03 }, | |
| 304 | + { 0x3102, 0x222b }, | |
| 305 | + { 0x3103, 0x5803 }, | |
| 306 | + { 0x3104, 0xe26f }, | |
| 307 | + { 0x3105, 0x030d }, | |
| 308 | + { 0x3106, 0x626f }, | |
| 309 | + { 0x3107, 0x2c01 }, | |
| 310 | + { 0x3108, 0xe26f }, | |
| 311 | + { 0x3109, 0x4342 }, | |
| 312 | + { 0x310a, 0xe26f }, | |
| 313 | + { 0x310b, 0x73c0 }, | |
| 314 | + { 0x310c, 0x026f }, | |
| 315 | + { 0x310d, 0x0c00 }, | |
| 316 | + { 0x310e, 0x022b }, | |
| 317 | + { 0x310f, 0x1f01 }, | |
| 318 | + { 0x3110, 0x022b }, | |
| 319 | + { 0x3111, 0x1e01 }, | |
| 320 | + { 0x3112, 0x022b }, | |
| 321 | + { 0x3113, 0xfa00 }, | |
| 322 | + { 0x3114, 0x0000 }, | |
| 323 | + { 0x3115, 0xf000 }, | |
| 324 | + { 0x3116, 0x0000 }, | |
| 325 | + { 0x3117, 0xf000 }, | |
| 326 | + { 0x3118, 0x0000 }, | |
| 327 | + { 0x3119, 0xf000 }, | |
| 328 | + { 0x311a, 0x0000 }, | |
| 329 | + { 0x311b, 0xf000 }, | |
| 330 | + { 0x311c, 0x0000 }, | |
| 331 | + { 0x311d, 0xf000 }, | |
| 332 | + { 0x311e, 0x0000 }, | |
| 333 | + { 0x311f, 0xf000 }, | |
| 334 | + { 0x3120, 0x022b }, | |
| 335 | + { 0x3121, 0x0a01 }, | |
| 336 | + { 0x3122, 0x022b }, | |
| 337 | + { 0x3123, 0x1e00 }, | |
| 338 | + { 0x3124, 0x022b }, | |
| 339 | + { 0x3125, 0x1f00 }, | |
| 340 | + { 0x3126, 0x622b }, | |
| 341 | + { 0x3127, 0xf800 }, | |
| 342 | + { 0x3128, 0x0000 }, | |
| 343 | + { 0x3129, 0xf000 }, | |
| 344 | + { 0x312a, 0x0000 }, | |
| 345 | + { 0x312b, 0xf000 }, | |
| 346 | + { 0x312c, 0x0000 }, | |
| 347 | + { 0x312d, 0xf000 }, | |
| 348 | + { 0x312e, 0x0000 }, | |
| 349 | + { 0x312f, 0xf000 }, | |
| 350 | + { 0x3130, 0x0000 }, | |
| 351 | + { 0x3131, 0xf000 }, | |
| 352 | + { 0x3132, 0x0000 }, | |
| 353 | + { 0x3133, 0xf000 }, | |
| 354 | + { 0x3134, 0x0000 }, | |
| 355 | + { 0x3135, 0xf000 }, | |
| 356 | + { 0x3136, 0x0000 }, | |
| 357 | + { 0x3137, 0xf000 }, | |
| 358 | + { 0x3138, 0x0000 }, | |
| 359 | + { 0x3139, 0xf000 }, | |
| 360 | + { 0x313a, 0x0000 }, | |
| 361 | + { 0x313b, 0xf000 }, | |
| 362 | + { 0x313c, 0x0000 }, | |
| 363 | + { 0x313d, 0xf000 }, | |
| 364 | + { 0x313e, 0x0000 }, | |
| 365 | + { 0x313f, 0xf000 }, | |
| 366 | + { 0x3140, 0x0000 }, | |
| 367 | + { 0x3141, 0xf000 }, | |
| 368 | + { 0x3142, 0x0000 }, | |
| 369 | + { 0x3143, 0xf000 }, | |
| 370 | + { 0x3144, 0x0000 }, | |
| 371 | + { 0x3145, 0xf000 }, | |
| 372 | + { 0x3146, 0x0000 }, | |
| 373 | + { 0x3147, 0xf000 }, | |
| 374 | + { 0x3148, 0x0000 }, | |
| 375 | + { 0x3149, 0xf000 }, | |
| 376 | + { 0x314a, 0x0000 }, | |
| 377 | + { 0x314b, 0xf000 }, | |
| 378 | + { 0x314c, 0x0000 }, | |
| 379 | + { 0x314d, 0xf000 }, | |
| 380 | + { 0x314e, 0x0000 }, | |
| 381 | + { 0x314f, 0xf000 }, | |
| 382 | + { 0x3150, 0x0000 }, | |
| 383 | + { 0x3151, 0xf000 }, | |
| 384 | + { 0x3152, 0x0000 }, | |
| 385 | + { 0x3153, 0xf000 }, | |
| 386 | + { 0x3154, 0x0000 }, | |
| 387 | + { 0x3155, 0xf000 }, | |
| 388 | + { 0x3156, 0x0000 }, | |
| 389 | + { 0x3157, 0xf000 }, | |
| 390 | + { 0x3158, 0x0000 }, | |
| 391 | + { 0x3159, 0xf000 }, | |
| 392 | + { 0x315a, 0x0000 }, | |
| 393 | + { 0x315b, 0xf000 }, | |
| 394 | + { 0x315c, 0x0000 }, | |
| 395 | + { 0x315d, 0xf000 }, | |
| 396 | + { 0x315e, 0x0000 }, | |
| 397 | + { 0x315f, 0xf000 }, | |
| 398 | + { 0x3160, 0x0000 }, | |
| 399 | + { 0x3161, 0xf000 }, | |
| 400 | + { 0x3162, 0x0000 }, | |
| 401 | + { 0x3163, 0xf000 }, | |
| 402 | + { 0x3164, 0x0000 }, | |
| 403 | + { 0x3165, 0xf000 }, | |
| 404 | + { 0x3166, 0x0000 }, | |
| 405 | + { 0x3167, 0xf000 }, | |
| 406 | + { 0x3168, 0x0000 }, | |
| 407 | + { 0x3169, 0xf000 }, | |
| 408 | + { 0x316a, 0x0000 }, | |
| 409 | + { 0x316b, 0xf000 }, | |
| 410 | + { 0x316c, 0x0000 }, | |
| 411 | + { 0x316d, 0xf000 }, | |
| 412 | + { 0x316e, 0x0000 }, | |
| 413 | + { 0x316f, 0xf000 }, | |
| 414 | + { 0x3170, 0x0000 }, | |
| 415 | + { 0x3171, 0xf000 }, | |
| 416 | + { 0x3172, 0x0000 }, | |
| 417 | + { 0x3173, 0xf000 }, | |
| 418 | + { 0x3174, 0x0000 }, | |
| 419 | + { 0x3175, 0xf000 }, | |
| 420 | + { 0x3176, 0x0000 }, | |
| 421 | + { 0x3177, 0xf000 }, | |
| 422 | + { 0x3178, 0x0000 }, | |
| 423 | + { 0x3179, 0xf000 }, | |
| 424 | + { 0x317a, 0x0000 }, | |
| 425 | + { 0x317b, 0xf000 }, | |
| 426 | + { 0x317c, 0x0000 }, | |
| 427 | + { 0x317d, 0xf000 }, | |
| 428 | + { 0x317e, 0x0000 }, | |
| 429 | + { 0x317f, 0xf000 }, | |
| 430 | + { 0x3180, 0x2001 }, | |
| 431 | + { 0x3181, 0xf101 }, | |
| 432 | + { 0x3182, 0x0000 }, | |
| 433 | + { 0x3183, 0xf000 }, | |
| 434 | + { 0x3184, 0x0000 }, | |
| 435 | + { 0x3185, 0xf000 }, | |
| 436 | + { 0x3186, 0x0000 }, | |
| 437 | + { 0x3187, 0xf000 }, | |
| 438 | + { 0x3188, 0x0000 }, | |
| 439 | + { 0x3189, 0xf000 }, | |
| 440 | + { 0x318a, 0x0000 }, | |
| 441 | + { 0x318b, 0xf000 }, | |
| 442 | + { 0x318c, 0x0000 }, | |
| 443 | + { 0x318d, 0xf000 }, | |
| 444 | + { 0x318e, 0x0000 }, | |
| 445 | + { 0x318f, 0xf000 }, | |
| 446 | + { 0x3190, 0x0000 }, | |
| 447 | + { 0x3191, 0xf000 }, | |
| 448 | + { 0x3192, 0x0000 }, | |
| 449 | + { 0x3193, 0xf000 }, | |
| 450 | + { 0x3194, 0x0000 }, | |
| 451 | + { 0x3195, 0xf000 }, | |
| 452 | + { 0x3196, 0x0000 }, | |
| 453 | + { 0x3197, 0xf000 }, | |
| 454 | + { 0x3198, 0x0000 }, | |
| 455 | + { 0x3199, 0xf000 }, | |
| 456 | + { 0x319a, 0x0000 }, | |
| 457 | + { 0x319b, 0xf000 }, | |
| 458 | + { 0x319c, 0x0000 }, | |
| 459 | + { 0x319d, 0xf000 }, | |
| 460 | + { 0x319e, 0x0000 }, | |
| 461 | + { 0x319f, 0xf000 }, | |
| 462 | + { 0x31a0, 0x0000 }, | |
| 463 | + { 0x31a1, 0xf000 }, | |
| 464 | + { 0x31a2, 0x0000 }, | |
| 465 | + { 0x31a3, 0xf000 }, | |
| 466 | + { 0x31a4, 0x0000 }, | |
| 467 | + { 0x31a5, 0xf000 }, | |
| 468 | + { 0x31a6, 0x0000 }, | |
| 469 | + { 0x31a7, 0xf000 }, | |
| 470 | + { 0x31a8, 0x0000 }, | |
| 471 | + { 0x31a9, 0xf000 }, | |
| 472 | + { 0x31aa, 0x0000 }, | |
| 473 | + { 0x31ab, 0xf000 }, | |
| 474 | + { 0x31ac, 0x0000 }, | |
| 475 | + { 0x31ad, 0xf000 }, | |
| 476 | + { 0x31ae, 0x0000 }, | |
| 477 | + { 0x31af, 0xf000 }, | |
| 478 | + { 0x31b0, 0x0000 }, | |
| 479 | + { 0x31b1, 0xf000 }, | |
| 480 | + { 0x31b2, 0x0000 }, | |
| 481 | + { 0x31b3, 0xf000 }, | |
| 482 | + { 0x31b4, 0x0000 }, | |
| 483 | + { 0x31b5, 0xf000 }, | |
| 484 | + { 0x31b6, 0x0000 }, | |
| 485 | + { 0x31b7, 0xf000 }, | |
| 486 | + { 0x31b8, 0x0000 }, | |
| 487 | + { 0x31b9, 0xf000 }, | |
| 488 | + { 0x31ba, 0x0000 }, | |
| 489 | + { 0x31bb, 0xf000 }, | |
| 490 | + { 0x31bc, 0x0000 }, | |
| 491 | + { 0x31bd, 0xf000 }, | |
| 492 | + { 0x31be, 0x0000 }, | |
| 493 | + { 0x31bf, 0xf000 }, | |
| 494 | + { 0x31c0, 0x0000 }, | |
| 495 | + { 0x31c1, 0xf000 }, | |
| 496 | + { 0x31c2, 0x0000 }, | |
| 497 | + { 0x31c3, 0xf000 }, | |
| 498 | + { 0x31c4, 0x0000 }, | |
| 499 | + { 0x31c5, 0xf000 }, | |
| 500 | + { 0x31c6, 0x0000 }, | |
| 501 | + { 0x31c7, 0xf000 }, | |
| 502 | + { 0x31c8, 0x0000 }, | |
| 503 | + { 0x31c9, 0xf000 }, | |
| 504 | + { 0x31ca, 0x0000 }, | |
| 505 | + { 0x31cb, 0xf000 }, | |
| 506 | + { 0x31cc, 0x0000 }, | |
| 507 | + { 0x31cd, 0xf000 }, | |
| 508 | + { 0x31ce, 0x0000 }, | |
| 509 | + { 0x31cf, 0xf000 }, | |
| 510 | + { 0x31d0, 0x0000 }, | |
| 511 | + { 0x31d1, 0xf000 }, | |
| 512 | + { 0x31d2, 0x0000 }, | |
| 513 | + { 0x31d3, 0xf000 }, | |
| 514 | + { 0x31d4, 0x0000 }, | |
| 515 | + { 0x31d5, 0xf000 }, | |
| 516 | + { 0x31d6, 0x0000 }, | |
| 517 | + { 0x31d7, 0xf000 }, | |
| 518 | + { 0x31d8, 0x0000 }, | |
| 519 | + { 0x31d9, 0xf000 }, | |
| 520 | + { 0x31da, 0x0000 }, | |
| 521 | + { 0x31db, 0xf000 }, | |
| 522 | + { 0x31dc, 0x0000 }, | |
| 523 | + { 0x31dd, 0xf000 }, | |
| 524 | + { 0x31de, 0x0000 }, | |
| 525 | + { 0x31df, 0xf000 }, | |
| 526 | + { 0x31e0, 0x0000 }, | |
| 527 | + { 0x31e1, 0xf000 }, | |
| 528 | + { 0x31e2, 0x0000 }, | |
| 529 | + { 0x31e3, 0xf000 }, | |
| 530 | + { 0x31e4, 0x0000 }, | |
| 531 | + { 0x31e5, 0xf000 }, | |
| 532 | + { 0x31e6, 0x0000 }, | |
| 533 | + { 0x31e7, 0xf000 }, | |
| 534 | + { 0x31e8, 0x0000 }, | |
| 535 | + { 0x31e9, 0xf000 }, | |
| 536 | + { 0x31ea, 0x0000 }, | |
| 537 | + { 0x31eb, 0xf000 }, | |
| 538 | + { 0x31ec, 0x0000 }, | |
| 539 | + { 0x31ed, 0xf000 }, | |
| 540 | + { 0x31ee, 0x0000 }, | |
| 541 | + { 0x31ef, 0xf000 }, | |
| 542 | + { 0x31f0, 0x0000 }, | |
| 543 | + { 0x31f1, 0xf000 }, | |
| 544 | + { 0x31f2, 0x0000 }, | |
| 545 | + { 0x31f3, 0xf000 }, | |
| 546 | + { 0x31f4, 0x0000 }, | |
| 547 | + { 0x31f5, 0xf000 }, | |
| 548 | + { 0x31f6, 0x0000 }, | |
| 549 | + { 0x31f7, 0xf000 }, | |
| 550 | + { 0x31f8, 0x0000 }, | |
| 551 | + { 0x31f9, 0xf000 }, | |
| 552 | + { 0x31fa, 0x0000 }, | |
| 553 | + { 0x31fb, 0xf000 }, | |
| 554 | + { 0x31fc, 0x0000 }, | |
| 555 | + { 0x31fd, 0xf000 }, | |
| 556 | + { 0x31fe, 0x0000 }, | |
| 557 | + { 0x31ff, 0xf000 }, | |
| 558 | + { 0x024d, 0xff50 }, | |
| 559 | + { 0x0252, 0xff50 }, | |
| 560 | + { 0x0259, 0x0112 }, | |
| 561 | + { 0x025e, 0x0112 }, | |
| 562 | +}; | |
| 563 | + | |
| 564 | +static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, | |
| 565 | + struct snd_kcontrol *kcontrol, int event) | |
| 566 | +{ | |
| 567 | + struct snd_soc_codec *codec = w->codec; | |
| 568 | + struct arizona *arizona = dev_get_drvdata(codec->dev); | |
| 569 | + struct regmap *regmap = codec->control_data; | |
| 570 | + const struct reg_default *patch = NULL; | |
| 571 | + int i, patch_size; | |
| 572 | + | |
| 573 | + switch (arizona->rev) { | |
| 574 | + case 0: | |
| 575 | + patch = wm5102_sysclk_reva_patch; | |
| 576 | + patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch); | |
| 577 | + break; | |
| 578 | + } | |
| 579 | + | |
| 580 | + switch (event) { | |
| 581 | + case SND_SOC_DAPM_POST_PMU: | |
| 582 | + if (patch) | |
| 583 | + for (i = 0; i < patch_size; i++) | |
| 584 | + regmap_write(regmap, patch[i].reg, | |
| 585 | + patch[i].def); | |
| 586 | + break; | |
| 587 | + | |
| 588 | + default: | |
| 589 | + break; | |
| 590 | + } | |
| 591 | + | |
| 592 | + return 0; | |
| 593 | +} | |
| 594 | + | |
| 45 | 595 | static const struct snd_kcontrol_new wm5102_snd_controls[] = { |
| 46 | 596 | SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, |
| 47 | 597 | ARIZONA_IN1_OSR_SHIFT, 1, 0), |
| @@ -297,7 +847,7 @@ static const struct snd_kcontrol_new wm5102_aec_loopback_mux = · 249 unmodified lines | ||
| 297 | 847 | |
| 298 | 848 | static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { |
| 299 | 849 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, |
| 300 | − 0, NULL, 0), | |
| 850 | + 0, wm5102_sysclk_ev, SND_SOC_DAPM_POST_PMU), | |
| 301 | 851 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, |
| 302 | 852 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), |
| 303 | 853 | SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, |
| @@ -782,7 +782,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream, · 781 unmodified lines | ||
| 782 | 782 | wm8978->mclk_idx = -1; |
| 783 | 783 | f_sel = wm8978->f_mclk; |
| 784 | 784 | } else { |
| 785 | − if (!wm8978->f_pllout) { | |
| 785 | + if (!wm8978->f_opclk) { | |
| 786 | 786 | /* We only enter here, if OPCLK is not used */ |
| 787 | 787 | int ret = wm8978_configure_pll(codec); |
| 788 | 788 | if (ret < 0) |
| @@ -3722,7 +3722,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) · 3721 unmodified lines | ||
| 3722 | 3722 | } while (count--); |
| 3723 | 3723 | |
| 3724 | 3724 | if (count == 0) |
| 3725 | − dev_warn(codec->dev, "No impedence range reported for jack\n"); | |
| 3725 | + dev_warn(codec->dev, "No impedance range reported for jack\n"); | |
| 3726 | 3726 | |
| 3727 | 3727 | #ifndef CONFIG_SND_SOC_WM8994_MODULE |
| 3728 | 3728 | trace_snd_soc_jack_irq(dev_name(codec->dev)); |
| @@ -523,16 +523,24 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, · 522 unmodified lines | ||
| 523 | 523 | |
| 524 | 524 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 525 | 525 | /* |
| 526 | − * write a data to saif data register to trigger | |
| 527 | − * the transfer | |
| 526 | + * write data to saif data register to trigger | |
| 527 | + * the transfer. | |
| 528 | + * For 24-bit format the 32-bit FIFO register stores | |
| 529 | + * only one channel, so we need to write twice. | |
| 530 | + * This is also safe for the other non 24-bit formats. | |
| 528 | 531 | */ |
| 529 | 532 | __raw_writel(0, saif->base + SAIF_DATA); |
| 533 | + __raw_writel(0, saif->base + SAIF_DATA); | |
| 530 | 534 | } else { |
| 531 | 535 | /* |
| 532 | − * read a data from saif data register to trigger | |
| 533 | − * the receive | |
| 536 | + * read data from saif data register to trigger | |
| 537 | + * the receive. | |
| 538 | + * For 24-bit format the 32-bit FIFO register stores | |
| 539 | + * only one channel, so we need to read twice. | |
| 540 | + * This is also safe for the other non 24-bit formats. | |
| 534 | 541 | */ |
| 535 | 542 | __raw_readl(saif->base + SAIF_DATA); |
| 543 | + __raw_readl(saif->base + SAIF_DATA); | |
| 536 | 544 | } |
| 537 | 545 | |
| 538 | 546 | master_saif->ongoing = 1; |
| @@ -812,3 +820,4 @@ module_platform_driver(mxs_saif_driver); · 273 unmodified lines | ||
| 812 | 820 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); |
| 813 | 821 | MODULE_DESCRIPTION("MXS ASoC SAIF driver"); |
| 814 | 822 | MODULE_LICENSE("GPL"); |
| 823 | +MODULE_ALIAS("platform:mxs-saif"); | |
| @@ -207,6 +207,8 @@ config SND_SOC_BELLS · 206 unmodified lines | ||
| 207 | 207 | select SND_SOC_WM5102 |
| 208 | 208 | select SND_SOC_WM5110 |
| 209 | 209 | select SND_SOC_WM9081 |
| 210 | + select SND_SOC_WM0010 | |
| 211 | + select SND_SOC_WM1250_EV1 | |
| 210 | 212 | |
| 211 | 213 | config SND_SOC_LOWLAND |
| 212 | 214 | tristate "Audio support for Wolfson Lowland" |
| @@ -247,7 +247,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { · 246 unmodified lines | ||
| 247 | 247 | { |
| 248 | 248 | .name = "Sub", |
| 249 | 249 | .stream_name = "Sub", |
| 250 | − .cpu_dai_name = "wm5110-aif3", | |
| 250 | + .cpu_dai_name = "wm5102-aif3", | |
| 251 | 251 | .codec_dai_name = "wm9081-hifi", |
| 252 | 252 | .codec_name = "wm9081.1-006c", |
| 253 | 253 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
| @@ -2786,8 +2786,9 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, · 2785 unmodified lines | ||
| 2786 | 2786 | val = (ucontrol->value.integer.value[0] + min) & mask; |
| 2787 | 2787 | val = val << shift; |
| 2788 | 2788 | |
| 2789 | − if (snd_soc_update_bits_locked(codec, reg, val_mask, val)) | |
| 2790 | − return err; | |
| 2789 | + err = snd_soc_update_bits_locked(codec, reg, val_mask, val); | |
| 2790 | + if (err < 0) | |
| 2791 | + return err; | |
| 2791 | 2792 | |
| 2792 | 2793 | if (snd_soc_volsw_is_stereo(mc)) { |
| 2793 | 2794 | val_mask = mask << rshift; |
| @@ -3745,7 +3745,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card) · 3744 unmodified lines | ||
| 3745 | 3745 | { |
| 3746 | 3746 | struct snd_soc_codec *codec; |
| 3747 | 3747 | |
| 3748 | − list_for_each_entry(codec, &card->codec_dev_list, list) { | |
| 3748 | + list_for_each_entry(codec, &card->codec_dev_list, card_list) { | |
| 3749 | 3749 | soc_dapm_shutdown_codec(&codec->dapm); |
| 3750 | 3750 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) |
| 3751 | 3751 | snd_soc_dapm_set_bias_level(&codec->dapm, |
| @@ -559,9 +559,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, · 558 unmodified lines | ||
| 559 | 559 | return; |
| 560 | 560 | |
| 561 | 561 | card = chip->card; |
| 562 | − mutex_lock(®ister_mutex); | |
| 563 | 562 | down_write(&chip->shutdown_rwsem); |
| 564 | 563 | chip->shutdown = 1; |
| 564 | + up_write(&chip->shutdown_rwsem); | |
| 565 | + | |
| 566 | + mutex_lock(®ister_mutex); | |
| 565 | 567 | chip->num_interfaces--; |
| 566 | 568 | if (chip->num_interfaces <= 0) { |
| 567 | 569 | snd_card_disconnect(card); |
| @@ -582,11 +584,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, · 14 unmodified lines | ||
| 582 | 584 | snd_usb_mixer_disconnect(p); |
| 583 | 585 | } |
| 584 | 586 | usb_chip[chip->index] = NULL; |
| 585 | − up_write(&chip->shutdown_rwsem); | |
| 586 | 587 | mutex_unlock(®ister_mutex); |
| 587 | 588 | snd_card_free_when_closed(card); |
| 588 | 589 | } else { |
| 589 | − up_write(&chip->shutdown_rwsem); | |
| 590 | 590 | mutex_unlock(®ister_mutex); |
| 591 | 591 | } |
| 592 | 592 | } |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | #define EP_FLAG_ACTIVATED 0 |
| 37 | 37 | #define EP_FLAG_RUNNING 1 |
| 38 | +#define EP_FLAG_STOPPING 2 | |
| 38 | 39 | |
| 39 | 40 | /* |
| 40 | 41 | * snd_usb_endpoint is a model that abstracts everything related to an |
| @@ -502,10 +503,20 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep) · 461 unmodified lines | ||
| 502 | 503 | if (alive) |
| 503 | 504 | snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", |
| 504 | 505 | alive, ep->ep_num); |
| 506 | + clear_bit(EP_FLAG_STOPPING, &ep->flags); | |
| 505 | 507 | |
| 506 | 508 | return 0; |
| 507 | 509 | } |
| 508 | 510 | |
| 511 | +/* sync the pending stop operation; | |
| 512 | + * this function itself doesn't trigger the stop operation | |
| 513 | + */ | |
| 514 | +void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep) | |
| 515 | +{ | |
| 516 | + if (ep && test_bit(EP_FLAG_STOPPING, &ep->flags)) | |
| 517 | + wait_clear_urbs(ep); | |
| 518 | +} | |
| 519 | + | |
| 509 | 520 | /* |
| 510 | 521 | * unlink active urbs. |
| 511 | 522 | */ |
| @@ -918,6 +929,8 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, · 406 unmodified lines | ||
| 918 | 929 | |
| 919 | 930 | if (wait) |
| 920 | 931 | wait_clear_urbs(ep); |
| 932 | + else | |
| 933 | + set_bit(EP_FLAG_STOPPING, &ep->flags); | |
| 921 | 934 | } |
| 922 | 935 | } |
| 923 | 936 | |
| @@ -19,6 +19,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, · 18 unmodified lines | ||
| 19 | 19 | int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep); |
| 20 | 20 | void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, |
| 21 | 21 | int force, int can_sleep, int wait); |
| 22 | +void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); | |
| 22 | 23 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); |
| 23 | 24 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); |
| 24 | 25 | void snd_usb_endpoint_free(struct list_head *head); |
| @@ -568,6 +568,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) · 567 unmodified lines | ||
| 568 | 568 | goto unlock; |
| 569 | 569 | } |
| 570 | 570 | |
| 571 | + snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint); | |
| 572 | + snd_usb_endpoint_sync_pending_stop(subs->data_endpoint); | |
| 573 | + | |
| 571 | 574 | ret = set_format(subs, subs->cur_audiofmt); |
| 572 | 575 | if (ret < 0) |
| 573 | 576 | goto unlock; |
| @@ -206,8 +206,10 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) · 205 unmodified lines | ||
| 206 | 206 | retval = pread(fd, msr, sizeof *msr, offset); |
| 207 | 207 | close(fd); |
| 208 | 208 | |
| 209 | − if (retval != sizeof *msr) | |
| 209 | + if (retval != sizeof *msr) { | |
| 210 | + fprintf(stderr, "%s offset 0x%zx read failed\n", pathname, offset); | |
| 210 | 211 | return -1; |
| 212 | + } | |
| 211 | 213 | |
| 212 | 214 | return 0; |
| 213 | 215 | } |
| @@ -1101,7 +1103,9 @@ void turbostat_loop() · 887 unmodified lines | ||
| 1101 | 1103 | |
| 1102 | 1104 | restart: |
| 1103 | 1105 | retval = for_all_cpus(get_counters, EVEN_COUNTERS); |
| 1104 | − if (retval) { | |
| 1106 | + if (retval < -1) { | |
| 1107 | + exit(retval); | |
| 1108 | + } else if (retval == -1) { | |
| 1105 | 1109 | re_initialize(); |
| 1106 | 1110 | goto restart; |
| 1107 | 1111 | } |
| @@ -1114,7 +1118,9 @@ restart: · 6 unmodified lines | ||
| 1114 | 1118 | } |
| 1115 | 1119 | sleep(interval_sec); |
| 1116 | 1120 | retval = for_all_cpus(get_counters, ODD_COUNTERS); |
| 1117 | − if (retval) { | |
| 1121 | + if (retval < -1) { | |
| 1122 | + exit(retval); | |
| 1123 | + } else if (retval == -1) { | |
| 1118 | 1124 | re_initialize(); |
| 1119 | 1125 | goto restart; |
| 1120 | 1126 | } |
| @@ -1126,7 +1132,9 @@ restart: · 5 unmodified lines | ||
| 1126 | 1132 | flush_stdout(); |
| 1127 | 1133 | sleep(interval_sec); |
| 1128 | 1134 | retval = for_all_cpus(get_counters, EVEN_COUNTERS); |
| 1129 | − if (retval) { | |
| 1135 | + if (retval < -1) { | |
| 1136 | + exit(retval); | |
| 1137 | + } else if (retval == -1) { | |
| 1130 | 1138 | re_initialize(); |
| 1131 | 1139 | goto restart; |
| 1132 | 1140 | } |
| @@ -1545,8 +1553,11 @@ void turbostat_init() · 412 unmodified lines | ||
| 1545 | 1553 | int fork_it(char **argv) |
| 1546 | 1554 | { |
| 1547 | 1555 | pid_t child_pid; |
| 1556 | + int status; | |
| 1548 | 1557 | |
| 1549 | − for_all_cpus(get_counters, EVEN_COUNTERS); | |
| 1558 | + status = for_all_cpus(get_counters, EVEN_COUNTERS); | |
| 1559 | + if (status) | |
| 1560 | + exit(status); | |
| 1550 | 1561 | /* clear affinity side-effect of get_counters() */ |
| 1551 | 1562 | sched_setaffinity(0, cpu_present_setsize, cpu_present_set); |
| 1552 | 1563 | gettimeofday(&tv_even, (struct timezone *)NULL); |
| @@ -1556,7 +1567,6 @@ int fork_it(char **argv) · 3 unmodified lines | ||
| 1556 | 1567 | /* child */ |
| 1557 | 1568 | execvp(argv[0], argv); |
| 1558 | 1569 | } else { |
| 1559 | − int status; | |
| 1560 | 1570 | |
| 1561 | 1571 | /* parent */ |
| 1562 | 1572 | if (child_pid == -1) { |
| @@ -1568,7 +1578,7 @@ int fork_it(char **argv) · 5 unmodified lines | ||
| 1568 | 1578 | signal(SIGQUIT, SIG_IGN); |
| 1569 | 1579 | if (waitpid(child_pid, &status, 0) == -1) { |
| 1570 | 1580 | perror("wait"); |
| 1571 | − exit(1); | |
| 1581 | + exit(status); | |
| 1572 | 1582 | } |
| 1573 | 1583 | } |
| 1574 | 1584 | /* |
| @@ -1585,7 +1595,7 @@ int fork_it(char **argv) · 10 unmodified lines | ||
| 1585 | 1595 | |
| 1586 | 1596 | fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); |
| 1587 | 1597 | |
| 1588 | − return 0; | |
| 1598 | + return status; | |
| 1589 | 1599 | } |
| 1590 | 1600 | |
| 1591 | 1601 | void cmdline(int argc, char **argv) |
| @@ -1594,7 +1604,7 @@ void cmdline(int argc, char **argv) · 2 unmodified lines | ||
| 1594 | 1604 | |
| 1595 | 1605 | progname = argv[0]; |
| 1596 | 1606 | |
| 1597 | − while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) { | |
| 1607 | + while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:")) != -1) { | |
| 1598 | 1608 | switch (opt) { |
| 1599 | 1609 | case 'p': |
| 1600 | 1610 | show_core_only++; |
| @@ -1,4 +1,4 @@ | ||
| 1 | −TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug epoll | |
| 1 | +TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug | |
| 2 | 2 | |
| 3 | 3 | all: |
| 4 | 4 | for TARGET in $(TARGETS); do \ |
| @@ -1,11 +0,0 @@ | ||
| 1 | −# Makefile for epoll selftests | |
| 2 | − | |
| 3 | −all: test_epoll | |
| 4 | −%: %.c | |
| 5 | − gcc -pthread -g -o $@ $^ | |
| 6 | − | |
| 7 | −run_tests: all | |
| 8 | − ./test_epoll | |
| 9 | − | |
| 10 | −clean: | |
| 11 | − $(RM) test_epoll | |
| @@ -1,344 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * tools/testing/selftests/epoll/test_epoll.c | |
| 3 | − * | |
| 4 | − * Copyright 2012 Adobe Systems Incorporated | |
| 5 | − * | |
| 6 | − * This program is free software; you can redistribute it and/or modify | |
| 7 | − * it under the terms of the GNU General Public License as published by | |
| 8 | − * the Free Software Foundation; either version 2 of the License, or | |
| 9 | − * (at your option) any later version. | |
| 10 | − * | |
| 11 | − * Paton J. Lewis <palewis@adobe.com> | |
| 12 | − * | |
| 13 | − */ | |
| 14 | − | |
| 15 | −#include <errno.h> | |
| 16 | −#include <fcntl.h> | |
| 17 | −#include <pthread.h> | |
| 18 | −#include <stdio.h> | |
| 19 | −#include <stdlib.h> | |
| 20 | −#include <unistd.h> | |
| 21 | −#include <sys/epoll.h> | |
| 22 | −#include <sys/socket.h> | |
| 23 | − | |
| 24 | −/* | |
| 25 | − * A pointer to an epoll_item_private structure will be stored in the epoll | |
| 26 | − * item's event structure so that we can get access to the epoll_item_private | |
| 27 | − * data after calling epoll_wait: | |
| 28 | − */ | |
| 29 | −struct epoll_item_private { | |
| 30 | − int index; /* Position of this struct within the epoll_items array. */ | |
| 31 | − int fd; | |
| 32 | − uint32_t events; | |
| 33 | − pthread_mutex_t mutex; /* Guards the following variables... */ | |
| 34 | − int stop; | |
| 35 | − int status; /* Stores any error encountered while handling item. */ | |
| 36 | − /* The following variable allows us to test whether we have encountered | |
| 37 | − a problem while attempting to cancel and delete the associated | |
| 38 | − event. When the test program exits, 'deleted' should be exactly | |
| 39 | − one. If it is greater than one, then the failed test reflects a real | |
| 40 | − world situation where we would have tried to access the epoll item's | |
| 41 | − private data after deleting it: */ | |
| 42 | − int deleted; | |
| 43 | −}; | |
| 44 | − | |
| 45 | −struct epoll_item_private *epoll_items; | |
| 46 | − | |
| 47 | −/* | |
| 48 | − * Delete the specified item from the epoll set. In a real-world secneario this | |
| 49 | − * is where we would free the associated data structure, but in this testing | |
| 50 | − * environment we retain the structure so that we can test for double-deletion: | |
| 51 | − */ | |
| 52 | −void delete_item(int index) | |
| 53 | −{ | |
| 54 | − __sync_fetch_and_add(&epoll_items[index].deleted, 1); | |
| 55 | −} | |
| 56 | − | |
| 57 | −/* | |
| 58 | − * A pointer to a read_thread_data structure will be passed as the argument to | |
| 59 | − * each read thread: | |
| 60 | − */ | |
| 61 | −struct read_thread_data { | |
| 62 | − int stop; | |
| 63 | − int status; /* Indicates any error encountered by the read thread. */ | |
| 64 | − int epoll_set; | |
| 65 | −}; | |
| 66 | − | |
| 67 | −/* | |
| 68 | − * The function executed by the read threads: | |
| 69 | − */ | |
| 70 | −void *read_thread_function(void *function_data) | |
| 71 | −{ | |
| 72 | − struct read_thread_data *thread_data = | |
| 73 | − (struct read_thread_data *)function_data; | |
| 74 | − struct epoll_event event_data; | |
| 75 | − struct epoll_item_private *item_data; | |
| 76 | − char socket_data; | |
| 77 | − | |
| 78 | − /* Handle events until we encounter an error or this thread's 'stop' | |
| 79 | − condition is set: */ | |
| 80 | − while (1) { | |
| 81 | − int result = epoll_wait(thread_data->epoll_set, | |
| 82 | − &event_data, | |
| 83 | − 1, /* Number of desired events */ | |
| 84 | − 1000); /* Timeout in ms */ | |
| 85 | − if (result < 0) { | |
| 86 | − /* Breakpoints signal all threads. Ignore that while | |
| 87 | − debugging: */ | |
| 88 | − if (errno == EINTR) | |
| 89 | − continue; | |
| 90 | − thread_data->status = errno; | |
| 91 | − return 0; | |
| 92 | − } else if (thread_data->stop) | |
| 93 | − return 0; | |
| 94 | − else if (result == 0) /* Timeout */ | |
| 95 | − continue; | |
| 96 | − | |
| 97 | − /* We need the mutex here because checking for the stop | |
| 98 | − condition and re-enabling the epoll item need to be done | |
| 99 | − together as one atomic operation when EPOLL_CTL_DISABLE is | |
| 100 | − available: */ | |
| 101 | − item_data = (struct epoll_item_private *)event_data.data.ptr; | |
| 102 | − pthread_mutex_lock(&item_data->mutex); | |
| 103 | − | |
| 104 | − /* Remove the item from the epoll set if we want to stop | |
| 105 | − handling that event: */ | |
| 106 | − if (item_data->stop) | |
| 107 | − delete_item(item_data->index); | |
| 108 | − else { | |
| 109 | − /* Clear the data that was written to the other end of | |
| 110 | − our non-blocking socket: */ | |
| 111 | − do { | |
| 112 | − if (read(item_data->fd, &socket_data, 1) < 1) { | |
| 113 | − if ((errno == EAGAIN) || | |
| 114 | − (errno == EWOULDBLOCK)) | |
| 115 | − break; | |
| 116 | − else | |
| 117 | − goto error_unlock; | |
| 118 | − } | |
| 119 | − } while (item_data->events & EPOLLET); | |
| 120 | − | |
| 121 | − /* The item was one-shot, so re-enable it: */ | |
| 122 | − event_data.events = item_data->events; | |
| 123 | − if (epoll_ctl(thread_data->epoll_set, | |
| 124 | − EPOLL_CTL_MOD, | |
| 125 | − item_data->fd, | |
| 126 | − &event_data) < 0) | |
| 127 | − goto error_unlock; | |
| 128 | − } | |
| 129 | − | |
| 130 | − pthread_mutex_unlock(&item_data->mutex); | |
| 131 | − } | |
| 132 | − | |
| 133 | −error_unlock: | |
| 134 | − thread_data->status = item_data->status = errno; | |
| 135 | − pthread_mutex_unlock(&item_data->mutex); | |
| 136 | − return 0; | |
| 137 | −} | |
| 138 | − | |
| 139 | −/* | |
| 140 | − * A pointer to a write_thread_data structure will be passed as the argument to | |
| 141 | − * the write thread: | |
| 142 | − */ | |
| 143 | −struct write_thread_data { | |
| 144 | − int stop; | |
| 145 | − int status; /* Indicates any error encountered by the write thread. */ | |
| 146 | − int n_fds; | |
| 147 | − int *fds; | |
| 148 | −}; | |
| 149 | − | |
| 150 | −/* | |
| 151 | − * The function executed by the write thread. It writes a single byte to each | |
| 152 | − * socket in turn until the stop condition for this thread is set. If writing to | |
| 153 | − * a socket would block (i.e. errno was EAGAIN), we leave that socket alone for | |
| 154 | − * the moment and just move on to the next socket in the list. We don't care | |
| 155 | − * about the order in which we deliver events to the epoll set. In fact we don't | |
| 156 | − * care about the data we're writing to the pipes at all; we just want to | |
| 157 | − * trigger epoll events: | |
| 158 | − */ | |
| 159 | −void *write_thread_function(void *function_data) | |
| 160 | −{ | |
| 161 | − const char data = 'X'; | |
| 162 | − int index; | |
| 163 | − struct write_thread_data *thread_data = | |
| 164 | − (struct write_thread_data *)function_data; | |
| 165 | − while (!thread_data->stop) | |
| 166 | − for (index = 0; | |
| 167 | − !thread_data->stop && (index < thread_data->n_fds); | |
| 168 | − ++index) | |
| 169 | − if ((write(thread_data->fds[index], &data, 1) < 1) && | |
| 170 | − (errno != EAGAIN) && | |
| 171 | − (errno != EWOULDBLOCK)) { | |
| 172 | − thread_data->status = errno; | |
| 173 | − return; | |
| 174 | − } | |
| 175 | −} | |
| 176 | − | |
| 177 | −/* | |
| 178 | − * Arguments are currently ignored: | |
| 179 | − */ | |
| 180 | −int main(int argc, char **argv) | |
| 181 | −{ | |
| 182 | − const int n_read_threads = 100; | |
| 183 | − const int n_epoll_items = 500; | |
| 184 | − int index; | |
| 185 | − int epoll_set = epoll_create1(0); | |
| 186 | − struct write_thread_data write_thread_data = { | |
| 187 | − 0, 0, n_epoll_items, malloc(n_epoll_items * sizeof(int)) | |
| 188 | − }; | |
| 189 | − struct read_thread_data *read_thread_data = | |
| 190 | − malloc(n_read_threads * sizeof(struct read_thread_data)); | |
| 191 | − pthread_t *read_threads = malloc(n_read_threads * sizeof(pthread_t)); | |
| 192 | − pthread_t write_thread; | |
| 193 | − | |
| 194 | − printf("-----------------\n"); | |
| 195 | − printf("Runing test_epoll\n"); | |
| 196 | − printf("-----------------\n"); | |
| 197 | − | |
| 198 | − epoll_items = malloc(n_epoll_items * sizeof(struct epoll_item_private)); | |
| 199 | − | |
| 200 | − if (epoll_set < 0 || epoll_items == 0 || write_thread_data.fds == 0 || | |
| 201 | − read_thread_data == 0 || read_threads == 0) | |
| 202 | − goto error; | |
| 203 | − | |
| 204 | − if (sysconf(_SC_NPROCESSORS_ONLN) < 2) { | |
| 205 | − printf("Error: please run this test on a multi-core system.\n"); | |
| 206 | − goto error; | |
| 207 | − } | |
| 208 | − | |
| 209 | − /* Create the socket pairs and epoll items: */ | |
| 210 | − for (index = 0; index < n_epoll_items; ++index) { | |
| 211 | − int socket_pair[2]; | |
| 212 | − struct epoll_event event_data; | |
| 213 | − if (socketpair(AF_UNIX, | |
| 214 | − SOCK_STREAM | SOCK_NONBLOCK, | |
| 215 | − 0, | |
| 216 | − socket_pair) < 0) | |
| 217 | − goto error; | |
| 218 | − write_thread_data.fds[index] = socket_pair[0]; | |
| 219 | − epoll_items[index].index = index; | |
| 220 | − epoll_items[index].fd = socket_pair[1]; | |
| 221 | − if (pthread_mutex_init(&epoll_items[index].mutex, NULL) != 0) | |
| 222 | − goto error; | |
| 223 | − /* We always use EPOLLONESHOT because this test is currently | |
| 224 | − structured to demonstrate the need for EPOLL_CTL_DISABLE, | |
| 225 | − which only produces useful information in the EPOLLONESHOT | |
| 226 | − case (without EPOLLONESHOT, calling epoll_ctl with | |
| 227 | − EPOLL_CTL_DISABLE will never return EBUSY). If support for | |
| 228 | − testing events without EPOLLONESHOT is desired, it should | |
| 229 | − probably be implemented in a separate unit test. */ | |
| 230 | − epoll_items[index].events = EPOLLIN | EPOLLONESHOT; | |
| 231 | − if (index < n_epoll_items / 2) | |
| 232 | − epoll_items[index].events |= EPOLLET; | |
| 233 | − epoll_items[index].stop = 0; | |
| 234 | − epoll_items[index].status = 0; | |
| 235 | − epoll_items[index].deleted = 0; | |
| 236 | − event_data.events = epoll_items[index].events; | |
| 237 | − event_data.data.ptr = &epoll_items[index]; | |
| 238 | − if (epoll_ctl(epoll_set, | |
| 239 | − EPOLL_CTL_ADD, | |
| 240 | − epoll_items[index].fd, | |
| 241 | − &event_data) < 0) | |
| 242 | − goto error; | |
| 243 | − } | |
| 244 | − | |
| 245 | − /* Create and start the read threads: */ | |
| 246 | − for (index = 0; index < n_read_threads; ++index) { | |
| 247 | − read_thread_data[index].stop = 0; | |
| 248 | − read_thread_data[index].status = 0; | |
| 249 | − read_thread_data[index].epoll_set = epoll_set; | |
| 250 | − if (pthread_create(&read_threads[index], | |
| 251 | − NULL, | |
| 252 | − read_thread_function, | |
| 253 | − &read_thread_data[index]) != 0) | |
| 254 | − goto error; | |
| 255 | − } | |
| 256 | − | |
| 257 | − if (pthread_create(&write_thread, | |
| 258 | − NULL, | |
| 259 | − write_thread_function, | |
| 260 | − &write_thread_data) != 0) | |
| 261 | − goto error; | |
| 262 | − | |
| 263 | − /* Cancel all event pollers: */ | |
| 264 | −#ifdef EPOLL_CTL_DISABLE | |
| 265 | − for (index = 0; index < n_epoll_items; ++index) { | |
| 266 | − pthread_mutex_lock(&epoll_items[index].mutex); | |
| 267 | − ++epoll_items[index].stop; | |
| 268 | − if (epoll_ctl(epoll_set, | |
| 269 | − EPOLL_CTL_DISABLE, | |
| 270 | − epoll_items[index].fd, | |
| 271 | − NULL) == 0) | |
| 272 | − delete_item(index); | |
| 273 | − else if (errno != EBUSY) { | |
| 274 | − pthread_mutex_unlock(&epoll_items[index].mutex); | |
| 275 | − goto error; | |
| 276 | − } | |
| 277 | − /* EBUSY means events were being handled; allow the other thread | |
| 278 | − to delete the item. */ | |
| 279 | − pthread_mutex_unlock(&epoll_items[index].mutex); | |
| 280 | − } | |
| 281 | −#else | |
| 282 | − for (index = 0; index < n_epoll_items; ++index) { | |
| 283 | − pthread_mutex_lock(&epoll_items[index].mutex); | |
| 284 | − ++epoll_items[index].stop; | |
| 285 | − pthread_mutex_unlock(&epoll_items[index].mutex); | |
| 286 | − /* Wait in case a thread running read_thread_function is | |
| 287 | − currently executing code between epoll_wait and | |
| 288 | − pthread_mutex_lock with this item. Note that a longer delay | |
| 289 | − would make double-deletion less likely (at the expense of | |
| 290 | − performance), but there is no guarantee that any delay would | |
| 291 | − ever be sufficient. Note also that we delete all event | |
| 292 | − pollers at once for testing purposes, but in a real-world | |
| 293 | − environment we are likely to want to be able to cancel event | |
| 294 | − pollers at arbitrary times. Therefore we can't improve this | |
| 295 | − situation by just splitting this loop into two loops | |
| 296 | − (i.e. signal 'stop' for all items, sleep, and then delete all | |
| 297 | − items). We also can't fix the problem via EPOLL_CTL_DEL | |
| 298 | − because that command can't prevent the case where some other | |
| 299 | − thread is executing read_thread_function within the region | |
| 300 | − mentioned above: */ | |
| 301 | − usleep(1); | |
| 302 | − pthread_mutex_lock(&epoll_items[index].mutex); | |
| 303 | − if (!epoll_items[index].deleted) | |
| 304 | − delete_item(index); | |
| 305 | − pthread_mutex_unlock(&epoll_items[index].mutex); | |
| 306 | − } | |
| 307 | −#endif | |
| 308 | − | |
| 309 | − /* Shut down the read threads: */ | |
| 310 | − for (index = 0; index < n_read_threads; ++index) | |
| 311 | − __sync_fetch_and_add(&read_thread_data[index].stop, 1); | |
| 312 | − for (index = 0; index < n_read_threads; ++index) { | |
| 313 | − if (pthread_join(read_threads[index], NULL) != 0) | |
| 314 | − goto error; | |
| 315 | − if (read_thread_data[index].status) | |
| 316 | − goto error; | |
| 317 | − } | |
| 318 | − | |
| 319 | − /* Shut down the write thread: */ | |
| 320 | − __sync_fetch_and_add(&write_thread_data.stop, 1); | |
| 321 | − if ((pthread_join(write_thread, NULL) != 0) || write_thread_data.status) | |
| 322 | − goto error; | |
| 323 | − | |
| 324 | − /* Check for final error conditions: */ | |
| 325 | − for (index = 0; index < n_epoll_items; ++index) { | |
| 326 | − if (epoll_items[index].status != 0) | |
| 327 | − goto error; | |
| 328 | − if (pthread_mutex_destroy(&epoll_items[index].mutex) < 0) | |
| 329 | − goto error; | |
| 330 | − } | |
| 331 | − for (index = 0; index < n_epoll_items; ++index) | |
| 332 | − if (epoll_items[index].deleted != 1) { | |
| 333 | − printf("Error: item data deleted %1d times.\n", | |
| 334 | − epoll_items[index].deleted); | |
| 335 | − goto error; | |
| 336 | − } | |
| 337 | − | |
| 338 | − printf("[PASS]\n"); | |
| 339 | − return 0; | |
| 340 | − | |
| 341 | − error: | |
| 342 | − printf("[FAIL]\n"); | |
| 343 | − return errno; | |
| 344 | −} | |