mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
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:
commit
4c7d3d79c7
229 changed files with 2295 additions and 1362 deletions
3
.mailmap
3
.mailmap
|
@ -72,6 +72,8 @@ Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com>
|
|||
Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com>
|
||||
André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com>
|
||||
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>
|
||||
Anirudh Ghayal <quic_aghayal@quicinc.com> <aghayal@codeaurora.org>
|
||||
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@gmail.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>
|
||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com>
|
||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>
|
||||
|
|
|
@ -467,11 +467,11 @@ anon_fault_fallback_charge
|
|||
instead falls back to using huge pages with lower orders or
|
||||
small pages even though the allocation was successful.
|
||||
|
||||
anon_swpout
|
||||
swpout
|
||||
is incremented every time a huge page is swapped out in one
|
||||
piece without splitting.
|
||||
|
||||
anon_swpout_fallback
|
||||
swpout_fallback
|
||||
is incremented if a huge page has to be split before swapout.
|
||||
Usually because failed to allocate some continuous swap space
|
||||
for the huge page.
|
||||
|
|
|
@ -217,7 +217,7 @@ current *struct* is::
|
|||
int (*media_changed)(struct cdrom_device_info *, int);
|
||||
int (*tray_move)(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 *,
|
||||
struct cdrom_multisession *);
|
||||
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
|
||||
are several reasons for changing the speed of a CD-ROM drive. Badly
|
||||
|
|
|
@ -18,9 +18,12 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- elan,ekth6915
|
||||
- ilitek,ili2901
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- elan,ekth5015m
|
||||
- const: elan,ekth6915
|
||||
- const: elan,ekth6915
|
||||
|
||||
reg:
|
||||
const: 0x10
|
||||
|
@ -33,6 +36,12 @@ properties:
|
|||
reset-gpios:
|
||||
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:
|
||||
description: The 3.3V supply to the touchscreen.
|
||||
|
||||
|
@ -58,8 +67,8 @@ examples:
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ap_ts: touchscreen@10 {
|
||||
compatible = "elan,ekth6915";
|
||||
touchscreen@10 {
|
||||
compatible = "elan,ekth5015m", "elan,ekth6915";
|
||||
reg = <0x10>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
|
|
66
Documentation/devicetree/bindings/input/ilitek,ili2901.yaml
Normal file
66
Documentation/devicetree/bindings/input/ilitek,ili2901.yaml
Normal 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>;
|
||||
};
|
||||
};
|
|
@ -150,6 +150,12 @@ applicable everywhere (see syntax).
|
|||
That will limit the usefulness but on the other hand avoid
|
||||
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>]
|
||||
|
||||
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
|
||||
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()::
|
||||
|
||||
foo_init()
|
||||
|
@ -202,6 +208,10 @@ applicable everywhere (see syntax).
|
|||
imply BAR
|
||||
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>
|
||||
|
||||
This attribute is only applicable to menu blocks, if the condition is
|
||||
|
|
|
@ -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
|
||||
routes or have a fixed routing configuration. If the routes can be disabled, not
|
||||
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
|
||||
back to the user in the routes array, with the ``V4L2_SUBDEV_STREAM_FL_ACTIVE``
|
||||
flag unset.
|
||||
|
|
|
@ -15825,7 +15825,7 @@ F: drivers/nfc/virtual_ncidev.c
|
|||
F: tools/testing/selftests/nci/
|
||||
|
||||
NFS, SUNRPC, AND LOCKD CLIENTS
|
||||
M: Trond Myklebust <trond.myklebust@hammerspace.com>
|
||||
M: Trond Myklebust <trondmy@kernel.org>
|
||||
M: Anna Schumaker <anna@kernel.org>
|
||||
L: linux-nfs@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@
|
|||
VERSION = 6
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc2
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -232,11 +232,24 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
|
|||
unsigned long old;
|
||||
|
||||
if (unlikely(atomic_read(¤t->tracing_graph_pause)))
|
||||
err_out:
|
||||
return;
|
||||
|
||||
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 {
|
||||
struct stackframe frame = {
|
||||
.fp = frame_pointer,
|
||||
|
|
|
@ -153,8 +153,9 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
|
|||
* emit the large TLP from the CPU.
|
||||
*/
|
||||
|
||||
static inline void __const_memcpy_toio_aligned32(volatile u32 __iomem *to,
|
||||
const u32 *from, size_t count)
|
||||
static __always_inline void
|
||||
__const_memcpy_toio_aligned32(volatile u32 __iomem *to, const u32 *from,
|
||||
size_t count)
|
||||
{
|
||||
switch (count) {
|
||||
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);
|
||||
|
||||
static inline void __const_iowrite32_copy(void __iomem *to, const void *from,
|
||||
size_t count)
|
||||
static __always_inline void
|
||||
__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);
|
||||
dgh();
|
||||
} else {
|
||||
__iowrite32_copy_full(to, from, count);
|
||||
}
|
||||
}
|
||||
#define __iowrite32_copy __iowrite32_copy
|
||||
|
||||
#define __iowrite32_copy(to, from, count) \
|
||||
(__builtin_constant_p(count) ? \
|
||||
__const_iowrite32_copy(to, from, count) : \
|
||||
__iowrite32_copy_full(to, from, count))
|
||||
|
||||
static inline void __const_memcpy_toio_aligned64(volatile u64 __iomem *to,
|
||||
const u64 *from, size_t count)
|
||||
static __always_inline void
|
||||
__const_memcpy_toio_aligned64(volatile u64 __iomem *to, const u64 *from,
|
||||
size_t count)
|
||||
{
|
||||
switch (count) {
|
||||
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);
|
||||
|
||||
static inline void __const_iowrite64_copy(void __iomem *to, const void *from,
|
||||
size_t count)
|
||||
static __always_inline void
|
||||
__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);
|
||||
dgh();
|
||||
} else {
|
||||
__iowrite64_copy_full(to, from, count);
|
||||
}
|
||||
}
|
||||
|
||||
#define __iowrite64_copy(to, from, count) \
|
||||
(__builtin_constant_p(count) ? \
|
||||
__const_iowrite64_copy(to, from, count) : \
|
||||
__iowrite64_copy_full(to, from, count))
|
||||
#define __iowrite64_copy __iowrite64_copy
|
||||
|
||||
/*
|
||||
* I/O memory mapping functions.
|
||||
|
|
|
@ -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++) {
|
||||
struct insn_emulation *insn = insn_emulations[i];
|
||||
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)) {
|
||||
pr_warn("CPU[%u] cannot support the emulation of %s",
|
||||
cpu, insn->name);
|
||||
|
|
|
@ -376,7 +376,7 @@ void contpte_clear_young_dirty_ptes(struct vm_area_struct *vma,
|
|||
* clearing access/dirty for the whole block.
|
||||
*/
|
||||
unsigned long start = addr;
|
||||
unsigned long end = start + nr;
|
||||
unsigned long end = start + nr * PAGE_SIZE;
|
||||
|
||||
if (pte_cont(__ptep_get(ptep + nr - 1)))
|
||||
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);
|
||||
}
|
||||
|
||||
__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);
|
||||
|
||||
|
|
|
@ -293,8 +293,8 @@ void handle_page_fault(struct pt_regs *regs)
|
|||
if (unlikely(access_error(cause, vma))) {
|
||||
vma_end_read(vma);
|
||||
count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
|
||||
tsk->thread.bad_cause = SEGV_ACCERR;
|
||||
bad_area_nosemaphore(regs, code, addr);
|
||||
tsk->thread.bad_cause = cause;
|
||||
bad_area_nosemaphore(regs, SEGV_ACCERR, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -250,18 +250,19 @@ static void __init setup_bootmem(void)
|
|||
kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base;
|
||||
|
||||
/*
|
||||
* memblock allocator is not aware of the fact that last 4K bytes of
|
||||
* the addressable memory can not be mapped because of IS_ERR_VALUE
|
||||
* macro. Make sure that last 4k bytes are not usable by memblock
|
||||
* if end of dram is equal to maximum addressable memory. For 64-bit
|
||||
* 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
|
||||
* be done as soon as the kernel mapping base address is determined.
|
||||
* Reserve physical address space that would be mapped to virtual
|
||||
* addresses greater than (void *)(-PAGE_SIZE) because:
|
||||
* - This memory would overlap with ERR_PTR
|
||||
* - This memory belongs to high memory, which is not supported
|
||||
*
|
||||
* This is not applicable to 64-bit kernel, because virtual addresses
|
||||
* 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)) {
|
||||
max_mapped_addr = __pa(~(ulong)0);
|
||||
if (max_mapped_addr == (phys_ram_end - 1))
|
||||
memblock_set_current_limit(max_mapped_addr - 4096);
|
||||
max_mapped_addr = __va_to_pa_nodebug(-PAGE_SIZE);
|
||||
memblock_reserve(max_mapped_addr, (phys_addr_t)-max_mapped_addr);
|
||||
}
|
||||
|
||||
min_low_pfn = PFN_UP(phys_ram_base);
|
||||
|
|
|
@ -451,7 +451,7 @@ static void *nt_final(void *ptr)
|
|||
/*
|
||||
* 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));
|
||||
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_ehsize = sizeof(Elf64_Ehdr);
|
||||
ehdr->e_phentsize = sizeof(Elf64_Phdr);
|
||||
/*
|
||||
* Number of memory chunk PT_LOAD program headers plus one kernel
|
||||
* image PT_LOAD program header plus one PT_NOTE program header.
|
||||
*/
|
||||
ehdr->e_phnum = mem_chunk_cnt + 1 + 1;
|
||||
/* Number of PT_LOAD program headers plus PT_NOTE program header */
|
||||
ehdr->e_phnum = phdr_count + 1;
|
||||
return ehdr + 1;
|
||||
}
|
||||
|
||||
|
@ -503,12 +500,14 @@ static int get_mem_chunk_cnt(void)
|
|||
/*
|
||||
* 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;
|
||||
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) {
|
||||
phdr->p_type = PT_LOAD;
|
||||
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
|
||||
*/
|
||||
|
@ -566,7 +570,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
static size_t get_elfcorehdr_size(int mem_chunk_cnt)
|
||||
static size_t get_elfcorehdr_size(int phdr_count)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
|
@ -581,10 +585,8 @@ static size_t get_elfcorehdr_size(int mem_chunk_cnt)
|
|||
size += nt_vmcoreinfo_size();
|
||||
/* nt_final */
|
||||
size += sizeof(Elf64_Nhdr);
|
||||
/* PT_LOAD type program header for kernel text region */
|
||||
size += sizeof(Elf64_Phdr);
|
||||
/* PT_LOADS */
|
||||
size += mem_chunk_cnt * sizeof(Elf64_Phdr);
|
||||
size += phdr_count * sizeof(Elf64_Phdr);
|
||||
|
||||
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)
|
||||
{
|
||||
Elf64_Phdr *phdr_notes, *phdr_loads, *phdr_text;
|
||||
int mem_chunk_cnt, phdr_text_cnt;
|
||||
size_t alloc_size;
|
||||
int mem_chunk_cnt;
|
||||
void *ptr, *hdr;
|
||||
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();
|
||||
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);
|
||||
|
||||
/* 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
|
||||
* 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");
|
||||
|
||||
/* Init elf header */
|
||||
ptr = ehdr_init(hdr, mem_chunk_cnt);
|
||||
phdr_notes = ehdr_init(hdr, mem_chunk_cnt + phdr_text_cnt);
|
||||
/* Init program headers */
|
||||
phdr_notes = ptr;
|
||||
ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr));
|
||||
phdr_text = ptr;
|
||||
ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr));
|
||||
phdr_loads = ptr;
|
||||
ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr) * mem_chunk_cnt);
|
||||
if (phdr_text_cnt) {
|
||||
phdr_text = phdr_notes + 1;
|
||||
phdr_loads = phdr_text + 1;
|
||||
} else {
|
||||
phdr_loads = phdr_notes + 1;
|
||||
}
|
||||
ptr = PTR_ADD(phdr_loads, sizeof(Elf64_Phdr) * mem_chunk_cnt);
|
||||
/* Init notes */
|
||||
hdr_off = PTR_DIFF(ptr, hdr);
|
||||
ptr = notes_init(phdr_notes, ptr, ((unsigned long) hdr) + hdr_off);
|
||||
/* Init kernel text program header */
|
||||
text_init(phdr_text);
|
||||
if (phdr_text_cnt)
|
||||
text_init(phdr_text);
|
||||
/* Init loads */
|
||||
loads_init(phdr_loads);
|
||||
loads_init(phdr_loads, phdr_text_cnt);
|
||||
/* Finalize program headers */
|
||||
hdr_off = PTR_DIFF(ptr, hdr);
|
||||
*addr = (unsigned long long) hdr;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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);
|
||||
|
||||
|
|
|
@ -295,8 +295,15 @@ void machine_kexec_cleanup(struct kimage *image)
|
|||
void machine_kexec(struct kimage *image)
|
||||
{
|
||||
unsigned long page_list[PAGES_NR];
|
||||
void *control_page;
|
||||
unsigned int host_mem_enc_active;
|
||||
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
|
||||
if (image->preserve_context)
|
||||
|
@ -358,7 +365,7 @@ void machine_kexec(struct kimage *image)
|
|||
(unsigned long)page_list,
|
||||
image->start,
|
||||
image->preserve_context,
|
||||
cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT));
|
||||
host_mem_enc_active);
|
||||
|
||||
#ifdef CONFIG_KEXEC_JUMP
|
||||
if (image->preserve_context)
|
||||
|
|
|
@ -493,7 +493,7 @@ static void __init numa_clear_kernel_node_hotplug(void)
|
|||
for_each_reserved_mem_region(mb_region) {
|
||||
int nid = memblock_get_region_node(mb_region);
|
||||
|
||||
if (nid != MAX_NUMNODES)
|
||||
if (nid != NUMA_NO_NODE)
|
||||
node_set(nid, reserved_nodemask);
|
||||
}
|
||||
|
||||
|
@ -614,9 +614,9 @@ static int __init numa_init(int (*init_func)(void))
|
|||
nodes_clear(node_online_map);
|
||||
memset(&numa_meminfo, 0, sizeof(numa_meminfo));
|
||||
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,
|
||||
MAX_NUMNODES));
|
||||
NUMA_NO_NODE));
|
||||
/* In case that parsing SRAT failed. */
|
||||
WARN_ON(memblock_clear_hotplug(0, ULLONG_MAX));
|
||||
numa_reset_distance();
|
||||
|
|
|
@ -915,10 +915,13 @@ static const struct scsi_host_template pata_macio_sht = {
|
|||
.sg_tablesize = MAX_DCMDS,
|
||||
/* We may not need that strict one */
|
||||
.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,
|
||||
.sdev_groups = ata_common_sdev_groups,
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
|
|
|
@ -1824,8 +1824,8 @@ static int null_validate_conf(struct nullb_device *dev)
|
|||
dev->queue_mode = NULL_Q_MQ;
|
||||
}
|
||||
|
||||
dev->blocksize = round_down(dev->blocksize, 512);
|
||||
dev->blocksize = clamp_t(unsigned int, dev->blocksize, 512, 4096);
|
||||
if (blk_validate_block_size(dev->blocksize))
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->use_per_node_hctx) {
|
||||
if (dev->submit_queues != nr_online_nodes)
|
||||
|
|
|
@ -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",
|
||||
&vaf, con_id, failure, max_size);
|
||||
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 *
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* Copyright (C) 2020 Zong Li
|
||||
*/
|
||||
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -537,13 +536,6 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
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,
|
||||
|
@ -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",
|
||||
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);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ret = pcibios_err_to_errno(ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
gpu_node_map.node_count = FIELD_GET(LNTM_NODE_COUNT, tmp);
|
||||
gpu_node_map.base_node_id = FIELD_GET(LNTM_BASE_NODE_ID, tmp);
|
||||
|
|
|
@ -800,7 +800,7 @@ static int errcmd_enable_error_reporting(bool enable)
|
|||
|
||||
rc = pci_read_config_word(imc->pdev, ERRCMD_OFFSET, &errcmd);
|
||||
if (rc)
|
||||
return rc;
|
||||
return pcibios_err_to_errno(rc);
|
||||
|
||||
if (enable)
|
||||
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);
|
||||
if (rc)
|
||||
return rc;
|
||||
return pcibios_err_to_errno(rc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1576,7 +1576,7 @@ config GPIO_TPS68470
|
|||
are "output only" GPIOs.
|
||||
|
||||
config GPIO_TQMX86
|
||||
tristate "TQ-Systems QTMX86 GPIO"
|
||||
tristate "TQ-Systems TQMx86 GPIO"
|
||||
depends on MFD_TQMX86 || COMPILE_TEST
|
||||
depends on HAS_IOPORT_MAP
|
||||
select GPIOLIB_IRQCHIP
|
||||
|
|
|
@ -130,5 +130,6 @@ static struct i2c_driver gw_pld_driver = {
|
|||
};
|
||||
module_i2c_driver(gw_pld_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Gateworks I2C PLD GPIO expander");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
|
||||
|
|
|
@ -168,5 +168,6 @@ static void __exit mc33880_exit(void)
|
|||
module_exit(mc33880_exit);
|
||||
|
||||
MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
|
||||
MODULE_DESCRIPTION("MC33880 high-side/low-side switch GPIO driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
|
|
|
@ -438,5 +438,6 @@ static void __exit pcf857x_exit(void)
|
|||
}
|
||||
module_exit(pcf857x_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Driver for pcf857x, pca857x, and pca967x I2C GPIO expanders");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("David Brownell");
|
||||
|
|
|
@ -438,4 +438,5 @@ static struct 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");
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Vadim V.Vlasov <vvlasov@dev.rtsoft.ru>
|
||||
*/
|
||||
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
@ -28,16 +29,25 @@
|
|||
#define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */
|
||||
#define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */
|
||||
|
||||
#define TQMX86_GPII_NONE 0
|
||||
#define TQMX86_GPII_FALLING BIT(0)
|
||||
#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_BITS 2
|
||||
/* Stored in irq_type with GPII bits */
|
||||
#define TQMX86_INT_UNMASKED BIT(2)
|
||||
|
||||
struct tqmx86_gpio_data {
|
||||
struct gpio_chip chip;
|
||||
void __iomem *io_base;
|
||||
int irq;
|
||||
/* Lock must be held for accessing output and irq_type fields */
|
||||
raw_spinlock_t spinlock;
|
||||
DECLARE_BITMAP(output, TQMX86_NGPIO);
|
||||
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);
|
||||
unsigned long flags;
|
||||
u8 val;
|
||||
|
||||
raw_spin_lock_irqsave(&gpio->spinlock, flags);
|
||||
val = tqmx86_gpio_read(gpio, TQMX86_GPIOD);
|
||||
if (value)
|
||||
val |= BIT(offset);
|
||||
else
|
||||
val &= ~BIT(offset);
|
||||
tqmx86_gpio_write(gpio, val, TQMX86_GPIOD);
|
||||
__assign_bit(offset, gpio->output, value);
|
||||
tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned int offset = (data->hwirq - TQMX86_NGPO);
|
||||
struct tqmx86_gpio_data *gpio = gpiochip_get_data(
|
||||
irq_data_get_irq_chip_data(data));
|
||||
unsigned long flags;
|
||||
u8 gpiic, mask;
|
||||
|
||||
mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
|
||||
|
||||
raw_spin_lock_irqsave(&gpio->spinlock, flags);
|
||||
gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
|
||||
gpiic &= ~mask;
|
||||
tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
|
||||
gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED;
|
||||
tqmx86_gpio_irq_config(gpio, offset);
|
||||
raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
|
||||
|
||||
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(
|
||||
irq_data_get_irq_chip_data(data));
|
||||
unsigned long flags;
|
||||
u8 gpiic, mask;
|
||||
|
||||
mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
|
||||
|
||||
gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data));
|
||||
|
||||
raw_spin_lock_irqsave(&gpio->spinlock, flags);
|
||||
gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
|
||||
gpiic &= ~mask;
|
||||
gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS);
|
||||
tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
|
||||
gpio->irq_type[offset] |= TQMX86_INT_UNMASKED;
|
||||
tqmx86_gpio_irq_config(gpio, offset);
|
||||
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 edge_type = type & IRQF_TRIGGER_MASK;
|
||||
unsigned long flags;
|
||||
u8 new_type, gpiic;
|
||||
u8 new_type;
|
||||
|
||||
switch (edge_type) {
|
||||
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;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
new_type = TQMX86_GPII_FALLING | TQMX86_GPII_RISING;
|
||||
new_type = TQMX86_INT_BOTH;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL; /* not supported */
|
||||
}
|
||||
|
||||
gpio->irq_type[offset] = new_type;
|
||||
|
||||
raw_spin_lock_irqsave(&gpio->spinlock, flags);
|
||||
gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
|
||||
gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS));
|
||||
gpiic |= new_type << (offset * TQMX86_GPII_BITS);
|
||||
tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
|
||||
gpio->irq_type[offset] &= ~TQMX86_GPII_MASK;
|
||||
gpio->irq_type[offset] |= new_type;
|
||||
tqmx86_gpio_irq_config(gpio, offset);
|
||||
raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
|
||||
|
||||
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 tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
|
||||
struct irq_chip *irq_chip = irq_desc_get_chip(desc);
|
||||
unsigned long irq_bits;
|
||||
int i = 0;
|
||||
unsigned long irq_bits, flags;
|
||||
int i;
|
||||
u8 irq_status;
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
generic_handle_domain_irq(gpio->chip.irq.domain,
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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->label = "gpio-tqmx86";
|
||||
chip->owner = THIS_MODULE;
|
||||
|
|
|
@ -477,31 +477,30 @@ typedef struct _ATOM_PPLIB_STATE_V2
|
|||
} ATOM_PPLIB_STATE_V2;
|
||||
|
||||
typedef struct _StateArray{
|
||||
//how many states we have
|
||||
UCHAR ucNumEntries;
|
||||
|
||||
ATOM_PPLIB_STATE_V2 states[1];
|
||||
//how many states we have
|
||||
UCHAR ucNumEntries;
|
||||
|
||||
ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */;
|
||||
}StateArray;
|
||||
|
||||
|
||||
typedef struct _ClockInfoArray{
|
||||
//how many clock levels we have
|
||||
UCHAR ucNumEntries;
|
||||
|
||||
//sizeof(ATOM_PPLIB_CLOCK_INFO)
|
||||
UCHAR ucEntrySize;
|
||||
|
||||
UCHAR clockInfo[];
|
||||
//how many clock levels we have
|
||||
UCHAR ucNumEntries;
|
||||
|
||||
//sizeof(ATOM_PPLIB_CLOCK_INFO)
|
||||
UCHAR ucEntrySize;
|
||||
|
||||
UCHAR clockInfo[];
|
||||
}ClockInfoArray;
|
||||
|
||||
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
|
||||
UCHAR ucNumEntries;
|
||||
//sizeof(ATOM_PPLIB_NONCLOCK_INFO)
|
||||
UCHAR ucEntrySize;
|
||||
|
||||
ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[];
|
||||
ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries);
|
||||
}NonClockInfoArray;
|
||||
|
||||
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
|
||||
{
|
||||
UCHAR ucNumEntries; // Number of entries.
|
||||
ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[1]; // Dynamically allocate entries.
|
||||
// Number of entries.
|
||||
UCHAR ucNumEntries;
|
||||
// Dynamically allocate entries.
|
||||
ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[] __counted_by(ucNumEntries);
|
||||
}ATOM_PPLIB_Clock_Voltage_Dependency_Table;
|
||||
|
||||
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
|
||||
{
|
||||
UCHAR ucNumEntries; // Number of entries.
|
||||
ATOM_PPLIB_Clock_Voltage_Limit_Record entries[1]; // Dynamically allocate entries.
|
||||
// Number of entries.
|
||||
UCHAR ucNumEntries;
|
||||
// Dynamically allocate entries.
|
||||
ATOM_PPLIB_Clock_Voltage_Limit_Record entries[] __counted_by(ucNumEntries);
|
||||
}ATOM_PPLIB_Clock_Voltage_Limit_Table;
|
||||
|
||||
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
|
||||
{
|
||||
UCHAR ucNumEntries; // Number of entries.
|
||||
ATOM_PPLIB_CAC_Leakage_Record entries[1]; // Dynamically allocate entries.
|
||||
// Number of entries.
|
||||
UCHAR ucNumEntries;
|
||||
// Dynamically allocate entries.
|
||||
ATOM_PPLIB_CAC_Leakage_Record entries[] __counted_by(ucNumEntries);
|
||||
}ATOM_PPLIB_CAC_Leakage_Table;
|
||||
|
||||
typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record
|
||||
|
@ -568,8 +573,10 @@ typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record
|
|||
|
||||
typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Table
|
||||
{
|
||||
UCHAR ucNumEntries; // Number of entries.
|
||||
ATOM_PPLIB_PhaseSheddingLimits_Record entries[1]; // Dynamically allocate entries.
|
||||
// Number of entries.
|
||||
UCHAR ucNumEntries;
|
||||
// Dynamically allocate entries.
|
||||
ATOM_PPLIB_PhaseSheddingLimits_Record entries[] __counted_by(ucNumEntries);
|
||||
}ATOM_PPLIB_PhaseSheddingLimits_Table;
|
||||
|
||||
typedef struct _VCEClockInfo{
|
||||
|
@ -580,8 +587,8 @@ typedef struct _VCEClockInfo{
|
|||
}VCEClockInfo;
|
||||
|
||||
typedef struct _VCEClockInfoArray{
|
||||
UCHAR ucNumEntries;
|
||||
VCEClockInfo entries[1];
|
||||
UCHAR ucNumEntries;
|
||||
VCEClockInfo entries[] __counted_by(ucNumEntries);
|
||||
}VCEClockInfoArray;
|
||||
|
||||
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
|
||||
{
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[1];
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries);
|
||||
}ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table;
|
||||
|
||||
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
|
||||
{
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_VCE_State_Record entries[1];
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_VCE_State_Record entries[] __counted_by(numEntries);
|
||||
}ATOM_PPLIB_VCE_State_Table;
|
||||
|
||||
|
||||
|
@ -626,8 +633,8 @@ typedef struct _UVDClockInfo{
|
|||
}UVDClockInfo;
|
||||
|
||||
typedef struct _UVDClockInfoArray{
|
||||
UCHAR ucNumEntries;
|
||||
UVDClockInfo entries[1];
|
||||
UCHAR ucNumEntries;
|
||||
UVDClockInfo entries[] __counted_by(ucNumEntries);
|
||||
}UVDClockInfoArray;
|
||||
|
||||
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
|
||||
{
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[1];
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries);
|
||||
}ATOM_PPLIB_UVD_Clock_Voltage_Limit_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;
|
||||
|
||||
typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Table{
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[];
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[] __counted_by(numEntries);
|
||||
}ATOM_PPLIB_SAMClk_Voltage_Limit_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;
|
||||
|
||||
typedef struct _ATOM_PPLIB_ACPClk_Voltage_Limit_Table{
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[1];
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[] __counted_by(numEntries);
|
||||
}ATOM_PPLIB_ACPClk_Voltage_Limit_Table;
|
||||
|
||||
typedef struct _ATOM_PPLIB_ACP_Table
|
||||
|
@ -743,9 +750,9 @@ typedef struct ATOM_PPLIB_VQ_Budgeting_Record{
|
|||
} ATOM_PPLIB_VQ_Budgeting_Record;
|
||||
|
||||
typedef struct ATOM_PPLIB_VQ_Budgeting_Table {
|
||||
UCHAR revid;
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_VQ_Budgeting_Record entries[1];
|
||||
UCHAR revid;
|
||||
UCHAR numEntries;
|
||||
ATOM_PPLIB_VQ_Budgeting_Record entries[] __counted_by(numEntries);
|
||||
} ATOM_PPLIB_VQ_Budgeting_Table;
|
||||
|
||||
#pragma pack()
|
||||
|
|
|
@ -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;
|
||||
int ret = 0;
|
||||
|
||||
if (!en && adev->in_s4) {
|
||||
/* Adds a GFX reset as workaround just before sending the
|
||||
* 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);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!en && !adev->in_s0ix) {
|
||||
if (adev->in_s4) {
|
||||
/* Adds a GFX reset as workaround just before sending the
|
||||
* 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);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
|
||||
}
|
||||
|
|
|
@ -72,11 +72,6 @@ struct gamma_curve_sector {
|
|||
u32 segment_width;
|
||||
};
|
||||
|
||||
struct gamma_curve_segment {
|
||||
u32 start;
|
||||
u32 end;
|
||||
};
|
||||
|
||||
static struct gamma_curve_sector sector_tbl[] = {
|
||||
{ 0, 4, 4 },
|
||||
{ 16, 4, 4 },
|
||||
|
|
|
@ -643,7 +643,9 @@ static int st7789v_probe(struct spi_device *spi)
|
|||
if (ret)
|
||||
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);
|
||||
|
||||
|
|
|
@ -746,7 +746,7 @@ static int vmw_setup_pci_resources(struct vmw_private *dev,
|
|||
dev->vram_size = pci_resource_len(pdev, 2);
|
||||
|
||||
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);
|
||||
dev->rmmio = devm_ioremap(dev->drm.dev,
|
||||
rmmio_start,
|
||||
|
@ -765,7 +765,7 @@ static int vmw_setup_pci_resources(struct vmw_private *dev,
|
|||
fifo_size = pci_resource_len(pdev, 2);
|
||||
|
||||
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);
|
||||
dev->fifo_mem = devm_memremap(dev->drm.dev,
|
||||
fifo_start,
|
||||
|
@ -790,7 +790,7 @@ static int vmw_setup_pci_resources(struct vmw_private *dev,
|
|||
* SVGA_REG_VRAM_SIZE.
|
||||
*/
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
@ -960,13 +960,6 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
|
|||
vmw_read(dev_priv,
|
||||
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_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;
|
||||
}
|
||||
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->fifo_mem_size / 1024,
|
||||
dev_priv->memory_size / 1024);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
/* Need mmio memory to check for fifo pitchlock cap. */
|
||||
|
|
|
@ -1043,9 +1043,6 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
|
|||
int vmw_kms_write_svga(struct vmw_private *vmw_priv,
|
||||
unsigned width, unsigned height, unsigned pitch,
|
||||
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,
|
||||
struct drm_file *file_priv,
|
||||
struct vmw_framebuffer *vfb,
|
||||
|
|
|
@ -94,14 +94,14 @@ static int vmw_gmrid_man_get_node(struct ttm_resource_manager *man,
|
|||
} else
|
||||
new_max_pages = gman->max_gmr_pages * 2;
|
||||
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)));
|
||||
|
||||
gman->max_gmr_pages = new_max_pages;
|
||||
} else {
|
||||
char buf[256];
|
||||
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)));
|
||||
vmw_host_printf(buf);
|
||||
DRM_WARN("%s", buf);
|
||||
|
|
|
@ -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);
|
||||
|
||||
changed = false;
|
||||
if (old_image && new_image)
|
||||
if (old_image && new_image && old_image != new_image)
|
||||
changed = memcmp(old_image, new_image, size) != 0;
|
||||
|
||||
return changed;
|
||||
|
@ -2171,13 +2171,12 @@ int vmw_kms_write_svga(struct vmw_private *vmw_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
|
||||
uint32_t pitch,
|
||||
uint32_t height)
|
||||
u64 pitch,
|
||||
u64 height)
|
||||
{
|
||||
return ((u64) pitch * (u64) height) < (u64)
|
||||
((dev_priv->active_display_unit == vmw_du_screen_target) ?
|
||||
dev_priv->max_primary_mem : dev_priv->vram_size);
|
||||
return (pitch * height) < (u64)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,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
enum drm_mode_status ret;
|
||||
struct drm_device *dev = connector->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;
|
||||
|
||||
if (dev_priv->assume_16bpp)
|
||||
assumed_cpp = 2;
|
||||
|
||||
if (dev_priv->active_display_unit == vmw_du_screen_target) {
|
||||
max_width = min(dev_priv->stdu_max_width, max_width);
|
||||
max_height = min(dev_priv->stdu_max_height, max_height);
|
||||
}
|
||||
|
||||
if (max_width < mode->hdisplay)
|
||||
return MODE_BAD_HVALUE;
|
||||
|
||||
if (max_height < mode->vdisplay)
|
||||
return MODE_BAD_VVALUE;
|
||||
ret = drm_mode_validate_size(mode, dev_priv->texture_max_width,
|
||||
dev_priv->texture_max_height);
|
||||
if (ret != MODE_OK)
|
||||
return ret;
|
||||
|
||||
if (!vmw_kms_validate_mode_vram(dev_priv,
|
||||
mode->hdisplay * assumed_cpp,
|
||||
|
|
|
@ -43,7 +43,14 @@
|
|||
#define vmw_connector_to_stdu(x) \
|
||||
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 {
|
||||
SAME_AS_DISPLAY = 0,
|
||||
|
@ -85,11 +92,6 @@ struct vmw_stdu_update {
|
|||
SVGA3dCmdUpdateGBScreenTarget body;
|
||||
};
|
||||
|
||||
struct vmw_stdu_dma {
|
||||
SVGA3dCmdHeader header;
|
||||
SVGA3dCmdSurfaceDMA body;
|
||||
};
|
||||
|
||||
struct vmw_stdu_surface_copy {
|
||||
SVGA3dCmdHeader header;
|
||||
SVGA3dCmdSurfaceCopy body;
|
||||
|
@ -414,6 +416,7 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc,
|
|||
{
|
||||
struct vmw_private *dev_priv;
|
||||
struct vmw_screen_target_display_unit *stdu;
|
||||
struct drm_crtc_state *new_crtc_state;
|
||||
int ret;
|
||||
|
||||
if (!crtc) {
|
||||
|
@ -423,6 +426,7 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc,
|
|||
|
||||
stdu = vmw_crtc_to_stdu(crtc);
|
||||
dev_priv = vmw_priv(crtc->dev);
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
if (dev_priv->vkms_enabled)
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
if (ret)
|
||||
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));
|
||||
}
|
||||
|
||||
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 = {
|
||||
.dpms = vmw_du_connector_dpms,
|
||||
|
@ -845,7 +891,7 @@ static const struct drm_connector_funcs vmw_stdu_connector_funcs = {
|
|||
static const struct
|
||||
drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = {
|
||||
.get_modes = vmw_connector_get_modes,
|
||||
.mode_valid = vmw_connector_mode_valid
|
||||
.mode_valid = vmw_stdu_connector_mode_valid
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1749,6 +1749,7 @@ static void pf_release_vf_config(struct xe_gt *gt, unsigned int vfid)
|
|||
if (!xe_gt_is_media_type(gt)) {
|
||||
pf_release_vf_config_ggtt(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_dbs(gt, config);
|
||||
|
|
|
@ -1204,8 +1204,8 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||
}
|
||||
|
||||
/* match many more n-key devices */
|
||||
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
|
||||
for (int i = 0; i < *rsize + 1; i++) {
|
||||
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && *rsize > 15) {
|
||||
for (int i = 0; i < *rsize - 15; i++) {
|
||||
/* offset to the count from 0x5a report part always 14 */
|
||||
if (rdesc[i] == 0x85 && rdesc[i + 1] == 0x5a &&
|
||||
rdesc[i + 14] == 0x95 && rdesc[i + 15] == 0x05) {
|
||||
|
|
|
@ -1448,7 +1448,6 @@ static void implement(const struct hid_device *hid, u8 *report,
|
|||
hid_warn(hid,
|
||||
"%s() called with too large value %d (n: %d)! (%s)\n",
|
||||
__func__, value, n, current->comm);
|
||||
WARN_ON(1);
|
||||
value &= m;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3366,6 +3366,8 @@ static const char *keys[KEY_MAX + 1] = {
|
|||
[KEY_CAMERA_ACCESS_ENABLE] = "CameraAccessEnable",
|
||||
[KEY_CAMERA_ACCESS_DISABLE] = "CameraAccessDisable",
|
||||
[KEY_CAMERA_ACCESS_TOGGLE] = "CameraAccessToggle",
|
||||
[KEY_ACCESSIBILITY] = "Accessibility",
|
||||
[KEY_DO_NOT_DISTURB] = "DoNotDisturb",
|
||||
[KEY_DICTATE] = "Dictate",
|
||||
[KEY_MICMUTE] = "MicrophoneMute",
|
||||
[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
|
||||
|
|
|
@ -423,6 +423,8 @@
|
|||
#define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF
|
||||
#define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
|
||||
#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_UX550_TOUCHSCREEN 0x2706
|
||||
#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A
|
||||
|
|
|
@ -377,6 +377,10 @@ static const struct hid_device_id hid_battery_quirks[] = {
|
|||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN),
|
||||
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_BATTERY_QUIRK_IGNORE },
|
||||
{ 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;
|
||||
}
|
||||
|
||||
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 */
|
||||
switch (usage->hid & 0xf) {
|
||||
case 0x9: map_key_clear(KEY_MICMUTE); break;
|
||||
case 0xa: map_key_clear(KEY_ACCESSIBILITY); break;
|
||||
default: goto ignore;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1284,8 +1284,10 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
|
|||
*/
|
||||
msleep(50);
|
||||
|
||||
if (retval)
|
||||
if (retval) {
|
||||
kfree(dj_report);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "usbhid/usbhid.h"
|
||||
#include "hid-ids.h"
|
||||
|
||||
MODULE_DESCRIPTION("Support for Logitech devices relying on the HID++ specification");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
|
||||
MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>");
|
||||
|
|
|
@ -2725,13 +2725,13 @@ static int nintendo_hid_probe(struct hid_device *hdev,
|
|||
ret = joycon_power_supply_create(ctlr);
|
||||
if (ret) {
|
||||
hid_err(hdev, "Failed to create power_supply; ret=%d\n", ret);
|
||||
goto err_close;
|
||||
goto err_ida;
|
||||
}
|
||||
|
||||
ret = joycon_input_create(ctlr);
|
||||
if (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;
|
||||
|
@ -2739,6 +2739,8 @@ static int nintendo_hid_probe(struct hid_device *hdev,
|
|||
hid_dbg(hdev, "probe - success\n");
|
||||
return 0;
|
||||
|
||||
err_ida:
|
||||
ida_free(&nintendo_player_id_allocator, ctlr->player_id);
|
||||
err_close:
|
||||
hid_hw_close(hdev);
|
||||
err_stop:
|
||||
|
|
|
@ -283,7 +283,9 @@ static struct input_dev *shield_haptics_create(
|
|||
return haptics;
|
||||
|
||||
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);
|
||||
if (ret)
|
||||
|
|
|
@ -31,6 +31,7 @@ struct i2c_hid_of_elan {
|
|||
struct regulator *vcc33;
|
||||
struct regulator *vccio;
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool no_reset_on_power_off;
|
||||
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);
|
||||
int ret;
|
||||
|
||||
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
|
||||
|
||||
if (ihid_elan->vcc33) {
|
||||
ret = regulator_enable(ihid_elan->vcc33);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_deassert_reset;
|
||||
}
|
||||
|
||||
ret = regulator_enable(ihid_elan->vccio);
|
||||
if (ret) {
|
||||
regulator_disable(ihid_elan->vcc33);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto err_disable_vcc33;
|
||||
|
||||
if (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);
|
||||
|
||||
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)
|
||||
|
@ -67,7 +77,14 @@ static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
|
|||
struct i2c_hid_of_elan *ihid_elan =
|
||||
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)
|
||||
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)
|
||||
{
|
||||
struct i2c_hid_of_elan *ihid_elan;
|
||||
int ret;
|
||||
|
||||
ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL);
|
||||
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))
|
||||
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");
|
||||
if (IS_ERR(ihid_elan->vccio))
|
||||
return PTR_ERR(ihid_elan->vccio);
|
||||
if (IS_ERR(ihid_elan->vccio)) {
|
||||
ret = PTR_ERR(ihid_elan->vccio);
|
||||
goto err_deassert_reset;
|
||||
}
|
||||
|
||||
ihid_elan->chip_data = device_get_match_data(&client->dev);
|
||||
|
||||
if (ihid_elan->chip_data->main_supply_name) {
|
||||
ihid_elan->vcc33 = devm_regulator_get(&client->dev,
|
||||
ihid_elan->chip_data->main_supply_name);
|
||||
if (IS_ERR(ihid_elan->vcc33))
|
||||
return PTR_ERR(ihid_elan->vcc33);
|
||||
if (IS_ERR(ihid_elan->vcc33)) {
|
||||
ret = PTR_ERR(ihid_elan->vcc33);
|
||||
goto err_deassert_reset;
|
||||
}
|
||||
}
|
||||
|
||||
return i2c_hid_core_probe(client, &ihid_elan->ops,
|
||||
ihid_elan->chip_data->hid_descriptor_address, 0);
|
||||
ret = i2c_hid_core_probe(client, &ihid_elan->ops,
|
||||
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 = {
|
||||
|
|
|
@ -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,
|
||||
void *resp, int resp_len)
|
||||
{
|
||||
struct loader_msg_header *req_hdr = req;
|
||||
struct loader_msg_header *resp_hdr = resp;
|
||||
union loader_msg_header req_hdr;
|
||||
union loader_msg_header resp_hdr;
|
||||
struct device *devc = dev->devc;
|
||||
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;
|
||||
|
||||
rv = loader_write_message(dev, req, req_len);
|
||||
req_hdr.val32 = le32_to_cpup(req);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Wait the ACK */
|
||||
wait_event_interruptible_timeout(dev->wait_loader_recvd_msg, dev->fw_loader_received,
|
||||
ISHTP_LOADER_TIMEOUT);
|
||||
resp_hdr.val32 = le32_to_cpup(resp);
|
||||
dev->fw_loader_rx_size = 0;
|
||||
dev->fw_loader_rx_buf = NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
if (!resp_hdr->is_response) {
|
||||
dev_err(devc, "not a response for %u\n", req_hdr->command);
|
||||
if (!resp_hdr.is_response) {
|
||||
dev_err(devc, "not a response for %u\n", req_hdr.command);
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
if (req_hdr->command != resp_hdr->command) {
|
||||
dev_err(devc, "unexpected cmd response %u:%u\n", 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,
|
||||
resp_hdr.command);
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
if (resp_hdr->status) {
|
||||
dev_err(devc, "cmd %u failed %u\n", req_hdr->command, resp_hdr->status);
|
||||
if (resp_hdr.status) {
|
||||
dev_err(devc, "cmd %u failed %u\n", req_hdr.command, resp_hdr.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -138,12 +141,13 @@ static void release_dma_bufs(struct ishtp_device *dev,
|
|||
struct loader_xfer_dma_fragment *fragment,
|
||||
void **dma_bufs, u32 fragment_size)
|
||||
{
|
||||
dma_addr_t dma_addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FRAGMENT_MAX_NUM; i++) {
|
||||
if (dma_bufs[i]) {
|
||||
dma_free_coherent(dev->devc, fragment_size, dma_bufs[i],
|
||||
fragment->fragment_tbl[i].ddr_adrs);
|
||||
dma_addr = le64_to_cpu(fragment->fragment_tbl[i].ddr_adrs);
|
||||
dma_free_coherent(dev->devc, fragment_size, dma_bufs[i], dma_addr);
|
||||
dma_bufs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -156,29 +160,33 @@ static void release_dma_bufs(struct ishtp_device *dev,
|
|||
* @fragment: The ISHTP firmware fragment descriptor
|
||||
* @dma_bufs: The array of DMA fragment buffers
|
||||
* @fragment_size: The size of a single DMA fragment
|
||||
* @fragment_count: Number of fragments
|
||||
*
|
||||
* Return: 0 on success, negative error code on failure
|
||||
*/
|
||||
static int prepare_dma_bufs(struct ishtp_device *dev,
|
||||
const struct firmware *ish_fw,
|
||||
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 length;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fragment->fragment_cnt && offset < ish_fw->size; i++) {
|
||||
dma_bufs[i] = dma_alloc_coherent(dev->devc, fragment_size,
|
||||
&fragment->fragment_tbl[i].ddr_adrs, GFP_KERNEL);
|
||||
for (i = 0; i < fragment_count && offset < ish_fw->size; i++) {
|
||||
dma_bufs[i] = dma_alloc_coherent(dev->devc, fragment_size, &dma_addr, GFP_KERNEL);
|
||||
if (!dma_bufs[i])
|
||||
return -ENOMEM;
|
||||
|
||||
fragment->fragment_tbl[i].length = clamp(ish_fw->size - offset, 0, fragment_size);
|
||||
fragment->fragment_tbl[i].fw_off = offset;
|
||||
memcpy(dma_bufs[i], ish_fw->data + offset, fragment->fragment_tbl[i].length);
|
||||
fragment->fragment_tbl[i].ddr_adrs = cpu_to_le64(dma_addr);
|
||||
length = clamp(ish_fw->size - offset, 0, fragment_size);
|
||||
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);
|
||||
|
||||
offset += fragment->fragment_tbl[i].length;
|
||||
offset += length;
|
||||
}
|
||||
|
||||
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);
|
||||
struct ishtp_device *dev = container_of(work, struct ishtp_device, work_fw_loader);
|
||||
struct loader_xfer_query query = {
|
||||
.header.command = LOADER_CMD_XFER_QUERY,
|
||||
};
|
||||
struct loader_start start = {
|
||||
.header.command = LOADER_CMD_START,
|
||||
};
|
||||
union loader_msg_header query_hdr = { .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_xfer_query query = { .header = cpu_to_le32(query_hdr.val32), };
|
||||
struct loader_start start = { .header = cpu_to_le32(start_hdr.val32), };
|
||||
union loader_recv_message recv_msg;
|
||||
char *filename = dev->driver_data->fw_filename;
|
||||
const struct firmware *ish_fw;
|
||||
void *dma_bufs[FRAGMENT_MAX_NUM] = {};
|
||||
u32 fragment_size;
|
||||
u32 fragment_count;
|
||||
int retry = ISHTP_LOADER_RETRY_TIMES;
|
||||
int rv;
|
||||
|
||||
|
@ -226,23 +234,24 @@ void ishtp_loader_work(struct work_struct *work)
|
|||
return;
|
||||
}
|
||||
|
||||
fragment->fragment.header.command = LOADER_CMD_XFER_FRAGMENT;
|
||||
fragment->fragment.xfer_mode = LOADER_XFER_MODE_DMA;
|
||||
fragment->fragment.is_last = 1;
|
||||
fragment->fragment.size = ish_fw->size;
|
||||
fragment->fragment.header = cpu_to_le32(fragment_hdr.val32);
|
||||
fragment->fragment.xfer_mode = cpu_to_le32(LOADER_XFER_MODE_DMA);
|
||||
fragment->fragment.is_last = cpu_to_le32(1);
|
||||
fragment->fragment.size = cpu_to_le32(ish_fw->size);
|
||||
/* Calculate the size of a single DMA fragment */
|
||||
fragment_size = PFN_ALIGN(DIV_ROUND_UP(ish_fw->size, FRAGMENT_MAX_NUM));
|
||||
/* 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) {
|
||||
dev_err(dev->devc, "prepare DMA buffer failed.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
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,
|
||||
sizeof(struct loader_xfer_query_ack));
|
||||
if (rv)
|
||||
|
@ -255,7 +264,7 @@ void ishtp_loader_work(struct work_struct *work)
|
|||
recv_msg.query_ack.version_build);
|
||||
|
||||
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));
|
||||
if (rv)
|
||||
continue; /* try again if failed */
|
||||
|
|
|
@ -30,19 +30,23 @@ struct work_struct;
|
|||
#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
|
||||
* @is_response: Indicates if the message is a response
|
||||
* @has_next: Indicates if there is a next message
|
||||
* @reserved: Reserved for future use
|
||||
* @status: Status of the message
|
||||
* @val32: entire header as a 32-bit value
|
||||
*/
|
||||
struct loader_msg_header {
|
||||
__le32 command:7;
|
||||
__le32 is_response:1;
|
||||
__le32 has_next:1;
|
||||
__le32 reserved:15;
|
||||
__le32 status:8;
|
||||
union loader_msg_header {
|
||||
struct {
|
||||
__u32 command:7;
|
||||
__u32 is_response:1;
|
||||
__u32 has_next:1;
|
||||
__u32 reserved:15;
|
||||
__u32 status:8;
|
||||
};
|
||||
__u32 val32;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -51,7 +55,7 @@ struct loader_msg_header {
|
|||
* @image_size: Size of the image
|
||||
*/
|
||||
struct loader_xfer_query {
|
||||
struct loader_msg_header header;
|
||||
__le32 header;
|
||||
__le32 image_size;
|
||||
};
|
||||
|
||||
|
@ -103,7 +107,7 @@ struct loader_capability {
|
|||
* @capability: Loader capability
|
||||
*/
|
||||
struct loader_xfer_query_ack {
|
||||
struct loader_msg_header header;
|
||||
__le32 header;
|
||||
__le16 version_major;
|
||||
__le16 version_minor;
|
||||
__le16 version_hotfix;
|
||||
|
@ -122,7 +126,7 @@ struct loader_xfer_query_ack {
|
|||
* @is_last: Is last
|
||||
*/
|
||||
struct loader_xfer_fragment {
|
||||
struct loader_msg_header header;
|
||||
__le32 header;
|
||||
__le32 xfer_mode;
|
||||
__le32 offset;
|
||||
__le32 size;
|
||||
|
@ -134,7 +138,7 @@ struct loader_xfer_fragment {
|
|||
* @header: Header of the message
|
||||
*/
|
||||
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
|
||||
*/
|
||||
struct loader_start {
|
||||
struct loader_msg_header header;
|
||||
__le32 header;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -178,10 +182,11 @@ struct loader_start {
|
|||
* @header: Header of the message
|
||||
*/
|
||||
struct loader_start_ack {
|
||||
struct loader_msg_header header;
|
||||
__le32 header;
|
||||
};
|
||||
|
||||
union loader_recv_message {
|
||||
__le32 header;
|
||||
struct loader_xfer_query_ack query_ack;
|
||||
struct loader_xfer_fragment_ack fragment_ack;
|
||||
struct loader_start_ack start_ack;
|
||||
|
|
|
@ -71,7 +71,6 @@ struct silead_ts_data {
|
|||
struct regulator_bulk_data regulators[2];
|
||||
char fw_name[64];
|
||||
struct touchscreen_properties prop;
|
||||
u32 max_fingers;
|
||||
u32 chip_id;
|
||||
struct input_mt_pos pos[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);
|
||||
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_TRACK);
|
||||
|
||||
|
@ -256,10 +255,10 @@ static void silead_ts_read_data(struct i2c_client *client)
|
|||
return;
|
||||
}
|
||||
|
||||
if (buf[0] > data->max_fingers) {
|
||||
if (buf[0] > SILEAD_MAX_FINGERS) {
|
||||
dev_warn(dev, "More touches reported then supported %d > %d\n",
|
||||
buf[0], data->max_fingers);
|
||||
buf[0] = data->max_fingers;
|
||||
buf[0], SILEAD_MAX_FINGERS);
|
||||
buf[0] = SILEAD_MAX_FINGERS;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct silead_ts_data *data = i2c_get_clientdata(client);
|
||||
int error;
|
||||
|
||||
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);
|
||||
|
||||
error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR,
|
||||
data->max_fingers);
|
||||
SILEAD_MAX_FINGERS);
|
||||
if (error)
|
||||
goto i2c_write_err;
|
||||
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;
|
||||
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);
|
||||
if (!error)
|
||||
snprintf(data->fw_name, sizeof(data->fw_name),
|
||||
|
|
|
@ -129,7 +129,8 @@ static inline int check_feature_gpt_level(void)
|
|||
static inline bool amd_iommu_gt_ppr_supported(void)
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
free_sysfs(iommu);
|
||||
free_cwwb_sem(iommu);
|
||||
free_command_buffer(iommu);
|
||||
free_event_buffer(iommu);
|
||||
|
|
|
@ -2032,7 +2032,6 @@ static int do_attach(struct iommu_dev_data *dev_data,
|
|||
struct protection_domain *domain)
|
||||
{
|
||||
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
|
||||
struct pci_dev *pdev;
|
||||
int ret = 0;
|
||||
|
||||
/* 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_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)) {
|
||||
ret = init_gcr3_table(dev_data, domain);
|
||||
if (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;
|
||||
}
|
||||
|
||||
|
@ -2163,6 +2145,11 @@ static void detach_device(struct device *dev)
|
|||
|
||||
do_detach(dev_data);
|
||||
|
||||
out:
|
||||
spin_unlock(&dev_data->lock);
|
||||
|
||||
spin_unlock_irqrestore(&domain->lock, flags);
|
||||
|
||||
/* Remove IOPF handler */
|
||||
if (ppr)
|
||||
amd_iommu_iopf_remove_device(iommu, dev_data);
|
||||
|
@ -2170,10 +2157,6 @@ static void detach_device(struct device *dev)
|
|||
if (dev_is_pci(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)
|
||||
|
@ -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 protection_domain *domain = to_pdomain(dom);
|
||||
struct amd_iommu *iommu = get_amd_iommu_from_dev(dev);
|
||||
struct pci_dev *pdev;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -2517,7 +2501,23 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
|
|||
}
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -222,8 +222,7 @@ int amd_iommu_iopf_init(struct amd_iommu *iommu)
|
|||
if (iommu->iopf_queue)
|
||||
return ret;
|
||||
|
||||
snprintf(iommu->iopfq_name, sizeof(iommu->iopfq_name),
|
||||
"amdiommu-%#x-iopfq",
|
||||
snprintf(iommu->iopfq_name, sizeof(iommu->iopfq_name), "amdvi-%#x",
|
||||
PCI_SEG_DEVID_TO_SBDF(iommu->pci_seg->id, iommu->devid));
|
||||
|
||||
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,
|
||||
struct iommu_dev_data *dev_data)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (!dev_data->pri_enabled)
|
||||
return ret;
|
||||
|
||||
raw_spin_lock_irqsave(&iommu->lock, flags);
|
||||
|
||||
if (!iommu->iopf_queue) {
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
if (!iommu->iopf_queue)
|
||||
return -EINVAL;
|
||||
|
||||
ret = iopf_queue_add_device(iommu->iopf_queue, dev_data->dev);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
return ret;
|
||||
|
||||
dev_data->ppr = true;
|
||||
|
||||
out_unlock:
|
||||
raw_spin_unlock_irqrestore(&iommu->lock, flags);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Its assumed that caller has verified that device was added to iopf queue */
|
||||
void amd_iommu_iopf_remove_device(struct amd_iommu *iommu,
|
||||
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);
|
||||
dev_data->ppr = false;
|
||||
|
||||
raw_spin_unlock_irqrestore(&iommu->lock, flags);
|
||||
}
|
||||
|
|
|
@ -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... */
|
||||
if (map) {
|
||||
dma_addr_t base = dma_range_map_min(map);
|
||||
if (base > domain->geometry.aperture_end ||
|
||||
if (dma_range_map_min(map) > domain->geometry.aperture_end ||
|
||||
dma_range_map_max(map) < domain->geometry.aperture_start) {
|
||||
pr_warn("specified DMA range outside IOMMU capability\n");
|
||||
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 */
|
||||
mutex_lock(&cookie->mutex);
|
||||
|
|
|
@ -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);
|
||||
u32 event = its_get_event_id(d);
|
||||
int ret = 0;
|
||||
|
||||
if (!info->map)
|
||||
return -EINVAL;
|
||||
|
||||
raw_spin_lock(&its_dev->event_map.vlpi_lock);
|
||||
|
||||
if (!its_dev->event_map.vm) {
|
||||
struct its_vlpi_map *maps;
|
||||
|
||||
maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps),
|
||||
GFP_ATOMIC);
|
||||
if (!maps) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (!maps)
|
||||
return -ENOMEM;
|
||||
|
||||
its_dev->event_map.vm = info->map->vm;
|
||||
its_dev->event_map.vlpi_maps = maps;
|
||||
} else if (its_dev->event_map.vm != info->map->vm) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* 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++;
|
||||
}
|
||||
|
||||
out:
|
||||
raw_spin_unlock(&its_dev->event_map.vlpi_lock);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_vlpi_map *map;
|
||||
int ret = 0;
|
||||
|
||||
raw_spin_lock(&its_dev->event_map.vlpi_lock);
|
||||
|
||||
map = get_vlpi_map(d);
|
||||
|
||||
if (!its_dev->event_map.vm || !map) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (!its_dev->event_map.vm || !map)
|
||||
return -EINVAL;
|
||||
|
||||
/* Copy our mapping information to the incoming request */
|
||||
*info->map = *map;
|
||||
|
||||
out:
|
||||
raw_spin_unlock(&its_dev->event_map.vlpi_lock);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int its_vlpi_unmap(struct irq_data *d)
|
||||
{
|
||||
struct its_device *its_dev = irq_data_get_irq_chip_data(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)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (!its_dev->event_map.vm || !irqd_is_forwarded_to_vcpu(d))
|
||||
return -EINVAL;
|
||||
|
||||
/* Drop the virtual mapping */
|
||||
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);
|
||||
}
|
||||
|
||||
out:
|
||||
raw_spin_unlock(&its_dev->event_map.vlpi_lock);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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))
|
||||
return -EINVAL;
|
||||
|
||||
guard(raw_spinlock_irq)(&its_dev->event_map.vlpi_lock);
|
||||
|
||||
/* Unmap request? */
|
||||
if (!info)
|
||||
return its_vlpi_unmap(d);
|
||||
|
|
|
@ -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,
|
||||
const unsigned long end)
|
||||
{
|
||||
struct fwnode_handle *fn;
|
||||
struct acpi_madt_rintc *rintc;
|
||||
struct fwnode_handle *fn;
|
||||
int rc;
|
||||
|
||||
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 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,
|
||||
|
|
|
@ -85,7 +85,7 @@ struct plic_handler {
|
|||
struct plic_priv *priv;
|
||||
};
|
||||
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 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;
|
||||
struct plic_handler *handler;
|
||||
u32 nr_irqs, parent_hwirq;
|
||||
struct irq_domain *domain;
|
||||
struct plic_priv *priv;
|
||||
irq_hw_number_t hwirq;
|
||||
bool cpuhp_setup;
|
||||
|
||||
if (is_of_node(dev->fwnode)) {
|
||||
const struct of_device_id *id;
|
||||
|
@ -549,14 +547,6 @@ static int plic_probe(struct platform_device *pdev)
|
|||
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.
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* handlers of all online CPUs are initialized.
|
||||
*/
|
||||
if (!plic_cpuhp_setup_done) {
|
||||
cpuhp_setup = true;
|
||||
if (!plic_global_setup_done) {
|
||||
struct irq_domain *domain;
|
||||
bool global_setup = true;
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
handler = per_cpu_ptr(&plic_handlers, cpu);
|
||||
if (!handler->present) {
|
||||
cpuhp_setup = false;
|
||||
global_setup = false;
|
||||
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,
|
||||
"irqchip/sifive/plic:starting",
|
||||
plic_starting_cpu, plic_dying_cpu);
|
||||
register_syscore_ops(&plic_irq_syscore_ops);
|
||||
plic_cpuhp_setup_done = true;
|
||||
plic_global_setup_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -301,10 +301,10 @@ static int ipu6_isys_stream_start(struct ipu6_isys_video *av,
|
|||
out_requeue:
|
||||
if (bl && bl->nbufs)
|
||||
ipu6_isys_buffer_list_queue(bl,
|
||||
(IPU6_ISYS_BUFFER_LIST_FL_INCOMING |
|
||||
error) ?
|
||||
IPU6_ISYS_BUFFER_LIST_FL_INCOMING |
|
||||
(error ?
|
||||
IPU6_ISYS_BUFFER_LIST_FL_SET_STATE :
|
||||
0, error ? VB2_BUF_STATE_ERROR :
|
||||
0), error ? VB2_BUF_STATE_ERROR :
|
||||
VB2_BUF_STATE_QUEUED);
|
||||
flush_firmware_streamon_fail(stream);
|
||||
|
||||
|
|
|
@ -678,6 +678,12 @@ static int isys_notifier_bound(struct v4l2_async_notifier *notifier,
|
|||
container_of(asc, struct sensor_async_sd, asc);
|
||||
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);
|
||||
if (ret) {
|
||||
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,
|
||||
};
|
||||
|
||||
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 ipu6_isys *isys = dev_get_drvdata(&auxdev->dev);
|
||||
struct ipu6_device *isp = adev->isp;
|
||||
struct device *dev = &isys->adev->auxdev.dev;
|
||||
struct isys_fw_msgs *fwmsg, *safe;
|
||||
unsigned int i;
|
||||
|
||||
list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist, head)
|
||||
dma_free_attrs(&auxdev->dev, sizeof(struct isys_fw_msgs),
|
||||
fwmsg, fwmsg->dma_addr, 0);
|
||||
dma_free_attrs(dev, sizeof(struct isys_fw_msgs), fwmsg,
|
||||
fwmsg->dma_addr, 0);
|
||||
|
||||
list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist_fw, head)
|
||||
dma_free_attrs(&auxdev->dev, sizeof(struct isys_fw_msgs),
|
||||
fwmsg, 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);
|
||||
dma_free_attrs(dev, sizeof(struct isys_fw_msgs), fwmsg,
|
||||
fwmsg->dma_addr, 0);
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret)
|
||||
goto out_remove_pkg_dir_shared_buffer;
|
||||
goto free_fw_msg_bufs;
|
||||
|
||||
ipu6_mmu_hw_cleanup(adev->mmu);
|
||||
|
||||
return 0;
|
||||
|
||||
free_fw_msg_bufs:
|
||||
free_fw_msg_bufs(isys);
|
||||
out_remove_pkg_dir_shared_buffer:
|
||||
if (!isp->secure_mode)
|
||||
ipu6_cpd_free_pkg_dir(adev);
|
||||
|
@ -1167,6 +1154,34 @@ static int isys_probe(struct auxiliary_device *auxdev,
|
|||
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 {
|
||||
int type;
|
||||
char *msg;
|
||||
|
|
|
@ -285,7 +285,7 @@ EXPORT_SYMBOL_NS_GPL(ipu6_configure_spc, INTEL_IPU6);
|
|||
#define IPU6_ISYS_CSI2_NPORTS 4
|
||||
#define IPU6SE_ISYS_CSI2_NPORTS 4
|
||||
#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)
|
||||
{
|
||||
|
@ -727,9 +727,6 @@ static void ipu6_pci_remove(struct pci_dev *pdev)
|
|||
pm_runtime_forbid(&pdev->dev);
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
|
||||
release_firmware(isp->cpd_fw);
|
||||
|
||||
ipu6_mmu_cleanup(psys_mmu);
|
||||
|
|
|
@ -677,10 +677,13 @@ static int mei_csi_probe(struct mei_cl_device *cldev,
|
|||
return -ENODEV;
|
||||
|
||||
ret = ipu_bridge_init(&ipu->dev, ipu_bridge_parse_ssdb);
|
||||
put_device(&ipu->dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (WARN_ON(!dev_fwnode(dev)))
|
||||
if (!dev_fwnode(dev)) {
|
||||
dev_err(dev, "mei-csi probed without device fwnode!\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
csi = devm_kzalloc(dev, sizeof(struct mei_csi), GFP_KERNEL);
|
||||
if (!csi)
|
||||
|
|
|
@ -642,9 +642,6 @@ static void mgb4_remove(struct pci_dev *pdev)
|
|||
struct mgb4_dev *mgbdev = pci_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
debugfs_remove_recursive(mgbdev->debugfs);
|
||||
#endif
|
||||
#if IS_REACHABLE(CONFIG_HWMON)
|
||||
hwmon_device_unregister(mgbdev->hwmon_dev);
|
||||
#endif
|
||||
|
@ -659,6 +656,10 @@ static void mgb4_remove(struct pci_dev *pdev)
|
|||
if (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);
|
||||
free_spi(mgbdev);
|
||||
free_i2c(mgbdev);
|
||||
|
|
|
@ -5152,7 +5152,7 @@ struct saa7134_board saa7134_boards[] = {
|
|||
},
|
||||
},
|
||||
[SAA7134_BOARD_AVERMEDIA_STUDIO_507UA] = {
|
||||
/* Andy Shevchenko <andy@smile.org.ua> */
|
||||
/* Andy Shevchenko <andy@kernel.org> */
|
||||
.name = "Avermedia AVerTV Studio 507UA",
|
||||
.audio_clock = 0x00187de7,
|
||||
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* Should be MK5 */
|
||||
|
|
|
@ -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",
|
||||
priv->internal_mdio_bus->id,
|
||||
port_num);
|
||||
if (!init_data.devicename)
|
||||
if (!init_data.devicename) {
|
||||
fwnode_handle_put(led);
|
||||
fwnode_handle_put(leds);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
|
||||
if (ret)
|
||||
|
@ -441,6 +444,7 @@ qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int p
|
|||
kfree(init_data.devicename);
|
||||
}
|
||||
|
||||
fwnode_handle_put(leds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -471,9 +475,13 @@ qca8k_setup_led_ctrl(struct qca8k_priv *priv)
|
|||
* the correct port for LED setup.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
fwnode_handle_put(ports);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1434,6 +1434,57 @@ struct bnxt_l2_filter {
|
|||
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 {
|
||||
u8 phy_type;
|
||||
u8 media_type;
|
||||
|
|
|
@ -680,7 +680,7 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
|
|||
req_type);
|
||||
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",
|
||||
req_type, token->seq_id, rc);
|
||||
req_type, le16_to_cpu(ctx->req->seq_id), rc);
|
||||
rc = __hwrm_to_stderr(rc);
|
||||
exit:
|
||||
if (token)
|
||||
|
|
|
@ -950,8 +950,11 @@ static int bnxt_hwrm_fwd_resp(struct bnxt *bp, struct bnxt_vf_info *vf,
|
|||
struct hwrm_fwd_resp_input *req;
|
||||
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;
|
||||
}
|
||||
|
||||
rc = hwrm_req_init(bp, req, HWRM_FWD_RESP);
|
||||
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(
|
||||
bp, vf, sizeof(struct hwrm_port_phy_qcfg_input));
|
||||
} 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;
|
||||
|
||||
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);
|
||||
phy_qcfg_resp.resp_len = cpu_to_le16(sizeof(phy_qcfg_resp));
|
||||
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;
|
||||
|
||||
if (vf->flags & BNXT_VF_LINK_UP) {
|
||||
|
|
|
@ -272,13 +272,12 @@ lio_vf_rep_copy_packet(struct octeon_device *oct,
|
|||
pg_info->page_offset;
|
||||
memcpy(skb->data, va, 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 {
|
||||
struct octeon_skb_page_info *pg_info =
|
||||
((struct octeon_skb_page_info *)(skb->cb));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
if (rx->ctx.skb_head == napi->skb)
|
||||
napi->skb = NULL;
|
||||
dev_kfree_skb_any(rx->ctx.skb_head);
|
||||
rx->ctx.skb_head = 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);
|
||||
if (err < 0) {
|
||||
gve_rx_free_skb(rx);
|
||||
gve_rx_free_skb(napi, rx);
|
||||
u64_stats_update_begin(&rx->statss);
|
||||
if (err == -ENOMEM)
|
||||
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 */
|
||||
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);
|
||||
rx->rx_desc_err_dropped_pkt++;
|
||||
u64_stats_update_end(&rx->statss);
|
||||
|
|
|
@ -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))
|
||||
return -1;
|
||||
|
||||
if (!(skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
|
||||
return -EINVAL;
|
||||
|
||||
/* Needed because we will modify header. */
|
||||
err = skb_cow_head(skb, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
tcp = tcp_hdr(skb);
|
||||
|
||||
/* Remove payload length from checksum. */
|
||||
paylen = skb->len - skb_transport_offset(skb);
|
||||
|
||||
switch (skb_shinfo(skb)->gso_type) {
|
||||
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;
|
||||
}
|
||||
csum_replace_by_diff(&tcp->check, (__force __wsum)htonl(paylen));
|
||||
header_len = skb_tcp_all_headers(skb);
|
||||
|
||||
if (unlikely(header_len > GVE_TX_MAX_HDR_SIZE_DQO))
|
||||
return -EINVAL;
|
||||
|
|
|
@ -3535,6 +3535,9 @@ static int hns3_alloc_ring_buffers(struct hns3_enet_ring *ring)
|
|||
ret = hns3_alloc_and_attach_buffer(ring, i);
|
||||
if (ret)
|
||||
goto out_buffer_fail;
|
||||
|
||||
if (!(i % HNS3_RESCHED_BD_NUM))
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -5107,6 +5110,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv)
|
|||
}
|
||||
|
||||
u64_stats_init(&priv->ring[i].syncp);
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -214,6 +214,8 @@ enum hns3_nic_state {
|
|||
#define HNS3_CQ_MODE_EQE 1U
|
||||
#define HNS3_CQ_MODE_CQE 0U
|
||||
|
||||
#define HNS3_RESCHED_BD_NUM 1024
|
||||
|
||||
enum hns3_pkt_l2t_type {
|
||||
HNS3_L2_TYPE_UNICAST,
|
||||
HNS3_L2_TYPE_MULTICAST,
|
||||
|
|
|
@ -3086,9 +3086,7 @@ static void hclge_push_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_client *rclient = hdev->roce_client;
|
||||
struct hnae3_client *client = hdev->nic_client;
|
||||
int state;
|
||||
int ret;
|
||||
|
@ -3112,8 +3110,15 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
|
|||
|
||||
client->ops->link_status_change(handle, 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);
|
||||
}
|
||||
|
@ -11319,6 +11324,12 @@ static int hclge_init_client_instance(struct hnae3_client *client,
|
|||
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,
|
||||
struct hnae3_ae_dev *ae_dev)
|
||||
{
|
||||
|
@ -11327,7 +11338,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
|
|||
|
||||
if (hdev->roce_client) {
|
||||
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);
|
||||
|
||||
hdev->roce_client->ops->uninit_instance(&vport->roce, 0);
|
||||
|
|
|
@ -7032,6 +7032,8 @@ static int igc_probe(struct pci_dev *pdev,
|
|||
device_set_wakeup_enable(&adapter->pdev->dev,
|
||||
adapter->flags & IGC_FLAG_WOL_SUPPORTED);
|
||||
|
||||
igc_ptp_init(adapter);
|
||||
|
||||
igc_tsn_clear_schedule(adapter);
|
||||
|
||||
/* 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 */
|
||||
adapter->ei = *ei;
|
||||
|
||||
/* do hw tstamp init after resetting */
|
||||
igc_ptp_init(adapter);
|
||||
|
||||
/* print pcie link status and MAC address */
|
||||
pcie_print_link_status(pdev);
|
||||
netdev_info(netdev, "MAC: %pM\n", netdev->dev_addr);
|
||||
|
|
|
@ -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 */
|
||||
if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port))
|
||||
return features;
|
||||
return vxlan_features_check(skb, features);
|
||||
|
||||
#if IS_ENABLED(CONFIG_GENEVE)
|
||||
/* 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);
|
||||
|
||||
features = vlan_features_check(skb, features);
|
||||
features = vxlan_features_check(skb, features);
|
||||
|
||||
/* Validate if the tunneled packet is being offloaded by HW */
|
||||
if (skb->encapsulation &&
|
||||
|
|
|
@ -304,10 +304,8 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (qcq->napi.poll)
|
||||
napi_enable(&qcq->napi);
|
||||
|
||||
if (qcq->flags & IONIC_QCQ_F_INTR) {
|
||||
napi_enable(&qcq->napi);
|
||||
irq_set_affinity_hint(qcq->intr.vector,
|
||||
&qcq->intr.affinity_mask);
|
||||
ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
|
||||
|
|
|
@ -93,6 +93,7 @@ struct ethqos_emac_driver_data {
|
|||
bool has_emac_ge_3;
|
||||
const char *link_clk_name;
|
||||
bool has_integrated_pcs;
|
||||
u32 dma_addr_width;
|
||||
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,
|
||||
.link_clk_name = "phyaux",
|
||||
.has_integrated_pcs = true,
|
||||
.dma_addr_width = 36,
|
||||
.dwmac4_addrs = {
|
||||
.dma_chan = 0x00008100,
|
||||
.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;
|
||||
if (data->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) {
|
||||
plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
|
||||
|
|
|
@ -343,10 +343,11 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
|
|||
struct tc_cbs_qopt_offload *qopt)
|
||||
{
|
||||
u32 tx_queues_count = priv->plat->tx_queues_to_use;
|
||||
s64 port_transmit_rate_kbps;
|
||||
u32 queue = qopt->queue;
|
||||
u32 ptr, speed_div;
|
||||
u32 mode_to_use;
|
||||
u64 value;
|
||||
u32 ptr;
|
||||
int ret;
|
||||
|
||||
/* Queue 0 is not AVB capable */
|
||||
|
@ -355,30 +356,26 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
|
|||
if (!priv->dma_cap.av)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
port_transmit_rate_kbps = qopt->idleslope - qopt->sendslope;
|
||||
|
||||
/* Port Transmit Rate and Speed Divider */
|
||||
switch (priv->speed) {
|
||||
switch (div_s64(port_transmit_rate_kbps, 1000)) {
|
||||
case SPEED_10000:
|
||||
ptr = 32;
|
||||
speed_div = 10000000;
|
||||
break;
|
||||
case SPEED_5000:
|
||||
ptr = 32;
|
||||
speed_div = 5000000;
|
||||
break;
|
||||
case SPEED_2500:
|
||||
ptr = 8;
|
||||
speed_div = 2500000;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
ptr = 8;
|
||||
speed_div = 1000000;
|
||||
break;
|
||||
case SPEED_100:
|
||||
ptr = 4;
|
||||
speed_div = 100000;
|
||||
break;
|
||||
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;
|
||||
|
@ -398,10 +395,10 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
|
|||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
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);
|
||||
|
||||
value = qopt->hicredit * 1024ll * 8;
|
||||
|
|
|
@ -815,6 +815,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
struct geneve_dev *geneve,
|
||||
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));
|
||||
struct geneve_sock *gs4 = rcu_dereference(geneve->sock4);
|
||||
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;
|
||||
int err;
|
||||
|
||||
if (!skb_vlan_inet_prepare(skb))
|
||||
if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
|
||||
return -EINVAL;
|
||||
|
||||
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),
|
||||
geneve->cfg.inner_proto_inherit);
|
||||
inner_proto_inherit);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
|
@ -925,6 +926,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
struct geneve_dev *geneve,
|
||||
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));
|
||||
struct geneve_sock *gs6 = rcu_dereference(geneve->sock6);
|
||||
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;
|
||||
int err;
|
||||
|
||||
if (!skb_vlan_inet_prepare(skb))
|
||||
if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
|
||||
return -EINVAL;
|
||||
|
||||
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);
|
||||
}
|
||||
err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr),
|
||||
geneve->cfg.inner_proto_inherit);
|
||||
inner_proto_inherit);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
|
|
|
@ -324,7 +324,8 @@ static int nsim_get_iflink(const struct net_device *dev)
|
|||
|
||||
rcu_read_lock();
|
||||
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();
|
||||
|
||||
return iflink;
|
||||
|
|
|
@ -2429,8 +2429,7 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
|
|||
|
||||
/* Handle remove event globally, it resets this state machine */
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
|
|||
cmd.prop_get.offset = cpu_to_le32(off);
|
||||
|
||||
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)
|
||||
*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);
|
||||
|
||||
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)
|
||||
*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);
|
||||
|
||||
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))
|
||||
dev_err(ctrl->device,
|
||||
"Property Set error: %d, offset %#x\n",
|
||||
|
|
|
@ -77,7 +77,7 @@ static int nvme_sc_to_pr_err(int nvme_sc)
|
|||
if (nvme_is_path_error(nvme_sc))
|
||||
return PR_STS_PATH_FAILED;
|
||||
|
||||
switch (nvme_sc) {
|
||||
switch (nvme_sc & 0x7ff) {
|
||||
case NVME_SC_SUCCESS:
|
||||
return PR_STS_SUCCESS;
|
||||
case NVME_SC_RESERVATION_CONFLICT:
|
||||
|
|
|
@ -289,8 +289,6 @@ void pci_cfg_access_lock(struct pci_dev *dev)
|
|||
{
|
||||
might_sleep();
|
||||
|
||||
lock_map_acquire(&dev->cfg_access_lock);
|
||||
|
||||
raw_spin_lock_irq(&pci_lock);
|
||||
if (dev->block_cfg_access)
|
||||
pci_wait_cfg(dev);
|
||||
|
@ -345,8 +343,6 @@ void pci_cfg_access_unlock(struct pci_dev *dev)
|
|||
raw_spin_unlock_irqrestore(&pci_lock, flags);
|
||||
|
||||
wake_up_all(&pci_cfg_wait);
|
||||
|
||||
lock_map_release(&dev->cfg_access_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_cfg_access_unlock);
|
||||
|
||||
|
|
|
@ -4883,7 +4883,6 @@ void __weak pcibios_reset_secondary_bus(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);
|
||||
|
||||
return pci_bridge_wait_for_secondary_bus(dev, "bus reset");
|
||||
|
|
|
@ -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_parms = &dev->dma_parms;
|
||||
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_seg_boundary(&dev->dev, 0xffffffff);
|
||||
|
|
|
@ -136,6 +136,7 @@ config YOGABOOK
|
|||
config YT2_1380
|
||||
tristate "Lenovo Yoga Tablet 2 1380 fast charge driver"
|
||||
depends on SERIAL_DEV_BUS
|
||||
depends on EXTCON
|
||||
depends on ACPI
|
||||
help
|
||||
Say Y here to enable support for the custom fast charging protocol
|
||||
|
|
|
@ -907,16 +907,44 @@ static int hsmp_plat_dev_register(void)
|
|||
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)
|
||||
{
|
||||
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
|
||||
* 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;
|
||||
|
||||
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)
|
||||
platform_driver_unregister(&amd_hsmp_driver);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/capability.h>
|
||||
|
@ -25,11 +26,16 @@ static u32 da_supported_commands;
|
|||
static int da_num_tokens;
|
||||
static struct platform_device *platform_device;
|
||||
static struct calling_interface_token *da_tokens;
|
||||
static struct device_attribute *token_location_attrs;
|
||||
static struct device_attribute *token_value_attrs;
|
||||
static struct token_sysfs_data *token_entries;
|
||||
static struct attribute **token_attrs;
|
||||
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 list_head list;
|
||||
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,
|
||||
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))
|
||||
return -EPERM;
|
||||
|
||||
i = match_attribute(dev, attr);
|
||||
if (i > 0)
|
||||
return sysfs_emit(buf, "%08x", da_tokens[i].location);
|
||||
return 0;
|
||||
return sysfs_emit(buf, "%08x", data->token->location);
|
||||
}
|
||||
|
||||
static ssize_t value_show(struct device *dev,
|
||||
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))
|
||||
return -EPERM;
|
||||
|
||||
i = match_attribute(dev, attr);
|
||||
if (i > 0)
|
||||
return sysfs_emit(buf, "%08x", da_tokens[i].value);
|
||||
return 0;
|
||||
return sysfs_emit(buf, "%08x", data->token->value);
|
||||
}
|
||||
|
||||
static struct attribute_group smbios_attribute_group = {
|
||||
|
@ -473,22 +458,15 @@ static int build_tokens_sysfs(struct platform_device *dev)
|
|||
{
|
||||
char *location_name;
|
||||
char *value_name;
|
||||
size_t size;
|
||||
int ret;
|
||||
int i, j;
|
||||
|
||||
/* (number of tokens + 1 for null terminated */
|
||||
size = sizeof(struct device_attribute) * (da_num_tokens + 1);
|
||||
token_location_attrs = kzalloc(size, GFP_KERNEL);
|
||||
if (!token_location_attrs)
|
||||
token_entries = kcalloc(da_num_tokens, sizeof(*token_entries), GFP_KERNEL);
|
||||
if (!token_entries)
|
||||
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*/
|
||||
size = sizeof(struct attribute *) * ((2 * da_num_tokens) + 1);
|
||||
token_attrs = kzalloc(size, GFP_KERNEL);
|
||||
token_attrs = kcalloc((2 * da_num_tokens) + 1, sizeof(*token_attrs), GFP_KERNEL);
|
||||
if (!token_attrs)
|
||||
goto out_allocate_attrs;
|
||||
|
||||
|
@ -496,32 +474,34 @@ static int build_tokens_sysfs(struct platform_device *dev)
|
|||
/* skip empty */
|
||||
if (da_tokens[i].tokenID == 0)
|
||||
continue;
|
||||
|
||||
token_entries[i].token = &da_tokens[i];
|
||||
|
||||
/* add location */
|
||||
location_name = kasprintf(GFP_KERNEL, "%04x_location",
|
||||
da_tokens[i].tokenID);
|
||||
if (location_name == NULL)
|
||||
goto out_unwind_strings;
|
||||
sysfs_attr_init(&token_location_attrs[i].attr);
|
||||
token_location_attrs[i].attr.name = location_name;
|
||||
token_location_attrs[i].attr.mode = 0444;
|
||||
token_location_attrs[i].show = location_show;
|
||||
token_attrs[j++] = &token_location_attrs[i].attr;
|
||||
|
||||
sysfs_attr_init(&token_entries[i].location_attr.attr);
|
||||
token_entries[i].location_attr.attr.name = location_name;
|
||||
token_entries[i].location_attr.attr.mode = 0444;
|
||||
token_entries[i].location_attr.show = location_show;
|
||||
token_attrs[j++] = &token_entries[i].location_attr.attr;
|
||||
|
||||
/* add value */
|
||||
value_name = kasprintf(GFP_KERNEL, "%04x_value",
|
||||
da_tokens[i].tokenID);
|
||||
if (value_name == NULL)
|
||||
goto loop_fail_create_value;
|
||||
sysfs_attr_init(&token_value_attrs[i].attr);
|
||||
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;
|
||||
if (!value_name) {
|
||||
kfree(location_name);
|
||||
goto out_unwind_strings;
|
||||
}
|
||||
|
||||
loop_fail_create_value:
|
||||
kfree(location_name);
|
||||
goto out_unwind_strings;
|
||||
sysfs_attr_init(&token_entries[i].value_attr.attr);
|
||||
token_entries[i].value_attr.attr.name = value_name;
|
||||
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;
|
||||
|
||||
|
@ -532,14 +512,12 @@ static int build_tokens_sysfs(struct platform_device *dev)
|
|||
|
||||
out_unwind_strings:
|
||||
while (i--) {
|
||||
kfree(token_location_attrs[i].attr.name);
|
||||
kfree(token_value_attrs[i].attr.name);
|
||||
kfree(token_entries[i].location_attr.attr.name);
|
||||
kfree(token_entries[i].value_attr.attr.name);
|
||||
}
|
||||
kfree(token_attrs);
|
||||
out_allocate_attrs:
|
||||
kfree(token_value_attrs);
|
||||
out_allocate_value:
|
||||
kfree(token_location_attrs);
|
||||
kfree(token_entries);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -551,12 +529,11 @@ static void free_group(struct platform_device *pdev)
|
|||
sysfs_remove_group(&pdev->dev.kobj,
|
||||
&smbios_attribute_group);
|
||||
for (i = 0; i < da_num_tokens; i++) {
|
||||
kfree(token_location_attrs[i].attr.name);
|
||||
kfree(token_value_attrs[i].attr.name);
|
||||
kfree(token_entries[i].location_attr.attr.name);
|
||||
kfree(token_entries[i].value_attr.attr.name);
|
||||
}
|
||||
kfree(token_attrs);
|
||||
kfree(token_value_attrs);
|
||||
kfree(token_location_attrs);
|
||||
kfree(token_entries);
|
||||
}
|
||||
|
||||
static int __init dell_smbios_init(void)
|
||||
|
|
|
@ -34,7 +34,6 @@ static const struct property_entry archos_101_cesium_educ_props[] = {
|
|||
PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
|
||||
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
|
||||
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
PROPERTY_ENTRY_BOOL("silead,home-button"),
|
||||
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-y", 1280),
|
||||
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
PROPERTY_ENTRY_BOOL("silead,home-button"),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-hi8-pro.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 4),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10-air.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1270),
|
||||
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,pen-supported"),
|
||||
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_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("silead,max-fingers", 10),
|
||||
PROPERTY_ENTRY_BOOL("silead,home-button"),
|
||||
PROPERTY_ENTRY_BOOL("silead,pen-supported"),
|
||||
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-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hibook.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-vi8.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1280),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-vi10.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1524),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-surbook-mini.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-swapped-x-y"),
|
||||
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-swapped-x-y"),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
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-y", 1513),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-cube-knote-i1101.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 630),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-dexp-ursus-7w.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1137),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-dexp-ursus-kx210i.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-inverted-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-digma_citi_e200.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-irbis_tw90.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1510),
|
||||
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-swapped-x-y"),
|
||||
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-y", 1500),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro-b.fw"),
|
||||
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1525),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-m4.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-jumper-ezpad-7.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
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-swapped-x-y"),
|
||||
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_BOOL("touchscreen-inverted-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-mpman-mpwin895cl.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-myria-my8307.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-v80-plus-v3.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-onda-v820w-32g.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_STRING("firmware-name",
|
||||
"gsl3676-onda-v891-v5.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1130),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-onda-v891w-v1.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-inverted-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-v891w-v3.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1532),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-pipo-w11.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1269),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
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"),
|
||||
{ }
|
||||
};
|
||||
|
@ -808,7 +770,6 @@ static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
|
|||
PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
|
||||
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-pov-mobii-wintab-p800w.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-inverted-y"),
|
||||
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"),
|
||||
{ }
|
||||
};
|
||||
|
@ -842,7 +802,6 @@ static const struct property_entry predia_basic_props[] = {
|
|||
PROPERTY_ENTRY_U32("touchscreen-size-y", 1144),
|
||||
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-predia-basic.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
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_BOOL("touchscreen-inverted-y"),
|
||||
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-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-schneider-sct101ctm.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1077),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-globalspace-solt-ivw116.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-inverted-y"),
|
||||
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_BOOL("touchscreen-inverted-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-teclast-tbook11.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-inverted-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-teclast-x16-plus.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1500),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y"),
|
||||
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_BOOL("touchscreen-inverted-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-trekstor-primebook-c11.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1920),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-trekstor-primebook-c13.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1900),
|
||||
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("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-inverted-y", 1),
|
||||
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"),
|
||||
{ }
|
||||
};
|
||||
|
@ -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-y", 632),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-surftab-wintron70-st70416-6.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-viglen-connect-10.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
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-y", 1280),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-vinga-twizzle_j116.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
PROPERTY_ENTRY_BOOL("silead,home-button"),
|
||||
{ }
|
||||
};
|
||||
|
@ -1907,7 +1850,7 @@ static int __init ts_parse_props(char *str)
|
|||
u32 u32val;
|
||||
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
|
||||
|
|
|
@ -414,28 +414,40 @@ static char print_alua_state(unsigned char state)
|
|||
}
|
||||
}
|
||||
|
||||
static enum scsi_disposition alua_check_sense(struct scsi_device *sdev,
|
||||
struct scsi_sense_hdr *sense_hdr)
|
||||
static void alua_handle_state_transition(struct scsi_device *sdev)
|
||||
{
|
||||
struct alua_dh_data *h = sdev->handler_data;
|
||||
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) {
|
||||
case NOT_READY:
|
||||
if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a) {
|
||||
/*
|
||||
* LUN Not Accessible - ALUA state transition
|
||||
*/
|
||||
rcu_read_lock();
|
||||
pg = rcu_dereference(h->pg);
|
||||
if (pg)
|
||||
pg->state = SCSI_ACCESS_STATE_TRANSITIONING;
|
||||
rcu_read_unlock();
|
||||
alua_check(sdev, false);
|
||||
alua_handle_state_transition(sdev);
|
||||
return NEEDS_RETRY;
|
||||
}
|
||||
break;
|
||||
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) {
|
||||
/*
|
||||
* 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,
|
||||
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)
|
||||
return SCSI_DH_RETRY;
|
||||
else if (retval)
|
||||
|
|
|
@ -1364,7 +1364,7 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
|
|||
continue;
|
||||
|
||||
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);
|
||||
goto out_fail;
|
||||
}
|
||||
|
|
|
@ -302,8 +302,8 @@ struct _scsi_io_transfer {
|
|||
|
||||
/**
|
||||
* _scsih_set_debug_level - global setting of ioc->logging_level.
|
||||
* @val: ?
|
||||
* @kp: ?
|
||||
* @val: value of the parameter to be set
|
||||
* @kp: pointer to kernel_param structure
|
||||
*
|
||||
* Note: The logging levels are defined in mpt3sas_debug.h.
|
||||
*/
|
||||
|
|
|
@ -363,6 +363,7 @@ struct qedf_ctx {
|
|||
#define QEDF_IN_RECOVERY 5
|
||||
#define QEDF_DBG_STOP_IO 6
|
||||
#define QEDF_PROBING 8
|
||||
#define QEDF_STAG_IN_PROGRESS 9
|
||||
unsigned long flags; /* Miscellaneous state flags */
|
||||
int fipvlan_retries;
|
||||
u8 num_queues;
|
||||
|
|
|
@ -318,11 +318,18 @@ static struct fc_seq *qedf_elsct_send(struct fc_lport *lport, u32 did,
|
|||
*/
|
||||
if (resp == fc_lport_flogi_resp) {
|
||||
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) {
|
||||
schedule_delayed_work(&qedf->stag_work, 2);
|
||||
return NULL;
|
||||
}
|
||||
qedf->flogi_pending++;
|
||||
|
||||
return fc_elsct_send(lport, did, fp, op, qedf_flogi_resp,
|
||||
arg, timeout);
|
||||
}
|
||||
|
@ -912,13 +919,14 @@ void qedf_ctx_soft_reset(struct fc_lport *lport)
|
|||
struct qedf_ctx *qedf;
|
||||
struct qed_link_output if_link;
|
||||
|
||||
qedf = lport_priv(lport);
|
||||
|
||||
if (lport->vport) {
|
||||
clear_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
|
||||
printk_ratelimited("Cannot issue host reset on NPIV port.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
qedf = lport_priv(lport);
|
||||
|
||||
qedf->flogi_pending = 0;
|
||||
/* For host reset, essentially do a soft link up/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) {
|
||||
QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
|
||||
"Physical link is not up.\n");
|
||||
clear_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
|
||||
return;
|
||||
}
|
||||
/* 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_delayed_work(qedf->link_update_wq, &qedf->link_update,
|
||||
0);
|
||||
clear_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
memset(&slowpath_params, 0, sizeof(struct qed_slowpath_params));
|
||||
slowpath_params.int_mode = QED_INT_MODE_MSIX;
|
||||
slowpath_params.drv_major = QEDF_DRIVER_MAJOR_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;
|
||||
int rc;
|
||||
int cnt = 0;
|
||||
|
||||
if (!pdev) {
|
||||
QEDF_ERR(NULL, "pdev is NULL.\n");
|
||||
|
@ -3738,6 +3750,17 @@ static void __qedf_remove(struct pci_dev *pdev, int mode)
|
|||
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)
|
||||
set_bit(QEDF_UNLOADING, &qedf->flags);
|
||||
|
||||
|
@ -3997,6 +4020,24 @@ void qedf_stag_change_work(struct work_struct *work)
|
|||
struct qedf_ctx *qedf =
|
||||
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.",
|
||||
dev_name(&qedf->pdev->dev), __func__, __LINE__,
|
||||
qedf->dbg_ctx.host_no);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue