Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pulling to get some TIPC fixes that a net-next series depends upon. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
f9474ddfaa
|
@ -315,7 +315,7 @@ char *date;</synopsis>
|
|||
<function>drm_dev_unregister()</function> followed by a call to
|
||||
<function>drm_dev_unref()</function>.
|
||||
</para>
|
||||
!Edrivers/gpu/drm/drm_stub.c
|
||||
!Edrivers/gpu/drm/drm_drv.c
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Driver Load</title>
|
||||
|
|
|
@ -4,11 +4,13 @@ Specifying interrupt information for devices
|
|||
1) Interrupt client nodes
|
||||
-------------------------
|
||||
|
||||
Nodes that describe devices which generate interrupts must contain an either an
|
||||
"interrupts" property or an "interrupts-extended" property. These properties
|
||||
contain a list of interrupt specifiers, one per output interrupt. The format of
|
||||
the interrupt specifier is determined by the interrupt controller to which the
|
||||
interrupts are routed; see section 2 below for details.
|
||||
Nodes that describe devices which generate interrupts must contain an
|
||||
"interrupts" property, an "interrupts-extended" property, or both. If both are
|
||||
present, the latter should take precedence; the former may be provided simply
|
||||
for compatibility with software that does not recognize the latter. These
|
||||
properties contain a list of interrupt specifiers, one per output interrupt. The
|
||||
format of the interrupt specifier is determined by the interrupt controller to
|
||||
which the interrupts are routed; see section 2 below for details.
|
||||
|
||||
Example:
|
||||
interrupt-parent = <&intc1>;
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
Required properties:
|
||||
- compatible: should contain "snps,dw-pcie" to identify the core.
|
||||
- reg: Should contain the configuration address space.
|
||||
- reg-names: Must be "config" for the PCIe configuration space.
|
||||
(The old way of getting the configuration address space from "ranges"
|
||||
is deprecated and should be avoided.)
|
||||
- #address-cells: set to <3>
|
||||
- #size-cells: set to <2>
|
||||
- device_type: set to "pci"
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
TI PCI Controllers
|
||||
|
||||
PCIe Designware Controller
|
||||
- compatible: Should be "ti,dra7-pcie""
|
||||
- reg : Two register ranges as listed in the reg-names property
|
||||
- reg-names : The first entry must be "ti-conf" for the TI specific registers
|
||||
The second entry must be "rc-dbics" for the designware pcie
|
||||
registers
|
||||
The third entry must be "config" for the PCIe configuration space
|
||||
- phys : list of PHY specifiers (used by generic PHY framework)
|
||||
- phy-names : must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the
|
||||
number of PHYs as specified in *phys* property.
|
||||
- ti,hwmods : Name of the hwmod associated to the pcie, "pcie<X>",
|
||||
where <X> is the instance number of the pcie from the HW spec.
|
||||
- interrupts : Two interrupt entries must be specified. The first one is for
|
||||
main interrupt line and the second for MSI interrupt line.
|
||||
- #address-cells,
|
||||
#size-cells,
|
||||
#interrupt-cells,
|
||||
device_type,
|
||||
ranges,
|
||||
num-lanes,
|
||||
interrupt-map-mask,
|
||||
interrupt-map : as specified in ../designware-pcie.txt
|
||||
|
||||
Example:
|
||||
axi {
|
||||
compatible = "simple-bus";
|
||||
#size-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
ranges = <0x51000000 0x51000000 0x3000
|
||||
0x0 0x20000000 0x10000000>;
|
||||
pcie@51000000 {
|
||||
compatible = "ti,dra7-pcie";
|
||||
reg = <0x51000000 0x2000>, <0x51002000 0x14c>, <0x1000 0x2000>;
|
||||
reg-names = "rc_dbics", "ti_conf", "config";
|
||||
interrupts = <0 232 0x4>, <0 233 0x4>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
ranges = <0x81000000 0 0 0x03000 0 0x00010000
|
||||
0x82000000 0 0x20013000 0x13000 0 0xffed000>;
|
||||
#interrupt-cells = <1>;
|
||||
num-lanes = <1>;
|
||||
ti,hwmods = "pcie1";
|
||||
phys = <&pcie1_phy>;
|
||||
phy-names = "pcie-phy0";
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc 1>,
|
||||
<0 0 0 2 &pcie_intc 2>,
|
||||
<0 0 0 3 &pcie_intc 3>,
|
||||
<0 0 0 4 &pcie_intc 4>;
|
||||
pcie_intc: interrupt-controller {
|
||||
interrupt-controller;
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -349,7 +349,11 @@ prototypes:
|
|||
locking rules:
|
||||
inode->i_lock may block
|
||||
fl_copy_lock: yes no
|
||||
fl_release_private: maybe no
|
||||
fl_release_private: maybe maybe[1]
|
||||
|
||||
[1]: ->fl_release_private for flock or POSIX locks is currently allowed
|
||||
to block. Leases however can still be freed while the i_lock is held and
|
||||
so fl_release_private called on a lease should not block.
|
||||
|
||||
----------------------- lock_manager_operations ---------------------------
|
||||
prototypes:
|
||||
|
|
|
@ -18,3 +18,5 @@ sonypi.txt
|
|||
- info on Linux Sony Programmable I/O Device support.
|
||||
thinkpad-acpi.txt
|
||||
- information on the (IBM and Lenovo) ThinkPad ACPI Extras driver.
|
||||
toshiba_haps.txt
|
||||
- information on the Toshiba HDD Active Protection Sensor driver.
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
Kernel driver toshiba_haps
|
||||
Toshiba HDD Active Protection Sensor
|
||||
====================================
|
||||
|
||||
Author: Azael Avalos <coproscefalo@gmail.com>
|
||||
|
||||
|
||||
0. Contents
|
||||
-----------
|
||||
|
||||
1. Description
|
||||
2. Interface
|
||||
3. Accelerometer axes
|
||||
4. Supported devices
|
||||
5. Usage
|
||||
|
||||
|
||||
1. Description
|
||||
--------------
|
||||
|
||||
This driver provides support for the accelerometer found in various Toshiba
|
||||
laptops, being called "Toshiba HDD Protection - Shock Sensor" officialy,
|
||||
and detects laptops automatically with this device.
|
||||
On Windows, Toshiba provided software monitors this device and provides
|
||||
automatic HDD protection (head unload) on sudden moves or harsh vibrations,
|
||||
however, this driver only provides a notification via a sysfs file to let
|
||||
userspace tools or daemons act accordingly, as well as providing a sysfs
|
||||
file to set the desired protection level or sensor sensibility.
|
||||
|
||||
|
||||
2. Interface
|
||||
------------
|
||||
|
||||
This device comes with 3 methods:
|
||||
_STA - Checks existence of the device, returning Zero if the device does not
|
||||
exists or is not supported.
|
||||
PTLV - Sets the desired protection level.
|
||||
RSSS - Shuts down the HDD protection interface for a few seconds,
|
||||
then restores normal operation.
|
||||
|
||||
Note:
|
||||
The presence of Solid State Drives (SSD) can make this driver to fail loading,
|
||||
given the fact that such drives have no movable parts, and thus, not requiring
|
||||
any "protection" as well as failing during the evaluation of the _STA method
|
||||
found under this device.
|
||||
|
||||
|
||||
3. Accelerometer axes
|
||||
---------------------
|
||||
|
||||
This device does not report any axes, however, to query the sensor position
|
||||
a couple HCI (Hardware Configuration Interface) calls (0x6D and 0xA6) are
|
||||
provided to query such information, handled by the kernel module toshiba_acpi
|
||||
since kernel version 3.15.
|
||||
|
||||
|
||||
4. Supported devices
|
||||
--------------------
|
||||
|
||||
This driver binds itself to the ACPI device TOS620A, and any Toshiba laptop
|
||||
with this device is supported, given the fact that they have the presence of
|
||||
conventional HDD and not only SSD, or a combination of both HDD and SSD.
|
||||
|
||||
|
||||
5. Usage
|
||||
--------
|
||||
|
||||
The sysfs files under /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS620A:00/ are:
|
||||
protection_level - The protection_level is readable and writeable, and
|
||||
provides a way to let userspace query the current protection
|
||||
level, as well as set the desired protection level, the
|
||||
available protection levels are:
|
||||
0 - Disabled | 1 - Low | 2 - Medium | 3 - High
|
||||
reset_protection - The reset_protection entry is writeable only, being "1"
|
||||
the only parameter it accepts, it is used to trigger
|
||||
a reset of the protection interface.
|
33
MAINTAINERS
33
MAINTAINERS
|
@ -1843,6 +1843,12 @@ S: Orphan
|
|||
F: Documentation/filesystems/befs.txt
|
||||
F: fs/befs/
|
||||
|
||||
BECKHOFF CX5020 ETHERCAT MASTER DRIVER
|
||||
M: Dariusz Marcinkiewicz <reksio@newterm.pl>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/ec_bhf.c
|
||||
|
||||
BFS FILE SYSTEM
|
||||
M: "Tigran A. Aivazian" <tigran@aivazian.fsnet.co.uk>
|
||||
S: Maintained
|
||||
|
@ -3843,10 +3849,13 @@ F: drivers/tty/serial/ucc_uart.c
|
|||
|
||||
FREESCALE SOC SOUND DRIVERS
|
||||
M: Timur Tabi <timur@tabi.org>
|
||||
M: Nicolin Chen <nicoleotsuka@gmail.com>
|
||||
M: Xiubo Li <Li.Xiubo@freescale.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Maintained
|
||||
F: sound/soc/fsl/fsl*
|
||||
F: sound/soc/fsl/imx*
|
||||
F: sound/soc/fsl/mpc8610_hpcd.c
|
||||
|
||||
FREEVXFS FILESYSTEM
|
||||
|
@ -4446,6 +4455,13 @@ F: include/linux/i2c-*.h
|
|||
F: include/uapi/linux/i2c.h
|
||||
F: include/uapi/linux/i2c-*.h
|
||||
|
||||
I2C ACPI SUPPORT
|
||||
M: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
L: linux-acpi@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/i2c/i2c-acpi.c
|
||||
|
||||
I2C-TAOS-EVM DRIVER
|
||||
M: Jean Delvare <jdelvare@suse.de>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
|
@ -5972,6 +5988,12 @@ T: git git://linuxtv.org/media_tree.git
|
|||
S: Maintained
|
||||
F: drivers/media/radio/radio-mr800.c
|
||||
|
||||
MRF24J40 IEEE 802.15.4 RADIO DRIVER
|
||||
M: Alan Ott <alan@signal11.us>
|
||||
L: linux-wpan@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ieee802154/mrf24j40.c
|
||||
|
||||
MSI LAPTOP SUPPORT
|
||||
M: "Lee, Chun-Yi" <jlee@suse.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
|
@ -6858,6 +6880,14 @@ S: Supported
|
|||
F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
|
||||
F: drivers/pci/host/pci-tegra.c
|
||||
|
||||
PCI DRIVER FOR TI DRA7XX
|
||||
M: Kishon Vijay Abraham I <kishon@ti.com>
|
||||
L: linux-omap@vger.kernel.org
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/pci/ti-pci.txt
|
||||
F: drivers/pci/host/pci-dra7xx.c
|
||||
|
||||
PCI DRIVER FOR RENESAS R-CAR
|
||||
M: Simon Horman <horms@verge.net.au>
|
||||
L: linux-pci@vger.kernel.org
|
||||
|
@ -7059,6 +7089,7 @@ F: drivers/scsi/pmcraid.*
|
|||
PMC SIERRA PM8001 DRIVER
|
||||
M: xjtuwjp@gmail.com
|
||||
M: lindar_liu@usish.com
|
||||
L: pmchba@pmcs.com
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/scsi/pm8001/
|
||||
|
@ -10016,7 +10047,7 @@ F: arch/x86/
|
|||
X86 PLATFORM DRIVERS
|
||||
M: Matthew Garrett <matthew.garrett@nebula.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
|
||||
T: git git://cavan.codon.org.uk/platform-drivers-x86.git
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/
|
||||
|
||||
|
|
4
Makefile
4
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 16
|
||||
PATCHLEVEL = 17
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION =
|
||||
EXTRAVERSION = -rc1
|
||||
NAME = Shuffling Zombie Juror
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -39,7 +39,7 @@ head-y := arch/arm64/kernel/head.o
|
|||
|
||||
# The byte offset of the kernel image in RAM from the start of RAM.
|
||||
ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y)
|
||||
TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%04x0\n", int(65535 * rand())}')
|
||||
TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}')
|
||||
else
|
||||
TEXT_OFFSET := 0x00080000
|
||||
endif
|
||||
|
|
|
@ -64,6 +64,8 @@ CONFIG_VIRTIO_BLK=y
|
|||
CONFIG_BLK_DEV_SD=y
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
CONFIG_ATA=y
|
||||
CONFIG_AHCI_XGENE=y
|
||||
CONFIG_PHY_XGENE=y
|
||||
CONFIG_PATA_PLATFORM=y
|
||||
CONFIG_PATA_OF_PLATFORM=y
|
||||
CONFIG_NETDEVICES=y
|
||||
|
@ -71,6 +73,7 @@ CONFIG_TUN=y
|
|||
CONFIG_VIRTIO_NET=y
|
||||
CONFIG_SMC91X=y
|
||||
CONFIG_SMSC911X=y
|
||||
CONFIG_NET_XGENE=y
|
||||
# CONFIG_WLAN is not set
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#define __ASM_SPARSEMEM_H
|
||||
|
||||
#ifdef CONFIG_SPARSEMEM
|
||||
#define MAX_PHYSMEM_BITS 40
|
||||
#define MAX_PHYSMEM_BITS 48
|
||||
#define SECTION_SIZE_BITS 30
|
||||
#endif
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2)
|
||||
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5)
|
||||
|
||||
#define __NR_compat_syscalls 383
|
||||
#define __NR_compat_syscalls 386
|
||||
#endif
|
||||
|
||||
#define __ARCH_WANT_SYS_CLONE
|
||||
|
|
|
@ -787,3 +787,8 @@ __SYSCALL(__NR_sched_setattr, sys_sched_setattr)
|
|||
__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
|
||||
#define __NR_renameat2 382
|
||||
__SYSCALL(__NR_renameat2, sys_renameat2)
|
||||
/* 383 for seccomp */
|
||||
#define __NR_getrandom 384
|
||||
__SYSCALL(__NR_getrandom, sys_getrandom)
|
||||
#define __NR_memfd_create 385
|
||||
__SYSCALL(__NR_memfd_create, sys_memfd_create)
|
||||
|
|
|
@ -49,7 +49,7 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
|
|||
|
||||
if (l1ip != ICACHE_POLICY_PIPT)
|
||||
set_bit(ICACHEF_ALIASING, &__icache_flags);
|
||||
if (l1ip == ICACHE_POLICY_AIVIVT);
|
||||
if (l1ip == ICACHE_POLICY_AIVIVT)
|
||||
set_bit(ICACHEF_AIVIVT, &__icache_flags);
|
||||
|
||||
pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
|
||||
|
|
|
@ -188,6 +188,8 @@ static __init void reserve_regions(void)
|
|||
if (uefi_debug)
|
||||
pr_cont("\n");
|
||||
}
|
||||
|
||||
set_bit(EFI_MEMMAP, &efi.flags);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,11 +38,11 @@
|
|||
|
||||
#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
|
||||
|
||||
#if (TEXT_OFFSET & 0xf) != 0
|
||||
#error TEXT_OFFSET must be at least 16B aligned
|
||||
#elif (PAGE_OFFSET & 0xfffff) != 0
|
||||
#if (TEXT_OFFSET & 0xfff) != 0
|
||||
#error TEXT_OFFSET must be at least 4KB aligned
|
||||
#elif (PAGE_OFFSET & 0x1fffff) != 0
|
||||
#error PAGE_OFFSET must be at least 2MB aligned
|
||||
#elif TEXT_OFFSET > 0xfffff
|
||||
#elif TEXT_OFFSET > 0x1fffff
|
||||
#error TEXT_OFFSET must be less than 2MB
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1115,19 +1115,15 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
|
|||
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
|
||||
trace_sys_enter(regs, regs->syscallno);
|
||||
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
audit_syscall_entry(syscall_get_arch(), regs->syscallno,
|
||||
regs->orig_x0, regs->regs[1], regs->regs[2], regs->regs[3]);
|
||||
#endif
|
||||
|
||||
return regs->syscallno;
|
||||
}
|
||||
|
||||
asmlinkage void syscall_trace_exit(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
audit_syscall_exit(regs);
|
||||
#endif
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
|
||||
trace_sys_exit(regs, regs_return_value(regs));
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/of_fdt.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dma-contiguous.h>
|
||||
#include <linux/efi.h>
|
||||
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/sections.h>
|
||||
|
@ -148,7 +149,8 @@ void __init arm64_memblock_init(void)
|
|||
memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
|
||||
#endif
|
||||
|
||||
early_init_fdt_scan_reserved_mem();
|
||||
if (!efi_enabled(EFI_MEMMAP))
|
||||
early_init_fdt_scan_reserved_mem();
|
||||
|
||||
/* 4GB maximum for 32-bit only capable devices */
|
||||
if (IS_ENABLED(CONFIG_ZONE_DMA))
|
||||
|
|
|
@ -129,7 +129,8 @@ unsigned long get_wchan(struct task_struct *p);
|
|||
#define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc)
|
||||
#define KSTK_ESP(tsk) ((tsk)->thread.frame0->sp)
|
||||
|
||||
#define cpu_relax() barrier()
|
||||
#define cpu_relax() barrier()
|
||||
#define cpu_relax_lowlatency() cpu_relax()
|
||||
|
||||
/* data cache prefetch */
|
||||
#define ARCH_HAS_PREFETCH
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
|
||||
|
||||
#define NR_syscalls 316 /* length of syscall table */
|
||||
#define NR_syscalls 317 /* length of syscall table */
|
||||
|
||||
/*
|
||||
* The following defines stop scripts/checksyscalls.sh from complaining about
|
||||
|
|
|
@ -329,5 +329,6 @@
|
|||
#define __NR_sched_getattr 1337
|
||||
#define __NR_renameat2 1338
|
||||
#define __NR_getrandom 1339
|
||||
#define __NR_memfd_create 1339
|
||||
|
||||
#endif /* _UAPI_ASM_IA64_UNISTD_H */
|
||||
|
|
|
@ -1777,6 +1777,7 @@ sys_call_table:
|
|||
data8 sys_sched_getattr
|
||||
data8 sys_renameat2
|
||||
data8 sys_getrandom
|
||||
data8 sys_memfd_create // 1340
|
||||
|
||||
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
|
||||
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
|
||||
|
|
|
@ -399,5 +399,8 @@
|
|||
#define __NR_sched_setattr 381
|
||||
#define __NR_sched_getattr 382
|
||||
#define __NR_renameat2 383
|
||||
#define __NR_seccomp 384
|
||||
#define __NR_getrandom 385
|
||||
#define __NR_memfd_create 386
|
||||
|
||||
#endif /* _UAPI_ASM_MICROBLAZE_UNISTD_H */
|
||||
|
|
|
@ -384,3 +384,6 @@ ENTRY(sys_call_table)
|
|||
.long sys_sched_setattr
|
||||
.long sys_sched_getattr
|
||||
.long sys_renameat2
|
||||
.long sys_seccomp
|
||||
.long sys_getrandom /* 385 */
|
||||
.long sys_memfd_create
|
||||
|
|
|
@ -101,7 +101,7 @@ struct kvm_rma_info *kvm_alloc_rma()
|
|||
ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL);
|
||||
if (!ri)
|
||||
return NULL;
|
||||
page = cma_alloc(kvm_cma, kvm_rma_pages, get_order(kvm_rma_pages));
|
||||
page = cma_alloc(kvm_cma, kvm_rma_pages, order_base_2(kvm_rma_pages));
|
||||
if (!page)
|
||||
goto err_out;
|
||||
atomic_set(&ri->use_count, 1);
|
||||
|
@ -135,12 +135,12 @@ struct page *kvm_alloc_hpt(unsigned long nr_pages)
|
|||
{
|
||||
unsigned long align_pages = HPT_ALIGN_PAGES;
|
||||
|
||||
VM_BUG_ON(get_order(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT);
|
||||
VM_BUG_ON(order_base_2(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT);
|
||||
|
||||
/* Old CPUs require HPT aligned on a multiple of its size */
|
||||
if (!cpu_has_feature(CPU_FTR_ARCH_206))
|
||||
align_pages = nr_pages;
|
||||
return cma_alloc(kvm_cma, nr_pages, get_order(align_pages));
|
||||
return cma_alloc(kvm_cma, nr_pages, order_base_2(align_pages));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_alloc_hpt);
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level)
|
|||
#define KVM_REFILL_PAGES 25
|
||||
#define KVM_MAX_CPUID_ENTRIES 80
|
||||
#define KVM_NR_FIXED_MTRR_REGION 88
|
||||
#define KVM_NR_VAR_MTRR 10
|
||||
#define KVM_NR_VAR_MTRR 8
|
||||
|
||||
#define ASYNC_PF_PER_VCPU 64
|
||||
|
||||
|
|
|
@ -149,6 +149,9 @@
|
|||
|
||||
#define MSR_CORE_C1_RES 0x00000660
|
||||
|
||||
#define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668
|
||||
#define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669
|
||||
|
||||
#define MSR_AMD64_MC0_MASK 0xc0010044
|
||||
|
||||
#define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x))
|
||||
|
|
|
@ -1491,9 +1491,6 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
|||
goto exception;
|
||||
break;
|
||||
case VCPU_SREG_CS:
|
||||
if (in_task_switch && rpl != dpl)
|
||||
goto exception;
|
||||
|
||||
if (!(seg_desc.type & 8))
|
||||
goto exception;
|
||||
|
||||
|
@ -4394,8 +4391,11 @@ done_prefixes:
|
|||
|
||||
ctxt->execute = opcode.u.execute;
|
||||
|
||||
if (unlikely(ctxt->ud) && likely(!(ctxt->d & EmulateOnUD)))
|
||||
return EMULATION_FAILED;
|
||||
|
||||
if (unlikely(ctxt->d &
|
||||
(NotImpl|EmulateOnUD|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm))) {
|
||||
(NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm))) {
|
||||
/*
|
||||
* These are copied unconditionally here, and checked unconditionally
|
||||
* in x86_emulate_insn.
|
||||
|
@ -4406,9 +4406,6 @@ done_prefixes:
|
|||
if (ctxt->d & NotImpl)
|
||||
return EMULATION_FAILED;
|
||||
|
||||
if (!(ctxt->d & EmulateOnUD) && ctxt->ud)
|
||||
return EMULATION_FAILED;
|
||||
|
||||
if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack))
|
||||
ctxt->op_bytes = 8;
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/tegra-powergate.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <soc/tegra/pmc.h>
|
||||
#include "ahci.h"
|
||||
|
||||
#define SATA_CONFIGURATION_0 0x180
|
||||
|
|
|
@ -344,7 +344,7 @@ static struct ata_port_operations xgene_ahci_ops = {
|
|||
};
|
||||
|
||||
static const struct ata_port_info xgene_ahci_port_info = {
|
||||
.flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
|
||||
.flags = AHCI_FLAG_COMMON,
|
||||
.pio_mask = ATA_PIO4,
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &xgene_ahci_ops,
|
||||
|
@ -480,7 +480,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
|
|||
/* Configure the host controller */
|
||||
xgene_ahci_hw_init(hpriv);
|
||||
|
||||
hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ;
|
||||
hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ;
|
||||
|
||||
rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info);
|
||||
if (rc)
|
||||
|
|
|
@ -4228,7 +4228,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|||
{ "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Crucial_CT???M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Crucial_CT*M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
|
||||
/*
|
||||
* Some WD SATA-I drives spin up and down erratically when the link
|
||||
|
|
|
@ -360,7 +360,7 @@ static int pata_s3c_wait_after_reset(struct ata_link *link,
|
|||
/*
|
||||
* pata_s3c_bus_softreset - PATA device software reset
|
||||
*/
|
||||
static unsigned int pata_s3c_bus_softreset(struct ata_port *ap,
|
||||
static int pata_s3c_bus_softreset(struct ata_port *ap,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
|
|
@ -585,7 +585,7 @@ static int scc_wait_after_reset(struct ata_link *link, unsigned int devmask,
|
|||
* Note: Original code is ata_bus_softreset().
|
||||
*/
|
||||
|
||||
static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
|
||||
static int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
@ -599,9 +599,7 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
|
|||
udelay(20);
|
||||
out_be32(ioaddr->ctl_addr, ap->ctl);
|
||||
|
||||
scc_wait_after_reset(&ap->link, devmask, deadline);
|
||||
|
||||
return 0;
|
||||
return scc_wait_after_reset(&ap->link, devmask, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -618,7 +616,8 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes,
|
|||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
|
||||
unsigned int devmask = 0, err_mask;
|
||||
unsigned int devmask = 0;
|
||||
int rc;
|
||||
u8 err;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
@ -634,9 +633,9 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes,
|
|||
|
||||
/* issue bus reset */
|
||||
DPRINTK("about to softreset, devmask=%x\n", devmask);
|
||||
err_mask = scc_bus_softreset(ap, devmask, deadline);
|
||||
if (err_mask) {
|
||||
ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", err_mask);
|
||||
rc = scc_bus_softreset(ap, devmask, deadline);
|
||||
if (rc) {
|
||||
ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", rc);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ static int probe_common(struct virtio_device *vdev)
|
|||
.cleanup = virtio_cleanup,
|
||||
.priv = (unsigned long)vi,
|
||||
.name = vi->name,
|
||||
.quality = 1000,
|
||||
};
|
||||
vdev->priv = vi;
|
||||
|
||||
|
|
|
@ -253,12 +253,12 @@ config EDAC_I7300
|
|||
Clarksboro MCH (Intel 7300 chipset).
|
||||
|
||||
config EDAC_SBRIDGE
|
||||
tristate "Intel Sandy-Bridge Integrated MC"
|
||||
tristate "Intel Sandy-Bridge/Ivy-Bridge/Haswell Integrated MC"
|
||||
depends on EDAC_MM_EDAC && PCI && X86_64 && X86_MCE_INTEL
|
||||
depends on PCI_MMCONFIG
|
||||
help
|
||||
Support for error detection and correction the Intel
|
||||
Sandy Bridge Integrated Memory Controller.
|
||||
Sandy Bridge, Ivy Bridge and Haswell Integrated Memory Controllers.
|
||||
|
||||
config EDAC_MPC85XX
|
||||
tristate "Freescale MPC83xx / MPC85xx"
|
||||
|
|
|
@ -108,7 +108,9 @@ static const char * const mem_types[] = {
|
|||
[MEM_RDDR2] = "Registered-DDR2",
|
||||
[MEM_XDR] = "XDR",
|
||||
[MEM_DDR3] = "Unbuffered-DDR3",
|
||||
[MEM_RDDR3] = "Registered-DDR3"
|
||||
[MEM_RDDR3] = "Registered-DDR3",
|
||||
[MEM_DDR4] = "Unbuffered-DDR4",
|
||||
[MEM_RDDR4] = "Registered-DDR4"
|
||||
};
|
||||
|
||||
static const char * const dev_types[] = {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -132,12 +132,12 @@ nvkm_client_notify_new(struct nouveau_client *client,
|
|||
if (ret == 0) {
|
||||
client->notify[index] = notify;
|
||||
notify->client = client;
|
||||
return 0;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(notify);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -163,6 +163,7 @@ nve0_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_ibus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
|
||||
|
|
|
@ -68,6 +68,9 @@ nvc0_graph_zbc_color_get(struct nvc0_graph_priv *priv, int format,
|
|||
}
|
||||
}
|
||||
|
||||
if (zbc < 0)
|
||||
return zbc;
|
||||
|
||||
memcpy(priv->zbc_color[zbc].ds, ds, sizeof(priv->zbc_color[zbc].ds));
|
||||
memcpy(priv->zbc_color[zbc].l2, l2, sizeof(priv->zbc_color[zbc].l2));
|
||||
priv->zbc_color[zbc].format = format;
|
||||
|
@ -109,6 +112,9 @@ nvc0_graph_zbc_depth_get(struct nvc0_graph_priv *priv, int format,
|
|||
}
|
||||
}
|
||||
|
||||
if (zbc < 0)
|
||||
return zbc;
|
||||
|
||||
priv->zbc_depth[zbc].format = format;
|
||||
priv->zbc_depth[zbc].ds = ds;
|
||||
priv->zbc_depth[zbc].l2 = l2;
|
||||
|
|
|
@ -14,7 +14,7 @@ struct nouveau_client {
|
|||
void *data;
|
||||
|
||||
int (*ntfy)(const void *, u32, const void *, u32);
|
||||
struct nvkm_client_notify *notify[8];
|
||||
struct nvkm_client_notify *notify[16];
|
||||
};
|
||||
|
||||
static inline struct nouveau_client *
|
||||
|
|
|
@ -99,8 +99,13 @@ nouveau_bar_alloc(struct nouveau_bar *bar, struct nouveau_object *parent,
|
|||
struct nouveau_mem *mem, struct nouveau_object **pobject)
|
||||
{
|
||||
struct nouveau_object *engine = nv_object(bar);
|
||||
return nouveau_object_ctor(parent, engine, &nouveau_barobj_oclass,
|
||||
mem, 0, pobject);
|
||||
int ret = -ENOMEM;
|
||||
if (bar->iomem) {
|
||||
ret = nouveau_object_ctor(parent, engine,
|
||||
&nouveau_barobj_oclass,
|
||||
mem, 0, pobject);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -118,9 +123,12 @@ nouveau_bar_create_(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (nv_device_resource_len(device, 3) != 0)
|
||||
if (nv_device_resource_len(device, 3) != 0) {
|
||||
bar->iomem = ioremap(nv_device_resource_start(device, 3),
|
||||
nv_device_resource_len(device, 3));
|
||||
if (!bar->iomem)
|
||||
nv_warn(bar, "PRAMIN ioremap failed\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -554,13 +554,13 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
} else {
|
||||
/* otherwise, address lowest common amount from 0GiB */
|
||||
ret = nouveau_mm_init(&pfb->vram, rsvd_head,
|
||||
(bsize << 8) * parts, 1);
|
||||
(bsize << 8) * parts - rsvd_head, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* and the rest starting from (8GiB + common_size) */
|
||||
offset = (0x0200000000ULL >> 12) + (bsize << 8);
|
||||
length = (ram->size >> 12) - (bsize << 8) - rsvd_tail;
|
||||
length = (ram->size >> 12) - ((bsize * parts) << 8) - rsvd_tail;
|
||||
|
||||
ret = nouveau_mm_init(&pfb->vram, offset, length, 0);
|
||||
if (ret)
|
||||
|
|
|
@ -156,7 +156,7 @@ gf100_ltc_init_tag_ram(struct nouveau_fb *pfb, struct nvkm_ltc_priv *priv)
|
|||
if (ret) {
|
||||
priv->num_tags = 0;
|
||||
} else {
|
||||
u64 tag_base = (priv->tag_ram->offset << 12) + tag_margin;
|
||||
u64 tag_base = ((u64)priv->tag_ram->offset << 12) + tag_margin;
|
||||
|
||||
tag_base += tag_align - 1;
|
||||
ret = do_div(tag_base, tag_align);
|
||||
|
|
|
@ -1228,7 +1228,6 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
|
|||
struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
|
||||
struct nouveau_drm *drm = nouveau_bdev(bdev);
|
||||
struct nouveau_mem *node = mem->mm_node;
|
||||
struct drm_device *dev = drm->dev;
|
||||
int ret;
|
||||
|
||||
mem->bus.addr = NULL;
|
||||
|
@ -1247,7 +1246,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
|
|||
if (drm->agp.stat == ENABLED) {
|
||||
mem->bus.offset = mem->start << PAGE_SHIFT;
|
||||
mem->bus.base = drm->agp.base;
|
||||
mem->bus.is_iomem = !dev->agp->cant_use_aperture;
|
||||
mem->bus.is_iomem = !drm->dev->agp->cant_use_aperture;
|
||||
}
|
||||
#endif
|
||||
if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA || !node->memtype)
|
||||
|
|
|
@ -592,7 +592,9 @@ nouveau_display_repin(struct drm_device *dev)
|
|||
if (!nouveau_fb || !nouveau_fb->nvbo)
|
||||
continue;
|
||||
|
||||
nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
|
||||
ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
|
||||
if (ret)
|
||||
NV_ERROR(drm, "Could not pin framebuffer\n");
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
|
|
|
@ -226,7 +226,7 @@ nouveau_fbcon_accel_restore(struct drm_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
nouveau_fbcon_accel_fini(struct drm_device *dev)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
|
@ -246,7 +246,7 @@ nouveau_fbcon_accel_fini(struct drm_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
nouveau_fbcon_accel_init(struct drm_device *dev)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
|
|
|
@ -149,7 +149,8 @@ power_down:
|
|||
static int nouveau_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct drm_device *drm_dev = platform_get_drvdata(pdev);
|
||||
struct nouveau_device *device = nouveau_dev(drm_dev);
|
||||
struct nouveau_drm *drm = nouveau_drm(drm_dev);
|
||||
struct nouveau_device *device = nvkm_device(&drm->device);
|
||||
struct nouveau_platform_gpu *gpu = nv_device_to_platform(device)->gpu;
|
||||
|
||||
nouveau_drm_device_remove(drm_dev);
|
||||
|
|
|
@ -428,8 +428,8 @@ struct nv50_disp_dac_pwr_v0 {
|
|||
struct nv50_disp_dac_load_v0 {
|
||||
__u8 version;
|
||||
__u8 load;
|
||||
__u16 data;
|
||||
__u8 pad04[4];
|
||||
__u8 pad02[2];
|
||||
__u32 data;
|
||||
};
|
||||
|
||||
struct nv50_disp_sor_pwr_v0 {
|
||||
|
|
|
@ -87,12 +87,25 @@ nvif_notify_get(struct nvif_notify *notify)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nvif_notify_func(struct nvif_notify *notify, bool keep)
|
||||
{
|
||||
int ret = notify->func(notify);
|
||||
if (ret == NVIF_NOTIFY_KEEP ||
|
||||
!test_and_clear_bit(NVKM_NOTIFY_USER, ¬ify->flags)) {
|
||||
if (!keep)
|
||||
atomic_dec(¬ify->putcnt);
|
||||
else
|
||||
nvif_notify_get_(notify);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
nvif_notify_work(struct work_struct *work)
|
||||
{
|
||||
struct nvif_notify *notify = container_of(work, typeof(*notify), work);
|
||||
if (notify->func(notify) == NVIF_NOTIFY_KEEP)
|
||||
nvif_notify_get_(notify);
|
||||
nvif_notify_func(notify, true);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -113,19 +126,15 @@ nvif_notify(const void *header, u32 length, const void *data, u32 size)
|
|||
if (!WARN_ON(notify == NULL)) {
|
||||
struct nvif_client *client = nvif_client(notify->object);
|
||||
if (!WARN_ON(notify->size != size)) {
|
||||
atomic_inc(¬ify->putcnt);
|
||||
if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) {
|
||||
atomic_inc(¬ify->putcnt);
|
||||
memcpy((void *)notify->data, data, size);
|
||||
schedule_work(¬ify->work);
|
||||
return NVIF_NOTIFY_DROP;
|
||||
}
|
||||
notify->data = data;
|
||||
ret = notify->func(notify);
|
||||
ret = nvif_notify_func(notify, client->driver->keep);
|
||||
notify->data = NULL;
|
||||
if (ret != NVIF_NOTIFY_DROP && client->driver->keep) {
|
||||
atomic_inc(¬ify->putcnt);
|
||||
nvif_notify_get_(notify);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,8 +237,10 @@ nvif_notify_new(struct nvif_object *object, int (*func)(struct nvif_notify *),
|
|||
if (notify) {
|
||||
int ret = nvif_notify_init(object, nvif_notify_del, func, work,
|
||||
type, data, size, reply, notify);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
kfree(notify);
|
||||
notify = NULL;
|
||||
}
|
||||
*pnotify = notify;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -275,8 +275,10 @@ nvif_object_new(struct nvif_object *parent, u32 handle, u32 oclass,
|
|||
if (object) {
|
||||
int ret = nvif_object_init(parent, nvif_object_del, handle,
|
||||
oclass, data, size, object);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
kfree(object);
|
||||
object = NULL;
|
||||
}
|
||||
*pobject = object;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
|
||||
if (*rsize >= 18 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
|
||||
hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n");
|
||||
rdesc[11] = rdesc[16] = 0xff;
|
||||
rdesc[12] = rdesc[17] = 0x03;
|
||||
|
|
|
@ -84,6 +84,15 @@ static const __u8 huion_tablet_rdesc_template[] = {
|
|||
0xC0 /* End Collection */
|
||||
};
|
||||
|
||||
/* Parameter indices */
|
||||
enum huion_prm {
|
||||
HUION_PRM_X_LM = 1,
|
||||
HUION_PRM_Y_LM = 2,
|
||||
HUION_PRM_PRESSURE_LM = 4,
|
||||
HUION_PRM_RESOLUTION = 5,
|
||||
HUION_PRM_NUM
|
||||
};
|
||||
|
||||
/* Driver data */
|
||||
struct huion_drvdata {
|
||||
__u8 *rdesc;
|
||||
|
@ -115,7 +124,12 @@ static int huion_tablet_enable(struct hid_device *hdev)
|
|||
int rc;
|
||||
struct usb_device *usb_dev = hid_to_usb_dev(hdev);
|
||||
struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
|
||||
__le16 buf[6];
|
||||
__le16 *buf = NULL;
|
||||
size_t len;
|
||||
s32 params[HUION_PH_ID_NUM];
|
||||
s32 resolution;
|
||||
__u8 *p;
|
||||
s32 v;
|
||||
|
||||
/*
|
||||
* Read string descriptor containing tablet parameters. The specific
|
||||
|
@ -123,65 +137,79 @@ static int huion_tablet_enable(struct hid_device *hdev)
|
|||
* driver traffic.
|
||||
* NOTE: This enables fully-functional tablet mode.
|
||||
*/
|
||||
len = HUION_PRM_NUM * sizeof(*buf);
|
||||
buf = kmalloc(len, GFP_KERNEL);
|
||||
if (buf == NULL) {
|
||||
hid_err(hdev, "failed to allocate parameter buffer\n");
|
||||
rc = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
|
||||
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
||||
(USB_DT_STRING << 8) + 0x64,
|
||||
0x0409, buf, sizeof(buf),
|
||||
0x0409, buf, len,
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
if (rc == -EPIPE)
|
||||
hid_warn(hdev, "device parameters not found\n");
|
||||
else if (rc < 0)
|
||||
hid_warn(hdev, "failed to get device parameters: %d\n", rc);
|
||||
else if (rc != sizeof(buf))
|
||||
hid_warn(hdev, "invalid device parameters\n");
|
||||
else {
|
||||
s32 params[HUION_PH_ID_NUM];
|
||||
s32 resolution;
|
||||
__u8 *p;
|
||||
s32 v;
|
||||
if (rc == -EPIPE) {
|
||||
hid_err(hdev, "device parameters not found\n");
|
||||
rc = -ENODEV;
|
||||
goto cleanup;
|
||||
} else if (rc < 0) {
|
||||
hid_err(hdev, "failed to get device parameters: %d\n", rc);
|
||||
rc = -ENODEV;
|
||||
goto cleanup;
|
||||
} else if (rc != len) {
|
||||
hid_err(hdev, "invalid device parameters\n");
|
||||
rc = -ENODEV;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Extract device parameters */
|
||||
params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]);
|
||||
params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]);
|
||||
params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]);
|
||||
resolution = le16_to_cpu(buf[5]);
|
||||
if (resolution == 0) {
|
||||
params[HUION_PH_ID_X_PM] = 0;
|
||||
params[HUION_PH_ID_Y_PM] = 0;
|
||||
/* Extract device parameters */
|
||||
params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[HUION_PRM_X_LM]);
|
||||
params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[HUION_PRM_Y_LM]);
|
||||
params[HUION_PH_ID_PRESSURE_LM] =
|
||||
le16_to_cpu(buf[HUION_PRM_PRESSURE_LM]);
|
||||
resolution = le16_to_cpu(buf[HUION_PRM_RESOLUTION]);
|
||||
if (resolution == 0) {
|
||||
params[HUION_PH_ID_X_PM] = 0;
|
||||
params[HUION_PH_ID_Y_PM] = 0;
|
||||
} else {
|
||||
params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] *
|
||||
1000 / resolution;
|
||||
params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] *
|
||||
1000 / resolution;
|
||||
}
|
||||
|
||||
/* Allocate fixed report descriptor */
|
||||
drvdata->rdesc = devm_kmalloc(&hdev->dev,
|
||||
sizeof(huion_tablet_rdesc_template),
|
||||
GFP_KERNEL);
|
||||
if (drvdata->rdesc == NULL) {
|
||||
hid_err(hdev, "failed to allocate fixed rdesc\n");
|
||||
rc = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
drvdata->rsize = sizeof(huion_tablet_rdesc_template);
|
||||
|
||||
/* Format fixed report descriptor */
|
||||
memcpy(drvdata->rdesc, huion_tablet_rdesc_template,
|
||||
drvdata->rsize);
|
||||
for (p = drvdata->rdesc;
|
||||
p <= drvdata->rdesc + drvdata->rsize - 4;) {
|
||||
if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D &&
|
||||
p[3] < sizeof(params)) {
|
||||
v = params[p[3]];
|
||||
put_unaligned(cpu_to_le32(v), (s32 *)p);
|
||||
p += 4;
|
||||
} else {
|
||||
params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] *
|
||||
1000 / resolution;
|
||||
params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] *
|
||||
1000 / resolution;
|
||||
}
|
||||
|
||||
/* Allocate fixed report descriptor */
|
||||
drvdata->rdesc = devm_kmalloc(&hdev->dev,
|
||||
sizeof(huion_tablet_rdesc_template),
|
||||
GFP_KERNEL);
|
||||
if (drvdata->rdesc == NULL) {
|
||||
hid_err(hdev, "failed to allocate fixed rdesc\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
drvdata->rsize = sizeof(huion_tablet_rdesc_template);
|
||||
|
||||
/* Format fixed report descriptor */
|
||||
memcpy(drvdata->rdesc, huion_tablet_rdesc_template,
|
||||
drvdata->rsize);
|
||||
for (p = drvdata->rdesc;
|
||||
p <= drvdata->rdesc + drvdata->rsize - 4;) {
|
||||
if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D &&
|
||||
p[3] < sizeof(params)) {
|
||||
v = params[p[3]];
|
||||
put_unaligned(cpu_to_le32(v), (s32 *)p);
|
||||
p += 4;
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
rc = 0;
|
||||
|
||||
cleanup:
|
||||
kfree(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
|
|
|
@ -300,7 +300,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||
* - change the button usage range to 4-7 for the extra
|
||||
* buttons
|
||||
*/
|
||||
if (*rsize >= 74 &&
|
||||
if (*rsize >= 75 &&
|
||||
rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
|
||||
rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
|
||||
rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
|
||||
|
|
|
@ -345,14 +345,14 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||
struct usb_device_descriptor *udesc;
|
||||
__u16 bcdDevice, rev_maj, rev_min;
|
||||
|
||||
if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
|
||||
if ((drv_data->quirks & LG_RDESC) && *rsize >= 91 && rdesc[83] == 0x26 &&
|
||||
rdesc[84] == 0x8c && rdesc[85] == 0x02) {
|
||||
hid_info(hdev,
|
||||
"fixing up Logitech keyboard report descriptor\n");
|
||||
rdesc[84] = rdesc[89] = 0x4d;
|
||||
rdesc[85] = rdesc[90] = 0x10;
|
||||
}
|
||||
if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
|
||||
if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 51 &&
|
||||
rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
|
||||
rdesc[49] == 0x81 && rdesc[50] == 0x06) {
|
||||
hid_info(hdev,
|
||||
|
|
|
@ -451,13 +451,13 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
|
|||
drv_data = hid_get_drvdata(hid);
|
||||
if (!drv_data) {
|
||||
hid_err(hid, "Private driver data not found!\n");
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
entry = drv_data->device_props;
|
||||
if (!entry) {
|
||||
hid_err(hid, "Device properties not found!\n");
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (range == 0)
|
||||
|
|
|
@ -238,13 +238,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
|
|||
return;
|
||||
}
|
||||
|
||||
if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
|
||||
(dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
|
||||
dev_err(&djrcv_hdev->dev, "%s: invalid device index:%d\n",
|
||||
__func__, dj_report->device_index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
|
||||
/* The device is already known. No need to reallocate it. */
|
||||
dbg_hid("%s: device is already known\n", __func__);
|
||||
|
@ -557,7 +550,7 @@ static int logi_dj_ll_raw_request(struct hid_device *hid,
|
|||
if (!out_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
if (count < DJREPORT_SHORT_LENGTH - 2)
|
||||
if (count > DJREPORT_SHORT_LENGTH - 2)
|
||||
count = DJREPORT_SHORT_LENGTH - 2;
|
||||
|
||||
out_buf[0] = REPORT_ID_DJ_SHORT;
|
||||
|
@ -690,6 +683,12 @@ static int logi_dj_raw_event(struct hid_device *hdev,
|
|||
* device (via hid_input_report() ) and return 1 so hid-core does not do
|
||||
* anything else with it.
|
||||
*/
|
||||
if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
|
||||
(dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
|
||||
dev_err(&hdev->dev, "%s: invalid device index:%d\n",
|
||||
__func__, dj_report->device_index);
|
||||
return false;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&djrcv_dev->lock, flags);
|
||||
if (dj_report->report_id == REPORT_ID_DJ_SHORT) {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) {
|
||||
if (*rsize >= 31 && rdesc[29] == 0x05 && rdesc[30] == 0x09) {
|
||||
hid_info(hdev, "fixing up button/consumer in HID report descriptor\n");
|
||||
rdesc[30] = 0x0c;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
|
||||
if (*rsize >= 62 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
|
||||
rdesc[41] == 0x00 && rdesc[59] == 0x26 &&
|
||||
rdesc[60] == 0xf9 && rdesc[61] == 0x00) {
|
||||
hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n");
|
||||
|
|
|
@ -909,10 +909,15 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!test_bit(RMI_STARTED, &data->flags)) {
|
||||
hid_hw_stop(hdev);
|
||||
return -EIO;
|
||||
}
|
||||
if (!test_bit(RMI_STARTED, &data->flags))
|
||||
/*
|
||||
* The device maybe in the bootloader if rmi_input_configured
|
||||
* failed to find F11 in the PDT. Print an error, but don't
|
||||
* return an error from rmi_probe so that hidraw will be
|
||||
* accessible from userspace. That way a userspace tool
|
||||
* can be used to reload working firmware on the touchpad.
|
||||
*/
|
||||
hid_err(hdev, "Device failed to be properly configured\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -604,9 +604,9 @@ static int sensor_hub_probe(struct hid_device *hdev,
|
|||
ret = -EINVAL;
|
||||
goto err_stop_hw;
|
||||
}
|
||||
sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt *
|
||||
sizeof(struct mfd_cell),
|
||||
GFP_KERNEL);
|
||||
sd->hid_sensor_hub_client_devs = devm_kzalloc(&hdev->dev, dev_cnt *
|
||||
sizeof(struct mfd_cell),
|
||||
GFP_KERNEL);
|
||||
if (sd->hid_sensor_hub_client_devs == NULL) {
|
||||
hid_err(hdev, "Failed to allocate memory for mfd cells\n");
|
||||
ret = -ENOMEM;
|
||||
|
@ -618,11 +618,12 @@ static int sensor_hub_probe(struct hid_device *hdev,
|
|||
|
||||
if (collection->type == HID_COLLECTION_PHYSICAL) {
|
||||
|
||||
hsdev = kzalloc(sizeof(*hsdev), GFP_KERNEL);
|
||||
hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev),
|
||||
GFP_KERNEL);
|
||||
if (!hsdev) {
|
||||
hid_err(hdev, "cannot allocate hid_sensor_hub_device\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_no_mem;
|
||||
goto err_stop_hw;
|
||||
}
|
||||
hsdev->hdev = hdev;
|
||||
hsdev->vendor_id = hdev->vendor;
|
||||
|
@ -631,13 +632,13 @@ static int sensor_hub_probe(struct hid_device *hdev,
|
|||
if (last_hsdev)
|
||||
last_hsdev->end_collection_index = i;
|
||||
last_hsdev = hsdev;
|
||||
name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x",
|
||||
collection->usage);
|
||||
name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
|
||||
"HID-SENSOR-%x",
|
||||
collection->usage);
|
||||
if (name == NULL) {
|
||||
hid_err(hdev, "Failed MFD device name\n");
|
||||
ret = -ENOMEM;
|
||||
kfree(hsdev);
|
||||
goto err_no_mem;
|
||||
goto err_stop_hw;
|
||||
}
|
||||
sd->hid_sensor_hub_client_devs[
|
||||
sd->hid_sensor_client_cnt].id =
|
||||
|
@ -661,16 +662,10 @@ static int sensor_hub_probe(struct hid_device *hdev,
|
|||
ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs,
|
||||
sd->hid_sensor_client_cnt, NULL, 0, NULL);
|
||||
if (ret < 0)
|
||||
goto err_no_mem;
|
||||
goto err_stop_hw;
|
||||
|
||||
return ret;
|
||||
|
||||
err_no_mem:
|
||||
for (i = 0; i < sd->hid_sensor_client_cnt; ++i) {
|
||||
kfree(sd->hid_sensor_hub_client_devs[i].name);
|
||||
kfree(sd->hid_sensor_hub_client_devs[i].platform_data);
|
||||
}
|
||||
kfree(sd->hid_sensor_hub_client_devs);
|
||||
err_stop_hw:
|
||||
hid_hw_stop(hdev);
|
||||
|
||||
|
@ -681,7 +676,6 @@ static void sensor_hub_remove(struct hid_device *hdev)
|
|||
{
|
||||
struct sensor_hub_data *data = hid_get_drvdata(hdev);
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
hid_dbg(hdev, " hardware removed\n");
|
||||
hid_hw_close(hdev);
|
||||
|
@ -691,11 +685,6 @@ static void sensor_hub_remove(struct hid_device *hdev)
|
|||
complete(&data->pending.ready);
|
||||
spin_unlock_irqrestore(&data->lock, flags);
|
||||
mfd_remove_devices(&hdev->dev);
|
||||
for (i = 0; i < data->hid_sensor_client_cnt; ++i) {
|
||||
kfree(data->hid_sensor_hub_client_devs[i].name);
|
||||
kfree(data->hid_sensor_hub_client_devs[i].platform_data);
|
||||
}
|
||||
kfree(data->hid_sensor_hub_client_devs);
|
||||
hid_set_drvdata(hdev, NULL);
|
||||
mutex_destroy(&data->mutex);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 &&
|
||||
if (*rsize >= 112 && rdesc[104] == 0x26 && rdesc[105] == 0x80 &&
|
||||
rdesc[106] == 0x03) {
|
||||
hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n");
|
||||
rdesc[105] = rdesc[110] = 0x03;
|
||||
|
|
|
@ -1416,6 +1416,7 @@ static void wacom_remove(struct hid_device *hdev)
|
|||
kfree(wacom);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int wacom_resume(struct hid_device *hdev)
|
||||
{
|
||||
struct wacom *wacom = hid_get_drvdata(hdev);
|
||||
|
@ -1436,6 +1437,7 @@ static int wacom_reset_resume(struct hid_device *hdev)
|
|||
{
|
||||
return wacom_resume(hdev);
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct hid_driver wacom_driver = {
|
||||
.name = "wacom",
|
||||
|
|
|
@ -23,17 +23,14 @@ config I2C
|
|||
This I2C support can also be built as a module. If so, the module
|
||||
will be called i2c-core.
|
||||
|
||||
config I2C_ACPI
|
||||
bool "I2C ACPI support"
|
||||
select I2C
|
||||
depends on ACPI
|
||||
config ACPI_I2C_OPREGION
|
||||
bool "ACPI I2C Operation region support"
|
||||
depends on I2C=y && ACPI
|
||||
default y
|
||||
help
|
||||
Say Y here if you want to enable ACPI I2C support. This includes support
|
||||
for automatic enumeration of I2C slave devices and support for ACPI I2C
|
||||
Operation Regions. Operation Regions allow firmware (BIOS) code to
|
||||
access I2C slave devices, such as smart batteries through an I2C host
|
||||
controller driver.
|
||||
Say Y here if you want to enable ACPI I2C operation region support.
|
||||
Operation Regions allow firmware (BIOS) code to access I2C slave devices,
|
||||
such as smart batteries through an I2C host controller driver.
|
||||
|
||||
if I2C
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
i2ccore-y := i2c-core.o
|
||||
i2ccore-$(CONFIG_I2C_ACPI) += i2c-acpi.o
|
||||
i2ccore-$(CONFIG_ACPI) += i2c-acpi.o
|
||||
|
||||
obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o
|
||||
obj-$(CONFIG_I2C) += i2ccore.o
|
||||
|
|
|
@ -164,6 +164,7 @@
|
|||
|
||||
/* Older devices have their ID defined in <linux/pci_ids.h> */
|
||||
#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12
|
||||
#define PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS 0x2292
|
||||
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
|
||||
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
|
||||
/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
|
||||
|
@ -828,6 +829,7 @@ static const struct pci_device_id i801_ids[] = {
|
|||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ void acpi_i2c_register_devices(struct i2c_adapter *adap)
|
|||
dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_I2C_OPREGION
|
||||
static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
|
||||
u8 cmd, u8 *data, u8 data_len)
|
||||
{
|
||||
|
@ -360,3 +361,4 @@ void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
|
|||
|
||||
acpi_bus_detach_private_data(handle);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -89,6 +89,7 @@ struct idle_cpu {
|
|||
* Indicate which enable bits to clear here.
|
||||
*/
|
||||
unsigned long auto_demotion_disable_flags;
|
||||
bool byt_auto_demotion_disable_flag;
|
||||
bool disable_promotion_to_c1e;
|
||||
};
|
||||
|
||||
|
@ -442,6 +443,66 @@ static struct cpuidle_state hsw_cstates[] = {
|
|||
{
|
||||
.enter = NULL }
|
||||
};
|
||||
static struct cpuidle_state bdw_cstates[] = {
|
||||
{
|
||||
.name = "C1-BDW",
|
||||
.desc = "MWAIT 0x00",
|
||||
.flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
|
||||
.exit_latency = 2,
|
||||
.target_residency = 2,
|
||||
.enter = &intel_idle },
|
||||
{
|
||||
.name = "C1E-BDW",
|
||||
.desc = "MWAIT 0x01",
|
||||
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
|
||||
.exit_latency = 10,
|
||||
.target_residency = 20,
|
||||
.enter = &intel_idle },
|
||||
{
|
||||
.name = "C3-BDW",
|
||||
.desc = "MWAIT 0x10",
|
||||
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 40,
|
||||
.target_residency = 100,
|
||||
.enter = &intel_idle },
|
||||
{
|
||||
.name = "C6-BDW",
|
||||
.desc = "MWAIT 0x20",
|
||||
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 133,
|
||||
.target_residency = 400,
|
||||
.enter = &intel_idle },
|
||||
{
|
||||
.name = "C7s-BDW",
|
||||
.desc = "MWAIT 0x32",
|
||||
.flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 166,
|
||||
.target_residency = 500,
|
||||
.enter = &intel_idle },
|
||||
{
|
||||
.name = "C8-BDW",
|
||||
.desc = "MWAIT 0x40",
|
||||
.flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 300,
|
||||
.target_residency = 900,
|
||||
.enter = &intel_idle },
|
||||
{
|
||||
.name = "C9-BDW",
|
||||
.desc = "MWAIT 0x50",
|
||||
.flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 600,
|
||||
.target_residency = 1800,
|
||||
.enter = &intel_idle },
|
||||
{
|
||||
.name = "C10-BDW",
|
||||
.desc = "MWAIT 0x60",
|
||||
.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
|
||||
.exit_latency = 2600,
|
||||
.target_residency = 7700,
|
||||
.enter = &intel_idle },
|
||||
{
|
||||
.enter = NULL }
|
||||
};
|
||||
|
||||
static struct cpuidle_state atom_cstates[] = {
|
||||
{
|
||||
|
@ -613,6 +674,7 @@ static const struct idle_cpu idle_cpu_snb = {
|
|||
static const struct idle_cpu idle_cpu_byt = {
|
||||
.state_table = byt_cstates,
|
||||
.disable_promotion_to_c1e = true,
|
||||
.byt_auto_demotion_disable_flag = true,
|
||||
};
|
||||
|
||||
static const struct idle_cpu idle_cpu_ivb = {
|
||||
|
@ -630,6 +692,11 @@ static const struct idle_cpu idle_cpu_hsw = {
|
|||
.disable_promotion_to_c1e = true,
|
||||
};
|
||||
|
||||
static const struct idle_cpu idle_cpu_bdw = {
|
||||
.state_table = bdw_cstates,
|
||||
.disable_promotion_to_c1e = true,
|
||||
};
|
||||
|
||||
static const struct idle_cpu idle_cpu_avn = {
|
||||
.state_table = avn_cstates,
|
||||
.disable_promotion_to_c1e = true,
|
||||
|
@ -658,7 +725,10 @@ static const struct x86_cpu_id intel_idle_ids[] = {
|
|||
ICPU(0x3f, idle_cpu_hsw),
|
||||
ICPU(0x45, idle_cpu_hsw),
|
||||
ICPU(0x46, idle_cpu_hsw),
|
||||
ICPU(0x4D, idle_cpu_avn),
|
||||
ICPU(0x4d, idle_cpu_avn),
|
||||
ICPU(0x3d, idle_cpu_bdw),
|
||||
ICPU(0x4f, idle_cpu_bdw),
|
||||
ICPU(0x56, idle_cpu_bdw),
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
|
||||
|
@ -814,6 +884,11 @@ static int __init intel_idle_cpuidle_driver_init(void)
|
|||
if (icpu->auto_demotion_disable_flags)
|
||||
on_each_cpu(auto_demotion_disable, NULL, 1);
|
||||
|
||||
if (icpu->byt_auto_demotion_disable_flag) {
|
||||
wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0);
|
||||
wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0);
|
||||
}
|
||||
|
||||
if (icpu->disable_promotion_to_c1e) /* each-cpu is redundant */
|
||||
on_each_cpu(c1e_promotion_disable, NULL, 1);
|
||||
|
||||
|
|
|
@ -236,6 +236,31 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
|
|||
}
|
||||
EXPORT_SYMBOL(input_mt_report_pointer_emulation);
|
||||
|
||||
/**
|
||||
* input_mt_drop_unused() - Inactivate slots not seen in this frame
|
||||
* @dev: input device with allocated MT slots
|
||||
*
|
||||
* Lift all slots not seen since the last call to this function.
|
||||
*/
|
||||
void input_mt_drop_unused(struct input_dev *dev)
|
||||
{
|
||||
struct input_mt *mt = dev->mt;
|
||||
int i;
|
||||
|
||||
if (!mt)
|
||||
return;
|
||||
|
||||
for (i = 0; i < mt->num_slots; i++) {
|
||||
if (!input_mt_is_used(mt, &mt->slots[i])) {
|
||||
input_mt_slot(dev, i);
|
||||
input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
|
||||
}
|
||||
}
|
||||
|
||||
mt->frame++;
|
||||
}
|
||||
EXPORT_SYMBOL(input_mt_drop_unused);
|
||||
|
||||
/**
|
||||
* input_mt_sync_frame() - synchronize mt frame
|
||||
* @dev: input device with allocated MT slots
|
||||
|
@ -247,27 +272,18 @@ EXPORT_SYMBOL(input_mt_report_pointer_emulation);
|
|||
void input_mt_sync_frame(struct input_dev *dev)
|
||||
{
|
||||
struct input_mt *mt = dev->mt;
|
||||
struct input_mt_slot *s;
|
||||
bool use_count = false;
|
||||
|
||||
if (!mt)
|
||||
return;
|
||||
|
||||
if (mt->flags & INPUT_MT_DROP_UNUSED) {
|
||||
for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
|
||||
if (input_mt_is_used(mt, s))
|
||||
continue;
|
||||
input_mt_slot(dev, s - mt->slots);
|
||||
input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
|
||||
}
|
||||
}
|
||||
if (mt->flags & INPUT_MT_DROP_UNUSED)
|
||||
input_mt_drop_unused(dev);
|
||||
|
||||
if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT))
|
||||
use_count = true;
|
||||
|
||||
input_mt_report_pointer_emulation(dev, use_count);
|
||||
|
||||
mt->frame++;
|
||||
}
|
||||
EXPORT_SYMBOL(input_mt_sync_frame);
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ static unsigned int get_time_pit(void)
|
|||
#define GET_TIME(x) rdtscl(x)
|
||||
#define DELTA(x,y) ((y)-(x))
|
||||
#define TIME_NAME "TSC"
|
||||
#elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_TILE)
|
||||
#elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_TILE)
|
||||
#define GET_TIME(x) do { x = get_cycles(); } while (0)
|
||||
#define DELTA(x,y) ((y)-(x))
|
||||
#define TIME_NAME "get_cycles"
|
||||
|
|
|
@ -95,7 +95,8 @@
|
|||
#define XTYPE_XBOX 0
|
||||
#define XTYPE_XBOX360 1
|
||||
#define XTYPE_XBOX360W 2
|
||||
#define XTYPE_UNKNOWN 3
|
||||
#define XTYPE_XBOXONE 3
|
||||
#define XTYPE_UNKNOWN 4
|
||||
|
||||
static bool dpad_to_buttons;
|
||||
module_param(dpad_to_buttons, bool, S_IRUGO);
|
||||
|
@ -121,6 +122,7 @@ static const struct xpad_device {
|
|||
{ 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
|
||||
{ 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
|
||||
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
|
||||
{ 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
|
||||
{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
||||
{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
||||
{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
|
||||
|
@ -231,10 +233,12 @@ static const signed short xpad_abs_triggers[] = {
|
|||
-1
|
||||
};
|
||||
|
||||
/* Xbox 360 has a vendor-specific class, so we cannot match it with only
|
||||
/*
|
||||
* Xbox 360 has a vendor-specific class, so we cannot match it with only
|
||||
* USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
|
||||
* match against vendor id as well. Wired Xbox 360 devices have protocol 1,
|
||||
* wireless controllers have protocol 129. */
|
||||
* wireless controllers have protocol 129.
|
||||
*/
|
||||
#define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
|
||||
.idVendor = (vend), \
|
||||
|
@ -245,9 +249,20 @@ static const signed short xpad_abs_triggers[] = {
|
|||
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \
|
||||
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) }
|
||||
|
||||
/* The Xbox One controller uses subclass 71 and protocol 208. */
|
||||
#define XPAD_XBOXONE_VENDOR_PROTOCOL(vend, pr) \
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
|
||||
.idVendor = (vend), \
|
||||
.bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
|
||||
.bInterfaceSubClass = 71, \
|
||||
.bInterfaceProtocol = (pr)
|
||||
#define XPAD_XBOXONE_VENDOR(vend) \
|
||||
{ XPAD_XBOXONE_VENDOR_PROTOCOL(vend, 208) }
|
||||
|
||||
static struct usb_device_id xpad_table[] = {
|
||||
{ USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
|
||||
XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */
|
||||
XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */
|
||||
XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */
|
||||
XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */
|
||||
{ USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */
|
||||
|
@ -278,12 +293,10 @@ struct usb_xpad {
|
|||
struct urb *bulk_out;
|
||||
unsigned char *bdata;
|
||||
|
||||
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
|
||||
struct urb *irq_out; /* urb for interrupt out report */
|
||||
unsigned char *odata; /* output data */
|
||||
dma_addr_t odata_dma;
|
||||
struct mutex odata_mutex;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
|
||||
struct xpad_led *led;
|
||||
|
@ -470,6 +483,105 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
|
|||
xpad360_process_packet(xpad, cmd, &data[4]);
|
||||
}
|
||||
|
||||
/*
|
||||
* xpadone_process_buttons
|
||||
*
|
||||
* Process a button update packet from an Xbox one controller.
|
||||
*/
|
||||
static void xpadone_process_buttons(struct usb_xpad *xpad,
|
||||
struct input_dev *dev,
|
||||
unsigned char *data)
|
||||
{
|
||||
/* menu/view buttons */
|
||||
input_report_key(dev, BTN_START, data[4] & 0x04);
|
||||
input_report_key(dev, BTN_SELECT, data[4] & 0x08);
|
||||
|
||||
/* buttons A,B,X,Y */
|
||||
input_report_key(dev, BTN_A, data[4] & 0x10);
|
||||
input_report_key(dev, BTN_B, data[4] & 0x20);
|
||||
input_report_key(dev, BTN_X, data[4] & 0x40);
|
||||
input_report_key(dev, BTN_Y, data[4] & 0x80);
|
||||
|
||||
/* digital pad */
|
||||
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
|
||||
/* dpad as buttons (left, right, up, down) */
|
||||
input_report_key(dev, BTN_TRIGGER_HAPPY1, data[5] & 0x04);
|
||||
input_report_key(dev, BTN_TRIGGER_HAPPY2, data[5] & 0x08);
|
||||
input_report_key(dev, BTN_TRIGGER_HAPPY3, data[5] & 0x01);
|
||||
input_report_key(dev, BTN_TRIGGER_HAPPY4, data[5] & 0x02);
|
||||
} else {
|
||||
input_report_abs(dev, ABS_HAT0X,
|
||||
!!(data[5] & 0x08) - !!(data[5] & 0x04));
|
||||
input_report_abs(dev, ABS_HAT0Y,
|
||||
!!(data[5] & 0x02) - !!(data[5] & 0x01));
|
||||
}
|
||||
|
||||
/* TL/TR */
|
||||
input_report_key(dev, BTN_TL, data[5] & 0x10);
|
||||
input_report_key(dev, BTN_TR, data[5] & 0x20);
|
||||
|
||||
/* stick press left/right */
|
||||
input_report_key(dev, BTN_THUMBL, data[5] & 0x40);
|
||||
input_report_key(dev, BTN_THUMBR, data[5] & 0x80);
|
||||
|
||||
if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
|
||||
/* left stick */
|
||||
input_report_abs(dev, ABS_X,
|
||||
(__s16) le16_to_cpup((__le16 *)(data + 10)));
|
||||
input_report_abs(dev, ABS_Y,
|
||||
~(__s16) le16_to_cpup((__le16 *)(data + 12)));
|
||||
|
||||
/* right stick */
|
||||
input_report_abs(dev, ABS_RX,
|
||||
(__s16) le16_to_cpup((__le16 *)(data + 14)));
|
||||
input_report_abs(dev, ABS_RY,
|
||||
~(__s16) le16_to_cpup((__le16 *)(data + 16)));
|
||||
}
|
||||
|
||||
/* triggers left/right */
|
||||
if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
|
||||
input_report_key(dev, BTN_TL2,
|
||||
(__u16) le16_to_cpup((__le16 *)(data + 6)));
|
||||
input_report_key(dev, BTN_TR2,
|
||||
(__u16) le16_to_cpup((__le16 *)(data + 8)));
|
||||
} else {
|
||||
input_report_abs(dev, ABS_Z,
|
||||
(__u16) le16_to_cpup((__le16 *)(data + 6)));
|
||||
input_report_abs(dev, ABS_RZ,
|
||||
(__u16) le16_to_cpup((__le16 *)(data + 8)));
|
||||
}
|
||||
|
||||
input_sync(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* xpadone_process_packet
|
||||
*
|
||||
* Completes a request by converting the data into events for the
|
||||
* input subsystem. This version is for the Xbox One controller.
|
||||
*
|
||||
* The report format was gleaned from
|
||||
* https://github.com/kylelemons/xbox/blob/master/xbox.go
|
||||
*/
|
||||
|
||||
static void xpadone_process_packet(struct usb_xpad *xpad,
|
||||
u16 cmd, unsigned char *data)
|
||||
{
|
||||
struct input_dev *dev = xpad->dev;
|
||||
|
||||
switch (data[0]) {
|
||||
case 0x20:
|
||||
xpadone_process_buttons(xpad, dev, data);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
/* the xbox button has its own special report */
|
||||
input_report_key(dev, BTN_MODE, data[4] & 0x01);
|
||||
input_sync(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void xpad_irq_in(struct urb *urb)
|
||||
{
|
||||
struct usb_xpad *xpad = urb->context;
|
||||
|
@ -502,6 +614,9 @@ static void xpad_irq_in(struct urb *urb)
|
|||
case XTYPE_XBOX360W:
|
||||
xpad360w_process_packet(xpad, 0, xpad->idata);
|
||||
break;
|
||||
case XTYPE_XBOXONE:
|
||||
xpadone_process_packet(xpad, 0, xpad->idata);
|
||||
break;
|
||||
default:
|
||||
xpad_process_packet(xpad, 0, xpad->idata);
|
||||
}
|
||||
|
@ -535,7 +650,6 @@ static void xpad_bulk_out(struct urb *urb)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
|
||||
static void xpad_irq_out(struct urb *urb)
|
||||
{
|
||||
struct usb_xpad *xpad = urb->context;
|
||||
|
@ -573,6 +687,7 @@ exit:
|
|||
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
|
||||
{
|
||||
struct usb_endpoint_descriptor *ep_irq_out;
|
||||
int ep_irq_out_idx;
|
||||
int error;
|
||||
|
||||
if (xpad->xtype == XTYPE_UNKNOWN)
|
||||
|
@ -593,7 +708,10 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
|
|||
goto fail2;
|
||||
}
|
||||
|
||||
ep_irq_out = &intf->cur_altsetting->endpoint[1].desc;
|
||||
/* Xbox One controller has in/out endpoints swapped. */
|
||||
ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1;
|
||||
ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc;
|
||||
|
||||
usb_fill_int_urb(xpad->irq_out, xpad->udev,
|
||||
usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
|
||||
xpad->odata, XPAD_PKT_LEN,
|
||||
|
@ -621,11 +739,6 @@ static void xpad_deinit_output(struct usb_xpad *xpad)
|
|||
xpad->odata, xpad->odata_dma);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; }
|
||||
static void xpad_deinit_output(struct usb_xpad *xpad) {}
|
||||
static void xpad_stop_output(struct usb_xpad *xpad) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_JOYSTICK_XPAD_FF
|
||||
static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
|
||||
|
@ -692,7 +805,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
|
|||
|
||||
static int xpad_init_ff(struct usb_xpad *xpad)
|
||||
{
|
||||
if (xpad->xtype == XTYPE_UNKNOWN)
|
||||
if (xpad->xtype == XTYPE_UNKNOWN || xpad->xtype == XTYPE_XBOXONE)
|
||||
return 0;
|
||||
|
||||
input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
|
||||
|
@ -801,6 +914,14 @@ static int xpad_open(struct input_dev *dev)
|
|||
if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
|
||||
return -EIO;
|
||||
|
||||
if (xpad->xtype == XTYPE_XBOXONE) {
|
||||
/* Xbox one controller needs to be initialized. */
|
||||
xpad->odata[0] = 0x05;
|
||||
xpad->odata[1] = 0x20;
|
||||
xpad->irq_out->transfer_buffer_length = 2;
|
||||
return usb_submit_urb(xpad->irq_out, GFP_KERNEL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -816,6 +937,7 @@ static void xpad_close(struct input_dev *dev)
|
|||
|
||||
static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
|
||||
{
|
||||
struct usb_xpad *xpad = input_get_drvdata(input_dev);
|
||||
set_bit(abs, input_dev->absbit);
|
||||
|
||||
switch (abs) {
|
||||
|
@ -827,7 +949,10 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
|
|||
break;
|
||||
case ABS_Z:
|
||||
case ABS_RZ: /* the triggers (if mapped to axes) */
|
||||
input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
|
||||
if (xpad->xtype == XTYPE_XBOXONE)
|
||||
input_set_abs_params(input_dev, abs, 0, 1023, 0, 0);
|
||||
else
|
||||
input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
|
||||
break;
|
||||
case ABS_HAT0X:
|
||||
case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */
|
||||
|
@ -842,6 +967,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
struct usb_xpad *xpad;
|
||||
struct input_dev *input_dev;
|
||||
struct usb_endpoint_descriptor *ep_irq_in;
|
||||
int ep_irq_in_idx;
|
||||
int i, error;
|
||||
|
||||
for (i = 0; xpad_device[i].idVendor; i++) {
|
||||
|
@ -850,6 +976,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
break;
|
||||
}
|
||||
|
||||
if (xpad_device[i].xtype == XTYPE_XBOXONE &&
|
||||
intf->cur_altsetting->desc.bInterfaceNumber != 0) {
|
||||
/*
|
||||
* The Xbox One controller lists three interfaces all with the
|
||||
* same interface class, subclass and protocol. Differentiate by
|
||||
* interface number.
|
||||
*/
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
|
||||
input_dev = input_allocate_device();
|
||||
if (!xpad || !input_dev) {
|
||||
|
@ -920,7 +1056,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
__set_bit(xpad_common_btn[i], input_dev->keybit);
|
||||
|
||||
/* set up model-specific ones */
|
||||
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
|
||||
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W ||
|
||||
xpad->xtype == XTYPE_XBOXONE) {
|
||||
for (i = 0; xpad360_btn[i] >= 0; i++)
|
||||
__set_bit(xpad360_btn[i], input_dev->keybit);
|
||||
} else {
|
||||
|
@ -933,7 +1070,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
__set_bit(xpad_btn_pad[i], input_dev->keybit);
|
||||
} else {
|
||||
for (i = 0; xpad_abs_pad[i] >= 0; i++)
|
||||
xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
|
||||
xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
|
||||
}
|
||||
|
||||
if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
|
||||
|
@ -956,7 +1093,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
if (error)
|
||||
goto fail5;
|
||||
|
||||
ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
|
||||
/* Xbox One controller has in/out endpoints swapped. */
|
||||
ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0;
|
||||
ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc;
|
||||
|
||||
usb_fill_int_urb(xpad->irq_in, udev,
|
||||
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
|
||||
xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
|
||||
|
|
|
@ -64,7 +64,7 @@ struct cap1106_priv {
|
|||
struct input_dev *idev;
|
||||
|
||||
/* config */
|
||||
unsigned int keycodes[CAP1106_NUM_CHN];
|
||||
unsigned short keycodes[CAP1106_NUM_CHN];
|
||||
};
|
||||
|
||||
static const struct reg_default cap1106_reg_defaults[] = {
|
||||
|
@ -272,6 +272,12 @@ static int cap1106_i2c_probe(struct i2c_client *i2c_client,
|
|||
for (i = 0; i < CAP1106_NUM_CHN; i++)
|
||||
__set_bit(priv->keycodes[i], priv->idev->keybit);
|
||||
|
||||
__clear_bit(KEY_RESERVED, priv->idev->keybit);
|
||||
|
||||
priv->idev->keycode = priv->keycodes;
|
||||
priv->idev->keycodesize = sizeof(priv->keycodes[0]);
|
||||
priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes);
|
||||
|
||||
priv->idev->id.vendor = CAP1106_MANUFACTURER_ID;
|
||||
priv->idev->id.product = CAP1106_PRODUCT_ID;
|
||||
priv->idev->id.version = rev;
|
||||
|
|
|
@ -117,6 +117,9 @@ void synaptics_reset(struct psmouse *psmouse)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
|
||||
|
||||
static bool cr48_profile_sensor;
|
||||
|
||||
struct min_max_quirk {
|
||||
const char * const *pnp_ids;
|
||||
int x_min, x_max, y_min, y_max;
|
||||
|
@ -1152,6 +1155,42 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse,
|
|||
priv->agm_pending = false;
|
||||
}
|
||||
|
||||
static void synaptics_profile_sensor_process(struct psmouse *psmouse,
|
||||
struct synaptics_hw_state *sgm,
|
||||
int num_fingers)
|
||||
{
|
||||
struct input_dev *dev = psmouse->dev;
|
||||
struct synaptics_data *priv = psmouse->private;
|
||||
struct synaptics_hw_state *hw[2] = { sgm, &priv->agm };
|
||||
struct input_mt_pos pos[2];
|
||||
int slot[2], nsemi, i;
|
||||
|
||||
nsemi = clamp_val(num_fingers, 0, 2);
|
||||
|
||||
for (i = 0; i < nsemi; i++) {
|
||||
pos[i].x = hw[i]->x;
|
||||
pos[i].y = synaptics_invert_y(hw[i]->y);
|
||||
}
|
||||
|
||||
input_mt_assign_slots(dev, slot, pos, nsemi);
|
||||
|
||||
for (i = 0; i < nsemi; i++) {
|
||||
input_mt_slot(dev, slot[i]);
|
||||
input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
|
||||
input_report_abs(dev, ABS_MT_POSITION_X, pos[i].x);
|
||||
input_report_abs(dev, ABS_MT_POSITION_Y, pos[i].y);
|
||||
input_report_abs(dev, ABS_MT_PRESSURE, hw[i]->z);
|
||||
}
|
||||
|
||||
input_mt_drop_unused(dev);
|
||||
input_mt_report_pointer_emulation(dev, false);
|
||||
input_mt_report_finger_count(dev, num_fingers);
|
||||
|
||||
synaptics_report_buttons(psmouse, sgm);
|
||||
|
||||
input_sync(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* called for each full received packet from the touchpad
|
||||
*/
|
||||
|
@ -1215,6 +1254,11 @@ static void synaptics_process_packet(struct psmouse *psmouse)
|
|||
finger_width = 0;
|
||||
}
|
||||
|
||||
if (cr48_profile_sensor) {
|
||||
synaptics_profile_sensor_process(psmouse, &hw, num_fingers);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
|
||||
synaptics_report_semi_mt_data(dev, &hw, &priv->agm,
|
||||
num_fingers);
|
||||
|
@ -1360,6 +1404,9 @@ static void set_input_params(struct psmouse *psmouse,
|
|||
set_abs_position_params(dev, priv, ABS_X, ABS_Y);
|
||||
input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
|
||||
|
||||
if (cr48_profile_sensor)
|
||||
input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
|
||||
|
||||
if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) {
|
||||
set_abs_position_params(dev, priv, ABS_MT_POSITION_X,
|
||||
ABS_MT_POSITION_Y);
|
||||
|
@ -1371,11 +1418,16 @@ static void set_input_params(struct psmouse *psmouse,
|
|||
__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
|
||||
__set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
|
||||
} else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
|
||||
/* Non-image sensors with AGM use semi-mt */
|
||||
__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
|
||||
input_mt_init_slots(dev, 2, 0);
|
||||
set_abs_position_params(dev, priv, ABS_MT_POSITION_X,
|
||||
ABS_MT_POSITION_Y);
|
||||
/*
|
||||
* Profile sensor in CR-48 tracks contacts reasonably well,
|
||||
* other non-image sensors with AGM use semi-mt.
|
||||
*/
|
||||
input_mt_init_slots(dev, 2,
|
||||
INPUT_MT_POINTER |
|
||||
(cr48_profile_sensor ?
|
||||
INPUT_MT_TRACK : INPUT_MT_SEMI_MT));
|
||||
}
|
||||
|
||||
if (SYN_CAP_PALMDETECT(priv->capabilities))
|
||||
|
@ -1577,10 +1629,24 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = {
|
|||
{ }
|
||||
};
|
||||
|
||||
static const struct dmi_system_id __initconst cr48_dmi_table[] = {
|
||||
#if defined(CONFIG_DMI) && defined(CONFIG_X86)
|
||||
{
|
||||
/* Cr-48 Chromebook (Codename Mario) */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "IEC"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Mario"),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
{ }
|
||||
};
|
||||
|
||||
void __init synaptics_module_init(void)
|
||||
{
|
||||
impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
|
||||
broken_olpc_ec = dmi_check_system(olpc_dmi_table);
|
||||
cr48_profile_sensor = dmi_check_system(cr48_dmi_table);
|
||||
}
|
||||
|
||||
static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
|
||||
|
|
|
@ -359,7 +359,6 @@ static int mxt_bootloader_read(struct mxt_data *data,
|
|||
msg.buf = val;
|
||||
|
||||
ret = i2c_transfer(data->client->adapter, &msg, 1);
|
||||
|
||||
if (ret == 1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
|
@ -414,6 +413,7 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry)
|
|||
case 0x5b:
|
||||
bootloader = appmode - 0x26;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(&data->client->dev,
|
||||
"Appmode i2c address 0x%02x not found\n",
|
||||
|
@ -425,20 +425,20 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mxt_probe_bootloader(struct mxt_data *data, bool retry)
|
||||
static int mxt_probe_bootloader(struct mxt_data *data, bool alt_address)
|
||||
{
|
||||
struct device *dev = &data->client->dev;
|
||||
int ret;
|
||||
int error;
|
||||
u8 val;
|
||||
bool crc_failure;
|
||||
|
||||
ret = mxt_lookup_bootloader_address(data, retry);
|
||||
if (ret)
|
||||
return ret;
|
||||
error = mxt_lookup_bootloader_address(data, alt_address);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
ret = mxt_bootloader_read(data, &val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
error = mxt_bootloader_read(data, &val, 1);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* Check app crc fail mode */
|
||||
crc_failure = (val & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL;
|
||||
|
@ -1064,131 +1064,21 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, off_t end_off)
|
|||
return crc;
|
||||
}
|
||||
|
||||
/*
|
||||
* mxt_update_cfg - download configuration to chip
|
||||
*
|
||||
* Atmel Raw Config File Format
|
||||
*
|
||||
* The first four lines of the raw config file contain:
|
||||
* 1) Version
|
||||
* 2) Chip ID Information (first 7 bytes of device memory)
|
||||
* 3) Chip Information Block 24-bit CRC Checksum
|
||||
* 4) Chip Configuration 24-bit CRC Checksum
|
||||
*
|
||||
* The rest of the file consists of one line per object instance:
|
||||
* <TYPE> <INSTANCE> <SIZE> <CONTENTS>
|
||||
*
|
||||
* <TYPE> - 2-byte object type as hex
|
||||
* <INSTANCE> - 2-byte object instance number as hex
|
||||
* <SIZE> - 2-byte object size as hex
|
||||
* <CONTENTS> - array of <SIZE> 1-byte hex values
|
||||
*/
|
||||
static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
|
||||
static int mxt_prepare_cfg_mem(struct mxt_data *data,
|
||||
const struct firmware *cfg,
|
||||
unsigned int data_pos,
|
||||
unsigned int cfg_start_ofs,
|
||||
u8 *config_mem,
|
||||
size_t config_mem_size)
|
||||
{
|
||||
struct device *dev = &data->client->dev;
|
||||
struct mxt_info cfg_info;
|
||||
struct mxt_object *object;
|
||||
int ret;
|
||||
unsigned int type, instance, size, byte_offset;
|
||||
int offset;
|
||||
int data_pos;
|
||||
int byte_offset;
|
||||
int ret;
|
||||
int i;
|
||||
int cfg_start_ofs;
|
||||
u32 info_crc, config_crc, calculated_crc;
|
||||
u8 *config_mem;
|
||||
size_t config_mem_size;
|
||||
unsigned int type, instance, size;
|
||||
u8 val;
|
||||
u16 reg;
|
||||
|
||||
mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
|
||||
|
||||
if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
|
||||
dev_err(dev, "Unrecognised config file\n");
|
||||
ret = -EINVAL;
|
||||
goto release;
|
||||
}
|
||||
|
||||
data_pos = strlen(MXT_CFG_MAGIC);
|
||||
|
||||
/* Load information block and check */
|
||||
for (i = 0; i < sizeof(struct mxt_info); i++) {
|
||||
ret = sscanf(cfg->data + data_pos, "%hhx%n",
|
||||
(unsigned char *)&cfg_info + i,
|
||||
&offset);
|
||||
if (ret != 1) {
|
||||
dev_err(dev, "Bad format\n");
|
||||
ret = -EINVAL;
|
||||
goto release;
|
||||
}
|
||||
|
||||
data_pos += offset;
|
||||
}
|
||||
|
||||
if (cfg_info.family_id != data->info.family_id) {
|
||||
dev_err(dev, "Family ID mismatch!\n");
|
||||
ret = -EINVAL;
|
||||
goto release;
|
||||
}
|
||||
|
||||
if (cfg_info.variant_id != data->info.variant_id) {
|
||||
dev_err(dev, "Variant ID mismatch!\n");
|
||||
ret = -EINVAL;
|
||||
goto release;
|
||||
}
|
||||
|
||||
/* Read CRCs */
|
||||
ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset);
|
||||
if (ret != 1) {
|
||||
dev_err(dev, "Bad format: failed to parse Info CRC\n");
|
||||
ret = -EINVAL;
|
||||
goto release;
|
||||
}
|
||||
data_pos += offset;
|
||||
|
||||
ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset);
|
||||
if (ret != 1) {
|
||||
dev_err(dev, "Bad format: failed to parse Config CRC\n");
|
||||
ret = -EINVAL;
|
||||
goto release;
|
||||
}
|
||||
data_pos += offset;
|
||||
|
||||
/*
|
||||
* The Info Block CRC is calculated over mxt_info and the object
|
||||
* table. If it does not match then we are trying to load the
|
||||
* configuration from a different chip or firmware version, so
|
||||
* the configuration CRC is invalid anyway.
|
||||
*/
|
||||
if (info_crc == data->info_crc) {
|
||||
if (config_crc == 0 || data->config_crc == 0) {
|
||||
dev_info(dev, "CRC zero, attempting to apply config\n");
|
||||
} else if (config_crc == data->config_crc) {
|
||||
dev_dbg(dev, "Config CRC 0x%06X: OK\n",
|
||||
data->config_crc);
|
||||
ret = 0;
|
||||
goto release;
|
||||
} else {
|
||||
dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
|
||||
data->config_crc, config_crc);
|
||||
}
|
||||
} else {
|
||||
dev_warn(dev,
|
||||
"Warning: Info CRC error - device=0x%06X file=0x%06X\n",
|
||||
data->info_crc, info_crc);
|
||||
}
|
||||
|
||||
/* Malloc memory to store configuration */
|
||||
cfg_start_ofs = MXT_OBJECT_START +
|
||||
data->info.object_num * sizeof(struct mxt_object) +
|
||||
MXT_INFO_CHECKSUM_SIZE;
|
||||
config_mem_size = data->mem_size - cfg_start_ofs;
|
||||
config_mem = kzalloc(config_mem_size, GFP_KERNEL);
|
||||
if (!config_mem) {
|
||||
dev_err(dev, "Failed to allocate memory\n");
|
||||
ret = -ENOMEM;
|
||||
goto release;
|
||||
}
|
||||
u8 val;
|
||||
|
||||
while (data_pos < cfg->size) {
|
||||
/* Read type, instance, length */
|
||||
|
@ -1199,8 +1089,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
|
|||
break;
|
||||
} else if (ret != 3) {
|
||||
dev_err(dev, "Bad format: failed to parse object\n");
|
||||
ret = -EINVAL;
|
||||
goto release_mem;
|
||||
return -EINVAL;
|
||||
}
|
||||
data_pos += offset;
|
||||
|
||||
|
@ -1209,8 +1098,12 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
|
|||
/* Skip object */
|
||||
for (i = 0; i < size; i++) {
|
||||
ret = sscanf(cfg->data + data_pos, "%hhx%n",
|
||||
&val,
|
||||
&offset);
|
||||
&val, &offset);
|
||||
if (ret != 1) {
|
||||
dev_err(dev, "Bad format in T%d at %d\n",
|
||||
type, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
data_pos += offset;
|
||||
}
|
||||
continue;
|
||||
|
@ -1240,8 +1133,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
|
|||
|
||||
if (instance >= mxt_obj_instances(object)) {
|
||||
dev_err(dev, "Object instances exceeded!\n");
|
||||
ret = -EINVAL;
|
||||
goto release_mem;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reg = object->start_address + mxt_obj_size(object) * instance;
|
||||
|
@ -1251,9 +1143,9 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
|
|||
&val,
|
||||
&offset);
|
||||
if (ret != 1) {
|
||||
dev_err(dev, "Bad format in T%d\n", type);
|
||||
ret = -EINVAL;
|
||||
goto release_mem;
|
||||
dev_err(dev, "Bad format in T%d at %d\n",
|
||||
type, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
data_pos += offset;
|
||||
|
||||
|
@ -1262,18 +1154,165 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
|
|||
|
||||
byte_offset = reg + i - cfg_start_ofs;
|
||||
|
||||
if ((byte_offset >= 0)
|
||||
&& (byte_offset <= config_mem_size)) {
|
||||
if (byte_offset >= 0 && byte_offset < config_mem_size) {
|
||||
*(config_mem + byte_offset) = val;
|
||||
} else {
|
||||
dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n",
|
||||
reg, object->type, byte_offset);
|
||||
ret = -EINVAL;
|
||||
goto release_mem;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxt_upload_cfg_mem(struct mxt_data *data, unsigned int cfg_start,
|
||||
u8 *config_mem, size_t config_mem_size)
|
||||
{
|
||||
unsigned int byte_offset = 0;
|
||||
int error;
|
||||
|
||||
/* Write configuration as blocks */
|
||||
while (byte_offset < config_mem_size) {
|
||||
unsigned int size = config_mem_size - byte_offset;
|
||||
|
||||
if (size > MXT_MAX_BLOCK_WRITE)
|
||||
size = MXT_MAX_BLOCK_WRITE;
|
||||
|
||||
error = __mxt_write_reg(data->client,
|
||||
cfg_start + byte_offset,
|
||||
size, config_mem + byte_offset);
|
||||
if (error) {
|
||||
dev_err(&data->client->dev,
|
||||
"Config write error, ret=%d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
byte_offset += size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* mxt_update_cfg - download configuration to chip
|
||||
*
|
||||
* Atmel Raw Config File Format
|
||||
*
|
||||
* The first four lines of the raw config file contain:
|
||||
* 1) Version
|
||||
* 2) Chip ID Information (first 7 bytes of device memory)
|
||||
* 3) Chip Information Block 24-bit CRC Checksum
|
||||
* 4) Chip Configuration 24-bit CRC Checksum
|
||||
*
|
||||
* The rest of the file consists of one line per object instance:
|
||||
* <TYPE> <INSTANCE> <SIZE> <CONTENTS>
|
||||
*
|
||||
* <TYPE> - 2-byte object type as hex
|
||||
* <INSTANCE> - 2-byte object instance number as hex
|
||||
* <SIZE> - 2-byte object size as hex
|
||||
* <CONTENTS> - array of <SIZE> 1-byte hex values
|
||||
*/
|
||||
static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
|
||||
{
|
||||
struct device *dev = &data->client->dev;
|
||||
struct mxt_info cfg_info;
|
||||
int ret;
|
||||
int offset;
|
||||
int data_pos;
|
||||
int i;
|
||||
int cfg_start_ofs;
|
||||
u32 info_crc, config_crc, calculated_crc;
|
||||
u8 *config_mem;
|
||||
size_t config_mem_size;
|
||||
|
||||
mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
|
||||
|
||||
if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
|
||||
dev_err(dev, "Unrecognised config file\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data_pos = strlen(MXT_CFG_MAGIC);
|
||||
|
||||
/* Load information block and check */
|
||||
for (i = 0; i < sizeof(struct mxt_info); i++) {
|
||||
ret = sscanf(cfg->data + data_pos, "%hhx%n",
|
||||
(unsigned char *)&cfg_info + i,
|
||||
&offset);
|
||||
if (ret != 1) {
|
||||
dev_err(dev, "Bad format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data_pos += offset;
|
||||
}
|
||||
|
||||
if (cfg_info.family_id != data->info.family_id) {
|
||||
dev_err(dev, "Family ID mismatch!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cfg_info.variant_id != data->info.variant_id) {
|
||||
dev_err(dev, "Variant ID mismatch!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Read CRCs */
|
||||
ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset);
|
||||
if (ret != 1) {
|
||||
dev_err(dev, "Bad format: failed to parse Info CRC\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
data_pos += offset;
|
||||
|
||||
ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset);
|
||||
if (ret != 1) {
|
||||
dev_err(dev, "Bad format: failed to parse Config CRC\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
data_pos += offset;
|
||||
|
||||
/*
|
||||
* The Info Block CRC is calculated over mxt_info and the object
|
||||
* table. If it does not match then we are trying to load the
|
||||
* configuration from a different chip or firmware version, so
|
||||
* the configuration CRC is invalid anyway.
|
||||
*/
|
||||
if (info_crc == data->info_crc) {
|
||||
if (config_crc == 0 || data->config_crc == 0) {
|
||||
dev_info(dev, "CRC zero, attempting to apply config\n");
|
||||
} else if (config_crc == data->config_crc) {
|
||||
dev_dbg(dev, "Config CRC 0x%06X: OK\n",
|
||||
data->config_crc);
|
||||
return 0;
|
||||
} else {
|
||||
dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
|
||||
data->config_crc, config_crc);
|
||||
}
|
||||
} else {
|
||||
dev_warn(dev,
|
||||
"Warning: Info CRC error - device=0x%06X file=0x%06X\n",
|
||||
data->info_crc, info_crc);
|
||||
}
|
||||
|
||||
/* Malloc memory to store configuration */
|
||||
cfg_start_ofs = MXT_OBJECT_START +
|
||||
data->info.object_num * sizeof(struct mxt_object) +
|
||||
MXT_INFO_CHECKSUM_SIZE;
|
||||
config_mem_size = data->mem_size - cfg_start_ofs;
|
||||
config_mem = kzalloc(config_mem_size, GFP_KERNEL);
|
||||
if (!config_mem) {
|
||||
dev_err(dev, "Failed to allocate memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs,
|
||||
config_mem, config_mem_size);
|
||||
if (ret)
|
||||
goto release_mem;
|
||||
|
||||
/* Calculate crc of the received configs (not the raw config file) */
|
||||
if (data->T7_address < cfg_start_ofs) {
|
||||
dev_err(dev, "Bad T7 address, T7addr = %x, config offset %x\n",
|
||||
|
@ -1286,28 +1325,14 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
|
|||
data->T7_address - cfg_start_ofs,
|
||||
config_mem_size);
|
||||
|
||||
if (config_crc > 0 && (config_crc != calculated_crc))
|
||||
if (config_crc > 0 && config_crc != calculated_crc)
|
||||
dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n",
|
||||
calculated_crc, config_crc);
|
||||
|
||||
/* Write configuration as blocks */
|
||||
byte_offset = 0;
|
||||
while (byte_offset < config_mem_size) {
|
||||
size = config_mem_size - byte_offset;
|
||||
|
||||
if (size > MXT_MAX_BLOCK_WRITE)
|
||||
size = MXT_MAX_BLOCK_WRITE;
|
||||
|
||||
ret = __mxt_write_reg(data->client,
|
||||
cfg_start_ofs + byte_offset,
|
||||
size, config_mem + byte_offset);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "Config write error, ret=%d\n", ret);
|
||||
goto release_mem;
|
||||
}
|
||||
|
||||
byte_offset += size;
|
||||
}
|
||||
ret = mxt_upload_cfg_mem(data, cfg_start_ofs,
|
||||
config_mem, config_mem_size);
|
||||
if (ret)
|
||||
goto release_mem;
|
||||
|
||||
mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
|
||||
|
||||
|
@ -1319,8 +1344,6 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
|
|||
|
||||
release_mem:
|
||||
kfree(config_mem);
|
||||
release:
|
||||
release_firmware(cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1422,10 +1445,12 @@ static int mxt_get_object_table(struct mxt_data *data)
|
|||
|
||||
switch (object->type) {
|
||||
case MXT_GEN_MESSAGE_T5:
|
||||
if (data->info.family_id == 0x80) {
|
||||
if (data->info.family_id == 0x80 &&
|
||||
data->info.version < 0x20) {
|
||||
/*
|
||||
* On mXT224 read and discard unused CRC byte
|
||||
* otherwise DMA reads are misaligned
|
||||
* On mXT224 firmware versions prior to V2.0
|
||||
* read and discard unused CRC byte otherwise
|
||||
* DMA reads are misaligned.
|
||||
*/
|
||||
data->T5_msg_size = mxt_obj_size(object);
|
||||
} else {
|
||||
|
@ -1433,6 +1458,7 @@ static int mxt_get_object_table(struct mxt_data *data)
|
|||
data->T5_msg_size = mxt_obj_size(object) - 1;
|
||||
}
|
||||
data->T5_address = object->start_address;
|
||||
break;
|
||||
case MXT_GEN_COMMAND_T6:
|
||||
data->T6_reportid = min_id;
|
||||
data->T6_address = object->start_address;
|
||||
|
@ -1638,46 +1664,45 @@ static int mxt_configure_objects(struct mxt_data *data,
|
|||
static void mxt_config_cb(const struct firmware *cfg, void *ctx)
|
||||
{
|
||||
mxt_configure_objects(ctx, cfg);
|
||||
release_firmware(cfg);
|
||||
}
|
||||
|
||||
static int mxt_initialize(struct mxt_data *data)
|
||||
{
|
||||
struct i2c_client *client = data->client;
|
||||
int recovery_attempts = 0;
|
||||
int error;
|
||||
bool alt_bootloader_addr = false;
|
||||
bool retry = false;
|
||||
|
||||
retry_info:
|
||||
error = mxt_get_info(data);
|
||||
if (error) {
|
||||
retry_bootloader:
|
||||
error = mxt_probe_bootloader(data, alt_bootloader_addr);
|
||||
while (1) {
|
||||
error = mxt_get_info(data);
|
||||
if (!error)
|
||||
break;
|
||||
|
||||
/* Check bootloader state */
|
||||
error = mxt_probe_bootloader(data, false);
|
||||
if (error) {
|
||||
if (alt_bootloader_addr) {
|
||||
dev_info(&client->dev, "Trying alternate bootloader address\n");
|
||||
error = mxt_probe_bootloader(data, true);
|
||||
if (error) {
|
||||
/* Chip is not in appmode or bootloader mode */
|
||||
return error;
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "Trying alternate bootloader address\n");
|
||||
alt_bootloader_addr = true;
|
||||
goto retry_bootloader;
|
||||
} else {
|
||||
if (retry) {
|
||||
dev_err(&client->dev, "Could not recover from bootloader mode\n");
|
||||
/*
|
||||
* We can reflash from this state, so do not
|
||||
* abort init
|
||||
*/
|
||||
data->in_bootloader = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Attempt to exit bootloader into app mode */
|
||||
mxt_send_bootloader_cmd(data, false);
|
||||
msleep(MXT_FW_RESET_TIME);
|
||||
retry = true;
|
||||
goto retry_info;
|
||||
}
|
||||
|
||||
/* OK, we are in bootloader, see if we can recover */
|
||||
if (++recovery_attempts > 1) {
|
||||
dev_err(&client->dev, "Could not recover from bootloader mode\n");
|
||||
/*
|
||||
* We can reflash from this state, so do not
|
||||
* abort initialization.
|
||||
*/
|
||||
data->in_bootloader = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Attempt to exit bootloader into app mode */
|
||||
mxt_send_bootloader_cmd(data, false);
|
||||
msleep(MXT_FW_RESET_TIME);
|
||||
}
|
||||
|
||||
/* Get object table information */
|
||||
|
@ -1687,13 +1712,18 @@ retry_bootloader:
|
|||
return error;
|
||||
}
|
||||
|
||||
mxt_acquire_irq(data);
|
||||
error = mxt_acquire_irq(data);
|
||||
if (error)
|
||||
goto err_free_object_table;
|
||||
|
||||
request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
|
||||
&data->client->dev, GFP_KERNEL, data,
|
||||
mxt_config_cb);
|
||||
error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
|
||||
&client->dev, GFP_KERNEL, data,
|
||||
mxt_config_cb);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
|
||||
error);
|
||||
goto err_free_object_table;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -262,7 +262,6 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
|
|||
case M06:
|
||||
wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
|
||||
wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
|
||||
wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
|
||||
wrbuf[2] = value;
|
||||
wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
|
||||
return edt_ft5x06_ts_readwrite(tsdata->client, 4,
|
||||
|
|
|
@ -3149,14 +3149,16 @@ free_domains:
|
|||
|
||||
static void cleanup_domain(struct protection_domain *domain)
|
||||
{
|
||||
struct iommu_dev_data *dev_data, *next;
|
||||
struct iommu_dev_data *entry;
|
||||
unsigned long flags;
|
||||
|
||||
write_lock_irqsave(&amd_iommu_devtable_lock, flags);
|
||||
|
||||
list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
|
||||
__detach_device(dev_data);
|
||||
atomic_set(&dev_data->bind, 0);
|
||||
while (!list_empty(&domain->dev_list)) {
|
||||
entry = list_first_entry(&domain->dev_list,
|
||||
struct iommu_dev_data, list);
|
||||
__detach_device(entry);
|
||||
atomic_set(&entry->bind, 0);
|
||||
}
|
||||
|
||||
write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
|
||||
|
|
|
@ -3869,6 +3869,14 @@ static int device_notifier(struct notifier_block *nb,
|
|||
action != BUS_NOTIFY_DEL_DEVICE)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If the device is still attached to a device driver we can't
|
||||
* tear down the domain yet as DMA mappings may still be in use.
|
||||
* Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that.
|
||||
*/
|
||||
if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL)
|
||||
return 0;
|
||||
|
||||
domain = find_domain(dev);
|
||||
if (!domain)
|
||||
return 0;
|
||||
|
|
|
@ -995,7 +995,7 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova,
|
|||
size_t orig_size = size;
|
||||
int ret = 0;
|
||||
|
||||
if (unlikely(domain->ops->unmap == NULL ||
|
||||
if (unlikely(domain->ops->map == NULL ||
|
||||
domain->ops->pgsize_bitmap == 0UL))
|
||||
return -ENODEV;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* $Id: xdi_msg.h,v 1.1.2.2 2001/02/16 08:40:36 armin Exp $ */
|
||||
|
||||
#ifndef __DIVA_XDI_UM_CFG_MESSSGE_H__
|
||||
#ifndef __DIVA_XDI_UM_CFG_MESSAGE_H__
|
||||
#define __DIVA_XDI_UM_CFG_MESSAGE_H__
|
||||
|
||||
/*
|
||||
|
|
|
@ -2953,6 +2953,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
|
|||
*/
|
||||
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
|
||||
end_reshape(conf);
|
||||
close_sync(conf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3081,6 +3082,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
|
|||
}
|
||||
|
||||
r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
|
||||
r10_bio->state = 0;
|
||||
raise_barrier(conf, rb2 != NULL);
|
||||
atomic_set(&r10_bio->remaining, 0);
|
||||
|
||||
|
@ -3269,6 +3271,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
|
|||
if (sync_blocks < max_sync)
|
||||
max_sync = sync_blocks;
|
||||
r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
|
||||
r10_bio->state = 0;
|
||||
|
||||
r10_bio->mddev = mddev;
|
||||
atomic_set(&r10_bio->remaining, 0);
|
||||
|
@ -4384,6 +4387,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
|
|||
read_more:
|
||||
/* Now schedule reads for blocks from sector_nr to last */
|
||||
r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
|
||||
r10_bio->state = 0;
|
||||
raise_barrier(conf, sectors_done != 0);
|
||||
atomic_set(&r10_bio->remaining, 0);
|
||||
r10_bio->mddev = mddev;
|
||||
|
@ -4398,6 +4402,7 @@ read_more:
|
|||
* on all the target devices.
|
||||
*/
|
||||
// FIXME
|
||||
mempool_free(r10_bio, conf->r10buf_pool);
|
||||
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||||
return sectors_done;
|
||||
}
|
||||
|
@ -4410,7 +4415,7 @@ read_more:
|
|||
read_bio->bi_private = r10_bio;
|
||||
read_bio->bi_end_io = end_sync_read;
|
||||
read_bio->bi_rw = READ;
|
||||
read_bio->bi_flags &= ~(BIO_POOL_MASK - 1);
|
||||
read_bio->bi_flags &= (~0UL << BIO_RESET_BITS);
|
||||
read_bio->bi_flags |= 1 << BIO_UPTODATE;
|
||||
read_bio->bi_vcnt = 0;
|
||||
read_bio->bi_iter.bi_size = 0;
|
||||
|
|
|
@ -2922,7 +2922,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s,
|
|||
(!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) &&
|
||||
!test_bit(R5_OVERWRITE, &fdev[0]->flags)) ||
|
||||
(sh->raid_conf->level == 6 && s->failed && s->to_write &&
|
||||
s->to_write < sh->raid_conf->raid_disks - 2 &&
|
||||
s->to_write - s->non_overwrite < sh->raid_conf->raid_disks - 2 &&
|
||||
(!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) {
|
||||
/* we would like to get this block, possibly by computing it,
|
||||
* otherwise read it if the backing disk is insync
|
||||
|
@ -3817,6 +3817,8 @@ static void handle_stripe(struct stripe_head *sh)
|
|||
set_bit(R5_Wantwrite, &dev->flags);
|
||||
if (prexor)
|
||||
continue;
|
||||
if (s.failed > 1)
|
||||
continue;
|
||||
if (!test_bit(R5_Insync, &dev->flags) ||
|
||||
((i == sh->pd_idx || i == sh->qd_idx) &&
|
||||
s.failed == 0))
|
||||
|
|
|
@ -280,7 +280,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
|
|||
|
||||
priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0)
|
||||
if (!priv->raminit_ctrlreg || priv->instance < 0)
|
||||
dev_info(&pdev->dev, "control memory is not used for raminit\n");
|
||||
else
|
||||
priv->raminit = c_can_hw_raminit_ti;
|
||||
|
|
|
@ -608,6 +608,13 @@ static void do_state(struct net_device *dev,
|
|||
|
||||
/* process state changes depending on the new state */
|
||||
switch (new_state) {
|
||||
case CAN_STATE_ERROR_WARNING:
|
||||
netdev_dbg(dev, "Error Warning\n");
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->data[1] = (bec.txerr > bec.rxerr) ?
|
||||
CAN_ERR_CRTL_TX_WARNING :
|
||||
CAN_ERR_CRTL_RX_WARNING;
|
||||
break;
|
||||
case CAN_STATE_ERROR_ACTIVE:
|
||||
netdev_dbg(dev, "Error Active\n");
|
||||
cf->can_id |= CAN_ERR_PROT;
|
||||
|
@ -911,6 +918,8 @@ static int flexcan_chip_start(struct net_device *dev)
|
|||
if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE ||
|
||||
priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
|
||||
reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
|
||||
else
|
||||
reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK;
|
||||
|
||||
/* save for later use */
|
||||
priv->reg_ctrl_default = reg_ctrl;
|
||||
|
|
|
@ -172,6 +172,35 @@ static void set_normal_mode(struct net_device *dev)
|
|||
netdev_err(dev, "setting SJA1000 into normal mode failed!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize SJA1000 chip:
|
||||
* - reset chip
|
||||
* - set output mode
|
||||
* - set baudrate
|
||||
* - enable interrupts
|
||||
* - start operating mode
|
||||
*/
|
||||
static void chipset_init(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* set clock divider and output control register */
|
||||
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
|
||||
|
||||
/* set acceptance filter (accept all) */
|
||||
priv->write_reg(priv, SJA1000_ACCC0, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC1, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC2, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC3, 0x00);
|
||||
|
||||
priv->write_reg(priv, SJA1000_ACCM0, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM1, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM2, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM3, 0xFF);
|
||||
|
||||
priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL);
|
||||
}
|
||||
|
||||
static void sja1000_start(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
@ -180,6 +209,10 @@ static void sja1000_start(struct net_device *dev)
|
|||
if (priv->can.state != CAN_STATE_STOPPED)
|
||||
set_reset_mode(dev);
|
||||
|
||||
/* Initialize chip if uninitialized at this stage */
|
||||
if (!(priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN))
|
||||
chipset_init(dev);
|
||||
|
||||
/* Clear error counters and error code capture */
|
||||
priv->write_reg(priv, SJA1000_TXERR, 0x0);
|
||||
priv->write_reg(priv, SJA1000_RXERR, 0x0);
|
||||
|
@ -236,35 +269,6 @@ static int sja1000_get_berr_counter(const struct net_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize SJA1000 chip:
|
||||
* - reset chip
|
||||
* - set output mode
|
||||
* - set baudrate
|
||||
* - enable interrupts
|
||||
* - start operating mode
|
||||
*/
|
||||
static void chipset_init(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* set clock divider and output control register */
|
||||
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
|
||||
|
||||
/* set acceptance filter (accept all) */
|
||||
priv->write_reg(priv, SJA1000_ACCC0, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC1, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC2, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC3, 0x00);
|
||||
|
||||
priv->write_reg(priv, SJA1000_ACCM0, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM1, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM2, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM3, 0xFF);
|
||||
|
||||
priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* transmit a CAN message
|
||||
* message layout in the sk_buff should be like this:
|
||||
|
|
|
@ -563,15 +563,21 @@ static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata)
|
|||
struct xgene_enet_desc_ring *ring;
|
||||
|
||||
ring = pdata->tx_ring;
|
||||
if (ring && ring->cp_ring && ring->cp_ring->cp_skb)
|
||||
devm_kfree(dev, ring->cp_ring->cp_skb);
|
||||
xgene_enet_free_desc_ring(ring);
|
||||
if (ring) {
|
||||
if (ring->cp_ring && ring->cp_ring->cp_skb)
|
||||
devm_kfree(dev, ring->cp_ring->cp_skb);
|
||||
xgene_enet_free_desc_ring(ring);
|
||||
}
|
||||
|
||||
ring = pdata->rx_ring;
|
||||
if (ring && ring->buf_pool && ring->buf_pool->rx_skb)
|
||||
devm_kfree(dev, ring->buf_pool->rx_skb);
|
||||
xgene_enet_free_desc_ring(ring->buf_pool);
|
||||
xgene_enet_free_desc_ring(ring);
|
||||
if (ring) {
|
||||
if (ring->buf_pool) {
|
||||
if (ring->buf_pool->rx_skb)
|
||||
devm_kfree(dev, ring->buf_pool->rx_skb);
|
||||
xgene_enet_free_desc_ring(ring->buf_pool);
|
||||
}
|
||||
xgene_enet_free_desc_ring(ring);
|
||||
}
|
||||
}
|
||||
|
||||
static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring(
|
||||
|
|
|
@ -483,11 +483,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
|
|||
|
||||
#ifdef BNX2X_STOP_ON_ERROR
|
||||
fp->tpa_queue_used |= (1 << queue);
|
||||
#ifdef _ASM_GENERIC_INT_L64_H
|
||||
DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n",
|
||||
#else
|
||||
DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n",
|
||||
#endif
|
||||
fp->tpa_queue_used);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -10123,6 +10123,8 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp,
|
|||
}
|
||||
|
||||
#define BNX2X_PREV_UNDI_PROD_ADDR(p) (BAR_TSTRORM_INTMEM + 0x1508 + ((p) << 4))
|
||||
#define BNX2X_PREV_UNDI_PROD_ADDR_H(f) (BAR_TSTRORM_INTMEM + \
|
||||
0x1848 + ((f) << 4))
|
||||
#define BNX2X_PREV_UNDI_RCQ(val) ((val) & 0xffff)
|
||||
#define BNX2X_PREV_UNDI_BD(val) ((val) >> 16 & 0xffff)
|
||||
#define BNX2X_PREV_UNDI_PROD(rcq, bd) ((bd) << 16 | (rcq))
|
||||
|
@ -10130,8 +10132,6 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp,
|
|||
#define BCM_5710_UNDI_FW_MF_MAJOR (0x07)
|
||||
#define BCM_5710_UNDI_FW_MF_MINOR (0x08)
|
||||
#define BCM_5710_UNDI_FW_MF_VERS (0x05)
|
||||
#define BNX2X_PREV_UNDI_MF_PORT(p) (BAR_TSTRORM_INTMEM + 0x150c + ((p) << 4))
|
||||
#define BNX2X_PREV_UNDI_MF_FUNC(f) (BAR_TSTRORM_INTMEM + 0x184c + ((f) << 4))
|
||||
|
||||
static bool bnx2x_prev_is_after_undi(struct bnx2x *bp)
|
||||
{
|
||||
|
@ -10150,72 +10150,25 @@ static bool bnx2x_prev_is_after_undi(struct bnx2x *bp)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool bnx2x_prev_unload_undi_fw_supports_mf(struct bnx2x *bp)
|
||||
{
|
||||
u8 major, minor, version;
|
||||
u32 fw;
|
||||
|
||||
/* Must check that FW is loaded */
|
||||
if (!(REG_RD(bp, MISC_REG_RESET_REG_1) &
|
||||
MISC_REGISTERS_RESET_REG_1_RST_XSEM)) {
|
||||
BNX2X_DEV_INFO("XSEM is reset - UNDI MF FW is not loaded\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Read Currently loaded FW version */
|
||||
fw = REG_RD(bp, XSEM_REG_PRAM);
|
||||
major = fw & 0xff;
|
||||
minor = (fw >> 0x8) & 0xff;
|
||||
version = (fw >> 0x10) & 0xff;
|
||||
BNX2X_DEV_INFO("Loaded FW: 0x%08x: Major 0x%02x Minor 0x%02x Version 0x%02x\n",
|
||||
fw, major, minor, version);
|
||||
|
||||
if (major > BCM_5710_UNDI_FW_MF_MAJOR)
|
||||
return true;
|
||||
|
||||
if ((major == BCM_5710_UNDI_FW_MF_MAJOR) &&
|
||||
(minor > BCM_5710_UNDI_FW_MF_MINOR))
|
||||
return true;
|
||||
|
||||
if ((major == BCM_5710_UNDI_FW_MF_MAJOR) &&
|
||||
(minor == BCM_5710_UNDI_FW_MF_MINOR) &&
|
||||
(version >= BCM_5710_UNDI_FW_MF_VERS))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void bnx2x_prev_unload_undi_mf(struct bnx2x *bp)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Due to legacy (FW) code, the first function on each engine has a
|
||||
* different offset macro from the rest of the functions.
|
||||
* Setting this for all 8 functions is harmless regardless of whether
|
||||
* this is actually a multi-function device.
|
||||
*/
|
||||
for (i = 0; i < 2; i++)
|
||||
REG_WR(bp, BNX2X_PREV_UNDI_MF_PORT(i), 1);
|
||||
|
||||
for (i = 2; i < 8; i++)
|
||||
REG_WR(bp, BNX2X_PREV_UNDI_MF_FUNC(i - 2), 1);
|
||||
|
||||
BNX2X_DEV_INFO("UNDI FW (MF) set to discard\n");
|
||||
}
|
||||
|
||||
static void bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 port, u8 inc)
|
||||
static void bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 inc)
|
||||
{
|
||||
u16 rcq, bd;
|
||||
u32 tmp_reg = REG_RD(bp, BNX2X_PREV_UNDI_PROD_ADDR(port));
|
||||
u32 addr, tmp_reg;
|
||||
|
||||
if (BP_FUNC(bp) < 2)
|
||||
addr = BNX2X_PREV_UNDI_PROD_ADDR(BP_PORT(bp));
|
||||
else
|
||||
addr = BNX2X_PREV_UNDI_PROD_ADDR_H(BP_FUNC(bp) - 2);
|
||||
|
||||
tmp_reg = REG_RD(bp, addr);
|
||||
rcq = BNX2X_PREV_UNDI_RCQ(tmp_reg) + inc;
|
||||
bd = BNX2X_PREV_UNDI_BD(tmp_reg) + inc;
|
||||
|
||||
tmp_reg = BNX2X_PREV_UNDI_PROD(rcq, bd);
|
||||
REG_WR(bp, BNX2X_PREV_UNDI_PROD_ADDR(port), tmp_reg);
|
||||
REG_WR(bp, addr, tmp_reg);
|
||||
|
||||
BNX2X_DEV_INFO("UNDI producer [%d] rings bd -> 0x%04x, rcq -> 0x%04x\n",
|
||||
port, bd, rcq);
|
||||
BNX2X_DEV_INFO("UNDI producer [%d/%d][%08x] rings bd -> 0x%04x, rcq -> 0x%04x\n",
|
||||
BP_PORT(bp), BP_FUNC(bp), addr, bd, rcq);
|
||||
}
|
||||
|
||||
static int bnx2x_prev_mcp_done(struct bnx2x *bp)
|
||||
|
@ -10454,7 +10407,6 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
|
|||
/* Reset should be performed after BRB is emptied */
|
||||
if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_BRB1) {
|
||||
u32 timer_count = 1000;
|
||||
bool need_write = true;
|
||||
|
||||
/* Close the MAC Rx to prevent BRB from filling up */
|
||||
bnx2x_prev_unload_close_mac(bp, &mac_vals);
|
||||
|
@ -10491,20 +10443,10 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
|
|||
else
|
||||
timer_count--;
|
||||
|
||||
/* New UNDI FW supports MF and contains better
|
||||
* cleaning methods - might be redundant but harmless.
|
||||
*/
|
||||
if (bnx2x_prev_unload_undi_fw_supports_mf(bp)) {
|
||||
if (need_write) {
|
||||
bnx2x_prev_unload_undi_mf(bp);
|
||||
need_write = false;
|
||||
}
|
||||
} else if (prev_undi) {
|
||||
/* If UNDI resides in memory,
|
||||
* manually increment it
|
||||
*/
|
||||
bnx2x_prev_unload_undi_inc(bp, BP_PORT(bp), 1);
|
||||
}
|
||||
/* If UNDI resides in memory, manually increment it */
|
||||
if (prev_undi)
|
||||
bnx2x_prev_unload_undi_inc(bp, 1);
|
||||
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
|
|
|
@ -652,6 +652,7 @@ struct adapter {
|
|||
struct tid_info tids;
|
||||
void **tid_release_head;
|
||||
spinlock_t tid_release_lock;
|
||||
struct workqueue_struct *workq;
|
||||
struct work_struct tid_release_task;
|
||||
struct work_struct db_full_task;
|
||||
struct work_struct db_drop_task;
|
||||
|
|
|
@ -643,8 +643,6 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct workqueue_struct *workq;
|
||||
|
||||
/**
|
||||
* link_start - enable a port
|
||||
* @dev: the port to enable
|
||||
|
@ -3340,7 +3338,7 @@ static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
|
|||
adap->tid_release_head = (void **)((uintptr_t)p | chan);
|
||||
if (!adap->tid_release_task_busy) {
|
||||
adap->tid_release_task_busy = true;
|
||||
queue_work(workq, &adap->tid_release_task);
|
||||
queue_work(adap->workq, &adap->tid_release_task);
|
||||
}
|
||||
spin_unlock_bh(&adap->tid_release_lock);
|
||||
}
|
||||
|
@ -4140,7 +4138,7 @@ void t4_db_full(struct adapter *adap)
|
|||
notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL);
|
||||
t4_set_reg_field(adap, SGE_INT_ENABLE3,
|
||||
DBFIFO_HP_INT | DBFIFO_LP_INT, 0);
|
||||
queue_work(workq, &adap->db_full_task);
|
||||
queue_work(adap->workq, &adap->db_full_task);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4150,7 +4148,7 @@ void t4_db_dropped(struct adapter *adap)
|
|||
disable_dbs(adap);
|
||||
notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL);
|
||||
}
|
||||
queue_work(workq, &adap->db_drop_task);
|
||||
queue_work(adap->workq, &adap->db_drop_task);
|
||||
}
|
||||
|
||||
static void uld_attach(struct adapter *adap, unsigned int uld)
|
||||
|
@ -6517,6 +6515,12 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
goto out_disable_device;
|
||||
}
|
||||
|
||||
adapter->workq = create_singlethread_workqueue("cxgb4");
|
||||
if (!adapter->workq) {
|
||||
err = -ENOMEM;
|
||||
goto out_free_adapter;
|
||||
}
|
||||
|
||||
/* PCI device has been enabled */
|
||||
adapter->flags |= DEV_ENABLED;
|
||||
|
||||
|
@ -6715,6 +6719,9 @@ sriov:
|
|||
out_unmap_bar0:
|
||||
iounmap(adapter->regs);
|
||||
out_free_adapter:
|
||||
if (adapter->workq)
|
||||
destroy_workqueue(adapter->workq);
|
||||
|
||||
kfree(adapter);
|
||||
out_disable_device:
|
||||
pci_disable_pcie_error_reporting(pdev);
|
||||
|
@ -6736,6 +6743,11 @@ static void remove_one(struct pci_dev *pdev)
|
|||
if (adapter) {
|
||||
int i;
|
||||
|
||||
/* Tear down per-adapter Work Queue first since it can contain
|
||||
* references to our adapter data structure.
|
||||
*/
|
||||
destroy_workqueue(adapter->workq);
|
||||
|
||||
if (is_offload(adapter))
|
||||
detach_ulds(adapter);
|
||||
|
||||
|
@ -6788,20 +6800,14 @@ static int __init cxgb4_init_module(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
workq = create_singlethread_workqueue("cxgb4");
|
||||
if (!workq)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Debugfs support is optional, just warn if this fails */
|
||||
cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
|
||||
if (!cxgb4_debugfs_root)
|
||||
pr_warn("could not create debugfs entry, continuing\n");
|
||||
|
||||
ret = pci_register_driver(&cxgb4_driver);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
debugfs_remove(cxgb4_debugfs_root);
|
||||
destroy_workqueue(workq);
|
||||
}
|
||||
|
||||
register_inet6addr_notifier(&cxgb4_inet6addr_notifier);
|
||||
|
||||
|
@ -6813,8 +6819,6 @@ static void __exit cxgb4_cleanup_module(void)
|
|||
unregister_inet6addr_notifier(&cxgb4_inet6addr_notifier);
|
||||
pci_unregister_driver(&cxgb4_driver);
|
||||
debugfs_remove(cxgb4_debugfs_root); /* NULL ok */
|
||||
flush_workqueue(workq);
|
||||
destroy_workqueue(workq);
|
||||
}
|
||||
|
||||
module_init(cxgb4_init_module);
|
||||
|
|
|
@ -2303,7 +2303,8 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
|
|||
FW_EQ_ETH_CMD_PFN(adap->fn) | FW_EQ_ETH_CMD_VFN(0));
|
||||
c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC |
|
||||
FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c));
|
||||
c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid));
|
||||
c.viid_pkd = htonl(FW_EQ_ETH_CMD_AUTOEQUEQE |
|
||||
FW_EQ_ETH_CMD_VIID(pi->viid));
|
||||
c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) |
|
||||
FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) |
|
||||
FW_EQ_ETH_CMD_FETCHRO(1) |
|
||||
|
|
|
@ -1227,6 +1227,7 @@ struct fw_eq_eth_cmd {
|
|||
#define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16)
|
||||
#define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0)
|
||||
|
||||
#define FW_EQ_ETH_CMD_AUTOEQUEQE (1U << 30)
|
||||
#define FW_EQ_ETH_CMD_VIID(x) ((x) << 16)
|
||||
|
||||
struct fw_eq_ctrl_cmd {
|
||||
|
|
|
@ -2250,7 +2250,8 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq,
|
|||
cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC |
|
||||
FW_EQ_ETH_CMD_EQSTART |
|
||||
FW_LEN16(cmd));
|
||||
cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_VIID(pi->viid));
|
||||
cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_AUTOEQUEQE |
|
||||
FW_EQ_ETH_CMD_VIID(pi->viid));
|
||||
cmd.fetchszm_to_iqid =
|
||||
cpu_to_be32(FW_EQ_ETH_CMD_HOSTFCMODE(SGE_HOSTFCMODE_STPG) |
|
||||
FW_EQ_ETH_CMD_PCIECHN(pi->port_id) |
|
||||
|
|
|
@ -275,6 +275,9 @@ struct fec_enet_private {
|
|||
struct clk *clk_enet_out;
|
||||
struct clk *clk_ptp;
|
||||
|
||||
bool ptp_clk_on;
|
||||
struct mutex ptp_clk_mutex;
|
||||
|
||||
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
|
||||
unsigned char *tx_bounce[TX_RING_SIZE];
|
||||
struct sk_buff *tx_skbuff[TX_RING_SIZE];
|
||||
|
@ -335,7 +338,7 @@ struct fec_enet_private {
|
|||
u32 cycle_speed;
|
||||
int hwts_rx_en;
|
||||
int hwts_tx_en;
|
||||
struct timer_list time_keep;
|
||||
struct delayed_work time_keep;
|
||||
struct regulator *reg_phy;
|
||||
};
|
||||
|
||||
|
|
|
@ -1611,17 +1611,27 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
|
|||
goto failed_clk_enet_out;
|
||||
}
|
||||
if (fep->clk_ptp) {
|
||||
mutex_lock(&fep->ptp_clk_mutex);
|
||||
ret = clk_prepare_enable(fep->clk_ptp);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
mutex_unlock(&fep->ptp_clk_mutex);
|
||||
goto failed_clk_ptp;
|
||||
} else {
|
||||
fep->ptp_clk_on = true;
|
||||
}
|
||||
mutex_unlock(&fep->ptp_clk_mutex);
|
||||
}
|
||||
} else {
|
||||
clk_disable_unprepare(fep->clk_ahb);
|
||||
clk_disable_unprepare(fep->clk_ipg);
|
||||
if (fep->clk_enet_out)
|
||||
clk_disable_unprepare(fep->clk_enet_out);
|
||||
if (fep->clk_ptp)
|
||||
if (fep->clk_ptp) {
|
||||
mutex_lock(&fep->ptp_clk_mutex);
|
||||
clk_disable_unprepare(fep->clk_ptp);
|
||||
fep->ptp_clk_on = false;
|
||||
mutex_unlock(&fep->ptp_clk_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2625,6 +2635,8 @@ fec_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(fep->clk_enet_out))
|
||||
fep->clk_enet_out = NULL;
|
||||
|
||||
fep->ptp_clk_on = false;
|
||||
mutex_init(&fep->ptp_clk_mutex);
|
||||
fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
|
||||
fep->bufdesc_ex =
|
||||
pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX;
|
||||
|
@ -2715,10 +2727,10 @@ fec_drv_remove(struct platform_device *pdev)
|
|||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||
|
||||
cancel_delayed_work_sync(&fep->time_keep);
|
||||
cancel_work_sync(&fep->tx_timeout_work);
|
||||
unregister_netdev(ndev);
|
||||
fec_enet_mii_remove(fep);
|
||||
del_timer_sync(&fep->time_keep);
|
||||
if (fep->reg_phy)
|
||||
regulator_disable(fep->reg_phy);
|
||||
if (fep->ptp_clock)
|
||||
|
|
|
@ -245,12 +245,20 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
|
|||
u64 ns;
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&fep->ptp_clk_mutex);
|
||||
/* Check the ptp clock */
|
||||
if (!fep->ptp_clk_on) {
|
||||
mutex_unlock(&fep->ptp_clk_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ns = ts->tv_sec * 1000000000ULL;
|
||||
ns += ts->tv_nsec;
|
||||
|
||||
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
||||
timecounter_init(&fep->tc, &fep->cc, ns);
|
||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
||||
mutex_unlock(&fep->ptp_clk_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -338,17 +346,22 @@ int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr)
|
|||
* fec_time_keep - call timecounter_read every second to avoid timer overrun
|
||||
* because ENET just support 32bit counter, will timeout in 4s
|
||||
*/
|
||||
static void fec_time_keep(unsigned long _data)
|
||||
static void fec_time_keep(struct work_struct *work)
|
||||
{
|
||||
struct fec_enet_private *fep = (struct fec_enet_private *)_data;
|
||||
struct delayed_work *dwork = to_delayed_work(work);
|
||||
struct fec_enet_private *fep = container_of(dwork, struct fec_enet_private, time_keep);
|
||||
u64 ns;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
||||
ns = timecounter_read(&fep->tc);
|
||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
||||
mutex_lock(&fep->ptp_clk_mutex);
|
||||
if (fep->ptp_clk_on) {
|
||||
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
||||
ns = timecounter_read(&fep->tc);
|
||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
||||
}
|
||||
mutex_unlock(&fep->ptp_clk_mutex);
|
||||
|
||||
mod_timer(&fep->time_keep, jiffies + HZ);
|
||||
schedule_delayed_work(&fep->time_keep, HZ);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -386,15 +399,13 @@ void fec_ptp_init(struct platform_device *pdev)
|
|||
|
||||
fec_ptp_start_cyclecounter(ndev);
|
||||
|
||||
init_timer(&fep->time_keep);
|
||||
fep->time_keep.data = (unsigned long)fep;
|
||||
fep->time_keep.function = fec_time_keep;
|
||||
fep->time_keep.expires = jiffies + HZ;
|
||||
add_timer(&fep->time_keep);
|
||||
INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep);
|
||||
|
||||
fep->ptp_clock = ptp_clock_register(&fep->ptp_caps, &pdev->dev);
|
||||
if (IS_ERR(fep->ptp_clock)) {
|
||||
fep->ptp_clock = NULL;
|
||||
pr_err("ptp_clock_register failed\n");
|
||||
}
|
||||
|
||||
schedule_delayed_work(&fep->time_keep, HZ);
|
||||
}
|
||||
|
|
|
@ -292,6 +292,18 @@ failure:
|
|||
atomic_add(buffers_added, &(pool->available));
|
||||
}
|
||||
|
||||
/*
|
||||
* The final 8 bytes of the buffer list is a counter of frames dropped
|
||||
* because there was not a buffer in the buffer list capable of holding
|
||||
* the frame.
|
||||
*/
|
||||
static void ibmveth_update_rx_no_buffer(struct ibmveth_adapter *adapter)
|
||||
{
|
||||
__be64 *p = adapter->buffer_list_addr + 4096 - 8;
|
||||
|
||||
adapter->rx_no_buffer = be64_to_cpup(p);
|
||||
}
|
||||
|
||||
/* replenish routine */
|
||||
static void ibmveth_replenish_task(struct ibmveth_adapter *adapter)
|
||||
{
|
||||
|
@ -307,8 +319,7 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter)
|
|||
ibmveth_replenish_buffer_pool(adapter, pool);
|
||||
}
|
||||
|
||||
adapter->rx_no_buffer = *(u64 *)(((char*)adapter->buffer_list_addr) +
|
||||
4096 - 8);
|
||||
ibmveth_update_rx_no_buffer(adapter);
|
||||
}
|
||||
|
||||
/* empty and free ana buffer pool - also used to do cleanup in error paths */
|
||||
|
@ -698,8 +709,7 @@ static int ibmveth_close(struct net_device *netdev)
|
|||
|
||||
free_irq(netdev->irq, netdev);
|
||||
|
||||
adapter->rx_no_buffer = *(u64 *)(((char *)adapter->buffer_list_addr) +
|
||||
4096 - 8);
|
||||
ibmveth_update_rx_no_buffer(adapter);
|
||||
|
||||
ibmveth_cleanup(adapter);
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi)
|
|||
u32 prttsyn_stat;
|
||||
int n;
|
||||
|
||||
if (pf->flags & I40E_FLAG_PTP)
|
||||
if (!(pf->flags & I40E_FLAG_PTP))
|
||||
return;
|
||||
|
||||
prttsyn_stat = rd32(hw, I40E_PRTTSYN_STAT_1);
|
||||
|
|
|
@ -1003,11 +1003,19 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
|
|||
static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode,
|
||||
u32 v_retval, u8 *msg, u16 msglen)
|
||||
{
|
||||
struct i40e_pf *pf = vf->pf;
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
||||
struct i40e_pf *pf;
|
||||
struct i40e_hw *hw;
|
||||
int abs_vf_id;
|
||||
i40e_status aq_ret;
|
||||
|
||||
/* validate the request */
|
||||
if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs)
|
||||
return -EINVAL;
|
||||
|
||||
pf = vf->pf;
|
||||
hw = &pf->hw;
|
||||
abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
||||
|
||||
/* single place to detect unsuccessful return values */
|
||||
if (v_retval) {
|
||||
vf->num_invalid_msgs++;
|
||||
|
@ -1928,17 +1936,20 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
|
|||
{
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
struct i40e_vf *vf = pf->vf;
|
||||
int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pf->num_alloc_vfs; i++) {
|
||||
for (i = 0; i < pf->num_alloc_vfs; i++, vf++) {
|
||||
int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
||||
/* Not all vfs are enabled so skip the ones that are not */
|
||||
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
|
||||
!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
|
||||
continue;
|
||||
|
||||
/* Ignore return value on purpose - a given VF may fail, but
|
||||
* we need to keep going and send to all of them
|
||||
*/
|
||||
i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval,
|
||||
msg, msglen, NULL);
|
||||
vf++;
|
||||
abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1954,12 +1965,12 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf)
|
|||
struct i40e_hw *hw = &pf->hw;
|
||||
struct i40e_vf *vf = pf->vf;
|
||||
struct i40e_link_status *ls = &pf->hw.phy.link_info;
|
||||
int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
||||
int i;
|
||||
|
||||
pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
|
||||
pfe.severity = I40E_PF_EVENT_SEVERITY_INFO;
|
||||
for (i = 0; i < pf->num_alloc_vfs; i++) {
|
||||
for (i = 0; i < pf->num_alloc_vfs; i++, vf++) {
|
||||
int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
||||
if (vf->link_forced) {
|
||||
pfe.event_data.link_event.link_status = vf->link_up;
|
||||
pfe.event_data.link_event.link_speed =
|
||||
|
@ -1972,8 +1983,6 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf)
|
|||
i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
|
||||
0, (u8 *)&pfe, sizeof(pfe),
|
||||
NULL);
|
||||
vf++;
|
||||
abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2002,7 +2011,18 @@ void i40e_vc_notify_reset(struct i40e_pf *pf)
|
|||
void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
|
||||
{
|
||||
struct i40e_virtchnl_pf_event pfe;
|
||||
int abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id;
|
||||
int abs_vf_id;
|
||||
|
||||
/* validate the request */
|
||||
if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs)
|
||||
return;
|
||||
|
||||
/* verify if the VF is in either init or active before proceeding */
|
||||
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
|
||||
!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
|
||||
return;
|
||||
|
||||
abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id;
|
||||
|
||||
pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
|
||||
pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
|
||||
|
|
|
@ -268,7 +268,7 @@ struct qlcnic_fdt {
|
|||
u16 cksum;
|
||||
u16 unused;
|
||||
u8 model[16];
|
||||
u16 mfg_id;
|
||||
u8 mfg_id;
|
||||
u16 id;
|
||||
u8 flag;
|
||||
u8 erase_cmd;
|
||||
|
@ -2362,6 +2362,19 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter)
|
|||
return QLC_DEFAULT_VNIC_COUNT;
|
||||
}
|
||||
|
||||
static inline void qlcnic_swap32_buffer(u32 *buffer, int count)
|
||||
{
|
||||
#if defined(__BIG_ENDIAN)
|
||||
u32 *tmp = buffer;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
*tmp = swab32(*tmp);
|
||||
tmp++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QLCNIC_HWMON
|
||||
void qlcnic_register_hwmon_dev(struct qlcnic_adapter *);
|
||||
void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue