mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-16 05:26:07 +00:00
Linux 6.7-rc3
-----BEGIN PGP SIGNATURE----- iQFSBAABCAA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAmVkFCUeHHRvcnZhbGRz QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiG2e4IAIMMxdUGC1RDpSk2 cNe2XfULYD8pNDT9Io6668jELSfFQe8ELv4QloFwDDCKk2EDZUZxr3crIX9rweYI D5xrAwY5uJQnAsRADEmWMUN0iWo3EX3G5OOUkJknGWvyPapByFvhDzzF2nZQ25xI HjJ9b0OTOVJxDYspCtK0g+CGFtBjCiGpLSe/V67zlLX4ptWh5noqPWQE9/dyyIFD Z2Jga3wQtsF1uvOx4g0tMzowTqaKMljf5R3t6LNT4yqmoxMdKGi4qgJQDp23vB36 KNmA/V4wQ+EDuD3QejebpuMCgZV7lYJxOlWtGt47/cF9z8wSp+8J92TUSzP23D4u 5yx5ihs= =2beF -----END PGP SIGNATURE----- Merge v6.7-rc3 into drm-next Thomas Zimermann needs 8d6ef26501 ("drm/ast: Disconnect BMC if physical connector is connected") for further ast work in -next. Minor conflicts in ivpu between 3de6d9597892 ("accel/ivpu: Pass D0i3 residency time to the VPU firmware") and 3f7c0634926d ("accel/ivpu/37xx: Fix hangs related to MMIO reset") changing adjacent lines. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
commit
a13fee31f5
@ -375,9 +375,9 @@ Developer web site of Loongson and LoongArch (Software and Documentation):
|
|||||||
|
|
||||||
Documentation of LoongArch ISA:
|
Documentation of LoongArch ISA:
|
||||||
|
|
||||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-CN.pdf (in Chinese)
|
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-CN.pdf (in Chinese)
|
||||||
|
|
||||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-EN.pdf (in English)
|
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-EN.pdf (in English)
|
||||||
|
|
||||||
Documentation of LoongArch ELF psABI:
|
Documentation of LoongArch ELF psABI:
|
||||||
|
|
||||||
|
@ -36,7 +36,11 @@ properties:
|
|||||||
|
|
||||||
vdd-supply:
|
vdd-supply:
|
||||||
description:
|
description:
|
||||||
VDD power supply to the hub
|
3V3 power supply to the hub
|
||||||
|
|
||||||
|
vdd2-supply:
|
||||||
|
description:
|
||||||
|
1V2 power supply to the hub
|
||||||
|
|
||||||
peer-hub:
|
peer-hub:
|
||||||
$ref: /schemas/types.yaml#/definitions/phandle
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
@ -62,6 +66,7 @@ allOf:
|
|||||||
properties:
|
properties:
|
||||||
reset-gpios: false
|
reset-gpios: false
|
||||||
vdd-supply: false
|
vdd-supply: false
|
||||||
|
vdd2-supply: false
|
||||||
peer-hub: false
|
peer-hub: false
|
||||||
i2c-bus: false
|
i2c-bus: false
|
||||||
else:
|
else:
|
||||||
|
@ -521,8 +521,8 @@ examples:
|
|||||||
|
|
||||||
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
|
<GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>,
|
<GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
|
||||||
<GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>;
|
<GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
|
||||||
interrupt-names = "hs_phy_irq", "ss_phy_irq",
|
interrupt-names = "hs_phy_irq", "ss_phy_irq",
|
||||||
"dm_hs_phy_irq", "dp_hs_phy_irq";
|
"dm_hs_phy_irq", "dp_hs_phy_irq";
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ examples:
|
|||||||
- |
|
- |
|
||||||
usb {
|
usb {
|
||||||
phys = <&usb2_phy1>, <&usb3_phy1>;
|
phys = <&usb2_phy1>, <&usb3_phy1>;
|
||||||
phy-names = "usb";
|
phy-names = "usb2", "usb3";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
@ -91,6 +91,10 @@ compatibility checking tool (fsck.erofs), and a debugging tool (dump.erofs):
|
|||||||
|
|
||||||
- git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git
|
- git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git
|
||||||
|
|
||||||
|
For more information, please also refer to the documentation site:
|
||||||
|
|
||||||
|
- https://erofs.docs.kernel.org
|
||||||
|
|
||||||
Bugs and patches are welcome, please kindly help us and send to the following
|
Bugs and patches are welcome, please kindly help us and send to the following
|
||||||
linux-erofs mailing list:
|
linux-erofs mailing list:
|
||||||
|
|
||||||
|
@ -193,9 +193,23 @@ Review timelines
|
|||||||
Generally speaking, the patches get triaged quickly (in less than
|
Generally speaking, the patches get triaged quickly (in less than
|
||||||
48h). But be patient, if your patch is active in patchwork (i.e. it's
|
48h). But be patient, if your patch is active in patchwork (i.e. it's
|
||||||
listed on the project's patch list) the chances it was missed are close to zero.
|
listed on the project's patch list) the chances it was missed are close to zero.
|
||||||
Asking the maintainer for status updates on your
|
|
||||||
patch is a good way to ensure your patch is ignored or pushed to the
|
The high volume of development on netdev makes reviewers move on
|
||||||
bottom of the priority list.
|
from discussions relatively quickly. New comments and replies
|
||||||
|
are very unlikely to arrive after a week of silence. If a patch
|
||||||
|
is no longer active in patchwork and the thread went idle for more
|
||||||
|
than a week - clarify the next steps and/or post the next version.
|
||||||
|
|
||||||
|
For RFC postings specifically, if nobody responded in a week - reviewers
|
||||||
|
either missed the posting or have no strong opinions. If the code is ready,
|
||||||
|
repost as a PATCH.
|
||||||
|
|
||||||
|
Emails saying just "ping" or "bump" are considered rude. If you can't figure
|
||||||
|
out the status of the patch from patchwork or where the discussion has
|
||||||
|
landed - describe your best guess and ask if it's correct. For example::
|
||||||
|
|
||||||
|
I don't understand what the next steps are. Person X seems to be unhappy
|
||||||
|
with A, should I do B and repost the patches?
|
||||||
|
|
||||||
.. _Changes requested:
|
.. _Changes requested:
|
||||||
|
|
||||||
|
@ -338,9 +338,9 @@ Loongson与LoongArch的开发者网站(软件与文档资源):
|
|||||||
|
|
||||||
LoongArch指令集架构的文档:
|
LoongArch指令集架构的文档:
|
||||||
|
|
||||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-CN.pdf (中文版)
|
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-CN.pdf (中文版)
|
||||||
|
|
||||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-EN.pdf (英文版)
|
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-EN.pdf (英文版)
|
||||||
|
|
||||||
LoongArch的ELF psABI文档:
|
LoongArch的ELF psABI文档:
|
||||||
|
|
||||||
|
@ -7852,6 +7852,7 @@ R: Yue Hu <huyue2@coolpad.com>
|
|||||||
R: Jeffle Xu <jefflexu@linux.alibaba.com>
|
R: Jeffle Xu <jefflexu@linux.alibaba.com>
|
||||||
L: linux-erofs@lists.ozlabs.org
|
L: linux-erofs@lists.ozlabs.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
W: https://erofs.docs.kernel.org
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
|
||||||
F: Documentation/ABI/testing/sysfs-fs-erofs
|
F: Documentation/ABI/testing/sysfs-fs-erofs
|
||||||
F: Documentation/filesystems/erofs.rst
|
F: Documentation/filesystems/erofs.rst
|
||||||
@ -11031,7 +11032,6 @@ F: drivers/net/wireless/intel/iwlwifi/
|
|||||||
|
|
||||||
INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER
|
INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER
|
||||||
M: Jithu Joseph <jithu.joseph@intel.com>
|
M: Jithu Joseph <jithu.joseph@intel.com>
|
||||||
R: Maurice Ma <maurice.ma@intel.com>
|
|
||||||
S: Maintained
|
S: Maintained
|
||||||
W: https://slimbootloader.github.io/security/firmware-update.html
|
W: https://slimbootloader.github.io/security/firmware-update.html
|
||||||
F: drivers/platform/x86/intel/wmi/sbl-fw-update.c
|
F: drivers/platform/x86/intel/wmi/sbl-fw-update.c
|
||||||
@ -13785,7 +13785,6 @@ F: drivers/net/ethernet/mellanox/mlxfw/
|
|||||||
MELLANOX HARDWARE PLATFORM SUPPORT
|
MELLANOX HARDWARE PLATFORM SUPPORT
|
||||||
M: Hans de Goede <hdegoede@redhat.com>
|
M: Hans de Goede <hdegoede@redhat.com>
|
||||||
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||||
M: Mark Gross <markgross@kernel.org>
|
|
||||||
M: Vadim Pasternak <vadimp@nvidia.com>
|
M: Vadim Pasternak <vadimp@nvidia.com>
|
||||||
L: platform-driver-x86@vger.kernel.org
|
L: platform-driver-x86@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
@ -14394,7 +14393,6 @@ F: drivers/platform/surface/surface_gpe.c
|
|||||||
MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT
|
MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT
|
||||||
M: Hans de Goede <hdegoede@redhat.com>
|
M: Hans de Goede <hdegoede@redhat.com>
|
||||||
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||||
M: Mark Gross <markgross@kernel.org>
|
|
||||||
M: Maximilian Luz <luzmaximilian@gmail.com>
|
M: Maximilian Luz <luzmaximilian@gmail.com>
|
||||||
L: platform-driver-x86@vger.kernel.org
|
L: platform-driver-x86@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
@ -15001,6 +14999,7 @@ M: Jakub Kicinski <kuba@kernel.org>
|
|||||||
M: Paolo Abeni <pabeni@redhat.com>
|
M: Paolo Abeni <pabeni@redhat.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
P: Documentation/process/maintainer-netdev.rst
|
||||||
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
|
||||||
@ -15052,6 +15051,7 @@ M: Jakub Kicinski <kuba@kernel.org>
|
|||||||
M: Paolo Abeni <pabeni@redhat.com>
|
M: Paolo Abeni <pabeni@redhat.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
P: Documentation/process/maintainer-netdev.rst
|
||||||
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
||||||
B: mailto:netdev@vger.kernel.org
|
B: mailto:netdev@vger.kernel.org
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
||||||
@ -15062,6 +15062,7 @@ F: Documentation/networking/
|
|||||||
F: Documentation/process/maintainer-netdev.rst
|
F: Documentation/process/maintainer-netdev.rst
|
||||||
F: Documentation/userspace-api/netlink/
|
F: Documentation/userspace-api/netlink/
|
||||||
F: include/linux/in.h
|
F: include/linux/in.h
|
||||||
|
F: include/linux/indirect_call_wrapper.h
|
||||||
F: include/linux/net.h
|
F: include/linux/net.h
|
||||||
F: include/linux/netdevice.h
|
F: include/linux/netdevice.h
|
||||||
F: include/net/
|
F: include/net/
|
||||||
@ -22085,6 +22086,7 @@ F: drivers/watchdog/tqmx86_wdt.c
|
|||||||
TRACING
|
TRACING
|
||||||
M: Steven Rostedt <rostedt@goodmis.org>
|
M: Steven Rostedt <rostedt@goodmis.org>
|
||||||
M: Masami Hiramatsu <mhiramat@kernel.org>
|
M: Masami Hiramatsu <mhiramat@kernel.org>
|
||||||
|
R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||||
L: linux-kernel@vger.kernel.org
|
L: linux-kernel@vger.kernel.org
|
||||||
L: linux-trace-kernel@vger.kernel.org
|
L: linux-trace-kernel@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
@ -23671,7 +23673,6 @@ F: drivers/platform/x86/x86-android-tablets/
|
|||||||
X86 PLATFORM DRIVERS
|
X86 PLATFORM DRIVERS
|
||||||
M: Hans de Goede <hdegoede@redhat.com>
|
M: Hans de Goede <hdegoede@redhat.com>
|
||||||
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||||
M: Mark Gross <markgross@kernel.org>
|
|
||||||
L: platform-driver-x86@vger.kernel.org
|
L: platform-driver-x86@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
Q: https://patchwork.kernel.org/project/platform-driver-x86/list/
|
Q: https://patchwork.kernel.org/project/platform-driver-x86/list/
|
||||||
|
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
|||||||
VERSION = 6
|
VERSION = 6
|
||||||
PATCHLEVEL = 7
|
PATCHLEVEL = 7
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION = -rc2
|
EXTRAVERSION = -rc3
|
||||||
NAME = Hurr durr I'ma ninja sloth
|
NAME = Hurr durr I'ma ninja sloth
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
@ -484,7 +484,8 @@ static int __init xen_guest_init(void)
|
|||||||
* for secondary CPUs as they are brought up.
|
* for secondary CPUs as they are brought up.
|
||||||
* For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
|
* For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
|
||||||
*/
|
*/
|
||||||
xen_vcpu_info = alloc_percpu(struct vcpu_info);
|
xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info),
|
||||||
|
1 << fls(sizeof(struct vcpu_info) - 1));
|
||||||
if (xen_vcpu_info == NULL)
|
if (xen_vcpu_info == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ endif
|
|||||||
|
|
||||||
all: $(notdir $(KBUILD_IMAGE))
|
all: $(notdir $(KBUILD_IMAGE))
|
||||||
|
|
||||||
|
vmlinuz.efi: Image
|
||||||
Image vmlinuz.efi: vmlinux
|
Image vmlinuz.efi: vmlinux
|
||||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||||
|
|
||||||
|
@ -21,9 +21,22 @@ static inline bool arch_parse_debug_rodata(char *arg)
|
|||||||
extern bool rodata_enabled;
|
extern bool rodata_enabled;
|
||||||
extern bool rodata_full;
|
extern bool rodata_full;
|
||||||
|
|
||||||
if (arg && !strcmp(arg, "full")) {
|
if (!arg)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!strcmp(arg, "full")) {
|
||||||
|
rodata_enabled = rodata_full = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arg, "off")) {
|
||||||
|
rodata_enabled = rodata_full = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arg, "on")) {
|
||||||
rodata_enabled = true;
|
rodata_enabled = true;
|
||||||
rodata_full = true;
|
rodata_full = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ bool can_set_direct_map(void)
|
|||||||
*
|
*
|
||||||
* KFENCE pool requires page-granular mapping if initialized late.
|
* KFENCE pool requires page-granular mapping if initialized late.
|
||||||
*/
|
*/
|
||||||
return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() ||
|
return rodata_full || debug_pagealloc_enabled() ||
|
||||||
arm64_kfence_can_set_direct_map();
|
arm64_kfence_can_set_direct_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
|
static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
|
||||||
@ -105,8 +105,7 @@ static int change_memory_common(unsigned long addr, int numpages,
|
|||||||
* If we are manipulating read-only permissions, apply the same
|
* If we are manipulating read-only permissions, apply the same
|
||||||
* change to the linear mapping of the pages that back this VM area.
|
* change to the linear mapping of the pages that back this VM area.
|
||||||
*/
|
*/
|
||||||
if (rodata_enabled &&
|
if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY ||
|
||||||
rodata_full && (pgprot_val(set_mask) == PTE_RDONLY ||
|
|
||||||
pgprot_val(clear_mask) == PTE_RDONLY)) {
|
pgprot_val(clear_mask) == PTE_RDONLY)) {
|
||||||
for (i = 0; i < area->nr_pages; i++) {
|
for (i = 0; i < area->nr_pages; i++) {
|
||||||
__change_memory_common((u64)page_address(area->pages[i]),
|
__change_memory_common((u64)page_address(area->pages[i]),
|
||||||
|
@ -68,6 +68,7 @@ LDFLAGS_vmlinux += -static -n -nostdlib
|
|||||||
ifdef CONFIG_AS_HAS_EXPLICIT_RELOCS
|
ifdef CONFIG_AS_HAS_EXPLICIT_RELOCS
|
||||||
cflags-y += $(call cc-option,-mexplicit-relocs)
|
cflags-y += $(call cc-option,-mexplicit-relocs)
|
||||||
KBUILD_CFLAGS_KERNEL += $(call cc-option,-mdirect-extern-access)
|
KBUILD_CFLAGS_KERNEL += $(call cc-option,-mdirect-extern-access)
|
||||||
|
KBUILD_CFLAGS_KERNEL += $(call cc-option,-fdirect-access-external-data)
|
||||||
KBUILD_AFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
|
KBUILD_AFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
|
||||||
KBUILD_CFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
|
KBUILD_CFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
|
||||||
KBUILD_AFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax)
|
KBUILD_AFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax)
|
||||||
@ -142,6 +143,8 @@ vdso-install-y += arch/loongarch/vdso/vdso.so.dbg
|
|||||||
|
|
||||||
all: $(notdir $(KBUILD_IMAGE))
|
all: $(notdir $(KBUILD_IMAGE))
|
||||||
|
|
||||||
|
vmlinuz.efi: vmlinux.efi
|
||||||
|
|
||||||
vmlinux.elf vmlinux.efi vmlinuz.efi: vmlinux
|
vmlinux.elf vmlinux.efi vmlinuz.efi: vmlinux
|
||||||
$(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@
|
$(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@
|
||||||
|
|
||||||
|
@ -609,8 +609,7 @@
|
|||||||
lu32i.d \reg, 0
|
lu32i.d \reg, 0
|
||||||
lu52i.d \reg, \reg, 0
|
lu52i.d \reg, \reg, 0
|
||||||
.pushsection ".la_abs", "aw", %progbits
|
.pushsection ".la_abs", "aw", %progbits
|
||||||
768:
|
.dword 766b
|
||||||
.dword 768b-766b
|
|
||||||
.dword \sym
|
.dword \sym
|
||||||
.popsection
|
.popsection
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,13 +40,13 @@ static __always_inline unsigned long __percpu_##op(void *ptr, \
|
|||||||
switch (size) { \
|
switch (size) { \
|
||||||
case 4: \
|
case 4: \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"am"#asm_op".w" " %[ret], %[val], %[ptr] \n" \
|
"am"#asm_op".w" " %[ret], %[val], %[ptr] \n" \
|
||||||
: [ret] "=&r" (ret), [ptr] "+ZB"(*(u32 *)ptr) \
|
: [ret] "=&r" (ret), [ptr] "+ZB"(*(u32 *)ptr) \
|
||||||
: [val] "r" (val)); \
|
: [val] "r" (val)); \
|
||||||
break; \
|
break; \
|
||||||
case 8: \
|
case 8: \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"am"#asm_op".d" " %[ret], %[val], %[ptr] \n" \
|
"am"#asm_op".d" " %[ret], %[val], %[ptr] \n" \
|
||||||
: [ret] "=&r" (ret), [ptr] "+ZB"(*(u64 *)ptr) \
|
: [ret] "=&r" (ret), [ptr] "+ZB"(*(u64 *)ptr) \
|
||||||
: [val] "r" (val)); \
|
: [val] "r" (val)); \
|
||||||
break; \
|
break; \
|
||||||
@ -63,7 +63,7 @@ PERCPU_OP(and, and, &)
|
|||||||
PERCPU_OP(or, or, |)
|
PERCPU_OP(or, or, |)
|
||||||
#undef PERCPU_OP
|
#undef PERCPU_OP
|
||||||
|
|
||||||
static __always_inline unsigned long __percpu_read(void *ptr, int size)
|
static __always_inline unsigned long __percpu_read(void __percpu *ptr, int size)
|
||||||
{
|
{
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ static __always_inline unsigned long __percpu_read(void *ptr, int size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline void __percpu_write(void *ptr, unsigned long val, int size)
|
static __always_inline void __percpu_write(void __percpu *ptr, unsigned long val, int size)
|
||||||
{
|
{
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -132,8 +132,7 @@ static __always_inline void __percpu_write(void *ptr, unsigned long val, int siz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val,
|
static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val, int size)
|
||||||
int size)
|
|
||||||
{
|
{
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -25,7 +25,7 @@ extern void set_merr_handler(unsigned long offset, void *addr, unsigned long len
|
|||||||
#ifdef CONFIG_RELOCATABLE
|
#ifdef CONFIG_RELOCATABLE
|
||||||
|
|
||||||
struct rela_la_abs {
|
struct rela_la_abs {
|
||||||
long offset;
|
long pc;
|
||||||
long symvalue;
|
long symvalue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ static inline void __init relocate_absolute(long random_offset)
|
|||||||
for (p = begin; (void *)p < end; p++) {
|
for (p = begin; (void *)p < end; p++) {
|
||||||
long v = p->symvalue;
|
long v = p->symvalue;
|
||||||
uint32_t lu12iw, ori, lu32id, lu52id;
|
uint32_t lu12iw, ori, lu32id, lu52id;
|
||||||
union loongarch_instruction *insn = (void *)p - p->offset;
|
union loongarch_instruction *insn = (void *)p->pc;
|
||||||
|
|
||||||
lu12iw = (v >> 12) & 0xfffff;
|
lu12iw = (v >> 12) & 0xfffff;
|
||||||
ori = v & 0xfff;
|
ori = v & 0xfff;
|
||||||
@ -102,6 +102,14 @@ static inline __init unsigned long get_random_boot(void)
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init nokaslr(char *p)
|
||||||
|
{
|
||||||
|
pr_info("KASLR is disabled.\n");
|
||||||
|
|
||||||
|
return 0; /* Print a notice and silence the boot warning */
|
||||||
|
}
|
||||||
|
early_param("nokaslr", nokaslr);
|
||||||
|
|
||||||
static inline __init bool kaslr_disabled(void)
|
static inline __init bool kaslr_disabled(void)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
|
@ -58,21 +58,6 @@ static int constant_set_state_oneshot(struct clock_event_device *evt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int constant_set_state_oneshot_stopped(struct clock_event_device *evt)
|
|
||||||
{
|
|
||||||
unsigned long timer_config;
|
|
||||||
|
|
||||||
raw_spin_lock(&state_lock);
|
|
||||||
|
|
||||||
timer_config = csr_read64(LOONGARCH_CSR_TCFG);
|
|
||||||
timer_config &= ~CSR_TCFG_EN;
|
|
||||||
csr_write64(timer_config, LOONGARCH_CSR_TCFG);
|
|
||||||
|
|
||||||
raw_spin_unlock(&state_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int constant_set_state_periodic(struct clock_event_device *evt)
|
static int constant_set_state_periodic(struct clock_event_device *evt)
|
||||||
{
|
{
|
||||||
unsigned long period;
|
unsigned long period;
|
||||||
@ -92,6 +77,16 @@ static int constant_set_state_periodic(struct clock_event_device *evt)
|
|||||||
|
|
||||||
static int constant_set_state_shutdown(struct clock_event_device *evt)
|
static int constant_set_state_shutdown(struct clock_event_device *evt)
|
||||||
{
|
{
|
||||||
|
unsigned long timer_config;
|
||||||
|
|
||||||
|
raw_spin_lock(&state_lock);
|
||||||
|
|
||||||
|
timer_config = csr_read64(LOONGARCH_CSR_TCFG);
|
||||||
|
timer_config &= ~CSR_TCFG_EN;
|
||||||
|
csr_write64(timer_config, LOONGARCH_CSR_TCFG);
|
||||||
|
|
||||||
|
raw_spin_unlock(&state_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +156,7 @@ int constant_clockevent_init(void)
|
|||||||
cd->rating = 320;
|
cd->rating = 320;
|
||||||
cd->cpumask = cpumask_of(cpu);
|
cd->cpumask = cpumask_of(cpu);
|
||||||
cd->set_state_oneshot = constant_set_state_oneshot;
|
cd->set_state_oneshot = constant_set_state_oneshot;
|
||||||
cd->set_state_oneshot_stopped = constant_set_state_oneshot_stopped;
|
cd->set_state_oneshot_stopped = constant_set_state_shutdown;
|
||||||
cd->set_state_periodic = constant_set_state_periodic;
|
cd->set_state_periodic = constant_set_state_periodic;
|
||||||
cd->set_state_shutdown = constant_set_state_shutdown;
|
cd->set_state_shutdown = constant_set_state_shutdown;
|
||||||
cd->set_next_event = constant_timer_next_event;
|
cd->set_next_event = constant_timer_next_event;
|
||||||
|
@ -13,13 +13,13 @@ struct page *dmw_virt_to_page(unsigned long kaddr)
|
|||||||
{
|
{
|
||||||
return pfn_to_page(virt_to_pfn(kaddr));
|
return pfn_to_page(virt_to_pfn(kaddr));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dmw_virt_to_page);
|
EXPORT_SYMBOL(dmw_virt_to_page);
|
||||||
|
|
||||||
struct page *tlb_virt_to_page(unsigned long kaddr)
|
struct page *tlb_virt_to_page(unsigned long kaddr)
|
||||||
{
|
{
|
||||||
return pfn_to_page(pte_pfn(*virt_to_kpte(kaddr)));
|
return pfn_to_page(pte_pfn(*virt_to_kpte(kaddr)));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(tlb_virt_to_page);
|
EXPORT_SYMBOL(tlb_virt_to_page);
|
||||||
|
|
||||||
pgd_t *pgd_alloc(struct mm_struct *mm)
|
pgd_t *pgd_alloc(struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
|
@ -115,9 +115,12 @@ config ARCH_HAS_ILOG2_U64
|
|||||||
default n
|
default n
|
||||||
|
|
||||||
config GENERIC_BUG
|
config GENERIC_BUG
|
||||||
bool
|
def_bool y
|
||||||
default y
|
|
||||||
depends on BUG
|
depends on BUG
|
||||||
|
select GENERIC_BUG_RELATIVE_POINTERS if 64BIT
|
||||||
|
|
||||||
|
config GENERIC_BUG_RELATIVE_POINTERS
|
||||||
|
bool
|
||||||
|
|
||||||
config GENERIC_HWEIGHT
|
config GENERIC_HWEIGHT
|
||||||
bool
|
bool
|
||||||
|
@ -34,7 +34,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end,
|
|||||||
|
|
||||||
/* Alternative SMP implementation. */
|
/* Alternative SMP implementation. */
|
||||||
#define ALTERNATIVE(cond, replacement) "!0:" \
|
#define ALTERNATIVE(cond, replacement) "!0:" \
|
||||||
".section .altinstructions, \"aw\" !" \
|
".section .altinstructions, \"a\" !" \
|
||||||
|
".align 4 !" \
|
||||||
".word (0b-4-.) !" \
|
".word (0b-4-.) !" \
|
||||||
".hword 1, " __stringify(cond) " !" \
|
".hword 1, " __stringify(cond) " !" \
|
||||||
".word " __stringify(replacement) " !" \
|
".word " __stringify(replacement) " !" \
|
||||||
@ -44,7 +45,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end,
|
|||||||
|
|
||||||
/* to replace one single instructions by a new instruction */
|
/* to replace one single instructions by a new instruction */
|
||||||
#define ALTERNATIVE(from, to, cond, replacement)\
|
#define ALTERNATIVE(from, to, cond, replacement)\
|
||||||
.section .altinstructions, "aw" ! \
|
.section .altinstructions, "a" ! \
|
||||||
|
.align 4 ! \
|
||||||
.word (from - .) ! \
|
.word (from - .) ! \
|
||||||
.hword (to - from)/4, cond ! \
|
.hword (to - from)/4, cond ! \
|
||||||
.word replacement ! \
|
.word replacement ! \
|
||||||
@ -52,7 +54,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end,
|
|||||||
|
|
||||||
/* to replace multiple instructions by new code */
|
/* to replace multiple instructions by new code */
|
||||||
#define ALTERNATIVE_CODE(from, num_instructions, cond, new_instr_ptr)\
|
#define ALTERNATIVE_CODE(from, num_instructions, cond, new_instr_ptr)\
|
||||||
.section .altinstructions, "aw" ! \
|
.section .altinstructions, "a" ! \
|
||||||
|
.align 4 ! \
|
||||||
.word (from - .) ! \
|
.word (from - .) ! \
|
||||||
.hword -num_instructions, cond ! \
|
.hword -num_instructions, cond ! \
|
||||||
.word (new_instr_ptr - .) ! \
|
.word (new_instr_ptr - .) ! \
|
||||||
|
@ -574,6 +574,7 @@
|
|||||||
*/
|
*/
|
||||||
#define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr) \
|
#define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr) \
|
||||||
.section __ex_table,"aw" ! \
|
.section __ex_table,"aw" ! \
|
||||||
|
.align 4 ! \
|
||||||
.word (fault_addr - .), (except_addr - .) ! \
|
.word (fault_addr - .), (except_addr - .) ! \
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
|
@ -17,24 +17,27 @@
|
|||||||
#define PARISC_BUG_BREAK_ASM "break 0x1f, 0x1fff"
|
#define PARISC_BUG_BREAK_ASM "break 0x1f, 0x1fff"
|
||||||
#define PARISC_BUG_BREAK_INSN 0x03ffe01f /* PARISC_BUG_BREAK_ASM */
|
#define PARISC_BUG_BREAK_INSN 0x03ffe01f /* PARISC_BUG_BREAK_ASM */
|
||||||
|
|
||||||
#if defined(CONFIG_64BIT)
|
#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
||||||
#define ASM_WORD_INSN ".dword\t"
|
# define __BUG_REL(val) ".word " __stringify(val) " - ."
|
||||||
#else
|
#else
|
||||||
#define ASM_WORD_INSN ".word\t"
|
# define __BUG_REL(val) ".word " __stringify(val)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||||
#define BUG() \
|
#define BUG() \
|
||||||
do { \
|
do { \
|
||||||
asm volatile("\n" \
|
asm volatile("\n" \
|
||||||
"1:\t" PARISC_BUG_BREAK_ASM "\n" \
|
"1:\t" PARISC_BUG_BREAK_ASM "\n" \
|
||||||
"\t.pushsection __bug_table,\"aw\"\n" \
|
"\t.pushsection __bug_table,\"a\"\n" \
|
||||||
"2:\t" ASM_WORD_INSN "1b, %c0\n" \
|
"\t.align 4\n" \
|
||||||
"\t.short %c1, %c2\n" \
|
"2:\t" __BUG_REL(1b) "\n" \
|
||||||
"\t.org 2b+%c3\n" \
|
"\t" __BUG_REL(%c0) "\n" \
|
||||||
|
"\t.short %1, %2\n" \
|
||||||
|
"\t.blockz %3-2*4-2*2\n" \
|
||||||
"\t.popsection" \
|
"\t.popsection" \
|
||||||
: : "i" (__FILE__), "i" (__LINE__), \
|
: : "i" (__FILE__), "i" (__LINE__), \
|
||||||
"i" (0), "i" (sizeof(struct bug_entry)) ); \
|
"i" (0), "i" (sizeof(struct bug_entry)) ); \
|
||||||
unreachable(); \
|
unreachable(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
@ -51,10 +54,12 @@
|
|||||||
do { \
|
do { \
|
||||||
asm volatile("\n" \
|
asm volatile("\n" \
|
||||||
"1:\t" PARISC_BUG_BREAK_ASM "\n" \
|
"1:\t" PARISC_BUG_BREAK_ASM "\n" \
|
||||||
"\t.pushsection __bug_table,\"aw\"\n" \
|
"\t.pushsection __bug_table,\"a\"\n" \
|
||||||
"2:\t" ASM_WORD_INSN "1b, %c0\n" \
|
"\t.align 4\n" \
|
||||||
"\t.short %c1, %c2\n" \
|
"2:\t" __BUG_REL(1b) "\n" \
|
||||||
"\t.org 2b+%c3\n" \
|
"\t" __BUG_REL(%c0) "\n" \
|
||||||
|
"\t.short %1, %2\n" \
|
||||||
|
"\t.blockz %3-2*4-2*2\n" \
|
||||||
"\t.popsection" \
|
"\t.popsection" \
|
||||||
: : "i" (__FILE__), "i" (__LINE__), \
|
: : "i" (__FILE__), "i" (__LINE__), \
|
||||||
"i" (BUGFLAG_WARNING|(flags)), \
|
"i" (BUGFLAG_WARNING|(flags)), \
|
||||||
@ -65,10 +70,11 @@
|
|||||||
do { \
|
do { \
|
||||||
asm volatile("\n" \
|
asm volatile("\n" \
|
||||||
"1:\t" PARISC_BUG_BREAK_ASM "\n" \
|
"1:\t" PARISC_BUG_BREAK_ASM "\n" \
|
||||||
"\t.pushsection __bug_table,\"aw\"\n" \
|
"\t.pushsection __bug_table,\"a\"\n" \
|
||||||
"2:\t" ASM_WORD_INSN "1b\n" \
|
"\t.align %2\n" \
|
||||||
"\t.short %c0\n" \
|
"2:\t" __BUG_REL(1b) "\n" \
|
||||||
"\t.org 2b+%c1\n" \
|
"\t.short %0\n" \
|
||||||
|
"\t.blockz %1-4-2\n" \
|
||||||
"\t.popsection" \
|
"\t.popsection" \
|
||||||
: : "i" (BUGFLAG_WARNING|(flags)), \
|
: : "i" (BUGFLAG_WARNING|(flags)), \
|
||||||
"i" (sizeof(struct bug_entry)) ); \
|
"i" (sizeof(struct bug_entry)) ); \
|
||||||
|
@ -15,10 +15,12 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
|
|||||||
asm_volatile_goto("1:\n\t"
|
asm_volatile_goto("1:\n\t"
|
||||||
"nop\n\t"
|
"nop\n\t"
|
||||||
".pushsection __jump_table, \"aw\"\n\t"
|
".pushsection __jump_table, \"aw\"\n\t"
|
||||||
|
".align %1\n\t"
|
||||||
".word 1b - ., %l[l_yes] - .\n\t"
|
".word 1b - ., %l[l_yes] - .\n\t"
|
||||||
__stringify(ASM_ULONG_INSN) " %c0 - .\n\t"
|
__stringify(ASM_ULONG_INSN) " %c0 - .\n\t"
|
||||||
".popsection\n\t"
|
".popsection\n\t"
|
||||||
: : "i" (&((char *)key)[branch]) : : l_yes);
|
: : "i" (&((char *)key)[branch]), "i" (sizeof(long))
|
||||||
|
: : l_yes);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
l_yes:
|
l_yes:
|
||||||
@ -30,10 +32,12 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
|
|||||||
asm_volatile_goto("1:\n\t"
|
asm_volatile_goto("1:\n\t"
|
||||||
"b,n %l[l_yes]\n\t"
|
"b,n %l[l_yes]\n\t"
|
||||||
".pushsection __jump_table, \"aw\"\n\t"
|
".pushsection __jump_table, \"aw\"\n\t"
|
||||||
|
".align %1\n\t"
|
||||||
".word 1b - ., %l[l_yes] - .\n\t"
|
".word 1b - ., %l[l_yes] - .\n\t"
|
||||||
__stringify(ASM_ULONG_INSN) " %c0 - .\n\t"
|
__stringify(ASM_ULONG_INSN) " %c0 - .\n\t"
|
||||||
".popsection\n\t"
|
".popsection\n\t"
|
||||||
: : "i" (&((char *)key)[branch]) : : l_yes);
|
: : "i" (&((char *)key)[branch]), "i" (sizeof(long))
|
||||||
|
: : l_yes);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
l_yes:
|
l_yes:
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
# define __lock_aligned __section(".data..lock_aligned")
|
# define __lock_aligned __section(".data..lock_aligned") __aligned(16)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __PARISC_LDCW_H */
|
#endif /* __PARISC_LDCW_H */
|
||||||
|
@ -41,6 +41,7 @@ struct exception_table_entry {
|
|||||||
|
|
||||||
#define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\
|
#define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\
|
||||||
".section __ex_table,\"aw\"\n" \
|
".section __ex_table,\"aw\"\n" \
|
||||||
|
".align 4\n" \
|
||||||
".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \
|
".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \
|
||||||
".previous\n"
|
".previous\n"
|
||||||
|
|
||||||
|
@ -75,7 +75,6 @@
|
|||||||
|
|
||||||
/* We now return you to your regularly scheduled HPUX. */
|
/* We now return you to your regularly scheduled HPUX. */
|
||||||
|
|
||||||
#define ENOSYM 215 /* symbol does not exist in executable */
|
|
||||||
#define ENOTSOCK 216 /* Socket operation on non-socket */
|
#define ENOTSOCK 216 /* Socket operation on non-socket */
|
||||||
#define EDESTADDRREQ 217 /* Destination address required */
|
#define EDESTADDRREQ 217 /* Destination address required */
|
||||||
#define EMSGSIZE 218 /* Message too long */
|
#define EMSGSIZE 218 /* Message too long */
|
||||||
@ -101,7 +100,6 @@
|
|||||||
#define ETIMEDOUT 238 /* Connection timed out */
|
#define ETIMEDOUT 238 /* Connection timed out */
|
||||||
#define ECONNREFUSED 239 /* Connection refused */
|
#define ECONNREFUSED 239 /* Connection refused */
|
||||||
#define EREFUSED ECONNREFUSED /* for HP's NFS apparently */
|
#define EREFUSED ECONNREFUSED /* for HP's NFS apparently */
|
||||||
#define EREMOTERELEASE 240 /* Remote peer released connection */
|
|
||||||
#define EHOSTDOWN 241 /* Host is down */
|
#define EHOSTDOWN 241 /* Host is down */
|
||||||
#define EHOSTUNREACH 242 /* No route to host */
|
#define EHOSTUNREACH 242 /* No route to host */
|
||||||
|
|
||||||
|
@ -130,6 +130,7 @@ SECTIONS
|
|||||||
RO_DATA(8)
|
RO_DATA(8)
|
||||||
|
|
||||||
/* unwind info */
|
/* unwind info */
|
||||||
|
. = ALIGN(4);
|
||||||
.PARISC.unwind : {
|
.PARISC.unwind : {
|
||||||
__start___unwind = .;
|
__start___unwind = .;
|
||||||
*(.PARISC.unwind)
|
*(.PARISC.unwind)
|
||||||
|
@ -228,7 +228,6 @@ typedef struct thread_struct thread_struct;
|
|||||||
execve_tail(); \
|
execve_tail(); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Forward declaration, a strange C thing */
|
|
||||||
struct task_struct;
|
struct task_struct;
|
||||||
struct mm_struct;
|
struct mm_struct;
|
||||||
struct seq_file;
|
struct seq_file;
|
||||||
|
@ -666,6 +666,7 @@ static int __init ipl_init(void)
|
|||||||
&ipl_ccw_attr_group_lpar);
|
&ipl_ccw_attr_group_lpar);
|
||||||
break;
|
break;
|
||||||
case IPL_TYPE_ECKD:
|
case IPL_TYPE_ECKD:
|
||||||
|
case IPL_TYPE_ECKD_DUMP:
|
||||||
rc = sysfs_create_group(&ipl_kset->kobj, &ipl_eckd_attr_group);
|
rc = sysfs_create_group(&ipl_kset->kobj, &ipl_eckd_attr_group);
|
||||||
break;
|
break;
|
||||||
case IPL_TYPE_FCP:
|
case IPL_TYPE_FCP:
|
||||||
|
@ -279,12 +279,6 @@ static int paicrypt_event_init(struct perf_event *event)
|
|||||||
if (IS_ERR(cpump))
|
if (IS_ERR(cpump))
|
||||||
return PTR_ERR(cpump);
|
return PTR_ERR(cpump);
|
||||||
|
|
||||||
/* Event initialization sets last_tag to 0. When later on the events
|
|
||||||
* are deleted and re-added, do not reset the event count value to zero.
|
|
||||||
* Events are added, deleted and re-added when 2 or more events
|
|
||||||
* are active at the same time.
|
|
||||||
*/
|
|
||||||
event->hw.last_tag = 0;
|
|
||||||
event->destroy = paicrypt_event_destroy;
|
event->destroy = paicrypt_event_destroy;
|
||||||
|
|
||||||
if (a->sample_period) {
|
if (a->sample_period) {
|
||||||
@ -318,6 +312,11 @@ static void paicrypt_start(struct perf_event *event, int flags)
|
|||||||
{
|
{
|
||||||
u64 sum;
|
u64 sum;
|
||||||
|
|
||||||
|
/* Event initialization sets last_tag to 0. When later on the events
|
||||||
|
* are deleted and re-added, do not reset the event count value to zero.
|
||||||
|
* Events are added, deleted and re-added when 2 or more events
|
||||||
|
* are active at the same time.
|
||||||
|
*/
|
||||||
if (!event->hw.last_tag) {
|
if (!event->hw.last_tag) {
|
||||||
event->hw.last_tag = 1;
|
event->hw.last_tag = 1;
|
||||||
sum = paicrypt_getall(event); /* Get current value */
|
sum = paicrypt_getall(event); /* Get current value */
|
||||||
|
@ -260,7 +260,6 @@ static int paiext_event_init(struct perf_event *event)
|
|||||||
rc = paiext_alloc(a, event);
|
rc = paiext_alloc(a, event);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
event->hw.last_tag = 0;
|
|
||||||
event->destroy = paiext_event_destroy;
|
event->destroy = paiext_event_destroy;
|
||||||
|
|
||||||
if (a->sample_period) {
|
if (a->sample_period) {
|
||||||
|
@ -4660,7 +4660,7 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
|
|||||||
if (pmu->intel_cap.pebs_output_pt_available)
|
if (pmu->intel_cap.pebs_output_pt_available)
|
||||||
pmu->pmu.capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
|
pmu->pmu.capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
|
||||||
else
|
else
|
||||||
pmu->pmu.capabilities |= ~PERF_PMU_CAP_AUX_OUTPUT;
|
pmu->pmu.capabilities &= ~PERF_PMU_CAP_AUX_OUTPUT;
|
||||||
|
|
||||||
intel_pmu_check_event_constraints(pmu->event_constraints,
|
intel_pmu_check_event_constraints(pmu->event_constraints,
|
||||||
pmu->num_counters,
|
pmu->num_counters,
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/desc.h>
|
#include <asm/desc.h>
|
||||||
|
#include <asm/e820/api.h>
|
||||||
#include <asm/sev.h>
|
#include <asm/sev.h>
|
||||||
#include <asm/ibt.h>
|
#include <asm/ibt.h>
|
||||||
#include <asm/hypervisor.h>
|
#include <asm/hypervisor.h>
|
||||||
@ -286,15 +287,31 @@ static int hv_cpu_die(unsigned int cpu)
|
|||||||
|
|
||||||
static int __init hv_pci_init(void)
|
static int __init hv_pci_init(void)
|
||||||
{
|
{
|
||||||
int gen2vm = efi_enabled(EFI_BOOT);
|
bool gen2vm = efi_enabled(EFI_BOOT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For Generation-2 VM, we exit from pci_arch_init() by returning 0.
|
* A Generation-2 VM doesn't support legacy PCI/PCIe, so both
|
||||||
* The purpose is to suppress the harmless warning:
|
* raw_pci_ops and raw_pci_ext_ops are NULL, and pci_subsys_init() ->
|
||||||
|
* pcibios_init() doesn't call pcibios_resource_survey() ->
|
||||||
|
* e820__reserve_resources_late(); as a result, any emulated persistent
|
||||||
|
* memory of E820_TYPE_PRAM (12) via the kernel parameter
|
||||||
|
* memmap=nn[KMG]!ss is not added into iomem_resource and hence can't be
|
||||||
|
* detected by register_e820_pmem(). Fix this by directly calling
|
||||||
|
* e820__reserve_resources_late() here: e820__reserve_resources_late()
|
||||||
|
* depends on e820__reserve_resources(), which has been called earlier
|
||||||
|
* from setup_arch(). Note: e820__reserve_resources_late() also adds
|
||||||
|
* any memory of E820_TYPE_PMEM (7) into iomem_resource, and
|
||||||
|
* acpi_nfit_register_region() -> acpi_nfit_insert_resource() ->
|
||||||
|
* region_intersects() returns REGION_INTERSECTS, so the memory of
|
||||||
|
* E820_TYPE_PMEM won't get added twice.
|
||||||
|
*
|
||||||
|
* We return 0 here so that pci_arch_init() won't print the warning:
|
||||||
* "PCI: Fatal: No config space access function found"
|
* "PCI: Fatal: No config space access function found"
|
||||||
*/
|
*/
|
||||||
if (gen2vm)
|
if (gen2vm) {
|
||||||
|
e820__reserve_resources_late();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* For Generation-1 VM, we'll proceed in pci_arch_init(). */
|
/* For Generation-1 VM, we'll proceed in pci_arch_init(). */
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -104,8 +104,6 @@ struct cont_desc {
|
|||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 ucode_new_rev;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Microcode patch container file is prepended to the initrd in cpio
|
* Microcode patch container file is prepended to the initrd in cpio
|
||||||
* format. See Documentation/arch/x86/microcode.rst
|
* format. See Documentation/arch/x86/microcode.rst
|
||||||
@ -442,12 +440,11 @@ static int __apply_microcode_amd(struct microcode_amd *mc)
|
|||||||
*
|
*
|
||||||
* Returns true if container found (sets @desc), false otherwise.
|
* Returns true if container found (sets @desc), false otherwise.
|
||||||
*/
|
*/
|
||||||
static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size)
|
static bool early_apply_microcode(u32 cpuid_1_eax, u32 old_rev, void *ucode, size_t size)
|
||||||
{
|
{
|
||||||
struct cont_desc desc = { 0 };
|
struct cont_desc desc = { 0 };
|
||||||
struct microcode_amd *mc;
|
struct microcode_amd *mc;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
u32 rev, dummy;
|
|
||||||
|
|
||||||
desc.cpuid_1_eax = cpuid_1_eax;
|
desc.cpuid_1_eax = cpuid_1_eax;
|
||||||
|
|
||||||
@ -457,22 +454,15 @@ static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size)
|
|||||||
if (!mc)
|
if (!mc)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow application of the same revision to pick up SMT-specific
|
* Allow application of the same revision to pick up SMT-specific
|
||||||
* changes even if the revision of the other SMT thread is already
|
* changes even if the revision of the other SMT thread is already
|
||||||
* up-to-date.
|
* up-to-date.
|
||||||
*/
|
*/
|
||||||
if (rev > mc->hdr.patch_id)
|
if (old_rev > mc->hdr.patch_id)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (!__apply_microcode_amd(mc)) {
|
return !__apply_microcode_amd(mc);
|
||||||
ucode_new_rev = mc->hdr.patch_id;
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family)
|
static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family)
|
||||||
@ -506,9 +496,12 @@ static void __init find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpi
|
|||||||
*ret = cp;
|
*ret = cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
|
void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_eax)
|
||||||
{
|
{
|
||||||
struct cpio_data cp = { };
|
struct cpio_data cp = { };
|
||||||
|
u32 dummy;
|
||||||
|
|
||||||
|
native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->old_rev, dummy);
|
||||||
|
|
||||||
/* Needed in load_microcode_amd() */
|
/* Needed in load_microcode_amd() */
|
||||||
ucode_cpu_info[0].cpu_sig.sig = cpuid_1_eax;
|
ucode_cpu_info[0].cpu_sig.sig = cpuid_1_eax;
|
||||||
@ -517,7 +510,8 @@ void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
|
|||||||
if (!(cp.data && cp.size))
|
if (!(cp.data && cp.size))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
early_apply_microcode(cpuid_1_eax, cp.data, cp.size);
|
if (early_apply_microcode(cpuid_1_eax, ed->old_rev, cp.data, cp.size))
|
||||||
|
native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->new_rev, dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
|
static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
|
||||||
@ -625,10 +619,8 @@ void reload_ucode_amd(unsigned int cpu)
|
|||||||
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
|
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
|
||||||
|
|
||||||
if (rev < mc->hdr.patch_id) {
|
if (rev < mc->hdr.patch_id) {
|
||||||
if (!__apply_microcode_amd(mc)) {
|
if (!__apply_microcode_amd(mc))
|
||||||
ucode_new_rev = mc->hdr.patch_id;
|
pr_info_once("reload revision: 0x%08x\n", mc->hdr.patch_id);
|
||||||
pr_info("reload patch_level=0x%08x\n", ucode_new_rev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,8 +641,6 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
|
|||||||
if (p && (p->patch_id == csig->rev))
|
if (p && (p->patch_id == csig->rev))
|
||||||
uci->mc = p->data;
|
uci->mc = p->data;
|
||||||
|
|
||||||
pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,8 +681,6 @@ static enum ucode_state apply_microcode_amd(int cpu)
|
|||||||
rev = mc_amd->hdr.patch_id;
|
rev = mc_amd->hdr.patch_id;
|
||||||
ret = UCODE_UPDATED;
|
ret = UCODE_UPDATED;
|
||||||
|
|
||||||
pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
uci->cpu_sig.rev = rev;
|
uci->cpu_sig.rev = rev;
|
||||||
c->microcode = rev;
|
c->microcode = rev;
|
||||||
@ -935,11 +923,6 @@ struct microcode_ops * __init init_amd_microcode(void)
|
|||||||
pr_warn("AMD CPU family 0x%x not supported\n", c->x86);
|
pr_warn("AMD CPU family 0x%x not supported\n", c->x86);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ucode_new_rev)
|
|
||||||
pr_info_once("microcode updated early to new patch_level=0x%08x\n",
|
|
||||||
ucode_new_rev);
|
|
||||||
|
|
||||||
return µcode_amd_ops;
|
return µcode_amd_ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,6 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define DRIVER_VERSION "2.2"
|
|
||||||
|
|
||||||
static struct microcode_ops *microcode_ops;
|
static struct microcode_ops *microcode_ops;
|
||||||
bool dis_ucode_ldr = true;
|
bool dis_ucode_ldr = true;
|
||||||
|
|
||||||
@ -77,6 +75,8 @@ static u32 final_levels[] = {
|
|||||||
0, /* T-101 terminator */
|
0, /* T-101 terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct early_load_data early_data;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the current patch level on this CPU.
|
* Check the current patch level on this CPU.
|
||||||
*
|
*
|
||||||
@ -155,9 +155,9 @@ void __init load_ucode_bsp(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (intel)
|
if (intel)
|
||||||
load_ucode_intel_bsp();
|
load_ucode_intel_bsp(&early_data);
|
||||||
else
|
else
|
||||||
load_ucode_amd_bsp(cpuid_1_eax);
|
load_ucode_amd_bsp(&early_data, cpuid_1_eax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_ucode_ap(void)
|
void load_ucode_ap(void)
|
||||||
@ -828,6 +828,11 @@ static int __init microcode_init(void)
|
|||||||
if (!microcode_ops)
|
if (!microcode_ops)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
pr_info_once("Current revision: 0x%08x\n", (early_data.new_rev ?: early_data.old_rev));
|
||||||
|
|
||||||
|
if (early_data.new_rev)
|
||||||
|
pr_info_once("Updated early from: 0x%08x\n", early_data.old_rev);
|
||||||
|
|
||||||
microcode_pdev = platform_device_register_simple("microcode", -1, NULL, 0);
|
microcode_pdev = platform_device_register_simple("microcode", -1, NULL, 0);
|
||||||
if (IS_ERR(microcode_pdev))
|
if (IS_ERR(microcode_pdev))
|
||||||
return PTR_ERR(microcode_pdev);
|
return PTR_ERR(microcode_pdev);
|
||||||
@ -846,8 +851,6 @@ static int __init microcode_init(void)
|
|||||||
cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
|
cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
|
||||||
mc_cpu_online, mc_cpu_down_prep);
|
mc_cpu_online, mc_cpu_down_prep);
|
||||||
|
|
||||||
pr_info("Microcode Update Driver: v%s.", DRIVER_VERSION);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_pdev:
|
out_pdev:
|
||||||
|
@ -339,16 +339,9 @@ static enum ucode_state __apply_microcode(struct ucode_cpu_info *uci,
|
|||||||
static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci)
|
static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci)
|
||||||
{
|
{
|
||||||
struct microcode_intel *mc = uci->mc;
|
struct microcode_intel *mc = uci->mc;
|
||||||
enum ucode_state ret;
|
u32 cur_rev;
|
||||||
u32 cur_rev, date;
|
|
||||||
|
|
||||||
ret = __apply_microcode(uci, mc, &cur_rev);
|
return __apply_microcode(uci, mc, &cur_rev);
|
||||||
if (ret == UCODE_UPDATED) {
|
|
||||||
date = mc->hdr.date;
|
|
||||||
pr_info_once("updated early: 0x%x -> 0x%x, date = %04x-%02x-%02x\n",
|
|
||||||
cur_rev, mc->hdr.rev, date & 0xffff, date >> 24, (date >> 16) & 0xff);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __init bool load_builtin_intel_microcode(struct cpio_data *cp)
|
static __init bool load_builtin_intel_microcode(struct cpio_data *cp)
|
||||||
@ -413,13 +406,17 @@ static int __init save_builtin_microcode(void)
|
|||||||
early_initcall(save_builtin_microcode);
|
early_initcall(save_builtin_microcode);
|
||||||
|
|
||||||
/* Load microcode on BSP from initrd or builtin blobs */
|
/* Load microcode on BSP from initrd or builtin blobs */
|
||||||
void __init load_ucode_intel_bsp(void)
|
void __init load_ucode_intel_bsp(struct early_load_data *ed)
|
||||||
{
|
{
|
||||||
struct ucode_cpu_info uci;
|
struct ucode_cpu_info uci;
|
||||||
|
|
||||||
|
ed->old_rev = intel_get_microcode_revision();
|
||||||
|
|
||||||
uci.mc = get_microcode_blob(&uci, false);
|
uci.mc = get_microcode_blob(&uci, false);
|
||||||
if (uci.mc && apply_microcode_early(&uci) == UCODE_UPDATED)
|
if (uci.mc && apply_microcode_early(&uci) == UCODE_UPDATED)
|
||||||
ucode_patch_va = UCODE_BSP_LOADED;
|
ucode_patch_va = UCODE_BSP_LOADED;
|
||||||
|
|
||||||
|
ed->new_rev = uci.cpu_sig.rev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_ucode_intel_ap(void)
|
void load_ucode_intel_ap(void)
|
||||||
|
@ -37,6 +37,12 @@ struct microcode_ops {
|
|||||||
use_nmi : 1;
|
use_nmi : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct early_load_data {
|
||||||
|
u32 old_rev;
|
||||||
|
u32 new_rev;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct early_load_data early_data;
|
||||||
extern struct ucode_cpu_info ucode_cpu_info[];
|
extern struct ucode_cpu_info ucode_cpu_info[];
|
||||||
struct cpio_data find_microcode_in_initrd(const char *path);
|
struct cpio_data find_microcode_in_initrd(const char *path);
|
||||||
|
|
||||||
@ -92,14 +98,14 @@ extern bool dis_ucode_ldr;
|
|||||||
extern bool force_minrev;
|
extern bool force_minrev;
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_SUP_AMD
|
#ifdef CONFIG_CPU_SUP_AMD
|
||||||
void load_ucode_amd_bsp(unsigned int family);
|
void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family);
|
||||||
void load_ucode_amd_ap(unsigned int family);
|
void load_ucode_amd_ap(unsigned int family);
|
||||||
int save_microcode_in_initrd_amd(unsigned int family);
|
int save_microcode_in_initrd_amd(unsigned int family);
|
||||||
void reload_ucode_amd(unsigned int cpu);
|
void reload_ucode_amd(unsigned int cpu);
|
||||||
struct microcode_ops *init_amd_microcode(void);
|
struct microcode_ops *init_amd_microcode(void);
|
||||||
void exit_amd_microcode(void);
|
void exit_amd_microcode(void);
|
||||||
#else /* CONFIG_CPU_SUP_AMD */
|
#else /* CONFIG_CPU_SUP_AMD */
|
||||||
static inline void load_ucode_amd_bsp(unsigned int family) { }
|
static inline void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family) { }
|
||||||
static inline void load_ucode_amd_ap(unsigned int family) { }
|
static inline void load_ucode_amd_ap(unsigned int family) { }
|
||||||
static inline int save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
|
static inline int save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
|
||||||
static inline void reload_ucode_amd(unsigned int cpu) { }
|
static inline void reload_ucode_amd(unsigned int cpu) { }
|
||||||
@ -108,12 +114,12 @@ static inline void exit_amd_microcode(void) { }
|
|||||||
#endif /* !CONFIG_CPU_SUP_AMD */
|
#endif /* !CONFIG_CPU_SUP_AMD */
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_SUP_INTEL
|
#ifdef CONFIG_CPU_SUP_INTEL
|
||||||
void load_ucode_intel_bsp(void);
|
void load_ucode_intel_bsp(struct early_load_data *ed);
|
||||||
void load_ucode_intel_ap(void);
|
void load_ucode_intel_ap(void);
|
||||||
void reload_ucode_intel(void);
|
void reload_ucode_intel(void);
|
||||||
struct microcode_ops *init_intel_microcode(void);
|
struct microcode_ops *init_intel_microcode(void);
|
||||||
#else /* CONFIG_CPU_SUP_INTEL */
|
#else /* CONFIG_CPU_SUP_INTEL */
|
||||||
static inline void load_ucode_intel_bsp(void) { }
|
static inline void load_ucode_intel_bsp(struct early_load_data *ed) { }
|
||||||
static inline void load_ucode_intel_ap(void) { }
|
static inline void load_ucode_intel_ap(void) { }
|
||||||
static inline void reload_ucode_intel(void) { }
|
static inline void reload_ucode_intel(void) { }
|
||||||
static inline struct microcode_ops *init_intel_microcode(void) { return NULL; }
|
static inline struct microcode_ops *init_intel_microcode(void) { return NULL; }
|
||||||
|
@ -262,11 +262,14 @@ static uint32_t __init ms_hyperv_platform(void)
|
|||||||
static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs)
|
static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
static atomic_t nmi_cpu = ATOMIC_INIT(-1);
|
static atomic_t nmi_cpu = ATOMIC_INIT(-1);
|
||||||
|
unsigned int old_cpu, this_cpu;
|
||||||
|
|
||||||
if (!unknown_nmi_panic)
|
if (!unknown_nmi_panic)
|
||||||
return NMI_DONE;
|
return NMI_DONE;
|
||||||
|
|
||||||
if (atomic_cmpxchg(&nmi_cpu, -1, raw_smp_processor_id()) != -1)
|
old_cpu = -1;
|
||||||
|
this_cpu = raw_smp_processor_id();
|
||||||
|
if (!atomic_try_cmpxchg(&nmi_cpu, &old_cpu, this_cpu))
|
||||||
return NMI_HANDLED;
|
return NMI_HANDLED;
|
||||||
|
|
||||||
return NMI_DONE;
|
return NMI_DONE;
|
||||||
|
@ -425,6 +425,8 @@ void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors)
|
|||||||
|
|
||||||
void bdev_add(struct block_device *bdev, dev_t dev)
|
void bdev_add(struct block_device *bdev, dev_t dev)
|
||||||
{
|
{
|
||||||
|
if (bdev_stable_writes(bdev))
|
||||||
|
mapping_set_stable_writes(bdev->bd_inode->i_mapping);
|
||||||
bdev->bd_dev = dev;
|
bdev->bd_dev = dev;
|
||||||
bdev->bd_inode->i_rdev = dev;
|
bdev->bd_inode->i_rdev = dev;
|
||||||
bdev->bd_inode->i_ino = dev;
|
bdev->bd_inode->i_ino = dev;
|
||||||
|
@ -577,6 +577,7 @@ static void blkg_destroy_all(struct gendisk *disk)
|
|||||||
struct request_queue *q = disk->queue;
|
struct request_queue *q = disk->queue;
|
||||||
struct blkcg_gq *blkg, *n;
|
struct blkcg_gq *blkg, *n;
|
||||||
int count = BLKG_DESTROY_BATCH_SIZE;
|
int count = BLKG_DESTROY_BATCH_SIZE;
|
||||||
|
int i;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
spin_lock_irq(&q->queue_lock);
|
spin_lock_irq(&q->queue_lock);
|
||||||
@ -602,6 +603,18 @@ restart:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark policy deactivated since policy offline has been done, and
|
||||||
|
* the free is scheduled, so future blkcg_deactivate_policy() can
|
||||||
|
* be bypassed
|
||||||
|
*/
|
||||||
|
for (i = 0; i < BLKCG_MAX_POLS; i++) {
|
||||||
|
struct blkcg_policy *pol = blkcg_policy[i];
|
||||||
|
|
||||||
|
if (pol)
|
||||||
|
__clear_bit(pol->plid, q->blkcg_pols);
|
||||||
|
}
|
||||||
|
|
||||||
q->root_blkg = NULL;
|
q->root_blkg = NULL;
|
||||||
spin_unlock_irq(&q->queue_lock);
|
spin_unlock_irq(&q->queue_lock);
|
||||||
}
|
}
|
||||||
|
@ -249,8 +249,6 @@ static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
|
|||||||
{
|
{
|
||||||
struct blkcg_gq *blkg;
|
struct blkcg_gq *blkg;
|
||||||
|
|
||||||
WARN_ON_ONCE(!rcu_read_lock_held());
|
|
||||||
|
|
||||||
if (blkcg == &blkcg_root)
|
if (blkcg == &blkcg_root)
|
||||||
return q->root_blkg;
|
return q->root_blkg;
|
||||||
|
|
||||||
|
@ -163,38 +163,15 @@ EXPORT_SYMBOL(blk_pre_runtime_resume);
|
|||||||
* @q: the queue of the device
|
* @q: the queue of the device
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* For historical reasons, this routine merely calls blk_set_runtime_active()
|
* Restart the queue of a runtime suspended device. It does this regardless
|
||||||
* to do the real work of restarting the queue. It does this regardless of
|
* of whether the device's runtime-resume succeeded; even if it failed the
|
||||||
* whether the device's runtime-resume succeeded; even if it failed the
|
|
||||||
* driver or error handler will need to communicate with the device.
|
* driver or error handler will need to communicate with the device.
|
||||||
*
|
*
|
||||||
* This function should be called near the end of the device's
|
* This function should be called near the end of the device's
|
||||||
* runtime_resume callback.
|
* runtime_resume callback to correct queue runtime PM status and re-enable
|
||||||
|
* peeking requests from the queue.
|
||||||
*/
|
*/
|
||||||
void blk_post_runtime_resume(struct request_queue *q)
|
void blk_post_runtime_resume(struct request_queue *q)
|
||||||
{
|
|
||||||
blk_set_runtime_active(q);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(blk_post_runtime_resume);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* blk_set_runtime_active - Force runtime status of the queue to be active
|
|
||||||
* @q: the queue of the device
|
|
||||||
*
|
|
||||||
* If the device is left runtime suspended during system suspend the resume
|
|
||||||
* hook typically resumes the device and corrects runtime status
|
|
||||||
* accordingly. However, that does not affect the queue runtime PM status
|
|
||||||
* which is still "suspended". This prevents processing requests from the
|
|
||||||
* queue.
|
|
||||||
*
|
|
||||||
* This function can be used in driver's resume hook to correct queue
|
|
||||||
* runtime PM status and re-enable peeking requests from the queue. It
|
|
||||||
* should be called before first request is added to the queue.
|
|
||||||
*
|
|
||||||
* This function is also called by blk_post_runtime_resume() for
|
|
||||||
* runtime resumes. It does everything necessary to restart the queue.
|
|
||||||
*/
|
|
||||||
void blk_set_runtime_active(struct request_queue *q)
|
|
||||||
{
|
{
|
||||||
int old_status;
|
int old_status;
|
||||||
|
|
||||||
@ -211,4 +188,4 @@ void blk_set_runtime_active(struct request_queue *q)
|
|||||||
if (old_status != RPM_ACTIVE)
|
if (old_status != RPM_ACTIVE)
|
||||||
blk_clear_pm_only(q);
|
blk_clear_pm_only(q);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(blk_set_runtime_active);
|
EXPORT_SYMBOL(blk_post_runtime_resume);
|
||||||
|
@ -1320,6 +1320,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global)
|
|||||||
tg_bps_limit(tg, READ), tg_bps_limit(tg, WRITE),
|
tg_bps_limit(tg, READ), tg_bps_limit(tg, WRITE),
|
||||||
tg_iops_limit(tg, READ), tg_iops_limit(tg, WRITE));
|
tg_iops_limit(tg, READ), tg_iops_limit(tg, WRITE));
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
/*
|
/*
|
||||||
* Update has_rules[] flags for the updated tg's subtree. A tg is
|
* Update has_rules[] flags for the updated tg's subtree. A tg is
|
||||||
* considered to have rules if either the tg itself or any of its
|
* considered to have rules if either the tg itself or any of its
|
||||||
@ -1347,6 +1348,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global)
|
|||||||
this_tg->latency_target = max(this_tg->latency_target,
|
this_tg->latency_target = max(this_tg->latency_target,
|
||||||
parent_tg->latency_target);
|
parent_tg->latency_target);
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're already holding queue_lock and know @tg is valid. Let's
|
* We're already holding queue_lock and know @tg is valid. Let's
|
||||||
|
@ -504,6 +504,16 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev)
|
||||||
|
{
|
||||||
|
ivpu_boot_dpu_active_drive(vdev, false);
|
||||||
|
ivpu_boot_pwr_island_isolation_drive(vdev, true);
|
||||||
|
ivpu_boot_pwr_island_trickle_drive(vdev, false);
|
||||||
|
ivpu_boot_pwr_island_drive(vdev, false);
|
||||||
|
|
||||||
|
return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
|
static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
|
||||||
{
|
{
|
||||||
u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
|
u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
|
||||||
@ -602,25 +612,17 @@ static int ivpu_hw_37xx_info_init(struct ivpu_device *vdev)
|
|||||||
|
|
||||||
static int ivpu_hw_37xx_reset(struct ivpu_device *vdev)
|
static int ivpu_hw_37xx_reset(struct ivpu_device *vdev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
u32 val;
|
|
||||||
|
|
||||||
if (IVPU_WA(punit_disabled))
|
if (ivpu_boot_pwr_domain_disable(vdev)) {
|
||||||
return 0;
|
ivpu_err(vdev, "Failed to disable power domain\n");
|
||||||
|
ret = -EIO;
|
||||||
ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
|
|
||||||
if (ret) {
|
|
||||||
ivpu_err(vdev, "Timed out waiting for TRIGGER bit\n");
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val = REGB_RD32(VPU_37XX_BUTTRESS_VPU_IP_RESET);
|
if (ivpu_pll_disable(vdev)) {
|
||||||
val = REG_SET_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, val);
|
ivpu_err(vdev, "Failed to disable PLL\n");
|
||||||
REGB_WR32(VPU_37XX_BUTTRESS_VPU_IP_RESET, val);
|
ret = -EIO;
|
||||||
|
}
|
||||||
ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
|
|
||||||
if (ret)
|
|
||||||
ivpu_err(vdev, "Timed out waiting for RESET completion\n");
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -733,14 +735,11 @@ static int ivpu_hw_37xx_power_down(struct ivpu_device *vdev)
|
|||||||
|
|
||||||
ivpu_hw_37xx_save_d0i3_entry_timestamp(vdev);
|
ivpu_hw_37xx_save_d0i3_entry_timestamp(vdev);
|
||||||
|
|
||||||
if (!ivpu_hw_37xx_is_idle(vdev)) {
|
if (!ivpu_hw_37xx_is_idle(vdev))
|
||||||
ivpu_warn(vdev, "VPU not idle during power down\n");
|
ivpu_warn(vdev, "VPU not idle during power down\n");
|
||||||
if (ivpu_hw_37xx_reset(vdev))
|
|
||||||
ivpu_warn(vdev, "Failed to reset the VPU\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ivpu_pll_disable(vdev)) {
|
if (ivpu_hw_37xx_reset(vdev)) {
|
||||||
ivpu_err(vdev, "Failed to disable PLL\n");
|
ivpu_err(vdev, "Failed to reset VPU\n");
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2031,7 +2031,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
|||||||
* HP ZBook Fury 16 G10 requires ACPI video's child devices have _PS0
|
* HP ZBook Fury 16 G10 requires ACPI video's child devices have _PS0
|
||||||
* evaluated to have functional panel brightness control.
|
* evaluated to have functional panel brightness control.
|
||||||
*/
|
*/
|
||||||
acpi_device_fix_up_power_extended(device);
|
acpi_device_fix_up_power_children(device);
|
||||||
|
|
||||||
pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n",
|
pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n",
|
||||||
ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
|
ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
|
||||||
|
@ -397,6 +397,19 @@ void acpi_device_fix_up_power_extended(struct acpi_device *adev)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_extended);
|
EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_extended);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acpi_device_fix_up_power_children - Force a device's children into D0.
|
||||||
|
* @adev: Parent device object whose children's power state is to be fixed up.
|
||||||
|
*
|
||||||
|
* Call acpi_device_fix_up_power() for @adev's children so long as they
|
||||||
|
* are reported as present and enabled.
|
||||||
|
*/
|
||||||
|
void acpi_device_fix_up_power_children(struct acpi_device *adev)
|
||||||
|
{
|
||||||
|
acpi_dev_for_each_child(adev, fix_up_power_if_applicable, NULL);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_children);
|
||||||
|
|
||||||
int acpi_device_update_power(struct acpi_device *device, int *state_p)
|
int acpi_device_update_power(struct acpi_device *device, int *state_p)
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
|
@ -592,7 +592,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
|
|||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
if (cx->entry_method == ACPI_CSTATE_HALT)
|
if (cx->entry_method == ACPI_CSTATE_HALT)
|
||||||
safe_halt();
|
raw_safe_halt();
|
||||||
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
|
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
|
||||||
io_idle(cx->address);
|
io_idle(cx->address);
|
||||||
} else
|
} else
|
||||||
|
@ -447,6 +447,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = {
|
|||||||
DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"),
|
DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
/* Asus ExpertBook B1402CVA */
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||||
|
DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
/* Asus ExpertBook B1502CBA */
|
/* Asus ExpertBook B1502CBA */
|
||||||
.matches = {
|
.matches = {
|
||||||
|
@ -82,6 +82,9 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
|
|||||||
if (pnp_port_valid(idev, 1)) {
|
if (pnp_port_valid(idev, 1)) {
|
||||||
ctl_addr = devm_ioport_map(&idev->dev,
|
ctl_addr = devm_ioport_map(&idev->dev,
|
||||||
pnp_port_start(idev, 1), 1);
|
pnp_port_start(idev, 1), 1);
|
||||||
|
if (!ctl_addr)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
ap->ioaddr.altstatus_addr = ctl_addr;
|
ap->ioaddr.altstatus_addr = ctl_addr;
|
||||||
ap->ioaddr.ctl_addr = ctl_addr;
|
ap->ioaddr.ctl_addr = ctl_addr;
|
||||||
ap->ops = &isapnp_port_ops;
|
ap->ops = &isapnp_port_ops;
|
||||||
|
@ -67,6 +67,7 @@ struct nbd_sock {
|
|||||||
struct recv_thread_args {
|
struct recv_thread_args {
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
struct nbd_device *nbd;
|
struct nbd_device *nbd;
|
||||||
|
struct nbd_sock *nsock;
|
||||||
int index;
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -395,6 +396,22 @@ static u32 req_to_nbd_cmd_type(struct request *req)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct nbd_config *nbd_get_config_unlocked(struct nbd_device *nbd)
|
||||||
|
{
|
||||||
|
if (refcount_inc_not_zero(&nbd->config_refs)) {
|
||||||
|
/*
|
||||||
|
* Add smp_mb__after_atomic to ensure that reading nbd->config_refs
|
||||||
|
* and reading nbd->config is ordered. The pair is the barrier in
|
||||||
|
* nbd_alloc_and_init_config(), avoid nbd->config_refs is set
|
||||||
|
* before nbd->config.
|
||||||
|
*/
|
||||||
|
smp_mb__after_atomic();
|
||||||
|
return nbd->config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
|
static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
|
||||||
{
|
{
|
||||||
struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
|
struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
|
||||||
@ -409,13 +426,13 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
|
|||||||
return BLK_EH_DONE;
|
return BLK_EH_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!refcount_inc_not_zero(&nbd->config_refs)) {
|
config = nbd_get_config_unlocked(nbd);
|
||||||
|
if (!config) {
|
||||||
cmd->status = BLK_STS_TIMEOUT;
|
cmd->status = BLK_STS_TIMEOUT;
|
||||||
__clear_bit(NBD_CMD_INFLIGHT, &cmd->flags);
|
__clear_bit(NBD_CMD_INFLIGHT, &cmd->flags);
|
||||||
mutex_unlock(&cmd->lock);
|
mutex_unlock(&cmd->lock);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
config = nbd->config;
|
|
||||||
|
|
||||||
if (config->num_connections > 1 ||
|
if (config->num_connections > 1 ||
|
||||||
(config->num_connections == 1 && nbd->tag_set.timeout)) {
|
(config->num_connections == 1 && nbd->tag_set.timeout)) {
|
||||||
@ -489,15 +506,9 @@ done:
|
|||||||
return BLK_EH_DONE;
|
return BLK_EH_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
|
||||||
* Send or receive packet. Return a positive value on success and
|
struct iov_iter *iter, int msg_flags, int *sent)
|
||||||
* negtive value on failue, and never return 0.
|
|
||||||
*/
|
|
||||||
static int sock_xmit(struct nbd_device *nbd, int index, int send,
|
|
||||||
struct iov_iter *iter, int msg_flags, int *sent)
|
|
||||||
{
|
{
|
||||||
struct nbd_config *config = nbd->config;
|
|
||||||
struct socket *sock = config->socks[index]->sock;
|
|
||||||
int result;
|
int result;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
unsigned int noreclaim_flag;
|
unsigned int noreclaim_flag;
|
||||||
@ -540,6 +551,19 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send or receive packet. Return a positive value on success and
|
||||||
|
* negtive value on failure, and never return 0.
|
||||||
|
*/
|
||||||
|
static int sock_xmit(struct nbd_device *nbd, int index, int send,
|
||||||
|
struct iov_iter *iter, int msg_flags, int *sent)
|
||||||
|
{
|
||||||
|
struct nbd_config *config = nbd->config;
|
||||||
|
struct socket *sock = config->socks[index]->sock;
|
||||||
|
|
||||||
|
return __sock_xmit(nbd, sock, send, iter, msg_flags, sent);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Different settings for sk->sk_sndtimeo can result in different return values
|
* Different settings for sk->sk_sndtimeo can result in different return values
|
||||||
* if there is a signal pending when we enter sendmsg, because reasons?
|
* if there is a signal pending when we enter sendmsg, because reasons?
|
||||||
@ -696,7 +720,7 @@ out:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nbd_read_reply(struct nbd_device *nbd, int index,
|
static int nbd_read_reply(struct nbd_device *nbd, struct socket *sock,
|
||||||
struct nbd_reply *reply)
|
struct nbd_reply *reply)
|
||||||
{
|
{
|
||||||
struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)};
|
struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)};
|
||||||
@ -705,7 +729,7 @@ static int nbd_read_reply(struct nbd_device *nbd, int index,
|
|||||||
|
|
||||||
reply->magic = 0;
|
reply->magic = 0;
|
||||||
iov_iter_kvec(&to, ITER_DEST, &iov, 1, sizeof(*reply));
|
iov_iter_kvec(&to, ITER_DEST, &iov, 1, sizeof(*reply));
|
||||||
result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL);
|
result = __sock_xmit(nbd, sock, 0, &to, MSG_WAITALL, NULL);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
if (!nbd_disconnected(nbd->config))
|
if (!nbd_disconnected(nbd->config))
|
||||||
dev_err(disk_to_dev(nbd->disk),
|
dev_err(disk_to_dev(nbd->disk),
|
||||||
@ -829,14 +853,14 @@ static void recv_work(struct work_struct *work)
|
|||||||
struct nbd_device *nbd = args->nbd;
|
struct nbd_device *nbd = args->nbd;
|
||||||
struct nbd_config *config = nbd->config;
|
struct nbd_config *config = nbd->config;
|
||||||
struct request_queue *q = nbd->disk->queue;
|
struct request_queue *q = nbd->disk->queue;
|
||||||
struct nbd_sock *nsock;
|
struct nbd_sock *nsock = args->nsock;
|
||||||
struct nbd_cmd *cmd;
|
struct nbd_cmd *cmd;
|
||||||
struct request *rq;
|
struct request *rq;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
struct nbd_reply reply;
|
struct nbd_reply reply;
|
||||||
|
|
||||||
if (nbd_read_reply(nbd, args->index, &reply))
|
if (nbd_read_reply(nbd, nsock->sock, &reply))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -871,7 +895,6 @@ static void recv_work(struct work_struct *work)
|
|||||||
percpu_ref_put(&q->q_usage_counter);
|
percpu_ref_put(&q->q_usage_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsock = config->socks[args->index];
|
|
||||||
mutex_lock(&nsock->tx_lock);
|
mutex_lock(&nsock->tx_lock);
|
||||||
nbd_mark_nsock_dead(nbd, nsock, 1);
|
nbd_mark_nsock_dead(nbd, nsock, 1);
|
||||||
mutex_unlock(&nsock->tx_lock);
|
mutex_unlock(&nsock->tx_lock);
|
||||||
@ -977,12 +1000,12 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
|
|||||||
struct nbd_sock *nsock;
|
struct nbd_sock *nsock;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!refcount_inc_not_zero(&nbd->config_refs)) {
|
config = nbd_get_config_unlocked(nbd);
|
||||||
|
if (!config) {
|
||||||
dev_err_ratelimited(disk_to_dev(nbd->disk),
|
dev_err_ratelimited(disk_to_dev(nbd->disk),
|
||||||
"Socks array is empty\n");
|
"Socks array is empty\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
config = nbd->config;
|
|
||||||
|
|
||||||
if (index >= config->num_connections) {
|
if (index >= config->num_connections) {
|
||||||
dev_err_ratelimited(disk_to_dev(nbd->disk),
|
dev_err_ratelimited(disk_to_dev(nbd->disk),
|
||||||
@ -1215,6 +1238,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
|
|||||||
INIT_WORK(&args->work, recv_work);
|
INIT_WORK(&args->work, recv_work);
|
||||||
args->index = i;
|
args->index = i;
|
||||||
args->nbd = nbd;
|
args->nbd = nbd;
|
||||||
|
args->nsock = nsock;
|
||||||
nsock->cookie++;
|
nsock->cookie++;
|
||||||
mutex_unlock(&nsock->tx_lock);
|
mutex_unlock(&nsock->tx_lock);
|
||||||
sockfd_put(old);
|
sockfd_put(old);
|
||||||
@ -1397,6 +1421,7 @@ static int nbd_start_device(struct nbd_device *nbd)
|
|||||||
refcount_inc(&nbd->config_refs);
|
refcount_inc(&nbd->config_refs);
|
||||||
INIT_WORK(&args->work, recv_work);
|
INIT_WORK(&args->work, recv_work);
|
||||||
args->nbd = nbd;
|
args->nbd = nbd;
|
||||||
|
args->nsock = config->socks[i];
|
||||||
args->index = i;
|
args->index = i;
|
||||||
queue_work(nbd->recv_workq, &args->work);
|
queue_work(nbd->recv_workq, &args->work);
|
||||||
}
|
}
|
||||||
@ -1530,17 +1555,20 @@ static int nbd_ioctl(struct block_device *bdev, blk_mode_t mode,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct nbd_config *nbd_alloc_config(void)
|
static int nbd_alloc_and_init_config(struct nbd_device *nbd)
|
||||||
{
|
{
|
||||||
struct nbd_config *config;
|
struct nbd_config *config;
|
||||||
|
|
||||||
|
if (WARN_ON(nbd->config))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (!try_module_get(THIS_MODULE))
|
if (!try_module_get(THIS_MODULE))
|
||||||
return ERR_PTR(-ENODEV);
|
return -ENODEV;
|
||||||
|
|
||||||
config = kzalloc(sizeof(struct nbd_config), GFP_NOFS);
|
config = kzalloc(sizeof(struct nbd_config), GFP_NOFS);
|
||||||
if (!config) {
|
if (!config) {
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
return ERR_PTR(-ENOMEM);
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_set(&config->recv_threads, 0);
|
atomic_set(&config->recv_threads, 0);
|
||||||
@ -1548,12 +1576,24 @@ static struct nbd_config *nbd_alloc_config(void)
|
|||||||
init_waitqueue_head(&config->conn_wait);
|
init_waitqueue_head(&config->conn_wait);
|
||||||
config->blksize_bits = NBD_DEF_BLKSIZE_BITS;
|
config->blksize_bits = NBD_DEF_BLKSIZE_BITS;
|
||||||
atomic_set(&config->live_connections, 0);
|
atomic_set(&config->live_connections, 0);
|
||||||
return config;
|
|
||||||
|
nbd->config = config;
|
||||||
|
/*
|
||||||
|
* Order refcount_set(&nbd->config_refs, 1) and nbd->config assignment,
|
||||||
|
* its pair is the barrier in nbd_get_config_unlocked().
|
||||||
|
* So nbd_get_config_unlocked() won't see nbd->config as null after
|
||||||
|
* refcount_inc_not_zero() succeed.
|
||||||
|
*/
|
||||||
|
smp_mb__before_atomic();
|
||||||
|
refcount_set(&nbd->config_refs, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nbd_open(struct gendisk *disk, blk_mode_t mode)
|
static int nbd_open(struct gendisk *disk, blk_mode_t mode)
|
||||||
{
|
{
|
||||||
struct nbd_device *nbd;
|
struct nbd_device *nbd;
|
||||||
|
struct nbd_config *config;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&nbd_index_mutex);
|
mutex_lock(&nbd_index_mutex);
|
||||||
@ -1566,27 +1606,25 @@ static int nbd_open(struct gendisk *disk, blk_mode_t mode)
|
|||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!refcount_inc_not_zero(&nbd->config_refs)) {
|
|
||||||
struct nbd_config *config;
|
|
||||||
|
|
||||||
|
config = nbd_get_config_unlocked(nbd);
|
||||||
|
if (!config) {
|
||||||
mutex_lock(&nbd->config_lock);
|
mutex_lock(&nbd->config_lock);
|
||||||
if (refcount_inc_not_zero(&nbd->config_refs)) {
|
if (refcount_inc_not_zero(&nbd->config_refs)) {
|
||||||
mutex_unlock(&nbd->config_lock);
|
mutex_unlock(&nbd->config_lock);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
config = nbd_alloc_config();
|
ret = nbd_alloc_and_init_config(nbd);
|
||||||
if (IS_ERR(config)) {
|
if (ret) {
|
||||||
ret = PTR_ERR(config);
|
|
||||||
mutex_unlock(&nbd->config_lock);
|
mutex_unlock(&nbd->config_lock);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
nbd->config = config;
|
|
||||||
refcount_set(&nbd->config_refs, 1);
|
|
||||||
refcount_inc(&nbd->refs);
|
refcount_inc(&nbd->refs);
|
||||||
mutex_unlock(&nbd->config_lock);
|
mutex_unlock(&nbd->config_lock);
|
||||||
if (max_part)
|
if (max_part)
|
||||||
set_bit(GD_NEED_PART_SCAN, &disk->state);
|
set_bit(GD_NEED_PART_SCAN, &disk->state);
|
||||||
} else if (nbd_disconnected(nbd->config)) {
|
} else if (nbd_disconnected(config)) {
|
||||||
if (max_part)
|
if (max_part)
|
||||||
set_bit(GD_NEED_PART_SCAN, &disk->state);
|
set_bit(GD_NEED_PART_SCAN, &disk->state);
|
||||||
}
|
}
|
||||||
@ -1990,22 +2028,17 @@ again:
|
|||||||
pr_err("nbd%d already in use\n", index);
|
pr_err("nbd%d already in use\n", index);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
if (WARN_ON(nbd->config)) {
|
|
||||||
mutex_unlock(&nbd->config_lock);
|
ret = nbd_alloc_and_init_config(nbd);
|
||||||
nbd_put(nbd);
|
if (ret) {
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
config = nbd_alloc_config();
|
|
||||||
if (IS_ERR(config)) {
|
|
||||||
mutex_unlock(&nbd->config_lock);
|
mutex_unlock(&nbd->config_lock);
|
||||||
nbd_put(nbd);
|
nbd_put(nbd);
|
||||||
pr_err("couldn't allocate config\n");
|
pr_err("couldn't allocate config\n");
|
||||||
return PTR_ERR(config);
|
return ret;
|
||||||
}
|
}
|
||||||
nbd->config = config;
|
|
||||||
refcount_set(&nbd->config_refs, 1);
|
|
||||||
set_bit(NBD_RT_BOUND, &config->runtime_flags);
|
|
||||||
|
|
||||||
|
config = nbd->config;
|
||||||
|
set_bit(NBD_RT_BOUND, &config->runtime_flags);
|
||||||
ret = nbd_genl_size_set(info, nbd);
|
ret = nbd_genl_size_set(info, nbd);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
@ -2208,7 +2241,8 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
|
|||||||
}
|
}
|
||||||
mutex_unlock(&nbd_index_mutex);
|
mutex_unlock(&nbd_index_mutex);
|
||||||
|
|
||||||
if (!refcount_inc_not_zero(&nbd->config_refs)) {
|
config = nbd_get_config_unlocked(nbd);
|
||||||
|
if (!config) {
|
||||||
dev_err(nbd_to_dev(nbd),
|
dev_err(nbd_to_dev(nbd),
|
||||||
"not configured, cannot reconfigure\n");
|
"not configured, cannot reconfigure\n");
|
||||||
nbd_put(nbd);
|
nbd_put(nbd);
|
||||||
@ -2216,7 +2250,6 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&nbd->config_lock);
|
mutex_lock(&nbd->config_lock);
|
||||||
config = nbd->config;
|
|
||||||
if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) ||
|
if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) ||
|
||||||
!nbd->pid) {
|
!nbd->pid) {
|
||||||
dev_err(nbd_to_dev(nbd),
|
dev_err(nbd_to_dev(nbd),
|
||||||
|
@ -1464,19 +1464,13 @@ blk_status_t null_process_cmd(struct nullb_cmd *cmd, enum req_op op,
|
|||||||
return BLK_STS_OK;
|
return BLK_STS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector,
|
static void null_handle_cmd(struct nullb_cmd *cmd, sector_t sector,
|
||||||
sector_t nr_sectors, enum req_op op)
|
sector_t nr_sectors, enum req_op op)
|
||||||
{
|
{
|
||||||
struct nullb_device *dev = cmd->nq->dev;
|
struct nullb_device *dev = cmd->nq->dev;
|
||||||
struct nullb *nullb = dev->nullb;
|
struct nullb *nullb = dev->nullb;
|
||||||
blk_status_t sts;
|
blk_status_t sts;
|
||||||
|
|
||||||
if (test_bit(NULLB_DEV_FL_THROTTLED, &dev->flags)) {
|
|
||||||
sts = null_handle_throttled(cmd);
|
|
||||||
if (sts != BLK_STS_OK)
|
|
||||||
return sts;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op == REQ_OP_FLUSH) {
|
if (op == REQ_OP_FLUSH) {
|
||||||
cmd->error = errno_to_blk_status(null_handle_flush(nullb));
|
cmd->error = errno_to_blk_status(null_handle_flush(nullb));
|
||||||
goto out;
|
goto out;
|
||||||
@ -1493,7 +1487,6 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
nullb_complete_cmd(cmd);
|
nullb_complete_cmd(cmd);
|
||||||
return BLK_STS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum hrtimer_restart nullb_bwtimer_fn(struct hrtimer *timer)
|
static enum hrtimer_restart nullb_bwtimer_fn(struct hrtimer *timer)
|
||||||
@ -1724,8 +1717,6 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||||||
cmd->fake_timeout = should_timeout_request(rq) ||
|
cmd->fake_timeout = should_timeout_request(rq) ||
|
||||||
blk_should_fake_timeout(rq->q);
|
blk_should_fake_timeout(rq->q);
|
||||||
|
|
||||||
blk_mq_start_request(rq);
|
|
||||||
|
|
||||||
if (should_requeue_request(rq)) {
|
if (should_requeue_request(rq)) {
|
||||||
/*
|
/*
|
||||||
* Alternate between hitting the core BUSY path, and the
|
* Alternate between hitting the core BUSY path, and the
|
||||||
@ -1738,6 +1729,15 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||||||
return BLK_STS_OK;
|
return BLK_STS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (test_bit(NULLB_DEV_FL_THROTTLED, &nq->dev->flags)) {
|
||||||
|
blk_status_t sts = null_handle_throttled(cmd);
|
||||||
|
|
||||||
|
if (sts != BLK_STS_OK)
|
||||||
|
return sts;
|
||||||
|
}
|
||||||
|
|
||||||
|
blk_mq_start_request(rq);
|
||||||
|
|
||||||
if (is_poll) {
|
if (is_poll) {
|
||||||
spin_lock(&nq->poll_lock);
|
spin_lock(&nq->poll_lock);
|
||||||
list_add_tail(&rq->queuelist, &nq->poll_list);
|
list_add_tail(&rq->queuelist, &nq->poll_list);
|
||||||
@ -1747,7 +1747,8 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||||||
if (cmd->fake_timeout)
|
if (cmd->fake_timeout)
|
||||||
return BLK_STS_OK;
|
return BLK_STS_OK;
|
||||||
|
|
||||||
return null_handle_cmd(cmd, sector, nr_sectors, req_op(rq));
|
null_handle_cmd(cmd, sector, nr_sectors, req_op(rq));
|
||||||
|
return BLK_STS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void null_queue_rqs(struct request **rqlist)
|
static void null_queue_rqs(struct request **rqlist)
|
||||||
|
@ -1093,9 +1093,10 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
||||||
DPLL_CMD_PIN_ID_GET);
|
DPLL_CMD_PIN_ID_GET);
|
||||||
if (!hdr)
|
if (!hdr) {
|
||||||
|
nlmsg_free(msg);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
pin = dpll_pin_find_from_nlattr(info);
|
pin = dpll_pin_find_from_nlattr(info);
|
||||||
if (!IS_ERR(pin)) {
|
if (!IS_ERR(pin)) {
|
||||||
ret = dpll_msg_add_pin_handle(msg, pin);
|
ret = dpll_msg_add_pin_handle(msg, pin);
|
||||||
@ -1123,8 +1124,10 @@ int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
||||||
DPLL_CMD_PIN_GET);
|
DPLL_CMD_PIN_GET);
|
||||||
if (!hdr)
|
if (!hdr) {
|
||||||
|
nlmsg_free(msg);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
ret = dpll_cmd_pin_get_one(msg, pin, info->extack);
|
ret = dpll_cmd_pin_get_one(msg, pin, info->extack);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
nlmsg_free(msg);
|
nlmsg_free(msg);
|
||||||
@ -1256,8 +1259,10 @@ int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
||||||
DPLL_CMD_DEVICE_ID_GET);
|
DPLL_CMD_DEVICE_ID_GET);
|
||||||
if (!hdr)
|
if (!hdr) {
|
||||||
|
nlmsg_free(msg);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
dpll = dpll_device_find_from_nlattr(info);
|
dpll = dpll_device_find_from_nlattr(info);
|
||||||
if (!IS_ERR(dpll)) {
|
if (!IS_ERR(dpll)) {
|
||||||
@ -1284,8 +1289,10 @@ int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
|
||||||
DPLL_CMD_DEVICE_GET);
|
DPLL_CMD_DEVICE_GET);
|
||||||
if (!hdr)
|
if (!hdr) {
|
||||||
|
nlmsg_free(msg);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
ret = dpll_device_get_one(dpll, msg, info->extack);
|
ret = dpll_device_get_one(dpll, msg, info->extack);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -174,6 +174,17 @@ to_ast_sil164_connector(struct drm_connector *connector)
|
|||||||
return container_of(connector, struct ast_sil164_connector, base);
|
return container_of(connector, struct ast_sil164_connector, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ast_bmc_connector {
|
||||||
|
struct drm_connector base;
|
||||||
|
struct drm_connector *physical_connector;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct ast_bmc_connector *
|
||||||
|
to_ast_bmc_connector(struct drm_connector *connector)
|
||||||
|
{
|
||||||
|
return container_of(connector, struct ast_bmc_connector, base);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Device
|
* Device
|
||||||
*/
|
*/
|
||||||
@ -218,7 +229,7 @@ struct ast_device {
|
|||||||
} astdp;
|
} astdp;
|
||||||
struct {
|
struct {
|
||||||
struct drm_encoder encoder;
|
struct drm_encoder encoder;
|
||||||
struct drm_connector connector;
|
struct ast_bmc_connector bmc_connector;
|
||||||
} bmc;
|
} bmc;
|
||||||
} output;
|
} output;
|
||||||
|
|
||||||
|
@ -1767,6 +1767,30 @@ static const struct drm_encoder_funcs ast_bmc_encoder_funcs = {
|
|||||||
.destroy = drm_encoder_cleanup,
|
.destroy = drm_encoder_cleanup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int ast_bmc_connector_helper_detect_ctx(struct drm_connector *connector,
|
||||||
|
struct drm_modeset_acquire_ctx *ctx,
|
||||||
|
bool force)
|
||||||
|
{
|
||||||
|
struct ast_bmc_connector *bmc_connector = to_ast_bmc_connector(connector);
|
||||||
|
struct drm_connector *physical_connector = bmc_connector->physical_connector;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Most user-space compositors cannot handle more than one connected
|
||||||
|
* connector per CRTC. Hence, we only mark the BMC as connected if the
|
||||||
|
* physical connector is disconnected. If the physical connector's status
|
||||||
|
* is connected or unknown, the BMC remains disconnected. This has no
|
||||||
|
* effect on the output of the BMC.
|
||||||
|
*
|
||||||
|
* FIXME: Remove this logic once user-space compositors can handle more
|
||||||
|
* than one connector per CRTC. The BMC should always be connected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (physical_connector && physical_connector->status == connector_status_disconnected)
|
||||||
|
return connector_status_connected;
|
||||||
|
|
||||||
|
return connector_status_disconnected;
|
||||||
|
}
|
||||||
|
|
||||||
static int ast_bmc_connector_helper_get_modes(struct drm_connector *connector)
|
static int ast_bmc_connector_helper_get_modes(struct drm_connector *connector)
|
||||||
{
|
{
|
||||||
return drm_add_modes_noedid(connector, 4096, 4096);
|
return drm_add_modes_noedid(connector, 4096, 4096);
|
||||||
@ -1774,6 +1798,7 @@ static int ast_bmc_connector_helper_get_modes(struct drm_connector *connector)
|
|||||||
|
|
||||||
static const struct drm_connector_helper_funcs ast_bmc_connector_helper_funcs = {
|
static const struct drm_connector_helper_funcs ast_bmc_connector_helper_funcs = {
|
||||||
.get_modes = ast_bmc_connector_helper_get_modes,
|
.get_modes = ast_bmc_connector_helper_get_modes,
|
||||||
|
.detect_ctx = ast_bmc_connector_helper_detect_ctx,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct drm_connector_funcs ast_bmc_connector_funcs = {
|
static const struct drm_connector_funcs ast_bmc_connector_funcs = {
|
||||||
@ -1784,12 +1809,33 @@ static const struct drm_connector_funcs ast_bmc_connector_funcs = {
|
|||||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ast_bmc_output_init(struct ast_device *ast)
|
static int ast_bmc_connector_init(struct drm_device *dev,
|
||||||
|
struct ast_bmc_connector *bmc_connector,
|
||||||
|
struct drm_connector *physical_connector)
|
||||||
|
{
|
||||||
|
struct drm_connector *connector = &bmc_connector->base;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = drm_connector_init(dev, connector, &ast_bmc_connector_funcs,
|
||||||
|
DRM_MODE_CONNECTOR_VIRTUAL);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
drm_connector_helper_add(connector, &ast_bmc_connector_helper_funcs);
|
||||||
|
|
||||||
|
bmc_connector->physical_connector = physical_connector;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ast_bmc_output_init(struct ast_device *ast,
|
||||||
|
struct drm_connector *physical_connector)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = &ast->base;
|
struct drm_device *dev = &ast->base;
|
||||||
struct drm_crtc *crtc = &ast->crtc;
|
struct drm_crtc *crtc = &ast->crtc;
|
||||||
struct drm_encoder *encoder = &ast->output.bmc.encoder;
|
struct drm_encoder *encoder = &ast->output.bmc.encoder;
|
||||||
struct drm_connector *connector = &ast->output.bmc.connector;
|
struct ast_bmc_connector *bmc_connector = &ast->output.bmc.bmc_connector;
|
||||||
|
struct drm_connector *connector = &bmc_connector->base;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = drm_encoder_init(dev, encoder,
|
ret = drm_encoder_init(dev, encoder,
|
||||||
@ -1799,13 +1845,10 @@ static int ast_bmc_output_init(struct ast_device *ast)
|
|||||||
return ret;
|
return ret;
|
||||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||||
|
|
||||||
ret = drm_connector_init(dev, connector, &ast_bmc_connector_funcs,
|
ret = ast_bmc_connector_init(dev, bmc_connector, physical_connector);
|
||||||
DRM_MODE_CONNECTOR_VIRTUAL);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
drm_connector_helper_add(connector, &ast_bmc_connector_helper_funcs);
|
|
||||||
|
|
||||||
ret = drm_connector_attach_encoder(connector, encoder);
|
ret = drm_connector_attach_encoder(connector, encoder);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -1864,6 +1907,7 @@ static const struct drm_mode_config_funcs ast_mode_config_funcs = {
|
|||||||
int ast_mode_config_init(struct ast_device *ast)
|
int ast_mode_config_init(struct ast_device *ast)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = &ast->base;
|
struct drm_device *dev = &ast->base;
|
||||||
|
struct drm_connector *physical_connector = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = drmm_mode_config_init(dev);
|
ret = drmm_mode_config_init(dev);
|
||||||
@ -1904,23 +1948,27 @@ int ast_mode_config_init(struct ast_device *ast)
|
|||||||
ret = ast_vga_output_init(ast);
|
ret = ast_vga_output_init(ast);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
physical_connector = &ast->output.vga.vga_connector.base;
|
||||||
}
|
}
|
||||||
if (ast->tx_chip_types & AST_TX_SIL164_BIT) {
|
if (ast->tx_chip_types & AST_TX_SIL164_BIT) {
|
||||||
ret = ast_sil164_output_init(ast);
|
ret = ast_sil164_output_init(ast);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
physical_connector = &ast->output.sil164.sil164_connector.base;
|
||||||
}
|
}
|
||||||
if (ast->tx_chip_types & AST_TX_DP501_BIT) {
|
if (ast->tx_chip_types & AST_TX_DP501_BIT) {
|
||||||
ret = ast_dp501_output_init(ast);
|
ret = ast_dp501_output_init(ast);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
physical_connector = &ast->output.dp501.connector;
|
||||||
}
|
}
|
||||||
if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
|
if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
|
||||||
ret = ast_astdp_output_init(ast);
|
ret = ast_astdp_output_init(ast);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
physical_connector = &ast->output.astdp.connector;
|
||||||
}
|
}
|
||||||
ret = ast_bmc_output_init(ast);
|
ret = ast_bmc_output_init(ast, physical_connector);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -982,8 +982,6 @@ int intel_gt_probe_all(struct drm_i915_private *i915)
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
i915_probe_error(i915, "Failed to initialize %s! (%d)\n", gtdef->name, ret);
|
i915_probe_error(i915, "Failed to initialize %s! (%d)\n", gtdef->name, ret);
|
||||||
intel_gt_release_all(i915);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1002,15 +1000,6 @@ int intel_gt_tiles_init(struct drm_i915_private *i915)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void intel_gt_release_all(struct drm_i915_private *i915)
|
|
||||||
{
|
|
||||||
struct intel_gt *gt;
|
|
||||||
unsigned int id;
|
|
||||||
|
|
||||||
for_each_gt(gt, i915, id)
|
|
||||||
i915->gt[id] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void intel_gt_info_print(const struct intel_gt_info *info,
|
void intel_gt_info_print(const struct intel_gt_info *info,
|
||||||
struct drm_printer *p)
|
struct drm_printer *p)
|
||||||
{
|
{
|
||||||
|
@ -776,7 +776,7 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
|
|
||||||
ret = i915_driver_mmio_probe(i915);
|
ret = i915_driver_mmio_probe(i915);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out_tiles_cleanup;
|
goto out_runtime_pm_put;
|
||||||
|
|
||||||
ret = i915_driver_hw_probe(i915);
|
ret = i915_driver_hw_probe(i915);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -836,8 +836,6 @@ out_cleanup_hw:
|
|||||||
i915_ggtt_driver_late_release(i915);
|
i915_ggtt_driver_late_release(i915);
|
||||||
out_cleanup_mmio:
|
out_cleanup_mmio:
|
||||||
i915_driver_mmio_release(i915);
|
i915_driver_mmio_release(i915);
|
||||||
out_tiles_cleanup:
|
|
||||||
intel_gt_release_all(i915);
|
|
||||||
out_runtime_pm_put:
|
out_runtime_pm_put:
|
||||||
enable_rpm_wakeref_asserts(&i915->runtime_pm);
|
enable_rpm_wakeref_asserts(&i915->runtime_pm);
|
||||||
i915_driver_late_release(i915);
|
i915_driver_late_release(i915);
|
||||||
|
@ -406,6 +406,7 @@ static const struct dpu_perf_cfg sc8280xp_perf_data = {
|
|||||||
.min_llcc_ib = 0,
|
.min_llcc_ib = 0,
|
||||||
.min_dram_ib = 800000,
|
.min_dram_ib = 800000,
|
||||||
.danger_lut_tbl = {0xf, 0xffff, 0x0},
|
.danger_lut_tbl = {0xf, 0xffff, 0x0},
|
||||||
|
.safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
|
||||||
.qos_lut_tbl = {
|
.qos_lut_tbl = {
|
||||||
{.nentry = ARRAY_SIZE(sc8180x_qos_linear),
|
{.nentry = ARRAY_SIZE(sc8180x_qos_linear),
|
||||||
.entries = sc8180x_qos_linear
|
.entries = sc8180x_qos_linear
|
||||||
|
@ -844,8 +844,7 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
if (mdp5_kms)
|
mdp5_destroy(mdp5_kms);
|
||||||
mdp5_destroy(mdp5_kms);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,9 +365,11 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp,
|
|||||||
/* reset video pattern flag on disconnect */
|
/* reset video pattern flag on disconnect */
|
||||||
if (!hpd) {
|
if (!hpd) {
|
||||||
dp->panel->video_test = false;
|
dp->panel->video_test = false;
|
||||||
drm_dp_set_subconnector_property(dp->dp_display.connector,
|
if (!dp->dp_display.is_edp)
|
||||||
connector_status_disconnected,
|
drm_dp_set_subconnector_property(dp->dp_display.connector,
|
||||||
dp->panel->dpcd, dp->panel->downstream_ports);
|
connector_status_disconnected,
|
||||||
|
dp->panel->dpcd,
|
||||||
|
dp->panel->downstream_ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
dp->dp_display.is_connected = hpd;
|
dp->dp_display.is_connected = hpd;
|
||||||
@ -396,8 +398,11 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
|
|||||||
|
|
||||||
dp_link_process_request(dp->link);
|
dp_link_process_request(dp->link);
|
||||||
|
|
||||||
drm_dp_set_subconnector_property(dp->dp_display.connector, connector_status_connected,
|
if (!dp->dp_display.is_edp)
|
||||||
dp->panel->dpcd, dp->panel->downstream_ports);
|
drm_dp_set_subconnector_property(dp->dp_display.connector,
|
||||||
|
connector_status_connected,
|
||||||
|
dp->panel->dpcd,
|
||||||
|
dp->panel->downstream_ports);
|
||||||
|
|
||||||
edid = dp->panel->edid;
|
edid = dp->panel->edid;
|
||||||
|
|
||||||
|
@ -345,6 +345,9 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct dr
|
|||||||
if (IS_ERR(connector))
|
if (IS_ERR(connector))
|
||||||
return connector;
|
return connector;
|
||||||
|
|
||||||
|
if (!dp_display->is_edp)
|
||||||
|
drm_connector_attach_dp_subconnector_property(connector);
|
||||||
|
|
||||||
drm_connector_attach_encoder(connector, encoder);
|
drm_connector_attach_encoder(connector, encoder);
|
||||||
|
|
||||||
return connector;
|
return connector;
|
||||||
|
@ -918,7 +918,7 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
|
|||||||
if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
|
if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
|
||||||
if (phy->cphy_mode) {
|
if (phy->cphy_mode) {
|
||||||
vreg_ctrl_0 = 0x45;
|
vreg_ctrl_0 = 0x45;
|
||||||
vreg_ctrl_1 = 0x45;
|
vreg_ctrl_1 = 0x41;
|
||||||
glbl_rescode_top_ctrl = 0x00;
|
glbl_rescode_top_ctrl = 0x00;
|
||||||
glbl_rescode_bot_ctrl = 0x00;
|
glbl_rescode_bot_ctrl = 0x00;
|
||||||
} else {
|
} else {
|
||||||
|
@ -288,8 +288,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err_msm_uninit;
|
goto err_msm_uninit;
|
||||||
|
|
||||||
drm_kms_helper_poll_init(ddev);
|
|
||||||
|
|
||||||
if (priv->kms_init) {
|
if (priv->kms_init) {
|
||||||
drm_kms_helper_poll_init(ddev);
|
drm_kms_helper_poll_init(ddev);
|
||||||
msm_fbdev_setup(ddev);
|
msm_fbdev_setup(ddev);
|
||||||
|
@ -539,7 +539,7 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo)
|
|||||||
struct nvkm_runl *runl;
|
struct nvkm_runl *runl;
|
||||||
struct nvkm_engn *engn;
|
struct nvkm_engn *engn;
|
||||||
u32 cgids = 2048;
|
u32 cgids = 2048;
|
||||||
u32 chids = 2048 / CHID_PER_USERD;
|
u32 chids = 2048;
|
||||||
int ret;
|
int ret;
|
||||||
NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS *ctrl;
|
NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS *ctrl;
|
||||||
|
|
||||||
|
@ -1709,6 +1709,7 @@ static const struct panel_desc auo_b101uan08_3_desc = {
|
|||||||
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
|
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
|
||||||
MIPI_DSI_MODE_LPM,
|
MIPI_DSI_MODE_LPM,
|
||||||
.init_cmds = auo_b101uan08_3_init_cmd,
|
.init_cmds = auo_b101uan08_3_init_cmd,
|
||||||
|
.lp11_before_reset = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct drm_display_mode boe_tv105wum_nw0_default_mode = {
|
static const struct drm_display_mode boe_tv105wum_nw0_default_mode = {
|
||||||
@ -1766,11 +1767,11 @@ static const struct panel_desc starry_qfh032011_53g_desc = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct drm_display_mode starry_himax83102_j02_default_mode = {
|
static const struct drm_display_mode starry_himax83102_j02_default_mode = {
|
||||||
.clock = 161600,
|
.clock = 162850,
|
||||||
.hdisplay = 1200,
|
.hdisplay = 1200,
|
||||||
.hsync_start = 1200 + 40,
|
.hsync_start = 1200 + 50,
|
||||||
.hsync_end = 1200 + 40 + 20,
|
.hsync_end = 1200 + 50 + 20,
|
||||||
.htotal = 1200 + 40 + 20 + 40,
|
.htotal = 1200 + 50 + 20 + 50,
|
||||||
.vdisplay = 1920,
|
.vdisplay = 1920,
|
||||||
.vsync_start = 1920 + 116,
|
.vsync_start = 1920 + 116,
|
||||||
.vsync_end = 1920 + 116 + 8,
|
.vsync_end = 1920 + 116 + 8,
|
||||||
|
@ -2379,13 +2379,13 @@ static const struct panel_desc innolux_g070y2_t02 = {
|
|||||||
static const struct display_timing innolux_g101ice_l01_timing = {
|
static const struct display_timing innolux_g101ice_l01_timing = {
|
||||||
.pixelclock = { 60400000, 71100000, 74700000 },
|
.pixelclock = { 60400000, 71100000, 74700000 },
|
||||||
.hactive = { 1280, 1280, 1280 },
|
.hactive = { 1280, 1280, 1280 },
|
||||||
.hfront_porch = { 41, 80, 100 },
|
.hfront_porch = { 30, 60, 70 },
|
||||||
.hback_porch = { 40, 79, 99 },
|
.hback_porch = { 30, 60, 70 },
|
||||||
.hsync_len = { 1, 1, 1 },
|
.hsync_len = { 22, 40, 60 },
|
||||||
.vactive = { 800, 800, 800 },
|
.vactive = { 800, 800, 800 },
|
||||||
.vfront_porch = { 5, 11, 14 },
|
.vfront_porch = { 3, 8, 14 },
|
||||||
.vback_porch = { 4, 11, 14 },
|
.vback_porch = { 3, 8, 14 },
|
||||||
.vsync_len = { 1, 1, 1 },
|
.vsync_len = { 4, 7, 12 },
|
||||||
.flags = DISPLAY_FLAGS_DE_HIGH,
|
.flags = DISPLAY_FLAGS_DE_HIGH,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2402,6 +2402,7 @@ static const struct panel_desc innolux_g101ice_l01 = {
|
|||||||
.disable = 200,
|
.disable = 200,
|
||||||
},
|
},
|
||||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
|
||||||
|
.bus_flags = DRM_BUS_FLAG_DE_HIGH,
|
||||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -247,14 +247,22 @@ static inline void vop_cfg_done(struct vop *vop)
|
|||||||
VOP_REG_SET(vop, common, cfg_done, 1);
|
VOP_REG_SET(vop, common, cfg_done, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool has_rb_swapped(uint32_t format)
|
static bool has_rb_swapped(uint32_t version, uint32_t format)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case DRM_FORMAT_XBGR8888:
|
case DRM_FORMAT_XBGR8888:
|
||||||
case DRM_FORMAT_ABGR8888:
|
case DRM_FORMAT_ABGR8888:
|
||||||
case DRM_FORMAT_BGR888:
|
|
||||||
case DRM_FORMAT_BGR565:
|
case DRM_FORMAT_BGR565:
|
||||||
return true;
|
return true;
|
||||||
|
/*
|
||||||
|
* full framework (IP version 3.x) only need rb swapped for RGB888 and
|
||||||
|
* little framework (IP version 2.x) only need rb swapped for BGR888,
|
||||||
|
* check for 3.x to also only rb swap BGR888 for unknown vop version
|
||||||
|
*/
|
||||||
|
case DRM_FORMAT_RGB888:
|
||||||
|
return VOP_MAJOR(version) == 3;
|
||||||
|
case DRM_FORMAT_BGR888:
|
||||||
|
return VOP_MAJOR(version) != 3;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1030,7 +1038,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
|
|||||||
VOP_WIN_SET(vop, win, dsp_info, dsp_info);
|
VOP_WIN_SET(vop, win, dsp_info, dsp_info);
|
||||||
VOP_WIN_SET(vop, win, dsp_st, dsp_st);
|
VOP_WIN_SET(vop, win, dsp_st, dsp_st);
|
||||||
|
|
||||||
rb_swap = has_rb_swapped(fb->format->format);
|
rb_swap = has_rb_swapped(vop->data->version, fb->format->format);
|
||||||
VOP_WIN_SET(vop, win, rb_swap, rb_swap);
|
VOP_WIN_SET(vop, win, rb_swap, rb_swap);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -345,6 +345,8 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = {
|
|||||||
{ "AONE" },
|
{ "AONE" },
|
||||||
{ "GANSS" },
|
{ "GANSS" },
|
||||||
{ "Hailuck" },
|
{ "Hailuck" },
|
||||||
|
{ "Jamesdonkey" },
|
||||||
|
{ "A3R" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
|
static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
|
||||||
|
@ -381,7 +381,7 @@ static int asus_raw_event(struct hid_device *hdev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size)
|
static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size)
|
||||||
{
|
{
|
||||||
unsigned char *dmabuf;
|
unsigned char *dmabuf;
|
||||||
int ret;
|
int ret;
|
||||||
@ -404,7 +404,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size
|
|||||||
|
|
||||||
static int asus_kbd_init(struct hid_device *hdev)
|
static int asus_kbd_init(struct hid_device *hdev)
|
||||||
{
|
{
|
||||||
u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
|
const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
|
||||||
0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
|
0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -418,7 +418,7 @@ static int asus_kbd_init(struct hid_device *hdev)
|
|||||||
static int asus_kbd_get_functions(struct hid_device *hdev,
|
static int asus_kbd_get_functions(struct hid_device *hdev,
|
||||||
unsigned char *kbd_func)
|
unsigned char *kbd_func)
|
||||||
{
|
{
|
||||||
u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };
|
const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };
|
||||||
u8 *readbuf;
|
u8 *readbuf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -449,7 +449,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev,
|
|||||||
|
|
||||||
static int rog_nkey_led_init(struct hid_device *hdev)
|
static int rog_nkey_led_init(struct hid_device *hdev)
|
||||||
{
|
{
|
||||||
u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 };
|
const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 };
|
||||||
u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20,
|
u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20,
|
||||||
0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
|
0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
|
||||||
u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1,
|
u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1,
|
||||||
@ -1000,6 +1000,24 @@ static int asus_start_multitouch(struct hid_device *hdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __maybe_unused asus_resume(struct hid_device *hdev) {
|
||||||
|
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (drvdata->kbd_backlight) {
|
||||||
|
const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4,
|
||||||
|
drvdata->kbd_backlight->cdev.brightness };
|
||||||
|
ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
|
||||||
|
if (ret < 0) {
|
||||||
|
hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret);
|
||||||
|
goto asus_resume_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asus_resume_err:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
|
static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
|
||||||
{
|
{
|
||||||
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
|
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
|
||||||
@ -1294,6 +1312,7 @@ static struct hid_driver asus_driver = {
|
|||||||
.input_configured = asus_input_configured,
|
.input_configured = asus_input_configured,
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.reset_resume = asus_reset_resume,
|
.reset_resume = asus_reset_resume,
|
||||||
|
.resume = asus_resume,
|
||||||
#endif
|
#endif
|
||||||
.event = asus_event,
|
.event = asus_event,
|
||||||
.raw_event = asus_raw_event
|
.raw_event = asus_raw_event
|
||||||
|
@ -702,15 +702,22 @@ static void hid_close_report(struct hid_device *device)
|
|||||||
* Free a device structure, all reports, and all fields.
|
* Free a device structure, all reports, and all fields.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void hid_device_release(struct device *dev)
|
void hiddev_free(struct kref *ref)
|
||||||
{
|
{
|
||||||
struct hid_device *hid = to_hid_device(dev);
|
struct hid_device *hid = container_of(ref, struct hid_device, ref);
|
||||||
|
|
||||||
hid_close_report(hid);
|
hid_close_report(hid);
|
||||||
kfree(hid->dev_rdesc);
|
kfree(hid->dev_rdesc);
|
||||||
kfree(hid);
|
kfree(hid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hid_device_release(struct device *dev)
|
||||||
|
{
|
||||||
|
struct hid_device *hid = to_hid_device(dev);
|
||||||
|
|
||||||
|
kref_put(&hid->ref, hiddev_free);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch a report description item from the data stream. We support long
|
* Fetch a report description item from the data stream. We support long
|
||||||
* items, though they are not used yet.
|
* items, though they are not used yet.
|
||||||
@ -2846,6 +2853,7 @@ struct hid_device *hid_allocate_device(void)
|
|||||||
spin_lock_init(&hdev->debug_list_lock);
|
spin_lock_init(&hdev->debug_list_lock);
|
||||||
sema_init(&hdev->driver_input_lock, 1);
|
sema_init(&hdev->driver_input_lock, 1);
|
||||||
mutex_init(&hdev->ll_open_lock);
|
mutex_init(&hdev->ll_open_lock);
|
||||||
|
kref_init(&hdev->ref);
|
||||||
|
|
||||||
hid_bpf_device_init(hdev);
|
hid_bpf_device_init(hdev);
|
||||||
|
|
||||||
|
@ -1135,6 +1135,7 @@ static int hid_debug_events_open(struct inode *inode, struct file *file)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
list->hdev = (struct hid_device *) inode->i_private;
|
list->hdev = (struct hid_device *) inode->i_private;
|
||||||
|
kref_get(&list->hdev->ref);
|
||||||
file->private_data = list;
|
file->private_data = list;
|
||||||
mutex_init(&list->read_mutex);
|
mutex_init(&list->read_mutex);
|
||||||
|
|
||||||
@ -1227,6 +1228,8 @@ static int hid_debug_events_release(struct inode *inode, struct file *file)
|
|||||||
list_del(&list->node);
|
list_del(&list->node);
|
||||||
spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags);
|
spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags);
|
||||||
kfifo_free(&list->hid_debug_fifo);
|
kfifo_free(&list->hid_debug_fifo);
|
||||||
|
|
||||||
|
kref_put(&list->hdev->ref, hiddev_free);
|
||||||
kfree(list);
|
kfree(list);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -21,6 +21,10 @@ MODULE_DESCRIPTION("HID driver for Glorious PC Gaming Race mice");
|
|||||||
* Glorious Model O and O- specify the const flag in the consumer input
|
* Glorious Model O and O- specify the const flag in the consumer input
|
||||||
* report descriptor, which leads to inputs being ignored. Fix this
|
* report descriptor, which leads to inputs being ignored. Fix this
|
||||||
* by patching the descriptor.
|
* by patching the descriptor.
|
||||||
|
*
|
||||||
|
* Glorious Model I incorrectly specifes the Usage Minimum for its
|
||||||
|
* keyboard HID report, causing keycodes to be misinterpreted.
|
||||||
|
* Fix this by setting Usage Minimum to 0 in that report.
|
||||||
*/
|
*/
|
||||||
static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||||
unsigned int *rsize)
|
unsigned int *rsize)
|
||||||
@ -32,6 +36,10 @@ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||||||
rdesc[85] = rdesc[113] = rdesc[141] = \
|
rdesc[85] = rdesc[113] = rdesc[141] = \
|
||||||
HID_MAIN_ITEM_VARIABLE | HID_MAIN_ITEM_RELATIVE;
|
HID_MAIN_ITEM_VARIABLE | HID_MAIN_ITEM_RELATIVE;
|
||||||
}
|
}
|
||||||
|
if (*rsize == 156 && rdesc[41] == 1) {
|
||||||
|
hid_info(hdev, "patching Glorious Model I keyboard report descriptor\n");
|
||||||
|
rdesc[41] = 0;
|
||||||
|
}
|
||||||
return rdesc;
|
return rdesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +52,8 @@ static void glorious_update_name(struct hid_device *hdev)
|
|||||||
model = "Model O"; break;
|
model = "Model O"; break;
|
||||||
case USB_DEVICE_ID_GLORIOUS_MODEL_D:
|
case USB_DEVICE_ID_GLORIOUS_MODEL_D:
|
||||||
model = "Model D"; break;
|
model = "Model D"; break;
|
||||||
|
case USB_DEVICE_ID_GLORIOUS_MODEL_I:
|
||||||
|
model = "Model I"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(hdev->name, sizeof(hdev->name), "%s %s", "Glorious", model);
|
snprintf(hdev->name, sizeof(hdev->name), "%s %s", "Glorious", model);
|
||||||
@ -66,10 +76,12 @@ static int glorious_probe(struct hid_device *hdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct hid_device_id glorious_devices[] = {
|
static const struct hid_device_id glorious_devices[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH,
|
||||||
USB_DEVICE_ID_GLORIOUS_MODEL_O) },
|
USB_DEVICE_ID_GLORIOUS_MODEL_O) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH,
|
||||||
USB_DEVICE_ID_GLORIOUS_MODEL_D) },
|
USB_DEVICE_ID_GLORIOUS_MODEL_D) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LAVIEW,
|
||||||
|
USB_DEVICE_ID_GLORIOUS_MODEL_I) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(hid, glorious_devices);
|
MODULE_DEVICE_TABLE(hid, glorious_devices);
|
||||||
|
@ -511,10 +511,6 @@
|
|||||||
#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a
|
#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a
|
||||||
#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
|
#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
|
||||||
|
|
||||||
#define USB_VENDOR_ID_GLORIOUS 0x258a
|
|
||||||
#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033
|
|
||||||
#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036
|
|
||||||
|
|
||||||
#define I2C_VENDOR_ID_GOODIX 0x27c6
|
#define I2C_VENDOR_ID_GOODIX 0x27c6
|
||||||
#define I2C_DEVICE_ID_GOODIX_01F0 0x01f0
|
#define I2C_DEVICE_ID_GOODIX_01F0 0x01f0
|
||||||
|
|
||||||
@ -745,6 +741,9 @@
|
|||||||
#define USB_VENDOR_ID_LABTEC 0x1020
|
#define USB_VENDOR_ID_LABTEC 0x1020
|
||||||
#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
|
#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
|
||||||
|
|
||||||
|
#define USB_VENDOR_ID_LAVIEW 0x22D4
|
||||||
|
#define USB_DEVICE_ID_GLORIOUS_MODEL_I 0x1503
|
||||||
|
|
||||||
#define USB_VENDOR_ID_LCPOWER 0x1241
|
#define USB_VENDOR_ID_LCPOWER 0x1241
|
||||||
#define USB_DEVICE_ID_LCPOWER_LC1000 0xf767
|
#define USB_DEVICE_ID_LCPOWER_LC1000 0xf767
|
||||||
|
|
||||||
@ -869,7 +868,6 @@
|
|||||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
|
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
|
||||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539
|
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539
|
||||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f
|
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f
|
||||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 0xc547
|
|
||||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
|
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
|
||||||
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
|
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
|
||||||
#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
|
#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
|
||||||
@ -1160,6 +1158,10 @@
|
|||||||
#define USB_VENDOR_ID_SIGMATEL 0x066F
|
#define USB_VENDOR_ID_SIGMATEL 0x066F
|
||||||
#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780
|
#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780
|
||||||
|
|
||||||
|
#define USB_VENDOR_ID_SINOWEALTH 0x258a
|
||||||
|
#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033
|
||||||
|
#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036
|
||||||
|
|
||||||
#define USB_VENDOR_ID_SIS_TOUCH 0x0457
|
#define USB_VENDOR_ID_SIS_TOUCH 0x0457
|
||||||
#define USB_DEVICE_ID_SIS9200_TOUCH 0x9200
|
#define USB_DEVICE_ID_SIS9200_TOUCH 0x9200
|
||||||
#define USB_DEVICE_ID_SIS817_TOUCH 0x0817
|
#define USB_DEVICE_ID_SIS817_TOUCH 0x0817
|
||||||
|
@ -1695,12 +1695,11 @@ static int logi_dj_raw_event(struct hid_device *hdev,
|
|||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Mouse-only receivers send unnumbered mouse data. The 27 MHz
|
* Mouse-only receivers send unnumbered mouse data. The 27 MHz
|
||||||
* receiver uses 6 byte packets, the nano receiver 8 bytes,
|
* receiver uses 6 byte packets, the nano receiver 8 bytes.
|
||||||
* the lightspeed receiver (Pro X Superlight) 13 bytes.
|
|
||||||
*/
|
*/
|
||||||
if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
|
if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
|
||||||
size <= 13){
|
size <= 8) {
|
||||||
u8 mouse_report[14];
|
u8 mouse_report[9];
|
||||||
|
|
||||||
/* Prepend report id */
|
/* Prepend report id */
|
||||||
mouse_report[0] = REPORT_TYPE_MOUSE;
|
mouse_report[0] = REPORT_TYPE_MOUSE;
|
||||||
@ -1984,10 +1983,6 @@ static const struct hid_device_id logi_dj_receivers[] = {
|
|||||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||||
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
|
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
|
||||||
.driver_data = recvr_type_gaming_hidpp},
|
.driver_data = recvr_type_gaming_hidpp},
|
||||||
{ /* Logitech lightspeed receiver (0xc547) */
|
|
||||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
|
||||||
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2),
|
|
||||||
.driver_data = recvr_type_gaming_hidpp},
|
|
||||||
|
|
||||||
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
|
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
|
||||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
|
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
|
||||||
|
@ -1142,6 +1142,8 @@ static int mcp2221_probe(struct hid_device *hdev,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
hid_device_io_start(hdev);
|
||||||
|
|
||||||
/* Set I2C bus clock diviser */
|
/* Set I2C bus clock diviser */
|
||||||
if (i2c_clk_freq > 400)
|
if (i2c_clk_freq > 400)
|
||||||
i2c_clk_freq = 400;
|
i2c_clk_freq = 400;
|
||||||
@ -1157,12 +1159,12 @@ static int mcp2221_probe(struct hid_device *hdev,
|
|||||||
snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
|
snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
|
||||||
"MCP2221 usb-i2c bridge");
|
"MCP2221 usb-i2c bridge");
|
||||||
|
|
||||||
|
i2c_set_adapdata(&mcp->adapter, mcp);
|
||||||
ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter);
|
ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret);
|
hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
i2c_set_adapdata(&mcp->adapter, mcp);
|
|
||||||
|
|
||||||
#if IS_REACHABLE(CONFIG_GPIOLIB)
|
#if IS_REACHABLE(CONFIG_GPIOLIB)
|
||||||
/* Setup GPIO chip */
|
/* Setup GPIO chip */
|
||||||
|
@ -2046,6 +2046,11 @@ static const struct hid_device_id mt_devices[] = {
|
|||||||
MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,
|
MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,
|
||||||
USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
|
USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
|
||||||
|
|
||||||
|
/* HONOR GLO-GXXX panel */
|
||||||
|
{ .driver_data = MT_CLS_VTL,
|
||||||
|
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
||||||
|
0x347d, 0x7853) },
|
||||||
|
|
||||||
/* Ilitek dual touch panel */
|
/* Ilitek dual touch panel */
|
||||||
{ .driver_data = MT_CLS_NSMU,
|
{ .driver_data = MT_CLS_NSMU,
|
||||||
MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
|
MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
|
||||||
|
@ -33,6 +33,7 @@ static const struct hid_device_id hid_quirks[] = {
|
|||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET },
|
||||||
|
@ -265,6 +265,7 @@ struct bcache_device {
|
|||||||
#define BCACHE_DEV_WB_RUNNING 3
|
#define BCACHE_DEV_WB_RUNNING 3
|
||||||
#define BCACHE_DEV_RATE_DW_RUNNING 4
|
#define BCACHE_DEV_RATE_DW_RUNNING 4
|
||||||
int nr_stripes;
|
int nr_stripes;
|
||||||
|
#define BCH_MIN_STRIPE_SZ ((4 << 20) >> SECTOR_SHIFT)
|
||||||
unsigned int stripe_size;
|
unsigned int stripe_size;
|
||||||
atomic_t *stripe_sectors_dirty;
|
atomic_t *stripe_sectors_dirty;
|
||||||
unsigned long *full_dirty_stripes;
|
unsigned long *full_dirty_stripes;
|
||||||
|
@ -1000,6 +1000,9 @@ err:
|
|||||||
*
|
*
|
||||||
* The btree node will have either a read or a write lock held, depending on
|
* The btree node will have either a read or a write lock held, depending on
|
||||||
* level and op->lock.
|
* level and op->lock.
|
||||||
|
*
|
||||||
|
* Note: Only error code or btree pointer will be returned, it is unncessary
|
||||||
|
* for callers to check NULL pointer.
|
||||||
*/
|
*/
|
||||||
struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op,
|
struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op,
|
||||||
struct bkey *k, int level, bool write,
|
struct bkey *k, int level, bool write,
|
||||||
@ -1111,6 +1114,10 @@ retry:
|
|||||||
mutex_unlock(&b->c->bucket_lock);
|
mutex_unlock(&b->c->bucket_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only error code or btree pointer will be returned, it is unncessary for
|
||||||
|
* callers to check NULL pointer.
|
||||||
|
*/
|
||||||
struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op,
|
struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op,
|
||||||
int level, bool wait,
|
int level, bool wait,
|
||||||
struct btree *parent)
|
struct btree *parent)
|
||||||
@ -1368,7 +1375,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op,
|
|||||||
memset(new_nodes, 0, sizeof(new_nodes));
|
memset(new_nodes, 0, sizeof(new_nodes));
|
||||||
closure_init_stack(&cl);
|
closure_init_stack(&cl);
|
||||||
|
|
||||||
while (nodes < GC_MERGE_NODES && !IS_ERR(r[nodes].b))
|
while (nodes < GC_MERGE_NODES && !IS_ERR_OR_NULL(r[nodes].b))
|
||||||
keys += r[nodes++].keys;
|
keys += r[nodes++].keys;
|
||||||
|
|
||||||
blocks = btree_default_blocks(b->c) * 2 / 3;
|
blocks = btree_default_blocks(b->c) * 2 / 3;
|
||||||
@ -1532,6 +1539,8 @@ static int btree_gc_rewrite_node(struct btree *b, struct btree_op *op,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
n = btree_node_alloc_replacement(replace, NULL);
|
n = btree_node_alloc_replacement(replace, NULL);
|
||||||
|
if (IS_ERR(n))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* recheck reserve after allocating replacement node */
|
/* recheck reserve after allocating replacement node */
|
||||||
if (btree_check_reserve(b, NULL)) {
|
if (btree_check_reserve(b, NULL)) {
|
||||||
|
@ -905,6 +905,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
|
|||||||
|
|
||||||
if (!d->stripe_size)
|
if (!d->stripe_size)
|
||||||
d->stripe_size = 1 << 31;
|
d->stripe_size = 1 << 31;
|
||||||
|
else if (d->stripe_size < BCH_MIN_STRIPE_SZ)
|
||||||
|
d->stripe_size = roundup(BCH_MIN_STRIPE_SZ, d->stripe_size);
|
||||||
|
|
||||||
n = DIV_ROUND_UP_ULL(sectors, d->stripe_size);
|
n = DIV_ROUND_UP_ULL(sectors, d->stripe_size);
|
||||||
if (!n || n > max_stripes) {
|
if (!n || n > max_stripes) {
|
||||||
@ -2016,7 +2018,7 @@ static int run_cache_set(struct cache_set *c)
|
|||||||
c->root = bch_btree_node_get(c, NULL, k,
|
c->root = bch_btree_node_get(c, NULL, k,
|
||||||
j->btree_level,
|
j->btree_level,
|
||||||
true, NULL);
|
true, NULL);
|
||||||
if (IS_ERR_OR_NULL(c->root))
|
if (IS_ERR(c->root))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
list_del_init(&c->root->list);
|
list_del_init(&c->root->list);
|
||||||
|
@ -1104,7 +1104,7 @@ SHOW(__bch_cache)
|
|||||||
sum += INITIAL_PRIO - cached[i];
|
sum += INITIAL_PRIO - cached[i];
|
||||||
|
|
||||||
if (n)
|
if (n)
|
||||||
do_div(sum, n);
|
sum = div64_u64(sum, n);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(q); i++)
|
for (i = 0; i < ARRAY_SIZE(q); i++)
|
||||||
q[i] = INITIAL_PRIO - cached[n * (i + 1) /
|
q[i] = INITIAL_PRIO - cached[n * (i + 1) /
|
||||||
|
@ -913,7 +913,7 @@ static int bch_dirty_init_thread(void *arg)
|
|||||||
int cur_idx, prev_idx, skip_nr;
|
int cur_idx, prev_idx, skip_nr;
|
||||||
|
|
||||||
k = p = NULL;
|
k = p = NULL;
|
||||||
cur_idx = prev_idx = 0;
|
prev_idx = 0;
|
||||||
|
|
||||||
bch_btree_iter_init(&c->root->keys, &iter, NULL);
|
bch_btree_iter_init(&c->root->keys, &iter, NULL);
|
||||||
k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad);
|
k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad);
|
||||||
@ -977,24 +977,35 @@ static int bch_btre_dirty_init_thread_nr(void)
|
|||||||
void bch_sectors_dirty_init(struct bcache_device *d)
|
void bch_sectors_dirty_init(struct bcache_device *d)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
struct btree *b = NULL;
|
||||||
struct bkey *k = NULL;
|
struct bkey *k = NULL;
|
||||||
struct btree_iter iter;
|
struct btree_iter iter;
|
||||||
struct sectors_dirty_init op;
|
struct sectors_dirty_init op;
|
||||||
struct cache_set *c = d->c;
|
struct cache_set *c = d->c;
|
||||||
struct bch_dirty_init_state state;
|
struct bch_dirty_init_state state;
|
||||||
|
|
||||||
|
retry_lock:
|
||||||
|
b = c->root;
|
||||||
|
rw_lock(0, b, b->level);
|
||||||
|
if (b != c->root) {
|
||||||
|
rw_unlock(0, b);
|
||||||
|
goto retry_lock;
|
||||||
|
}
|
||||||
|
|
||||||
/* Just count root keys if no leaf node */
|
/* Just count root keys if no leaf node */
|
||||||
rw_lock(0, c->root, c->root->level);
|
|
||||||
if (c->root->level == 0) {
|
if (c->root->level == 0) {
|
||||||
bch_btree_op_init(&op.op, -1);
|
bch_btree_op_init(&op.op, -1);
|
||||||
op.inode = d->id;
|
op.inode = d->id;
|
||||||
op.count = 0;
|
op.count = 0;
|
||||||
|
|
||||||
for_each_key_filter(&c->root->keys,
|
for_each_key_filter(&c->root->keys,
|
||||||
k, &iter, bch_ptr_invalid)
|
k, &iter, bch_ptr_invalid) {
|
||||||
|
if (KEY_INODE(k) != op.inode)
|
||||||
|
continue;
|
||||||
sectors_dirty_init_fn(&op.op, c->root, k);
|
sectors_dirty_init_fn(&op.op, c->root, k);
|
||||||
|
}
|
||||||
|
|
||||||
rw_unlock(0, c->root);
|
rw_unlock(0, b);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1014,23 +1025,24 @@ void bch_sectors_dirty_init(struct bcache_device *d)
|
|||||||
if (atomic_read(&state.enough))
|
if (atomic_read(&state.enough))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
atomic_inc(&state.started);
|
||||||
state.infos[i].state = &state;
|
state.infos[i].state = &state;
|
||||||
state.infos[i].thread =
|
state.infos[i].thread =
|
||||||
kthread_run(bch_dirty_init_thread, &state.infos[i],
|
kthread_run(bch_dirty_init_thread, &state.infos[i],
|
||||||
"bch_dirtcnt[%d]", i);
|
"bch_dirtcnt[%d]", i);
|
||||||
if (IS_ERR(state.infos[i].thread)) {
|
if (IS_ERR(state.infos[i].thread)) {
|
||||||
pr_err("fails to run thread bch_dirty_init[%d]\n", i);
|
pr_err("fails to run thread bch_dirty_init[%d]\n", i);
|
||||||
|
atomic_dec(&state.started);
|
||||||
for (--i; i >= 0; i--)
|
for (--i; i >= 0; i--)
|
||||||
kthread_stop(state.infos[i].thread);
|
kthread_stop(state.infos[i].thread);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
atomic_inc(&state.started);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
/* Must wait for all threads to stop. */
|
/* Must wait for all threads to stop. */
|
||||||
wait_event(state.wait, atomic_read(&state.started) == 0);
|
wait_event(state.wait, atomic_read(&state.started) == 0);
|
||||||
rw_unlock(0, c->root);
|
rw_unlock(0, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bch_cached_dev_writeback_init(struct cached_dev *dc)
|
void bch_cached_dev_writeback_init(struct cached_dev *dc)
|
||||||
|
@ -8666,7 +8666,8 @@ static void md_end_clone_io(struct bio *bio)
|
|||||||
struct bio *orig_bio = md_io_clone->orig_bio;
|
struct bio *orig_bio = md_io_clone->orig_bio;
|
||||||
struct mddev *mddev = md_io_clone->mddev;
|
struct mddev *mddev = md_io_clone->mddev;
|
||||||
|
|
||||||
orig_bio->bi_status = bio->bi_status;
|
if (bio->bi_status && !orig_bio->bi_status)
|
||||||
|
orig_bio->bi_status = bio->bi_status;
|
||||||
|
|
||||||
if (md_io_clone->start_time)
|
if (md_io_clone->start_time)
|
||||||
bio_end_io_acct(orig_bio, md_io_clone->start_time);
|
bio_end_io_acct(orig_bio, md_io_clone->start_time);
|
||||||
|
@ -682,10 +682,24 @@ static void xgbe_service(struct work_struct *work)
|
|||||||
static void xgbe_service_timer(struct timer_list *t)
|
static void xgbe_service_timer(struct timer_list *t)
|
||||||
{
|
{
|
||||||
struct xgbe_prv_data *pdata = from_timer(pdata, t, service_timer);
|
struct xgbe_prv_data *pdata = from_timer(pdata, t, service_timer);
|
||||||
|
struct xgbe_channel *channel;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
queue_work(pdata->dev_workqueue, &pdata->service_work);
|
queue_work(pdata->dev_workqueue, &pdata->service_work);
|
||||||
|
|
||||||
mod_timer(&pdata->service_timer, jiffies + HZ);
|
mod_timer(&pdata->service_timer, jiffies + HZ);
|
||||||
|
|
||||||
|
if (!pdata->tx_usecs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < pdata->channel_count; i++) {
|
||||||
|
channel = pdata->channel[i];
|
||||||
|
if (!channel->tx_ring || channel->tx_timer_active)
|
||||||
|
break;
|
||||||
|
channel->tx_timer_active = 1;
|
||||||
|
mod_timer(&channel->tx_timer,
|
||||||
|
jiffies + usecs_to_jiffies(pdata->tx_usecs));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xgbe_init_timers(struct xgbe_prv_data *pdata)
|
static void xgbe_init_timers(struct xgbe_prv_data *pdata)
|
||||||
|
@ -314,10 +314,15 @@ static int xgbe_get_link_ksettings(struct net_device *netdev,
|
|||||||
|
|
||||||
cmd->base.phy_address = pdata->phy.address;
|
cmd->base.phy_address = pdata->phy.address;
|
||||||
|
|
||||||
cmd->base.autoneg = pdata->phy.autoneg;
|
if (netif_carrier_ok(netdev)) {
|
||||||
cmd->base.speed = pdata->phy.speed;
|
cmd->base.speed = pdata->phy.speed;
|
||||||
cmd->base.duplex = pdata->phy.duplex;
|
cmd->base.duplex = pdata->phy.duplex;
|
||||||
|
} else {
|
||||||
|
cmd->base.speed = SPEED_UNKNOWN;
|
||||||
|
cmd->base.duplex = DUPLEX_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->base.autoneg = pdata->phy.autoneg;
|
||||||
cmd->base.port = PORT_NONE;
|
cmd->base.port = PORT_NONE;
|
||||||
|
|
||||||
XGBE_LM_COPY(cmd, supported, lks, supported);
|
XGBE_LM_COPY(cmd, supported, lks, supported);
|
||||||
|
@ -1193,7 +1193,19 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
|
|||||||
if (pdata->phy.duplex != DUPLEX_FULL)
|
if (pdata->phy.duplex != DUPLEX_FULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
xgbe_set_mode(pdata, mode);
|
/* Force the mode change for SFI in Fixed PHY config.
|
||||||
|
* Fixed PHY configs needs PLL to be enabled while doing mode set.
|
||||||
|
* When the SFP module isn't connected during boot, driver assumes
|
||||||
|
* AN is ON and attempts autonegotiation. However, if the connected
|
||||||
|
* SFP comes up in Fixed PHY config, the link will not come up as
|
||||||
|
* PLL isn't enabled while the initial mode set command is issued.
|
||||||
|
* So, force the mode change for SFI in Fixed PHY configuration to
|
||||||
|
* fix link issues.
|
||||||
|
*/
|
||||||
|
if (mode == XGBE_MODE_SFI)
|
||||||
|
xgbe_change_mode(pdata, mode);
|
||||||
|
else
|
||||||
|
xgbe_set_mode(pdata, mode);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3844,7 +3844,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg)
|
|||||||
struct i40e_pf *pf = vf->pf;
|
struct i40e_pf *pf = vf->pf;
|
||||||
struct i40e_vsi *vsi = NULL;
|
struct i40e_vsi *vsi = NULL;
|
||||||
int aq_ret = 0;
|
int aq_ret = 0;
|
||||||
int i, ret;
|
int i;
|
||||||
|
|
||||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||||
aq_ret = -EINVAL;
|
aq_ret = -EINVAL;
|
||||||
@ -3868,8 +3868,10 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cfilter = kzalloc(sizeof(*cfilter), GFP_KERNEL);
|
cfilter = kzalloc(sizeof(*cfilter), GFP_KERNEL);
|
||||||
if (!cfilter)
|
if (!cfilter) {
|
||||||
return -ENOMEM;
|
aq_ret = -ENOMEM;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
/* parse destination mac address */
|
/* parse destination mac address */
|
||||||
for (i = 0; i < ETH_ALEN; i++)
|
for (i = 0; i < ETH_ALEN; i++)
|
||||||
@ -3917,13 +3919,13 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg)
|
|||||||
|
|
||||||
/* Adding cloud filter programmed as TC filter */
|
/* Adding cloud filter programmed as TC filter */
|
||||||
if (tcf.dst_port)
|
if (tcf.dst_port)
|
||||||
ret = i40e_add_del_cloud_filter_big_buf(vsi, cfilter, true);
|
aq_ret = i40e_add_del_cloud_filter_big_buf(vsi, cfilter, true);
|
||||||
else
|
else
|
||||||
ret = i40e_add_del_cloud_filter(vsi, cfilter, true);
|
aq_ret = i40e_add_del_cloud_filter(vsi, cfilter, true);
|
||||||
if (ret) {
|
if (aq_ret) {
|
||||||
dev_err(&pf->pdev->dev,
|
dev_err(&pf->pdev->dev,
|
||||||
"VF %d: Failed to add cloud filter, err %pe aq_err %s\n",
|
"VF %d: Failed to add cloud filter, err %pe aq_err %s\n",
|
||||||
vf->vf_id, ERR_PTR(ret),
|
vf->vf_id, ERR_PTR(aq_ret),
|
||||||
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
|
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
|
||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
@ -7401,15 +7401,6 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
|||||||
goto err_vsi_rebuild;
|
goto err_vsi_rebuild;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* configure PTP timestamping after VSI rebuild */
|
|
||||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags)) {
|
|
||||||
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
|
||||||
ice_ptp_cfg_timestamp(pf, false);
|
|
||||||
else if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL)
|
|
||||||
/* for E82x PHC owner always need to have interrupts */
|
|
||||||
ice_ptp_cfg_timestamp(pf, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL);
|
err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err);
|
dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err);
|
||||||
@ -7461,6 +7452,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
|||||||
ice_plug_aux_dev(pf);
|
ice_plug_aux_dev(pf);
|
||||||
if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG))
|
if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG))
|
||||||
ice_lag_rebuild(pf);
|
ice_lag_rebuild(pf);
|
||||||
|
|
||||||
|
/* Restore timestamp mode settings after VSI rebuild */
|
||||||
|
ice_ptp_restore_timestamp_mode(pf);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err_vsi_rebuild:
|
err_vsi_rebuild:
|
||||||
|
@ -256,48 +256,42 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_ptp_configure_tx_tstamp - Enable or disable Tx timestamp interrupt
|
* ice_ptp_cfg_tx_interrupt - Configure Tx timestamp interrupt for the device
|
||||||
* @pf: The PF pointer to search in
|
* @pf: Board private structure
|
||||||
* @on: bool value for whether timestamp interrupt is enabled or disabled
|
*
|
||||||
|
* Program the device to respond appropriately to the Tx timestamp interrupt
|
||||||
|
* cause.
|
||||||
*/
|
*/
|
||||||
static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf)
|
||||||
{
|
{
|
||||||
|
struct ice_hw *hw = &pf->hw;
|
||||||
|
bool enable;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
|
switch (pf->ptp.tx_interrupt_mode) {
|
||||||
|
case ICE_PTP_TX_INTERRUPT_ALL:
|
||||||
|
/* React to interrupts across all quads. */
|
||||||
|
wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||||
|
enable = true;
|
||||||
|
break;
|
||||||
|
case ICE_PTP_TX_INTERRUPT_NONE:
|
||||||
|
/* Do not react to interrupts on any quad. */
|
||||||
|
wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||||
|
enable = false;
|
||||||
|
break;
|
||||||
|
case ICE_PTP_TX_INTERRUPT_SELF:
|
||||||
|
default:
|
||||||
|
enable = pf->ptp.tstamp_config.tx_type == HWTSTAMP_TX_ON;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure the Tx timestamp interrupt */
|
/* Configure the Tx timestamp interrupt */
|
||||||
val = rd32(&pf->hw, PFINT_OICR_ENA);
|
val = rd32(hw, PFINT_OICR_ENA);
|
||||||
if (on)
|
if (enable)
|
||||||
val |= PFINT_OICR_TSYN_TX_M;
|
val |= PFINT_OICR_TSYN_TX_M;
|
||||||
else
|
else
|
||||||
val &= ~PFINT_OICR_TSYN_TX_M;
|
val &= ~PFINT_OICR_TSYN_TX_M;
|
||||||
wr32(&pf->hw, PFINT_OICR_ENA, val);
|
wr32(hw, PFINT_OICR_ENA, val);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ice_set_tx_tstamp - Enable or disable Tx timestamping
|
|
||||||
* @pf: The PF pointer to search in
|
|
||||||
* @on: bool value for whether timestamps are enabled or disabled
|
|
||||||
*/
|
|
||||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
|
||||||
{
|
|
||||||
struct ice_vsi *vsi;
|
|
||||||
u16 i;
|
|
||||||
|
|
||||||
vsi = ice_get_main_vsi(pf);
|
|
||||||
if (!vsi)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Set the timestamp enable flag for all the Tx rings */
|
|
||||||
ice_for_each_txq(vsi, i) {
|
|
||||||
if (!vsi->tx_rings[i])
|
|
||||||
continue;
|
|
||||||
vsi->tx_rings[i]->ptp_tx = on;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
|
||||||
ice_ptp_configure_tx_tstamp(pf, on);
|
|
||||||
|
|
||||||
pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -311,7 +305,7 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
|
|||||||
u16 i;
|
u16 i;
|
||||||
|
|
||||||
vsi = ice_get_main_vsi(pf);
|
vsi = ice_get_main_vsi(pf);
|
||||||
if (!vsi)
|
if (!vsi || !vsi->rx_rings)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Set the timestamp flag for all the Rx rings */
|
/* Set the timestamp flag for all the Rx rings */
|
||||||
@ -320,23 +314,50 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
|
|||||||
continue;
|
continue;
|
||||||
vsi->rx_rings[i]->ptp_rx = on;
|
vsi->rx_rings[i]->ptp_rx = on;
|
||||||
}
|
}
|
||||||
|
|
||||||
pf->ptp.tstamp_config.rx_filter = on ? HWTSTAMP_FILTER_ALL :
|
|
||||||
HWTSTAMP_FILTER_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_ptp_cfg_timestamp - Configure timestamp for init/deinit
|
* ice_ptp_disable_timestamp_mode - Disable current timestamp mode
|
||||||
* @pf: Board private structure
|
* @pf: Board private structure
|
||||||
* @ena: bool value to enable or disable time stamp
|
|
||||||
*
|
*
|
||||||
* This function will configure timestamping during PTP initialization
|
* Called during preparation for reset to temporarily disable timestamping on
|
||||||
* and deinitialization
|
* the device. Called during remove to disable timestamping while cleaning up
|
||||||
|
* driver resources.
|
||||||
*/
|
*/
|
||||||
void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena)
|
static void ice_ptp_disable_timestamp_mode(struct ice_pf *pf)
|
||||||
{
|
{
|
||||||
ice_set_tx_tstamp(pf, ena);
|
struct ice_hw *hw = &pf->hw;
|
||||||
ice_set_rx_tstamp(pf, ena);
|
u32 val;
|
||||||
|
|
||||||
|
val = rd32(hw, PFINT_OICR_ENA);
|
||||||
|
val &= ~PFINT_OICR_TSYN_TX_M;
|
||||||
|
wr32(hw, PFINT_OICR_ENA, val);
|
||||||
|
|
||||||
|
ice_set_rx_tstamp(pf, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_ptp_restore_timestamp_mode - Restore timestamp configuration
|
||||||
|
* @pf: Board private structure
|
||||||
|
*
|
||||||
|
* Called at the end of rebuild to restore timestamp configuration after
|
||||||
|
* a device reset.
|
||||||
|
*/
|
||||||
|
void ice_ptp_restore_timestamp_mode(struct ice_pf *pf)
|
||||||
|
{
|
||||||
|
struct ice_hw *hw = &pf->hw;
|
||||||
|
bool enable_rx;
|
||||||
|
|
||||||
|
ice_ptp_cfg_tx_interrupt(pf);
|
||||||
|
|
||||||
|
enable_rx = pf->ptp.tstamp_config.rx_filter == HWTSTAMP_FILTER_ALL;
|
||||||
|
ice_set_rx_tstamp(pf, enable_rx);
|
||||||
|
|
||||||
|
/* Trigger an immediate software interrupt to ensure that timestamps
|
||||||
|
* which occurred during reset are handled now.
|
||||||
|
*/
|
||||||
|
wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
|
||||||
|
ice_flush(hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2037,10 +2058,10 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
|||||||
{
|
{
|
||||||
switch (config->tx_type) {
|
switch (config->tx_type) {
|
||||||
case HWTSTAMP_TX_OFF:
|
case HWTSTAMP_TX_OFF:
|
||||||
ice_set_tx_tstamp(pf, false);
|
pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_OFF;
|
||||||
break;
|
break;
|
||||||
case HWTSTAMP_TX_ON:
|
case HWTSTAMP_TX_ON:
|
||||||
ice_set_tx_tstamp(pf, true);
|
pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_ON;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
@ -2048,7 +2069,7 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
|||||||
|
|
||||||
switch (config->rx_filter) {
|
switch (config->rx_filter) {
|
||||||
case HWTSTAMP_FILTER_NONE:
|
case HWTSTAMP_FILTER_NONE:
|
||||||
ice_set_rx_tstamp(pf, false);
|
pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||||
break;
|
break;
|
||||||
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
|
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
|
||||||
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
||||||
@ -2064,12 +2085,15 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
|||||||
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
||||||
case HWTSTAMP_FILTER_NTP_ALL:
|
case HWTSTAMP_FILTER_NTP_ALL:
|
||||||
case HWTSTAMP_FILTER_ALL:
|
case HWTSTAMP_FILTER_ALL:
|
||||||
ice_set_rx_tstamp(pf, true);
|
pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_ALL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Immediately update the device timestamping mode */
|
||||||
|
ice_ptp_restore_timestamp_mode(pf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2737,7 +2761,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
|||||||
clear_bit(ICE_FLAG_PTP, pf->flags);
|
clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||||
|
|
||||||
/* Disable timestamping for both Tx and Rx */
|
/* Disable timestamping for both Tx and Rx */
|
||||||
ice_ptp_cfg_timestamp(pf, false);
|
ice_ptp_disable_timestamp_mode(pf);
|
||||||
|
|
||||||
kthread_cancel_delayed_work_sync(&ptp->work);
|
kthread_cancel_delayed_work_sync(&ptp->work);
|
||||||
|
|
||||||
@ -2803,15 +2827,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
|||||||
/* Release the global hardware lock */
|
/* Release the global hardware lock */
|
||||||
ice_ptp_unlock(hw);
|
ice_ptp_unlock(hw);
|
||||||
|
|
||||||
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) {
|
if (!ice_is_e810(hw)) {
|
||||||
/* The clock owner for this device type handles the timestamp
|
|
||||||
* interrupt for all ports.
|
|
||||||
*/
|
|
||||||
ice_ptp_configure_tx_tstamp(pf, true);
|
|
||||||
|
|
||||||
/* React on all quads interrupts for E82x */
|
|
||||||
wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
|
||||||
|
|
||||||
/* Enable quad interrupts */
|
/* Enable quad interrupts */
|
||||||
err = ice_ptp_tx_ena_intr(pf, true, itr);
|
err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||||
if (err)
|
if (err)
|
||||||
@ -2881,13 +2897,6 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
|||||||
case ICE_PHY_E810:
|
case ICE_PHY_E810:
|
||||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||||
case ICE_PHY_E822:
|
case ICE_PHY_E822:
|
||||||
/* Non-owner PFs don't react to any interrupts on E82x,
|
|
||||||
* neither on own quad nor on others
|
|
||||||
*/
|
|
||||||
if (!ice_ptp_pf_handles_tx_interrupt(pf)) {
|
|
||||||
ice_ptp_configure_tx_tstamp(pf, false);
|
|
||||||
wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
|
||||||
}
|
|
||||||
kthread_init_delayed_work(&ptp_port->ov_work,
|
kthread_init_delayed_work(&ptp_port->ov_work,
|
||||||
ice_ptp_wait_for_offsets);
|
ice_ptp_wait_for_offsets);
|
||||||
|
|
||||||
@ -3032,6 +3041,9 @@ void ice_ptp_init(struct ice_pf *pf)
|
|||||||
/* Start the PHY timestamping block */
|
/* Start the PHY timestamping block */
|
||||||
ice_ptp_reset_phy_timestamping(pf);
|
ice_ptp_reset_phy_timestamping(pf);
|
||||||
|
|
||||||
|
/* Configure initial Tx interrupt settings */
|
||||||
|
ice_ptp_cfg_tx_interrupt(pf);
|
||||||
|
|
||||||
set_bit(ICE_FLAG_PTP, pf->flags);
|
set_bit(ICE_FLAG_PTP, pf->flags);
|
||||||
err = ice_ptp_init_work(pf, ptp);
|
err = ice_ptp_init_work(pf, ptp);
|
||||||
if (err)
|
if (err)
|
||||||
@ -3067,7 +3079,7 @@ void ice_ptp_release(struct ice_pf *pf)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Disable timestamping for both Tx and Rx */
|
/* Disable timestamping for both Tx and Rx */
|
||||||
ice_ptp_cfg_timestamp(pf, false);
|
ice_ptp_disable_timestamp_mode(pf);
|
||||||
|
|
||||||
ice_ptp_remove_auxbus_device(pf);
|
ice_ptp_remove_auxbus_device(pf);
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ int ice_ptp_clock_index(struct ice_pf *pf);
|
|||||||
struct ice_pf;
|
struct ice_pf;
|
||||||
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
||||||
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
||||||
void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena);
|
void ice_ptp_restore_timestamp_mode(struct ice_pf *pf);
|
||||||
|
|
||||||
void ice_ptp_extts_event(struct ice_pf *pf);
|
void ice_ptp_extts_event(struct ice_pf *pf);
|
||||||
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
|
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
|
||||||
@ -317,8 +317,7 @@ static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { }
|
static inline void ice_ptp_restore_timestamp_mode(struct ice_pf *pf) { }
|
||||||
|
|
||||||
static inline void ice_ptp_extts_event(struct ice_pf *pf) { }
|
static inline void ice_ptp_extts_event(struct ice_pf *pf) { }
|
||||||
static inline s8
|
static inline s8
|
||||||
ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||||
|
@ -2306,9 +2306,6 @@ ice_tstamp(struct ice_tx_ring *tx_ring, struct sk_buff *skb,
|
|||||||
if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)))
|
if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!tx_ring->ptp_tx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Tx timestamps cannot be sampled when doing TSO */
|
/* Tx timestamps cannot be sampled when doing TSO */
|
||||||
if (first->tx_flags & ICE_TX_FLAGS_TSO)
|
if (first->tx_flags & ICE_TX_FLAGS_TSO)
|
||||||
return;
|
return;
|
||||||
|
@ -380,7 +380,6 @@ struct ice_tx_ring {
|
|||||||
#define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2)
|
#define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2)
|
||||||
u8 flags;
|
u8 flags;
|
||||||
u8 dcb_tc; /* Traffic class of ring */
|
u8 dcb_tc; /* Traffic class of ring */
|
||||||
u8 ptp_tx;
|
|
||||||
} ____cacheline_internodealigned_in_smp;
|
} ____cacheline_internodealigned_in_smp;
|
||||||
|
|
||||||
static inline bool ice_ring_uses_build_skb(struct ice_rx_ring *ring)
|
static inline bool ice_ring_uses_build_skb(struct ice_rx_ring *ring)
|
||||||
|
@ -1088,6 +1088,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
|
|||||||
struct ethhdr *eth_hdr;
|
struct ethhdr *eth_hdr;
|
||||||
bool new = false;
|
bool new = false;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
u64 vf_num;
|
||||||
u32 ring;
|
u32 ring;
|
||||||
|
|
||||||
if (!flow_cfg->max_flows) {
|
if (!flow_cfg->max_flows) {
|
||||||
@ -1100,7 +1101,21 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
|
|||||||
if (!(pfvf->flags & OTX2_FLAG_NTUPLE_SUPPORT))
|
if (!(pfvf->flags & OTX2_FLAG_NTUPLE_SUPPORT))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (ring >= pfvf->hw.rx_queues && fsp->ring_cookie != RX_CLS_FLOW_DISC)
|
/* Number of queues on a VF can be greater or less than
|
||||||
|
* the PF's queue. Hence no need to check for the
|
||||||
|
* queue count. Hence no need to check queue count if PF
|
||||||
|
* is installing for its VF. Below is the expected vf_num value
|
||||||
|
* based on the ethtool commands.
|
||||||
|
*
|
||||||
|
* e.g.
|
||||||
|
* 1. ethtool -U <netdev> ... action -1 ==> vf_num:255
|
||||||
|
* 2. ethtool -U <netdev> ... action <queue_num> ==> vf_num:0
|
||||||
|
* 3. ethtool -U <netdev> ... vf <vf_idx> queue <queue_num> ==>
|
||||||
|
* vf_num:vf_idx+1
|
||||||
|
*/
|
||||||
|
vf_num = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie);
|
||||||
|
if (!is_otx2_vf(pfvf->pcifunc) && !vf_num &&
|
||||||
|
ring >= pfvf->hw.rx_queues && fsp->ring_cookie != RX_CLS_FLOW_DISC)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (fsp->location >= otx2_get_maxflows(flow_cfg))
|
if (fsp->location >= otx2_get_maxflows(flow_cfg))
|
||||||
@ -1182,6 +1197,9 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
|
|||||||
flow_cfg->nr_flows++;
|
flow_cfg->nr_flows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flow->is_vf)
|
||||||
|
netdev_info(pfvf->netdev,
|
||||||
|
"Make sure that VF's queue number is within its queue limit\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1934,6 +1934,8 @@ int otx2_stop(struct net_device *netdev)
|
|||||||
/* Clear RSS enable flag */
|
/* Clear RSS enable flag */
|
||||||
rss = &pf->hw.rss_info;
|
rss = &pf->hw.rss_info;
|
||||||
rss->enable = false;
|
rss->enable = false;
|
||||||
|
if (!netif_is_rxfh_configured(netdev))
|
||||||
|
kfree(rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]);
|
||||||
|
|
||||||
/* Cleanup Queue IRQ */
|
/* Cleanup Queue IRQ */
|
||||||
vec = pci_irq_vector(pf->pdev,
|
vec = pci_irq_vector(pf->pdev,
|
||||||
|
@ -2599,9 +2599,7 @@ static void rtl_set_rx_mode(struct net_device *dev)
|
|||||||
rx_mode &= ~AcceptMulticast;
|
rx_mode &= ~AcceptMulticast;
|
||||||
} else if (netdev_mc_count(dev) > MC_FILTER_LIMIT ||
|
} else if (netdev_mc_count(dev) > MC_FILTER_LIMIT ||
|
||||||
dev->flags & IFF_ALLMULTI ||
|
dev->flags & IFF_ALLMULTI ||
|
||||||
tp->mac_version == RTL_GIGA_MAC_VER_35 ||
|
tp->mac_version == RTL_GIGA_MAC_VER_35) {
|
||||||
tp->mac_version == RTL_GIGA_MAC_VER_46 ||
|
|
||||||
tp->mac_version == RTL_GIGA_MAC_VER_48) {
|
|
||||||
/* accept all multicasts */
|
/* accept all multicasts */
|
||||||
} else if (netdev_mc_empty(dev)) {
|
} else if (netdev_mc_empty(dev)) {
|
||||||
rx_mode &= ~AcceptMulticast;
|
rx_mode &= ~AcceptMulticast;
|
||||||
|
@ -280,7 +280,7 @@ config DWMAC_INTEL
|
|||||||
config DWMAC_LOONGSON
|
config DWMAC_LOONGSON
|
||||||
tristate "Loongson PCI DWMAC support"
|
tristate "Loongson PCI DWMAC support"
|
||||||
default MACH_LOONGSON64
|
default MACH_LOONGSON64
|
||||||
depends on STMMAC_ETH && PCI
|
depends on (MACH_LOONGSON64 || COMPILE_TEST) && STMMAC_ETH && PCI
|
||||||
depends on COMMON_CLK
|
depends on COMMON_CLK
|
||||||
help
|
help
|
||||||
This selects the LOONGSON PCI bus support for the stmmac driver,
|
This selects the LOONGSON PCI bus support for the stmmac driver,
|
||||||
|
@ -1769,10 +1769,12 @@ int wx_sw_init(struct wx *wx)
|
|||||||
wx->subsystem_device_id = pdev->subsystem_device;
|
wx->subsystem_device_id = pdev->subsystem_device;
|
||||||
} else {
|
} else {
|
||||||
err = wx_flash_read_dword(wx, 0xfffdc, &ssid);
|
err = wx_flash_read_dword(wx, 0xfffdc, &ssid);
|
||||||
if (!err)
|
if (err < 0) {
|
||||||
wx->subsystem_device_id = swab16((u16)ssid);
|
wx_err(wx, "read of internal subsystem device id failed\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
wx->subsystem_device_id = swab16((u16)ssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
wx->mac_table = kcalloc(wx->mac.num_rar_entries,
|
wx->mac_table = kcalloc(wx->mac.num_rar_entries,
|
||||||
|
@ -121,10 +121,8 @@ static int ngbe_sw_init(struct wx *wx)
|
|||||||
|
|
||||||
/* PCI config space info */
|
/* PCI config space info */
|
||||||
err = wx_sw_init(wx);
|
err = wx_sw_init(wx);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
wx_err(wx, "read of internal subsystem device id failed\n");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
/* mac type, phy type , oem type */
|
/* mac type, phy type , oem type */
|
||||||
ngbe_init_type_code(wx);
|
ngbe_init_type_code(wx);
|
||||||
|
@ -364,10 +364,8 @@ static int txgbe_sw_init(struct wx *wx)
|
|||||||
|
|
||||||
/* PCI config space info */
|
/* PCI config space info */
|
||||||
err = wx_sw_init(wx);
|
err = wx_sw_init(wx);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
wx_err(wx, "read of internal subsystem device id failed\n");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
txgbe_init_type_code(wx);
|
txgbe_init_type_code(wx);
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user