mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-07-05 21:35:46 +02:00
Merge branch 'v4.14/standard/base' into v4.14/standard/arm-versatile-926ejs
This commit is contained in:
commit
cd7e9214a6
|
@ -1905,8 +1905,12 @@
|
||||||
Default is 1 (enabled)
|
Default is 1 (enabled)
|
||||||
|
|
||||||
kvm-intel.emulate_invalid_guest_state=
|
kvm-intel.emulate_invalid_guest_state=
|
||||||
[KVM,Intel] Enable emulation of invalid guest states
|
[KVM,Intel] Disable emulation of invalid guest state.
|
||||||
Default is 0 (disabled)
|
Ignored if kvm-intel.enable_unrestricted_guest=1, as
|
||||||
|
guest state is never invalid for unrestricted guests.
|
||||||
|
This param doesn't apply to nested guests (L2), as KVM
|
||||||
|
never emulates invalid L2 guest state.
|
||||||
|
Default is 1 (enabled)
|
||||||
|
|
||||||
kvm-intel.flexpriority=
|
kvm-intel.flexpriority=
|
||||||
[KVM,Intel] Disable FlexPriority feature (TPR shadow).
|
[KVM,Intel] Disable FlexPriority feature (TPR shadow).
|
||||||
|
|
|
@ -43,26 +43,26 @@ group emmc_nb
|
||||||
|
|
||||||
group pwm0
|
group pwm0
|
||||||
- pin 11 (GPIO1-11)
|
- pin 11 (GPIO1-11)
|
||||||
- functions pwm, gpio
|
- functions pwm, led, gpio
|
||||||
|
|
||||||
group pwm1
|
group pwm1
|
||||||
- pin 12
|
- pin 12
|
||||||
- functions pwm, gpio
|
- functions pwm, led, gpio
|
||||||
|
|
||||||
group pwm2
|
group pwm2
|
||||||
- pin 13
|
- pin 13
|
||||||
- functions pwm, gpio
|
- functions pwm, led, gpio
|
||||||
|
|
||||||
group pwm3
|
group pwm3
|
||||||
- pin 14
|
- pin 14
|
||||||
- functions pwm, gpio
|
- functions pwm, led, gpio
|
||||||
|
|
||||||
group pmic1
|
group pmic1
|
||||||
- pin 17
|
- pin 7
|
||||||
- functions pmic, gpio
|
- functions pmic, gpio
|
||||||
|
|
||||||
group pmic0
|
group pmic0
|
||||||
- pin 16
|
- pin 6
|
||||||
- functions pmic, gpio
|
- functions pmic, gpio
|
||||||
|
|
||||||
group i2c2
|
group i2c2
|
||||||
|
@ -112,17 +112,25 @@ group usb2_drvvbus1
|
||||||
- functions drvbus, gpio
|
- functions drvbus, gpio
|
||||||
|
|
||||||
group sdio_sb
|
group sdio_sb
|
||||||
- pins 60-64
|
- pins 60-65
|
||||||
- functions sdio, gpio
|
- functions sdio, gpio
|
||||||
|
|
||||||
group rgmii
|
group rgmii
|
||||||
- pins 42-55
|
- pins 42-53
|
||||||
- functions mii, gpio
|
- functions mii, gpio
|
||||||
|
|
||||||
group pcie1
|
group pcie1
|
||||||
- pins 39-40
|
- pins 39
|
||||||
- functions pcie, gpio
|
- functions pcie, gpio
|
||||||
|
|
||||||
|
group pcie1_clkreq
|
||||||
|
- pins 40
|
||||||
|
- functions pcie, gpio
|
||||||
|
|
||||||
|
group smi
|
||||||
|
- pins 54-55
|
||||||
|
- functions smi, gpio
|
||||||
|
|
||||||
group ptp
|
group ptp
|
||||||
- pins 56-58
|
- pins 56-58
|
||||||
- functions ptp, gpio
|
- functions ptp, gpio
|
||||||
|
|
|
@ -191,11 +191,12 @@ ad_actor_sys_prio
|
||||||
ad_actor_system
|
ad_actor_system
|
||||||
|
|
||||||
In an AD system, this specifies the mac-address for the actor in
|
In an AD system, this specifies the mac-address for the actor in
|
||||||
protocol packet exchanges (LACPDUs). The value cannot be NULL or
|
protocol packet exchanges (LACPDUs). The value cannot be a multicast
|
||||||
multicast. It is preferred to have the local-admin bit set for this
|
address. If the all-zeroes MAC is specified, bonding will internally
|
||||||
mac but driver does not enforce it. If the value is not given then
|
use the MAC of the bond itself. It is preferred to have the
|
||||||
system defaults to using the masters' mac address as actors' system
|
local-admin bit set for this mac but driver does not enforce it. If
|
||||||
address.
|
the value is not given then system defaults to using the masters'
|
||||||
|
mac address as actors' system address.
|
||||||
|
|
||||||
This parameter has effect only in 802.3ad mode and is available through
|
This parameter has effect only in 802.3ad mode and is available through
|
||||||
SysFs interface.
|
SysFs interface.
|
||||||
|
|
|
@ -30,8 +30,7 @@ conn_reuse_mode - INTEGER
|
||||||
|
|
||||||
0: disable any special handling on port reuse. The new
|
0: disable any special handling on port reuse. The new
|
||||||
connection will be delivered to the same real server that was
|
connection will be delivered to the same real server that was
|
||||||
servicing the previous connection. This will effectively
|
servicing the previous connection.
|
||||||
disable expire_nodest_conn.
|
|
||||||
|
|
||||||
bit 1: enable rescheduling of new connections when it is safe.
|
bit 1: enable rescheduling of new connections when it is safe.
|
||||||
That is, whenever expire_nodest_conn and for TCP sockets, when
|
That is, whenever expire_nodest_conn and for TCP sockets, when
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 14
|
PATCHLEVEL = 14
|
||||||
SUBLEVEL = 256
|
SUBLEVEL = 262
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Petit Gorille
|
NAME = Petit Gorille
|
||||||
|
|
||||||
|
|
|
@ -980,4 +980,7 @@ config HAVE_ARCH_COMPILER_H
|
||||||
linux/compiler-*.h in order to override macro definitions that those
|
linux/compiler-*.h in order to override macro definitions that those
|
||||||
headers generally provide.
|
headers generally provide.
|
||||||
|
|
||||||
|
config ARCH_USE_MEMREMAP_PROT
|
||||||
|
bool
|
||||||
|
|
||||||
source "kernel/gcov/Kconfig"
|
source "kernel/gcov/Kconfig"
|
||||||
|
|
|
@ -16,30 +16,42 @@ config ARM_PTDUMP
|
||||||
kernel.
|
kernel.
|
||||||
If in doubt, say "N"
|
If in doubt, say "N"
|
||||||
|
|
||||||
# RMK wants arm kernels compiled with frame pointers or stack unwinding.
|
choice
|
||||||
# If you know what you are doing and are willing to live without stack
|
prompt "Choose kernel unwinder"
|
||||||
# traces, you can get a slightly smaller kernel by setting this option to
|
default UNWINDER_ARM if AEABI && !FUNCTION_GRAPH_TRACER
|
||||||
# n, but then RMK will have to kill you ;).
|
default UNWINDER_FRAME_POINTER if !AEABI || FUNCTION_GRAPH_TRACER
|
||||||
config FRAME_POINTER
|
|
||||||
bool
|
|
||||||
depends on !THUMB2_KERNEL
|
|
||||||
default y if !ARM_UNWIND || FUNCTION_GRAPH_TRACER
|
|
||||||
help
|
help
|
||||||
If you say N here, the resulting kernel will be slightly smaller and
|
This determines which method will be used for unwinding kernel stack
|
||||||
faster. However, if neither FRAME_POINTER nor ARM_UNWIND are enabled,
|
traces for panics, oopses, bugs, warnings, perf, /proc/<pid>/stack,
|
||||||
when a problem occurs with the kernel, the information that is
|
livepatch, lockdep, and more.
|
||||||
reported is severely limited.
|
|
||||||
|
|
||||||
config ARM_UNWIND
|
config UNWINDER_FRAME_POINTER
|
||||||
bool "Enable stack unwinding support (EXPERIMENTAL)"
|
bool "Frame pointer unwinder"
|
||||||
|
depends on !THUMB2_KERNEL && !CC_IS_CLANG
|
||||||
|
select ARCH_WANT_FRAME_POINTERS
|
||||||
|
select FRAME_POINTER
|
||||||
|
help
|
||||||
|
This option enables the frame pointer unwinder for unwinding
|
||||||
|
kernel stack traces.
|
||||||
|
|
||||||
|
config UNWINDER_ARM
|
||||||
|
bool "ARM EABI stack unwinder"
|
||||||
depends on AEABI
|
depends on AEABI
|
||||||
default y
|
select ARM_UNWIND
|
||||||
help
|
help
|
||||||
This option enables stack unwinding support in the kernel
|
This option enables stack unwinding support in the kernel
|
||||||
using the information automatically generated by the
|
using the information automatically generated by the
|
||||||
compiler. The resulting kernel image is slightly bigger but
|
compiler. The resulting kernel image is slightly bigger but
|
||||||
the performance is not affected. Currently, this feature
|
the performance is not affected. Currently, this feature
|
||||||
only works with EABI compilers. If unsure say Y.
|
only works with EABI compilers.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config ARM_UNWIND
|
||||||
|
bool
|
||||||
|
|
||||||
|
config FRAME_POINTER
|
||||||
|
bool
|
||||||
|
|
||||||
config OLD_MCOUNT
|
config OLD_MCOUNT
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -246,6 +246,8 @@
|
||||||
|
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
pcie0: pcie@12000 {
|
pcie0: pcie@12000 {
|
||||||
|
@ -365,7 +367,7 @@
|
||||||
i2c0: i2c@18009000 {
|
i2c0: i2c@18009000 {
|
||||||
compatible = "brcm,iproc-i2c";
|
compatible = "brcm,iproc-i2c";
|
||||||
reg = <0x18009000 0x50>;
|
reg = <0x18009000 0x50>;
|
||||||
interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
clock-frequency = <100000>;
|
clock-frequency = <100000>;
|
||||||
|
|
|
@ -51,6 +51,6 @@
|
||||||
#define MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS 0x01F4 0x0480 0x0000 0x9 0x0
|
#define MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS 0x01F4 0x0480 0x0000 0x9 0x0
|
||||||
#define MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK 0x01F8 0x0484 0x0000 0x9 0x0
|
#define MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK 0x01F8 0x0484 0x0000 0x9 0x0
|
||||||
#define MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0 0x01FC 0x0488 0x0000 0x9 0x0
|
#define MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0 0x01FC 0x0488 0x0000 0x9 0x0
|
||||||
#define MX6ULL_PAD_CSI_DATA07__ESAI_T0 0x0200 0x048C 0x0000 0x9 0x0
|
#define MX6ULL_PAD_CSI_DATA07__ESAI_TX0 0x0200 0x048C 0x0000 0x9 0x0
|
||||||
|
|
||||||
#endif /* __DTS_IMX6ULL_PINFUNC_H */
|
#endif /* __DTS_IMX6ULL_PINFUNC_H */
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
flash0: n25q00@0 {
|
flash0: n25q00@0 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "n25q00aa";
|
compatible = "micron,mt25qu02g", "jedec,spi-nor";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
spi-max-frequency = <100000000>;
|
spi-max-frequency = <100000000>;
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@
|
||||||
flash: flash@0 {
|
flash: flash@0 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "n25q256a";
|
compatible = "micron,n25q256a", "jedec,spi-nor";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
spi-max-frequency = <100000000>;
|
spi-max-frequency = <100000000>;
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@
|
||||||
flash0: n25q00@0 {
|
flash0: n25q00@0 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "n25q00";
|
compatible = "micron,mt25qu02g", "jedec,spi-nor";
|
||||||
reg = <0>; /* chip select */
|
reg = <0>; /* chip select */
|
||||||
spi-max-frequency = <100000000>;
|
spi-max-frequency = <100000000>;
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@
|
||||||
flash: flash@0 {
|
flash: flash@0 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "n25q00";
|
compatible = "micron,mt25qu02g", "jedec,spi-nor";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
spi-max-frequency = <100000000>;
|
spi-max-frequency = <100000000>;
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@
|
||||||
flash: flash@0 {
|
flash: flash@0 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "n25q256a";
|
compatible = "micron,n25q256a", "jedec,spi-nor";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
spi-max-frequency = <100000000>;
|
spi-max-frequency = <100000000>;
|
||||||
m25p,fast-read;
|
m25p,fast-read;
|
||||||
|
|
|
@ -128,7 +128,7 @@
|
||||||
flash0: n25q512a@0 {
|
flash0: n25q512a@0 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "n25q512a";
|
compatible = "micron,n25q512a", "jedec,spi-nor";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
spi-max-frequency = <100000000>;
|
spi-max-frequency = <100000000>;
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@
|
||||||
n25q128@0 {
|
n25q128@0 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "n25q128";
|
compatible = "micron,n25q128", "jedec,spi-nor";
|
||||||
reg = <0>; /* chip select */
|
reg = <0>; /* chip select */
|
||||||
spi-max-frequency = <100000000>;
|
spi-max-frequency = <100000000>;
|
||||||
m25p,fast-read;
|
m25p,fast-read;
|
||||||
|
@ -266,7 +266,7 @@
|
||||||
n25q00@1 {
|
n25q00@1 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "n25q00";
|
compatible = "micron,mt25qu02g", "jedec,spi-nor";
|
||||||
reg = <1>; /* chip select */
|
reg = <1>; /* chip select */
|
||||||
spi-max-frequency = <100000000>;
|
spi-max-frequency = <100000000>;
|
||||||
m25p,fast-read;
|
m25p,fast-read;
|
||||||
|
|
|
@ -280,6 +280,14 @@ tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr
|
||||||
tlb_add_flush(tlb, addr);
|
tlb_add_flush(tlb, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address,
|
||||||
|
unsigned long size)
|
||||||
|
{
|
||||||
|
tlb_add_flush(tlb, address);
|
||||||
|
tlb_add_flush(tlb, address + size - PMD_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr)
|
#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr)
|
||||||
#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr)
|
#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr)
|
||||||
#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
|
#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
|
||||||
|
|
|
@ -624,11 +624,9 @@ call_fpe:
|
||||||
tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2
|
tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2
|
||||||
reteq lr
|
reteq lr
|
||||||
and r8, r0, #0x00000f00 @ mask out CP number
|
and r8, r0, #0x00000f00 @ mask out CP number
|
||||||
THUMB( lsr r8, r8, #8 )
|
|
||||||
mov r7, #1
|
mov r7, #1
|
||||||
add r6, r10, #TI_USED_CP
|
add r6, r10, r8, lsr #8 @ add used_cp[] array offset first
|
||||||
ARM( strb r7, [r6, r8, lsr #8] ) @ set appropriate used_cp[]
|
strb r7, [r6, #TI_USED_CP] @ set appropriate used_cp[]
|
||||||
THUMB( strb r7, [r6, r8] ) @ set appropriate used_cp[]
|
|
||||||
#ifdef CONFIG_IWMMXT
|
#ifdef CONFIG_IWMMXT
|
||||||
@ Test if we need to give access to iWMMXt coprocessors
|
@ Test if we need to give access to iWMMXt coprocessors
|
||||||
ldr r5, [r10, #TI_FLAGS]
|
ldr r5, [r10, #TI_FLAGS]
|
||||||
|
@ -637,7 +635,7 @@ call_fpe:
|
||||||
bcs iwmmxt_task_enable
|
bcs iwmmxt_task_enable
|
||||||
#endif
|
#endif
|
||||||
ARM( add pc, pc, r8, lsr #6 )
|
ARM( add pc, pc, r8, lsr #6 )
|
||||||
THUMB( lsl r8, r8, #2 )
|
THUMB( lsr r8, r8, #6 )
|
||||||
THUMB( add pc, r8 )
|
THUMB( add pc, r8 )
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ extern void __iomem *sdr_ctl_base_addr;
|
||||||
u32 socfpga_sdram_self_refresh(u32 sdr_base);
|
u32 socfpga_sdram_self_refresh(u32 sdr_base);
|
||||||
extern unsigned int socfpga_sdram_self_refresh_sz;
|
extern unsigned int socfpga_sdram_self_refresh_sz;
|
||||||
|
|
||||||
extern char secondary_trampoline, secondary_trampoline_end;
|
extern char secondary_trampoline[], secondary_trampoline_end[];
|
||||||
|
|
||||||
extern unsigned long socfpga_cpu1start_addr;
|
extern unsigned long socfpga_cpu1start_addr;
|
||||||
|
|
||||||
|
|
|
@ -31,14 +31,14 @@
|
||||||
|
|
||||||
static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
{
|
{
|
||||||
int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
|
int trampoline_size = secondary_trampoline_end - secondary_trampoline;
|
||||||
|
|
||||||
if (socfpga_cpu1start_addr) {
|
if (socfpga_cpu1start_addr) {
|
||||||
/* This will put CPU #1 into reset. */
|
/* This will put CPU #1 into reset. */
|
||||||
writel(RSTMGR_MPUMODRST_CPU1,
|
writel(RSTMGR_MPUMODRST_CPU1,
|
||||||
rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST);
|
rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST);
|
||||||
|
|
||||||
memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
|
memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size);
|
||||||
|
|
||||||
writel(__pa_symbol(secondary_startup),
|
writel(__pa_symbol(secondary_startup),
|
||||||
sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff));
|
sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff));
|
||||||
|
@ -56,12 +56,12 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
|
|
||||||
static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
{
|
{
|
||||||
int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
|
int trampoline_size = secondary_trampoline_end - secondary_trampoline;
|
||||||
|
|
||||||
if (socfpga_cpu1start_addr) {
|
if (socfpga_cpu1start_addr) {
|
||||||
writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr +
|
writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr +
|
||||||
SOCFPGA_A10_RSTMGR_MODMPURST);
|
SOCFPGA_A10_RSTMGR_MODMPURST);
|
||||||
memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
|
memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size);
|
||||||
|
|
||||||
writel(__pa_symbol(secondary_startup),
|
writel(__pa_symbol(secondary_startup),
|
||||||
sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff));
|
sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff));
|
||||||
|
|
|
@ -17,26 +17,25 @@
|
||||||
/*
|
/*
|
||||||
* Faraday optimised copy_user_page
|
* Faraday optimised copy_user_page
|
||||||
*/
|
*/
|
||||||
static void __naked
|
static void fa_copy_user_page(void *kto, const void *kfrom)
|
||||||
fa_copy_user_page(void *kto, const void *kfrom)
|
|
||||||
{
|
{
|
||||||
asm("\
|
int tmp;
|
||||||
stmfd sp!, {r4, lr} @ 2\n\
|
|
||||||
mov r2, %0 @ 1\n\
|
asm volatile ("\
|
||||||
1: ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
1: ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
stmia r0, {r3, r4, ip, lr} @ 4\n\
|
stmia %0, {r3, r4, ip, lr} @ 4\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
||||||
add r0, r0, #16 @ 1\n\
|
add %0, %0, #16 @ 1\n\
|
||||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
stmia r0, {r3, r4, ip, lr} @ 4\n\
|
stmia %0, {r3, r4, ip, lr} @ 4\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
|
||||||
add r0, r0, #16 @ 1\n\
|
add %0, %0, #16 @ 1\n\
|
||||||
subs r2, r2, #1 @ 1\n\
|
subs %2, %2, #1 @ 1\n\
|
||||||
bne 1b @ 1\n\
|
bne 1b @ 1\n\
|
||||||
mcr p15, 0, r2, c7, c10, 4 @ 1 drain WB\n\
|
mcr p15, 0, %2, c7, c10, 4 @ 1 drain WB"
|
||||||
ldmfd sp!, {r4, pc} @ 3"
|
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||||
:
|
: "2" (PAGE_SIZE / 32)
|
||||||
: "I" (PAGE_SIZE / 32));
|
: "r3", "r4", "ip", "lr");
|
||||||
}
|
}
|
||||||
|
|
||||||
void fa_copy_user_highpage(struct page *to, struct page *from,
|
void fa_copy_user_highpage(struct page *to, struct page *from,
|
||||||
|
|
|
@ -13,58 +13,56 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
|
|
||||||
static void __naked
|
static void feroceon_copy_user_page(void *kto, const void *kfrom)
|
||||||
feroceon_copy_user_page(void *kto, const void *kfrom)
|
|
||||||
{
|
{
|
||||||
asm("\
|
int tmp;
|
||||||
stmfd sp!, {r4-r9, lr} \n\
|
|
||||||
mov ip, %2 \n\
|
asm volatile ("\
|
||||||
1: mov lr, r1 \n\
|
1: ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||||
ldmia r1!, {r2 - r9} \n\
|
pld [%1, #0] \n\
|
||||||
pld [lr, #32] \n\
|
pld [%1, #32] \n\
|
||||||
pld [lr, #64] \n\
|
pld [%1, #64] \n\
|
||||||
pld [lr, #96] \n\
|
pld [%1, #96] \n\
|
||||||
pld [lr, #128] \n\
|
pld [%1, #128] \n\
|
||||||
pld [lr, #160] \n\
|
pld [%1, #160] \n\
|
||||||
pld [lr, #192] \n\
|
pld [%1, #192] \n\
|
||||||
pld [lr, #224] \n\
|
stmia %0, {r2 - r7, ip, lr} \n\
|
||||||
stmia r0, {r2 - r9} \n\
|
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||||
ldmia r1!, {r2 - r9} \n\
|
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
add %0, %0, #32 \n\
|
||||||
add r0, r0, #32 \n\
|
stmia %0, {r2 - r7, ip, lr} \n\
|
||||||
stmia r0, {r2 - r9} \n\
|
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||||
ldmia r1!, {r2 - r9} \n\
|
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
add %0, %0, #32 \n\
|
||||||
add r0, r0, #32 \n\
|
stmia %0, {r2 - r7, ip, lr} \n\
|
||||||
stmia r0, {r2 - r9} \n\
|
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||||
ldmia r1!, {r2 - r9} \n\
|
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
add %0, %0, #32 \n\
|
||||||
add r0, r0, #32 \n\
|
stmia %0, {r2 - r7, ip, lr} \n\
|
||||||
stmia r0, {r2 - r9} \n\
|
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||||
ldmia r1!, {r2 - r9} \n\
|
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
add %0, %0, #32 \n\
|
||||||
add r0, r0, #32 \n\
|
stmia %0, {r2 - r7, ip, lr} \n\
|
||||||
stmia r0, {r2 - r9} \n\
|
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||||
ldmia r1!, {r2 - r9} \n\
|
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
add %0, %0, #32 \n\
|
||||||
add r0, r0, #32 \n\
|
stmia %0, {r2 - r7, ip, lr} \n\
|
||||||
stmia r0, {r2 - r9} \n\
|
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||||
ldmia r1!, {r2 - r9} \n\
|
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
add %0, %0, #32 \n\
|
||||||
add r0, r0, #32 \n\
|
stmia %0, {r2 - r7, ip, lr} \n\
|
||||||
stmia r0, {r2 - r9} \n\
|
ldmia %1!, {r2 - r7, ip, lr} \n\
|
||||||
ldmia r1!, {r2 - r9} \n\
|
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
add %0, %0, #32 \n\
|
||||||
add r0, r0, #32 \n\
|
stmia %0, {r2 - r7, ip, lr} \n\
|
||||||
stmia r0, {r2 - r9} \n\
|
subs %2, %2, #(32 * 8) \n\
|
||||||
subs ip, ip, #(32 * 8) \n\
|
mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
|
add %0, %0, #32 \n\
|
||||||
add r0, r0, #32 \n\
|
|
||||||
bne 1b \n\
|
bne 1b \n\
|
||||||
mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\
|
mcr p15, 0, %2, c7, c10, 4 @ drain WB"
|
||||||
ldmfd sp!, {r4-r9, pc}"
|
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||||
:
|
: "2" (PAGE_SIZE)
|
||||||
: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE));
|
: "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
|
||||||
}
|
}
|
||||||
|
|
||||||
void feroceon_copy_user_highpage(struct page *to, struct page *from,
|
void feroceon_copy_user_highpage(struct page *to, struct page *from,
|
||||||
|
|
|
@ -40,12 +40,11 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
|
||||||
* instruction. If your processor does not supply this, you have to write your
|
* instruction. If your processor does not supply this, you have to write your
|
||||||
* own copy_user_highpage that does the right thing.
|
* own copy_user_highpage that does the right thing.
|
||||||
*/
|
*/
|
||||||
static void __naked
|
static void mc_copy_user_page(void *from, void *to)
|
||||||
mc_copy_user_page(void *from, void *to)
|
|
||||||
{
|
{
|
||||||
asm volatile(
|
int tmp;
|
||||||
"stmfd sp!, {r4, lr} @ 2\n\
|
|
||||||
mov r4, %2 @ 1\n\
|
asm volatile ("\
|
||||||
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||||
1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
||||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||||
|
@ -55,13 +54,13 @@ mc_copy_user_page(void *from, void *to)
|
||||||
mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
||||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||||
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||||
subs r4, r4, #1 @ 1\n\
|
subs %2, %2, #1 @ 1\n\
|
||||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||||
ldmneia %0!, {r2, r3, ip, lr} @ 4\n\
|
ldmneia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||||
bne 1b @ 1\n\
|
bne 1b @ "
|
||||||
ldmfd sp!, {r4, pc} @ 3"
|
: "+&r" (from), "+&r" (to), "=&r" (tmp)
|
||||||
:
|
: "2" (PAGE_SIZE / 64)
|
||||||
: "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
|
: "r2", "r3", "ip", "lr");
|
||||||
}
|
}
|
||||||
|
|
||||||
void v4_mc_copy_user_highpage(struct page *to, struct page *from,
|
void v4_mc_copy_user_highpage(struct page *to, struct page *from,
|
||||||
|
|
|
@ -22,29 +22,28 @@
|
||||||
* instruction. If your processor does not supply this, you have to write your
|
* instruction. If your processor does not supply this, you have to write your
|
||||||
* own copy_user_highpage that does the right thing.
|
* own copy_user_highpage that does the right thing.
|
||||||
*/
|
*/
|
||||||
static void __naked
|
static void v4wb_copy_user_page(void *kto, const void *kfrom)
|
||||||
v4wb_copy_user_page(void *kto, const void *kfrom)
|
|
||||||
{
|
{
|
||||||
asm("\
|
int tmp;
|
||||||
stmfd sp!, {r4, lr} @ 2\n\
|
|
||||||
mov r2, %2 @ 1\n\
|
asm volatile ("\
|
||||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
|
1: mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
|
||||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||||
ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\
|
ldmia %1!, {r3, r4, ip, lr} @ 4+1\n\
|
||||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
|
mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
|
||||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
subs r2, r2, #1 @ 1\n\
|
subs %2, %2, #1 @ 1\n\
|
||||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||||
ldmneia r1!, {r3, r4, ip, lr} @ 4\n\
|
ldmneia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
bne 1b @ 1\n\
|
bne 1b @ 1\n\
|
||||||
mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB\n\
|
mcr p15, 0, %1, c7, c10, 4 @ 1 drain WB"
|
||||||
ldmfd sp!, {r4, pc} @ 3"
|
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||||
:
|
: "2" (PAGE_SIZE / 64)
|
||||||
: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
|
: "r3", "r4", "ip", "lr");
|
||||||
}
|
}
|
||||||
|
|
||||||
void v4wb_copy_user_highpage(struct page *to, struct page *from,
|
void v4wb_copy_user_highpage(struct page *to, struct page *from,
|
||||||
|
|
|
@ -20,27 +20,26 @@
|
||||||
* dirty data in the cache. However, we do have to ensure that
|
* dirty data in the cache. However, we do have to ensure that
|
||||||
* subsequent reads are up to date.
|
* subsequent reads are up to date.
|
||||||
*/
|
*/
|
||||||
static void __naked
|
static void v4wt_copy_user_page(void *kto, const void *kfrom)
|
||||||
v4wt_copy_user_page(void *kto, const void *kfrom)
|
|
||||||
{
|
{
|
||||||
asm("\
|
int tmp;
|
||||||
stmfd sp!, {r4, lr} @ 2\n\
|
|
||||||
mov r2, %2 @ 1\n\
|
asm volatile ("\
|
||||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
1: stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
1: stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||||
ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\
|
ldmia %1!, {r3, r4, ip, lr} @ 4+1\n\
|
||||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||||
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
|
ldmia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
subs r2, r2, #1 @ 1\n\
|
subs %2, %2, #1 @ 1\n\
|
||||||
stmia r0!, {r3, r4, ip, lr} @ 4\n\
|
stmia %0!, {r3, r4, ip, lr} @ 4\n\
|
||||||
ldmneia r1!, {r3, r4, ip, lr} @ 4\n\
|
ldmneia %1!, {r3, r4, ip, lr} @ 4\n\
|
||||||
bne 1b @ 1\n\
|
bne 1b @ 1\n\
|
||||||
mcr p15, 0, r2, c7, c7, 0 @ flush ID cache\n\
|
mcr p15, 0, %2, c7, c7, 0 @ flush ID cache"
|
||||||
ldmfd sp!, {r4, pc} @ 3"
|
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||||
:
|
: "2" (PAGE_SIZE / 64)
|
||||||
: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
|
: "r3", "r4", "ip", "lr");
|
||||||
}
|
}
|
||||||
|
|
||||||
void v4wt_copy_user_highpage(struct page *to, struct page *from,
|
void v4wt_copy_user_highpage(struct page *to, struct page *from,
|
||||||
|
|
|
@ -21,53 +21,46 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XSC3 optimised copy_user_highpage
|
* XSC3 optimised copy_user_highpage
|
||||||
* r0 = destination
|
|
||||||
* r1 = source
|
|
||||||
*
|
*
|
||||||
* The source page may have some clean entries in the cache already, but we
|
* The source page may have some clean entries in the cache already, but we
|
||||||
* can safely ignore them - break_cow() will flush them out of the cache
|
* can safely ignore them - break_cow() will flush them out of the cache
|
||||||
* if we eventually end up using our copied page.
|
* if we eventually end up using our copied page.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void __naked
|
static void xsc3_mc_copy_user_page(void *kto, const void *kfrom)
|
||||||
xsc3_mc_copy_user_page(void *kto, const void *kfrom)
|
|
||||||
{
|
{
|
||||||
asm("\
|
int tmp;
|
||||||
stmfd sp!, {r4, r5, lr} \n\
|
|
||||||
mov lr, %2 \n\
|
asm volatile ("\
|
||||||
|
pld [%1, #0] \n\
|
||||||
|
pld [%1, #32] \n\
|
||||||
|
1: pld [%1, #64] \n\
|
||||||
|
pld [%1, #96] \n\
|
||||||
\n\
|
\n\
|
||||||
pld [r1, #0] \n\
|
2: ldrd r2, [%1], #8 \n\
|
||||||
pld [r1, #32] \n\
|
ldrd r4, [%1], #8 \n\
|
||||||
1: pld [r1, #64] \n\
|
mcr p15, 0, %0, c7, c6, 1 @ invalidate\n\
|
||||||
pld [r1, #96] \n\
|
strd r2, [%0], #8 \n\
|
||||||
\n\
|
ldrd r2, [%1], #8 \n\
|
||||||
2: ldrd r2, [r1], #8 \n\
|
strd r4, [%0], #8 \n\
|
||||||
mov ip, r0 \n\
|
ldrd r4, [%1], #8 \n\
|
||||||
ldrd r4, [r1], #8 \n\
|
strd r2, [%0], #8 \n\
|
||||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\
|
strd r4, [%0], #8 \n\
|
||||||
strd r2, [r0], #8 \n\
|
ldrd r2, [%1], #8 \n\
|
||||||
ldrd r2, [r1], #8 \n\
|
ldrd r4, [%1], #8 \n\
|
||||||
strd r4, [r0], #8 \n\
|
mcr p15, 0, %0, c7, c6, 1 @ invalidate\n\
|
||||||
ldrd r4, [r1], #8 \n\
|
strd r2, [%0], #8 \n\
|
||||||
strd r2, [r0], #8 \n\
|
ldrd r2, [%1], #8 \n\
|
||||||
strd r4, [r0], #8 \n\
|
subs %2, %2, #1 \n\
|
||||||
ldrd r2, [r1], #8 \n\
|
strd r4, [%0], #8 \n\
|
||||||
mov ip, r0 \n\
|
ldrd r4, [%1], #8 \n\
|
||||||
ldrd r4, [r1], #8 \n\
|
strd r2, [%0], #8 \n\
|
||||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\
|
strd r4, [%0], #8 \n\
|
||||||
strd r2, [r0], #8 \n\
|
|
||||||
ldrd r2, [r1], #8 \n\
|
|
||||||
subs lr, lr, #1 \n\
|
|
||||||
strd r4, [r0], #8 \n\
|
|
||||||
ldrd r4, [r1], #8 \n\
|
|
||||||
strd r2, [r0], #8 \n\
|
|
||||||
strd r4, [r0], #8 \n\
|
|
||||||
bgt 1b \n\
|
bgt 1b \n\
|
||||||
beq 2b \n\
|
beq 2b "
|
||||||
\n\
|
: "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
|
||||||
ldmfd sp!, {r4, r5, pc}"
|
: "2" (PAGE_SIZE / 64 - 1)
|
||||||
:
|
: "r2", "r3", "r4", "r5");
|
||||||
: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
|
void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
|
||||||
|
@ -85,8 +78,6 @@ void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XScale optimised clear_user_page
|
* XScale optimised clear_user_page
|
||||||
* r0 = destination
|
|
||||||
* r1 = virtual user address of ultimate destination page
|
|
||||||
*/
|
*/
|
||||||
void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
|
void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,52 +36,51 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
|
||||||
* Dcache aliasing issue. The writes will be forwarded to the write buffer,
|
* Dcache aliasing issue. The writes will be forwarded to the write buffer,
|
||||||
* and merged as appropriate.
|
* and merged as appropriate.
|
||||||
*/
|
*/
|
||||||
static void __naked
|
static void mc_copy_user_page(void *from, void *to)
|
||||||
mc_copy_user_page(void *from, void *to)
|
|
||||||
{
|
{
|
||||||
|
int tmp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Strangely enough, best performance is achieved
|
* Strangely enough, best performance is achieved
|
||||||
* when prefetching destination as well. (NP)
|
* when prefetching destination as well. (NP)
|
||||||
*/
|
*/
|
||||||
asm volatile(
|
asm volatile ("\
|
||||||
"stmfd sp!, {r4, r5, lr} \n\
|
pld [%0, #0] \n\
|
||||||
mov lr, %2 \n\
|
pld [%0, #32] \n\
|
||||||
pld [r0, #0] \n\
|
pld [%1, #0] \n\
|
||||||
pld [r0, #32] \n\
|
pld [%1, #32] \n\
|
||||||
pld [r1, #0] \n\
|
1: pld [%0, #64] \n\
|
||||||
pld [r1, #32] \n\
|
pld [%0, #96] \n\
|
||||||
1: pld [r0, #64] \n\
|
pld [%1, #64] \n\
|
||||||
pld [r0, #96] \n\
|
pld [%1, #96] \n\
|
||||||
pld [r1, #64] \n\
|
2: ldrd r2, [%0], #8 \n\
|
||||||
pld [r1, #96] \n\
|
ldrd r4, [%0], #8 \n\
|
||||||
2: ldrd r2, [r0], #8 \n\
|
mov ip, %1 \n\
|
||||||
ldrd r4, [r0], #8 \n\
|
strd r2, [%1], #8 \n\
|
||||||
mov ip, r1 \n\
|
ldrd r2, [%0], #8 \n\
|
||||||
strd r2, [r1], #8 \n\
|
strd r4, [%1], #8 \n\
|
||||||
ldrd r2, [r0], #8 \n\
|
ldrd r4, [%0], #8 \n\
|
||||||
strd r4, [r1], #8 \n\
|
strd r2, [%1], #8 \n\
|
||||||
ldrd r4, [r0], #8 \n\
|
strd r4, [%1], #8 \n\
|
||||||
strd r2, [r1], #8 \n\
|
|
||||||
strd r4, [r1], #8 \n\
|
|
||||||
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
||||||
ldrd r2, [r0], #8 \n\
|
ldrd r2, [%0], #8 \n\
|
||||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
||||||
ldrd r4, [r0], #8 \n\
|
ldrd r4, [%0], #8 \n\
|
||||||
mov ip, r1 \n\
|
mov ip, %1 \n\
|
||||||
strd r2, [r1], #8 \n\
|
strd r2, [%1], #8 \n\
|
||||||
ldrd r2, [r0], #8 \n\
|
ldrd r2, [%0], #8 \n\
|
||||||
strd r4, [r1], #8 \n\
|
strd r4, [%1], #8 \n\
|
||||||
ldrd r4, [r0], #8 \n\
|
ldrd r4, [%0], #8 \n\
|
||||||
strd r2, [r1], #8 \n\
|
strd r2, [%1], #8 \n\
|
||||||
strd r4, [r1], #8 \n\
|
strd r4, [%1], #8 \n\
|
||||||
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
||||||
subs lr, lr, #1 \n\
|
subs %2, %2, #1 \n\
|
||||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
||||||
bgt 1b \n\
|
bgt 1b \n\
|
||||||
beq 2b \n\
|
beq 2b "
|
||||||
ldmfd sp!, {r4, r5, pc} "
|
: "+&r" (from), "+&r" (to), "=&r" (tmp)
|
||||||
:
|
: "2" (PAGE_SIZE / 64 - 1)
|
||||||
: "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
|
: "r2", "r3", "r4", "r5", "ip");
|
||||||
}
|
}
|
||||||
|
|
||||||
void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
|
void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
|
||||||
|
|
|
@ -155,6 +155,9 @@
|
||||||
|
|
||||||
/* CON15(V2.0)/CON17(V1.4) : PCIe / CON15(V2.0)/CON12(V1.4) :mini-PCIe */
|
/* CON15(V2.0)/CON17(V1.4) : PCIe / CON15(V2.0)/CON12(V1.4) :mini-PCIe */
|
||||||
&pcie0 {
|
&pcie0 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>;
|
||||||
|
reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,9 @@
|
||||||
|
|
||||||
/* J9 */
|
/* J9 */
|
||||||
&pcie0 {
|
&pcie0 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>;
|
||||||
|
reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,15 @@
|
||||||
function = "mii";
|
function = "mii";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pcie_reset_pins: pcie-reset-pins {
|
||||||
|
groups = "pcie1";
|
||||||
|
function = "gpio";
|
||||||
|
};
|
||||||
|
|
||||||
|
pcie_clkreq_pins: pcie-clkreq-pins {
|
||||||
|
groups = "pcie1_clkreq";
|
||||||
|
function = "pcie";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
eth0: ethernet@30000 {
|
eth0: ethernet@30000 {
|
||||||
|
|
|
@ -269,6 +269,16 @@ __tlb_remove_tlb_entry (struct mmu_gather *tlb, pte_t *ptep, unsigned long addre
|
||||||
tlb->end_addr = address + PAGE_SIZE;
|
tlb->end_addr = address + PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address,
|
||||||
|
unsigned long size)
|
||||||
|
{
|
||||||
|
if (tlb->start_addr > address)
|
||||||
|
tlb->start_addr = address;
|
||||||
|
if (tlb->end_addr < address + size)
|
||||||
|
tlb->end_addr = address + size;
|
||||||
|
}
|
||||||
|
|
||||||
#define tlb_migrate_finish(mm) platform_tlb_migrate_finish(mm)
|
#define tlb_migrate_finish(mm) platform_tlb_migrate_finish(mm)
|
||||||
|
|
||||||
#define tlb_start_vma(tlb, vma) do { } while (0)
|
#define tlb_start_vma(tlb, vma) do { } while (0)
|
||||||
|
|
|
@ -2990,7 +2990,7 @@ config HAVE_LATENCYTOP_SUPPORT
|
||||||
config PGTABLE_LEVELS
|
config PGTABLE_LEVELS
|
||||||
int
|
int
|
||||||
default 4 if PAGE_SIZE_4KB && MIPS_VA_BITS_48
|
default 4 if PAGE_SIZE_4KB && MIPS_VA_BITS_48
|
||||||
default 3 if 64BIT && !PAGE_SIZE_64KB
|
default 3 if 64BIT && (!PAGE_SIZE_64KB || MIPS_VA_BITS_48)
|
||||||
default 2
|
default 2
|
||||||
|
|
||||||
source "init/Kconfig"
|
source "init/Kconfig"
|
||||||
|
|
|
@ -17,7 +17,12 @@
|
||||||
# Mike Shaver, Helge Deller and Martin K. Petersen
|
# Mike Shaver, Helge Deller and Martin K. Petersen
|
||||||
#
|
#
|
||||||
|
|
||||||
|
ifdef CONFIG_PARISC_SELF_EXTRACT
|
||||||
|
boot := arch/parisc/boot
|
||||||
|
KBUILD_IMAGE := $(boot)/bzImage
|
||||||
|
else
|
||||||
KBUILD_IMAGE := vmlinuz
|
KBUILD_IMAGE := vmlinuz
|
||||||
|
endif
|
||||||
|
|
||||||
KBUILD_DEFCONFIG := default_defconfig
|
KBUILD_DEFCONFIG := default_defconfig
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ verify "$3"
|
||||||
if [ -n "${INSTALLKERNEL}" ]; then
|
if [ -n "${INSTALLKERNEL}" ]; then
|
||||||
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
|
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
|
||||||
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
|
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
|
||||||
|
if [ -x /usr/sbin/${INSTALLKERNEL} ]; then exec /usr/sbin/${INSTALLKERNEL} "$@"; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Default install
|
# Default install
|
||||||
|
|
|
@ -245,27 +245,13 @@ void __init time_init(void)
|
||||||
static int __init init_cr16_clocksource(void)
|
static int __init init_cr16_clocksource(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The cr16 interval timers are not syncronized across CPUs on
|
* The cr16 interval timers are not syncronized across CPUs, even if
|
||||||
* different sockets, so mark them unstable and lower rating on
|
* they share the same socket.
|
||||||
* multi-socket SMP systems.
|
|
||||||
*/
|
*/
|
||||||
if (num_online_cpus() > 1 && !running_on_qemu) {
|
if (num_online_cpus() > 1 && !running_on_qemu) {
|
||||||
int cpu;
|
clocksource_cr16.name = "cr16_unstable";
|
||||||
unsigned long cpu0_loc;
|
clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
|
||||||
cpu0_loc = per_cpu(cpu_data, 0).cpu_loc;
|
clocksource_cr16.rating = 0;
|
||||||
|
|
||||||
for_each_online_cpu(cpu) {
|
|
||||||
if (cpu == 0)
|
|
||||||
continue;
|
|
||||||
if ((cpu0_loc != 0) &&
|
|
||||||
(cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
clocksource_cr16.name = "cr16_unstable";
|
|
||||||
clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
|
|
||||||
clocksource_cr16.rating = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: We may want to mark sched_clock stable here if cr16 clocks are
|
/* XXX: We may want to mark sched_clock stable here if cr16 clocks are
|
||||||
|
|
|
@ -116,6 +116,20 @@ static inline void tlb_remove_page_size(struct mmu_gather *tlb,
|
||||||
return tlb_remove_page(tlb, page);
|
return tlb_remove_page(tlb, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void tlb_flush_pmd_range(struct mmu_gather *tlb,
|
||||||
|
unsigned long address, unsigned long size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* the range might exceed the original range that was provided to
|
||||||
|
* tlb_gather_mmu(), so we need to update it despite the fact it is
|
||||||
|
* usually not updated.
|
||||||
|
*/
|
||||||
|
if (tlb->start > address)
|
||||||
|
tlb->start = address;
|
||||||
|
if (tlb->end < address + size)
|
||||||
|
tlb->end = address + size;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pte_free_tlb frees a pte table and clears the CRSTE for the
|
* pte_free_tlb frees a pte table and clears the CRSTE for the
|
||||||
* page table from the tlb.
|
* page table from the tlb.
|
||||||
|
|
|
@ -706,9 +706,6 @@ static void __init setup_memory(void)
|
||||||
storage_key_init_range(reg->base, reg->base + reg->size);
|
storage_key_init_range(reg->base, reg->base + reg->size);
|
||||||
}
|
}
|
||||||
psw_set_key(PAGE_DEFAULT_KEY);
|
psw_set_key(PAGE_DEFAULT_KEY);
|
||||||
|
|
||||||
/* Only cosmetics */
|
|
||||||
memblock_enforce_memory_limit(memblock_end_of_DRAM());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -896,6 +896,7 @@ EXPORT_SYMBOL(get_guest_storage_key);
|
||||||
int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc,
|
int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc,
|
||||||
unsigned long *oldpte, unsigned long *oldpgste)
|
unsigned long *oldpte, unsigned long *oldpgste)
|
||||||
{
|
{
|
||||||
|
struct vm_area_struct *vma;
|
||||||
unsigned long pgstev;
|
unsigned long pgstev;
|
||||||
spinlock_t *ptl;
|
spinlock_t *ptl;
|
||||||
pgste_t pgste;
|
pgste_t pgste;
|
||||||
|
@ -905,6 +906,10 @@ int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc,
|
||||||
WARN_ON_ONCE(orc > ESSA_MAX);
|
WARN_ON_ONCE(orc > ESSA_MAX);
|
||||||
if (unlikely(orc > ESSA_MAX))
|
if (unlikely(orc > ESSA_MAX))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
vma = find_vma(mm, hva);
|
||||||
|
if (!vma || hva < vma->vm_start || is_vm_hugetlb_page(vma))
|
||||||
|
return -EFAULT;
|
||||||
ptep = get_locked_pte(mm, hva, &ptl);
|
ptep = get_locked_pte(mm, hva, &ptl);
|
||||||
if (unlikely(!ptep))
|
if (unlikely(!ptep))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -997,10 +1002,14 @@ EXPORT_SYMBOL(pgste_perform_essa);
|
||||||
int set_pgste_bits(struct mm_struct *mm, unsigned long hva,
|
int set_pgste_bits(struct mm_struct *mm, unsigned long hva,
|
||||||
unsigned long bits, unsigned long value)
|
unsigned long bits, unsigned long value)
|
||||||
{
|
{
|
||||||
|
struct vm_area_struct *vma;
|
||||||
spinlock_t *ptl;
|
spinlock_t *ptl;
|
||||||
pgste_t new;
|
pgste_t new;
|
||||||
pte_t *ptep;
|
pte_t *ptep;
|
||||||
|
|
||||||
|
vma = find_vma(mm, hva);
|
||||||
|
if (!vma || hva < vma->vm_start || is_vm_hugetlb_page(vma))
|
||||||
|
return -EFAULT;
|
||||||
ptep = get_locked_pte(mm, hva, &ptl);
|
ptep = get_locked_pte(mm, hva, &ptl);
|
||||||
if (unlikely(!ptep))
|
if (unlikely(!ptep))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -1025,9 +1034,13 @@ EXPORT_SYMBOL(set_pgste_bits);
|
||||||
*/
|
*/
|
||||||
int get_pgste(struct mm_struct *mm, unsigned long hva, unsigned long *pgstep)
|
int get_pgste(struct mm_struct *mm, unsigned long hva, unsigned long *pgstep)
|
||||||
{
|
{
|
||||||
|
struct vm_area_struct *vma;
|
||||||
spinlock_t *ptl;
|
spinlock_t *ptl;
|
||||||
pte_t *ptep;
|
pte_t *ptep;
|
||||||
|
|
||||||
|
vma = find_vma(mm, hva);
|
||||||
|
if (!vma || hva < vma->vm_start || is_vm_hugetlb_page(vma))
|
||||||
|
return -EFAULT;
|
||||||
ptep = get_locked_pte(mm, hva, &ptl);
|
ptep = get_locked_pte(mm, hva, &ptl);
|
||||||
if (unlikely(!ptep))
|
if (unlikely(!ptep))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
|
@ -127,6 +127,16 @@ static inline void tlb_remove_page_size(struct mmu_gather *tlb,
|
||||||
return tlb_remove_page(tlb, page);
|
return tlb_remove_page(tlb, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address,
|
||||||
|
unsigned long size)
|
||||||
|
{
|
||||||
|
if (tlb->start > address)
|
||||||
|
tlb->start = address;
|
||||||
|
if (tlb->end < address + size)
|
||||||
|
tlb->end = address + size;
|
||||||
|
}
|
||||||
|
|
||||||
#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
|
#define tlb_remove_check_page_size_change tlb_remove_check_page_size_change
|
||||||
static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
|
static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
|
||||||
unsigned int page_size)
|
unsigned int page_size)
|
||||||
|
|
|
@ -130,6 +130,18 @@ static inline void tlb_remove_page_size(struct mmu_gather *tlb,
|
||||||
return tlb_remove_page(tlb, page);
|
return tlb_remove_page(tlb, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
tlb_flush_pmd_range(struct mmu_gather *tlb, unsigned long address,
|
||||||
|
unsigned long size)
|
||||||
|
{
|
||||||
|
tlb->need_flush = 1;
|
||||||
|
|
||||||
|
if (tlb->start > address)
|
||||||
|
tlb->start = address;
|
||||||
|
if (tlb->end < address + size)
|
||||||
|
tlb->end = address + size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tlb_remove_tlb_entry - remember a pte unmapping for later tlb invalidation.
|
* tlb_remove_tlb_entry - remember a pte unmapping for later tlb invalidation.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1449,6 +1449,7 @@ config ARCH_HAS_MEM_ENCRYPT
|
||||||
config AMD_MEM_ENCRYPT
|
config AMD_MEM_ENCRYPT
|
||||||
bool "AMD Secure Memory Encryption (SME) support"
|
bool "AMD Secure Memory Encryption (SME) support"
|
||||||
depends on X86_64 && CPU_SUP_AMD
|
depends on X86_64 && CPU_SUP_AMD
|
||||||
|
select ARCH_USE_MEMREMAP_PROT
|
||||||
---help---
|
---help---
|
||||||
Say yes to enable support for the encryption of system memory.
|
Say yes to enable support for the encryption of system memory.
|
||||||
This requires an AMD processor that supports Secure Memory
|
This requires an AMD processor that supports Secure Memory
|
||||||
|
@ -1467,10 +1468,6 @@ config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
|
||||||
If set to N, then the encryption of system memory can be
|
If set to N, then the encryption of system memory can be
|
||||||
activated with the mem_encrypt=on command line option.
|
activated with the mem_encrypt=on command line option.
|
||||||
|
|
||||||
config ARCH_USE_MEMREMAP_PROT
|
|
||||||
def_bool y
|
|
||||||
depends on AMD_MEM_ENCRYPT
|
|
||||||
|
|
||||||
# Common NUMA Features
|
# Common NUMA Features
|
||||||
config NUMA
|
config NUMA
|
||||||
bool "Numa Memory Allocation and Scheduler Support"
|
bool "Numa Memory Allocation and Scheduler Support"
|
||||||
|
@ -1903,6 +1900,7 @@ config EFI
|
||||||
depends on ACPI
|
depends on ACPI
|
||||||
select UCS2_STRING
|
select UCS2_STRING
|
||||||
select EFI_RUNTIME_WRAPPERS
|
select EFI_RUNTIME_WRAPPERS
|
||||||
|
select ARCH_USE_MEMREMAP_PROT
|
||||||
---help---
|
---help---
|
||||||
This enables the kernel to use EFI runtime services that are
|
This enables the kernel to use EFI runtime services that are
|
||||||
available (such as the EFI variable services).
|
available (such as the EFI variable services).
|
||||||
|
|
|
@ -1220,8 +1220,8 @@ static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PKRU_AD_BIT 0x1
|
#define PKRU_AD_BIT 0x1u
|
||||||
#define PKRU_WD_BIT 0x2
|
#define PKRU_WD_BIT 0x2u
|
||||||
#define PKRU_BITS_PER_PKEY 2
|
#define PKRU_BITS_PER_PKEY 2
|
||||||
|
|
||||||
static inline bool __pkru_allows_read(u32 pkru, u16 pkey)
|
static inline bool __pkru_allows_read(u32 pkru, u16 pkey)
|
||||||
|
|
|
@ -626,7 +626,7 @@ bool phys_mem_access_encrypted(unsigned long phys_addr, unsigned long size)
|
||||||
return arch_memremap_can_ram_remap(phys_addr, size, 0);
|
return arch_memremap_can_ram_remap(phys_addr, size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_USE_MEMREMAP_PROT
|
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
||||||
/* Remap memory with encryption */
|
/* Remap memory with encryption */
|
||||||
void __init *early_memremap_encrypted(resource_size_t phys_addr,
|
void __init *early_memremap_encrypted(resource_size_t phys_addr,
|
||||||
unsigned long size)
|
unsigned long size)
|
||||||
|
@ -668,7 +668,7 @@ void __init *early_memremap_decrypted_wp(resource_size_t phys_addr,
|
||||||
|
|
||||||
return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_NOENC_WP);
|
return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_NOENC_WP);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ARCH_USE_MEMREMAP_PROT */
|
#endif /* CONFIG_AMD_MEM_ENCRYPT */
|
||||||
|
|
||||||
static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
|
static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,8 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = early_memremap(new_phys, new_size);
|
new = early_memremap_prot(new_phys, new_size,
|
||||||
|
pgprot_val(pgprot_encrypted(FIXMAP_PAGE_NORMAL)));
|
||||||
if (!new) {
|
if (!new) {
|
||||||
pr_err("Failed to map new boot services memmap\n");
|
pr_err("Failed to map new boot services memmap\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -57,6 +57,7 @@ static void __init setup_real_mode(void)
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
u64 *trampoline_pgd;
|
u64 *trampoline_pgd;
|
||||||
u64 efer;
|
u64 efer;
|
||||||
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
base = (unsigned char *)real_mode_header;
|
base = (unsigned char *)real_mode_header;
|
||||||
|
@ -114,8 +115,17 @@ static void __init setup_real_mode(void)
|
||||||
trampoline_header->flags |= TH_FLAGS_SME_ACTIVE;
|
trampoline_header->flags |= TH_FLAGS_SME_ACTIVE;
|
||||||
|
|
||||||
trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
|
trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
|
||||||
|
|
||||||
|
/* Map the real mode stub as virtual == physical */
|
||||||
trampoline_pgd[0] = trampoline_pgd_entry.pgd;
|
trampoline_pgd[0] = trampoline_pgd_entry.pgd;
|
||||||
trampoline_pgd[511] = init_top_pgt[511].pgd;
|
|
||||||
|
/*
|
||||||
|
* Include the entirety of the kernel mapping into the trampoline
|
||||||
|
* PGD. This way, all mappings present in the normal kernel page
|
||||||
|
* tables are usable while running on trampoline_pgd.
|
||||||
|
*/
|
||||||
|
for (i = pgd_index(__PAGE_OFFSET); i < PTRS_PER_PGD; i++)
|
||||||
|
trampoline_pgd[i] = init_top_pgt[i].pgd;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
|
||||||
pgrp = task_pgrp(current);
|
pgrp = task_pgrp(current);
|
||||||
else
|
else
|
||||||
pgrp = find_vpid(who);
|
pgrp = find_vpid(who);
|
||||||
|
read_lock(&tasklist_lock);
|
||||||
do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
|
do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
|
||||||
tmpio = get_task_ioprio(p);
|
tmpio = get_task_ioprio(p);
|
||||||
if (tmpio < 0)
|
if (tmpio < 0)
|
||||||
|
@ -205,6 +206,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
|
||||||
else
|
else
|
||||||
ret = ioprio_best(ret, tmpio);
|
ret = ioprio_best(ret, tmpio);
|
||||||
} while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
|
} while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
|
||||||
|
read_unlock(&tasklist_lock);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IOPRIO_WHO_USER:
|
case IOPRIO_WHO_USER:
|
||||||
uid = make_kuid(current_user_ns(), who);
|
uid = make_kuid(current_user_ns(), who);
|
||||||
|
|
|
@ -2894,7 +2894,7 @@ static void binder_transaction(struct binder_proc *proc,
|
||||||
t->from = thread;
|
t->from = thread;
|
||||||
else
|
else
|
||||||
t->from = NULL;
|
t->from = NULL;
|
||||||
t->sender_euid = proc->cred->euid;
|
t->sender_euid = task_euid(proc->tsk);
|
||||||
t->to_proc = target_proc;
|
t->to_proc = target_proc;
|
||||||
t->to_thread = target_thread;
|
t->to_thread = target_thread;
|
||||||
t->code = tr->code;
|
t->code = tr->code;
|
||||||
|
@ -4336,23 +4336,20 @@ static int binder_thread_release(struct binder_proc *proc,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this thread used poll, make sure we remove the waitqueue
|
* If this thread used poll, make sure we remove the waitqueue from any
|
||||||
* from any epoll data structures holding it with POLLFREE.
|
* poll data structures holding it.
|
||||||
* waitqueue_active() is safe to use here because we're holding
|
|
||||||
* the inner lock.
|
|
||||||
*/
|
*/
|
||||||
if ((thread->looper & BINDER_LOOPER_STATE_POLL) &&
|
if (thread->looper & BINDER_LOOPER_STATE_POLL)
|
||||||
waitqueue_active(&thread->wait)) {
|
wake_up_pollfree(&thread->wait);
|
||||||
wake_up_poll(&thread->wait, POLLHUP | POLLFREE);
|
|
||||||
}
|
|
||||||
|
|
||||||
binder_inner_proc_unlock(thread->proc);
|
binder_inner_proc_unlock(thread->proc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is needed to avoid races between wake_up_poll() above and
|
* This is needed to avoid races between wake_up_pollfree() above and
|
||||||
* and ep_remove_waitqueue() called for other reasons (eg the epoll file
|
* someone else removing the last entry from the queue for other reasons
|
||||||
* descriptor being closed); ep_remove_waitqueue() holds an RCU read
|
* (e.g. ep_remove_wait_queue() being called due to an epoll file
|
||||||
* lock, so we can be sure it's done after calling synchronize_rcu().
|
* descriptor being closed). Such other users hold an RCU read lock, so
|
||||||
|
* we can be sure they're done after we call synchronize_rcu().
|
||||||
*/
|
*/
|
||||||
if (thread->looper & BINDER_LOOPER_STATE_POLL)
|
if (thread->looper & BINDER_LOOPER_STATE_POLL)
|
||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
|
|
|
@ -619,7 +619,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc,
|
||||||
BUG_ON(buffer->data > alloc->buffer + alloc->buffer_size);
|
BUG_ON(buffer->data > alloc->buffer + alloc->buffer_size);
|
||||||
|
|
||||||
if (buffer->async_transaction) {
|
if (buffer->async_transaction) {
|
||||||
alloc->free_async_space += size + sizeof(struct binder_buffer);
|
alloc->free_async_space += buffer_size + sizeof(struct binder_buffer);
|
||||||
|
|
||||||
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
|
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
|
||||||
"%d: binder_free_buf size %zd async free %zd\n",
|
"%d: binder_free_buf size %zd async free %zd\n",
|
||||||
|
|
|
@ -4449,6 +4449,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||||
{ "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA },
|
{ "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA },
|
||||||
/* Odd clown on sil3726/4726 PMPs */
|
/* Odd clown on sil3726/4726 PMPs */
|
||||||
{ "Config Disk", NULL, ATA_HORKAGE_DISABLE },
|
{ "Config Disk", NULL, ATA_HORKAGE_DISABLE },
|
||||||
|
/* Similar story with ASMedia 1092 */
|
||||||
|
{ "ASMT109x- Config", NULL, ATA_HORKAGE_DISABLE },
|
||||||
|
|
||||||
/* Weird ATAPI devices */
|
/* Weird ATAPI devices */
|
||||||
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
|
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
|
||||||
|
|
|
@ -3182,8 +3182,19 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
||||||
goto invalid_fld;
|
goto invalid_fld;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ata_is_ncq(tf->protocol) && (cdb[2 + cdb_offset] & 0x3) == 0)
|
if ((cdb[2 + cdb_offset] & 0x3) == 0) {
|
||||||
tf->protocol = ATA_PROT_NCQ_NODATA;
|
/*
|
||||||
|
* When T_LENGTH is zero (No data is transferred), dir should
|
||||||
|
* be DMA_NONE.
|
||||||
|
*/
|
||||||
|
if (scmd->sc_data_direction != DMA_NONE) {
|
||||||
|
fp = 2 + cdb_offset;
|
||||||
|
goto invalid_fld;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ata_is_ncq(tf->protocol))
|
||||||
|
tf->protocol = ATA_PROT_NCQ_NODATA;
|
||||||
|
}
|
||||||
|
|
||||||
/* enable LBA */
|
/* enable LBA */
|
||||||
tf->flags |= ATA_TFLAG_LBA;
|
tf->flags |= ATA_TFLAG_LBA;
|
||||||
|
|
|
@ -1406,6 +1406,14 @@ static int sata_fsl_init_controller(struct ata_host *host)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sata_fsl_host_stop(struct ata_host *host)
|
||||||
|
{
|
||||||
|
struct sata_fsl_host_priv *host_priv = host->private_data;
|
||||||
|
|
||||||
|
iounmap(host_priv->hcr_base);
|
||||||
|
kfree(host_priv);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* scsi mid-layer and libata interface structures
|
* scsi mid-layer and libata interface structures
|
||||||
*/
|
*/
|
||||||
|
@ -1438,6 +1446,8 @@ static struct ata_port_operations sata_fsl_ops = {
|
||||||
.port_start = sata_fsl_port_start,
|
.port_start = sata_fsl_port_start,
|
||||||
.port_stop = sata_fsl_port_stop,
|
.port_stop = sata_fsl_port_stop,
|
||||||
|
|
||||||
|
.host_stop = sata_fsl_host_stop,
|
||||||
|
|
||||||
.pmp_attach = sata_fsl_pmp_attach,
|
.pmp_attach = sata_fsl_pmp_attach,
|
||||||
.pmp_detach = sata_fsl_pmp_detach,
|
.pmp_detach = sata_fsl_pmp_detach,
|
||||||
};
|
};
|
||||||
|
@ -1492,9 +1502,9 @@ static int sata_fsl_probe(struct platform_device *ofdev)
|
||||||
host_priv->ssr_base = ssr_base;
|
host_priv->ssr_base = ssr_base;
|
||||||
host_priv->csr_base = csr_base;
|
host_priv->csr_base = csr_base;
|
||||||
|
|
||||||
irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
|
irq = platform_get_irq(ofdev, 0);
|
||||||
if (!irq) {
|
if (irq < 0) {
|
||||||
dev_err(&ofdev->dev, "invalid irq from platform\n");
|
retval = irq;
|
||||||
goto error_exit_with_cleanup;
|
goto error_exit_with_cleanup;
|
||||||
}
|
}
|
||||||
host_priv->irq = irq;
|
host_priv->irq = irq;
|
||||||
|
@ -1569,10 +1579,6 @@ static int sata_fsl_remove(struct platform_device *ofdev)
|
||||||
|
|
||||||
ata_host_detach(host);
|
ata_host_detach(host);
|
||||||
|
|
||||||
irq_dispose_mapping(host_priv->irq);
|
|
||||||
iounmap(host_priv->hcr_base);
|
|
||||||
kfree(host_priv);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ enum blkif_state {
|
||||||
BLKIF_STATE_DISCONNECTED,
|
BLKIF_STATE_DISCONNECTED,
|
||||||
BLKIF_STATE_CONNECTED,
|
BLKIF_STATE_CONNECTED,
|
||||||
BLKIF_STATE_SUSPENDED,
|
BLKIF_STATE_SUSPENDED,
|
||||||
|
BLKIF_STATE_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grant {
|
struct grant {
|
||||||
|
@ -87,6 +88,7 @@ struct grant {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum blk_req_status {
|
enum blk_req_status {
|
||||||
|
REQ_PROCESSING,
|
||||||
REQ_WAITING,
|
REQ_WAITING,
|
||||||
REQ_DONE,
|
REQ_DONE,
|
||||||
REQ_ERROR,
|
REQ_ERROR,
|
||||||
|
@ -534,10 +536,10 @@ static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
|
||||||
|
|
||||||
id = get_id_from_freelist(rinfo);
|
id = get_id_from_freelist(rinfo);
|
||||||
rinfo->shadow[id].request = req;
|
rinfo->shadow[id].request = req;
|
||||||
rinfo->shadow[id].status = REQ_WAITING;
|
rinfo->shadow[id].status = REQ_PROCESSING;
|
||||||
rinfo->shadow[id].associated_id = NO_ASSOCIATED_ID;
|
rinfo->shadow[id].associated_id = NO_ASSOCIATED_ID;
|
||||||
|
|
||||||
(*ring_req)->u.rw.id = id;
|
rinfo->shadow[id].req.u.rw.id = id;
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -545,11 +547,12 @@ static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
|
||||||
static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_info *rinfo)
|
static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_info *rinfo)
|
||||||
{
|
{
|
||||||
struct blkfront_info *info = rinfo->dev_info;
|
struct blkfront_info *info = rinfo->dev_info;
|
||||||
struct blkif_request *ring_req;
|
struct blkif_request *ring_req, *final_ring_req;
|
||||||
unsigned long id;
|
unsigned long id;
|
||||||
|
|
||||||
/* Fill out a communications ring structure. */
|
/* Fill out a communications ring structure. */
|
||||||
id = blkif_ring_get_request(rinfo, req, &ring_req);
|
id = blkif_ring_get_request(rinfo, req, &final_ring_req);
|
||||||
|
ring_req = &rinfo->shadow[id].req;
|
||||||
|
|
||||||
ring_req->operation = BLKIF_OP_DISCARD;
|
ring_req->operation = BLKIF_OP_DISCARD;
|
||||||
ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
|
ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
|
||||||
|
@ -560,8 +563,9 @@ static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_inf
|
||||||
else
|
else
|
||||||
ring_req->u.discard.flag = 0;
|
ring_req->u.discard.flag = 0;
|
||||||
|
|
||||||
/* Keep a private copy so we can reissue requests when recovering. */
|
/* Copy the request to the ring page. */
|
||||||
rinfo->shadow[id].req = *ring_req;
|
*final_ring_req = *ring_req;
|
||||||
|
rinfo->shadow[id].status = REQ_WAITING;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -694,6 +698,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
|
||||||
{
|
{
|
||||||
struct blkfront_info *info = rinfo->dev_info;
|
struct blkfront_info *info = rinfo->dev_info;
|
||||||
struct blkif_request *ring_req, *extra_ring_req = NULL;
|
struct blkif_request *ring_req, *extra_ring_req = NULL;
|
||||||
|
struct blkif_request *final_ring_req, *final_extra_ring_req = NULL;
|
||||||
unsigned long id, extra_id = NO_ASSOCIATED_ID;
|
unsigned long id, extra_id = NO_ASSOCIATED_ID;
|
||||||
bool require_extra_req = false;
|
bool require_extra_req = false;
|
||||||
int i;
|
int i;
|
||||||
|
@ -738,7 +743,8 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill out a communications ring structure. */
|
/* Fill out a communications ring structure. */
|
||||||
id = blkif_ring_get_request(rinfo, req, &ring_req);
|
id = blkif_ring_get_request(rinfo, req, &final_ring_req);
|
||||||
|
ring_req = &rinfo->shadow[id].req;
|
||||||
|
|
||||||
num_sg = blk_rq_map_sg(req->q, req, rinfo->shadow[id].sg);
|
num_sg = blk_rq_map_sg(req->q, req, rinfo->shadow[id].sg);
|
||||||
num_grant = 0;
|
num_grant = 0;
|
||||||
|
@ -789,7 +795,9 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
|
||||||
ring_req->u.rw.nr_segments = num_grant;
|
ring_req->u.rw.nr_segments = num_grant;
|
||||||
if (unlikely(require_extra_req)) {
|
if (unlikely(require_extra_req)) {
|
||||||
extra_id = blkif_ring_get_request(rinfo, req,
|
extra_id = blkif_ring_get_request(rinfo, req,
|
||||||
&extra_ring_req);
|
&final_extra_ring_req);
|
||||||
|
extra_ring_req = &rinfo->shadow[extra_id].req;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only the first request contains the scatter-gather
|
* Only the first request contains the scatter-gather
|
||||||
* list.
|
* list.
|
||||||
|
@ -831,10 +839,13 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
|
||||||
if (setup.segments)
|
if (setup.segments)
|
||||||
kunmap_atomic(setup.segments);
|
kunmap_atomic(setup.segments);
|
||||||
|
|
||||||
/* Keep a private copy so we can reissue requests when recovering. */
|
/* Copy request(s) to the ring page. */
|
||||||
rinfo->shadow[id].req = *ring_req;
|
*final_ring_req = *ring_req;
|
||||||
if (unlikely(require_extra_req))
|
rinfo->shadow[id].status = REQ_WAITING;
|
||||||
rinfo->shadow[extra_id].req = *extra_ring_req;
|
if (unlikely(require_extra_req)) {
|
||||||
|
*final_extra_ring_req = *extra_ring_req;
|
||||||
|
rinfo->shadow[extra_id].status = REQ_WAITING;
|
||||||
|
}
|
||||||
|
|
||||||
if (new_persistent_gnts)
|
if (new_persistent_gnts)
|
||||||
gnttab_free_grant_references(setup.gref_head);
|
gnttab_free_grant_references(setup.gref_head);
|
||||||
|
@ -1408,8 +1419,8 @@ static enum blk_req_status blkif_rsp_to_req_status(int rsp)
|
||||||
static int blkif_get_final_status(enum blk_req_status s1,
|
static int blkif_get_final_status(enum blk_req_status s1,
|
||||||
enum blk_req_status s2)
|
enum blk_req_status s2)
|
||||||
{
|
{
|
||||||
BUG_ON(s1 == REQ_WAITING);
|
BUG_ON(s1 < REQ_DONE);
|
||||||
BUG_ON(s2 == REQ_WAITING);
|
BUG_ON(s2 < REQ_DONE);
|
||||||
|
|
||||||
if (s1 == REQ_ERROR || s2 == REQ_ERROR)
|
if (s1 == REQ_ERROR || s2 == REQ_ERROR)
|
||||||
return BLKIF_RSP_ERROR;
|
return BLKIF_RSP_ERROR;
|
||||||
|
@ -1442,7 +1453,7 @@ static bool blkif_completion(unsigned long *id,
|
||||||
s->status = blkif_rsp_to_req_status(bret->status);
|
s->status = blkif_rsp_to_req_status(bret->status);
|
||||||
|
|
||||||
/* Wait the second response if not yet here. */
|
/* Wait the second response if not yet here. */
|
||||||
if (s2->status == REQ_WAITING)
|
if (s2->status < REQ_DONE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bret->status = blkif_get_final_status(s->status,
|
bret->status = blkif_get_final_status(s->status,
|
||||||
|
@ -1550,65 +1561,92 @@ static bool blkif_completion(unsigned long *id,
|
||||||
static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct request *req;
|
struct request *req;
|
||||||
struct blkif_response *bret;
|
struct blkif_response bret;
|
||||||
RING_IDX i, rp;
|
RING_IDX i, rp;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
|
struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
|
||||||
struct blkfront_info *info = rinfo->dev_info;
|
struct blkfront_info *info = rinfo->dev_info;
|
||||||
|
unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;
|
||||||
|
|
||||||
if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
|
if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
|
||||||
|
xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&rinfo->ring_lock, flags);
|
spin_lock_irqsave(&rinfo->ring_lock, flags);
|
||||||
again:
|
again:
|
||||||
rp = rinfo->ring.sring->rsp_prod;
|
rp = READ_ONCE(rinfo->ring.sring->rsp_prod);
|
||||||
rmb(); /* Ensure we see queued responses up to 'rp'. */
|
virt_rmb(); /* Ensure we see queued responses up to 'rp'. */
|
||||||
|
if (RING_RESPONSE_PROD_OVERFLOW(&rinfo->ring, rp)) {
|
||||||
|
pr_alert("%s: illegal number of responses %u\n",
|
||||||
|
info->gd->disk_name, rp - rinfo->ring.rsp_cons);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = rinfo->ring.rsp_cons; i != rp; i++) {
|
for (i = rinfo->ring.rsp_cons; i != rp; i++) {
|
||||||
unsigned long id;
|
unsigned long id;
|
||||||
|
unsigned int op;
|
||||||
|
|
||||||
|
eoiflag = 0;
|
||||||
|
|
||||||
|
RING_COPY_RESPONSE(&rinfo->ring, i, &bret);
|
||||||
|
id = bret.id;
|
||||||
|
|
||||||
bret = RING_GET_RESPONSE(&rinfo->ring, i);
|
|
||||||
id = bret->id;
|
|
||||||
/*
|
/*
|
||||||
* The backend has messed up and given us an id that we would
|
* The backend has messed up and given us an id that we would
|
||||||
* never have given to it (we stamp it up to BLK_RING_SIZE -
|
* never have given to it (we stamp it up to BLK_RING_SIZE -
|
||||||
* look in get_id_from_freelist.
|
* look in get_id_from_freelist.
|
||||||
*/
|
*/
|
||||||
if (id >= BLK_RING_SIZE(info)) {
|
if (id >= BLK_RING_SIZE(info)) {
|
||||||
WARN(1, "%s: response to %s has incorrect id (%ld)\n",
|
pr_alert("%s: response has incorrect id (%ld)\n",
|
||||||
info->gd->disk_name, op_name(bret->operation), id);
|
info->gd->disk_name, id);
|
||||||
/* We can't safely get the 'struct request' as
|
goto err;
|
||||||
* the id is busted. */
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
if (rinfo->shadow[id].status != REQ_WAITING) {
|
||||||
|
pr_alert("%s: response references no pending request\n",
|
||||||
|
info->gd->disk_name);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rinfo->shadow[id].status = REQ_PROCESSING;
|
||||||
req = rinfo->shadow[id].request;
|
req = rinfo->shadow[id].request;
|
||||||
|
|
||||||
if (bret->operation != BLKIF_OP_DISCARD) {
|
op = rinfo->shadow[id].req.operation;
|
||||||
|
if (op == BLKIF_OP_INDIRECT)
|
||||||
|
op = rinfo->shadow[id].req.u.indirect.indirect_op;
|
||||||
|
if (bret.operation != op) {
|
||||||
|
pr_alert("%s: response has wrong operation (%u instead of %u)\n",
|
||||||
|
info->gd->disk_name, bret.operation, op);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bret.operation != BLKIF_OP_DISCARD) {
|
||||||
/*
|
/*
|
||||||
* We may need to wait for an extra response if the
|
* We may need to wait for an extra response if the
|
||||||
* I/O request is split in 2
|
* I/O request is split in 2
|
||||||
*/
|
*/
|
||||||
if (!blkif_completion(&id, rinfo, bret))
|
if (!blkif_completion(&id, rinfo, &bret))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_id_to_freelist(rinfo, id)) {
|
if (add_id_to_freelist(rinfo, id)) {
|
||||||
WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n",
|
WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n",
|
||||||
info->gd->disk_name, op_name(bret->operation), id);
|
info->gd->disk_name, op_name(bret.operation), id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bret->status == BLKIF_RSP_OKAY)
|
if (bret.status == BLKIF_RSP_OKAY)
|
||||||
blkif_req(req)->error = BLK_STS_OK;
|
blkif_req(req)->error = BLK_STS_OK;
|
||||||
else
|
else
|
||||||
blkif_req(req)->error = BLK_STS_IOERR;
|
blkif_req(req)->error = BLK_STS_IOERR;
|
||||||
|
|
||||||
switch (bret->operation) {
|
switch (bret.operation) {
|
||||||
case BLKIF_OP_DISCARD:
|
case BLKIF_OP_DISCARD:
|
||||||
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
|
if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) {
|
||||||
struct request_queue *rq = info->rq;
|
struct request_queue *rq = info->rq;
|
||||||
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
|
|
||||||
info->gd->disk_name, op_name(bret->operation));
|
pr_warn_ratelimited("blkfront: %s: %s op failed\n",
|
||||||
|
info->gd->disk_name, op_name(bret.operation));
|
||||||
blkif_req(req)->error = BLK_STS_NOTSUPP;
|
blkif_req(req)->error = BLK_STS_NOTSUPP;
|
||||||
info->feature_discard = 0;
|
info->feature_discard = 0;
|
||||||
info->feature_secdiscard = 0;
|
info->feature_secdiscard = 0;
|
||||||
|
@ -1618,15 +1656,15 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||||
break;
|
break;
|
||||||
case BLKIF_OP_FLUSH_DISKCACHE:
|
case BLKIF_OP_FLUSH_DISKCACHE:
|
||||||
case BLKIF_OP_WRITE_BARRIER:
|
case BLKIF_OP_WRITE_BARRIER:
|
||||||
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
|
if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) {
|
||||||
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
|
pr_warn_ratelimited("blkfront: %s: %s op failed\n",
|
||||||
info->gd->disk_name, op_name(bret->operation));
|
info->gd->disk_name, op_name(bret.operation));
|
||||||
blkif_req(req)->error = BLK_STS_NOTSUPP;
|
blkif_req(req)->error = BLK_STS_NOTSUPP;
|
||||||
}
|
}
|
||||||
if (unlikely(bret->status == BLKIF_RSP_ERROR &&
|
if (unlikely(bret.status == BLKIF_RSP_ERROR &&
|
||||||
rinfo->shadow[id].req.u.rw.nr_segments == 0)) {
|
rinfo->shadow[id].req.u.rw.nr_segments == 0)) {
|
||||||
printk(KERN_WARNING "blkfront: %s: empty %s op failed\n",
|
pr_warn_ratelimited("blkfront: %s: empty %s op failed\n",
|
||||||
info->gd->disk_name, op_name(bret->operation));
|
info->gd->disk_name, op_name(bret.operation));
|
||||||
blkif_req(req)->error = BLK_STS_NOTSUPP;
|
blkif_req(req)->error = BLK_STS_NOTSUPP;
|
||||||
}
|
}
|
||||||
if (unlikely(blkif_req(req)->error)) {
|
if (unlikely(blkif_req(req)->error)) {
|
||||||
|
@ -1639,9 +1677,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case BLKIF_OP_READ:
|
case BLKIF_OP_READ:
|
||||||
case BLKIF_OP_WRITE:
|
case BLKIF_OP_WRITE:
|
||||||
if (unlikely(bret->status != BLKIF_RSP_OKAY))
|
if (unlikely(bret.status != BLKIF_RSP_OKAY))
|
||||||
dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
|
dev_dbg_ratelimited(&info->xbdev->dev,
|
||||||
"request: %x\n", bret->status);
|
"Bad return from blkdev data request: %#x\n",
|
||||||
|
bret.status);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1665,6 +1704,18 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||||
|
|
||||||
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
||||||
|
|
||||||
|
xen_irq_lateeoi(irq, eoiflag);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
|
||||||
|
err:
|
||||||
|
info->connected = BLKIF_STATE_ERROR;
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
||||||
|
|
||||||
|
/* No EOI in order to avoid further interrupts. */
|
||||||
|
|
||||||
|
pr_alert("%s disabled for further use\n", info->gd->disk_name);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1703,8 +1754,8 @@ static int setup_blkring(struct xenbus_device *dev,
|
||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
err = bind_evtchn_to_irqhandler(rinfo->evtchn, blkif_interrupt, 0,
|
err = bind_evtchn_to_irqhandler_lateeoi(rinfo->evtchn, blkif_interrupt,
|
||||||
"blkif", rinfo);
|
0, "blkif", rinfo);
|
||||||
if (err <= 0) {
|
if (err <= 0) {
|
||||||
xenbus_dev_fatal(dev, err,
|
xenbus_dev_fatal(dev, err,
|
||||||
"bind_evtchn_to_irqhandler failed");
|
"bind_evtchn_to_irqhandler failed");
|
||||||
|
|
|
@ -2548,11 +2548,9 @@ static const struct qca_device_info qca_devices_table[] = {
|
||||||
{ 0x00000302, 28, 4, 18 }, /* Rome 3.2 */
|
{ 0x00000302, 28, 4, 18 }, /* Rome 3.2 */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request,
|
static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
|
||||||
void *data, u16 size)
|
void *data, u16 size)
|
||||||
{
|
{
|
||||||
struct btusb_data *btdata = hci_get_drvdata(hdev);
|
|
||||||
struct usb_device *udev = btdata->udev;
|
|
||||||
int pipe, err;
|
int pipe, err;
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
|
|
||||||
|
@ -2567,7 +2565,7 @@ static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request,
|
||||||
err = usb_control_msg(udev, pipe, request, USB_TYPE_VENDOR | USB_DIR_IN,
|
err = usb_control_msg(udev, pipe, request, USB_TYPE_VENDOR | USB_DIR_IN,
|
||||||
0, 0, buf, size, USB_CTRL_SET_TIMEOUT);
|
0, 0, buf, size, USB_CTRL_SET_TIMEOUT);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
BT_ERR("%s: Failed to access otp area (%d)", hdev->name, err);
|
dev_err(&udev->dev, "Failed to access otp area (%d)", err);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2723,20 +2721,38 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* identify the ROM version and check whether patches are needed */
|
||||||
|
static bool btusb_qca_need_patch(struct usb_device *udev)
|
||||||
|
{
|
||||||
|
struct qca_version ver;
|
||||||
|
|
||||||
|
if (btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
|
||||||
|
sizeof(ver)) < 0)
|
||||||
|
return false;
|
||||||
|
/* only low ROM versions need patches */
|
||||||
|
return !(le32_to_cpu(ver.rom_version) & ~0xffffU);
|
||||||
|
}
|
||||||
|
|
||||||
static int btusb_setup_qca(struct hci_dev *hdev)
|
static int btusb_setup_qca(struct hci_dev *hdev)
|
||||||
{
|
{
|
||||||
|
struct btusb_data *btdata = hci_get_drvdata(hdev);
|
||||||
|
struct usb_device *udev = btdata->udev;
|
||||||
const struct qca_device_info *info = NULL;
|
const struct qca_device_info *info = NULL;
|
||||||
struct qca_version ver;
|
struct qca_version ver;
|
||||||
u32 ver_rom;
|
u32 ver_rom;
|
||||||
u8 status;
|
u8 status;
|
||||||
int i, err;
|
int i, err;
|
||||||
|
|
||||||
err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver,
|
err = btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
|
||||||
sizeof(ver));
|
sizeof(ver));
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
ver_rom = le32_to_cpu(ver.rom_version);
|
ver_rom = le32_to_cpu(ver.rom_version);
|
||||||
|
/* Don't care about high ROM versions */
|
||||||
|
if (ver_rom & ~0xffffU)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(qca_devices_table); i++) {
|
for (i = 0; i < ARRAY_SIZE(qca_devices_table); i++) {
|
||||||
if (ver_rom == qca_devices_table[i].rom_version)
|
if (ver_rom == qca_devices_table[i].rom_version)
|
||||||
info = &qca_devices_table[i];
|
info = &qca_devices_table[i];
|
||||||
|
@ -2747,7 +2763,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = btusb_qca_send_vendor_req(hdev, QCA_CHECK_STATUS, &status,
|
err = btusb_qca_send_vendor_req(udev, QCA_CHECK_STATUS, &status,
|
||||||
sizeof(status));
|
sizeof(status));
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
@ -2974,7 +2990,8 @@ static int btusb_probe(struct usb_interface *intf,
|
||||||
/* Old firmware would otherwise let ath3k driver load
|
/* Old firmware would otherwise let ath3k driver load
|
||||||
* patch and sysconfig files
|
* patch and sysconfig files
|
||||||
*/
|
*/
|
||||||
if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001)
|
if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001 &&
|
||||||
|
!btusb_qca_need_patch(udev))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3136,6 +3153,7 @@ static int btusb_probe(struct usb_interface *intf,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id->driver_info & BTUSB_ATH3012) {
|
if (id->driver_info & BTUSB_ATH3012) {
|
||||||
|
data->setup_on_usb = btusb_setup_qca;
|
||||||
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
||||||
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
||||||
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
|
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
|
||||||
|
|
|
@ -285,7 +285,7 @@ agp_ioc_init(void __iomem *ioc_regs)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int __init
|
||||||
lba_find_capability(int cap)
|
lba_find_capability(int cap)
|
||||||
{
|
{
|
||||||
struct _parisc_agp_info *info = &parisc_agp_info;
|
struct _parisc_agp_info *info = &parisc_agp_info;
|
||||||
|
@ -370,7 +370,7 @@ fail:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int __init
|
||||||
find_quicksilver(struct device *dev, void *data)
|
find_quicksilver(struct device *dev, void *data)
|
||||||
{
|
{
|
||||||
struct parisc_device **lba = data;
|
struct parisc_device **lba = data;
|
||||||
|
@ -382,7 +382,7 @@ find_quicksilver(struct device *dev, void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int __init
|
||||||
parisc_agp_init(void)
|
parisc_agp_init(void)
|
||||||
{
|
{
|
||||||
extern struct sba_device *sba_list;
|
extern struct sba_device *sba_list;
|
||||||
|
|
|
@ -886,4 +886,4 @@ MODULE_LICENSE("GPL v2");
|
||||||
MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver");
|
MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver");
|
||||||
MODULE_AUTHOR("Ludovic.barre <Ludovic.barre@st.com>");
|
MODULE_AUTHOR("Ludovic.barre <Ludovic.barre@st.com>");
|
||||||
MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
|
MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
|
||||||
MODULE_ALIAS("platform: " DRIVER_NAME);
|
MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||||
|
|
|
@ -27,7 +27,6 @@ struct scpi_pm_domain {
|
||||||
struct generic_pm_domain genpd;
|
struct generic_pm_domain genpd;
|
||||||
struct scpi_ops *ops;
|
struct scpi_ops *ops;
|
||||||
u32 domain;
|
u32 domain;
|
||||||
char name[30];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -121,8 +120,13 @@ static int scpi_pm_domain_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
scpi_pd->domain = i;
|
scpi_pd->domain = i;
|
||||||
scpi_pd->ops = scpi_ops;
|
scpi_pd->ops = scpi_ops;
|
||||||
sprintf(scpi_pd->name, "%s.%d", np->name, i);
|
scpi_pd->genpd.name = devm_kasprintf(dev, GFP_KERNEL,
|
||||||
scpi_pd->genpd.name = scpi_pd->name;
|
"%s.%d", np->name, i);
|
||||||
|
if (!scpi_pd->genpd.name) {
|
||||||
|
dev_err(dev, "Failed to allocate genpd name:%s.%d\n",
|
||||||
|
np->name, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
scpi_pd->genpd.power_off = scpi_pd_power_off;
|
scpi_pd->genpd.power_off = scpi_pd_power_off;
|
||||||
scpi_pd->genpd.power_on = scpi_pd_power_on;
|
scpi_pd->genpd.power_on = scpi_pd_power_on;
|
||||||
|
|
||||||
|
|
|
@ -1563,6 +1563,8 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host,
|
||||||
if (!prop) {
|
if (!prop) {
|
||||||
dev_dbg(dev,
|
dev_dbg(dev,
|
||||||
"failed to find data lane mapping, using default\n");
|
"failed to find data lane mapping, using default\n");
|
||||||
|
/* Set the number of date lanes to 4 by default. */
|
||||||
|
msm_host->num_data_lanes = 4;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
|
||||||
|
|
||||||
bo = kzalloc(sizeof(*bo), GFP_KERNEL);
|
bo = kzalloc(sizeof(*bo), GFP_KERNEL);
|
||||||
if (!bo)
|
if (!bo)
|
||||||
return ERR_PTR(-ENOMEM);
|
return NULL;
|
||||||
|
|
||||||
mutex_lock(&vc4->bo_lock);
|
mutex_lock(&vc4->bo_lock);
|
||||||
bo->label = VC4_BO_TYPE_KERNEL;
|
bo->label = VC4_BO_TYPE_KERNEL;
|
||||||
|
|
|
@ -148,6 +148,7 @@ config HID_APPLEIR
|
||||||
|
|
||||||
config HID_ASUS
|
config HID_ASUS
|
||||||
tristate "Asus"
|
tristate "Asus"
|
||||||
|
depends on USB_HID
|
||||||
depends on LEDS_CLASS
|
depends on LEDS_CLASS
|
||||||
---help---
|
---help---
|
||||||
Support for Asus notebook built-in keyboard and touchpad via i2c, and
|
Support for Asus notebook built-in keyboard and touchpad via i2c, and
|
||||||
|
@ -191,14 +192,14 @@ config HID_CHERRY
|
||||||
|
|
||||||
config HID_CHICONY
|
config HID_CHICONY
|
||||||
tristate "Chicony devices"
|
tristate "Chicony devices"
|
||||||
depends on HID
|
depends on USB_HID
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
---help---
|
---help---
|
||||||
Support for Chicony Tactical pad and special keys on Chicony keyboards.
|
Support for Chicony Tactical pad and special keys on Chicony keyboards.
|
||||||
|
|
||||||
config HID_CORSAIR
|
config HID_CORSAIR
|
||||||
tristate "Corsair devices"
|
tristate "Corsair devices"
|
||||||
depends on HID && USB && LEDS_CLASS
|
depends on USB_HID && LEDS_CLASS
|
||||||
---help---
|
---help---
|
||||||
Support for Corsair devices that are not fully compliant with the
|
Support for Corsair devices that are not fully compliant with the
|
||||||
HID standard.
|
HID standard.
|
||||||
|
@ -209,7 +210,7 @@ config HID_CORSAIR
|
||||||
|
|
||||||
config HID_PRODIKEYS
|
config HID_PRODIKEYS
|
||||||
tristate "Prodikeys PC-MIDI Keyboard support"
|
tristate "Prodikeys PC-MIDI Keyboard support"
|
||||||
depends on HID && SND
|
depends on USB_HID && SND
|
||||||
select SND_RAWMIDI
|
select SND_RAWMIDI
|
||||||
---help---
|
---help---
|
||||||
Support for Prodikeys PC-MIDI Keyboard device support.
|
Support for Prodikeys PC-MIDI Keyboard device support.
|
||||||
|
@ -448,7 +449,7 @@ config HID_LENOVO
|
||||||
|
|
||||||
config HID_LOGITECH
|
config HID_LOGITECH
|
||||||
tristate "Logitech devices"
|
tristate "Logitech devices"
|
||||||
depends on HID
|
depends on USB_HID
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
---help---
|
---help---
|
||||||
Support for Logitech devices that are not fully compliant with HID standard.
|
Support for Logitech devices that are not fully compliant with HID standard.
|
||||||
|
@ -780,7 +781,7 @@ config HID_SAITEK
|
||||||
|
|
||||||
config HID_SAMSUNG
|
config HID_SAMSUNG
|
||||||
tristate "Samsung InfraRed remote control or keyboards"
|
tristate "Samsung InfraRed remote control or keyboards"
|
||||||
depends on HID
|
depends on USB_HID
|
||||||
---help---
|
---help---
|
||||||
Support for Samsung InfraRed remote control or keyboards.
|
Support for Samsung InfraRed remote control or keyboards.
|
||||||
|
|
||||||
|
|
|
@ -600,7 +600,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
|
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
|
||||||
drvdata->tp = &asus_i2c_tp;
|
drvdata->tp = &asus_i2c_tp;
|
||||||
|
|
||||||
if (drvdata->quirks & QUIRK_T100_KEYBOARD) {
|
if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) {
|
||||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||||
|
|
||||||
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
|
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
|
||||||
|
|
|
@ -61,8 +61,12 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||||
static __u8 *ch_switch12_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
static __u8 *ch_switch12_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||||
unsigned int *rsize)
|
unsigned int *rsize)
|
||||||
{
|
{
|
||||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
struct usb_interface *intf;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return rdesc;
|
||||||
|
|
||||||
|
intf = to_usb_interface(hdev->dev.parent);
|
||||||
if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
|
if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
|
||||||
/* Change usage maximum and logical maximum from 0x7fff to
|
/* Change usage maximum and logical maximum from 0x7fff to
|
||||||
* 0x2fff, so they don't exceed HID_MAX_USAGES */
|
* 0x2fff, so they don't exceed HID_MAX_USAGES */
|
||||||
|
|
|
@ -553,7 +553,12 @@ static int corsair_probe(struct hid_device *dev, const struct hid_device_id *id)
|
||||||
int ret;
|
int ret;
|
||||||
unsigned long quirks = id->driver_data;
|
unsigned long quirks = id->driver_data;
|
||||||
struct corsair_drvdata *drvdata;
|
struct corsair_drvdata *drvdata;
|
||||||
struct usb_interface *usbif = to_usb_interface(dev->dev.parent);
|
struct usb_interface *usbif;
|
||||||
|
|
||||||
|
if (!hid_is_usb(dev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
usbif = to_usb_interface(dev->dev.parent);
|
||||||
|
|
||||||
drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata),
|
drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|
|
@ -230,6 +230,9 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
struct elo_priv *priv;
|
struct elo_priv *priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -143,12 +143,17 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type,
|
||||||
static int holtek_kbd_probe(struct hid_device *hdev,
|
static int holtek_kbd_probe(struct hid_device *hdev,
|
||||||
const struct hid_device_id *id)
|
const struct hid_device_id *id)
|
||||||
{
|
{
|
||||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
struct usb_interface *intf;
|
||||||
int ret = hid_parse(hdev);
|
int ret;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = hid_parse(hdev);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||||
|
|
||||||
|
intf = to_usb_interface(hdev->dev.parent);
|
||||||
if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) {
|
if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) {
|
||||||
struct hid_input *hidinput;
|
struct hid_input *hidinput;
|
||||||
list_for_each_entry(hidinput, &hdev->inputs, list) {
|
list_for_each_entry(hidinput, &hdev->inputs, list) {
|
||||||
|
|
|
@ -65,6 +65,29 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||||
return rdesc;
|
return rdesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int holtek_mouse_probe(struct hid_device *hdev,
|
||||||
|
const struct hid_device_id *id)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = hid_parse(hdev);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "hid parse failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "hw start failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct hid_device_id holtek_mouse_devices[] = {
|
static const struct hid_device_id holtek_mouse_devices[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
|
||||||
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
|
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
|
||||||
|
@ -86,6 +109,7 @@ static struct hid_driver holtek_mouse_driver = {
|
||||||
.name = "holtek_mouse",
|
.name = "holtek_mouse",
|
||||||
.id_table = holtek_mouse_devices,
|
.id_table = holtek_mouse_devices,
|
||||||
.report_fixup = holtek_mouse_report_fixup,
|
.report_fixup = holtek_mouse_report_fixup,
|
||||||
|
.probe = holtek_mouse_probe,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_hid_driver(holtek_mouse_driver);
|
module_hid_driver(holtek_mouse_driver);
|
||||||
|
|
|
@ -714,12 +714,18 @@ static int lg_raw_event(struct hid_device *hdev, struct hid_report *report,
|
||||||
|
|
||||||
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
{
|
{
|
||||||
struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
|
struct usb_interface *iface;
|
||||||
__u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
|
__u8 iface_num;
|
||||||
unsigned int connect_mask = HID_CONNECT_DEFAULT;
|
unsigned int connect_mask = HID_CONNECT_DEFAULT;
|
||||||
struct lg_drv_data *drv_data;
|
struct lg_drv_data *drv_data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
iface = to_usb_interface(hdev->dev.parent);
|
||||||
|
iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
|
||||||
|
|
||||||
/* G29 only work with the 1st interface */
|
/* G29 only work with the 1st interface */
|
||||||
if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) &&
|
if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) &&
|
||||||
(iface_num != 0)) {
|
(iface_num != 0)) {
|
||||||
|
|
|
@ -803,12 +803,18 @@ static int pk_raw_event(struct hid_device *hdev, struct hid_report *report,
|
||||||
static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
struct usb_interface *intf;
|
||||||
unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
|
unsigned short ifnum;
|
||||||
unsigned long quirks = id->driver_data;
|
unsigned long quirks = id->driver_data;
|
||||||
struct pk_device *pk;
|
struct pk_device *pk;
|
||||||
struct pcmidi_snd *pm = NULL;
|
struct pcmidi_snd *pm = NULL;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
intf = to_usb_interface(hdev->dev.parent);
|
||||||
|
ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
|
||||||
|
|
||||||
pk = kzalloc(sizeof(*pk), GFP_KERNEL);
|
pk = kzalloc(sizeof(*pk), GFP_KERNEL);
|
||||||
if (pk == NULL) {
|
if (pk == NULL) {
|
||||||
hid_err(hdev, "can't alloc descriptor\n");
|
hid_err(hdev, "can't alloc descriptor\n");
|
||||||
|
|
|
@ -347,6 +347,9 @@ static int arvo_probe(struct hid_device *hdev,
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -327,6 +327,9 @@ static int isku_probe(struct hid_device *hdev,
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -752,6 +752,9 @@ static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -434,6 +434,9 @@ static int koneplus_probe(struct hid_device *hdev,
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -136,6 +136,9 @@ static int konepure_probe(struct hid_device *hdev,
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -504,6 +504,9 @@ static int kovaplus_probe(struct hid_device *hdev,
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -163,6 +163,9 @@ static int lua_probe(struct hid_device *hdev,
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -452,6 +452,9 @@ static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -144,6 +144,9 @@ static int ryos_probe(struct hid_device *hdev,
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -116,6 +116,9 @@ static int savu_probe(struct hid_device *hdev,
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
retval = hid_parse(hdev);
|
retval = hid_parse(hdev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -157,6 +157,9 @@ static int samsung_probe(struct hid_device *hdev,
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int cmask = HID_CONNECT_DEFAULT;
|
unsigned int cmask = HID_CONNECT_DEFAULT;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
ret = hid_parse(hdev);
|
ret = hid_parse(hdev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
hid_err(hdev, "parse failed\n");
|
hid_err(hdev, "parse failed\n");
|
||||||
|
|
|
@ -791,6 +791,9 @@ static int uclogic_tablet_enable(struct hid_device *hdev)
|
||||||
__u8 *p;
|
__u8 *p;
|
||||||
s32 v;
|
s32 v;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read string descriptor containing tablet parameters. The specific
|
* Read string descriptor containing tablet parameters. The specific
|
||||||
* string descriptor and data were discovered by sniffing the Windows
|
* string descriptor and data were discovered by sniffing the Windows
|
||||||
|
|
|
@ -578,7 +578,7 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev,
|
||||||
* Skip the query for this type and modify defaults based on
|
* Skip the query for this type and modify defaults based on
|
||||||
* interface number.
|
* interface number.
|
||||||
*/
|
*/
|
||||||
if (features->type == WIRELESS) {
|
if (features->type == WIRELESS && intf) {
|
||||||
if (intf->cur_altsetting->desc.bInterfaceNumber == 0)
|
if (intf->cur_altsetting->desc.bInterfaceNumber == 0)
|
||||||
features->device_type = WACOM_DEVICETYPE_WL_MONITOR;
|
features->device_type = WACOM_DEVICETYPE_WL_MONITOR;
|
||||||
else
|
else
|
||||||
|
@ -2049,7 +2049,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix)
|
||||||
if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) {
|
if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) {
|
||||||
char *product_name = wacom->hdev->name;
|
char *product_name = wacom->hdev->name;
|
||||||
|
|
||||||
if (hid_is_using_ll_driver(wacom->hdev, &usb_hid_driver)) {
|
if (hid_is_usb(wacom->hdev)) {
|
||||||
struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent);
|
struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent);
|
||||||
struct usb_device *dev = interface_to_usbdev(intf);
|
struct usb_device *dev = interface_to_usbdev(intf);
|
||||||
product_name = dev->product;
|
product_name = dev->product;
|
||||||
|
@ -2280,6 +2280,9 @@ static void wacom_wireless_work(struct work_struct *work)
|
||||||
|
|
||||||
wacom_destroy_battery(wacom);
|
wacom_destroy_battery(wacom);
|
||||||
|
|
||||||
|
if (!usbdev)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Stylus interface */
|
/* Stylus interface */
|
||||||
hdev1 = usb_get_intfdata(usbdev->config->interface[1]);
|
hdev1 = usb_get_intfdata(usbdev->config->interface[1]);
|
||||||
wacom1 = hid_get_drvdata(hdev1);
|
wacom1 = hid_get_drvdata(hdev1);
|
||||||
|
@ -2559,8 +2562,6 @@ static void wacom_mode_change_work(struct work_struct *work)
|
||||||
static int wacom_probe(struct hid_device *hdev,
|
static int wacom_probe(struct hid_device *hdev,
|
||||||
const struct hid_device_id *id)
|
const struct hid_device_id *id)
|
||||||
{
|
{
|
||||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
|
||||||
struct usb_device *dev = interface_to_usbdev(intf);
|
|
||||||
struct wacom *wacom;
|
struct wacom *wacom;
|
||||||
struct wacom_wac *wacom_wac;
|
struct wacom_wac *wacom_wac;
|
||||||
struct wacom_features *features;
|
struct wacom_features *features;
|
||||||
|
@ -2593,8 +2594,14 @@ static int wacom_probe(struct hid_device *hdev,
|
||||||
wacom_wac->hid_data.inputmode = -1;
|
wacom_wac->hid_data.inputmode = -1;
|
||||||
wacom_wac->mode_report = -1;
|
wacom_wac->mode_report = -1;
|
||||||
|
|
||||||
wacom->usbdev = dev;
|
if (hid_is_usb(hdev)) {
|
||||||
wacom->intf = intf;
|
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||||
|
struct usb_device *dev = interface_to_usbdev(intf);
|
||||||
|
|
||||||
|
wacom->usbdev = dev;
|
||||||
|
wacom->intf = intf;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_init(&wacom->lock);
|
mutex_init(&wacom->lock);
|
||||||
INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work);
|
INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work);
|
||||||
INIT_WORK(&wacom->wireless_work, wacom_wireless_work);
|
INIT_WORK(&wacom->wireless_work, wacom_wireless_work);
|
||||||
|
|
|
@ -2433,6 +2433,9 @@ static void wacom_wac_finger_event(struct hid_device *hdev,
|
||||||
struct wacom_features *features = &wacom->wacom_wac.features;
|
struct wacom_features *features = &wacom->wacom_wac.features;
|
||||||
|
|
||||||
switch (equivalent_usage) {
|
switch (equivalent_usage) {
|
||||||
|
case HID_DG_CONFIDENCE:
|
||||||
|
wacom_wac->hid_data.confidence = value;
|
||||||
|
break;
|
||||||
case HID_GD_X:
|
case HID_GD_X:
|
||||||
wacom_wac->hid_data.x = value;
|
wacom_wac->hid_data.x = value;
|
||||||
break;
|
break;
|
||||||
|
@ -2463,7 +2466,8 @@ static void wacom_wac_finger_event(struct hid_device *hdev,
|
||||||
|
|
||||||
|
|
||||||
if (usage->usage_index + 1 == field->report_count) {
|
if (usage->usage_index + 1 == field->report_count) {
|
||||||
if (equivalent_usage == wacom_wac->hid_data.last_slot_field)
|
if (equivalent_usage == wacom_wac->hid_data.last_slot_field &&
|
||||||
|
wacom_wac->hid_data.confidence)
|
||||||
wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
|
wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2476,6 +2480,8 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
|
||||||
struct hid_data* hid_data = &wacom_wac->hid_data;
|
struct hid_data* hid_data = &wacom_wac->hid_data;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
hid_data->confidence = true;
|
||||||
|
|
||||||
for (i = 0; i < report->maxfield; i++) {
|
for (i = 0; i < report->maxfield; i++) {
|
||||||
struct hid_field *field = report->field[i];
|
struct hid_field *field = report->field[i];
|
||||||
int j;
|
int j;
|
||||||
|
|
|
@ -293,6 +293,7 @@ struct hid_data {
|
||||||
bool inrange_state;
|
bool inrange_state;
|
||||||
bool invert_state;
|
bool invert_state;
|
||||||
bool tipswitch;
|
bool tipswitch;
|
||||||
|
bool confidence;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int pressure;
|
int pressure;
|
||||||
|
|
|
@ -578,15 +578,18 @@ static const struct file_operations i8k_fops = {
|
||||||
.unlocked_ioctl = i8k_ioctl,
|
.unlocked_ioctl = i8k_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct proc_dir_entry *entry;
|
||||||
|
|
||||||
static void __init i8k_init_procfs(void)
|
static void __init i8k_init_procfs(void)
|
||||||
{
|
{
|
||||||
/* Register the proc entry */
|
/* Register the proc entry */
|
||||||
proc_create("i8k", 0, NULL, &i8k_fops);
|
entry = proc_create("i8k", 0, NULL, &i8k_fops);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit i8k_exit_procfs(void)
|
static void __exit i8k_exit_procfs(void)
|
||||||
{
|
{
|
||||||
remove_proc_entry("i8k", NULL);
|
if (entry)
|
||||||
|
remove_proc_entry("i8k", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -197,6 +197,7 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
|
||||||
#define LM90_STATUS_RHIGH (1 << 4) /* remote high temp limit tripped */
|
#define LM90_STATUS_RHIGH (1 << 4) /* remote high temp limit tripped */
|
||||||
#define LM90_STATUS_LLOW (1 << 5) /* local low temp limit tripped */
|
#define LM90_STATUS_LLOW (1 << 5) /* local low temp limit tripped */
|
||||||
#define LM90_STATUS_LHIGH (1 << 6) /* local high temp limit tripped */
|
#define LM90_STATUS_LHIGH (1 << 6) /* local high temp limit tripped */
|
||||||
|
#define LM90_STATUS_BUSY (1 << 7) /* conversion is ongoing */
|
||||||
|
|
||||||
#define MAX6696_STATUS2_R2THRM (1 << 1) /* remote2 THERM limit tripped */
|
#define MAX6696_STATUS2_R2THRM (1 << 1) /* remote2 THERM limit tripped */
|
||||||
#define MAX6696_STATUS2_R2OPEN (1 << 2) /* remote2 is an open circuit */
|
#define MAX6696_STATUS2_R2OPEN (1 << 2) /* remote2 is an open circuit */
|
||||||
|
@ -786,7 +787,7 @@ static int lm90_update_device(struct device *dev)
|
||||||
val = lm90_read_reg(client, LM90_REG_R_STATUS);
|
val = lm90_read_reg(client, LM90_REG_R_STATUS);
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
return val;
|
return val;
|
||||||
data->alarms = val; /* lower 8 bit of alarms */
|
data->alarms = val & ~LM90_STATUS_BUSY;
|
||||||
|
|
||||||
if (data->kind == max6696) {
|
if (data->kind == max6696) {
|
||||||
val = lm90_select_remote_channel(client, data, 1);
|
val = lm90_select_remote_channel(client, data, 1);
|
||||||
|
@ -1439,12 +1440,11 @@ static int lm90_detect(struct i2c_client *client,
|
||||||
if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0)
|
if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) {
|
if (man_id == 0x01 || man_id == 0x5C || man_id == 0xA1) {
|
||||||
config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2);
|
config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2);
|
||||||
if (config2 < 0)
|
if (config2 < 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else
|
}
|
||||||
config2 = 0; /* Make compiler happy */
|
|
||||||
|
|
||||||
if ((address == 0x4C || address == 0x4D)
|
if ((address == 0x4C || address == 0x4D)
|
||||||
&& man_id == 0x01) { /* National Semiconductor */
|
&& man_id == 0x01) { /* National Semiconductor */
|
||||||
|
|
|
@ -424,8 +424,8 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
|
||||||
if (!(ipd & REG_INT_MBRF))
|
if (!(ipd & REG_INT_MBRF))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* ack interrupt */
|
/* ack interrupt (read also produces a spurious START flag, clear it too) */
|
||||||
i2c_writel(i2c, REG_INT_MBRF, REG_IPD);
|
i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD);
|
||||||
|
|
||||||
/* Can only handle a maximum of 32 bytes at a time */
|
/* Can only handle a maximum of 32 bytes at a time */
|
||||||
if (len > 32)
|
if (len > 32)
|
||||||
|
|
|
@ -1326,8 +1326,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_buffer_cleanup:
|
err_buffer_cleanup:
|
||||||
if (data->dready_trig)
|
iio_triggered_buffer_cleanup(indio_dev);
|
||||||
iio_triggered_buffer_cleanup(indio_dev);
|
|
||||||
err_trigger_unregister:
|
err_trigger_unregister:
|
||||||
if (data->dready_trig)
|
if (data->dready_trig)
|
||||||
iio_trigger_unregister(data->dready_trig);
|
iio_trigger_unregister(data->dready_trig);
|
||||||
|
@ -1350,8 +1349,8 @@ static int kxcjk1013_remove(struct i2c_client *client)
|
||||||
pm_runtime_set_suspended(&client->dev);
|
pm_runtime_set_suspended(&client->dev);
|
||||||
pm_runtime_put_noidle(&client->dev);
|
pm_runtime_put_noidle(&client->dev);
|
||||||
|
|
||||||
|
iio_triggered_buffer_cleanup(indio_dev);
|
||||||
if (data->dready_trig) {
|
if (data->dready_trig) {
|
||||||
iio_triggered_buffer_cleanup(indio_dev);
|
|
||||||
iio_trigger_unregister(data->dready_trig);
|
iio_trigger_unregister(data->dready_trig);
|
||||||
iio_trigger_unregister(data->motion_trig);
|
iio_trigger_unregister(data->motion_trig);
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,14 +227,14 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
|
||||||
hw_values.chan,
|
hw_values.chan,
|
||||||
sizeof(hw_values.chan));
|
sizeof(hw_values.chan));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(st->dev,
|
dev_err(st->dev, "error reading data: %d\n", ret);
|
||||||
"error reading data\n");
|
goto out;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iio_push_to_buffers_with_timestamp(indio_dev,
|
iio_push_to_buffers_with_timestamp(indio_dev,
|
||||||
&hw_values,
|
&hw_values,
|
||||||
iio_get_time_ns(indio_dev));
|
iio_get_time_ns(indio_dev));
|
||||||
|
out:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
|
|
@ -1396,7 +1396,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
indio_dev->trig = trig;
|
indio_dev->trig = iio_trigger_get(trig);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,19 +224,8 @@ static int axp22x_adc_raw(struct iio_dev *indio_dev,
|
||||||
struct iio_chan_spec const *chan, int *val)
|
struct iio_chan_spec const *chan, int *val)
|
||||||
{
|
{
|
||||||
struct axp20x_adc_iio *info = iio_priv(indio_dev);
|
struct axp20x_adc_iio *info = iio_priv(indio_dev);
|
||||||
int size;
|
|
||||||
|
|
||||||
/*
|
*val = axp20x_read_variable_width(info->regmap, chan->address, 12);
|
||||||
* N.B.: Unlike the Chinese datasheets tell, the charging current is
|
|
||||||
* stored on 12 bits, not 13 bits. Only discharging current is on 13
|
|
||||||
* bits.
|
|
||||||
*/
|
|
||||||
if (chan->type == IIO_CURRENT && chan->channel == AXP22X_BATT_DISCHRG_I)
|
|
||||||
size = 13;
|
|
||||||
else
|
|
||||||
size = 12;
|
|
||||||
|
|
||||||
*val = axp20x_read_variable_width(info->regmap, chan->address, size);
|
|
||||||
if (*val < 0)
|
if (*val < 0)
|
||||||
return *val;
|
return *val;
|
||||||
|
|
||||||
|
@ -329,9 +318,8 @@ static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,
|
||||||
return IIO_VAL_INT_PLUS_MICRO;
|
return IIO_VAL_INT_PLUS_MICRO;
|
||||||
|
|
||||||
case IIO_CURRENT:
|
case IIO_CURRENT:
|
||||||
*val = 0;
|
*val = 1;
|
||||||
*val2 = 500000;
|
return IIO_VAL_INT;
|
||||||
return IIO_VAL_INT_PLUS_MICRO;
|
|
||||||
|
|
||||||
case IIO_TEMP:
|
case IIO_TEMP:
|
||||||
*val = 100;
|
*val = 100;
|
||||||
|
|
|
@ -251,7 +251,6 @@ static int dln2_adc_set_chan_period(struct dln2_adc *dln2,
|
||||||
static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
|
static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
|
||||||
{
|
{
|
||||||
int ret, i;
|
int ret, i;
|
||||||
struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev);
|
|
||||||
u16 conflict;
|
u16 conflict;
|
||||||
__le16 value;
|
__le16 value;
|
||||||
int olen = sizeof(value);
|
int olen = sizeof(value);
|
||||||
|
@ -260,13 +259,9 @@ static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel)
|
||||||
.chan = channel,
|
.chan = channel,
|
||||||
};
|
};
|
||||||
|
|
||||||
ret = iio_device_claim_direct_mode(indio_dev);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = dln2_adc_set_chan_enabled(dln2, channel, true);
|
ret = dln2_adc_set_chan_enabled(dln2, channel, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto release_direct;
|
return ret;
|
||||||
|
|
||||||
ret = dln2_adc_set_port_enabled(dln2, true, &conflict);
|
ret = dln2_adc_set_port_enabled(dln2, true, &conflict);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -303,8 +298,6 @@ disable_port:
|
||||||
dln2_adc_set_port_enabled(dln2, false, NULL);
|
dln2_adc_set_port_enabled(dln2, false, NULL);
|
||||||
disable_chan:
|
disable_chan:
|
||||||
dln2_adc_set_chan_enabled(dln2, channel, false);
|
dln2_adc_set_chan_enabled(dln2, channel, false);
|
||||||
release_direct:
|
|
||||||
iio_device_release_direct_mode(indio_dev);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -340,10 +333,16 @@ static int dln2_adc_read_raw(struct iio_dev *indio_dev,
|
||||||
|
|
||||||
switch (mask) {
|
switch (mask) {
|
||||||
case IIO_CHAN_INFO_RAW:
|
case IIO_CHAN_INFO_RAW:
|
||||||
|
ret = iio_device_claim_direct_mode(indio_dev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
mutex_lock(&dln2->mutex);
|
mutex_lock(&dln2->mutex);
|
||||||
ret = dln2_adc_read(dln2, chan->channel);
|
ret = dln2_adc_read(dln2, chan->channel);
|
||||||
mutex_unlock(&dln2->mutex);
|
mutex_unlock(&dln2->mutex);
|
||||||
|
|
||||||
|
iio_device_release_direct_mode(indio_dev);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -675,7 +674,11 @@ static int dln2_adc_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
dln2->trig->ops = &dln2_adc_trigger_ops;
|
dln2->trig->ops = &dln2_adc_trigger_ops;
|
||||||
iio_trigger_set_drvdata(dln2->trig, dln2);
|
iio_trigger_set_drvdata(dln2->trig, dln2);
|
||||||
devm_iio_trigger_register(dev, dln2->trig);
|
ret = devm_iio_trigger_register(dev, dln2->trig);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "failed to register trigger: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
iio_trigger_set_immutable(indio_dev, dln2->trig);
|
iio_trigger_set_immutable(indio_dev, dln2->trig);
|
||||||
|
|
||||||
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
|
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
|
||||||
|
|
|
@ -64,9 +64,9 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
|
||||||
|
|
||||||
iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
|
iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
|
||||||
|
|
||||||
|
error_ret:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
error_ret:
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -549,7 +549,6 @@ static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs)
|
||||||
irq_modify_status(trig->subirq_base + i,
|
irq_modify_status(trig->subirq_base + i,
|
||||||
IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
|
IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
|
||||||
}
|
}
|
||||||
get_device(&trig->dev);
|
|
||||||
|
|
||||||
return trig;
|
return trig;
|
||||||
|
|
||||||
|
|
|
@ -1279,7 +1279,7 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p)
|
||||||
ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1,
|
ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1,
|
||||||
(u8 *)als_buf, sizeof(als_buf));
|
(u8 *)als_buf, sizeof(als_buf));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto done;
|
||||||
if (test_bit(0, indio_dev->active_scan_mask))
|
if (test_bit(0, indio_dev->active_scan_mask))
|
||||||
scan.channels[j++] = le16_to_cpu(als_buf[1]);
|
scan.channels[j++] = le16_to_cpu(als_buf[1]);
|
||||||
if (test_bit(1, indio_dev->active_scan_mask))
|
if (test_bit(1, indio_dev->active_scan_mask))
|
||||||
|
|
|
@ -546,9 +546,8 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private)
|
||||||
mutex_lock(&data->lock);
|
mutex_lock(&data->lock);
|
||||||
ret = regmap_field_read(data->reg_flag_nf, &dir);
|
ret = regmap_field_read(data->reg_flag_nf, &dir);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&data->client->dev, "register read failed\n");
|
dev_err(&data->client->dev, "register read failed: %d\n", ret);
|
||||||
mutex_unlock(&data->lock);
|
goto out;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1,
|
event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1,
|
||||||
IIO_EV_TYPE_THRESH,
|
IIO_EV_TYPE_THRESH,
|
||||||
|
@ -560,6 +559,7 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private)
|
||||||
ret = regmap_field_write(data->reg_flag_psint, 0);
|
ret = regmap_field_write(data->reg_flag_psint, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
dev_err(&data->client->dev, "failed to reset interrupts\n");
|
dev_err(&data->client->dev, "failed to reset interrupts\n");
|
||||||
|
out:
|
||||||
mutex_unlock(&data->lock);
|
mutex_unlock(&data->lock);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
|
|
@ -886,6 +886,6 @@ static struct platform_driver stm32_timer_trigger_driver = {
|
||||||
};
|
};
|
||||||
module_platform_driver(stm32_timer_trigger_driver);
|
module_platform_driver(stm32_timer_trigger_driver);
|
||||||
|
|
||||||
MODULE_ALIAS("platform: stm32-timer-trigger");
|
MODULE_ALIAS("platform:stm32-timer-trigger");
|
||||||
MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver");
|
MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
|
@ -66,7 +66,7 @@ void ib_copy_ah_attr_to_user(struct ib_device *device,
|
||||||
struct rdma_ah_attr *src = ah_attr;
|
struct rdma_ah_attr *src = ah_attr;
|
||||||
struct rdma_ah_attr conv_ah;
|
struct rdma_ah_attr conv_ah;
|
||||||
|
|
||||||
memset(&dst->grh.reserved, 0, sizeof(dst->grh.reserved));
|
memset(&dst->grh, 0, sizeof(dst->grh));
|
||||||
|
|
||||||
if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) &&
|
if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) &&
|
||||||
(rdma_ah_get_dlid(ah_attr) >=
|
(rdma_ah_get_dlid(ah_attr) >=
|
||||||
|
|
|
@ -1138,7 +1138,7 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
|
||||||
rcd->egrbufs.rcvtids = NULL;
|
rcd->egrbufs.rcvtids = NULL;
|
||||||
|
|
||||||
for (e = 0; e < rcd->egrbufs.alloced; e++) {
|
for (e = 0; e < rcd->egrbufs.alloced; e++) {
|
||||||
if (rcd->egrbufs.buffers[e].dma)
|
if (rcd->egrbufs.buffers[e].addr)
|
||||||
dma_free_coherent(&dd->pcidev->dev,
|
dma_free_coherent(&dd->pcidev->dev,
|
||||||
rcd->egrbufs.buffers[e].len,
|
rcd->egrbufs.buffers[e].len,
|
||||||
rcd->egrbufs.buffers[e].addr,
|
rcd->egrbufs.buffers[e].addr,
|
||||||
|
|
|
@ -946,7 +946,7 @@ static int qib_user_sdma_queue_pkts(const struct qib_devdata *dd,
|
||||||
&addrlimit) ||
|
&addrlimit) ||
|
||||||
addrlimit > type_max(typeof(pkt->addrlimit))) {
|
addrlimit > type_max(typeof(pkt->addrlimit))) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto free_pbc;
|
goto free_pkt;
|
||||||
}
|
}
|
||||||
pkt->addrlimit = addrlimit;
|
pkt->addrlimit = addrlimit;
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/serio.h>
|
#include <linux/serio.h>
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
#define DRIVER_DESC "SpaceTec SpaceBall 2003/3003/4000 FLX driver"
|
#define DRIVER_DESC "SpaceTec SpaceBall 2003/3003/4000 FLX driver"
|
||||||
|
|
||||||
|
@ -91,9 +92,15 @@ static void spaceball_process_packet(struct spaceball* spaceball)
|
||||||
|
|
||||||
case 'D': /* Ball data */
|
case 'D': /* Ball data */
|
||||||
if (spaceball->idx != 15) return;
|
if (spaceball->idx != 15) return;
|
||||||
for (i = 0; i < 6; i++)
|
/*
|
||||||
|
* Skip first three bytes; read six axes worth of data.
|
||||||
|
* Axis values are signed 16-bit big-endian.
|
||||||
|
*/
|
||||||
|
data += 3;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(spaceball_axes); i++) {
|
||||||
input_report_abs(dev, spaceball_axes[i],
|
input_report_abs(dev, spaceball_axes[i],
|
||||||
(__s16)((data[2 * i + 3] << 8) | data[2 * i + 2]));
|
(__s16)get_unaligned_be16(&data[i * 2]));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'K': /* Button data */
|
case 'K': /* Button data */
|
||||||
|
|
|
@ -929,6 +929,8 @@ static int atp_probe(struct usb_interface *iface,
|
||||||
set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
|
set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
|
||||||
set_bit(BTN_LEFT, input_dev->keybit);
|
set_bit(BTN_LEFT, input_dev->keybit);
|
||||||
|
|
||||||
|
INIT_WORK(&dev->work, atp_reinit);
|
||||||
|
|
||||||
error = input_register_device(dev->input);
|
error = input_register_device(dev->input);
|
||||||
if (error)
|
if (error)
|
||||||
goto err_free_buffer;
|
goto err_free_buffer;
|
||||||
|
@ -936,8 +938,6 @@ static int atp_probe(struct usb_interface *iface,
|
||||||
/* save our data pointer in this interface device */
|
/* save our data pointer in this interface device */
|
||||||
usb_set_intfdata(iface, dev);
|
usb_set_intfdata(iface, dev);
|
||||||
|
|
||||||
INIT_WORK(&dev->work, atp_reinit);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free_buffer:
|
err_free_buffer:
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user