Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Cross-merge networking fixes after downstream PR.

No conflicts, no adjacent changes.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2024-06-13 13:13:38 -07:00
commit 4c7d3d79c7
229 changed files with 2295 additions and 1362 deletions

View File

@ -72,6 +72,8 @@ Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com>
Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com>
André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com> André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com>
Andy Adamson <andros@citi.umich.edu> Andy Adamson <andros@citi.umich.edu>
Andy Shevchenko <andy@kernel.org> <andy@smile.org.ua>
Andy Shevchenko <andy@kernel.org> <ext-andriy.shevchenko@nokia.com>
Anilkumar Kolli <quic_akolli@quicinc.com> <akolli@codeaurora.org> Anilkumar Kolli <quic_akolli@quicinc.com> <akolli@codeaurora.org>
Anirudh Ghayal <quic_aghayal@quicinc.com> <aghayal@codeaurora.org> Anirudh Ghayal <quic_aghayal@quicinc.com> <aghayal@codeaurora.org>
Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com> Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com>
@ -217,6 +219,7 @@ Geliang Tang <geliang@kernel.org> <geliang.tang@suse.com>
Geliang Tang <geliang@kernel.org> <geliangtang@xiaomi.com> Geliang Tang <geliang@kernel.org> <geliangtang@xiaomi.com>
Geliang Tang <geliang@kernel.org> <geliangtang@gmail.com> Geliang Tang <geliang@kernel.org> <geliangtang@gmail.com>
Geliang Tang <geliang@kernel.org> <geliangtang@163.com> Geliang Tang <geliang@kernel.org> <geliangtang@163.com>
Geliang Tang <geliang@kernel.org> <tanggeliang@kylinos.cn>
Georgi Djakov <djakov@kernel.org> <georgi.djakov@linaro.org> Georgi Djakov <djakov@kernel.org> <georgi.djakov@linaro.org>
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com> Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com>
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com> Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>

View File

@ -467,11 +467,11 @@ anon_fault_fallback_charge
instead falls back to using huge pages with lower orders or instead falls back to using huge pages with lower orders or
small pages even though the allocation was successful. small pages even though the allocation was successful.
anon_swpout swpout
is incremented every time a huge page is swapped out in one is incremented every time a huge page is swapped out in one
piece without splitting. piece without splitting.
anon_swpout_fallback swpout_fallback
is incremented if a huge page has to be split before swapout. is incremented if a huge page has to be split before swapout.
Usually because failed to allocate some continuous swap space Usually because failed to allocate some continuous swap space
for the huge page. for the huge page.

View File

@ -217,7 +217,7 @@ current *struct* is::
int (*media_changed)(struct cdrom_device_info *, int); int (*media_changed)(struct cdrom_device_info *, int);
int (*tray_move)(struct cdrom_device_info *, int); int (*tray_move)(struct cdrom_device_info *, int);
int (*lock_door)(struct cdrom_device_info *, int); int (*lock_door)(struct cdrom_device_info *, int);
int (*select_speed)(struct cdrom_device_info *, int); int (*select_speed)(struct cdrom_device_info *, unsigned long);
int (*get_last_session) (struct cdrom_device_info *, int (*get_last_session) (struct cdrom_device_info *,
struct cdrom_multisession *); struct cdrom_multisession *);
int (*get_mcn)(struct cdrom_device_info *, struct cdrom_mcn *); int (*get_mcn)(struct cdrom_device_info *, struct cdrom_mcn *);
@ -396,7 +396,7 @@ action need be taken, and the return value should be 0.
:: ::
int select_speed(struct cdrom_device_info *cdi, int speed) int select_speed(struct cdrom_device_info *cdi, unsigned long speed)
Some CD-ROM drives are capable of changing their head-speed. There Some CD-ROM drives are capable of changing their head-speed. There
are several reasons for changing the speed of a CD-ROM drive. Badly are several reasons for changing the speed of a CD-ROM drive. Badly

View File

@ -18,9 +18,12 @@ allOf:
properties: properties:
compatible: compatible:
enum: oneOf:
- elan,ekth6915 - items:
- ilitek,ili2901 - enum:
- elan,ekth5015m
- const: elan,ekth6915
- const: elan,ekth6915
reg: reg:
const: 0x10 const: 0x10
@ -33,6 +36,12 @@ properties:
reset-gpios: reset-gpios:
description: Reset GPIO; not all touchscreens using eKTH6915 hook this up. description: Reset GPIO; not all touchscreens using eKTH6915 hook this up.
no-reset-on-power-off:
type: boolean
description:
Reset line is wired so that it can (and should) be left deasserted when
the power supply is off.
vcc33-supply: vcc33-supply:
description: The 3.3V supply to the touchscreen. description: The 3.3V supply to the touchscreen.
@ -58,8 +67,8 @@ examples:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
ap_ts: touchscreen@10 { touchscreen@10 {
compatible = "elan,ekth6915"; compatible = "elan,ekth5015m", "elan,ekth6915";
reg = <0x10>; reg = <0x10>;
interrupt-parent = <&tlmm>; interrupt-parent = <&tlmm>;

View File

@ -0,0 +1,66 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/ilitek,ili2901.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Ilitek ILI2901 touchscreen controller
maintainers:
- Jiri Kosina <jkosina@suse.com>
description:
Supports the Ilitek ILI2901 touchscreen controller.
This touchscreen controller uses the i2c-hid protocol with a reset GPIO.
allOf:
- $ref: /schemas/input/touchscreen/touchscreen.yaml#
properties:
compatible:
enum:
- ilitek,ili2901
reg:
maxItems: 1
interrupts:
maxItems: 1
panel: true
reset-gpios:
maxItems: 1
vcc33-supply: true
vccio-supply: true
required:
- compatible
- reg
- interrupts
- vcc33-supply
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
touchscreen@41 {
compatible = "ilitek,ili2901";
reg = <0x41>;
interrupt-parent = <&tlmm>;
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
vcc33-supply = <&pp3300_ts>;
};
};

View File

@ -150,6 +150,12 @@ applicable everywhere (see syntax).
That will limit the usefulness but on the other hand avoid That will limit the usefulness but on the other hand avoid
the illegal configurations all over. the illegal configurations all over.
If "select" <symbol> is followed by "if" <expr>, <symbol> will be
selected by the logical AND of the value of the current menu symbol
and <expr>. This means, the lower limit can be downgraded due to the
presence of "if" <expr>. This behavior may seem weird, but we rely on
it. (The future of this behavior is undecided.)
- weak reverse dependencies: "imply" <symbol> ["if" <expr>] - weak reverse dependencies: "imply" <symbol> ["if" <expr>]
This is similar to "select" as it enforces a lower limit on another This is similar to "select" as it enforces a lower limit on another
@ -184,7 +190,7 @@ applicable everywhere (see syntax).
ability to hook into a secondary subsystem while allowing the user to ability to hook into a secondary subsystem while allowing the user to
configure that subsystem out without also having to unset these drivers. configure that subsystem out without also having to unset these drivers.
Note: If the combination of FOO=y and BAR=m causes a link error, Note: If the combination of FOO=y and BAZ=m causes a link error,
you can guard the function call with IS_REACHABLE():: you can guard the function call with IS_REACHABLE()::
foo_init() foo_init()
@ -202,6 +208,10 @@ applicable everywhere (see syntax).
imply BAR imply BAR
imply BAZ imply BAZ
Note: If "imply" <symbol> is followed by "if" <expr>, the default of <symbol>
will be the logical AND of the value of the current menu symbol and <expr>.
(The future of this behavior is undecided.)
- limiting menu display: "visible if" <expr> - limiting menu display: "visible if" <expr>
This attribute is only applicable to menu blocks, if the condition is This attribute is only applicable to menu blocks, if the condition is

View File

@ -582,7 +582,7 @@ depending on the hardware. In all cases, however, only routes that have the
Devices generating the streams may allow enabling and disabling some of the Devices generating the streams may allow enabling and disabling some of the
routes or have a fixed routing configuration. If the routes can be disabled, not routes or have a fixed routing configuration. If the routes can be disabled, not
declaring the routes (or declaring them without declaring the routes (or declaring them without
``VIDIOC_SUBDEV_STREAM_FL_ACTIVE`` flag set) in ``VIDIOC_SUBDEV_S_ROUTING`` will ``V4L2_SUBDEV_STREAM_FL_ACTIVE`` flag set) in ``VIDIOC_SUBDEV_S_ROUTING`` will
disable the routes. ``VIDIOC_SUBDEV_S_ROUTING`` will still return such routes disable the routes. ``VIDIOC_SUBDEV_S_ROUTING`` will still return such routes
back to the user in the routes array, with the ``V4L2_SUBDEV_STREAM_FL_ACTIVE`` back to the user in the routes array, with the ``V4L2_SUBDEV_STREAM_FL_ACTIVE``
flag unset. flag unset.

View File

@ -15825,7 +15825,7 @@ F: drivers/nfc/virtual_ncidev.c
F: tools/testing/selftests/nci/ F: tools/testing/selftests/nci/
NFS, SUNRPC, AND LOCKD CLIENTS NFS, SUNRPC, AND LOCKD CLIENTS
M: Trond Myklebust <trond.myklebust@hammerspace.com> M: Trond Myklebust <trondmy@kernel.org>
M: Anna Schumaker <anna@kernel.org> M: Anna Schumaker <anna@kernel.org>
L: linux-nfs@vger.kernel.org L: linux-nfs@vger.kernel.org
S: Maintained S: Maintained

View File

@ -2,7 +2,7 @@
VERSION = 6 VERSION = 6
PATCHLEVEL = 10 PATCHLEVEL = 10
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc2 EXTRAVERSION = -rc3
NAME = Baby Opossum Posse NAME = Baby Opossum Posse
# *DOCUMENTATION* # *DOCUMENTATION*

View File

@ -232,11 +232,24 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
unsigned long old; unsigned long old;
if (unlikely(atomic_read(&current->tracing_graph_pause))) if (unlikely(atomic_read(&current->tracing_graph_pause)))
err_out:
return; return;
if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) { if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) {
/* FP points one word below parent's top of stack */ /*
frame_pointer += 4; * Usually, the stack frames are contiguous in memory but cases
* have been observed where the next stack frame does not live
* at 'frame_pointer + 4' as this code used to assume.
*
* Instead, dereference the field in the stack frame that
* stores the SP of the calling frame: to avoid unbounded
* recursion, this cannot involve any ftrace instrumented
* functions, so use the __get_kernel_nofault() primitive
* directly.
*/
__get_kernel_nofault(&frame_pointer,
(unsigned long *)(frame_pointer - 8),
unsigned long, err_out);
} else { } else {
struct stackframe frame = { struct stackframe frame = {
.fp = frame_pointer, .fp = frame_pointer,

View File

@ -153,8 +153,9 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
* emit the large TLP from the CPU. * emit the large TLP from the CPU.
*/ */
static inline void __const_memcpy_toio_aligned32(volatile u32 __iomem *to, static __always_inline void
const u32 *from, size_t count) __const_memcpy_toio_aligned32(volatile u32 __iomem *to, const u32 *from,
size_t count)
{ {
switch (count) { switch (count) {
case 8: case 8:
@ -196,24 +197,22 @@ static inline void __const_memcpy_toio_aligned32(volatile u32 __iomem *to,
void __iowrite32_copy_full(void __iomem *to, const void *from, size_t count); void __iowrite32_copy_full(void __iomem *to, const void *from, size_t count);
static inline void __const_iowrite32_copy(void __iomem *to, const void *from, static __always_inline void
size_t count) __iowrite32_copy(void __iomem *to, const void *from, size_t count)
{ {
if (count == 8 || count == 4 || count == 2 || count == 1) { if (__builtin_constant_p(count) &&
(count == 8 || count == 4 || count == 2 || count == 1)) {
__const_memcpy_toio_aligned32(to, from, count); __const_memcpy_toio_aligned32(to, from, count);
dgh(); dgh();
} else { } else {
__iowrite32_copy_full(to, from, count); __iowrite32_copy_full(to, from, count);
} }
} }
#define __iowrite32_copy __iowrite32_copy
#define __iowrite32_copy(to, from, count) \ static __always_inline void
(__builtin_constant_p(count) ? \ __const_memcpy_toio_aligned64(volatile u64 __iomem *to, const u64 *from,
__const_iowrite32_copy(to, from, count) : \ size_t count)
__iowrite32_copy_full(to, from, count))
static inline void __const_memcpy_toio_aligned64(volatile u64 __iomem *to,
const u64 *from, size_t count)
{ {
switch (count) { switch (count) {
case 8: case 8:
@ -255,21 +254,18 @@ static inline void __const_memcpy_toio_aligned64(volatile u64 __iomem *to,
void __iowrite64_copy_full(void __iomem *to, const void *from, size_t count); void __iowrite64_copy_full(void __iomem *to, const void *from, size_t count);
static inline void __const_iowrite64_copy(void __iomem *to, const void *from, static __always_inline void
size_t count) __iowrite64_copy(void __iomem *to, const void *from, size_t count)
{ {
if (count == 8 || count == 4 || count == 2 || count == 1) { if (__builtin_constant_p(count) &&
(count == 8 || count == 4 || count == 2 || count == 1)) {
__const_memcpy_toio_aligned64(to, from, count); __const_memcpy_toio_aligned64(to, from, count);
dgh(); dgh();
} else { } else {
__iowrite64_copy_full(to, from, count); __iowrite64_copy_full(to, from, count);
} }
} }
#define __iowrite64_copy __iowrite64_copy
#define __iowrite64_copy(to, from, count) \
(__builtin_constant_p(count) ? \
__const_iowrite64_copy(to, from, count) : \
__iowrite64_copy_full(to, from, count))
/* /*
* I/O memory mapping functions. * I/O memory mapping functions.

View File

@ -462,6 +462,9 @@ static int run_all_insn_set_hw_mode(unsigned int cpu)
for (int i = 0; i < ARRAY_SIZE(insn_emulations); i++) { for (int i = 0; i < ARRAY_SIZE(insn_emulations); i++) {
struct insn_emulation *insn = insn_emulations[i]; struct insn_emulation *insn = insn_emulations[i];
bool enable = READ_ONCE(insn->current_mode) == INSN_HW; bool enable = READ_ONCE(insn->current_mode) == INSN_HW;
if (insn->status == INSN_UNAVAILABLE)
continue;
if (insn->set_hw_mode && insn->set_hw_mode(enable)) { if (insn->set_hw_mode && insn->set_hw_mode(enable)) {
pr_warn("CPU[%u] cannot support the emulation of %s", pr_warn("CPU[%u] cannot support the emulation of %s",
cpu, insn->name); cpu, insn->name);

View File

@ -376,7 +376,7 @@ void contpte_clear_young_dirty_ptes(struct vm_area_struct *vma,
* clearing access/dirty for the whole block. * clearing access/dirty for the whole block.
*/ */
unsigned long start = addr; unsigned long start = addr;
unsigned long end = start + nr; unsigned long end = start + nr * PAGE_SIZE;
if (pte_cont(__ptep_get(ptep + nr - 1))) if (pte_cont(__ptep_get(ptep + nr - 1)))
end = ALIGN(end, CONT_PTE_SIZE); end = ALIGN(end, CONT_PTE_SIZE);
@ -386,7 +386,7 @@ void contpte_clear_young_dirty_ptes(struct vm_area_struct *vma,
ptep = contpte_align_down(ptep); ptep = contpte_align_down(ptep);
} }
__clear_young_dirty_ptes(vma, start, ptep, end - start, flags); __clear_young_dirty_ptes(vma, start, ptep, (end - start) / PAGE_SIZE, flags);
} }
EXPORT_SYMBOL_GPL(contpte_clear_young_dirty_ptes); EXPORT_SYMBOL_GPL(contpte_clear_young_dirty_ptes);

View File

@ -293,8 +293,8 @@ void handle_page_fault(struct pt_regs *regs)
if (unlikely(access_error(cause, vma))) { if (unlikely(access_error(cause, vma))) {
vma_end_read(vma); vma_end_read(vma);
count_vm_vma_lock_event(VMA_LOCK_SUCCESS); count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
tsk->thread.bad_cause = SEGV_ACCERR; tsk->thread.bad_cause = cause;
bad_area_nosemaphore(regs, code, addr); bad_area_nosemaphore(regs, SEGV_ACCERR, addr);
return; return;
} }

View File

@ -250,18 +250,19 @@ static void __init setup_bootmem(void)
kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base; kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base;
/* /*
* memblock allocator is not aware of the fact that last 4K bytes of * Reserve physical address space that would be mapped to virtual
* the addressable memory can not be mapped because of IS_ERR_VALUE * addresses greater than (void *)(-PAGE_SIZE) because:
* macro. Make sure that last 4k bytes are not usable by memblock * - This memory would overlap with ERR_PTR
* if end of dram is equal to maximum addressable memory. For 64-bit * - This memory belongs to high memory, which is not supported
* kernel, this problem can't happen here as the end of the virtual *
* address space is occupied by the kernel mapping then this check must * This is not applicable to 64-bit kernel, because virtual addresses
* be done as soon as the kernel mapping base address is determined. * after (void *)(-PAGE_SIZE) are not linearly mapped: they are
* occupied by kernel mapping. Also it is unrealistic for high memory
* to exist on 64-bit platforms.
*/ */
if (!IS_ENABLED(CONFIG_64BIT)) { if (!IS_ENABLED(CONFIG_64BIT)) {
max_mapped_addr = __pa(~(ulong)0); max_mapped_addr = __va_to_pa_nodebug(-PAGE_SIZE);
if (max_mapped_addr == (phys_ram_end - 1)) memblock_reserve(max_mapped_addr, (phys_addr_t)-max_mapped_addr);
memblock_set_current_limit(max_mapped_addr - 4096);
} }
min_low_pfn = PFN_UP(phys_ram_base); min_low_pfn = PFN_UP(phys_ram_base);

View File

@ -451,7 +451,7 @@ static void *nt_final(void *ptr)
/* /*
* Initialize ELF header (new kernel) * Initialize ELF header (new kernel)
*/ */
static void *ehdr_init(Elf64_Ehdr *ehdr, int mem_chunk_cnt) static void *ehdr_init(Elf64_Ehdr *ehdr, int phdr_count)
{ {
memset(ehdr, 0, sizeof(*ehdr)); memset(ehdr, 0, sizeof(*ehdr));
memcpy(ehdr->e_ident, ELFMAG, SELFMAG); memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
@ -465,11 +465,8 @@ static void *ehdr_init(Elf64_Ehdr *ehdr, int mem_chunk_cnt)
ehdr->e_phoff = sizeof(Elf64_Ehdr); ehdr->e_phoff = sizeof(Elf64_Ehdr);
ehdr->e_ehsize = sizeof(Elf64_Ehdr); ehdr->e_ehsize = sizeof(Elf64_Ehdr);
ehdr->e_phentsize = sizeof(Elf64_Phdr); ehdr->e_phentsize = sizeof(Elf64_Phdr);
/* /* Number of PT_LOAD program headers plus PT_NOTE program header */
* Number of memory chunk PT_LOAD program headers plus one kernel ehdr->e_phnum = phdr_count + 1;
* image PT_LOAD program header plus one PT_NOTE program header.
*/
ehdr->e_phnum = mem_chunk_cnt + 1 + 1;
return ehdr + 1; return ehdr + 1;
} }
@ -503,12 +500,14 @@ static int get_mem_chunk_cnt(void)
/* /*
* Initialize ELF loads (new kernel) * Initialize ELF loads (new kernel)
*/ */
static void loads_init(Elf64_Phdr *phdr) static void loads_init(Elf64_Phdr *phdr, bool os_info_has_vm)
{ {
unsigned long old_identity_base = os_info_old_value(OS_INFO_IDENTITY_BASE); unsigned long old_identity_base = 0;
phys_addr_t start, end; phys_addr_t start, end;
u64 idx; u64 idx;
if (os_info_has_vm)
old_identity_base = os_info_old_value(OS_INFO_IDENTITY_BASE);
for_each_physmem_range(idx, &oldmem_type, &start, &end) { for_each_physmem_range(idx, &oldmem_type, &start, &end) {
phdr->p_type = PT_LOAD; phdr->p_type = PT_LOAD;
phdr->p_vaddr = old_identity_base + start; phdr->p_vaddr = old_identity_base + start;
@ -522,6 +521,11 @@ static void loads_init(Elf64_Phdr *phdr)
} }
} }
static bool os_info_has_vm(void)
{
return os_info_old_value(OS_INFO_KASLR_OFFSET);
}
/* /*
* Prepare PT_LOAD type program header for kernel image region * Prepare PT_LOAD type program header for kernel image region
*/ */
@ -566,7 +570,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
return ptr; return ptr;
} }
static size_t get_elfcorehdr_size(int mem_chunk_cnt) static size_t get_elfcorehdr_size(int phdr_count)
{ {
size_t size; size_t size;
@ -581,10 +585,8 @@ static size_t get_elfcorehdr_size(int mem_chunk_cnt)
size += nt_vmcoreinfo_size(); size += nt_vmcoreinfo_size();
/* nt_final */ /* nt_final */
size += sizeof(Elf64_Nhdr); size += sizeof(Elf64_Nhdr);
/* PT_LOAD type program header for kernel text region */
size += sizeof(Elf64_Phdr);
/* PT_LOADS */ /* PT_LOADS */
size += mem_chunk_cnt * sizeof(Elf64_Phdr); size += phdr_count * sizeof(Elf64_Phdr);
return size; return size;
} }
@ -595,8 +597,8 @@ static size_t get_elfcorehdr_size(int mem_chunk_cnt)
int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
{ {
Elf64_Phdr *phdr_notes, *phdr_loads, *phdr_text; Elf64_Phdr *phdr_notes, *phdr_loads, *phdr_text;
int mem_chunk_cnt, phdr_text_cnt;
size_t alloc_size; size_t alloc_size;
int mem_chunk_cnt;
void *ptr, *hdr; void *ptr, *hdr;
u64 hdr_off; u64 hdr_off;
@ -615,12 +617,14 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
} }
mem_chunk_cnt = get_mem_chunk_cnt(); mem_chunk_cnt = get_mem_chunk_cnt();
phdr_text_cnt = os_info_has_vm() ? 1 : 0;
alloc_size = get_elfcorehdr_size(mem_chunk_cnt); alloc_size = get_elfcorehdr_size(mem_chunk_cnt + phdr_text_cnt);
hdr = kzalloc(alloc_size, GFP_KERNEL); hdr = kzalloc(alloc_size, GFP_KERNEL);
/* Without elfcorehdr /proc/vmcore cannot be created. Thus creating /*
* Without elfcorehdr /proc/vmcore cannot be created. Thus creating
* a dump with this crash kernel will fail. Panic now to allow other * a dump with this crash kernel will fail. Panic now to allow other
* dump mechanisms to take over. * dump mechanisms to take over.
*/ */
@ -628,21 +632,23 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
panic("s390 kdump allocating elfcorehdr failed"); panic("s390 kdump allocating elfcorehdr failed");
/* Init elf header */ /* Init elf header */
ptr = ehdr_init(hdr, mem_chunk_cnt); phdr_notes = ehdr_init(hdr, mem_chunk_cnt + phdr_text_cnt);
/* Init program headers */ /* Init program headers */
phdr_notes = ptr; if (phdr_text_cnt) {
ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr)); phdr_text = phdr_notes + 1;
phdr_text = ptr; phdr_loads = phdr_text + 1;
ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr)); } else {
phdr_loads = ptr; phdr_loads = phdr_notes + 1;
ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr) * mem_chunk_cnt); }
ptr = PTR_ADD(phdr_loads, sizeof(Elf64_Phdr) * mem_chunk_cnt);
/* Init notes */ /* Init notes */
hdr_off = PTR_DIFF(ptr, hdr); hdr_off = PTR_DIFF(ptr, hdr);
ptr = notes_init(phdr_notes, ptr, ((unsigned long) hdr) + hdr_off); ptr = notes_init(phdr_notes, ptr, ((unsigned long) hdr) + hdr_off);
/* Init kernel text program header */ /* Init kernel text program header */
text_init(phdr_text); if (phdr_text_cnt)
text_init(phdr_text);
/* Init loads */ /* Init loads */
loads_init(phdr_loads); loads_init(phdr_loads, phdr_text_cnt);
/* Finalize program headers */ /* Finalize program headers */
hdr_off = PTR_DIFF(ptr, hdr); hdr_off = PTR_DIFF(ptr, hdr);
*addr = (unsigned long long) hdr; *addr = (unsigned long long) hdr;

View File

@ -215,7 +215,14 @@ static int __amd_smn_rw(u16 node, u32 address, u32 *value, bool write)
int amd_smn_read(u16 node, u32 address, u32 *value) int amd_smn_read(u16 node, u32 address, u32 *value)
{ {
return __amd_smn_rw(node, address, value, false); int err = __amd_smn_rw(node, address, value, false);
if (PCI_POSSIBLE_ERROR(*value)) {
err = -ENODEV;
*value = 0;
}
return err;
} }
EXPORT_SYMBOL_GPL(amd_smn_read); EXPORT_SYMBOL_GPL(amd_smn_read);

View File

@ -295,8 +295,15 @@ void machine_kexec_cleanup(struct kimage *image)
void machine_kexec(struct kimage *image) void machine_kexec(struct kimage *image)
{ {
unsigned long page_list[PAGES_NR]; unsigned long page_list[PAGES_NR];
void *control_page; unsigned int host_mem_enc_active;
int save_ftrace_enabled; int save_ftrace_enabled;
void *control_page;
/*
* This must be done before load_segments() since if call depth tracking
* is used then GS must be valid to make any function calls.
*/
host_mem_enc_active = cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT);
#ifdef CONFIG_KEXEC_JUMP #ifdef CONFIG_KEXEC_JUMP
if (image->preserve_context) if (image->preserve_context)
@ -358,7 +365,7 @@ void machine_kexec(struct kimage *image)
(unsigned long)page_list, (unsigned long)page_list,
image->start, image->start,
image->preserve_context, image->preserve_context,
cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)); host_mem_enc_active);
#ifdef CONFIG_KEXEC_JUMP #ifdef CONFIG_KEXEC_JUMP
if (image->preserve_context) if (image->preserve_context)

View File

@ -493,7 +493,7 @@ static void __init numa_clear_kernel_node_hotplug(void)
for_each_reserved_mem_region(mb_region) { for_each_reserved_mem_region(mb_region) {
int nid = memblock_get_region_node(mb_region); int nid = memblock_get_region_node(mb_region);
if (nid != MAX_NUMNODES) if (nid != NUMA_NO_NODE)
node_set(nid, reserved_nodemask); node_set(nid, reserved_nodemask);
} }
@ -614,9 +614,9 @@ static int __init numa_init(int (*init_func)(void))
nodes_clear(node_online_map); nodes_clear(node_online_map);
memset(&numa_meminfo, 0, sizeof(numa_meminfo)); memset(&numa_meminfo, 0, sizeof(numa_meminfo));
WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.memory, WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.memory,
MAX_NUMNODES)); NUMA_NO_NODE));
WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.reserved, WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.reserved,
MAX_NUMNODES)); NUMA_NO_NODE));
/* In case that parsing SRAT failed. */ /* In case that parsing SRAT failed. */
WARN_ON(memblock_clear_hotplug(0, ULLONG_MAX)); WARN_ON(memblock_clear_hotplug(0, ULLONG_MAX));
numa_reset_distance(); numa_reset_distance();

View File

@ -915,10 +915,13 @@ static const struct scsi_host_template pata_macio_sht = {
.sg_tablesize = MAX_DCMDS, .sg_tablesize = MAX_DCMDS,
/* We may not need that strict one */ /* We may not need that strict one */
.dma_boundary = ATA_DMA_BOUNDARY, .dma_boundary = ATA_DMA_BOUNDARY,
/* Not sure what the real max is but we know it's less than 64K, let's /*
* use 64K minus 256 * The SCSI core requires the segment size to cover at least a page, so
* for 64K page size kernels this must be at least 64K. However the
* hardware can't handle 64K, so pata_macio_qc_prep() will split large
* requests.
*/ */
.max_segment_size = MAX_DBDMA_SEG, .max_segment_size = SZ_64K,
.device_configure = pata_macio_device_configure, .device_configure = pata_macio_device_configure,
.sdev_groups = ata_common_sdev_groups, .sdev_groups = ata_common_sdev_groups,
.can_queue = ATA_DEF_QUEUE, .can_queue = ATA_DEF_QUEUE,

View File

@ -1824,8 +1824,8 @@ static int null_validate_conf(struct nullb_device *dev)
dev->queue_mode = NULL_Q_MQ; dev->queue_mode = NULL_Q_MQ;
} }
dev->blocksize = round_down(dev->blocksize, 512); if (blk_validate_block_size(dev->blocksize))
dev->blocksize = clamp_t(unsigned int, dev->blocksize, 512, 4096); return -EINVAL;
if (dev->use_per_node_hctx) { if (dev->use_per_node_hctx) {
if (dev->submit_queues != nr_online_nodes) if (dev->submit_queues != nr_online_nodes)

View File

@ -204,8 +204,15 @@ vclkdev_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
pr_err("%pV:%s: %s ID is greater than %zu\n", pr_err("%pV:%s: %s ID is greater than %zu\n",
&vaf, con_id, failure, max_size); &vaf, con_id, failure, max_size);
va_end(ap_copy); va_end(ap_copy);
kfree(cla);
return NULL; /*
* Don't fail in this case, but as the entry won't ever match just
* fill it with something that also won't match.
*/
strscpy(cla->con_id, "bad", sizeof(cla->con_id));
strscpy(cla->dev_id, "bad", sizeof(cla->dev_id));
return &cla->cl;
} }
static struct clk_lookup * static struct clk_lookup *

View File

@ -4,7 +4,6 @@
* Copyright (C) 2020 Zong Li * Copyright (C) 2020 Zong Li
*/ */
#include <linux/clkdev.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
@ -537,13 +536,6 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd,
return r; return r;
} }
r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev));
if (r) {
dev_warn(dev, "Failed to register clkdev for %s: %d\n",
init.name, r);
return r;
}
pd->hw_clks.hws[i] = &pic->hw; pd->hw_clks.hws[i] = &pic->hw;
} }

View File

@ -81,7 +81,7 @@ int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
amd64_warn("%s: error reading F%dx%03x.\n", amd64_warn("%s: error reading F%dx%03x.\n",
func, PCI_FUNC(pdev->devfn), offset); func, PCI_FUNC(pdev->devfn), offset);
return err; return pcibios_err_to_errno(err);
} }
int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset, int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset,
@ -94,7 +94,7 @@ int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset,
amd64_warn("%s: error writing to F%dx%03x.\n", amd64_warn("%s: error writing to F%dx%03x.\n",
func, PCI_FUNC(pdev->devfn), offset); func, PCI_FUNC(pdev->devfn), offset);
return err; return pcibios_err_to_errno(err);
} }
/* /*
@ -1025,8 +1025,10 @@ static int gpu_get_node_map(struct amd64_pvt *pvt)
} }
ret = pci_read_config_dword(pdev, REG_LOCAL_NODE_TYPE_MAP, &tmp); ret = pci_read_config_dword(pdev, REG_LOCAL_NODE_TYPE_MAP, &tmp);
if (ret) if (ret) {
ret = pcibios_err_to_errno(ret);
goto out; goto out;
}
gpu_node_map.node_count = FIELD_GET(LNTM_NODE_COUNT, tmp); gpu_node_map.node_count = FIELD_GET(LNTM_NODE_COUNT, tmp);
gpu_node_map.base_node_id = FIELD_GET(LNTM_BASE_NODE_ID, tmp); gpu_node_map.base_node_id = FIELD_GET(LNTM_BASE_NODE_ID, tmp);

View File

@ -800,7 +800,7 @@ static int errcmd_enable_error_reporting(bool enable)
rc = pci_read_config_word(imc->pdev, ERRCMD_OFFSET, &errcmd); rc = pci_read_config_word(imc->pdev, ERRCMD_OFFSET, &errcmd);
if (rc) if (rc)
return rc; return pcibios_err_to_errno(rc);
if (enable) if (enable)
errcmd |= ERRCMD_CE | ERRSTS_UE; errcmd |= ERRCMD_CE | ERRSTS_UE;
@ -809,7 +809,7 @@ static int errcmd_enable_error_reporting(bool enable)
rc = pci_write_config_word(imc->pdev, ERRCMD_OFFSET, errcmd); rc = pci_write_config_word(imc->pdev, ERRCMD_OFFSET, errcmd);
if (rc) if (rc)
return rc; return pcibios_err_to_errno(rc);
return 0; return 0;
} }

View File

@ -1576,7 +1576,7 @@ config GPIO_TPS68470
are "output only" GPIOs. are "output only" GPIOs.
config GPIO_TQMX86 config GPIO_TQMX86
tristate "TQ-Systems QTMX86 GPIO" tristate "TQ-Systems TQMx86 GPIO"
depends on MFD_TQMX86 || COMPILE_TEST depends on MFD_TQMX86 || COMPILE_TEST
depends on HAS_IOPORT_MAP depends on HAS_IOPORT_MAP
select GPIOLIB_IRQCHIP select GPIOLIB_IRQCHIP

View File

@ -130,5 +130,6 @@ static struct i2c_driver gw_pld_driver = {
}; };
module_i2c_driver(gw_pld_driver); module_i2c_driver(gw_pld_driver);
MODULE_DESCRIPTION("Gateworks I2C PLD GPIO expander");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");

View File

@ -168,5 +168,6 @@ static void __exit mc33880_exit(void)
module_exit(mc33880_exit); module_exit(mc33880_exit);
MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>"); MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
MODULE_DESCRIPTION("MC33880 high-side/low-side switch GPIO driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");

View File

@ -438,5 +438,6 @@ static void __exit pcf857x_exit(void)
} }
module_exit(pcf857x_exit); module_exit(pcf857x_exit);
MODULE_DESCRIPTION("Driver for pcf857x, pca857x, and pca967x I2C GPIO expanders");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Brownell"); MODULE_AUTHOR("David Brownell");

View File

@ -438,4 +438,5 @@ static struct amba_driver pl061_gpio_driver = {
}; };
module_amba_driver(pl061_gpio_driver); module_amba_driver(pl061_gpio_driver);
MODULE_DESCRIPTION("Driver for the ARM PrimeCell(tm) General Purpose Input/Output (PL061)");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");

View File

@ -6,6 +6,7 @@
* Vadim V.Vlasov <vvlasov@dev.rtsoft.ru> * Vadim V.Vlasov <vvlasov@dev.rtsoft.ru>
*/ */
#include <linux/bitmap.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
@ -28,16 +29,25 @@
#define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */ #define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */
#define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */ #define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */
#define TQMX86_GPII_NONE 0
#define TQMX86_GPII_FALLING BIT(0) #define TQMX86_GPII_FALLING BIT(0)
#define TQMX86_GPII_RISING BIT(1) #define TQMX86_GPII_RISING BIT(1)
/* Stored in irq_type as a trigger type, but not actually valid as a register
* value, so the name doesn't use "GPII"
*/
#define TQMX86_INT_BOTH (BIT(0) | BIT(1))
#define TQMX86_GPII_MASK (BIT(0) | BIT(1)) #define TQMX86_GPII_MASK (BIT(0) | BIT(1))
#define TQMX86_GPII_BITS 2 #define TQMX86_GPII_BITS 2
/* Stored in irq_type with GPII bits */
#define TQMX86_INT_UNMASKED BIT(2)
struct tqmx86_gpio_data { struct tqmx86_gpio_data {
struct gpio_chip chip; struct gpio_chip chip;
void __iomem *io_base; void __iomem *io_base;
int irq; int irq;
/* Lock must be held for accessing output and irq_type fields */
raw_spinlock_t spinlock; raw_spinlock_t spinlock;
DECLARE_BITMAP(output, TQMX86_NGPIO);
u8 irq_type[TQMX86_NGPI]; u8 irq_type[TQMX86_NGPI];
}; };
@ -64,15 +74,10 @@ static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,
{ {
struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
unsigned long flags; unsigned long flags;
u8 val;
raw_spin_lock_irqsave(&gpio->spinlock, flags); raw_spin_lock_irqsave(&gpio->spinlock, flags);
val = tqmx86_gpio_read(gpio, TQMX86_GPIOD); __assign_bit(offset, gpio->output, value);
if (value) tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
val |= BIT(offset);
else
val &= ~BIT(offset);
tqmx86_gpio_write(gpio, val, TQMX86_GPIOD);
raw_spin_unlock_irqrestore(&gpio->spinlock, flags); raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
} }
@ -107,21 +112,38 @@ static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
return GPIO_LINE_DIRECTION_OUT; return GPIO_LINE_DIRECTION_OUT;
} }
static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset)
__must_hold(&gpio->spinlock)
{
u8 type = TQMX86_GPII_NONE, gpiic;
if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) {
type = gpio->irq_type[offset] & TQMX86_GPII_MASK;
if (type == TQMX86_INT_BOTH)
type = tqmx86_gpio_get(&gpio->chip, offset + TQMX86_NGPO)
? TQMX86_GPII_FALLING
: TQMX86_GPII_RISING;
}
gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS));
gpiic |= type << (offset * TQMX86_GPII_BITS);
tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
}
static void tqmx86_gpio_irq_mask(struct irq_data *data) static void tqmx86_gpio_irq_mask(struct irq_data *data)
{ {
unsigned int offset = (data->hwirq - TQMX86_NGPO); unsigned int offset = (data->hwirq - TQMX86_NGPO);
struct tqmx86_gpio_data *gpio = gpiochip_get_data( struct tqmx86_gpio_data *gpio = gpiochip_get_data(
irq_data_get_irq_chip_data(data)); irq_data_get_irq_chip_data(data));
unsigned long flags; unsigned long flags;
u8 gpiic, mask;
mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
raw_spin_lock_irqsave(&gpio->spinlock, flags); raw_spin_lock_irqsave(&gpio->spinlock, flags);
gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED;
gpiic &= ~mask; tqmx86_gpio_irq_config(gpio, offset);
tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
raw_spin_unlock_irqrestore(&gpio->spinlock, flags); raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data)); gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data));
} }
@ -131,16 +153,12 @@ static void tqmx86_gpio_irq_unmask(struct irq_data *data)
struct tqmx86_gpio_data *gpio = gpiochip_get_data( struct tqmx86_gpio_data *gpio = gpiochip_get_data(
irq_data_get_irq_chip_data(data)); irq_data_get_irq_chip_data(data));
unsigned long flags; unsigned long flags;
u8 gpiic, mask;
mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data)); gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data));
raw_spin_lock_irqsave(&gpio->spinlock, flags); raw_spin_lock_irqsave(&gpio->spinlock, flags);
gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); gpio->irq_type[offset] |= TQMX86_INT_UNMASKED;
gpiic &= ~mask; tqmx86_gpio_irq_config(gpio, offset);
gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS);
tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
raw_spin_unlock_irqrestore(&gpio->spinlock, flags); raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
} }
@ -151,7 +169,7 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
unsigned int offset = (data->hwirq - TQMX86_NGPO); unsigned int offset = (data->hwirq - TQMX86_NGPO);
unsigned int edge_type = type & IRQF_TRIGGER_MASK; unsigned int edge_type = type & IRQF_TRIGGER_MASK;
unsigned long flags; unsigned long flags;
u8 new_type, gpiic; u8 new_type;
switch (edge_type) { switch (edge_type) {
case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_RISING:
@ -161,19 +179,16 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
new_type = TQMX86_GPII_FALLING; new_type = TQMX86_GPII_FALLING;
break; break;
case IRQ_TYPE_EDGE_BOTH: case IRQ_TYPE_EDGE_BOTH:
new_type = TQMX86_GPII_FALLING | TQMX86_GPII_RISING; new_type = TQMX86_INT_BOTH;
break; break;
default: default:
return -EINVAL; /* not supported */ return -EINVAL; /* not supported */
} }
gpio->irq_type[offset] = new_type;
raw_spin_lock_irqsave(&gpio->spinlock, flags); raw_spin_lock_irqsave(&gpio->spinlock, flags);
gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); gpio->irq_type[offset] &= ~TQMX86_GPII_MASK;
gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS)); gpio->irq_type[offset] |= new_type;
gpiic |= new_type << (offset * TQMX86_GPII_BITS); tqmx86_gpio_irq_config(gpio, offset);
tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
raw_spin_unlock_irqrestore(&gpio->spinlock, flags); raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
return 0; return 0;
@ -184,8 +199,8 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
struct gpio_chip *chip = irq_desc_get_handler_data(desc); struct gpio_chip *chip = irq_desc_get_handler_data(desc);
struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
struct irq_chip *irq_chip = irq_desc_get_chip(desc); struct irq_chip *irq_chip = irq_desc_get_chip(desc);
unsigned long irq_bits; unsigned long irq_bits, flags;
int i = 0; int i;
u8 irq_status; u8 irq_status;
chained_irq_enter(irq_chip, desc); chained_irq_enter(irq_chip, desc);
@ -194,6 +209,34 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS); tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
irq_bits = irq_status; irq_bits = irq_status;
raw_spin_lock_irqsave(&gpio->spinlock, flags);
for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {
/*
* Edge-both triggers are implemented by flipping the edge
* trigger after each interrupt, as the controller only supports
* either rising or falling edge triggers, but not both.
*
* Internally, the TQMx86 GPIO controller has separate status
* registers for rising and falling edge interrupts. GPIIC
* configures which bits from which register are visible in the
* interrupt status register GPIIS and defines what triggers the
* parent IRQ line. Writing to GPIIS always clears both rising
* and falling interrupt flags internally, regardless of the
* currently configured trigger.
*
* In consequence, we can cleanly implement the edge-both
* trigger in software by first clearing the interrupt and then
* setting the new trigger based on the current GPIO input in
* tqmx86_gpio_irq_config() - even if an edge arrives between
* reading the input and setting the trigger, we will have a new
* interrupt pending.
*/
if ((gpio->irq_type[i] & TQMX86_GPII_MASK) == TQMX86_INT_BOTH)
tqmx86_gpio_irq_config(gpio, i);
}
raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
for_each_set_bit(i, &irq_bits, TQMX86_NGPI) for_each_set_bit(i, &irq_bits, TQMX86_NGPI)
generic_handle_domain_irq(gpio->chip.irq.domain, generic_handle_domain_irq(gpio->chip.irq.domain,
i + TQMX86_NGPO); i + TQMX86_NGPO);
@ -277,6 +320,13 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD); tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
/*
* Reading the previous output state is not possible with TQMx86 hardware.
* Initialize all outputs to 0 to have a defined state that matches the
* shadow register.
*/
tqmx86_gpio_write(gpio, 0, TQMX86_GPIOD);
chip = &gpio->chip; chip = &gpio->chip;
chip->label = "gpio-tqmx86"; chip->label = "gpio-tqmx86";
chip->owner = THIS_MODULE; chip->owner = THIS_MODULE;

View File

@ -477,31 +477,30 @@ typedef struct _ATOM_PPLIB_STATE_V2
} ATOM_PPLIB_STATE_V2; } ATOM_PPLIB_STATE_V2;
typedef struct _StateArray{ typedef struct _StateArray{
//how many states we have //how many states we have
UCHAR ucNumEntries; UCHAR ucNumEntries;
ATOM_PPLIB_STATE_V2 states[1]; ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */;
}StateArray; }StateArray;
typedef struct _ClockInfoArray{ typedef struct _ClockInfoArray{
//how many clock levels we have //how many clock levels we have
UCHAR ucNumEntries; UCHAR ucNumEntries;
//sizeof(ATOM_PPLIB_CLOCK_INFO) //sizeof(ATOM_PPLIB_CLOCK_INFO)
UCHAR ucEntrySize; UCHAR ucEntrySize;
UCHAR clockInfo[]; UCHAR clockInfo[];
}ClockInfoArray; }ClockInfoArray;
typedef struct _NonClockInfoArray{ typedef struct _NonClockInfoArray{
//how many non-clock levels we have. normally should be same as number of states
UCHAR ucNumEntries;
//sizeof(ATOM_PPLIB_NONCLOCK_INFO)
UCHAR ucEntrySize;
//how many non-clock levels we have. normally should be same as number of states ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries);
UCHAR ucNumEntries;
//sizeof(ATOM_PPLIB_NONCLOCK_INFO)
UCHAR ucEntrySize;
ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[];
}NonClockInfoArray; }NonClockInfoArray;
typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record
@ -513,8 +512,10 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record
typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Table typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Table
{ {
UCHAR ucNumEntries; // Number of entries. // Number of entries.
ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[1]; // Dynamically allocate entries. UCHAR ucNumEntries;
// Dynamically allocate entries.
ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[] __counted_by(ucNumEntries);
}ATOM_PPLIB_Clock_Voltage_Dependency_Table; }ATOM_PPLIB_Clock_Voltage_Dependency_Table;
typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record
@ -529,8 +530,10 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record
typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table
{ {
UCHAR ucNumEntries; // Number of entries. // Number of entries.
ATOM_PPLIB_Clock_Voltage_Limit_Record entries[1]; // Dynamically allocate entries. UCHAR ucNumEntries;
// Dynamically allocate entries.
ATOM_PPLIB_Clock_Voltage_Limit_Record entries[] __counted_by(ucNumEntries);
}ATOM_PPLIB_Clock_Voltage_Limit_Table; }ATOM_PPLIB_Clock_Voltage_Limit_Table;
union _ATOM_PPLIB_CAC_Leakage_Record union _ATOM_PPLIB_CAC_Leakage_Record
@ -553,8 +556,10 @@ typedef union _ATOM_PPLIB_CAC_Leakage_Record ATOM_PPLIB_CAC_Leakage_Record;
typedef struct _ATOM_PPLIB_CAC_Leakage_Table typedef struct _ATOM_PPLIB_CAC_Leakage_Table
{ {
UCHAR ucNumEntries; // Number of entries. // Number of entries.
ATOM_PPLIB_CAC_Leakage_Record entries[1]; // Dynamically allocate entries. UCHAR ucNumEntries;
// Dynamically allocate entries.
ATOM_PPLIB_CAC_Leakage_Record entries[] __counted_by(ucNumEntries);
}ATOM_PPLIB_CAC_Leakage_Table; }ATOM_PPLIB_CAC_Leakage_Table;
typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record
@ -568,8 +573,10 @@ typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record
typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Table typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Table
{ {
UCHAR ucNumEntries; // Number of entries. // Number of entries.
ATOM_PPLIB_PhaseSheddingLimits_Record entries[1]; // Dynamically allocate entries. UCHAR ucNumEntries;
// Dynamically allocate entries.
ATOM_PPLIB_PhaseSheddingLimits_Record entries[] __counted_by(ucNumEntries);
}ATOM_PPLIB_PhaseSheddingLimits_Table; }ATOM_PPLIB_PhaseSheddingLimits_Table;
typedef struct _VCEClockInfo{ typedef struct _VCEClockInfo{
@ -580,8 +587,8 @@ typedef struct _VCEClockInfo{
}VCEClockInfo; }VCEClockInfo;
typedef struct _VCEClockInfoArray{ typedef struct _VCEClockInfoArray{
UCHAR ucNumEntries; UCHAR ucNumEntries;
VCEClockInfo entries[1]; VCEClockInfo entries[] __counted_by(ucNumEntries);
}VCEClockInfoArray; }VCEClockInfoArray;
typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record
@ -592,8 +599,8 @@ typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record
typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table
{ {
UCHAR numEntries; UCHAR numEntries;
ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[1]; ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries);
}ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table; }ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table;
typedef struct _ATOM_PPLIB_VCE_State_Record typedef struct _ATOM_PPLIB_VCE_State_Record
@ -604,8 +611,8 @@ typedef struct _ATOM_PPLIB_VCE_State_Record
typedef struct _ATOM_PPLIB_VCE_State_Table typedef struct _ATOM_PPLIB_VCE_State_Table
{ {
UCHAR numEntries; UCHAR numEntries;
ATOM_PPLIB_VCE_State_Record entries[1]; ATOM_PPLIB_VCE_State_Record entries[] __counted_by(numEntries);
}ATOM_PPLIB_VCE_State_Table; }ATOM_PPLIB_VCE_State_Table;
@ -626,8 +633,8 @@ typedef struct _UVDClockInfo{
}UVDClockInfo; }UVDClockInfo;
typedef struct _UVDClockInfoArray{ typedef struct _UVDClockInfoArray{
UCHAR ucNumEntries; UCHAR ucNumEntries;
UVDClockInfo entries[1]; UVDClockInfo entries[] __counted_by(ucNumEntries);
}UVDClockInfoArray; }UVDClockInfoArray;
typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record
@ -638,8 +645,8 @@ typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record
typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table
{ {
UCHAR numEntries; UCHAR numEntries;
ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[1]; ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries);
}ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table; }ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table;
typedef struct _ATOM_PPLIB_UVD_Table typedef struct _ATOM_PPLIB_UVD_Table
@ -657,8 +664,8 @@ typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Record
}ATOM_PPLIB_SAMClk_Voltage_Limit_Record; }ATOM_PPLIB_SAMClk_Voltage_Limit_Record;
typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Table{ typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Table{
UCHAR numEntries; UCHAR numEntries;
ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[]; ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[] __counted_by(numEntries);
}ATOM_PPLIB_SAMClk_Voltage_Limit_Table; }ATOM_PPLIB_SAMClk_Voltage_Limit_Table;
typedef struct _ATOM_PPLIB_SAMU_Table typedef struct _ATOM_PPLIB_SAMU_Table
@ -675,8 +682,8 @@ typedef struct _ATOM_PPLIB_ACPClk_Voltage_Limit_Record
}ATOM_PPLIB_ACPClk_Voltage_Limit_Record; }ATOM_PPLIB_ACPClk_Voltage_Limit_Record;
typedef struct _ATOM_PPLIB_ACPClk_Voltage_Limit_Table{ typedef struct _ATOM_PPLIB_ACPClk_Voltage_Limit_Table{
UCHAR numEntries; UCHAR numEntries;
ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[1]; ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[] __counted_by(numEntries);
}ATOM_PPLIB_ACPClk_Voltage_Limit_Table; }ATOM_PPLIB_ACPClk_Voltage_Limit_Table;
typedef struct _ATOM_PPLIB_ACP_Table typedef struct _ATOM_PPLIB_ACP_Table
@ -743,9 +750,9 @@ typedef struct ATOM_PPLIB_VQ_Budgeting_Record{
} ATOM_PPLIB_VQ_Budgeting_Record; } ATOM_PPLIB_VQ_Budgeting_Record;
typedef struct ATOM_PPLIB_VQ_Budgeting_Table { typedef struct ATOM_PPLIB_VQ_Budgeting_Table {
UCHAR revid; UCHAR revid;
UCHAR numEntries; UCHAR numEntries;
ATOM_PPLIB_VQ_Budgeting_Record entries[1]; ATOM_PPLIB_VQ_Budgeting_Record entries[] __counted_by(numEntries);
} ATOM_PPLIB_VQ_Budgeting_Table; } ATOM_PPLIB_VQ_Budgeting_Table;
#pragma pack() #pragma pack()

View File

@ -226,15 +226,17 @@ static int smu_v13_0_4_system_features_control(struct smu_context *smu, bool en)
struct amdgpu_device *adev = smu->adev; struct amdgpu_device *adev = smu->adev;
int ret = 0; int ret = 0;
if (!en && adev->in_s4) { if (!en && !adev->in_s0ix) {
/* Adds a GFX reset as workaround just before sending the if (adev->in_s4) {
* MP1_UNLOAD message to prevent GC/RLC/PMFW from entering /* Adds a GFX reset as workaround just before sending the
* an invalid state. * MP1_UNLOAD message to prevent GC/RLC/PMFW from entering
*/ * an invalid state.
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, */
SMU_RESET_MODE_2, NULL); ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset,
if (ret) SMU_RESET_MODE_2, NULL);
return ret; if (ret)
return ret;
}
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL); ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
} }

View File

@ -72,11 +72,6 @@ struct gamma_curve_sector {
u32 segment_width; u32 segment_width;
}; };
struct gamma_curve_segment {
u32 start;
u32 end;
};
static struct gamma_curve_sector sector_tbl[] = { static struct gamma_curve_sector sector_tbl[] = {
{ 0, 4, 4 }, { 0, 4, 4 },
{ 16, 4, 4 }, { 16, 4, 4 },

View File

@ -643,7 +643,9 @@ static int st7789v_probe(struct spi_device *spi)
if (ret) if (ret)
return dev_err_probe(dev, ret, "Failed to get backlight\n"); return dev_err_probe(dev, ret, "Failed to get backlight\n");
of_drm_get_panel_orientation(spi->dev.of_node, &ctx->orientation); ret = of_drm_get_panel_orientation(spi->dev.of_node, &ctx->orientation);
if (ret)
return dev_err_probe(&spi->dev, ret, "Failed to get orientation\n");
drm_panel_add(&ctx->panel); drm_panel_add(&ctx->panel);

View File

@ -746,7 +746,7 @@ static int vmw_setup_pci_resources(struct vmw_private *dev,
dev->vram_size = pci_resource_len(pdev, 2); dev->vram_size = pci_resource_len(pdev, 2);
drm_info(&dev->drm, drm_info(&dev->drm,
"Register MMIO at 0x%pa size is %llu kiB\n", "Register MMIO at 0x%pa size is %llu KiB\n",
&rmmio_start, (uint64_t)rmmio_size / 1024); &rmmio_start, (uint64_t)rmmio_size / 1024);
dev->rmmio = devm_ioremap(dev->drm.dev, dev->rmmio = devm_ioremap(dev->drm.dev,
rmmio_start, rmmio_start,
@ -765,7 +765,7 @@ static int vmw_setup_pci_resources(struct vmw_private *dev,
fifo_size = pci_resource_len(pdev, 2); fifo_size = pci_resource_len(pdev, 2);
drm_info(&dev->drm, drm_info(&dev->drm,
"FIFO at %pa size is %llu kiB\n", "FIFO at %pa size is %llu KiB\n",
&fifo_start, (uint64_t)fifo_size / 1024); &fifo_start, (uint64_t)fifo_size / 1024);
dev->fifo_mem = devm_memremap(dev->drm.dev, dev->fifo_mem = devm_memremap(dev->drm.dev,
fifo_start, fifo_start,
@ -790,7 +790,7 @@ static int vmw_setup_pci_resources(struct vmw_private *dev,
* SVGA_REG_VRAM_SIZE. * SVGA_REG_VRAM_SIZE.
*/ */
drm_info(&dev->drm, drm_info(&dev->drm,
"VRAM at %pa size is %llu kiB\n", "VRAM at %pa size is %llu KiB\n",
&dev->vram_start, (uint64_t)dev->vram_size / 1024); &dev->vram_start, (uint64_t)dev->vram_size / 1024);
return 0; return 0;
@ -960,13 +960,6 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
vmw_read(dev_priv, vmw_read(dev_priv,
SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB);
/*
* Workaround for low memory 2D VMs to compensate for the
* allocation taken by fbdev
*/
if (!(dev_priv->capabilities & SVGA_CAP_3D))
mem_size *= 3;
dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE; dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE;
dev_priv->max_primary_mem = dev_priv->max_primary_mem =
vmw_read(dev_priv, SVGA_REG_MAX_PRIMARY_MEM); vmw_read(dev_priv, SVGA_REG_MAX_PRIMARY_MEM);
@ -991,13 +984,13 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
dev_priv->max_primary_mem = dev_priv->vram_size; dev_priv->max_primary_mem = dev_priv->vram_size;
} }
drm_info(&dev_priv->drm, drm_info(&dev_priv->drm,
"Legacy memory limits: VRAM = %llu kB, FIFO = %llu kB, surface = %u kB\n", "Legacy memory limits: VRAM = %llu KiB, FIFO = %llu KiB, surface = %u KiB\n",
(u64)dev_priv->vram_size / 1024, (u64)dev_priv->vram_size / 1024,
(u64)dev_priv->fifo_mem_size / 1024, (u64)dev_priv->fifo_mem_size / 1024,
dev_priv->memory_size / 1024); dev_priv->memory_size / 1024);
drm_info(&dev_priv->drm, drm_info(&dev_priv->drm,
"MOB limits: max mob size = %u kB, max mob pages = %u\n", "MOB limits: max mob size = %u KiB, max mob pages = %u\n",
dev_priv->max_mob_size / 1024, dev_priv->max_mob_pages); dev_priv->max_mob_size / 1024, dev_priv->max_mob_pages);
ret = vmw_dma_masks(dev_priv); ret = vmw_dma_masks(dev_priv);
@ -1015,7 +1008,7 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
(unsigned)dev_priv->max_gmr_pages); (unsigned)dev_priv->max_gmr_pages);
} }
drm_info(&dev_priv->drm, drm_info(&dev_priv->drm,
"Maximum display memory size is %llu kiB\n", "Maximum display memory size is %llu KiB\n",
(uint64_t)dev_priv->max_primary_mem / 1024); (uint64_t)dev_priv->max_primary_mem / 1024);
/* Need mmio memory to check for fifo pitchlock cap. */ /* Need mmio memory to check for fifo pitchlock cap. */

View File

@ -1043,9 +1043,6 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
int vmw_kms_write_svga(struct vmw_private *vmw_priv, int vmw_kms_write_svga(struct vmw_private *vmw_priv,
unsigned width, unsigned height, unsigned pitch, unsigned width, unsigned height, unsigned pitch,
unsigned bpp, unsigned depth); unsigned bpp, unsigned depth);
bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
uint32_t pitch,
uint32_t height);
int vmw_kms_present(struct vmw_private *dev_priv, int vmw_kms_present(struct vmw_private *dev_priv,
struct drm_file *file_priv, struct drm_file *file_priv,
struct vmw_framebuffer *vfb, struct vmw_framebuffer *vfb,

View File

@ -94,14 +94,14 @@ static int vmw_gmrid_man_get_node(struct ttm_resource_manager *man,
} else } else
new_max_pages = gman->max_gmr_pages * 2; new_max_pages = gman->max_gmr_pages * 2;
if (new_max_pages > gman->max_gmr_pages && new_max_pages >= gman->used_gmr_pages) { if (new_max_pages > gman->max_gmr_pages && new_max_pages >= gman->used_gmr_pages) {
DRM_WARN("vmwgfx: increasing guest mob limits to %u kB.\n", DRM_WARN("vmwgfx: increasing guest mob limits to %u KiB.\n",
((new_max_pages) << (PAGE_SHIFT - 10))); ((new_max_pages) << (PAGE_SHIFT - 10)));
gman->max_gmr_pages = new_max_pages; gman->max_gmr_pages = new_max_pages;
} else { } else {
char buf[256]; char buf[256];
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"vmwgfx, error: guest graphics is out of memory (mob limit at: %ukB).\n", "vmwgfx, error: guest graphics is out of memory (mob limit at: %u KiB).\n",
((gman->max_gmr_pages) << (PAGE_SHIFT - 10))); ((gman->max_gmr_pages) << (PAGE_SHIFT - 10)));
vmw_host_printf(buf); vmw_host_printf(buf);
DRM_WARN("%s", buf); DRM_WARN("%s", buf);

View File

@ -224,7 +224,7 @@ static bool vmw_du_cursor_plane_has_changed(struct vmw_plane_state *old_vps,
new_image = vmw_du_cursor_plane_acquire_image(new_vps); new_image = vmw_du_cursor_plane_acquire_image(new_vps);
changed = false; changed = false;
if (old_image && new_image) if (old_image && new_image && old_image != new_image)
changed = memcmp(old_image, new_image, size) != 0; changed = memcmp(old_image, new_image, size) != 0;
return changed; return changed;
@ -2171,13 +2171,12 @@ int vmw_kms_write_svga(struct vmw_private *vmw_priv,
return 0; return 0;
} }
static
bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv, bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
uint32_t pitch, u64 pitch,
uint32_t height) u64 height)
{ {
return ((u64) pitch * (u64) height) < (u64) return (pitch * height) < (u64)dev_priv->vram_size;
((dev_priv->active_display_unit == vmw_du_screen_target) ?
dev_priv->max_primary_mem : dev_priv->vram_size);
} }
/** /**
@ -2873,25 +2872,18 @@ int vmw_du_helper_plane_update(struct vmw_du_update_plane *update)
enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector, enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
enum drm_mode_status ret;
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct vmw_private *dev_priv = vmw_priv(dev); struct vmw_private *dev_priv = vmw_priv(dev);
u32 max_width = dev_priv->texture_max_width;
u32 max_height = dev_priv->texture_max_height;
u32 assumed_cpp = 4; u32 assumed_cpp = 4;
if (dev_priv->assume_16bpp) if (dev_priv->assume_16bpp)
assumed_cpp = 2; assumed_cpp = 2;
if (dev_priv->active_display_unit == vmw_du_screen_target) { ret = drm_mode_validate_size(mode, dev_priv->texture_max_width,
max_width = min(dev_priv->stdu_max_width, max_width); dev_priv->texture_max_height);
max_height = min(dev_priv->stdu_max_height, max_height); if (ret != MODE_OK)
} return ret;
if (max_width < mode->hdisplay)
return MODE_BAD_HVALUE;
if (max_height < mode->vdisplay)
return MODE_BAD_VVALUE;
if (!vmw_kms_validate_mode_vram(dev_priv, if (!vmw_kms_validate_mode_vram(dev_priv,
mode->hdisplay * assumed_cpp, mode->hdisplay * assumed_cpp,

View File

@ -43,7 +43,14 @@
#define vmw_connector_to_stdu(x) \ #define vmw_connector_to_stdu(x) \
container_of(x, struct vmw_screen_target_display_unit, base.connector) container_of(x, struct vmw_screen_target_display_unit, base.connector)
/*
* Some renderers such as llvmpipe will align the width and height of their
* buffers to match their tile size. We need to keep this in mind when exposing
* modes to userspace so that this possible over-allocation will not exceed
* graphics memory. 64x64 pixels seems to be a reasonable upper bound for the
* tile size of current renderers.
*/
#define GPU_TILE_SIZE 64
enum stdu_content_type { enum stdu_content_type {
SAME_AS_DISPLAY = 0, SAME_AS_DISPLAY = 0,
@ -85,11 +92,6 @@ struct vmw_stdu_update {
SVGA3dCmdUpdateGBScreenTarget body; SVGA3dCmdUpdateGBScreenTarget body;
}; };
struct vmw_stdu_dma {
SVGA3dCmdHeader header;
SVGA3dCmdSurfaceDMA body;
};
struct vmw_stdu_surface_copy { struct vmw_stdu_surface_copy {
SVGA3dCmdHeader header; SVGA3dCmdHeader header;
SVGA3dCmdSurfaceCopy body; SVGA3dCmdSurfaceCopy body;
@ -414,6 +416,7 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc,
{ {
struct vmw_private *dev_priv; struct vmw_private *dev_priv;
struct vmw_screen_target_display_unit *stdu; struct vmw_screen_target_display_unit *stdu;
struct drm_crtc_state *new_crtc_state;
int ret; int ret;
if (!crtc) { if (!crtc) {
@ -423,6 +426,7 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc,
stdu = vmw_crtc_to_stdu(crtc); stdu = vmw_crtc_to_stdu(crtc);
dev_priv = vmw_priv(crtc->dev); dev_priv = vmw_priv(crtc->dev);
new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
if (dev_priv->vkms_enabled) if (dev_priv->vkms_enabled)
drm_crtc_vblank_off(crtc); drm_crtc_vblank_off(crtc);
@ -434,6 +438,14 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc,
(void) vmw_stdu_update_st(dev_priv, stdu); (void) vmw_stdu_update_st(dev_priv, stdu);
/* Don't destroy the Screen Target if we are only setting the
* display as inactive
*/
if (new_crtc_state->enable &&
!new_crtc_state->active &&
!new_crtc_state->mode_changed)
return;
ret = vmw_stdu_destroy_st(dev_priv, stdu); ret = vmw_stdu_destroy_st(dev_priv, stdu);
if (ret) if (ret)
DRM_ERROR("Failed to destroy Screen Target\n"); DRM_ERROR("Failed to destroy Screen Target\n");
@ -829,7 +841,41 @@ static void vmw_stdu_connector_destroy(struct drm_connector *connector)
vmw_stdu_destroy(vmw_connector_to_stdu(connector)); vmw_stdu_destroy(vmw_connector_to_stdu(connector));
} }
static enum drm_mode_status
vmw_stdu_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
enum drm_mode_status ret;
struct drm_device *dev = connector->dev;
struct vmw_private *dev_priv = vmw_priv(dev);
u64 assumed_cpp = dev_priv->assume_16bpp ? 2 : 4;
/* Align width and height to account for GPU tile over-alignment */
u64 required_mem = ALIGN(mode->hdisplay, GPU_TILE_SIZE) *
ALIGN(mode->vdisplay, GPU_TILE_SIZE) *
assumed_cpp;
required_mem = ALIGN(required_mem, PAGE_SIZE);
ret = drm_mode_validate_size(mode, dev_priv->stdu_max_width,
dev_priv->stdu_max_height);
if (ret != MODE_OK)
return ret;
ret = drm_mode_validate_size(mode, dev_priv->texture_max_width,
dev_priv->texture_max_height);
if (ret != MODE_OK)
return ret;
if (required_mem > dev_priv->max_primary_mem)
return MODE_MEM;
if (required_mem > dev_priv->max_mob_pages * PAGE_SIZE)
return MODE_MEM;
if (required_mem > dev_priv->max_mob_size)
return MODE_MEM;
return MODE_OK;
}
static const struct drm_connector_funcs vmw_stdu_connector_funcs = { static const struct drm_connector_funcs vmw_stdu_connector_funcs = {
.dpms = vmw_du_connector_dpms, .dpms = vmw_du_connector_dpms,
@ -845,7 +891,7 @@ static const struct drm_connector_funcs vmw_stdu_connector_funcs = {
static const struct static const struct
drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = { drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = {
.get_modes = vmw_connector_get_modes, .get_modes = vmw_connector_get_modes,
.mode_valid = vmw_connector_mode_valid .mode_valid = vmw_stdu_connector_mode_valid
}; };

View File

@ -1749,6 +1749,7 @@ static void pf_release_vf_config(struct xe_gt *gt, unsigned int vfid)
if (!xe_gt_is_media_type(gt)) { if (!xe_gt_is_media_type(gt)) {
pf_release_vf_config_ggtt(gt, config); pf_release_vf_config_ggtt(gt, config);
pf_release_vf_config_lmem(gt, config); pf_release_vf_config_lmem(gt, config);
pf_update_vf_lmtt(gt_to_xe(gt), vfid);
} }
pf_release_config_ctxs(gt, config); pf_release_config_ctxs(gt, config);
pf_release_config_dbs(gt, config); pf_release_config_dbs(gt, config);

View File

@ -1204,8 +1204,8 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
} }
/* match many more n-key devices */ /* match many more n-key devices */
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) { if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && *rsize > 15) {
for (int i = 0; i < *rsize + 1; i++) { for (int i = 0; i < *rsize - 15; i++) {
/* offset to the count from 0x5a report part always 14 */ /* offset to the count from 0x5a report part always 14 */
if (rdesc[i] == 0x85 && rdesc[i + 1] == 0x5a && if (rdesc[i] == 0x85 && rdesc[i + 1] == 0x5a &&
rdesc[i + 14] == 0x95 && rdesc[i + 15] == 0x05) { rdesc[i + 14] == 0x95 && rdesc[i + 15] == 0x05) {

View File

@ -1448,7 +1448,6 @@ static void implement(const struct hid_device *hid, u8 *report,
hid_warn(hid, hid_warn(hid,
"%s() called with too large value %d (n: %d)! (%s)\n", "%s() called with too large value %d (n: %d)! (%s)\n",
__func__, value, n, current->comm); __func__, value, n, current->comm);
WARN_ON(1);
value &= m; value &= m;
} }
} }

View File

@ -3366,6 +3366,8 @@ static const char *keys[KEY_MAX + 1] = {
[KEY_CAMERA_ACCESS_ENABLE] = "CameraAccessEnable", [KEY_CAMERA_ACCESS_ENABLE] = "CameraAccessEnable",
[KEY_CAMERA_ACCESS_DISABLE] = "CameraAccessDisable", [KEY_CAMERA_ACCESS_DISABLE] = "CameraAccessDisable",
[KEY_CAMERA_ACCESS_TOGGLE] = "CameraAccessToggle", [KEY_CAMERA_ACCESS_TOGGLE] = "CameraAccessToggle",
[KEY_ACCESSIBILITY] = "Accessibility",
[KEY_DO_NOT_DISTURB] = "DoNotDisturb",
[KEY_DICTATE] = "Dictate", [KEY_DICTATE] = "Dictate",
[KEY_MICMUTE] = "MicrophoneMute", [KEY_MICMUTE] = "MicrophoneMute",
[KEY_BRIGHTNESS_MIN] = "BrightnessMin", [KEY_BRIGHTNESS_MIN] = "BrightnessMin",

View File

@ -423,6 +423,8 @@
#define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF #define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF
#define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8 #define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
#define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82 #define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82
#define I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN 0x2F2C
#define I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN 0x4116
#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544 #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A

View File

@ -377,6 +377,10 @@ static const struct hid_device_id hid_battery_quirks[] = {
HID_BATTERY_QUIRK_IGNORE }, HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN), { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE }, HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE }, HID_BATTERY_QUIRK_IGNORE },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN), { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
@ -833,9 +837,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
break; break;
} }
if ((usage->hid & 0xf0) == 0x90) { /* SystemControl*/
switch (usage->hid & 0xf) {
case 0xb: map_key_clear(KEY_DO_NOT_DISTURB); break;
default: goto ignore;
}
break;
}
if ((usage->hid & 0xf0) == 0xa0) { /* SystemControl */ if ((usage->hid & 0xf0) == 0xa0) { /* SystemControl */
switch (usage->hid & 0xf) { switch (usage->hid & 0xf) {
case 0x9: map_key_clear(KEY_MICMUTE); break; case 0x9: map_key_clear(KEY_MICMUTE); break;
case 0xa: map_key_clear(KEY_ACCESSIBILITY); break;
default: goto ignore; default: goto ignore;
} }
break; break;

View File

@ -1284,8 +1284,10 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
*/ */
msleep(50); msleep(50);
if (retval) if (retval) {
kfree(dj_report);
return retval; return retval;
}
} }
/* /*

View File

@ -27,6 +27,7 @@
#include "usbhid/usbhid.h" #include "usbhid/usbhid.h"
#include "hid-ids.h" #include "hid-ids.h"
MODULE_DESCRIPTION("Support for Logitech devices relying on the HID++ specification");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>"); MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>");

View File

@ -2725,13 +2725,13 @@ static int nintendo_hid_probe(struct hid_device *hdev,
ret = joycon_power_supply_create(ctlr); ret = joycon_power_supply_create(ctlr);
if (ret) { if (ret) {
hid_err(hdev, "Failed to create power_supply; ret=%d\n", ret); hid_err(hdev, "Failed to create power_supply; ret=%d\n", ret);
goto err_close; goto err_ida;
} }
ret = joycon_input_create(ctlr); ret = joycon_input_create(ctlr);
if (ret) { if (ret) {
hid_err(hdev, "Failed to create input device; ret=%d\n", ret); hid_err(hdev, "Failed to create input device; ret=%d\n", ret);
goto err_close; goto err_ida;
} }
ctlr->ctlr_state = JOYCON_CTLR_STATE_READ; ctlr->ctlr_state = JOYCON_CTLR_STATE_READ;
@ -2739,6 +2739,8 @@ static int nintendo_hid_probe(struct hid_device *hdev,
hid_dbg(hdev, "probe - success\n"); hid_dbg(hdev, "probe - success\n");
return 0; return 0;
err_ida:
ida_free(&nintendo_player_id_allocator, ctlr->player_id);
err_close: err_close:
hid_hw_close(hdev); hid_hw_close(hdev);
err_stop: err_stop:

View File

@ -283,7 +283,9 @@ static struct input_dev *shield_haptics_create(
return haptics; return haptics;
input_set_capability(haptics, EV_FF, FF_RUMBLE); input_set_capability(haptics, EV_FF, FF_RUMBLE);
input_ff_create_memless(haptics, NULL, play_effect); ret = input_ff_create_memless(haptics, NULL, play_effect);
if (ret)
goto err;
ret = input_register_device(haptics); ret = input_register_device(haptics);
if (ret) if (ret)

View File

@ -31,6 +31,7 @@ struct i2c_hid_of_elan {
struct regulator *vcc33; struct regulator *vcc33;
struct regulator *vccio; struct regulator *vccio;
struct gpio_desc *reset_gpio; struct gpio_desc *reset_gpio;
bool no_reset_on_power_off;
const struct elan_i2c_hid_chip_data *chip_data; const struct elan_i2c_hid_chip_data *chip_data;
}; };
@ -40,17 +41,17 @@ static int elan_i2c_hid_power_up(struct i2chid_ops *ops)
container_of(ops, struct i2c_hid_of_elan, ops); container_of(ops, struct i2c_hid_of_elan, ops);
int ret; int ret;
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
if (ihid_elan->vcc33) { if (ihid_elan->vcc33) {
ret = regulator_enable(ihid_elan->vcc33); ret = regulator_enable(ihid_elan->vcc33);
if (ret) if (ret)
return ret; goto err_deassert_reset;
} }
ret = regulator_enable(ihid_elan->vccio); ret = regulator_enable(ihid_elan->vccio);
if (ret) { if (ret)
regulator_disable(ihid_elan->vcc33); goto err_disable_vcc33;
return ret;
}
if (ihid_elan->chip_data->post_power_delay_ms) if (ihid_elan->chip_data->post_power_delay_ms)
msleep(ihid_elan->chip_data->post_power_delay_ms); msleep(ihid_elan->chip_data->post_power_delay_ms);
@ -60,6 +61,15 @@ static int elan_i2c_hid_power_up(struct i2chid_ops *ops)
msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms); msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms);
return 0; return 0;
err_disable_vcc33:
if (ihid_elan->vcc33)
regulator_disable(ihid_elan->vcc33);
err_deassert_reset:
if (ihid_elan->no_reset_on_power_off)
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);
return ret;
} }
static void elan_i2c_hid_power_down(struct i2chid_ops *ops) static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
@ -67,7 +77,14 @@ static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
struct i2c_hid_of_elan *ihid_elan = struct i2c_hid_of_elan *ihid_elan =
container_of(ops, struct i2c_hid_of_elan, ops); container_of(ops, struct i2c_hid_of_elan, ops);
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); /*
* Do not assert reset when the hardware allows for it to remain
* deasserted regardless of the state of the (shared) power supply to
* avoid wasting power when the supply is left on.
*/
if (!ihid_elan->no_reset_on_power_off)
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms) if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms)
msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms); msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms);
@ -79,6 +96,7 @@ static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
static int i2c_hid_of_elan_probe(struct i2c_client *client) static int i2c_hid_of_elan_probe(struct i2c_client *client)
{ {
struct i2c_hid_of_elan *ihid_elan; struct i2c_hid_of_elan *ihid_elan;
int ret;
ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL); ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL);
if (!ihid_elan) if (!ihid_elan)
@ -93,21 +111,38 @@ static int i2c_hid_of_elan_probe(struct i2c_client *client)
if (IS_ERR(ihid_elan->reset_gpio)) if (IS_ERR(ihid_elan->reset_gpio))
return PTR_ERR(ihid_elan->reset_gpio); return PTR_ERR(ihid_elan->reset_gpio);
ihid_elan->no_reset_on_power_off = of_property_read_bool(client->dev.of_node,
"no-reset-on-power-off");
ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio"); ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio");
if (IS_ERR(ihid_elan->vccio)) if (IS_ERR(ihid_elan->vccio)) {
return PTR_ERR(ihid_elan->vccio); ret = PTR_ERR(ihid_elan->vccio);
goto err_deassert_reset;
}
ihid_elan->chip_data = device_get_match_data(&client->dev); ihid_elan->chip_data = device_get_match_data(&client->dev);
if (ihid_elan->chip_data->main_supply_name) { if (ihid_elan->chip_data->main_supply_name) {
ihid_elan->vcc33 = devm_regulator_get(&client->dev, ihid_elan->vcc33 = devm_regulator_get(&client->dev,
ihid_elan->chip_data->main_supply_name); ihid_elan->chip_data->main_supply_name);
if (IS_ERR(ihid_elan->vcc33)) if (IS_ERR(ihid_elan->vcc33)) {
return PTR_ERR(ihid_elan->vcc33); ret = PTR_ERR(ihid_elan->vcc33);
goto err_deassert_reset;
}
} }
return i2c_hid_core_probe(client, &ihid_elan->ops, ret = i2c_hid_core_probe(client, &ihid_elan->ops,
ihid_elan->chip_data->hid_descriptor_address, 0); ihid_elan->chip_data->hid_descriptor_address, 0);
if (ret)
goto err_deassert_reset;
return 0;
err_deassert_reset:
if (ihid_elan->no_reset_on_power_off)
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);
return ret;
} }
static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = { static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = {

View File

@ -84,8 +84,8 @@ static int loader_write_message(struct ishtp_device *dev, void *buf, int len)
static int loader_xfer_cmd(struct ishtp_device *dev, void *req, int req_len, static int loader_xfer_cmd(struct ishtp_device *dev, void *req, int req_len,
void *resp, int resp_len) void *resp, int resp_len)
{ {
struct loader_msg_header *req_hdr = req; union loader_msg_header req_hdr;
struct loader_msg_header *resp_hdr = resp; union loader_msg_header resp_hdr;
struct device *devc = dev->devc; struct device *devc = dev->devc;
int rv; int rv;
@ -93,34 +93,37 @@ static int loader_xfer_cmd(struct ishtp_device *dev, void *req, int req_len,
dev->fw_loader_rx_size = resp_len; dev->fw_loader_rx_size = resp_len;
rv = loader_write_message(dev, req, req_len); rv = loader_write_message(dev, req, req_len);
req_hdr.val32 = le32_to_cpup(req);
if (rv < 0) { if (rv < 0) {
dev_err(devc, "write cmd %u failed:%d\n", req_hdr->command, rv); dev_err(devc, "write cmd %u failed:%d\n", req_hdr.command, rv);
return rv; return rv;
} }
/* Wait the ACK */ /* Wait the ACK */
wait_event_interruptible_timeout(dev->wait_loader_recvd_msg, dev->fw_loader_received, wait_event_interruptible_timeout(dev->wait_loader_recvd_msg, dev->fw_loader_received,
ISHTP_LOADER_TIMEOUT); ISHTP_LOADER_TIMEOUT);
resp_hdr.val32 = le32_to_cpup(resp);
dev->fw_loader_rx_size = 0; dev->fw_loader_rx_size = 0;
dev->fw_loader_rx_buf = NULL; dev->fw_loader_rx_buf = NULL;
if (!dev->fw_loader_received) { if (!dev->fw_loader_received) {
dev_err(devc, "wait response of cmd %u timeout\n", req_hdr->command); dev_err(devc, "wait response of cmd %u timeout\n", req_hdr.command);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
if (!resp_hdr->is_response) { if (!resp_hdr.is_response) {
dev_err(devc, "not a response for %u\n", req_hdr->command); dev_err(devc, "not a response for %u\n", req_hdr.command);
return -EBADMSG; return -EBADMSG;
} }
if (req_hdr->command != resp_hdr->command) { if (req_hdr.command != resp_hdr.command) {
dev_err(devc, "unexpected cmd response %u:%u\n", req_hdr->command, dev_err(devc, "unexpected cmd response %u:%u\n", req_hdr.command,
resp_hdr->command); resp_hdr.command);
return -EBADMSG; return -EBADMSG;
} }
if (resp_hdr->status) { if (resp_hdr.status) {
dev_err(devc, "cmd %u failed %u\n", req_hdr->command, resp_hdr->status); dev_err(devc, "cmd %u failed %u\n", req_hdr.command, resp_hdr.status);
return -EIO; return -EIO;
} }
@ -138,12 +141,13 @@ static void release_dma_bufs(struct ishtp_device *dev,
struct loader_xfer_dma_fragment *fragment, struct loader_xfer_dma_fragment *fragment,
void **dma_bufs, u32 fragment_size) void **dma_bufs, u32 fragment_size)
{ {
dma_addr_t dma_addr;
int i; int i;
for (i = 0; i < FRAGMENT_MAX_NUM; i++) { for (i = 0; i < FRAGMENT_MAX_NUM; i++) {
if (dma_bufs[i]) { if (dma_bufs[i]) {
dma_free_coherent(dev->devc, fragment_size, dma_bufs[i], dma_addr = le64_to_cpu(fragment->fragment_tbl[i].ddr_adrs);
fragment->fragment_tbl[i].ddr_adrs); dma_free_coherent(dev->devc, fragment_size, dma_bufs[i], dma_addr);
dma_bufs[i] = NULL; dma_bufs[i] = NULL;
} }
} }
@ -156,29 +160,33 @@ static void release_dma_bufs(struct ishtp_device *dev,
* @fragment: The ISHTP firmware fragment descriptor * @fragment: The ISHTP firmware fragment descriptor
* @dma_bufs: The array of DMA fragment buffers * @dma_bufs: The array of DMA fragment buffers
* @fragment_size: The size of a single DMA fragment * @fragment_size: The size of a single DMA fragment
* @fragment_count: Number of fragments
* *
* Return: 0 on success, negative error code on failure * Return: 0 on success, negative error code on failure
*/ */
static int prepare_dma_bufs(struct ishtp_device *dev, static int prepare_dma_bufs(struct ishtp_device *dev,
const struct firmware *ish_fw, const struct firmware *ish_fw,
struct loader_xfer_dma_fragment *fragment, struct loader_xfer_dma_fragment *fragment,
void **dma_bufs, u32 fragment_size) void **dma_bufs, u32 fragment_size, u32 fragment_count)
{ {
dma_addr_t dma_addr;
u32 offset = 0; u32 offset = 0;
u32 length;
int i; int i;
for (i = 0; i < fragment->fragment_cnt && offset < ish_fw->size; i++) { for (i = 0; i < fragment_count && offset < ish_fw->size; i++) {
dma_bufs[i] = dma_alloc_coherent(dev->devc, fragment_size, dma_bufs[i] = dma_alloc_coherent(dev->devc, fragment_size, &dma_addr, GFP_KERNEL);
&fragment->fragment_tbl[i].ddr_adrs, GFP_KERNEL);
if (!dma_bufs[i]) if (!dma_bufs[i])
return -ENOMEM; return -ENOMEM;
fragment->fragment_tbl[i].length = clamp(ish_fw->size - offset, 0, fragment_size); fragment->fragment_tbl[i].ddr_adrs = cpu_to_le64(dma_addr);
fragment->fragment_tbl[i].fw_off = offset; length = clamp(ish_fw->size - offset, 0, fragment_size);
memcpy(dma_bufs[i], ish_fw->data + offset, fragment->fragment_tbl[i].length); fragment->fragment_tbl[i].length = cpu_to_le32(length);
fragment->fragment_tbl[i].fw_off = cpu_to_le32(offset);
memcpy(dma_bufs[i], ish_fw->data + offset, length);
clflush_cache_range(dma_bufs[i], fragment_size); clflush_cache_range(dma_bufs[i], fragment_size);
offset += fragment->fragment_tbl[i].length; offset += length;
} }
return 0; return 0;
@ -206,17 +214,17 @@ void ishtp_loader_work(struct work_struct *work)
{ {
DEFINE_RAW_FLEX(struct loader_xfer_dma_fragment, fragment, fragment_tbl, FRAGMENT_MAX_NUM); DEFINE_RAW_FLEX(struct loader_xfer_dma_fragment, fragment, fragment_tbl, FRAGMENT_MAX_NUM);
struct ishtp_device *dev = container_of(work, struct ishtp_device, work_fw_loader); struct ishtp_device *dev = container_of(work, struct ishtp_device, work_fw_loader);
struct loader_xfer_query query = { union loader_msg_header query_hdr = { .command = LOADER_CMD_XFER_QUERY, };
.header.command = LOADER_CMD_XFER_QUERY, union loader_msg_header start_hdr = { .command = LOADER_CMD_START, };
}; union loader_msg_header fragment_hdr = { .command = LOADER_CMD_XFER_FRAGMENT, };
struct loader_start start = { struct loader_xfer_query query = { .header = cpu_to_le32(query_hdr.val32), };
.header.command = LOADER_CMD_START, struct loader_start start = { .header = cpu_to_le32(start_hdr.val32), };
};
union loader_recv_message recv_msg; union loader_recv_message recv_msg;
char *filename = dev->driver_data->fw_filename; char *filename = dev->driver_data->fw_filename;
const struct firmware *ish_fw; const struct firmware *ish_fw;
void *dma_bufs[FRAGMENT_MAX_NUM] = {}; void *dma_bufs[FRAGMENT_MAX_NUM] = {};
u32 fragment_size; u32 fragment_size;
u32 fragment_count;
int retry = ISHTP_LOADER_RETRY_TIMES; int retry = ISHTP_LOADER_RETRY_TIMES;
int rv; int rv;
@ -226,23 +234,24 @@ void ishtp_loader_work(struct work_struct *work)
return; return;
} }
fragment->fragment.header.command = LOADER_CMD_XFER_FRAGMENT; fragment->fragment.header = cpu_to_le32(fragment_hdr.val32);
fragment->fragment.xfer_mode = LOADER_XFER_MODE_DMA; fragment->fragment.xfer_mode = cpu_to_le32(LOADER_XFER_MODE_DMA);
fragment->fragment.is_last = 1; fragment->fragment.is_last = cpu_to_le32(1);
fragment->fragment.size = ish_fw->size; fragment->fragment.size = cpu_to_le32(ish_fw->size);
/* Calculate the size of a single DMA fragment */ /* Calculate the size of a single DMA fragment */
fragment_size = PFN_ALIGN(DIV_ROUND_UP(ish_fw->size, FRAGMENT_MAX_NUM)); fragment_size = PFN_ALIGN(DIV_ROUND_UP(ish_fw->size, FRAGMENT_MAX_NUM));
/* Calculate the count of DMA fragments */ /* Calculate the count of DMA fragments */
fragment->fragment_cnt = DIV_ROUND_UP(ish_fw->size, fragment_size); fragment_count = DIV_ROUND_UP(ish_fw->size, fragment_size);
fragment->fragment_cnt = cpu_to_le32(fragment_count);
rv = prepare_dma_bufs(dev, ish_fw, fragment, dma_bufs, fragment_size); rv = prepare_dma_bufs(dev, ish_fw, fragment, dma_bufs, fragment_size, fragment_count);
if (rv) { if (rv) {
dev_err(dev->devc, "prepare DMA buffer failed.\n"); dev_err(dev->devc, "prepare DMA buffer failed.\n");
goto out; goto out;
} }
do { do {
query.image_size = ish_fw->size; query.image_size = cpu_to_le32(ish_fw->size);
rv = loader_xfer_cmd(dev, &query, sizeof(query), recv_msg.raw_data, rv = loader_xfer_cmd(dev, &query, sizeof(query), recv_msg.raw_data,
sizeof(struct loader_xfer_query_ack)); sizeof(struct loader_xfer_query_ack));
if (rv) if (rv)
@ -255,7 +264,7 @@ void ishtp_loader_work(struct work_struct *work)
recv_msg.query_ack.version_build); recv_msg.query_ack.version_build);
rv = loader_xfer_cmd(dev, fragment, rv = loader_xfer_cmd(dev, fragment,
struct_size(fragment, fragment_tbl, fragment->fragment_cnt), struct_size(fragment, fragment_tbl, fragment_count),
recv_msg.raw_data, sizeof(struct loader_xfer_fragment_ack)); recv_msg.raw_data, sizeof(struct loader_xfer_fragment_ack));
if (rv) if (rv)
continue; /* try again if failed */ continue; /* try again if failed */

View File

@ -30,19 +30,23 @@ struct work_struct;
#define LOADER_XFER_MODE_DMA BIT(0) #define LOADER_XFER_MODE_DMA BIT(0)
/** /**
* struct loader_msg_header - ISHTP firmware loader message header * union loader_msg_header - ISHTP firmware loader message header
* @command: Command type * @command: Command type
* @is_response: Indicates if the message is a response * @is_response: Indicates if the message is a response
* @has_next: Indicates if there is a next message * @has_next: Indicates if there is a next message
* @reserved: Reserved for future use * @reserved: Reserved for future use
* @status: Status of the message * @status: Status of the message
* @val32: entire header as a 32-bit value
*/ */
struct loader_msg_header { union loader_msg_header {
__le32 command:7; struct {
__le32 is_response:1; __u32 command:7;
__le32 has_next:1; __u32 is_response:1;
__le32 reserved:15; __u32 has_next:1;
__le32 status:8; __u32 reserved:15;
__u32 status:8;
};
__u32 val32;
}; };
/** /**
@ -51,7 +55,7 @@ struct loader_msg_header {
* @image_size: Size of the image * @image_size: Size of the image
*/ */
struct loader_xfer_query { struct loader_xfer_query {
struct loader_msg_header header; __le32 header;
__le32 image_size; __le32 image_size;
}; };
@ -103,7 +107,7 @@ struct loader_capability {
* @capability: Loader capability * @capability: Loader capability
*/ */
struct loader_xfer_query_ack { struct loader_xfer_query_ack {
struct loader_msg_header header; __le32 header;
__le16 version_major; __le16 version_major;
__le16 version_minor; __le16 version_minor;
__le16 version_hotfix; __le16 version_hotfix;
@ -122,7 +126,7 @@ struct loader_xfer_query_ack {
* @is_last: Is last * @is_last: Is last
*/ */
struct loader_xfer_fragment { struct loader_xfer_fragment {
struct loader_msg_header header; __le32 header;
__le32 xfer_mode; __le32 xfer_mode;
__le32 offset; __le32 offset;
__le32 size; __le32 size;
@ -134,7 +138,7 @@ struct loader_xfer_fragment {
* @header: Header of the message * @header: Header of the message
*/ */
struct loader_xfer_fragment_ack { struct loader_xfer_fragment_ack {
struct loader_msg_header header; __le32 header;
}; };
/** /**
@ -170,7 +174,7 @@ struct loader_xfer_dma_fragment {
* @header: Header of the message * @header: Header of the message
*/ */
struct loader_start { struct loader_start {
struct loader_msg_header header; __le32 header;
}; };
/** /**
@ -178,10 +182,11 @@ struct loader_start {
* @header: Header of the message * @header: Header of the message
*/ */
struct loader_start_ack { struct loader_start_ack {
struct loader_msg_header header; __le32 header;
}; };
union loader_recv_message { union loader_recv_message {
__le32 header;
struct loader_xfer_query_ack query_ack; struct loader_xfer_query_ack query_ack;
struct loader_xfer_fragment_ack fragment_ack; struct loader_xfer_fragment_ack fragment_ack;
struct loader_start_ack start_ack; struct loader_start_ack start_ack;

View File

@ -71,7 +71,6 @@ struct silead_ts_data {
struct regulator_bulk_data regulators[2]; struct regulator_bulk_data regulators[2];
char fw_name[64]; char fw_name[64];
struct touchscreen_properties prop; struct touchscreen_properties prop;
u32 max_fingers;
u32 chip_id; u32 chip_id;
struct input_mt_pos pos[SILEAD_MAX_FINGERS]; struct input_mt_pos pos[SILEAD_MAX_FINGERS];
int slots[SILEAD_MAX_FINGERS]; int slots[SILEAD_MAX_FINGERS];
@ -136,7 +135,7 @@ static int silead_ts_request_input_dev(struct silead_ts_data *data)
touchscreen_parse_properties(data->input, true, &data->prop); touchscreen_parse_properties(data->input, true, &data->prop);
silead_apply_efi_fw_min_max(data); silead_apply_efi_fw_min_max(data);
input_mt_init_slots(data->input, data->max_fingers, input_mt_init_slots(data->input, SILEAD_MAX_FINGERS,
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED |
INPUT_MT_TRACK); INPUT_MT_TRACK);
@ -256,10 +255,10 @@ static void silead_ts_read_data(struct i2c_client *client)
return; return;
} }
if (buf[0] > data->max_fingers) { if (buf[0] > SILEAD_MAX_FINGERS) {
dev_warn(dev, "More touches reported then supported %d > %d\n", dev_warn(dev, "More touches reported then supported %d > %d\n",
buf[0], data->max_fingers); buf[0], SILEAD_MAX_FINGERS);
buf[0] = data->max_fingers; buf[0] = SILEAD_MAX_FINGERS;
} }
if (silead_ts_handle_pen_data(data, buf)) if (silead_ts_handle_pen_data(data, buf))
@ -315,7 +314,6 @@ static void silead_ts_read_data(struct i2c_client *client)
static int silead_ts_init(struct i2c_client *client) static int silead_ts_init(struct i2c_client *client)
{ {
struct silead_ts_data *data = i2c_get_clientdata(client);
int error; int error;
error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET, error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET,
@ -325,7 +323,7 @@ static int silead_ts_init(struct i2c_client *client)
usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR, error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR,
data->max_fingers); SILEAD_MAX_FINGERS);
if (error) if (error)
goto i2c_write_err; goto i2c_write_err;
usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
@ -591,13 +589,6 @@ static void silead_ts_read_props(struct i2c_client *client)
const char *str; const char *str;
int error; int error;
error = device_property_read_u32(dev, "silead,max-fingers",
&data->max_fingers);
if (error) {
dev_dbg(dev, "Max fingers read error %d\n", error);
data->max_fingers = 5; /* Most devices handle up-to 5 fingers */
}
error = device_property_read_string(dev, "firmware-name", &str); error = device_property_read_string(dev, "firmware-name", &str);
if (!error) if (!error)
snprintf(data->fw_name, sizeof(data->fw_name), snprintf(data->fw_name, sizeof(data->fw_name),

View File

@ -129,7 +129,8 @@ static inline int check_feature_gpt_level(void)
static inline bool amd_iommu_gt_ppr_supported(void) static inline bool amd_iommu_gt_ppr_supported(void)
{ {
return (check_feature(FEATURE_GT) && return (check_feature(FEATURE_GT) &&
check_feature(FEATURE_PPR)); check_feature(FEATURE_PPR) &&
check_feature(FEATURE_EPHSUP));
} }
static inline u64 iommu_virt_to_phys(void *vaddr) static inline u64 iommu_virt_to_phys(void *vaddr)

View File

@ -1626,8 +1626,17 @@ static void __init free_pci_segments(void)
} }
} }
static void __init free_sysfs(struct amd_iommu *iommu)
{
if (iommu->iommu.dev) {
iommu_device_unregister(&iommu->iommu);
iommu_device_sysfs_remove(&iommu->iommu);
}
}
static void __init free_iommu_one(struct amd_iommu *iommu) static void __init free_iommu_one(struct amd_iommu *iommu)
{ {
free_sysfs(iommu);
free_cwwb_sem(iommu); free_cwwb_sem(iommu);
free_command_buffer(iommu); free_command_buffer(iommu);
free_event_buffer(iommu); free_event_buffer(iommu);

View File

@ -2032,7 +2032,6 @@ static int do_attach(struct iommu_dev_data *dev_data,
struct protection_domain *domain) struct protection_domain *domain)
{ {
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data); struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
struct pci_dev *pdev;
int ret = 0; int ret = 0;
/* Update data structures */ /* Update data structures */
@ -2047,30 +2046,13 @@ static int do_attach(struct iommu_dev_data *dev_data,
domain->dev_iommu[iommu->index] += 1; domain->dev_iommu[iommu->index] += 1;
domain->dev_cnt += 1; domain->dev_cnt += 1;
pdev = dev_is_pci(dev_data->dev) ? to_pci_dev(dev_data->dev) : NULL; /* Setup GCR3 table */
if (pdom_is_sva_capable(domain)) { if (pdom_is_sva_capable(domain)) {
ret = init_gcr3_table(dev_data, domain); ret = init_gcr3_table(dev_data, domain);
if (ret) if (ret)
return ret; return ret;
if (pdev) {
pdev_enable_caps(pdev);
/*
* Device can continue to function even if IOPF
* enablement failed. Hence in error path just
* disable device PRI support.
*/
if (amd_iommu_iopf_add_device(iommu, dev_data))
pdev_disable_cap_pri(pdev);
}
} else if (pdev) {
pdev_enable_cap_ats(pdev);
} }
/* Update device table */
amd_iommu_dev_update_dte(dev_data, true);
return ret; return ret;
} }
@ -2163,6 +2145,11 @@ static void detach_device(struct device *dev)
do_detach(dev_data); do_detach(dev_data);
out:
spin_unlock(&dev_data->lock);
spin_unlock_irqrestore(&domain->lock, flags);
/* Remove IOPF handler */ /* Remove IOPF handler */
if (ppr) if (ppr)
amd_iommu_iopf_remove_device(iommu, dev_data); amd_iommu_iopf_remove_device(iommu, dev_data);
@ -2170,10 +2157,6 @@ static void detach_device(struct device *dev)
if (dev_is_pci(dev)) if (dev_is_pci(dev))
pdev_disable_caps(to_pci_dev(dev)); pdev_disable_caps(to_pci_dev(dev));
out:
spin_unlock(&dev_data->lock);
spin_unlock_irqrestore(&domain->lock, flags);
} }
static struct iommu_device *amd_iommu_probe_device(struct device *dev) static struct iommu_device *amd_iommu_probe_device(struct device *dev)
@ -2485,6 +2468,7 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev); struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
struct protection_domain *domain = to_pdomain(dom); struct protection_domain *domain = to_pdomain(dom);
struct amd_iommu *iommu = get_amd_iommu_from_dev(dev); struct amd_iommu *iommu = get_amd_iommu_from_dev(dev);
struct pci_dev *pdev;
int ret; int ret;
/* /*
@ -2517,7 +2501,23 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
} }
#endif #endif
iommu_completion_wait(iommu); pdev = dev_is_pci(dev_data->dev) ? to_pci_dev(dev_data->dev) : NULL;
if (pdev && pdom_is_sva_capable(domain)) {
pdev_enable_caps(pdev);
/*
* Device can continue to function even if IOPF
* enablement failed. Hence in error path just
* disable device PRI support.
*/
if (amd_iommu_iopf_add_device(iommu, dev_data))
pdev_disable_cap_pri(pdev);
} else if (pdev) {
pdev_enable_cap_ats(pdev);
}
/* Update device table */
amd_iommu_dev_update_dte(dev_data, true);
return ret; return ret;
} }

View File

@ -222,8 +222,7 @@ int amd_iommu_iopf_init(struct amd_iommu *iommu)
if (iommu->iopf_queue) if (iommu->iopf_queue)
return ret; return ret;
snprintf(iommu->iopfq_name, sizeof(iommu->iopfq_name), snprintf(iommu->iopfq_name, sizeof(iommu->iopfq_name), "amdvi-%#x",
"amdiommu-%#x-iopfq",
PCI_SEG_DEVID_TO_SBDF(iommu->pci_seg->id, iommu->devid)); PCI_SEG_DEVID_TO_SBDF(iommu->pci_seg->id, iommu->devid));
iommu->iopf_queue = iopf_queue_alloc(iommu->iopfq_name); iommu->iopf_queue = iopf_queue_alloc(iommu->iopfq_name);
@ -249,40 +248,26 @@ void amd_iommu_page_response(struct device *dev, struct iopf_fault *evt,
int amd_iommu_iopf_add_device(struct amd_iommu *iommu, int amd_iommu_iopf_add_device(struct amd_iommu *iommu,
struct iommu_dev_data *dev_data) struct iommu_dev_data *dev_data)
{ {
unsigned long flags;
int ret = 0; int ret = 0;
if (!dev_data->pri_enabled) if (!dev_data->pri_enabled)
return ret; return ret;
raw_spin_lock_irqsave(&iommu->lock, flags); if (!iommu->iopf_queue)
return -EINVAL;
if (!iommu->iopf_queue) {
ret = -EINVAL;
goto out_unlock;
}
ret = iopf_queue_add_device(iommu->iopf_queue, dev_data->dev); ret = iopf_queue_add_device(iommu->iopf_queue, dev_data->dev);
if (ret) if (ret)
goto out_unlock; return ret;
dev_data->ppr = true; dev_data->ppr = true;
return 0;
out_unlock:
raw_spin_unlock_irqrestore(&iommu->lock, flags);
return ret;
} }
/* Its assumed that caller has verified that device was added to iopf queue */ /* Its assumed that caller has verified that device was added to iopf queue */
void amd_iommu_iopf_remove_device(struct amd_iommu *iommu, void amd_iommu_iopf_remove_device(struct amd_iommu *iommu,
struct iommu_dev_data *dev_data) struct iommu_dev_data *dev_data)
{ {
unsigned long flags;
raw_spin_lock_irqsave(&iommu->lock, flags);
iopf_queue_remove_device(iommu->iopf_queue, dev_data->dev); iopf_queue_remove_device(iommu->iopf_queue, dev_data->dev);
dev_data->ppr = false; dev_data->ppr = false;
raw_spin_unlock_irqrestore(&iommu->lock, flags);
} }

View File

@ -686,15 +686,15 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, struct device *dev
/* Check the domain allows at least some access to the device... */ /* Check the domain allows at least some access to the device... */
if (map) { if (map) {
dma_addr_t base = dma_range_map_min(map); if (dma_range_map_min(map) > domain->geometry.aperture_end ||
if (base > domain->geometry.aperture_end ||
dma_range_map_max(map) < domain->geometry.aperture_start) { dma_range_map_max(map) < domain->geometry.aperture_start) {
pr_warn("specified DMA range outside IOMMU capability\n"); pr_warn("specified DMA range outside IOMMU capability\n");
return -EFAULT; return -EFAULT;
} }
/* ...then finally give it a kicking to make sure it fits */
base_pfn = max(base, domain->geometry.aperture_start) >> order;
} }
/* ...then finally give it a kicking to make sure it fits */
base_pfn = max_t(unsigned long, base_pfn,
domain->geometry.aperture_start >> order);
/* start_pfn is always nonzero for an already-initialised domain */ /* start_pfn is always nonzero for an already-initialised domain */
mutex_lock(&cookie->mutex); mutex_lock(&cookie->mutex);

View File

@ -1846,28 +1846,22 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
{ {
struct its_device *its_dev = irq_data_get_irq_chip_data(d); struct its_device *its_dev = irq_data_get_irq_chip_data(d);
u32 event = its_get_event_id(d); u32 event = its_get_event_id(d);
int ret = 0;
if (!info->map) if (!info->map)
return -EINVAL; return -EINVAL;
raw_spin_lock(&its_dev->event_map.vlpi_lock);
if (!its_dev->event_map.vm) { if (!its_dev->event_map.vm) {
struct its_vlpi_map *maps; struct its_vlpi_map *maps;
maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps), maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps),
GFP_ATOMIC); GFP_ATOMIC);
if (!maps) { if (!maps)
ret = -ENOMEM; return -ENOMEM;
goto out;
}
its_dev->event_map.vm = info->map->vm; its_dev->event_map.vm = info->map->vm;
its_dev->event_map.vlpi_maps = maps; its_dev->event_map.vlpi_maps = maps;
} else if (its_dev->event_map.vm != info->map->vm) { } else if (its_dev->event_map.vm != info->map->vm) {
ret = -EINVAL; return -EINVAL;
goto out;
} }
/* Get our private copy of the mapping information */ /* Get our private copy of the mapping information */
@ -1899,46 +1893,32 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
its_dev->event_map.nr_vlpis++; its_dev->event_map.nr_vlpis++;
} }
out: return 0;
raw_spin_unlock(&its_dev->event_map.vlpi_lock);
return ret;
} }
static int its_vlpi_get(struct irq_data *d, struct its_cmd_info *info) static int its_vlpi_get(struct irq_data *d, struct its_cmd_info *info)
{ {
struct its_device *its_dev = irq_data_get_irq_chip_data(d); struct its_device *its_dev = irq_data_get_irq_chip_data(d);
struct its_vlpi_map *map; struct its_vlpi_map *map;
int ret = 0;
raw_spin_lock(&its_dev->event_map.vlpi_lock);
map = get_vlpi_map(d); map = get_vlpi_map(d);
if (!its_dev->event_map.vm || !map) { if (!its_dev->event_map.vm || !map)
ret = -EINVAL; return -EINVAL;
goto out;
}
/* Copy our mapping information to the incoming request */ /* Copy our mapping information to the incoming request */
*info->map = *map; *info->map = *map;
out: return 0;
raw_spin_unlock(&its_dev->event_map.vlpi_lock);
return ret;
} }
static int its_vlpi_unmap(struct irq_data *d) static int its_vlpi_unmap(struct irq_data *d)
{ {
struct its_device *its_dev = irq_data_get_irq_chip_data(d); struct its_device *its_dev = irq_data_get_irq_chip_data(d);
u32 event = its_get_event_id(d); u32 event = its_get_event_id(d);
int ret = 0;
raw_spin_lock(&its_dev->event_map.vlpi_lock); if (!its_dev->event_map.vm || !irqd_is_forwarded_to_vcpu(d))
return -EINVAL;
if (!its_dev->event_map.vm || !irqd_is_forwarded_to_vcpu(d)) {
ret = -EINVAL;
goto out;
}
/* Drop the virtual mapping */ /* Drop the virtual mapping */
its_send_discard(its_dev, event); its_send_discard(its_dev, event);
@ -1962,9 +1942,7 @@ static int its_vlpi_unmap(struct irq_data *d)
kfree(its_dev->event_map.vlpi_maps); kfree(its_dev->event_map.vlpi_maps);
} }
out: return 0;
raw_spin_unlock(&its_dev->event_map.vlpi_lock);
return ret;
} }
static int its_vlpi_prop_update(struct irq_data *d, struct its_cmd_info *info) static int its_vlpi_prop_update(struct irq_data *d, struct its_cmd_info *info)
@ -1992,6 +1970,8 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
if (!is_v4(its_dev->its)) if (!is_v4(its_dev->its))
return -EINVAL; return -EINVAL;
guard(raw_spinlock_irq)(&its_dev->event_map.vlpi_lock);
/* Unmap request? */ /* Unmap request? */
if (!info) if (!info)
return its_vlpi_unmap(d); return its_vlpi_unmap(d);

View File

@ -253,8 +253,9 @@ IRQCHIP_DECLARE(andes, "andestech,cpu-intc", riscv_intc_init);
static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
const unsigned long end) const unsigned long end)
{ {
struct fwnode_handle *fn;
struct acpi_madt_rintc *rintc; struct acpi_madt_rintc *rintc;
struct fwnode_handle *fn;
int rc;
rintc = (struct acpi_madt_rintc *)header; rintc = (struct acpi_madt_rintc *)header;
@ -273,7 +274,11 @@ static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
return -ENOMEM; return -ENOMEM;
} }
return riscv_intc_init_common(fn, &riscv_intc_chip); rc = riscv_intc_init_common(fn, &riscv_intc_chip);
if (rc)
irq_domain_free_fwnode(fn);
return rc;
} }
IRQCHIP_ACPI_DECLARE(riscv_intc, ACPI_MADT_TYPE_RINTC, NULL, IRQCHIP_ACPI_DECLARE(riscv_intc, ACPI_MADT_TYPE_RINTC, NULL,

View File

@ -85,7 +85,7 @@ struct plic_handler {
struct plic_priv *priv; struct plic_priv *priv;
}; };
static int plic_parent_irq __ro_after_init; static int plic_parent_irq __ro_after_init;
static bool plic_cpuhp_setup_done __ro_after_init; static bool plic_global_setup_done __ro_after_init;
static DEFINE_PER_CPU(struct plic_handler, plic_handlers); static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
static int plic_irq_set_type(struct irq_data *d, unsigned int type); static int plic_irq_set_type(struct irq_data *d, unsigned int type);
@ -487,10 +487,8 @@ static int plic_probe(struct platform_device *pdev)
unsigned long plic_quirks = 0; unsigned long plic_quirks = 0;
struct plic_handler *handler; struct plic_handler *handler;
u32 nr_irqs, parent_hwirq; u32 nr_irqs, parent_hwirq;
struct irq_domain *domain;
struct plic_priv *priv; struct plic_priv *priv;
irq_hw_number_t hwirq; irq_hw_number_t hwirq;
bool cpuhp_setup;
if (is_of_node(dev->fwnode)) { if (is_of_node(dev->fwnode)) {
const struct of_device_id *id; const struct of_device_id *id;
@ -549,14 +547,6 @@ static int plic_probe(struct platform_device *pdev)
continue; continue;
} }
/* Find parent domain and register chained handler */
domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
if (!plic_parent_irq && domain) {
plic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
if (plic_parent_irq)
irq_set_chained_handler(plic_parent_irq, plic_handle_irq);
}
/* /*
* When running in M-mode we need to ignore the S-mode handler. * When running in M-mode we need to ignore the S-mode handler.
* Here we assume it always comes later, but that might be a * Here we assume it always comes later, but that might be a
@ -597,25 +587,35 @@ static int plic_probe(struct platform_device *pdev)
goto fail_cleanup_contexts; goto fail_cleanup_contexts;
/* /*
* We can have multiple PLIC instances so setup cpuhp state * We can have multiple PLIC instances so setup global state
* and register syscore operations only once after context * and register syscore operations only once after context
* handlers of all online CPUs are initialized. * handlers of all online CPUs are initialized.
*/ */
if (!plic_cpuhp_setup_done) { if (!plic_global_setup_done) {
cpuhp_setup = true; struct irq_domain *domain;
bool global_setup = true;
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
handler = per_cpu_ptr(&plic_handlers, cpu); handler = per_cpu_ptr(&plic_handlers, cpu);
if (!handler->present) { if (!handler->present) {
cpuhp_setup = false; global_setup = false;
break; break;
} }
} }
if (cpuhp_setup) {
if (global_setup) {
/* Find parent domain and register chained handler */
domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
if (domain)
plic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
if (plic_parent_irq)
irq_set_chained_handler(plic_parent_irq, plic_handle_irq);
cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING, cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
"irqchip/sifive/plic:starting", "irqchip/sifive/plic:starting",
plic_starting_cpu, plic_dying_cpu); plic_starting_cpu, plic_dying_cpu);
register_syscore_ops(&plic_irq_syscore_ops); register_syscore_ops(&plic_irq_syscore_ops);
plic_cpuhp_setup_done = true; plic_global_setup_done = true;
} }
} }

View File

@ -301,10 +301,10 @@ static int ipu6_isys_stream_start(struct ipu6_isys_video *av,
out_requeue: out_requeue:
if (bl && bl->nbufs) if (bl && bl->nbufs)
ipu6_isys_buffer_list_queue(bl, ipu6_isys_buffer_list_queue(bl,
(IPU6_ISYS_BUFFER_LIST_FL_INCOMING | IPU6_ISYS_BUFFER_LIST_FL_INCOMING |
error) ? (error ?
IPU6_ISYS_BUFFER_LIST_FL_SET_STATE : IPU6_ISYS_BUFFER_LIST_FL_SET_STATE :
0, error ? VB2_BUF_STATE_ERROR : 0), error ? VB2_BUF_STATE_ERROR :
VB2_BUF_STATE_QUEUED); VB2_BUF_STATE_QUEUED);
flush_firmware_streamon_fail(stream); flush_firmware_streamon_fail(stream);

View File

@ -678,6 +678,12 @@ static int isys_notifier_bound(struct v4l2_async_notifier *notifier,
container_of(asc, struct sensor_async_sd, asc); container_of(asc, struct sensor_async_sd, asc);
int ret; int ret;
if (s_asd->csi2.port >= isys->pdata->ipdata->csi2.nports) {
dev_err(&isys->adev->auxdev.dev, "invalid csi2 port %u\n",
s_asd->csi2.port);
return -EINVAL;
}
ret = ipu_bridge_instantiate_vcm(sd->dev); ret = ipu_bridge_instantiate_vcm(sd->dev);
if (ret) { if (ret) {
dev_err(&isys->adev->auxdev.dev, "instantiate vcm failed\n"); dev_err(&isys->adev->auxdev.dev, "instantiate vcm failed\n");
@ -925,39 +931,18 @@ static const struct dev_pm_ops isys_pm_ops = {
.resume = isys_resume, .resume = isys_resume,
}; };
static void isys_remove(struct auxiliary_device *auxdev) static void free_fw_msg_bufs(struct ipu6_isys *isys)
{ {
struct ipu6_bus_device *adev = auxdev_to_adev(auxdev); struct device *dev = &isys->adev->auxdev.dev;
struct ipu6_isys *isys = dev_get_drvdata(&auxdev->dev);
struct ipu6_device *isp = adev->isp;
struct isys_fw_msgs *fwmsg, *safe; struct isys_fw_msgs *fwmsg, *safe;
unsigned int i;
list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist, head) list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist, head)
dma_free_attrs(&auxdev->dev, sizeof(struct isys_fw_msgs), dma_free_attrs(dev, sizeof(struct isys_fw_msgs), fwmsg,
fwmsg, fwmsg->dma_addr, 0); fwmsg->dma_addr, 0);
list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist_fw, head) list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist_fw, head)
dma_free_attrs(&auxdev->dev, sizeof(struct isys_fw_msgs), dma_free_attrs(dev, sizeof(struct isys_fw_msgs), fwmsg,
fwmsg, fwmsg->dma_addr, 0); fwmsg->dma_addr, 0);
isys_unregister_devices(isys);
isys_notifier_cleanup(isys);
cpu_latency_qos_remove_request(&isys->pm_qos);
if (!isp->secure_mode) {
ipu6_cpd_free_pkg_dir(adev);
ipu6_buttress_unmap_fw_image(adev, &adev->fw_sgt);
release_firmware(adev->fw);
}
for (i = 0; i < IPU6_ISYS_MAX_STREAMS; i++)
mutex_destroy(&isys->streams[i].mutex);
isys_iwake_watermark_cleanup(isys);
mutex_destroy(&isys->stream_mutex);
mutex_destroy(&isys->mutex);
} }
static int alloc_fw_msg_bufs(struct ipu6_isys *isys, int amount) static int alloc_fw_msg_bufs(struct ipu6_isys *isys, int amount)
@ -1140,12 +1125,14 @@ static int isys_probe(struct auxiliary_device *auxdev,
ret = isys_register_devices(isys); ret = isys_register_devices(isys);
if (ret) if (ret)
goto out_remove_pkg_dir_shared_buffer; goto free_fw_msg_bufs;
ipu6_mmu_hw_cleanup(adev->mmu); ipu6_mmu_hw_cleanup(adev->mmu);
return 0; return 0;
free_fw_msg_bufs:
free_fw_msg_bufs(isys);
out_remove_pkg_dir_shared_buffer: out_remove_pkg_dir_shared_buffer:
if (!isp->secure_mode) if (!isp->secure_mode)
ipu6_cpd_free_pkg_dir(adev); ipu6_cpd_free_pkg_dir(adev);
@ -1167,6 +1154,34 @@ static int isys_probe(struct auxiliary_device *auxdev,
return ret; return ret;
} }
static void isys_remove(struct auxiliary_device *auxdev)
{
struct ipu6_bus_device *adev = auxdev_to_adev(auxdev);
struct ipu6_isys *isys = dev_get_drvdata(&auxdev->dev);
struct ipu6_device *isp = adev->isp;
unsigned int i;
free_fw_msg_bufs(isys);
isys_unregister_devices(isys);
isys_notifier_cleanup(isys);
cpu_latency_qos_remove_request(&isys->pm_qos);
if (!isp->secure_mode) {
ipu6_cpd_free_pkg_dir(adev);
ipu6_buttress_unmap_fw_image(adev, &adev->fw_sgt);
release_firmware(adev->fw);
}
for (i = 0; i < IPU6_ISYS_MAX_STREAMS; i++)
mutex_destroy(&isys->streams[i].mutex);
isys_iwake_watermark_cleanup(isys);
mutex_destroy(&isys->stream_mutex);
mutex_destroy(&isys->mutex);
}
struct fwmsg { struct fwmsg {
int type; int type;
char *msg; char *msg;

View File

@ -285,7 +285,7 @@ EXPORT_SYMBOL_NS_GPL(ipu6_configure_spc, INTEL_IPU6);
#define IPU6_ISYS_CSI2_NPORTS 4 #define IPU6_ISYS_CSI2_NPORTS 4
#define IPU6SE_ISYS_CSI2_NPORTS 4 #define IPU6SE_ISYS_CSI2_NPORTS 4
#define IPU6_TGL_ISYS_CSI2_NPORTS 8 #define IPU6_TGL_ISYS_CSI2_NPORTS 8
#define IPU6EP_MTL_ISYS_CSI2_NPORTS 4 #define IPU6EP_MTL_ISYS_CSI2_NPORTS 6
static void ipu6_internal_pdata_init(struct ipu6_device *isp) static void ipu6_internal_pdata_init(struct ipu6_device *isp)
{ {
@ -727,9 +727,6 @@ static void ipu6_pci_remove(struct pci_dev *pdev)
pm_runtime_forbid(&pdev->dev); pm_runtime_forbid(&pdev->dev);
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
release_firmware(isp->cpd_fw); release_firmware(isp->cpd_fw);
ipu6_mmu_cleanup(psys_mmu); ipu6_mmu_cleanup(psys_mmu);

View File

@ -677,10 +677,13 @@ static int mei_csi_probe(struct mei_cl_device *cldev,
return -ENODEV; return -ENODEV;
ret = ipu_bridge_init(&ipu->dev, ipu_bridge_parse_ssdb); ret = ipu_bridge_init(&ipu->dev, ipu_bridge_parse_ssdb);
put_device(&ipu->dev);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (WARN_ON(!dev_fwnode(dev))) if (!dev_fwnode(dev)) {
dev_err(dev, "mei-csi probed without device fwnode!\n");
return -ENXIO; return -ENXIO;
}
csi = devm_kzalloc(dev, sizeof(struct mei_csi), GFP_KERNEL); csi = devm_kzalloc(dev, sizeof(struct mei_csi), GFP_KERNEL);
if (!csi) if (!csi)

View File

@ -642,9 +642,6 @@ static void mgb4_remove(struct pci_dev *pdev)
struct mgb4_dev *mgbdev = pci_get_drvdata(pdev); struct mgb4_dev *mgbdev = pci_get_drvdata(pdev);
int i; int i;
#ifdef CONFIG_DEBUG_FS
debugfs_remove_recursive(mgbdev->debugfs);
#endif
#if IS_REACHABLE(CONFIG_HWMON) #if IS_REACHABLE(CONFIG_HWMON)
hwmon_device_unregister(mgbdev->hwmon_dev); hwmon_device_unregister(mgbdev->hwmon_dev);
#endif #endif
@ -659,6 +656,10 @@ static void mgb4_remove(struct pci_dev *pdev)
if (mgbdev->vin[i]) if (mgbdev->vin[i])
mgb4_vin_free(mgbdev->vin[i]); mgb4_vin_free(mgbdev->vin[i]);
#ifdef CONFIG_DEBUG_FS
debugfs_remove_recursive(mgbdev->debugfs);
#endif
device_remove_groups(&mgbdev->pdev->dev, mgb4_pci_groups); device_remove_groups(&mgbdev->pdev->dev, mgb4_pci_groups);
free_spi(mgbdev); free_spi(mgbdev);
free_i2c(mgbdev); free_i2c(mgbdev);

View File

@ -5152,7 +5152,7 @@ struct saa7134_board saa7134_boards[] = {
}, },
}, },
[SAA7134_BOARD_AVERMEDIA_STUDIO_507UA] = { [SAA7134_BOARD_AVERMEDIA_STUDIO_507UA] = {
/* Andy Shevchenko <andy@smile.org.ua> */ /* Andy Shevchenko <andy@kernel.org> */
.name = "Avermedia AVerTV Studio 507UA", .name = "Avermedia AVerTV Studio 507UA",
.audio_clock = 0x00187de7, .audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* Should be MK5 */ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* Should be MK5 */

View File

@ -431,8 +431,11 @@ qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int p
init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d",
priv->internal_mdio_bus->id, priv->internal_mdio_bus->id,
port_num); port_num);
if (!init_data.devicename) if (!init_data.devicename) {
fwnode_handle_put(led);
fwnode_handle_put(leds);
return -ENOMEM; return -ENOMEM;
}
ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data); ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
if (ret) if (ret)
@ -441,6 +444,7 @@ qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int p
kfree(init_data.devicename); kfree(init_data.devicename);
} }
fwnode_handle_put(leds);
return 0; return 0;
} }
@ -471,9 +475,13 @@ qca8k_setup_led_ctrl(struct qca8k_priv *priv)
* the correct port for LED setup. * the correct port for LED setup.
*/ */
ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num)); ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num));
if (ret) if (ret) {
fwnode_handle_put(port);
fwnode_handle_put(ports);
return ret; return ret;
}
} }
fwnode_handle_put(ports);
return 0; return 0;
} }

View File

@ -1434,6 +1434,57 @@ struct bnxt_l2_filter {
atomic_t refcnt; atomic_t refcnt;
}; };
/* Compat version of hwrm_port_phy_qcfg_output capped at 96 bytes. The
* first 95 bytes are identical to hwrm_port_phy_qcfg_output in bnxt_hsi.h.
* The last valid byte in the compat version is different.
*/
struct hwrm_port_phy_qcfg_output_compat {
__le16 error_code;
__le16 req_type;
__le16 seq_id;
__le16 resp_len;
u8 link;
u8 active_fec_signal_mode;
__le16 link_speed;
u8 duplex_cfg;
u8 pause;
__le16 support_speeds;
__le16 force_link_speed;
u8 auto_mode;
u8 auto_pause;
__le16 auto_link_speed;
__le16 auto_link_speed_mask;
u8 wirespeed;
u8 lpbk;
u8 force_pause;
u8 module_status;
__le32 preemphasis;
u8 phy_maj;
u8 phy_min;
u8 phy_bld;
u8 phy_type;
u8 media_type;
u8 xcvr_pkg_type;
u8 eee_config_phy_addr;
u8 parallel_detect;
__le16 link_partner_adv_speeds;
u8 link_partner_adv_auto_mode;
u8 link_partner_adv_pause;
__le16 adv_eee_link_speed_mask;
__le16 link_partner_adv_eee_link_speed_mask;
__le32 xcvr_identifier_type_tx_lpi_timer;
__le16 fec_cfg;
u8 duplex_state;
u8 option_flags;
char phy_vendor_name[16];
char phy_vendor_partnumber[16];
__le16 support_pam4_speeds;
__le16 force_pam4_link_speed;
__le16 auto_pam4_link_speed_mask;
u8 link_partner_pam4_adv_speeds;
u8 valid;
};
struct bnxt_link_info { struct bnxt_link_info {
u8 phy_type; u8 phy_type;
u8 media_type; u8 media_type;

View File

@ -680,7 +680,7 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
req_type); req_type);
else if (rc && rc != HWRM_ERR_CODE_PF_UNAVAILABLE) else if (rc && rc != HWRM_ERR_CODE_PF_UNAVAILABLE)
hwrm_err(bp, ctx, "hwrm req_type 0x%x seq id 0x%x error 0x%x\n", hwrm_err(bp, ctx, "hwrm req_type 0x%x seq id 0x%x error 0x%x\n",
req_type, token->seq_id, rc); req_type, le16_to_cpu(ctx->req->seq_id), rc);
rc = __hwrm_to_stderr(rc); rc = __hwrm_to_stderr(rc);
exit: exit:
if (token) if (token)

View File

@ -950,8 +950,11 @@ static int bnxt_hwrm_fwd_resp(struct bnxt *bp, struct bnxt_vf_info *vf,
struct hwrm_fwd_resp_input *req; struct hwrm_fwd_resp_input *req;
int rc; int rc;
if (BNXT_FWD_RESP_SIZE_ERR(msg_size)) if (BNXT_FWD_RESP_SIZE_ERR(msg_size)) {
netdev_warn_once(bp->dev, "HWRM fwd response too big (%d bytes)\n",
msg_size);
return -EINVAL; return -EINVAL;
}
rc = hwrm_req_init(bp, req, HWRM_FWD_RESP); rc = hwrm_req_init(bp, req, HWRM_FWD_RESP);
if (!rc) { if (!rc) {
@ -1085,7 +1088,7 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf)
rc = bnxt_hwrm_exec_fwd_resp( rc = bnxt_hwrm_exec_fwd_resp(
bp, vf, sizeof(struct hwrm_port_phy_qcfg_input)); bp, vf, sizeof(struct hwrm_port_phy_qcfg_input));
} else { } else {
struct hwrm_port_phy_qcfg_output phy_qcfg_resp = {0}; struct hwrm_port_phy_qcfg_output_compat phy_qcfg_resp = {};
struct hwrm_port_phy_qcfg_input *phy_qcfg_req; struct hwrm_port_phy_qcfg_input *phy_qcfg_req;
phy_qcfg_req = phy_qcfg_req =
@ -1096,6 +1099,11 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf)
mutex_unlock(&bp->link_lock); mutex_unlock(&bp->link_lock);
phy_qcfg_resp.resp_len = cpu_to_le16(sizeof(phy_qcfg_resp)); phy_qcfg_resp.resp_len = cpu_to_le16(sizeof(phy_qcfg_resp));
phy_qcfg_resp.seq_id = phy_qcfg_req->seq_id; phy_qcfg_resp.seq_id = phy_qcfg_req->seq_id;
/* New SPEEDS2 fields are beyond the legacy structure, so
* clear the SPEEDS2_SUPPORTED flag.
*/
phy_qcfg_resp.option_flags &=
~PORT_PHY_QCAPS_RESP_FLAGS2_SPEEDS2_SUPPORTED;
phy_qcfg_resp.valid = 1; phy_qcfg_resp.valid = 1;
if (vf->flags & BNXT_VF_LINK_UP) { if (vf->flags & BNXT_VF_LINK_UP) {

View File

@ -272,13 +272,12 @@ lio_vf_rep_copy_packet(struct octeon_device *oct,
pg_info->page_offset; pg_info->page_offset;
memcpy(skb->data, va, MIN_SKB_SIZE); memcpy(skb->data, va, MIN_SKB_SIZE);
skb_put(skb, MIN_SKB_SIZE); skb_put(skb, MIN_SKB_SIZE);
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
pg_info->page,
pg_info->page_offset + MIN_SKB_SIZE,
len - MIN_SKB_SIZE,
LIO_RXBUFFER_SZ);
} }
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
pg_info->page,
pg_info->page_offset + MIN_SKB_SIZE,
len - MIN_SKB_SIZE,
LIO_RXBUFFER_SZ);
} else { } else {
struct octeon_skb_page_info *pg_info = struct octeon_skb_page_info *pg_info =
((struct octeon_skb_page_info *)(skb->cb)); ((struct octeon_skb_page_info *)(skb->cb));

View File

@ -647,11 +647,13 @@ static void gve_rx_skb_hash(struct sk_buff *skb,
skb_set_hash(skb, le32_to_cpu(compl_desc->hash), hash_type); skb_set_hash(skb, le32_to_cpu(compl_desc->hash), hash_type);
} }
static void gve_rx_free_skb(struct gve_rx_ring *rx) static void gve_rx_free_skb(struct napi_struct *napi, struct gve_rx_ring *rx)
{ {
if (!rx->ctx.skb_head) if (!rx->ctx.skb_head)
return; return;
if (rx->ctx.skb_head == napi->skb)
napi->skb = NULL;
dev_kfree_skb_any(rx->ctx.skb_head); dev_kfree_skb_any(rx->ctx.skb_head);
rx->ctx.skb_head = NULL; rx->ctx.skb_head = NULL;
rx->ctx.skb_tail = NULL; rx->ctx.skb_tail = NULL;
@ -950,7 +952,7 @@ int gve_rx_poll_dqo(struct gve_notify_block *block, int budget)
err = gve_rx_dqo(napi, rx, compl_desc, complq->head, rx->q_num); err = gve_rx_dqo(napi, rx, compl_desc, complq->head, rx->q_num);
if (err < 0) { if (err < 0) {
gve_rx_free_skb(rx); gve_rx_free_skb(napi, rx);
u64_stats_update_begin(&rx->statss); u64_stats_update_begin(&rx->statss);
if (err == -ENOMEM) if (err == -ENOMEM)
rx->rx_skb_alloc_fail++; rx->rx_skb_alloc_fail++;
@ -993,7 +995,7 @@ int gve_rx_poll_dqo(struct gve_notify_block *block, int budget)
/* gve_rx_complete_skb() will consume skb if successful */ /* gve_rx_complete_skb() will consume skb if successful */
if (gve_rx_complete_skb(rx, napi, compl_desc, feat) != 0) { if (gve_rx_complete_skb(rx, napi, compl_desc, feat) != 0) {
gve_rx_free_skb(rx); gve_rx_free_skb(napi, rx);
u64_stats_update_begin(&rx->statss); u64_stats_update_begin(&rx->statss);
rx->rx_desc_err_dropped_pkt++; rx->rx_desc_err_dropped_pkt++;
u64_stats_update_end(&rx->statss); u64_stats_update_end(&rx->statss);

View File

@ -555,28 +555,18 @@ static int gve_prep_tso(struct sk_buff *skb)
if (unlikely(skb_shinfo(skb)->gso_size < GVE_TX_MIN_TSO_MSS_DQO)) if (unlikely(skb_shinfo(skb)->gso_size < GVE_TX_MIN_TSO_MSS_DQO))
return -1; return -1;
if (!(skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
return -EINVAL;
/* Needed because we will modify header. */ /* Needed because we will modify header. */
err = skb_cow_head(skb, 0); err = skb_cow_head(skb, 0);
if (err < 0) if (err < 0)
return err; return err;
tcp = tcp_hdr(skb); tcp = tcp_hdr(skb);
/* Remove payload length from checksum. */
paylen = skb->len - skb_transport_offset(skb); paylen = skb->len - skb_transport_offset(skb);
csum_replace_by_diff(&tcp->check, (__force __wsum)htonl(paylen));
switch (skb_shinfo(skb)->gso_type) { header_len = skb_tcp_all_headers(skb);
case SKB_GSO_TCPV4:
case SKB_GSO_TCPV6:
csum_replace_by_diff(&tcp->check,
(__force __wsum)htonl(paylen));
/* Compute length of segmentation header. */
header_len = skb_tcp_all_headers(skb);
break;
default:
return -EINVAL;
}
if (unlikely(header_len > GVE_TX_MAX_HDR_SIZE_DQO)) if (unlikely(header_len > GVE_TX_MAX_HDR_SIZE_DQO))
return -EINVAL; return -EINVAL;

View File

@ -3535,6 +3535,9 @@ static int hns3_alloc_ring_buffers(struct hns3_enet_ring *ring)
ret = hns3_alloc_and_attach_buffer(ring, i); ret = hns3_alloc_and_attach_buffer(ring, i);
if (ret) if (ret)
goto out_buffer_fail; goto out_buffer_fail;
if (!(i % HNS3_RESCHED_BD_NUM))
cond_resched();
} }
return 0; return 0;
@ -5107,6 +5110,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv)
} }
u64_stats_init(&priv->ring[i].syncp); u64_stats_init(&priv->ring[i].syncp);
cond_resched();
} }
return 0; return 0;

View File

@ -214,6 +214,8 @@ enum hns3_nic_state {
#define HNS3_CQ_MODE_EQE 1U #define HNS3_CQ_MODE_EQE 1U
#define HNS3_CQ_MODE_CQE 0U #define HNS3_CQ_MODE_CQE 0U
#define HNS3_RESCHED_BD_NUM 1024
enum hns3_pkt_l2t_type { enum hns3_pkt_l2t_type {
HNS3_L2_TYPE_UNICAST, HNS3_L2_TYPE_UNICAST,
HNS3_L2_TYPE_MULTICAST, HNS3_L2_TYPE_MULTICAST,

View File

@ -3086,9 +3086,7 @@ static void hclge_push_link_status(struct hclge_dev *hdev)
static void hclge_update_link_status(struct hclge_dev *hdev) static void hclge_update_link_status(struct hclge_dev *hdev)
{ {
struct hnae3_handle *rhandle = &hdev->vport[0].roce;
struct hnae3_handle *handle = &hdev->vport[0].nic; struct hnae3_handle *handle = &hdev->vport[0].nic;
struct hnae3_client *rclient = hdev->roce_client;
struct hnae3_client *client = hdev->nic_client; struct hnae3_client *client = hdev->nic_client;
int state; int state;
int ret; int ret;
@ -3112,8 +3110,15 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
client->ops->link_status_change(handle, state); client->ops->link_status_change(handle, state);
hclge_config_mac_tnl_int(hdev, state); hclge_config_mac_tnl_int(hdev, state);
if (rclient && rclient->ops->link_status_change)
rclient->ops->link_status_change(rhandle, state); if (test_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state)) {
struct hnae3_handle *rhandle = &hdev->vport[0].roce;
struct hnae3_client *rclient = hdev->roce_client;
if (rclient && rclient->ops->link_status_change)
rclient->ops->link_status_change(rhandle,
state);
}
hclge_push_link_status(hdev); hclge_push_link_status(hdev);
} }
@ -11319,6 +11324,12 @@ static int hclge_init_client_instance(struct hnae3_client *client,
return ret; return ret;
} }
static bool hclge_uninit_need_wait(struct hclge_dev *hdev)
{
return test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) ||
test_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state);
}
static void hclge_uninit_client_instance(struct hnae3_client *client, static void hclge_uninit_client_instance(struct hnae3_client *client,
struct hnae3_ae_dev *ae_dev) struct hnae3_ae_dev *ae_dev)
{ {
@ -11327,7 +11338,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
if (hdev->roce_client) { if (hdev->roce_client) {
clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state); clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state);
while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) while (hclge_uninit_need_wait(hdev))
msleep(HCLGE_WAIT_RESET_DONE); msleep(HCLGE_WAIT_RESET_DONE);
hdev->roce_client->ops->uninit_instance(&vport->roce, 0); hdev->roce_client->ops->uninit_instance(&vport->roce, 0);

View File

@ -7032,6 +7032,8 @@ static int igc_probe(struct pci_dev *pdev,
device_set_wakeup_enable(&adapter->pdev->dev, device_set_wakeup_enable(&adapter->pdev->dev,
adapter->flags & IGC_FLAG_WOL_SUPPORTED); adapter->flags & IGC_FLAG_WOL_SUPPORTED);
igc_ptp_init(adapter);
igc_tsn_clear_schedule(adapter); igc_tsn_clear_schedule(adapter);
/* reset the hardware with the new settings */ /* reset the hardware with the new settings */
@ -7053,9 +7055,6 @@ static int igc_probe(struct pci_dev *pdev,
/* Check if Media Autosense is enabled */ /* Check if Media Autosense is enabled */
adapter->ei = *ei; adapter->ei = *ei;
/* do hw tstamp init after resetting */
igc_ptp_init(adapter);
/* print pcie link status and MAC address */ /* print pcie link status and MAC address */
pcie_print_link_status(pdev); pcie_print_link_status(pdev);
netdev_info(netdev, "MAC: %pM\n", netdev->dev_addr); netdev_info(netdev, "MAC: %pM\n", netdev->dev_addr);

View File

@ -4895,7 +4895,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
/* Verify if UDP port is being offloaded by HW */ /* Verify if UDP port is being offloaded by HW */
if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port)) if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port))
return features; return vxlan_features_check(skb, features);
#if IS_ENABLED(CONFIG_GENEVE) #if IS_ENABLED(CONFIG_GENEVE)
/* Support Geneve offload for default UDP port */ /* Support Geneve offload for default UDP port */
@ -4921,7 +4921,6 @@ netdev_features_t mlx5e_features_check(struct sk_buff *skb,
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
features = vlan_features_check(skb, features); features = vlan_features_check(skb, features);
features = vxlan_features_check(skb, features);
/* Validate if the tunneled packet is being offloaded by HW */ /* Validate if the tunneled packet is being offloaded by HW */
if (skb->encapsulation && if (skb->encapsulation &&

View File

@ -304,10 +304,8 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq)
if (ret) if (ret)
return ret; return ret;
if (qcq->napi.poll)
napi_enable(&qcq->napi);
if (qcq->flags & IONIC_QCQ_F_INTR) { if (qcq->flags & IONIC_QCQ_F_INTR) {
napi_enable(&qcq->napi);
irq_set_affinity_hint(qcq->intr.vector, irq_set_affinity_hint(qcq->intr.vector,
&qcq->intr.affinity_mask); &qcq->intr.affinity_mask);
ionic_intr_mask(idev->intr_ctrl, qcq->intr.index, ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,

View File

@ -93,6 +93,7 @@ struct ethqos_emac_driver_data {
bool has_emac_ge_3; bool has_emac_ge_3;
const char *link_clk_name; const char *link_clk_name;
bool has_integrated_pcs; bool has_integrated_pcs;
u32 dma_addr_width;
struct dwmac4_addrs dwmac4_addrs; struct dwmac4_addrs dwmac4_addrs;
}; };
@ -276,6 +277,7 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
.has_emac_ge_3 = true, .has_emac_ge_3 = true,
.link_clk_name = "phyaux", .link_clk_name = "phyaux",
.has_integrated_pcs = true, .has_integrated_pcs = true,
.dma_addr_width = 36,
.dwmac4_addrs = { .dwmac4_addrs = {
.dma_chan = 0x00008100, .dma_chan = 0x00008100,
.dma_chan_offset = 0x1000, .dma_chan_offset = 0x1000,
@ -845,6 +847,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI; plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;
if (data->has_integrated_pcs) if (data->has_integrated_pcs)
plat_dat->flags |= STMMAC_FLAG_HAS_INTEGRATED_PCS; plat_dat->flags |= STMMAC_FLAG_HAS_INTEGRATED_PCS;
if (data->dma_addr_width)
plat_dat->host_dma_width = data->dma_addr_width;
if (ethqos->serdes_phy) { if (ethqos->serdes_phy) {
plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup; plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;

View File

@ -343,10 +343,11 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
struct tc_cbs_qopt_offload *qopt) struct tc_cbs_qopt_offload *qopt)
{ {
u32 tx_queues_count = priv->plat->tx_queues_to_use; u32 tx_queues_count = priv->plat->tx_queues_to_use;
s64 port_transmit_rate_kbps;
u32 queue = qopt->queue; u32 queue = qopt->queue;
u32 ptr, speed_div;
u32 mode_to_use; u32 mode_to_use;
u64 value; u64 value;
u32 ptr;
int ret; int ret;
/* Queue 0 is not AVB capable */ /* Queue 0 is not AVB capable */
@ -355,30 +356,26 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
if (!priv->dma_cap.av) if (!priv->dma_cap.av)
return -EOPNOTSUPP; return -EOPNOTSUPP;
port_transmit_rate_kbps = qopt->idleslope - qopt->sendslope;
/* Port Transmit Rate and Speed Divider */ /* Port Transmit Rate and Speed Divider */
switch (priv->speed) { switch (div_s64(port_transmit_rate_kbps, 1000)) {
case SPEED_10000: case SPEED_10000:
ptr = 32;
speed_div = 10000000;
break;
case SPEED_5000: case SPEED_5000:
ptr = 32; ptr = 32;
speed_div = 5000000;
break; break;
case SPEED_2500: case SPEED_2500:
ptr = 8;
speed_div = 2500000;
break;
case SPEED_1000: case SPEED_1000:
ptr = 8; ptr = 8;
speed_div = 1000000;
break; break;
case SPEED_100: case SPEED_100:
ptr = 4; ptr = 4;
speed_div = 100000;
break; break;
default: default:
return -EOPNOTSUPP; netdev_err(priv->dev,
"Invalid portTransmitRate %lld (idleSlope - sendSlope)\n",
port_transmit_rate_kbps);
return -EINVAL;
} }
mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use; mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use;
@ -398,10 +395,10 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
} }
/* Final adjustments for HW */ /* Final adjustments for HW */
value = div_s64(qopt->idleslope * 1024ll * ptr, speed_div); value = div_s64(qopt->idleslope * 1024ll * ptr, port_transmit_rate_kbps);
priv->plat->tx_queues_cfg[queue].idle_slope = value & GENMASK(31, 0); priv->plat->tx_queues_cfg[queue].idle_slope = value & GENMASK(31, 0);
value = div_s64(-qopt->sendslope * 1024ll * ptr, speed_div); value = div_s64(-qopt->sendslope * 1024ll * ptr, port_transmit_rate_kbps);
priv->plat->tx_queues_cfg[queue].send_slope = value & GENMASK(31, 0); priv->plat->tx_queues_cfg[queue].send_slope = value & GENMASK(31, 0);
value = qopt->hicredit * 1024ll * 8; value = qopt->hicredit * 1024ll * 8;

View File

@ -815,6 +815,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
struct geneve_dev *geneve, struct geneve_dev *geneve,
const struct ip_tunnel_info *info) const struct ip_tunnel_info *info)
{ {
bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
bool xnet = !net_eq(geneve->net, dev_net(geneve->dev)); bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
struct geneve_sock *gs4 = rcu_dereference(geneve->sock4); struct geneve_sock *gs4 = rcu_dereference(geneve->sock4);
const struct ip_tunnel_key *key = &info->key; const struct ip_tunnel_key *key = &info->key;
@ -826,7 +827,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
__be16 sport; __be16 sport;
int err; int err;
if (!skb_vlan_inet_prepare(skb)) if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
return -EINVAL; return -EINVAL;
if (!gs4) if (!gs4)
@ -908,7 +909,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
} }
err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr), err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr),
geneve->cfg.inner_proto_inherit); inner_proto_inherit);
if (unlikely(err)) if (unlikely(err))
return err; return err;
@ -925,6 +926,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
struct geneve_dev *geneve, struct geneve_dev *geneve,
const struct ip_tunnel_info *info) const struct ip_tunnel_info *info)
{ {
bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
bool xnet = !net_eq(geneve->net, dev_net(geneve->dev)); bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
struct geneve_sock *gs6 = rcu_dereference(geneve->sock6); struct geneve_sock *gs6 = rcu_dereference(geneve->sock6);
const struct ip_tunnel_key *key = &info->key; const struct ip_tunnel_key *key = &info->key;
@ -935,7 +937,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
__be16 sport; __be16 sport;
int err; int err;
if (!skb_vlan_inet_prepare(skb)) if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
return -EINVAL; return -EINVAL;
if (!gs6) if (!gs6)
@ -997,7 +999,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
ttl = ttl ? : ip6_dst_hoplimit(dst); ttl = ttl ? : ip6_dst_hoplimit(dst);
} }
err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr), err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr),
geneve->cfg.inner_proto_inherit); inner_proto_inherit);
if (unlikely(err)) if (unlikely(err))
return err; return err;

View File

@ -324,7 +324,8 @@ static int nsim_get_iflink(const struct net_device *dev)
rcu_read_lock(); rcu_read_lock();
peer = rcu_dereference(nsim->peer); peer = rcu_dereference(nsim->peer);
iflink = peer ? READ_ONCE(peer->netdev->ifindex) : 0; iflink = peer ? READ_ONCE(peer->netdev->ifindex) :
READ_ONCE(dev->ifindex);
rcu_read_unlock(); rcu_read_unlock();
return iflink; return iflink;

View File

@ -2429,8 +2429,7 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
/* Handle remove event globally, it resets this state machine */ /* Handle remove event globally, it resets this state machine */
if (event == SFP_E_REMOVE) { if (event == SFP_E_REMOVE) {
if (sfp->sm_mod_state > SFP_MOD_PROBE) sfp_sm_mod_remove(sfp);
sfp_sm_mod_remove(sfp);
sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0);
return; return;
} }

View File

@ -180,7 +180,7 @@ int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
cmd.prop_get.offset = cpu_to_le32(off); cmd.prop_get.offset = cpu_to_le32(off);
ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0, ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0,
NVME_QID_ANY, 0); NVME_QID_ANY, NVME_SUBMIT_RESERVED);
if (ret >= 0) if (ret >= 0)
*val = le64_to_cpu(res.u64); *val = le64_to_cpu(res.u64);
@ -226,7 +226,7 @@ int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
cmd.prop_get.offset = cpu_to_le32(off); cmd.prop_get.offset = cpu_to_le32(off);
ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0, ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0,
NVME_QID_ANY, 0); NVME_QID_ANY, NVME_SUBMIT_RESERVED);
if (ret >= 0) if (ret >= 0)
*val = le64_to_cpu(res.u64); *val = le64_to_cpu(res.u64);
@ -271,7 +271,7 @@ int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
cmd.prop_set.value = cpu_to_le64(val); cmd.prop_set.value = cpu_to_le64(val);
ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, NULL, NULL, 0, ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, NULL, NULL, 0,
NVME_QID_ANY, 0); NVME_QID_ANY, NVME_SUBMIT_RESERVED);
if (unlikely(ret)) if (unlikely(ret))
dev_err(ctrl->device, dev_err(ctrl->device,
"Property Set error: %d, offset %#x\n", "Property Set error: %d, offset %#x\n",

View File

@ -77,7 +77,7 @@ static int nvme_sc_to_pr_err(int nvme_sc)
if (nvme_is_path_error(nvme_sc)) if (nvme_is_path_error(nvme_sc))
return PR_STS_PATH_FAILED; return PR_STS_PATH_FAILED;
switch (nvme_sc) { switch (nvme_sc & 0x7ff) {
case NVME_SC_SUCCESS: case NVME_SC_SUCCESS:
return PR_STS_SUCCESS; return PR_STS_SUCCESS;
case NVME_SC_RESERVATION_CONFLICT: case NVME_SC_RESERVATION_CONFLICT:

View File

@ -289,8 +289,6 @@ void pci_cfg_access_lock(struct pci_dev *dev)
{ {
might_sleep(); might_sleep();
lock_map_acquire(&dev->cfg_access_lock);
raw_spin_lock_irq(&pci_lock); raw_spin_lock_irq(&pci_lock);
if (dev->block_cfg_access) if (dev->block_cfg_access)
pci_wait_cfg(dev); pci_wait_cfg(dev);
@ -345,8 +343,6 @@ void pci_cfg_access_unlock(struct pci_dev *dev)
raw_spin_unlock_irqrestore(&pci_lock, flags); raw_spin_unlock_irqrestore(&pci_lock, flags);
wake_up_all(&pci_cfg_wait); wake_up_all(&pci_cfg_wait);
lock_map_release(&dev->cfg_access_lock);
} }
EXPORT_SYMBOL_GPL(pci_cfg_access_unlock); EXPORT_SYMBOL_GPL(pci_cfg_access_unlock);

View File

@ -4883,7 +4883,6 @@ void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
*/ */
int pci_bridge_secondary_bus_reset(struct pci_dev *dev) int pci_bridge_secondary_bus_reset(struct pci_dev *dev)
{ {
lock_map_assert_held(&dev->cfg_access_lock);
pcibios_reset_secondary_bus(dev); pcibios_reset_secondary_bus(dev);
return pci_bridge_wait_for_secondary_bus(dev, "bus reset"); return pci_bridge_wait_for_secondary_bus(dev, "bus reset");

View File

@ -2546,9 +2546,6 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
dev->dev.dma_mask = &dev->dma_mask; dev->dev.dma_mask = &dev->dma_mask;
dev->dev.dma_parms = &dev->dma_parms; dev->dev.dma_parms = &dev->dma_parms;
dev->dev.coherent_dma_mask = 0xffffffffull; dev->dev.coherent_dma_mask = 0xffffffffull;
lockdep_register_key(&dev->cfg_access_key);
lockdep_init_map(&dev->cfg_access_lock, dev_name(&dev->dev),
&dev->cfg_access_key, 0);
dma_set_max_seg_size(&dev->dev, 65536); dma_set_max_seg_size(&dev->dev, 65536);
dma_set_seg_boundary(&dev->dev, 0xffffffff); dma_set_seg_boundary(&dev->dev, 0xffffffff);

View File

@ -136,6 +136,7 @@ config YOGABOOK
config YT2_1380 config YT2_1380
tristate "Lenovo Yoga Tablet 2 1380 fast charge driver" tristate "Lenovo Yoga Tablet 2 1380 fast charge driver"
depends on SERIAL_DEV_BUS depends on SERIAL_DEV_BUS
depends on EXTCON
depends on ACPI depends on ACPI
help help
Say Y here to enable support for the custom fast charging protocol Say Y here to enable support for the custom fast charging protocol

View File

@ -907,16 +907,44 @@ static int hsmp_plat_dev_register(void)
return ret; return ret;
} }
/*
* This check is only needed for backward compatibility of previous platforms.
* All new platforms are expected to support ACPI based probing.
*/
static bool legacy_hsmp_support(void)
{
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
return false;
switch (boot_cpu_data.x86) {
case 0x19:
switch (boot_cpu_data.x86_model) {
case 0x00 ... 0x1F:
case 0x30 ... 0x3F:
case 0x90 ... 0x9F:
case 0xA0 ... 0xAF:
return true;
default:
return false;
}
case 0x1A:
switch (boot_cpu_data.x86_model) {
case 0x00 ... 0x1F:
return true;
default:
return false;
}
default:
return false;
}
return false;
}
static int __init hsmp_plt_init(void) static int __init hsmp_plt_init(void)
{ {
int ret = -ENODEV; int ret = -ENODEV;
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD || boot_cpu_data.x86 < 0x19) {
pr_err("HSMP is not supported on Family:%x model:%x\n",
boot_cpu_data.x86, boot_cpu_data.x86_model);
return ret;
}
/* /*
* amd_nb_num() returns number of SMN/DF interfaces present in the system * amd_nb_num() returns number of SMN/DF interfaces present in the system
* if we have N SMN/DF interfaces that ideally means N sockets * if we have N SMN/DF interfaces that ideally means N sockets
@ -930,7 +958,15 @@ static int __init hsmp_plt_init(void)
return ret; return ret;
if (!plat_dev.is_acpi_device) { if (!plat_dev.is_acpi_device) {
ret = hsmp_plat_dev_register(); if (legacy_hsmp_support()) {
/* Not ACPI device, but supports HSMP, register a plat_dev */
ret = hsmp_plat_dev_register();
} else {
/* Not ACPI, Does not support HSMP */
pr_info("HSMP is not supported on Family:%x model:%x\n",
boot_cpu_data.x86, boot_cpu_data.x86_model);
ret = -ENODEV;
}
if (ret) if (ret)
platform_driver_unregister(&amd_hsmp_driver); platform_driver_unregister(&amd_hsmp_driver);
} }

View File

@ -11,6 +11,7 @@
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/container_of.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/capability.h> #include <linux/capability.h>
@ -25,11 +26,16 @@ static u32 da_supported_commands;
static int da_num_tokens; static int da_num_tokens;
static struct platform_device *platform_device; static struct platform_device *platform_device;
static struct calling_interface_token *da_tokens; static struct calling_interface_token *da_tokens;
static struct device_attribute *token_location_attrs; static struct token_sysfs_data *token_entries;
static struct device_attribute *token_value_attrs;
static struct attribute **token_attrs; static struct attribute **token_attrs;
static DEFINE_MUTEX(smbios_mutex); static DEFINE_MUTEX(smbios_mutex);
struct token_sysfs_data {
struct device_attribute location_attr;
struct device_attribute value_attr;
struct calling_interface_token *token;
};
struct smbios_device { struct smbios_device {
struct list_head list; struct list_head list;
struct device *device; struct device *device;
@ -416,47 +422,26 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy)
} }
} }
static int match_attribute(struct device *dev,
struct device_attribute *attr)
{
int i;
for (i = 0; i < da_num_tokens * 2; i++) {
if (!token_attrs[i])
continue;
if (strcmp(token_attrs[i]->name, attr->attr.name) == 0)
return i/2;
}
dev_dbg(dev, "couldn't match: %s\n", attr->attr.name);
return -EINVAL;
}
static ssize_t location_show(struct device *dev, static ssize_t location_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
int i; struct token_sysfs_data *data = container_of(attr, struct token_sysfs_data, location_attr);
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
i = match_attribute(dev, attr); return sysfs_emit(buf, "%08x", data->token->location);
if (i > 0)
return sysfs_emit(buf, "%08x", da_tokens[i].location);
return 0;
} }
static ssize_t value_show(struct device *dev, static ssize_t value_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
int i; struct token_sysfs_data *data = container_of(attr, struct token_sysfs_data, value_attr);
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
i = match_attribute(dev, attr); return sysfs_emit(buf, "%08x", data->token->value);
if (i > 0)
return sysfs_emit(buf, "%08x", da_tokens[i].value);
return 0;
} }
static struct attribute_group smbios_attribute_group = { static struct attribute_group smbios_attribute_group = {
@ -473,22 +458,15 @@ static int build_tokens_sysfs(struct platform_device *dev)
{ {
char *location_name; char *location_name;
char *value_name; char *value_name;
size_t size;
int ret; int ret;
int i, j; int i, j;
/* (number of tokens + 1 for null terminated */ token_entries = kcalloc(da_num_tokens, sizeof(*token_entries), GFP_KERNEL);
size = sizeof(struct device_attribute) * (da_num_tokens + 1); if (!token_entries)
token_location_attrs = kzalloc(size, GFP_KERNEL);
if (!token_location_attrs)
return -ENOMEM; return -ENOMEM;
token_value_attrs = kzalloc(size, GFP_KERNEL);
if (!token_value_attrs)
goto out_allocate_value;
/* need to store both location and value + terminator*/ /* need to store both location and value + terminator*/
size = sizeof(struct attribute *) * ((2 * da_num_tokens) + 1); token_attrs = kcalloc((2 * da_num_tokens) + 1, sizeof(*token_attrs), GFP_KERNEL);
token_attrs = kzalloc(size, GFP_KERNEL);
if (!token_attrs) if (!token_attrs)
goto out_allocate_attrs; goto out_allocate_attrs;
@ -496,32 +474,34 @@ static int build_tokens_sysfs(struct platform_device *dev)
/* skip empty */ /* skip empty */
if (da_tokens[i].tokenID == 0) if (da_tokens[i].tokenID == 0)
continue; continue;
token_entries[i].token = &da_tokens[i];
/* add location */ /* add location */
location_name = kasprintf(GFP_KERNEL, "%04x_location", location_name = kasprintf(GFP_KERNEL, "%04x_location",
da_tokens[i].tokenID); da_tokens[i].tokenID);
if (location_name == NULL) if (location_name == NULL)
goto out_unwind_strings; goto out_unwind_strings;
sysfs_attr_init(&token_location_attrs[i].attr);
token_location_attrs[i].attr.name = location_name; sysfs_attr_init(&token_entries[i].location_attr.attr);
token_location_attrs[i].attr.mode = 0444; token_entries[i].location_attr.attr.name = location_name;
token_location_attrs[i].show = location_show; token_entries[i].location_attr.attr.mode = 0444;
token_attrs[j++] = &token_location_attrs[i].attr; token_entries[i].location_attr.show = location_show;
token_attrs[j++] = &token_entries[i].location_attr.attr;
/* add value */ /* add value */
value_name = kasprintf(GFP_KERNEL, "%04x_value", value_name = kasprintf(GFP_KERNEL, "%04x_value",
da_tokens[i].tokenID); da_tokens[i].tokenID);
if (value_name == NULL) if (!value_name) {
goto loop_fail_create_value; kfree(location_name);
sysfs_attr_init(&token_value_attrs[i].attr); goto out_unwind_strings;
token_value_attrs[i].attr.name = value_name; }
token_value_attrs[i].attr.mode = 0444;
token_value_attrs[i].show = value_show;
token_attrs[j++] = &token_value_attrs[i].attr;
continue;
loop_fail_create_value: sysfs_attr_init(&token_entries[i].value_attr.attr);
kfree(location_name); token_entries[i].value_attr.attr.name = value_name;
goto out_unwind_strings; token_entries[i].value_attr.attr.mode = 0444;
token_entries[i].value_attr.show = value_show;
token_attrs[j++] = &token_entries[i].value_attr.attr;
} }
smbios_attribute_group.attrs = token_attrs; smbios_attribute_group.attrs = token_attrs;
@ -532,14 +512,12 @@ static int build_tokens_sysfs(struct platform_device *dev)
out_unwind_strings: out_unwind_strings:
while (i--) { while (i--) {
kfree(token_location_attrs[i].attr.name); kfree(token_entries[i].location_attr.attr.name);
kfree(token_value_attrs[i].attr.name); kfree(token_entries[i].value_attr.attr.name);
} }
kfree(token_attrs); kfree(token_attrs);
out_allocate_attrs: out_allocate_attrs:
kfree(token_value_attrs); kfree(token_entries);
out_allocate_value:
kfree(token_location_attrs);
return -ENOMEM; return -ENOMEM;
} }
@ -551,12 +529,11 @@ static void free_group(struct platform_device *pdev)
sysfs_remove_group(&pdev->dev.kobj, sysfs_remove_group(&pdev->dev.kobj,
&smbios_attribute_group); &smbios_attribute_group);
for (i = 0; i < da_num_tokens; i++) { for (i = 0; i < da_num_tokens; i++) {
kfree(token_location_attrs[i].attr.name); kfree(token_entries[i].location_attr.attr.name);
kfree(token_value_attrs[i].attr.name); kfree(token_entries[i].value_attr.attr.name);
} }
kfree(token_attrs); kfree(token_attrs);
kfree(token_value_attrs); kfree(token_entries);
kfree(token_location_attrs);
} }
static int __init dell_smbios_init(void) static int __init dell_smbios_init(void)

View File

@ -34,7 +34,6 @@ static const struct property_entry archos_101_cesium_educ_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-archos-101-cesium-educ.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-archos-101-cesium-educ.fw"),
{ } { }
@ -49,7 +48,6 @@ static const struct property_entry bush_bush_windows_tablet_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1850), PROPERTY_ENTRY_U32("touchscreen-size-x", 1850),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-bush-bush-windows-tablet.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-bush-bush-windows-tablet.fw"),
{ } { }
@ -79,7 +77,6 @@ static const struct property_entry chuwi_hi8_air_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1148), PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-hi8-air.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-hi8-air.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -95,7 +92,6 @@ static const struct property_entry chuwi_hi8_pro_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1148), PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-hi8-pro.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-hi8-pro.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -123,7 +119,6 @@ static const struct property_entry chuwi_hi10_air_props[] = {
PROPERTY_ENTRY_U32("touchscreen-fuzz-x", 5), PROPERTY_ENTRY_U32("touchscreen-fuzz-x", 5),
PROPERTY_ENTRY_U32("touchscreen-fuzz-y", 4), PROPERTY_ENTRY_U32("touchscreen-fuzz-y", 4),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10-air.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10-air.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -139,7 +134,6 @@ static const struct property_entry chuwi_hi10_plus_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1908), PROPERTY_ENTRY_U32("touchscreen-size-x", 1908),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1270), PROPERTY_ENTRY_U32("touchscreen-size-y", 1270),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10plus.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10plus.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
PROPERTY_ENTRY_BOOL("silead,pen-supported"), PROPERTY_ENTRY_BOOL("silead,pen-supported"),
PROPERTY_ENTRY_U32("silead,pen-resolution-x", 8), PROPERTY_ENTRY_U32("silead,pen-resolution-x", 8),
@ -171,7 +165,6 @@ static const struct property_entry chuwi_hi10_pro_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10-pro.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10-pro.fw"),
PROPERTY_ENTRY_U32_ARRAY("silead,efi-fw-min-max", chuwi_hi10_pro_efi_min_max), PROPERTY_ENTRY_U32_ARRAY("silead,efi-fw-min-max", chuwi_hi10_pro_efi_min_max),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
PROPERTY_ENTRY_BOOL("silead,pen-supported"), PROPERTY_ENTRY_BOOL("silead,pen-supported"),
PROPERTY_ENTRY_U32("silead,pen-resolution-x", 8), PROPERTY_ENTRY_U32("silead,pen-resolution-x", 8),
@ -201,7 +194,6 @@ static const struct property_entry chuwi_hibook_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hibook.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hibook.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -227,7 +219,6 @@ static const struct property_entry chuwi_vi8_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1140), PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-vi8.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-vi8.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -255,7 +246,6 @@ static const struct property_entry chuwi_vi10_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1858), PROPERTY_ENTRY_U32("touchscreen-size-x", 1858),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-vi10.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-vi10.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -271,7 +261,6 @@ static const struct property_entry chuwi_surbook_mini_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 2040), PROPERTY_ENTRY_U32("touchscreen-size-x", 2040),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1524), PROPERTY_ENTRY_U32("touchscreen-size-y", 1524),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-surbook-mini.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-surbook-mini.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
{ } { }
}; };
@ -289,7 +278,6 @@ static const struct property_entry connect_tablet9_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-connect-tablet9.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-connect-tablet9.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -306,7 +294,6 @@ static const struct property_entry csl_panther_tab_hd_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-csl-panther-tab-hd.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-csl-panther-tab-hd.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -322,7 +309,6 @@ static const struct property_entry cube_iwork8_air_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 896), PROPERTY_ENTRY_U32("touchscreen-size-y", 896),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-cube-iwork8-air.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-cube-iwork8-air.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -346,7 +332,6 @@ static const struct property_entry cube_knote_i1101_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1961), PROPERTY_ENTRY_U32("touchscreen-size-x", 1961),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1513), PROPERTY_ENTRY_U32("touchscreen-size-y", 1513),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-cube-knote-i1101.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-cube-knote-i1101.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -360,7 +345,6 @@ static const struct property_entry dexp_ursus_7w_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 890), PROPERTY_ENTRY_U32("touchscreen-size-x", 890),
PROPERTY_ENTRY_U32("touchscreen-size-y", 630), PROPERTY_ENTRY_U32("touchscreen-size-y", 630),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-dexp-ursus-7w.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-dexp-ursus-7w.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -376,7 +360,6 @@ static const struct property_entry dexp_ursus_kx210i_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1720), PROPERTY_ENTRY_U32("touchscreen-size-x", 1720),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1137), PROPERTY_ENTRY_U32("touchscreen-size-y", 1137),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-dexp-ursus-kx210i.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-dexp-ursus-kx210i.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -391,7 +374,6 @@ static const struct property_entry digma_citi_e200_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-digma_citi_e200.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-digma_citi_e200.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -450,7 +432,6 @@ static const struct property_entry irbis_tw90_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-irbis_tw90.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-irbis_tw90.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -466,7 +447,6 @@ static const struct property_entry irbis_tw118_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1960), PROPERTY_ENTRY_U32("touchscreen-size-x", 1960),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1510), PROPERTY_ENTRY_U32("touchscreen-size-y", 1510),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-irbis-tw118.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-irbis-tw118.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -483,7 +463,6 @@ static const struct property_entry itworks_tw891_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-itworks-tw891.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-itworks-tw891.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -496,7 +475,6 @@ static const struct property_entry jumper_ezpad_6_pro_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -511,7 +489,6 @@ static const struct property_entry jumper_ezpad_6_pro_b_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro-b.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro-b.fw"),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -527,7 +504,6 @@ static const struct property_entry jumper_ezpad_6_m4_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1950), PROPERTY_ENTRY_U32("touchscreen-size-x", 1950),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1525), PROPERTY_ENTRY_U32("touchscreen-size-y", 1525),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-m4.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-m4.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -544,7 +520,6 @@ static const struct property_entry jumper_ezpad_7_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1526), PROPERTY_ENTRY_U32("touchscreen-size-y", 1526),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-jumper-ezpad-7.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-jumper-ezpad-7.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,stuck-controller-bug"), PROPERTY_ENTRY_BOOL("silead,stuck-controller-bug"),
{ } { }
}; };
@ -561,7 +536,6 @@ static const struct property_entry jumper_ezpad_mini3_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1138), PROPERTY_ENTRY_U32("touchscreen-size-y", 1138),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -578,7 +552,6 @@ static const struct property_entry mpman_converter9_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-mpman-converter9.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-mpman-converter9.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -594,7 +567,6 @@ static const struct property_entry mpman_mpwin895cl_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1150), PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-mpman-mpwin895cl.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-mpman-mpwin895cl.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -611,7 +583,6 @@ static const struct property_entry myria_my8307_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-myria-my8307.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-myria-my8307.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -628,7 +599,6 @@ static const struct property_entry onda_obook_20_plus_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -645,7 +615,6 @@ static const struct property_entry onda_v80_plus_v3_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1140), PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-v80-plus-v3.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-v80-plus-v3.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -669,7 +638,6 @@ static const struct property_entry onda_v820w_32g_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1140), PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-onda-v820w-32g.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-onda-v820w-32g.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -687,7 +655,6 @@ static const struct property_entry onda_v891_v5_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", PROPERTY_ENTRY_STRING("firmware-name",
"gsl3676-onda-v891-v5.fw"), "gsl3676-onda-v891-v5.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -703,7 +670,6 @@ static const struct property_entry onda_v891w_v1_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1676), PROPERTY_ENTRY_U32("touchscreen-size-x", 1676),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1130), PROPERTY_ENTRY_U32("touchscreen-size-y", 1130),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-onda-v891w-v1.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-onda-v891w-v1.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -720,7 +686,6 @@ static const struct property_entry onda_v891w_v3_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1135), PROPERTY_ENTRY_U32("touchscreen-size-y", 1135),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-v891w-v3.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-v891w-v3.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -759,7 +724,6 @@ static const struct property_entry pipo_w11_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1984), PROPERTY_ENTRY_U32("touchscreen-size-x", 1984),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1532), PROPERTY_ENTRY_U32("touchscreen-size-y", 1532),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-pipo-w11.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-pipo-w11.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -775,7 +739,6 @@ static const struct property_entry positivo_c4128b_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1915), PROPERTY_ENTRY_U32("touchscreen-size-x", 1915),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1269), PROPERTY_ENTRY_U32("touchscreen-size-y", 1269),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-positivo-c4128b.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-positivo-c4128b.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -791,7 +754,6 @@ static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1146), PROPERTY_ENTRY_U32("touchscreen-size-y", 1146),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-pov-mobii-wintab-p800w-v20.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-pov-mobii-wintab-p800w-v20.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -808,7 +770,6 @@ static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1148), PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-pov-mobii-wintab-p800w.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-pov-mobii-wintab-p800w.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -825,7 +786,6 @@ static const struct property_entry pov_mobii_wintab_p1006w_v10_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1520), PROPERTY_ENTRY_U32("touchscreen-size-y", 1520),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-pov-mobii-wintab-p1006w-v10.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-pov-mobii-wintab-p1006w-v10.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -842,7 +802,6 @@ static const struct property_entry predia_basic_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1144), PROPERTY_ENTRY_U32("touchscreen-size-y", 1144),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-predia-basic.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-predia-basic.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -859,7 +818,6 @@ static const struct property_entry rca_cambio_w101_v2_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 874), PROPERTY_ENTRY_U32("touchscreen-size-y", 874),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-rca-cambio-w101-v2.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-rca-cambio-w101-v2.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -874,7 +832,6 @@ static const struct property_entry rwc_nanote_p8_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1140), PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-rwc-nanote-p8.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-rwc-nanote-p8.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -890,7 +847,6 @@ static const struct property_entry schneider_sct101ctm_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-schneider-sct101ctm.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-schneider-sct101ctm.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -906,7 +862,6 @@ static const struct property_entry globalspace_solt_ivw116_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1723), PROPERTY_ENTRY_U32("touchscreen-size-x", 1723),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1077), PROPERTY_ENTRY_U32("touchscreen-size-y", 1077),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-globalspace-solt-ivw116.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-globalspace-solt-ivw116.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -923,7 +878,6 @@ static const struct property_entry techbite_arc_11_6_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1270), PROPERTY_ENTRY_U32("touchscreen-size-y", 1270),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-techbite-arc-11-6.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-techbite-arc-11-6.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -939,7 +893,6 @@ static const struct property_entry teclast_tbook11_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1264), PROPERTY_ENTRY_U32("touchscreen-size-y", 1264),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-teclast-tbook11.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-teclast-tbook11.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -965,7 +918,6 @@ static const struct property_entry teclast_x16_plus_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1264), PROPERTY_ENTRY_U32("touchscreen-size-y", 1264),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-teclast-x16-plus.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-teclast-x16-plus.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -988,7 +940,6 @@ static const struct property_entry teclast_x3_plus_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -1004,7 +955,6 @@ static const struct property_entry teclast_x98plus2_props[] = {
PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-teclast_x98plus2.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-teclast_x98plus2.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ } { }
}; };
@ -1018,7 +968,6 @@ static const struct property_entry trekstor_primebook_c11_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1530), PROPERTY_ENTRY_U32("touchscreen-size-y", 1530),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-trekstor-primebook-c11.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-trekstor-primebook-c11.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -1032,7 +981,6 @@ static const struct property_entry trekstor_primebook_c13_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 2624), PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1920), PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-trekstor-primebook-c13.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-trekstor-primebook-c13.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -1046,7 +994,6 @@ static const struct property_entry trekstor_primetab_t13b_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 2500), PROPERTY_ENTRY_U32("touchscreen-size-x", 2500),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1900), PROPERTY_ENTRY_U32("touchscreen-size-y", 1900),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-trekstor-primetab-t13b.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-trekstor-primetab-t13b.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
{ } { }
@ -1074,7 +1021,6 @@ static const struct property_entry trekstor_surftab_twin_10_1_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
PROPERTY_ENTRY_U32("touchscreen-inverted-y", 1), PROPERTY_ENTRY_U32("touchscreen-inverted-y", 1),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-surftab-twin-10-1-st10432-8.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-surftab-twin-10-1-st10432-8.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -1090,7 +1036,6 @@ static const struct property_entry trekstor_surftab_wintron70_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 884), PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
PROPERTY_ENTRY_U32("touchscreen-size-y", 632), PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-surftab-wintron70-st70416-6.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-surftab-wintron70-st70416-6.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -1107,7 +1052,6 @@ static const struct property_entry viglen_connect_10_props[] = {
PROPERTY_ENTRY_U32("touchscreen-fuzz-y", 6), PROPERTY_ENTRY_U32("touchscreen-fuzz-y", 6),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-viglen-connect-10.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-viglen-connect-10.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -1121,7 +1065,6 @@ static const struct property_entry vinga_twizzle_j116_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1920), PROPERTY_ENTRY_U32("touchscreen-size-x", 1920),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-vinga-twizzle_j116.fw"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-vinga-twizzle_j116.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_BOOL("silead,home-button"),
{ } { }
}; };
@ -1907,7 +1850,7 @@ static int __init ts_parse_props(char *str)
u32 u32val; u32 u32val;
int i, ret; int i, ret;
strscpy(orig_str, str, sizeof(orig_str)); strscpy(orig_str, str);
/* /*
* str is part of the static_command_line from init/main.c and poking * str is part of the static_command_line from init/main.c and poking

View File

@ -414,28 +414,40 @@ static char print_alua_state(unsigned char state)
} }
} }
static enum scsi_disposition alua_check_sense(struct scsi_device *sdev, static void alua_handle_state_transition(struct scsi_device *sdev)
struct scsi_sense_hdr *sense_hdr)
{ {
struct alua_dh_data *h = sdev->handler_data; struct alua_dh_data *h = sdev->handler_data;
struct alua_port_group *pg; struct alua_port_group *pg;
rcu_read_lock();
pg = rcu_dereference(h->pg);
if (pg)
pg->state = SCSI_ACCESS_STATE_TRANSITIONING;
rcu_read_unlock();
alua_check(sdev, false);
}
static enum scsi_disposition alua_check_sense(struct scsi_device *sdev,
struct scsi_sense_hdr *sense_hdr)
{
switch (sense_hdr->sense_key) { switch (sense_hdr->sense_key) {
case NOT_READY: case NOT_READY:
if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a) { if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a) {
/* /*
* LUN Not Accessible - ALUA state transition * LUN Not Accessible - ALUA state transition
*/ */
rcu_read_lock(); alua_handle_state_transition(sdev);
pg = rcu_dereference(h->pg);
if (pg)
pg->state = SCSI_ACCESS_STATE_TRANSITIONING;
rcu_read_unlock();
alua_check(sdev, false);
return NEEDS_RETRY; return NEEDS_RETRY;
} }
break; break;
case UNIT_ATTENTION: case UNIT_ATTENTION:
if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a) {
/*
* LUN Not Accessible - ALUA state transition
*/
alua_handle_state_transition(sdev);
return NEEDS_RETRY;
}
if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) { if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) {
/* /*
* Power On, Reset, or Bus Device Reset. * Power On, Reset, or Bus Device Reset.
@ -502,7 +514,8 @@ static int alua_tur(struct scsi_device *sdev)
retval = scsi_test_unit_ready(sdev, ALUA_FAILOVER_TIMEOUT * HZ, retval = scsi_test_unit_ready(sdev, ALUA_FAILOVER_TIMEOUT * HZ,
ALUA_FAILOVER_RETRIES, &sense_hdr); ALUA_FAILOVER_RETRIES, &sense_hdr);
if (sense_hdr.sense_key == NOT_READY && if ((sense_hdr.sense_key == NOT_READY ||
sense_hdr.sense_key == UNIT_ATTENTION) &&
sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a)
return SCSI_DH_RETRY; return SCSI_DH_RETRY;
else if (retval) else if (retval)

View File

@ -1364,7 +1364,7 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
continue; continue;
if (i > sizeof(mr_sas_port->phy_mask) * 8) { if (i > sizeof(mr_sas_port->phy_mask) * 8) {
ioc_warn(mrioc, "skipping port %u, max allowed value is %lu\n", ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n",
i, sizeof(mr_sas_port->phy_mask) * 8); i, sizeof(mr_sas_port->phy_mask) * 8);
goto out_fail; goto out_fail;
} }

View File

@ -302,8 +302,8 @@ struct _scsi_io_transfer {
/** /**
* _scsih_set_debug_level - global setting of ioc->logging_level. * _scsih_set_debug_level - global setting of ioc->logging_level.
* @val: ? * @val: value of the parameter to be set
* @kp: ? * @kp: pointer to kernel_param structure
* *
* Note: The logging levels are defined in mpt3sas_debug.h. * Note: The logging levels are defined in mpt3sas_debug.h.
*/ */

View File

@ -363,6 +363,7 @@ struct qedf_ctx {
#define QEDF_IN_RECOVERY 5 #define QEDF_IN_RECOVERY 5
#define QEDF_DBG_STOP_IO 6 #define QEDF_DBG_STOP_IO 6
#define QEDF_PROBING 8 #define QEDF_PROBING 8
#define QEDF_STAG_IN_PROGRESS 9
unsigned long flags; /* Miscellaneous state flags */ unsigned long flags; /* Miscellaneous state flags */
int fipvlan_retries; int fipvlan_retries;
u8 num_queues; u8 num_queues;

View File

@ -318,11 +318,18 @@ static struct fc_seq *qedf_elsct_send(struct fc_lport *lport, u32 did,
*/ */
if (resp == fc_lport_flogi_resp) { if (resp == fc_lport_flogi_resp) {
qedf->flogi_cnt++; qedf->flogi_cnt++;
qedf->flogi_pending++;
if (test_bit(QEDF_UNLOADING, &qedf->flags)) {
QEDF_ERR(&qedf->dbg_ctx, "Driver unloading\n");
qedf->flogi_pending = 0;
}
if (qedf->flogi_pending >= QEDF_FLOGI_RETRY_CNT) { if (qedf->flogi_pending >= QEDF_FLOGI_RETRY_CNT) {
schedule_delayed_work(&qedf->stag_work, 2); schedule_delayed_work(&qedf->stag_work, 2);
return NULL; return NULL;
} }
qedf->flogi_pending++;
return fc_elsct_send(lport, did, fp, op, qedf_flogi_resp, return fc_elsct_send(lport, did, fp, op, qedf_flogi_resp,
arg, timeout); arg, timeout);
} }
@ -912,13 +919,14 @@ void qedf_ctx_soft_reset(struct fc_lport *lport)
struct qedf_ctx *qedf; struct qedf_ctx *qedf;
struct qed_link_output if_link; struct qed_link_output if_link;
qedf = lport_priv(lport);
if (lport->vport) { if (lport->vport) {
clear_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
printk_ratelimited("Cannot issue host reset on NPIV port.\n"); printk_ratelimited("Cannot issue host reset on NPIV port.\n");
return; return;
} }
qedf = lport_priv(lport);
qedf->flogi_pending = 0; qedf->flogi_pending = 0;
/* For host reset, essentially do a soft link up/down */ /* For host reset, essentially do a soft link up/down */
atomic_set(&qedf->link_state, QEDF_LINK_DOWN); atomic_set(&qedf->link_state, QEDF_LINK_DOWN);
@ -938,6 +946,7 @@ void qedf_ctx_soft_reset(struct fc_lport *lport)
if (!if_link.link_up) { if (!if_link.link_up) {
QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
"Physical link is not up.\n"); "Physical link is not up.\n");
clear_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
return; return;
} }
/* Flush and wait to make sure link down is processed */ /* Flush and wait to make sure link down is processed */
@ -950,6 +959,7 @@ void qedf_ctx_soft_reset(struct fc_lport *lport)
"Queue link up work.\n"); "Queue link up work.\n");
queue_delayed_work(qedf->link_update_wq, &qedf->link_update, queue_delayed_work(qedf->link_update_wq, &qedf->link_update,
0); 0);
clear_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
} }
/* Reset the host by gracefully logging out and then logging back in */ /* Reset the host by gracefully logging out and then logging back in */
@ -3463,6 +3473,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
} }
/* Start the Slowpath-process */ /* Start the Slowpath-process */
memset(&slowpath_params, 0, sizeof(struct qed_slowpath_params));
slowpath_params.int_mode = QED_INT_MODE_MSIX; slowpath_params.int_mode = QED_INT_MODE_MSIX;
slowpath_params.drv_major = QEDF_DRIVER_MAJOR_VER; slowpath_params.drv_major = QEDF_DRIVER_MAJOR_VER;
slowpath_params.drv_minor = QEDF_DRIVER_MINOR_VER; slowpath_params.drv_minor = QEDF_DRIVER_MINOR_VER;
@ -3721,6 +3732,7 @@ static void __qedf_remove(struct pci_dev *pdev, int mode)
{ {
struct qedf_ctx *qedf; struct qedf_ctx *qedf;
int rc; int rc;
int cnt = 0;
if (!pdev) { if (!pdev) {
QEDF_ERR(NULL, "pdev is NULL.\n"); QEDF_ERR(NULL, "pdev is NULL.\n");
@ -3738,6 +3750,17 @@ static void __qedf_remove(struct pci_dev *pdev, int mode)
return; return;
} }
stag_in_prog:
if (test_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags)) {
QEDF_ERR(&qedf->dbg_ctx, "Stag in progress, cnt=%d.\n", cnt);
cnt++;
if (cnt < 5) {
msleep(500);
goto stag_in_prog;
}
}
if (mode != QEDF_MODE_RECOVERY) if (mode != QEDF_MODE_RECOVERY)
set_bit(QEDF_UNLOADING, &qedf->flags); set_bit(QEDF_UNLOADING, &qedf->flags);
@ -3997,6 +4020,24 @@ void qedf_stag_change_work(struct work_struct *work)
struct qedf_ctx *qedf = struct qedf_ctx *qedf =
container_of(work, struct qedf_ctx, stag_work.work); container_of(work, struct qedf_ctx, stag_work.work);
if (!qedf) {
QEDF_ERR(&qedf->dbg_ctx, "qedf is NULL");
return;
}
if (test_bit(QEDF_IN_RECOVERY, &qedf->flags)) {
QEDF_ERR(&qedf->dbg_ctx,
"Already is in recovery, hence not calling software context reset.\n");
return;
}
if (test_bit(QEDF_UNLOADING, &qedf->flags)) {
QEDF_ERR(&qedf->dbg_ctx, "Driver unloading\n");
return;
}
set_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
printk_ratelimited("[%s]:[%s:%d]:%d: Performing software context reset.", printk_ratelimited("[%s]:[%s:%d]:%d: Performing software context reset.",
dev_name(&qedf->pdev->dev), __func__, __LINE__, dev_name(&qedf->pdev->dev), __func__, __LINE__,
qedf->dbg_ctx.host_no); qedf->dbg_ctx.host_no);

Some files were not shown because too many files have changed in this diff Show More