Merge tag 'v6.11-rc5' into android-mainline
Linux 6.11-rc5 Signed-off-by: Lee Jones <joneslee@google.com> Change-Id: I636ad79a57de4da27ea1c3bb8e91b864dab35c57
This commit is contained in:
@@ -260,7 +260,7 @@ Some users depend on strict execution ordering where only one work item
|
||||
is in flight at any given time and the work items are processed in
|
||||
queueing order. While the combination of ``@max_active`` of 1 and
|
||||
``WQ_UNBOUND`` used to achieve this behavior, this is no longer the
|
||||
case. Use ``alloc_ordered_queue()`` instead.
|
||||
case. Use alloc_ordered_workqueue() instead.
|
||||
|
||||
|
||||
Example Execution Scenarios
|
||||
|
||||
@@ -42,6 +42,7 @@ properties:
|
||||
- focaltech,ft5426
|
||||
- focaltech,ft5452
|
||||
- focaltech,ft6236
|
||||
- focaltech,ft8201
|
||||
- focaltech,ft8719
|
||||
|
||||
reg:
|
||||
|
||||
@@ -75,7 +75,7 @@ Here are the main features of EROFS:
|
||||
|
||||
- Support merging tail-end data into a special inode as fragments.
|
||||
|
||||
- Support large folios for uncompressed files.
|
||||
- Support large folios to make use of THPs (Transparent Hugepages);
|
||||
|
||||
- Support direct I/O on uncompressed files to avoid double caching for loop
|
||||
devices;
|
||||
|
||||
@@ -13,7 +13,7 @@ KSMBD architecture
|
||||
The subset of performance related operations belong in kernelspace and
|
||||
the other subset which belong to operations which are not really related with
|
||||
performance in userspace. So, DCE/RPC management that has historically resulted
|
||||
into number of buffer overflow issues and dangerous security bugs and user
|
||||
into a number of buffer overflow issues and dangerous security bugs and user
|
||||
account management are implemented in user space as ksmbd.mountd.
|
||||
File operations that are related with performance (open/read/write/close etc.)
|
||||
in kernel space (ksmbd). This also allows for easier integration with VFS
|
||||
@@ -24,8 +24,8 @@ ksmbd (kernel daemon)
|
||||
|
||||
When the server daemon is started, It starts up a forker thread
|
||||
(ksmbd/interface name) at initialization time and open a dedicated port 445
|
||||
for listening to SMB requests. Whenever new clients make request, Forker
|
||||
thread will accept the client connection and fork a new thread for dedicated
|
||||
for listening to SMB requests. Whenever new clients make a request, the Forker
|
||||
thread will accept the client connection and fork a new thread for a dedicated
|
||||
communication channel between the client and the server. It allows for parallel
|
||||
processing of SMB requests(commands) from clients as well as allowing for new
|
||||
clients to make new connections. Each instance is named ksmbd/1~n(port number)
|
||||
@@ -34,12 +34,12 @@ thread can decide to pass through the commands to the user space (ksmbd.mountd),
|
||||
currently DCE/RPC commands are identified to be handled through the user space.
|
||||
To further utilize the linux kernel, it has been chosen to process the commands
|
||||
as workitems and to be executed in the handlers of the ksmbd-io kworker threads.
|
||||
It allows for multiplexing of the handlers as the kernel take care of initiating
|
||||
It allows for multiplexing of the handlers as the kernel takes care of initiating
|
||||
extra worker threads if the load is increased and vice versa, if the load is
|
||||
decreased it destroys the extra worker threads. So, after connection is
|
||||
established with client. Dedicated ksmbd/1..n(port number) takes complete
|
||||
decreased it destroys the extra worker threads. So, after the connection is
|
||||
established with the client. Dedicated ksmbd/1..n(port number) takes complete
|
||||
ownership of receiving/parsing of SMB commands. Each received command is worked
|
||||
in parallel i.e., There can be multiple clients commands which are worked in
|
||||
in parallel i.e., there can be multiple client commands which are worked in
|
||||
parallel. After receiving each command a separated kernel workitem is prepared
|
||||
for each command which is further queued to be handled by ksmbd-io kworkers.
|
||||
So, each SMB workitem is queued to the kworkers. This allows the benefit of load
|
||||
@@ -49,9 +49,9 @@ performance by handling client commands in parallel.
|
||||
ksmbd.mountd (user space daemon)
|
||||
--------------------------------
|
||||
|
||||
ksmbd.mountd is userspace process to, transfer user account and password that
|
||||
ksmbd.mountd is a userspace process to, transfer the user account and password that
|
||||
are registered using ksmbd.adduser (part of utils for user space). Further it
|
||||
allows sharing information parameters that parsed from smb.conf to ksmbd in
|
||||
allows sharing information parameters that are parsed from smb.conf to ksmbd in
|
||||
kernel. For the execution part it has a daemon which is continuously running
|
||||
and connected to the kernel interface using netlink socket, it waits for the
|
||||
requests (dcerpc and share/user info). It handles RPC calls (at a minimum few
|
||||
@@ -124,7 +124,7 @@ How to run
|
||||
1. Download ksmbd-tools(https://github.com/cifsd-team/ksmbd-tools/releases) and
|
||||
compile them.
|
||||
|
||||
- Refer README(https://github.com/cifsd-team/ksmbd-tools/blob/master/README.md)
|
||||
- Refer to README(https://github.com/cifsd-team/ksmbd-tools/blob/master/README.md)
|
||||
to know how to use ksmbd.mountd/adduser/addshare/control utils
|
||||
|
||||
$ ./autogen.sh
|
||||
@@ -133,7 +133,7 @@ How to run
|
||||
|
||||
2. Create /usr/local/etc/ksmbd/ksmbd.conf file, add SMB share in ksmbd.conf file.
|
||||
|
||||
- Refer ksmbd.conf.example in ksmbd-utils, See ksmbd.conf manpage
|
||||
- Refer to ksmbd.conf.example in ksmbd-utils, See ksmbd.conf manpage
|
||||
for details to configure shares.
|
||||
|
||||
$ man ksmbd.conf
|
||||
@@ -145,7 +145,7 @@ How to run
|
||||
$ man ksmbd.adduser
|
||||
$ sudo ksmbd.adduser -a <Enter USERNAME for SMB share access>
|
||||
|
||||
4. Insert ksmbd.ko module after build your kernel. No need to load module
|
||||
4. Insert the ksmbd.ko module after you build your kernel. No need to load the module
|
||||
if ksmbd is built into the kernel.
|
||||
|
||||
- Set ksmbd in menuconfig(e.g. $ make menuconfig)
|
||||
@@ -175,7 +175,7 @@ Each layer
|
||||
1. Enable all component prints
|
||||
# sudo ksmbd.control -d "all"
|
||||
|
||||
2. Enable one of components (smb, auth, vfs, oplock, ipc, conn, rdma)
|
||||
2. Enable one of the components (smb, auth, vfs, oplock, ipc, conn, rdma)
|
||||
# sudo ksmbd.control -d "smb"
|
||||
|
||||
3. Show what prints are enabled.
|
||||
|
||||
@@ -126,7 +126,7 @@ Ccache
|
||||
|
||||
``ccache`` can be used with ``clang`` to improve subsequent builds, (though
|
||||
KBUILD_BUILD_TIMESTAMP_ should be set to a deterministic value between builds
|
||||
in order to avoid 100% cache misses, see Reproducible_builds_ for more info):
|
||||
in order to avoid 100% cache misses, see Reproducible_builds_ for more info)::
|
||||
|
||||
KBUILD_BUILD_TIMESTAMP='' make LLVM=1 CC="ccache clang"
|
||||
|
||||
|
||||
+29
-7
@@ -3504,7 +3504,9 @@ S: Maintained
|
||||
W: http://linux-atm.sourceforge.net
|
||||
F: drivers/atm/
|
||||
F: include/linux/atm*
|
||||
F: include/linux/sonet.h
|
||||
F: include/uapi/linux/atm*
|
||||
F: include/uapi/linux/sonet.h
|
||||
|
||||
ATMEL MACB ETHERNET DRIVER
|
||||
M: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
@@ -10173,7 +10175,7 @@ F: Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt
|
||||
F: drivers/infiniband/hw/hns/
|
||||
|
||||
HISILICON SAS Controller
|
||||
M: Xiang Chen <chenxiang66@hisilicon.com>
|
||||
M: Yihang Li <liyihang9@huawei.com>
|
||||
S: Supported
|
||||
W: http://www.hisilicon.com
|
||||
F: Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
|
||||
@@ -12000,7 +12002,7 @@ F: fs/jfs/
|
||||
JME NETWORK DRIVER
|
||||
M: Guo-Fu Tseng <cooldavid@cooldavid.org>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: drivers/net/ethernet/jme.*
|
||||
|
||||
JOURNALLING FLASH FILE SYSTEM V2 (JFFS2)
|
||||
@@ -15884,15 +15886,19 @@ F: drivers/net/
|
||||
F: include/dt-bindings/net/
|
||||
F: include/linux/cn_proc.h
|
||||
F: include/linux/etherdevice.h
|
||||
F: include/linux/ethtool_netlink.h
|
||||
F: include/linux/fcdevice.h
|
||||
F: include/linux/fddidevice.h
|
||||
F: include/linux/hippidevice.h
|
||||
F: include/linux/if_*
|
||||
F: include/linux/inetdevice.h
|
||||
F: include/linux/netdevice.h
|
||||
F: include/linux/netdev*
|
||||
F: include/linux/platform_data/wiznet.h
|
||||
F: include/uapi/linux/cn_proc.h
|
||||
F: include/uapi/linux/ethtool_netlink.h
|
||||
F: include/uapi/linux/if_*
|
||||
F: include/uapi/linux/netdevice.h
|
||||
F: include/uapi/linux/netdev*
|
||||
F: tools/testing/selftests/drivers/net/
|
||||
X: drivers/net/wireless/
|
||||
|
||||
NETWORKING DRIVERS (WIRELESS)
|
||||
@@ -15943,14 +15949,28 @@ F: include/linux/framer/framer-provider.h
|
||||
F: include/linux/framer/framer.h
|
||||
F: include/linux/in.h
|
||||
F: include/linux/indirect_call_wrapper.h
|
||||
F: include/linux/inet.h
|
||||
F: include/linux/inet_diag.h
|
||||
F: include/linux/net.h
|
||||
F: include/linux/netdevice.h
|
||||
F: include/linux/skbuff.h
|
||||
F: include/linux/netdev*
|
||||
F: include/linux/netlink.h
|
||||
F: include/linux/netpoll.h
|
||||
F: include/linux/rtnetlink.h
|
||||
F: include/linux/seq_file_net.h
|
||||
F: include/linux/skbuff*
|
||||
F: include/net/
|
||||
F: include/uapi/linux/genetlink.h
|
||||
F: include/uapi/linux/hsr_netlink.h
|
||||
F: include/uapi/linux/in.h
|
||||
F: include/uapi/linux/inet_diag.h
|
||||
F: include/uapi/linux/nbd-netlink.h
|
||||
F: include/uapi/linux/net.h
|
||||
F: include/uapi/linux/net_namespace.h
|
||||
F: include/uapi/linux/netdevice.h
|
||||
F: include/uapi/linux/netconf.h
|
||||
F: include/uapi/linux/netdev*
|
||||
F: include/uapi/linux/netlink.h
|
||||
F: include/uapi/linux/netlink_diag.h
|
||||
F: include/uapi/linux/rtnetlink.h
|
||||
F: lib/net_utils.c
|
||||
F: lib/random32.c
|
||||
F: net/
|
||||
@@ -20361,6 +20381,7 @@ F: Documentation/devicetree/bindings/scsi/
|
||||
F: drivers/scsi/
|
||||
F: drivers/ufs/
|
||||
F: include/scsi/
|
||||
F: include/uapi/scsi/
|
||||
|
||||
SCSI TAPE DRIVER
|
||||
M: Kai Mäkisara <Kai.Makisara@kolumbus.fi>
|
||||
@@ -21061,6 +21082,7 @@ SOCKET TIMESTAMPING
|
||||
M: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
|
||||
S: Maintained
|
||||
F: Documentation/networking/timestamping.rst
|
||||
F: include/linux/net_tstamp.h
|
||||
F: include/uapi/linux/net_tstamp.h
|
||||
F: tools/testing/selftests/net/so_txtime.c
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 11
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc4
|
||||
EXTRAVERSION = -rc5
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@@ -2026,7 +2026,7 @@ nsdeps: modules
|
||||
quiet_cmd_gen_compile_commands = GEN $@
|
||||
cmd_gen_compile_commands = $(PYTHON3) $< -a $(AR) -o $@ $(filter-out $<, $(real-prereqs))
|
||||
|
||||
$(extmod_prefix)compile_commands.json: scripts/clang-tools/gen_compile_commands.py \
|
||||
$(extmod_prefix)compile_commands.json: $(srctree)/scripts/clang-tools/gen_compile_commands.py \
|
||||
$(if $(KBUILD_EXTMOD)$(KBUILD_MIXED_TREE),, vmlinux.a $(KBUILD_VMLINUX_LIBS)) \
|
||||
$(if $(CONFIG_MODULES), $(MODORDER)) FORCE
|
||||
$(call if_changed,gen_compile_commands)
|
||||
|
||||
@@ -1540,8 +1540,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
|
||||
vma_pagesize = min(vma_pagesize, (long)max_map_size);
|
||||
}
|
||||
|
||||
if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE)
|
||||
/*
|
||||
* Both the canonical IPA and fault IPA must be hugepage-aligned to
|
||||
* ensure we find the right PFN and lay down the mapping in the right
|
||||
* place.
|
||||
*/
|
||||
if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE) {
|
||||
fault_ipa &= ~(vma_pagesize - 1);
|
||||
ipa &= ~(vma_pagesize - 1);
|
||||
}
|
||||
|
||||
gfn = ipa >> PAGE_SHIFT;
|
||||
mte_allowed = kvm_vma_mte_allowed(vma);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <trace/events/kvm.h>
|
||||
|
||||
#include "sys_regs.h"
|
||||
#include "vgic/vgic.h"
|
||||
|
||||
#include "trace.h"
|
||||
|
||||
@@ -435,6 +436,11 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
bool g1;
|
||||
|
||||
if (!kvm_has_gicv3(vcpu->kvm)) {
|
||||
kvm_inject_undefined(vcpu);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!p->is_write)
|
||||
return read_from_write_only(vcpu, p, r);
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ static void iter_unmark_lpis(struct kvm *kvm)
|
||||
struct vgic_irq *irq;
|
||||
unsigned long intid;
|
||||
|
||||
xa_for_each(&dist->lpi_xa, intid, irq) {
|
||||
xa_for_each_marked(&dist->lpi_xa, intid, irq, LPI_XA_MARK_DEBUG_ITER) {
|
||||
xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER);
|
||||
vgic_put_irq(kvm, irq);
|
||||
}
|
||||
|
||||
@@ -417,10 +417,8 @@ static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
|
||||
kfree(vgic_cpu->private_irqs);
|
||||
vgic_cpu->private_irqs = NULL;
|
||||
|
||||
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
|
||||
vgic_unregister_redist_iodev(vcpu);
|
||||
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
|
||||
vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
|
||||
@@ -448,6 +446,11 @@ void kvm_vgic_destroy(struct kvm *kvm)
|
||||
kvm_vgic_dist_destroy(kvm);
|
||||
|
||||
mutex_unlock(&kvm->arch.config_lock);
|
||||
|
||||
if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
|
||||
kvm_for_each_vcpu(i, vcpu, kvm)
|
||||
vgic_unregister_redist_iodev(vcpu);
|
||||
|
||||
mutex_unlock(&kvm->slots_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,11 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
|
||||
* we have to disable IRQs before taking this lock and everything lower
|
||||
* than it.
|
||||
*
|
||||
* The config_lock has additional ordering requirements:
|
||||
* kvm->slots_lock
|
||||
* kvm->srcu
|
||||
* kvm->arch.config_lock
|
||||
*
|
||||
* If you need to take multiple locks, always take the upper lock first,
|
||||
* then the lower ones, e.g. first take the its_lock, then the irq_lock.
|
||||
* If you are already holding a lock and need to take a higher one, you
|
||||
|
||||
@@ -346,4 +346,11 @@ void vgic_v4_configure_vsgis(struct kvm *kvm);
|
||||
void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val);
|
||||
int vgic_v4_request_vpe_irq(struct kvm_vcpu *vcpu, int irq);
|
||||
|
||||
static inline bool kvm_has_gicv3(struct kvm *kvm)
|
||||
{
|
||||
return (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) &&
|
||||
irqchip_in_kernel(kvm) &&
|
||||
kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -303,13 +303,6 @@ int r4k_clockevent_init(void)
|
||||
if (!c0_compare_int_usable())
|
||||
return -ENXIO;
|
||||
|
||||
/*
|
||||
* With vectored interrupts things are getting platform specific.
|
||||
* get_c0_compare_int is a hook to allow a platform to return the
|
||||
* interrupt number of its liking.
|
||||
*/
|
||||
irq = get_c0_compare_int();
|
||||
|
||||
cd = &per_cpu(mips_clockevent_device, cpu);
|
||||
|
||||
cd->name = "MIPS";
|
||||
@@ -320,7 +313,6 @@ int r4k_clockevent_init(void)
|
||||
min_delta = calculate_min_delta();
|
||||
|
||||
cd->rating = 300;
|
||||
cd->irq = irq;
|
||||
cd->cpumask = cpumask_of(cpu);
|
||||
cd->set_next_event = mips_next_event;
|
||||
cd->event_handler = mips_event_handler;
|
||||
@@ -332,6 +324,13 @@ int r4k_clockevent_init(void)
|
||||
|
||||
cp0_timer_irq_installed = 1;
|
||||
|
||||
/*
|
||||
* With vectored interrupts things are getting platform specific.
|
||||
* get_c0_compare_int is a hook to allow a platform to return the
|
||||
* interrupt number of its liking.
|
||||
*/
|
||||
irq = get_c0_compare_int();
|
||||
|
||||
if (request_irq(irq, c0_compare_interrupt, flags, "timer",
|
||||
c0_compare_interrupt))
|
||||
pr_err("Failed to request irq %d (timer)\n", irq);
|
||||
|
||||
@@ -1724,12 +1724,16 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
|
||||
MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
|
||||
c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */
|
||||
change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER,
|
||||
LOONGSON_CONF6_INTIMER);
|
||||
break;
|
||||
case PRID_IMP_LOONGSON_64G:
|
||||
__cpu_name[cpu] = "ICT Loongson-3";
|
||||
set_elf_platform(cpu, "loongson3a");
|
||||
set_isa(c, MIPS_CPU_ISA_M64R2);
|
||||
decode_cpucfg(c);
|
||||
change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER,
|
||||
LOONGSON_CONF6_INTIMER);
|
||||
break;
|
||||
default:
|
||||
panic("Unknown Loongson Processor ID!");
|
||||
|
||||
@@ -604,6 +604,19 @@ config RANDOMIZE_BASE
|
||||
as a security feature that deters exploit attempts relying on
|
||||
knowledge of the location of kernel internals.
|
||||
|
||||
config RANDOMIZE_IDENTITY_BASE
|
||||
bool "Randomize the address of the identity mapping base"
|
||||
depends on RANDOMIZE_BASE
|
||||
default DEBUG_VM
|
||||
help
|
||||
The identity mapping base address is pinned to zero by default.
|
||||
Allow randomization of that base to expose otherwise missed
|
||||
notion of physical and virtual addresses of data structures.
|
||||
That does not have any impact on the base address at which the
|
||||
kernel image is loaded.
|
||||
|
||||
If unsure, say N
|
||||
|
||||
config KERNEL_IMAGE_BASE
|
||||
hex "Kernel image base address"
|
||||
range 0x100000 0x1FFFFFE0000000 if !KASAN
|
||||
|
||||
+32
-26
@@ -162,7 +162,7 @@ static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
|
||||
loc = (long)*reloc + phys_offset;
|
||||
if (loc < min_addr || loc > max_addr)
|
||||
error("64-bit relocation outside of kernel!\n");
|
||||
*(u64 *)loc += offset - __START_KERNEL;
|
||||
*(u64 *)loc += offset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ static void kaslr_adjust_got(unsigned long offset)
|
||||
*/
|
||||
for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++) {
|
||||
if (*entry)
|
||||
*entry += offset - __START_KERNEL;
|
||||
*entry += offset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ static unsigned long setup_kernel_memory_layout(unsigned long kernel_size)
|
||||
vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page);
|
||||
|
||||
/* choose kernel address space layout: 4 or 3 levels. */
|
||||
BUILD_BUG_ON(!IS_ALIGNED(__START_KERNEL, THREAD_SIZE));
|
||||
BUILD_BUG_ON(!IS_ALIGNED(TEXT_OFFSET, THREAD_SIZE));
|
||||
BUILD_BUG_ON(!IS_ALIGNED(__NO_KASLR_START_KERNEL, THREAD_SIZE));
|
||||
BUILD_BUG_ON(__NO_KASLR_END_KERNEL > _REGION1_SIZE);
|
||||
vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION3_SIZE);
|
||||
@@ -341,7 +341,8 @@ static unsigned long setup_kernel_memory_layout(unsigned long kernel_size)
|
||||
BUILD_BUG_ON(MAX_DCSS_ADDR > (1UL << MAX_PHYSMEM_BITS));
|
||||
max_mappable = max(ident_map_size, MAX_DCSS_ADDR);
|
||||
max_mappable = min(max_mappable, vmemmap_start);
|
||||
__identity_base = round_down(vmemmap_start - max_mappable, rte_size);
|
||||
if (IS_ENABLED(CONFIG_RANDOMIZE_IDENTITY_BASE))
|
||||
__identity_base = round_down(vmemmap_start - max_mappable, rte_size);
|
||||
|
||||
return asce_limit;
|
||||
}
|
||||
@@ -388,31 +389,25 @@ static void kaslr_adjust_vmlinux_info(long offset)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fixup_vmlinux_info(void)
|
||||
{
|
||||
vmlinux.entry -= __START_KERNEL;
|
||||
kaslr_adjust_vmlinux_info(-__START_KERNEL);
|
||||
}
|
||||
|
||||
void startup_kernel(void)
|
||||
{
|
||||
unsigned long kernel_size = vmlinux.image_size + vmlinux.bss_size;
|
||||
unsigned long nokaslr_offset_phys, kaslr_large_page_offset;
|
||||
unsigned long amode31_lma = 0;
|
||||
unsigned long vmlinux_size = vmlinux.image_size + vmlinux.bss_size;
|
||||
unsigned long nokaslr_text_lma, text_lma = 0, amode31_lma = 0;
|
||||
unsigned long kernel_size = TEXT_OFFSET + vmlinux_size;
|
||||
unsigned long kaslr_large_page_offset;
|
||||
unsigned long max_physmem_end;
|
||||
unsigned long asce_limit;
|
||||
unsigned long safe_addr;
|
||||
psw_t psw;
|
||||
|
||||
fixup_vmlinux_info();
|
||||
setup_lpp();
|
||||
|
||||
/*
|
||||
* Non-randomized kernel physical start address must be _SEGMENT_SIZE
|
||||
* aligned (see blow).
|
||||
*/
|
||||
nokaslr_offset_phys = ALIGN(mem_safe_offset(), _SEGMENT_SIZE);
|
||||
safe_addr = PAGE_ALIGN(nokaslr_offset_phys + kernel_size);
|
||||
nokaslr_text_lma = ALIGN(mem_safe_offset(), _SEGMENT_SIZE);
|
||||
safe_addr = PAGE_ALIGN(nokaslr_text_lma + vmlinux_size);
|
||||
|
||||
/*
|
||||
* Reserve decompressor memory together with decompression heap,
|
||||
@@ -456,16 +451,27 @@ void startup_kernel(void)
|
||||
*/
|
||||
kaslr_large_page_offset = __kaslr_offset & ~_SEGMENT_MASK;
|
||||
if (kaslr_enabled()) {
|
||||
unsigned long end = ident_map_size - kaslr_large_page_offset;
|
||||
unsigned long size = vmlinux_size + kaslr_large_page_offset;
|
||||
|
||||
__kaslr_offset_phys = randomize_within_range(kernel_size, _SEGMENT_SIZE, 0, end);
|
||||
text_lma = randomize_within_range(size, _SEGMENT_SIZE, TEXT_OFFSET, ident_map_size);
|
||||
}
|
||||
if (!__kaslr_offset_phys)
|
||||
__kaslr_offset_phys = nokaslr_offset_phys;
|
||||
__kaslr_offset_phys |= kaslr_large_page_offset;
|
||||
if (!text_lma)
|
||||
text_lma = nokaslr_text_lma;
|
||||
text_lma |= kaslr_large_page_offset;
|
||||
|
||||
/*
|
||||
* [__kaslr_offset_phys..__kaslr_offset_phys + TEXT_OFFSET] region is
|
||||
* never accessed via the kernel image mapping as per the linker script:
|
||||
*
|
||||
* . = TEXT_OFFSET;
|
||||
*
|
||||
* Therefore, this region could be used for something else and does
|
||||
* not need to be reserved. See how it is skipped in setup_vmem().
|
||||
*/
|
||||
__kaslr_offset_phys = text_lma - TEXT_OFFSET;
|
||||
kaslr_adjust_vmlinux_info(__kaslr_offset_phys);
|
||||
physmem_reserve(RR_VMLINUX, __kaslr_offset_phys, kernel_size);
|
||||
deploy_kernel((void *)__kaslr_offset_phys);
|
||||
physmem_reserve(RR_VMLINUX, text_lma, vmlinux_size);
|
||||
deploy_kernel((void *)text_lma);
|
||||
|
||||
/* vmlinux decompression is done, shrink reserved low memory */
|
||||
physmem_reserve(RR_DECOMPRESSOR, 0, (unsigned long)_decompressor_end);
|
||||
@@ -488,7 +494,7 @@ void startup_kernel(void)
|
||||
amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, amode31_min, SZ_2G);
|
||||
}
|
||||
if (!amode31_lma)
|
||||
amode31_lma = __kaslr_offset_phys - vmlinux.amode31_size;
|
||||
amode31_lma = text_lma - vmlinux.amode31_size;
|
||||
physmem_reserve(RR_AMODE31, amode31_lma, vmlinux.amode31_size);
|
||||
|
||||
/*
|
||||
@@ -504,8 +510,8 @@ void startup_kernel(void)
|
||||
* - copy_bootdata() must follow setup_vmem() to propagate changes
|
||||
* to bootdata made by setup_vmem()
|
||||
*/
|
||||
clear_bss_section(__kaslr_offset_phys);
|
||||
kaslr_adjust_relocs(__kaslr_offset_phys, __kaslr_offset_phys + vmlinux.image_size,
|
||||
clear_bss_section(text_lma);
|
||||
kaslr_adjust_relocs(text_lma, text_lma + vmlinux.image_size,
|
||||
__kaslr_offset, __kaslr_offset_phys);
|
||||
kaslr_adjust_got(__kaslr_offset);
|
||||
setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit);
|
||||
|
||||
+12
-2
@@ -90,7 +90,7 @@ static void kasan_populate_shadow(unsigned long kernel_start, unsigned long kern
|
||||
}
|
||||
memgap_start = end;
|
||||
}
|
||||
kasan_populate(kernel_start, kernel_end, POPULATE_KASAN_MAP_SHADOW);
|
||||
kasan_populate(kernel_start + TEXT_OFFSET, kernel_end, POPULATE_KASAN_MAP_SHADOW);
|
||||
kasan_populate(0, (unsigned long)__identity_va(0), POPULATE_KASAN_ZERO_SHADOW);
|
||||
kasan_populate(AMODE31_START, AMODE31_END, POPULATE_KASAN_ZERO_SHADOW);
|
||||
if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
|
||||
@@ -475,7 +475,17 @@ void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned l
|
||||
(unsigned long)__identity_va(end),
|
||||
POPULATE_IDENTITY);
|
||||
}
|
||||
pgtable_populate(kernel_start, kernel_end, POPULATE_KERNEL);
|
||||
|
||||
/*
|
||||
* [kernel_start..kernel_start + TEXT_OFFSET] region is never
|
||||
* accessed as per the linker script:
|
||||
*
|
||||
* . = TEXT_OFFSET;
|
||||
*
|
||||
* Therefore, skip mapping TEXT_OFFSET bytes to prevent access to
|
||||
* [__kaslr_offset_phys..__kaslr_offset_phys + TEXT_OFFSET] region.
|
||||
*/
|
||||
pgtable_populate(kernel_start + TEXT_OFFSET, kernel_end, POPULATE_KERNEL);
|
||||
pgtable_populate(AMODE31_START, AMODE31_END, POPULATE_DIRECT);
|
||||
pgtable_populate(__abs_lowcore, __abs_lowcore + sizeof(struct lowcore),
|
||||
POPULATE_ABS_LOWCORE);
|
||||
|
||||
@@ -109,7 +109,12 @@ SECTIONS
|
||||
#ifdef CONFIG_KERNEL_UNCOMPRESSED
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
. += AMODE31_SIZE; /* .amode31 section */
|
||||
. = ALIGN(1 << 20); /* _SEGMENT_SIZE */
|
||||
|
||||
/*
|
||||
* Make sure the location counter is not less than TEXT_OFFSET.
|
||||
* _SEGMENT_SIZE is not available, use ALIGN(1 << 20) instead.
|
||||
*/
|
||||
. = MAX(TEXT_OFFSET, ALIGN(1 << 20));
|
||||
#else
|
||||
. = ALIGN(8);
|
||||
#endif
|
||||
|
||||
@@ -279,8 +279,9 @@ static inline unsigned long virt_to_pfn(const void *kaddr)
|
||||
#define AMODE31_SIZE (3 * PAGE_SIZE)
|
||||
|
||||
#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024)
|
||||
#define __START_KERNEL 0x100000
|
||||
#define __NO_KASLR_START_KERNEL CONFIG_KERNEL_IMAGE_BASE
|
||||
#define __NO_KASLR_END_KERNEL (__NO_KASLR_START_KERNEL + KERNEL_IMAGE_SIZE)
|
||||
|
||||
#define TEXT_OFFSET 0x100000
|
||||
|
||||
#endif /* _S390_PAGE_H */
|
||||
|
||||
@@ -734,7 +734,23 @@ static void __init memblock_add_physmem_info(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Reserve memory used for lowcore/command line/kernel image.
|
||||
* Reserve memory used for lowcore.
|
||||
*/
|
||||
static void __init reserve_lowcore(void)
|
||||
{
|
||||
void *lowcore_start = get_lowcore();
|
||||
void *lowcore_end = lowcore_start + sizeof(struct lowcore);
|
||||
void *start, *end;
|
||||
|
||||
if ((void *)__identity_base < lowcore_end) {
|
||||
start = max(lowcore_start, (void *)__identity_base);
|
||||
end = min(lowcore_end, (void *)(__identity_base + ident_map_size));
|
||||
memblock_reserve(__pa(start), __pa(end));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reserve memory used for absolute lowcore/command line/kernel image.
|
||||
*/
|
||||
static void __init reserve_kernel(void)
|
||||
{
|
||||
@@ -918,6 +934,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
/* Do some memory reservations *before* memory is added to memblock */
|
||||
reserve_pgtables();
|
||||
reserve_lowcore();
|
||||
reserve_kernel();
|
||||
reserve_initrd();
|
||||
reserve_certificate_list();
|
||||
|
||||
@@ -39,7 +39,7 @@ PHDRS {
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = __START_KERNEL;
|
||||
. = TEXT_OFFSET;
|
||||
.text : {
|
||||
_stext = .; /* Start of text section */
|
||||
_text = .; /* Text and read-only data */
|
||||
|
||||
@@ -280,7 +280,7 @@ static int do_reloc(struct section *sec, Elf_Rel *rel)
|
||||
case R_390_GOTOFF64:
|
||||
break;
|
||||
case R_390_64:
|
||||
add_reloc(&relocs64, offset - ehdr.e_entry);
|
||||
add_reloc(&relocs64, offset);
|
||||
break;
|
||||
default:
|
||||
die("Unsupported relocation type: %d\n", r_type);
|
||||
|
||||
+18
-7
@@ -111,13 +111,20 @@ static sector_t bio_write_zeroes_limit(struct block_device *bdev)
|
||||
(UINT_MAX >> SECTOR_SHIFT) & ~bs_mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no reliable way for the SCSI subsystem to determine whether a
|
||||
* device supports a WRITE SAME operation without actually performing a write
|
||||
* to media. As a result, write_zeroes is enabled by default and will be
|
||||
* disabled if a zeroing operation subsequently fails. This means that this
|
||||
* queue limit is likely to change at runtime.
|
||||
*/
|
||||
static void __blkdev_issue_write_zeroes(struct block_device *bdev,
|
||||
sector_t sector, sector_t nr_sects, gfp_t gfp_mask,
|
||||
struct bio **biop, unsigned flags)
|
||||
struct bio **biop, unsigned flags, sector_t limit)
|
||||
{
|
||||
|
||||
while (nr_sects) {
|
||||
unsigned int len = min_t(sector_t, nr_sects,
|
||||
bio_write_zeroes_limit(bdev));
|
||||
unsigned int len = min(nr_sects, limit);
|
||||
struct bio *bio;
|
||||
|
||||
if ((flags & BLKDEV_ZERO_KILLABLE) &&
|
||||
@@ -141,12 +148,14 @@ static void __blkdev_issue_write_zeroes(struct block_device *bdev,
|
||||
static int blkdev_issue_write_zeroes(struct block_device *bdev, sector_t sector,
|
||||
sector_t nr_sects, gfp_t gfp, unsigned flags)
|
||||
{
|
||||
sector_t limit = bio_write_zeroes_limit(bdev);
|
||||
struct bio *bio = NULL;
|
||||
struct blk_plug plug;
|
||||
int ret = 0;
|
||||
|
||||
blk_start_plug(&plug);
|
||||
__blkdev_issue_write_zeroes(bdev, sector, nr_sects, gfp, &bio, flags);
|
||||
__blkdev_issue_write_zeroes(bdev, sector, nr_sects, gfp, &bio,
|
||||
flags, limit);
|
||||
if (bio) {
|
||||
if ((flags & BLKDEV_ZERO_KILLABLE) &&
|
||||
fatal_signal_pending(current)) {
|
||||
@@ -165,7 +174,7 @@ static int blkdev_issue_write_zeroes(struct block_device *bdev, sector_t sector,
|
||||
* on an I/O error, in which case we'll turn any error into
|
||||
* "not supported" here.
|
||||
*/
|
||||
if (ret && !bdev_write_zeroes_sectors(bdev))
|
||||
if (ret && !limit)
|
||||
return -EOPNOTSUPP;
|
||||
return ret;
|
||||
}
|
||||
@@ -265,12 +274,14 @@ int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
|
||||
sector_t nr_sects, gfp_t gfp_mask, struct bio **biop,
|
||||
unsigned flags)
|
||||
{
|
||||
sector_t limit = bio_write_zeroes_limit(bdev);
|
||||
|
||||
if (bdev_read_only(bdev))
|
||||
return -EPERM;
|
||||
|
||||
if (bdev_write_zeroes_sectors(bdev)) {
|
||||
if (limit) {
|
||||
__blkdev_issue_write_zeroes(bdev, sector, nr_sects,
|
||||
gfp_mask, biop, flags);
|
||||
gfp_mask, biop, flags, limit);
|
||||
} else {
|
||||
if (flags & BLKDEV_ZERO_NOFALLBACK)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <stdio.h>
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
#include <linux/version.h>
|
||||
#include <ctype.h>
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <stdio.h>
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
#include <linux/version.h>
|
||||
#include <ctype.h>
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ static void acpi_video_parse_cmdline(void)
|
||||
acpi_backlight_cmdline = acpi_backlight_nvidia_wmi_ec;
|
||||
if (!strcmp("apple_gmux", acpi_video_backlight_string))
|
||||
acpi_backlight_cmdline = acpi_backlight_apple_gmux;
|
||||
if (!strcmp("dell_uart", acpi_video_backlight_string))
|
||||
acpi_backlight_cmdline = acpi_backlight_dell_uart;
|
||||
if (!strcmp("none", acpi_video_backlight_string))
|
||||
acpi_backlight_cmdline = acpi_backlight_none;
|
||||
}
|
||||
@@ -821,6 +823,21 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Dell AIO (All in Ones) which advertise an UART attached backlight
|
||||
* controller board in their ACPI tables (and may even have one), but
|
||||
* which need native backlight control nevertheless.
|
||||
*/
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=2303936 */
|
||||
.callback = video_detect_force_native,
|
||||
/* Dell OptiPlex 7760 AIO */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7760 AIO"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Models which have nvidia-ec-wmi support, but should not use it.
|
||||
* Note this indicates a likely firmware bug on these models and should
|
||||
@@ -918,6 +935,7 @@ enum acpi_backlight_type __acpi_video_get_backlight_type(bool native, bool *auto
|
||||
static DEFINE_MUTEX(init_mutex);
|
||||
static bool nvidia_wmi_ec_present;
|
||||
static bool apple_gmux_present;
|
||||
static bool dell_uart_present;
|
||||
static bool native_available;
|
||||
static bool init_done;
|
||||
static long video_caps;
|
||||
@@ -932,6 +950,7 @@ enum acpi_backlight_type __acpi_video_get_backlight_type(bool native, bool *auto
|
||||
&video_caps, NULL);
|
||||
nvidia_wmi_ec_present = nvidia_wmi_ec_supported();
|
||||
apple_gmux_present = apple_gmux_detect(NULL, NULL);
|
||||
dell_uart_present = acpi_dev_present("DELL0501", NULL, -1);
|
||||
init_done = true;
|
||||
}
|
||||
if (native)
|
||||
@@ -962,6 +981,9 @@ enum acpi_backlight_type __acpi_video_get_backlight_type(bool native, bool *auto
|
||||
if (apple_gmux_present)
|
||||
return acpi_backlight_apple_gmux;
|
||||
|
||||
if (dell_uart_present)
|
||||
return acpi_backlight_dell_uart;
|
||||
|
||||
/* Use ACPI video if available, except when native should be preferred. */
|
||||
if ((video_caps & ACPI_VIDEO_BACKLIGHT) &&
|
||||
!(native_available && prefer_native_over_acpi_video()))
|
||||
|
||||
+20
-10
@@ -208,6 +208,19 @@ static const char* macio_ata_names[] = {
|
||||
/* Don't let a DMA segment go all the way to 64K */
|
||||
#define MAX_DBDMA_SEG 0xff00
|
||||
|
||||
#ifdef CONFIG_PAGE_SIZE_64KB
|
||||
/*
|
||||
* The SCSI core requires the segment size to cover at least a page, so
|
||||
* for 64K page size kernels it must be at least 64K. However the
|
||||
* hardware can't handle 64K, so pata_macio_qc_prep() will split large
|
||||
* requests. To handle the split requests the tablesize must be halved.
|
||||
*/
|
||||
#define PATA_MACIO_MAX_SEGMENT_SIZE SZ_64K
|
||||
#define PATA_MACIO_SG_TABLESIZE (MAX_DCMDS / 2)
|
||||
#else
|
||||
#define PATA_MACIO_MAX_SEGMENT_SIZE MAX_DBDMA_SEG
|
||||
#define PATA_MACIO_SG_TABLESIZE MAX_DCMDS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wait 1s for disk to answer on IDE bus after a hard reset
|
||||
@@ -541,7 +554,8 @@ static enum ata_completion_errors pata_macio_qc_prep(struct ata_queued_cmd *qc)
|
||||
|
||||
while (sg_len) {
|
||||
/* table overflow should never happen */
|
||||
BUG_ON (pi++ >= MAX_DCMDS);
|
||||
if (WARN_ON_ONCE(pi >= MAX_DCMDS))
|
||||
return AC_ERR_SYSTEM;
|
||||
|
||||
len = (sg_len < MAX_DBDMA_SEG) ? sg_len : MAX_DBDMA_SEG;
|
||||
table->command = cpu_to_le16(write ? OUTPUT_MORE: INPUT_MORE);
|
||||
@@ -553,11 +567,13 @@ static enum ata_completion_errors pata_macio_qc_prep(struct ata_queued_cmd *qc)
|
||||
addr += len;
|
||||
sg_len -= len;
|
||||
++table;
|
||||
++pi;
|
||||
}
|
||||
}
|
||||
|
||||
/* Should never happen according to Tejun */
|
||||
BUG_ON(!pi);
|
||||
if (WARN_ON_ONCE(!pi))
|
||||
return AC_ERR_SYSTEM;
|
||||
|
||||
/* Convert the last command to an input/output */
|
||||
table--;
|
||||
@@ -912,16 +928,10 @@ static int pata_macio_do_resume(struct pata_macio_priv *priv)
|
||||
|
||||
static const struct scsi_host_template pata_macio_sht = {
|
||||
__ATA_BASE_SHT(DRV_NAME),
|
||||
.sg_tablesize = MAX_DCMDS,
|
||||
.sg_tablesize = PATA_MACIO_SG_TABLESIZE,
|
||||
/* We may not need that strict one */
|
||||
.dma_boundary = ATA_DMA_BOUNDARY,
|
||||
/*
|
||||
* The SCSI core requires the segment size to cover at least a page, so
|
||||
* for 64K page size kernels this must be at least 64K. However the
|
||||
* hardware can't handle 64K, so pata_macio_qc_prep() will split large
|
||||
* requests.
|
||||
*/
|
||||
.max_segment_size = SZ_64K,
|
||||
.max_segment_size = PATA_MACIO_MAX_SEGMENT_SIZE,
|
||||
.device_configure = pata_macio_device_configure,
|
||||
.sdev_groups = ata_common_sdev_groups,
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
|
||||
@@ -2945,9 +2945,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
|
||||
INTEL_ROM_LEGACY_NO_WBS_SUPPORT))
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
|
||||
&hdev->quirks);
|
||||
if (ver.hw_variant == 0x08 && ver.fw_variant == 0x22)
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES,
|
||||
&hdev->quirks);
|
||||
|
||||
err = btintel_legacy_rom_setup(hdev, &ver);
|
||||
break;
|
||||
@@ -2956,7 +2953,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
|
||||
case 0x12: /* ThP */
|
||||
case 0x13: /* HrP */
|
||||
case 0x14: /* CcP */
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
fallthrough;
|
||||
case 0x0c: /* WsP */
|
||||
/* Apply the device specific HCI quirks
|
||||
@@ -3048,9 +3044,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
|
||||
/* These variants don't seem to support LE Coded PHY */
|
||||
set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
|
||||
|
||||
/* Set Valid LE States quirk */
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
|
||||
/* Setup MSFT Extension support */
|
||||
btintel_set_msft_opcode(hdev, ver.hw_variant);
|
||||
|
||||
@@ -3076,9 +3069,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
|
||||
*/
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
|
||||
/* Apply LE States quirk from solar onwards */
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
|
||||
/* Setup MSFT Extension support */
|
||||
btintel_set_msft_opcode(hdev,
|
||||
INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
|
||||
|
||||
@@ -1180,9 +1180,6 @@ static int btintel_pcie_setup(struct hci_dev *hdev)
|
||||
*/
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
|
||||
/* Apply LE States quirk from solar onwards */
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
|
||||
/* Setup MSFT Extension support */
|
||||
btintel_set_msft_opcode(hdev,
|
||||
INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
|
||||
|
||||
@@ -1148,9 +1148,6 @@ static int btmtksdio_setup(struct hci_dev *hdev)
|
||||
}
|
||||
}
|
||||
|
||||
/* Valid LE States quirk for MediaTek 7921 */
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
|
||||
break;
|
||||
case 0x7663:
|
||||
case 0x7668:
|
||||
|
||||
@@ -1287,7 +1287,6 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
|
||||
case CHIP_ID_8852C:
|
||||
case CHIP_ID_8851B:
|
||||
case CHIP_ID_8852BT:
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
|
||||
/* RTL8852C needs to transmit mSBC data continuously without
|
||||
|
||||
@@ -3956,8 +3956,8 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
if (id->driver_info & BTUSB_WIDEBAND_SPEECH)
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
|
||||
if (id->driver_info & BTUSB_VALID_LE_STATES)
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
if (!(id->driver_info & BTUSB_VALID_LE_STATES))
|
||||
set_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks);
|
||||
|
||||
if (id->driver_info & BTUSB_DIGIANSWER) {
|
||||
data->cmdreq_type = USB_TYPE_VENDOR;
|
||||
|
||||
@@ -2474,8 +2474,8 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
|
||||
&hdev->quirks);
|
||||
|
||||
if (data->capabilities & QCA_CAP_VALID_LE_STATES)
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
if (!(data->capabilities & QCA_CAP_VALID_LE_STATES))
|
||||
set_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -425,8 +425,6 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
|
||||
if (opcode & 0x80)
|
||||
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
|
||||
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
|
||||
if (hci_register_dev(hdev) < 0) {
|
||||
BT_ERR("Can't register HCI device");
|
||||
hci_free_dev(hdev);
|
||||
|
||||
@@ -834,11 +834,13 @@ static void cxl_disable_rch_root_ints(struct cxl_dport *dport)
|
||||
void cxl_setup_parent_dport(struct device *host, struct cxl_dport *dport)
|
||||
{
|
||||
struct device *dport_dev = dport->dport_dev;
|
||||
struct pci_host_bridge *host_bridge;
|
||||
|
||||
host_bridge = to_pci_host_bridge(dport_dev);
|
||||
if (host_bridge->native_aer)
|
||||
dport->rcrb.aer_cap = cxl_rcrb_to_aer(dport_dev, dport->rcrb.base);
|
||||
if (dport->rch) {
|
||||
struct pci_host_bridge *host_bridge = to_pci_host_bridge(dport_dev);
|
||||
|
||||
if (host_bridge->native_aer)
|
||||
dport->rcrb.aer_cap = cxl_rcrb_to_aer(dport_dev, dport->rcrb.base);
|
||||
}
|
||||
|
||||
dport->reg_map.host = host;
|
||||
cxl_dport_map_regs(dport);
|
||||
|
||||
@@ -278,7 +278,7 @@ static int amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev,
|
||||
msg = RREG32(mmMP0_SMN_C2PMSG_33);
|
||||
if (msg & 0x80000000)
|
||||
break;
|
||||
usleep_range(1000, 1100);
|
||||
msleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -166,6 +166,9 @@ static ssize_t ta_if_load_debugfs_write(struct file *fp, const char *buf, size_t
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
if (ta_bin_len > PSP_1_MEG)
|
||||
return -EINVAL;
|
||||
|
||||
copy_pos += sizeof(uint32_t);
|
||||
|
||||
ta_bin = kzalloc(ta_bin_len, GFP_KERNEL);
|
||||
|
||||
@@ -4116,6 +4116,7 @@ static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev)
|
||||
|
||||
static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
char fw_name[53];
|
||||
char ucode_prefix[30];
|
||||
const char *wks = "";
|
||||
int err;
|
||||
@@ -4149,8 +4150,8 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_CE);
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw,
|
||||
"amdgpu/%s_rlc.bin", ucode_prefix);
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix);
|
||||
err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -176,14 +176,16 @@ static void sdma_v5_2_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n",
|
||||
ring->doorbell_index, ring->wptr << 2);
|
||||
WDOORBELL64(ring->doorbell_index, ring->wptr << 2);
|
||||
/* SDMA seems to miss doorbells sometimes when powergating kicks in.
|
||||
* Updating the wptr directly will wake it. This is only safe because
|
||||
* we disallow gfxoff in begin_use() and then allow it again in end_use().
|
||||
*/
|
||||
WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR),
|
||||
lower_32_bits(ring->wptr << 2));
|
||||
WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI),
|
||||
upper_32_bits(ring->wptr << 2));
|
||||
if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) == IP_VERSION(5, 2, 1)) {
|
||||
/* SDMA seems to miss doorbells sometimes when powergating kicks in.
|
||||
* Updating the wptr directly will wake it. This is only safe because
|
||||
* we disallow gfxoff in begin_use() and then allow it again in end_use().
|
||||
*/
|
||||
WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR),
|
||||
lower_32_bits(ring->wptr << 2));
|
||||
WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI),
|
||||
upper_32_bits(ring->wptr << 2));
|
||||
}
|
||||
} else {
|
||||
DRM_DEBUG("Not using doorbell -- "
|
||||
"mmSDMA%i_GFX_RB_WPTR == 0x%08x "
|
||||
|
||||
@@ -39,7 +39,9 @@ static u32 transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
|
||||
static void intel_dp_hdcp_wait_for_cp_irq(struct intel_connector *connector,
|
||||
int timeout)
|
||||
{
|
||||
struct intel_hdcp *hdcp = &connector->hdcp;
|
||||
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
|
||||
struct intel_dp *dp = &dig_port->dp;
|
||||
struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
|
||||
long ret;
|
||||
|
||||
#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
|
||||
|
||||
@@ -99,7 +99,7 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname,
|
||||
* was a bad idea, and is only provided for backwards
|
||||
* compatibility for older targets.
|
||||
*/
|
||||
return -ENODEV;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (IS_ERR(fw)) {
|
||||
|
||||
@@ -1171,8 +1171,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
|
||||
|
||||
cstate->num_mixers = num_lm;
|
||||
|
||||
dpu_enc->connector = conn_state->connector;
|
||||
|
||||
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
|
||||
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
|
||||
|
||||
@@ -1270,6 +1268,8 @@ static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc,
|
||||
|
||||
dpu_enc->commit_done_timedout = false;
|
||||
|
||||
dpu_enc->connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
|
||||
|
||||
cur_mode = &dpu_enc->base.crtc->state->adjusted_mode;
|
||||
|
||||
dpu_enc->wide_bus_en = dpu_encoder_is_widebus_enabled(drm_enc);
|
||||
|
||||
@@ -308,8 +308,8 @@ static const u32 wb2_formats_rgb_yuv[] = {
|
||||
{ \
|
||||
.maxdwnscale = SSPP_UNITY_SCALE, \
|
||||
.maxupscale = SSPP_UNITY_SCALE, \
|
||||
.format_list = plane_formats_yuv, \
|
||||
.num_formats = ARRAY_SIZE(plane_formats_yuv), \
|
||||
.format_list = plane_formats, \
|
||||
.num_formats = ARRAY_SIZE(plane_formats), \
|
||||
.virt_format_list = plane_formats, \
|
||||
.virt_num_formats = ARRAY_SIZE(plane_formats), \
|
||||
}
|
||||
|
||||
@@ -31,24 +31,14 @@
|
||||
* @fmt: Pointer to format string
|
||||
*/
|
||||
#define DPU_DEBUG(fmt, ...) \
|
||||
do { \
|
||||
if (drm_debug_enabled(DRM_UT_KMS)) \
|
||||
DRM_DEBUG(fmt, ##__VA_ARGS__); \
|
||||
else \
|
||||
pr_debug(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* DPU_DEBUG_DRIVER - macro for hardware driver logging
|
||||
* @fmt: Pointer to format string
|
||||
*/
|
||||
#define DPU_DEBUG_DRIVER(fmt, ...) \
|
||||
do { \
|
||||
if (drm_debug_enabled(DRM_UT_DRIVER)) \
|
||||
DRM_ERROR(fmt, ##__VA_ARGS__); \
|
||||
else \
|
||||
pr_debug(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__)
|
||||
|
||||
#define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__)
|
||||
#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__)
|
||||
|
||||
@@ -681,6 +681,9 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane,
|
||||
new_state->fb, &layout);
|
||||
if (ret) {
|
||||
DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
|
||||
if (pstate->aspace)
|
||||
msm_framebuffer_cleanup(new_state->fb, pstate->aspace,
|
||||
pstate->needs_dirtyfb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -744,10 +747,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
|
||||
min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1;
|
||||
|
||||
if (MSM_FORMAT_IS_YUV(fmt) &&
|
||||
(!pipe->sspp->cap->sblk->scaler_blk.len ||
|
||||
!pipe->sspp->cap->sblk->csc_blk.len)) {
|
||||
!pipe->sspp->cap->sblk->csc_blk.len) {
|
||||
DPU_DEBUG_PLANE(pdpu,
|
||||
"plane doesn't have scaler/csc for yuv\n");
|
||||
"plane doesn't have csc for yuv\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -864,6 +866,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
|
||||
|
||||
max_linewidth = pdpu->catalog->caps->max_linewidth;
|
||||
|
||||
drm_rect_rotate(&pipe_cfg->src_rect,
|
||||
new_plane_state->fb->width, new_plane_state->fb->height,
|
||||
new_plane_state->rotation);
|
||||
|
||||
if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
|
||||
_dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) {
|
||||
/*
|
||||
@@ -913,6 +919,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
|
||||
r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
|
||||
}
|
||||
|
||||
drm_rect_rotate_inv(&pipe_cfg->src_rect,
|
||||
new_plane_state->fb->width, new_plane_state->fb->height,
|
||||
new_plane_state->rotation);
|
||||
if (r_pipe->sspp)
|
||||
drm_rect_rotate_inv(&r_pipe_cfg->src_rect,
|
||||
new_plane_state->fb->width, new_plane_state->fb->height,
|
||||
new_plane_state->rotation);
|
||||
|
||||
ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt, &crtc_state->adjusted_mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1286,6 +1286,8 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
|
||||
link_info.rate = ctrl->link->link_params.rate;
|
||||
link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING;
|
||||
|
||||
dp_link_reset_phy_params_vx_px(ctrl->link);
|
||||
|
||||
dp_aux_link_configure(ctrl->aux, &link_info);
|
||||
|
||||
if (drm_dp_max_downspread(dpcd))
|
||||
|
||||
@@ -90,22 +90,22 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel)
|
||||
static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel,
|
||||
u32 mode_edid_bpp, u32 mode_pclk_khz)
|
||||
{
|
||||
struct dp_link_info *link_info;
|
||||
const struct dp_link_info *link_info;
|
||||
const u32 max_supported_bpp = 30, min_supported_bpp = 18;
|
||||
u32 bpp = 0, data_rate_khz = 0;
|
||||
u32 bpp, data_rate_khz;
|
||||
|
||||
bpp = min_t(u32, mode_edid_bpp, max_supported_bpp);
|
||||
bpp = min(mode_edid_bpp, max_supported_bpp);
|
||||
|
||||
link_info = &dp_panel->link_info;
|
||||
data_rate_khz = link_info->num_lanes * link_info->rate * 8;
|
||||
|
||||
while (bpp > min_supported_bpp) {
|
||||
do {
|
||||
if (mode_pclk_khz * bpp <= data_rate_khz)
|
||||
break;
|
||||
return bpp;
|
||||
bpp -= 6;
|
||||
}
|
||||
} while (bpp > min_supported_bpp);
|
||||
|
||||
return bpp;
|
||||
return min_supported_bpp;
|
||||
}
|
||||
|
||||
int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
|
||||
@@ -423,8 +423,9 @@ int dp_panel_init_panel_info(struct dp_panel *dp_panel)
|
||||
drm_mode->clock);
|
||||
drm_dbg_dp(panel->drm_dev, "bpp = %d\n", dp_panel->dp_mode.bpp);
|
||||
|
||||
dp_panel->dp_mode.bpp = max_t(u32, 18,
|
||||
min_t(u32, dp_panel->dp_mode.bpp, 30));
|
||||
dp_panel->dp_mode.bpp = dp_panel_get_mode_bpp(dp_panel, dp_panel->dp_mode.bpp,
|
||||
dp_panel->dp_mode.drm_mode.clock);
|
||||
|
||||
drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n",
|
||||
dp_panel->dp_mode.bpp);
|
||||
|
||||
|
||||
@@ -577,7 +577,7 @@ static const struct msm_mdss_data sc7180_data = {
|
||||
.ubwc_enc_version = UBWC_2_0,
|
||||
.ubwc_dec_version = UBWC_2_0,
|
||||
.ubwc_static = 0x1e,
|
||||
.highest_bank_bit = 0x3,
|
||||
.highest_bank_bit = 0x1,
|
||||
.reg_bus_bw = 76800,
|
||||
};
|
||||
|
||||
|
||||
@@ -205,7 +205,8 @@ nvkm_firmware_dtor(struct nvkm_firmware *fw)
|
||||
break;
|
||||
case NVKM_FIRMWARE_IMG_DMA:
|
||||
nvkm_memory_unref(&memory);
|
||||
dma_free_coherent(fw->device->dev, sg_dma_len(&fw->mem.sgl), fw->img, fw->phys);
|
||||
dma_free_noncoherent(fw->device->dev, sg_dma_len(&fw->mem.sgl),
|
||||
fw->img, fw->phys, DMA_TO_DEVICE);
|
||||
break;
|
||||
case NVKM_FIRMWARE_IMG_SGT:
|
||||
nvkm_memory_unref(&memory);
|
||||
@@ -236,10 +237,12 @@ nvkm_firmware_ctor(const struct nvkm_firmware_func *func, const char *name,
|
||||
break;
|
||||
case NVKM_FIRMWARE_IMG_DMA: {
|
||||
dma_addr_t addr;
|
||||
|
||||
len = ALIGN(fw->len, PAGE_SIZE);
|
||||
|
||||
fw->img = dma_alloc_coherent(fw->device->dev, len, &addr, GFP_KERNEL);
|
||||
fw->img = dma_alloc_noncoherent(fw->device->dev,
|
||||
len, &addr,
|
||||
DMA_TO_DEVICE,
|
||||
GFP_KERNEL);
|
||||
if (fw->img) {
|
||||
memcpy(fw->img, src, fw->len);
|
||||
fw->phys = addr;
|
||||
|
||||
@@ -89,6 +89,12 @@ nvkm_falcon_fw_boot(struct nvkm_falcon_fw *fw, struct nvkm_subdev *user,
|
||||
nvkm_falcon_fw_dtor_sigs(fw);
|
||||
}
|
||||
|
||||
/* after last write to the img, sync dma mappings */
|
||||
dma_sync_single_for_device(fw->fw.device->dev,
|
||||
fw->fw.phys,
|
||||
sg_dma_len(&fw->fw.mem.sgl),
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
FLCNFW_DBG(fw, "resetting");
|
||||
fw->func->reset(fw);
|
||||
|
||||
|
||||
@@ -25,12 +25,14 @@ $(obj)/generated/%_wa_oob.c $(obj)/generated/%_wa_oob.h: $(obj)/xe_gen_wa_oob \
|
||||
|
||||
uses_generated_oob := \
|
||||
$(obj)/xe_ggtt.o \
|
||||
$(obj)/xe_device.o \
|
||||
$(obj)/xe_gsc.o \
|
||||
$(obj)/xe_gt.o \
|
||||
$(obj)/xe_guc.o \
|
||||
$(obj)/xe_guc_ads.o \
|
||||
$(obj)/xe_guc_pc.o \
|
||||
$(obj)/xe_migrate.o \
|
||||
$(obj)/xe_pat.o \
|
||||
$(obj)/xe_ring_ops.o \
|
||||
$(obj)/xe_vm.o \
|
||||
$(obj)/xe_wa.o \
|
||||
|
||||
@@ -132,6 +132,7 @@ static void xe_display_fini_noirq(void *arg)
|
||||
return;
|
||||
|
||||
intel_display_driver_remove_noirq(xe);
|
||||
intel_opregion_cleanup(xe);
|
||||
}
|
||||
|
||||
int xe_display_init_noirq(struct xe_device *xe)
|
||||
@@ -157,8 +158,10 @@ int xe_display_init_noirq(struct xe_device *xe)
|
||||
intel_display_device_info_runtime_init(xe);
|
||||
|
||||
err = intel_display_driver_probe_noirq(xe);
|
||||
if (err)
|
||||
if (err) {
|
||||
intel_opregion_cleanup(xe);
|
||||
return err;
|
||||
}
|
||||
|
||||
return devm_add_action_or_reset(xe->drm.dev, xe_display_fini_noirq, xe);
|
||||
}
|
||||
@@ -280,6 +283,27 @@ static bool suspend_to_idle(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void xe_display_flush_cleanup_work(struct xe_device *xe)
|
||||
{
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
for_each_intel_crtc(&xe->drm, crtc) {
|
||||
struct drm_crtc_commit *commit;
|
||||
|
||||
spin_lock(&crtc->base.commit_lock);
|
||||
commit = list_first_entry_or_null(&crtc->base.commit_list,
|
||||
struct drm_crtc_commit, commit_entry);
|
||||
if (commit)
|
||||
drm_crtc_commit_get(commit);
|
||||
spin_unlock(&crtc->base.commit_lock);
|
||||
|
||||
if (commit) {
|
||||
wait_for_completion(&commit->cleanup_done);
|
||||
drm_crtc_commit_put(commit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void xe_display_pm_suspend(struct xe_device *xe, bool runtime)
|
||||
{
|
||||
bool s2idle = suspend_to_idle();
|
||||
@@ -297,6 +321,8 @@ void xe_display_pm_suspend(struct xe_device *xe, bool runtime)
|
||||
if (!runtime)
|
||||
intel_display_driver_suspend(xe);
|
||||
|
||||
xe_display_flush_cleanup_work(xe);
|
||||
|
||||
intel_dp_mst_suspend(xe);
|
||||
|
||||
intel_hpd_cancel_work(xe);
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dsb_buffer.h"
|
||||
#include "xe_bo.h"
|
||||
#include "xe_device.h"
|
||||
#include "xe_device_types.h"
|
||||
#include "xe_gt.h"
|
||||
|
||||
u32 intel_dsb_buffer_ggtt_offset(struct intel_dsb_buffer *dsb_buf)
|
||||
@@ -16,7 +18,10 @@ u32 intel_dsb_buffer_ggtt_offset(struct intel_dsb_buffer *dsb_buf)
|
||||
|
||||
void intel_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val)
|
||||
{
|
||||
struct xe_device *xe = dsb_buf->vma->bo->tile->xe;
|
||||
|
||||
iosys_map_wr(&dsb_buf->vma->bo->vmap, idx * 4, u32, val);
|
||||
xe_device_l2_flush(xe);
|
||||
}
|
||||
|
||||
u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx)
|
||||
@@ -26,9 +31,12 @@ u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx)
|
||||
|
||||
void intel_dsb_buffer_memset(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size)
|
||||
{
|
||||
struct xe_device *xe = dsb_buf->vma->bo->tile->xe;
|
||||
|
||||
WARN_ON(idx > (dsb_buf->buf_size - size) / sizeof(*dsb_buf->cmd_buf));
|
||||
|
||||
iosys_map_memset(&dsb_buf->vma->bo->vmap, idx * 4, val, size);
|
||||
xe_device_l2_flush(xe);
|
||||
}
|
||||
|
||||
bool intel_dsb_buffer_create(struct intel_crtc *crtc, struct intel_dsb_buffer *dsb_buf, size_t size)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "intel_fb.h"
|
||||
#include "intel_fb_pin.h"
|
||||
#include "xe_bo.h"
|
||||
#include "xe_device.h"
|
||||
#include "xe_ggtt.h"
|
||||
#include "xe_gt.h"
|
||||
#include "xe_pm.h"
|
||||
@@ -304,6 +305,8 @@ static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb,
|
||||
if (ret)
|
||||
goto err_unpin;
|
||||
|
||||
/* Ensure DPT writes are flushed */
|
||||
xe_device_l2_flush(xe);
|
||||
return vma;
|
||||
|
||||
err_unpin:
|
||||
|
||||
@@ -80,6 +80,9 @@
|
||||
#define LE_CACHEABILITY_MASK REG_GENMASK(1, 0)
|
||||
#define LE_CACHEABILITY(value) REG_FIELD_PREP(LE_CACHEABILITY_MASK, value)
|
||||
|
||||
#define XE2_GAMREQSTRM_CTRL XE_REG(0x4194)
|
||||
#define CG_DIS_CNTLBUS REG_BIT(6)
|
||||
|
||||
#define CCS_AUX_INV XE_REG(0x4208)
|
||||
|
||||
#define VD0_AUX_INV XE_REG(0x4218)
|
||||
@@ -372,6 +375,11 @@
|
||||
|
||||
#define XEHPC_L3CLOS_MASK(i) XE_REG_MCR(0xb194 + (i) * 8)
|
||||
|
||||
#define XE2_GLOBAL_INVAL XE_REG(0xb404)
|
||||
|
||||
#define SCRATCH1LPFC XE_REG(0xb474)
|
||||
#define EN_L3_RW_CCS_CACHE_FLUSH REG_BIT(0)
|
||||
|
||||
#define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658)
|
||||
|
||||
#define XE2_TDF_CTRL XE_REG(0xb418)
|
||||
@@ -429,6 +437,7 @@
|
||||
#define DIS_FIX_EOT1_FLUSH REG_BIT(9)
|
||||
|
||||
#define TDL_TSL_CHICKEN XE_REG_MCR(0xe4c4, XE_REG_OPTION_MASKED)
|
||||
#define STK_ID_RESTRICT REG_BIT(12)
|
||||
#define SLM_WMTP_RESTORE REG_BIT(11)
|
||||
|
||||
#define ROW_CHICKEN XE_REG_MCR(0xe4f0, XE_REG_OPTION_MASKED)
|
||||
|
||||
@@ -1575,7 +1575,7 @@ struct xe_bo *xe_bo_create_from_data(struct xe_device *xe, struct xe_tile *tile,
|
||||
return bo;
|
||||
}
|
||||
|
||||
static void __xe_bo_unpin_map_no_vm(struct drm_device *drm, void *arg)
|
||||
static void __xe_bo_unpin_map_no_vm(void *arg)
|
||||
{
|
||||
xe_bo_unpin_map_no_vm(arg);
|
||||
}
|
||||
@@ -1590,7 +1590,7 @@ struct xe_bo *xe_managed_bo_create_pin_map(struct xe_device *xe, struct xe_tile
|
||||
if (IS_ERR(bo))
|
||||
return bo;
|
||||
|
||||
ret = drmm_add_action_or_reset(&xe->drm, __xe_bo_unpin_map_no_vm, bo);
|
||||
ret = devm_add_action_or_reset(xe->drm.dev, __xe_bo_unpin_map_no_vm, bo);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
@@ -1638,7 +1638,7 @@ int xe_managed_bo_reinit_in_vram(struct xe_device *xe, struct xe_tile *tile, str
|
||||
if (IS_ERR(bo))
|
||||
return PTR_ERR(bo);
|
||||
|
||||
drmm_release_action(&xe->drm, __xe_bo_unpin_map_no_vm, *src);
|
||||
devm_release_action(xe->drm.dev, __xe_bo_unpin_map_no_vm, *src);
|
||||
*src = bo;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -54,6 +54,9 @@
|
||||
#include "xe_vm.h"
|
||||
#include "xe_vram.h"
|
||||
#include "xe_wait_user_fence.h"
|
||||
#include "xe_wa.h"
|
||||
|
||||
#include <generated/xe_wa_oob.h>
|
||||
|
||||
static int xe_file_open(struct drm_device *dev, struct drm_file *file)
|
||||
{
|
||||
@@ -820,6 +823,11 @@ void xe_device_td_flush(struct xe_device *xe)
|
||||
if (!IS_DGFX(xe) || GRAPHICS_VER(xe) < 20)
|
||||
return;
|
||||
|
||||
if (XE_WA(xe_root_mmio_gt(xe), 16023588340)) {
|
||||
xe_device_l2_flush(xe);
|
||||
return;
|
||||
}
|
||||
|
||||
for_each_gt(gt, xe, id) {
|
||||
if (xe_gt_is_media_type(gt))
|
||||
continue;
|
||||
@@ -843,6 +851,30 @@ void xe_device_td_flush(struct xe_device *xe)
|
||||
}
|
||||
}
|
||||
|
||||
void xe_device_l2_flush(struct xe_device *xe)
|
||||
{
|
||||
struct xe_gt *gt;
|
||||
int err;
|
||||
|
||||
gt = xe_root_mmio_gt(xe);
|
||||
|
||||
if (!XE_WA(gt, 16023588340))
|
||||
return;
|
||||
|
||||
err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
spin_lock(>->global_invl_lock);
|
||||
xe_mmio_write32(gt, XE2_GLOBAL_INVAL, 0x1);
|
||||
|
||||
if (xe_mmio_wait32(gt, XE2_GLOBAL_INVAL, 0x1, 0x0, 150, NULL, true))
|
||||
xe_gt_err_once(gt, "Global invalidation timeout\n");
|
||||
spin_unlock(>->global_invl_lock);
|
||||
|
||||
xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
|
||||
}
|
||||
|
||||
u32 xe_device_ccs_bytes(struct xe_device *xe, u64 size)
|
||||
{
|
||||
return xe_device_has_flat_ccs(xe) ?
|
||||
|
||||
@@ -162,6 +162,7 @@ u64 xe_device_canonicalize_addr(struct xe_device *xe, u64 address);
|
||||
u64 xe_device_uncanonicalize_addr(struct xe_device *xe, u64 address);
|
||||
|
||||
void xe_device_td_flush(struct xe_device *xe);
|
||||
void xe_device_l2_flush(struct xe_device *xe);
|
||||
|
||||
static inline bool xe_device_wedged(struct xe_device *xe)
|
||||
{
|
||||
|
||||
@@ -105,22 +105,35 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
|
||||
|
||||
static int __xe_exec_queue_init(struct xe_exec_queue *q)
|
||||
{
|
||||
struct xe_vm *vm = q->vm;
|
||||
int i, err;
|
||||
|
||||
if (vm) {
|
||||
err = xe_vm_lock(vm, true);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < q->width; ++i) {
|
||||
q->lrc[i] = xe_lrc_create(q->hwe, q->vm, SZ_16K);
|
||||
if (IS_ERR(q->lrc[i])) {
|
||||
err = PTR_ERR(q->lrc[i]);
|
||||
goto err_lrc;
|
||||
goto err_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm)
|
||||
xe_vm_unlock(vm);
|
||||
|
||||
err = q->ops->init(q);
|
||||
if (err)
|
||||
goto err_lrc;
|
||||
|
||||
return 0;
|
||||
|
||||
err_unlock:
|
||||
if (vm)
|
||||
xe_vm_unlock(vm);
|
||||
err_lrc:
|
||||
for (i = i - 1; i >= 0; --i)
|
||||
xe_lrc_put(q->lrc[i]);
|
||||
@@ -140,15 +153,7 @@ struct xe_exec_queue *xe_exec_queue_create(struct xe_device *xe, struct xe_vm *v
|
||||
if (IS_ERR(q))
|
||||
return q;
|
||||
|
||||
if (vm) {
|
||||
err = xe_vm_lock(vm, true);
|
||||
if (err)
|
||||
goto err_post_alloc;
|
||||
}
|
||||
|
||||
err = __xe_exec_queue_init(q);
|
||||
if (vm)
|
||||
xe_vm_unlock(vm);
|
||||
if (err)
|
||||
goto err_post_alloc;
|
||||
|
||||
@@ -638,7 +643,6 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
if (xe_vm_in_preempt_fence_mode(vm)) {
|
||||
q->lr.context = dma_fence_context_alloc(1);
|
||||
spin_lock_init(&q->lr.lock);
|
||||
|
||||
err = xe_vm_add_compute_exec_queue(vm, q);
|
||||
if (XE_IOCTL_DBG(xe, err))
|
||||
|
||||
@@ -126,8 +126,6 @@ struct xe_exec_queue {
|
||||
u32 seqno;
|
||||
/** @lr.link: link into VM's list of exec queues */
|
||||
struct list_head link;
|
||||
/** @lr.lock: preemption fences lock */
|
||||
spinlock_t lock;
|
||||
} lr;
|
||||
|
||||
/** @ops: submission backend exec queue operations */
|
||||
|
||||
@@ -260,7 +260,7 @@ static int gsc_upload_and_init(struct xe_gsc *gsc)
|
||||
struct xe_tile *tile = gt_to_tile(gt);
|
||||
int ret;
|
||||
|
||||
if (XE_WA(gt, 14018094691)) {
|
||||
if (XE_WA(tile->primary_gt, 14018094691)) {
|
||||
ret = xe_force_wake_get(gt_to_fw(tile->primary_gt), XE_FORCEWAKE_ALL);
|
||||
|
||||
/*
|
||||
@@ -278,7 +278,7 @@ static int gsc_upload_and_init(struct xe_gsc *gsc)
|
||||
|
||||
ret = gsc_upload(gsc);
|
||||
|
||||
if (XE_WA(gt, 14018094691))
|
||||
if (XE_WA(tile->primary_gt, 14018094691))
|
||||
xe_force_wake_put(gt_to_fw(tile->primary_gt), XE_FORCEWAKE_ALL);
|
||||
|
||||
if (ret)
|
||||
@@ -437,7 +437,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void free_resources(struct drm_device *drm, void *arg)
|
||||
static void free_resources(void *arg)
|
||||
{
|
||||
struct xe_gsc *gsc = arg;
|
||||
|
||||
@@ -501,7 +501,7 @@ int xe_gsc_init_post_hwconfig(struct xe_gsc *gsc)
|
||||
gsc->q = q;
|
||||
gsc->wq = wq;
|
||||
|
||||
err = drmm_add_action_or_reset(&xe->drm, free_resources, gsc);
|
||||
err = devm_add_action_or_reset(xe->drm.dev, free_resources, gsc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <drm/xe_drm.h>
|
||||
#include <generated/xe_wa_oob.h>
|
||||
|
||||
#include <generated/xe_wa_oob.h>
|
||||
|
||||
#include "instructions/xe_gfxpipe_commands.h"
|
||||
#include "instructions/xe_mi_commands.h"
|
||||
#include "regs/xe_gt_regs.h"
|
||||
@@ -95,6 +97,51 @@ void xe_gt_sanitize(struct xe_gt *gt)
|
||||
gt->uc.guc.submission_state.enabled = false;
|
||||
}
|
||||
|
||||
static void xe_gt_enable_host_l2_vram(struct xe_gt *gt)
|
||||
{
|
||||
u32 reg;
|
||||
int err;
|
||||
|
||||
if (!XE_WA(gt, 16023588340))
|
||||
return;
|
||||
|
||||
err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
|
||||
if (WARN_ON(err))
|
||||
return;
|
||||
|
||||
if (!xe_gt_is_media_type(gt)) {
|
||||
xe_mmio_write32(gt, SCRATCH1LPFC, EN_L3_RW_CCS_CACHE_FLUSH);
|
||||
reg = xe_mmio_read32(gt, XE2_GAMREQSTRM_CTRL);
|
||||
reg |= CG_DIS_CNTLBUS;
|
||||
xe_mmio_write32(gt, XE2_GAMREQSTRM_CTRL, reg);
|
||||
}
|
||||
|
||||
xe_gt_mcr_multicast_write(gt, XEHPC_L3CLOS_MASK(3), 0x3);
|
||||
xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
|
||||
}
|
||||
|
||||
static void xe_gt_disable_host_l2_vram(struct xe_gt *gt)
|
||||
{
|
||||
u32 reg;
|
||||
int err;
|
||||
|
||||
if (!XE_WA(gt, 16023588340))
|
||||
return;
|
||||
|
||||
if (xe_gt_is_media_type(gt))
|
||||
return;
|
||||
|
||||
err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
|
||||
if (WARN_ON(err))
|
||||
return;
|
||||
|
||||
reg = xe_mmio_read32(gt, XE2_GAMREQSTRM_CTRL);
|
||||
reg &= ~CG_DIS_CNTLBUS;
|
||||
xe_mmio_write32(gt, XE2_GAMREQSTRM_CTRL, reg);
|
||||
|
||||
xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_gt_remove() - Clean up the GT structures before driver removal
|
||||
* @gt: the GT object
|
||||
@@ -111,6 +158,8 @@ void xe_gt_remove(struct xe_gt *gt)
|
||||
|
||||
for (i = 0; i < XE_ENGINE_CLASS_MAX; ++i)
|
||||
xe_hw_fence_irq_finish(>->fence_irq[i]);
|
||||
|
||||
xe_gt_disable_host_l2_vram(gt);
|
||||
}
|
||||
|
||||
static void gt_reset_worker(struct work_struct *w);
|
||||
@@ -339,6 +388,7 @@ int xe_gt_init_early(struct xe_gt *gt)
|
||||
|
||||
xe_force_wake_init_gt(gt, gt_to_fw(gt));
|
||||
xe_pcode_init(gt);
|
||||
spin_lock_init(>->global_invl_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -508,6 +558,7 @@ int xe_gt_init_hwconfig(struct xe_gt *gt)
|
||||
|
||||
xe_gt_mcr_init_early(gt);
|
||||
xe_pat_init(gt);
|
||||
xe_gt_enable_host_l2_vram(gt);
|
||||
|
||||
err = xe_uc_init(>->uc);
|
||||
if (err)
|
||||
@@ -643,6 +694,8 @@ static int do_gt_restart(struct xe_gt *gt)
|
||||
|
||||
xe_pat_init(gt);
|
||||
|
||||
xe_gt_enable_host_l2_vram(gt);
|
||||
|
||||
xe_gt_mcr_set_implicit_defaults(gt);
|
||||
xe_reg_sr_apply_mmio(>->reg_sr, gt);
|
||||
|
||||
@@ -796,6 +849,8 @@ int xe_gt_suspend(struct xe_gt *gt)
|
||||
|
||||
xe_gt_idle_disable_pg(gt);
|
||||
|
||||
xe_gt_disable_host_l2_vram(gt);
|
||||
|
||||
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
|
||||
xe_gt_dbg(gt, "suspended\n");
|
||||
|
||||
|
||||
@@ -382,6 +382,18 @@ static void pf_queue_work_func(struct work_struct *w)
|
||||
|
||||
static void acc_queue_work_func(struct work_struct *w);
|
||||
|
||||
static void pagefault_fini(void *arg)
|
||||
{
|
||||
struct xe_gt *gt = arg;
|
||||
struct xe_device *xe = gt_to_xe(gt);
|
||||
|
||||
if (!xe->info.has_usm)
|
||||
return;
|
||||
|
||||
destroy_workqueue(gt->usm.acc_wq);
|
||||
destroy_workqueue(gt->usm.pf_wq);
|
||||
}
|
||||
|
||||
int xe_gt_pagefault_init(struct xe_gt *gt)
|
||||
{
|
||||
struct xe_device *xe = gt_to_xe(gt);
|
||||
@@ -409,10 +421,12 @@ int xe_gt_pagefault_init(struct xe_gt *gt)
|
||||
gt->usm.acc_wq = alloc_workqueue("xe_gt_access_counter_work_queue",
|
||||
WQ_UNBOUND | WQ_HIGHPRI,
|
||||
NUM_ACC_QUEUE);
|
||||
if (!gt->usm.acc_wq)
|
||||
if (!gt->usm.acc_wq) {
|
||||
destroy_workqueue(gt->usm.pf_wq);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return devm_add_action_or_reset(xe->drm.dev, pagefault_fini, gt);
|
||||
}
|
||||
|
||||
void xe_gt_pagefault_reset(struct xe_gt *gt)
|
||||
|
||||
@@ -362,6 +362,12 @@ struct xe_gt {
|
||||
*/
|
||||
spinlock_t mcr_lock;
|
||||
|
||||
/**
|
||||
* @global_invl_lock: protects the register for the duration
|
||||
* of a global invalidation of l2 cache
|
||||
*/
|
||||
spinlock_t global_invl_lock;
|
||||
|
||||
/** @wa_active: keep track of active workarounds */
|
||||
struct {
|
||||
/** @wa_active.gt: bitmap with active GT workarounds */
|
||||
|
||||
@@ -284,7 +284,7 @@ static void guc_submit_fini(struct drm_device *drm, void *arg)
|
||||
free_submit_wq(guc);
|
||||
}
|
||||
|
||||
static void guc_submit_wedged_fini(struct drm_device *drm, void *arg)
|
||||
static void guc_submit_wedged_fini(void *arg)
|
||||
{
|
||||
struct xe_guc *guc = arg;
|
||||
struct xe_exec_queue *q;
|
||||
@@ -877,7 +877,7 @@ void xe_guc_submit_wedge(struct xe_guc *guc)
|
||||
|
||||
xe_gt_assert(guc_to_gt(guc), guc_to_xe(guc)->wedged.mode);
|
||||
|
||||
err = drmm_add_action_or_reset(&guc_to_xe(guc)->drm,
|
||||
err = devm_add_action_or_reset(guc_to_xe(guc)->drm.dev,
|
||||
guc_submit_wedged_fini, guc);
|
||||
if (err) {
|
||||
drm_err(&xe->drm, "Failed to register xe_guc_submit clean-up on wedged.mode=2. Although device is wedged.\n");
|
||||
|
||||
@@ -148,20 +148,20 @@ static const char *xe_hw_fence_get_driver_name(struct dma_fence *dma_fence)
|
||||
{
|
||||
struct xe_hw_fence *fence = to_xe_hw_fence(dma_fence);
|
||||
|
||||
return dev_name(gt_to_xe(fence->ctx->gt)->drm.dev);
|
||||
return dev_name(fence->xe->drm.dev);
|
||||
}
|
||||
|
||||
static const char *xe_hw_fence_get_timeline_name(struct dma_fence *dma_fence)
|
||||
{
|
||||
struct xe_hw_fence *fence = to_xe_hw_fence(dma_fence);
|
||||
|
||||
return fence->ctx->name;
|
||||
return fence->name;
|
||||
}
|
||||
|
||||
static bool xe_hw_fence_signaled(struct dma_fence *dma_fence)
|
||||
{
|
||||
struct xe_hw_fence *fence = to_xe_hw_fence(dma_fence);
|
||||
struct xe_device *xe = gt_to_xe(fence->ctx->gt);
|
||||
struct xe_device *xe = fence->xe;
|
||||
u32 seqno = xe_map_rd(xe, &fence->seqno_map, 0, u32);
|
||||
|
||||
return dma_fence->error ||
|
||||
@@ -253,7 +253,8 @@ void xe_hw_fence_init(struct dma_fence *fence, struct xe_hw_fence_ctx *ctx,
|
||||
struct xe_hw_fence *hw_fence =
|
||||
container_of(fence, typeof(*hw_fence), dma);
|
||||
|
||||
hw_fence->ctx = ctx;
|
||||
hw_fence->xe = gt_to_xe(ctx->gt);
|
||||
snprintf(hw_fence->name, sizeof(hw_fence->name), "%s", ctx->name);
|
||||
hw_fence->seqno_map = seqno_map;
|
||||
INIT_LIST_HEAD(&hw_fence->irq_link);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
struct xe_device;
|
||||
struct xe_gt;
|
||||
|
||||
/**
|
||||
@@ -61,8 +62,10 @@ struct xe_hw_fence_ctx {
|
||||
struct xe_hw_fence {
|
||||
/** @dma: base dma fence for hardware fence context */
|
||||
struct dma_fence dma;
|
||||
/** @ctx: hardware fence context */
|
||||
struct xe_hw_fence_ctx *ctx;
|
||||
/** @xe: Xe device for hw fence driver name */
|
||||
struct xe_device *xe;
|
||||
/** @name: name of hardware fence context */
|
||||
char name[MAX_FENCE_NAME_LEN];
|
||||
/** @seqno_map: I/O map for seqno */
|
||||
struct iosys_map seqno_map;
|
||||
/** @irq_link: Link in struct xe_hw_fence_irq.pending */
|
||||
|
||||
@@ -30,7 +30,8 @@ static void tiles_fini(void *arg)
|
||||
int id;
|
||||
|
||||
for_each_tile(tile, xe, id)
|
||||
tile->mmio.regs = NULL;
|
||||
if (tile != xe_device_get_root_tile(xe))
|
||||
tile->mmio.regs = NULL;
|
||||
}
|
||||
|
||||
int xe_mmio_probe_tiles(struct xe_device *xe)
|
||||
@@ -91,9 +92,11 @@ add_mmio_ext:
|
||||
static void mmio_fini(void *arg)
|
||||
{
|
||||
struct xe_device *xe = arg;
|
||||
struct xe_tile *root_tile = xe_device_get_root_tile(xe);
|
||||
|
||||
pci_iounmap(to_pci_dev(xe->drm.dev), xe->mmio.regs);
|
||||
xe->mmio.regs = NULL;
|
||||
root_tile->mmio.regs = NULL;
|
||||
}
|
||||
|
||||
int xe_mmio_init(struct xe_device *xe)
|
||||
@@ -121,12 +124,29 @@ int xe_mmio_init(struct xe_device *xe)
|
||||
return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe);
|
||||
}
|
||||
|
||||
static void mmio_flush_pending_writes(struct xe_gt *gt)
|
||||
{
|
||||
#define DUMMY_REG_OFFSET 0x130030
|
||||
struct xe_tile *tile = gt_to_tile(gt);
|
||||
int i;
|
||||
|
||||
if (tile->xe->info.platform != XE_LUNARLAKE)
|
||||
return;
|
||||
|
||||
/* 4 dummy writes */
|
||||
for (i = 0; i < 4; i++)
|
||||
writel(0, tile->mmio.regs + DUMMY_REG_OFFSET);
|
||||
}
|
||||
|
||||
u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg)
|
||||
{
|
||||
struct xe_tile *tile = gt_to_tile(gt);
|
||||
u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
|
||||
u8 val;
|
||||
|
||||
/* Wa_15015404425 */
|
||||
mmio_flush_pending_writes(gt);
|
||||
|
||||
val = readb((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr);
|
||||
trace_xe_reg_rw(gt, false, addr, val, sizeof(val));
|
||||
|
||||
@@ -139,6 +159,9 @@ u16 xe_mmio_read16(struct xe_gt *gt, struct xe_reg reg)
|
||||
u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
|
||||
u16 val;
|
||||
|
||||
/* Wa_15015404425 */
|
||||
mmio_flush_pending_writes(gt);
|
||||
|
||||
val = readw((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr);
|
||||
trace_xe_reg_rw(gt, false, addr, val, sizeof(val));
|
||||
|
||||
@@ -160,6 +183,9 @@ u32 xe_mmio_read32(struct xe_gt *gt, struct xe_reg reg)
|
||||
u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
|
||||
u32 val;
|
||||
|
||||
/* Wa_15015404425 */
|
||||
mmio_flush_pending_writes(gt);
|
||||
|
||||
if (!reg.vf && IS_SRIOV_VF(gt_to_xe(gt)))
|
||||
val = xe_gt_sriov_vf_read32(gt, reg);
|
||||
else
|
||||
|
||||
@@ -66,7 +66,6 @@ static struct ctl_table observation_ctl_table[] = {
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
.extra2 = SYSCTL_ONE,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <drm/xe_drm.h>
|
||||
|
||||
#include <generated/xe_wa_oob.h>
|
||||
|
||||
#include "regs/xe_reg_defs.h"
|
||||
#include "xe_assert.h"
|
||||
#include "xe_device.h"
|
||||
@@ -15,6 +17,7 @@
|
||||
#include "xe_gt_mcr.h"
|
||||
#include "xe_mmio.h"
|
||||
#include "xe_sriov.h"
|
||||
#include "xe_wa.h"
|
||||
|
||||
#define _PAT_ATS 0x47fc
|
||||
#define _PAT_INDEX(index) _PICK_EVEN_2RANGES(index, 8, \
|
||||
@@ -382,7 +385,13 @@ void xe_pat_init_early(struct xe_device *xe)
|
||||
if (GRAPHICS_VER(xe) == 20) {
|
||||
xe->pat.ops = &xe2_pat_ops;
|
||||
xe->pat.table = xe2_pat_table;
|
||||
xe->pat.n_entries = ARRAY_SIZE(xe2_pat_table);
|
||||
|
||||
/* Wa_16023588340. XXX: Should use XE_WA */
|
||||
if (GRAPHICS_VERx100(xe) == 2001)
|
||||
xe->pat.n_entries = 28; /* Disable CLOS3 */
|
||||
else
|
||||
xe->pat.n_entries = ARRAY_SIZE(xe2_pat_table);
|
||||
|
||||
xe->pat.idx[XE_CACHE_NONE] = 3;
|
||||
xe->pat.idx[XE_CACHE_WT] = 15;
|
||||
xe->pat.idx[XE_CACHE_WB] = 2;
|
||||
|
||||
@@ -91,13 +91,13 @@ int xe_pm_suspend(struct xe_device *xe)
|
||||
for_each_gt(gt, xe, id)
|
||||
xe_gt_suspend_prepare(gt);
|
||||
|
||||
xe_display_pm_suspend(xe, false);
|
||||
|
||||
/* FIXME: Super racey... */
|
||||
err = xe_bo_evict_all(xe);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
xe_display_pm_suspend(xe, false);
|
||||
|
||||
for_each_gt(gt, xe, id) {
|
||||
err = xe_gt_suspend(gt);
|
||||
if (err) {
|
||||
@@ -151,11 +151,11 @@ int xe_pm_resume(struct xe_device *xe)
|
||||
|
||||
xe_irq_resume(xe);
|
||||
|
||||
xe_display_pm_resume(xe, false);
|
||||
|
||||
for_each_gt(gt, xe, id)
|
||||
xe_gt_resume(gt);
|
||||
|
||||
xe_display_pm_resume(xe, false);
|
||||
|
||||
err = xe_bo_restore_user(xe);
|
||||
if (err)
|
||||
goto err;
|
||||
@@ -363,10 +363,11 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
|
||||
mutex_unlock(&xe->mem_access.vram_userfault.lock);
|
||||
|
||||
if (xe->d3cold.allowed) {
|
||||
xe_display_pm_suspend(xe, true);
|
||||
|
||||
err = xe_bo_evict_all(xe);
|
||||
if (err)
|
||||
goto out;
|
||||
xe_display_pm_suspend(xe, true);
|
||||
}
|
||||
|
||||
for_each_gt(gt, xe, id) {
|
||||
|
||||
@@ -128,8 +128,9 @@ xe_preempt_fence_arm(struct xe_preempt_fence *pfence, struct xe_exec_queue *q,
|
||||
{
|
||||
list_del_init(&pfence->link);
|
||||
pfence->q = xe_exec_queue_get(q);
|
||||
spin_lock_init(&pfence->lock);
|
||||
dma_fence_init(&pfence->base, &preempt_fence_ops,
|
||||
&q->lr.lock, context, seqno);
|
||||
&pfence->lock, context, seqno);
|
||||
|
||||
return &pfence->base;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ struct xe_preempt_fence {
|
||||
struct xe_exec_queue *q;
|
||||
/** @preempt_work: work struct which issues preemption */
|
||||
struct work_struct preempt_work;
|
||||
/** @lock: dma-fence fence lock */
|
||||
spinlock_t lock;
|
||||
/** @error: preempt fence is in error state */
|
||||
int error;
|
||||
};
|
||||
|
||||
@@ -171,12 +171,13 @@ void xe_sched_job_destroy(struct kref *ref)
|
||||
struct xe_sched_job *job =
|
||||
container_of(ref, struct xe_sched_job, refcount);
|
||||
struct xe_device *xe = job_to_xe(job);
|
||||
struct xe_exec_queue *q = job->q;
|
||||
|
||||
xe_sched_job_free_fences(job);
|
||||
xe_exec_queue_put(job->q);
|
||||
dma_fence_put(job->fence);
|
||||
drm_sched_job_cleanup(&job->drm);
|
||||
job_free(job);
|
||||
xe_exec_queue_put(q);
|
||||
xe_pm_runtime_put(xe);
|
||||
}
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ DECLARE_EVENT_CLASS(xe_hw_fence,
|
||||
TP_ARGS(fence),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, __dev_name_gt(fence->ctx->gt))
|
||||
__string(dev, __dev_name_xe(fence->xe))
|
||||
__field(u64, ctx)
|
||||
__field(u32, seqno)
|
||||
__field(struct xe_hw_fence *, fence)
|
||||
|
||||
@@ -486,6 +486,10 @@ static const struct xe_rtp_entry_sr engine_was[] = {
|
||||
XE_RTP_RULES(GRAPHICS_VERSION(2004), FUNC(xe_rtp_match_first_render_or_compute)),
|
||||
XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, SLM_WMTP_RESTORE))
|
||||
},
|
||||
{ XE_RTP_NAME("14021402888"),
|
||||
XE_RTP_RULES(GRAPHICS_VERSION(2004), ENGINE_CLASS(RENDER)),
|
||||
XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE))
|
||||
},
|
||||
|
||||
/* Xe2_HPG */
|
||||
|
||||
@@ -538,6 +542,20 @@ static const struct xe_rtp_entry_sr engine_was[] = {
|
||||
XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
|
||||
XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE))
|
||||
},
|
||||
{ XE_RTP_NAME("14021821874"),
|
||||
XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)),
|
||||
XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, STK_ID_RESTRICT))
|
||||
},
|
||||
|
||||
/* Xe2_LPM */
|
||||
|
||||
{ XE_RTP_NAME("16021639441"),
|
||||
XE_RTP_RULES(MEDIA_VERSION(2000)),
|
||||
XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0),
|
||||
GHWSP_CSB_REPORT_DIS |
|
||||
PPHWSP_CSB_AND_TIMESTAMP_REPORT_DIS,
|
||||
XE_RTP_ACTION_FLAG(ENGINE_BASE)))
|
||||
},
|
||||
|
||||
/* Xe2_HPM */
|
||||
|
||||
|
||||
@@ -29,3 +29,4 @@
|
||||
13011645652 GRAPHICS_VERSION(2004)
|
||||
22019338487 MEDIA_VERSION(2000)
|
||||
GRAPHICS_VERSION(2001)
|
||||
16023588340 GRAPHICS_VERSION(2001)
|
||||
|
||||
@@ -171,11 +171,13 @@ err_hid_data:
|
||||
void amdtp_hid_remove(struct amdtp_cl_data *cli_data)
|
||||
{
|
||||
int i;
|
||||
struct amdtp_hid_data *hid_data;
|
||||
|
||||
for (i = 0; i < cli_data->num_hid_devices; ++i) {
|
||||
if (cli_data->hid_sensor_hubs[i]) {
|
||||
kfree(cli_data->hid_sensor_hubs[i]->driver_data);
|
||||
hid_data = cli_data->hid_sensor_hubs[i]->driver_data;
|
||||
hid_destroy_device(cli_data->hid_sensor_hubs[i]);
|
||||
kfree(hid_data);
|
||||
cli_data->hid_sensor_hubs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1248,6 +1248,9 @@ static const struct hid_device_id asus_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY),
|
||||
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X),
|
||||
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD),
|
||||
QUIRK_ROG_CLAYMORE_II_KEYBOARD },
|
||||
|
||||
@@ -106,7 +106,7 @@ static void cougar_fix_g6_mapping(void)
|
||||
static __u8 *cougar_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
if (rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
|
||||
if (*rsize >= 117 && rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
|
||||
(rdesc[115] | rdesc[116] << 8) >= HID_MAX_USAGES) {
|
||||
hid_info(hdev,
|
||||
"usage count exceeds max: fixing up report descriptor\n");
|
||||
|
||||
@@ -210,6 +210,7 @@
|
||||
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30
|
||||
#define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6
|
||||
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe
|
||||
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c
|
||||
#define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b
|
||||
#define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
|
||||
|
||||
@@ -520,6 +521,8 @@
|
||||
#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
|
||||
|
||||
#define I2C_VENDOR_ID_GOODIX 0x27c6
|
||||
#define I2C_DEVICE_ID_GOODIX_01E8 0x01e8
|
||||
#define I2C_DEVICE_ID_GOODIX_01E9 0x01e9
|
||||
#define I2C_DEVICE_ID_GOODIX_01F0 0x01f0
|
||||
|
||||
#define USB_VENDOR_ID_GOODTOUCH 0x1aad
|
||||
|
||||
@@ -1441,6 +1441,30 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __u8 *mt_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *size)
|
||||
{
|
||||
if (hdev->vendor == I2C_VENDOR_ID_GOODIX &&
|
||||
(hdev->product == I2C_DEVICE_ID_GOODIX_01E8 ||
|
||||
hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) {
|
||||
if (rdesc[607] == 0x15) {
|
||||
rdesc[607] = 0x25;
|
||||
dev_info(
|
||||
&hdev->dev,
|
||||
"GT7868Q report descriptor fixup is applied.\n");
|
||||
} else {
|
||||
dev_info(
|
||||
&hdev->dev,
|
||||
"The byte is not expected for fixing the report descriptor. \
|
||||
It's possible that the touchpad firmware is not suitable for applying the fix. \
|
||||
got: %x\n",
|
||||
rdesc[607]);
|
||||
}
|
||||
}
|
||||
|
||||
return rdesc;
|
||||
}
|
||||
|
||||
static void mt_report(struct hid_device *hid, struct hid_report *report)
|
||||
{
|
||||
struct mt_device *td = hid_get_drvdata(hid);
|
||||
@@ -2035,6 +2059,14 @@ static const struct hid_device_id mt_devices[] = {
|
||||
MT_BT_DEVICE(USB_VENDOR_ID_FRUCTEL,
|
||||
USB_DEVICE_ID_GAMETEL_MT_MODE) },
|
||||
|
||||
/* Goodix GT7868Q devices */
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
|
||||
HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
|
||||
I2C_DEVICE_ID_GOODIX_01E8) },
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
|
||||
HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
|
||||
I2C_DEVICE_ID_GOODIX_01E8) },
|
||||
|
||||
/* GoodTouch panels */
|
||||
{ .driver_data = MT_CLS_NSMU,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
|
||||
@@ -2270,6 +2302,7 @@ static struct hid_driver mt_driver = {
|
||||
.feature_mapping = mt_feature_mapping,
|
||||
.usage_table = mt_grabbed_usages,
|
||||
.event = mt_event,
|
||||
.report_fixup = mt_report_fixup,
|
||||
.report = mt_report,
|
||||
.suspend = pm_ptr(mt_suspend),
|
||||
.reset_resume = pm_ptr(mt_reset_resume),
|
||||
|
||||
@@ -1878,12 +1878,14 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
|
||||
int fmax = field->logical_maximum;
|
||||
unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
|
||||
int resolution_code = code;
|
||||
int resolution = hidinput_calc_abs_res(field, resolution_code);
|
||||
int resolution;
|
||||
|
||||
if (equivalent_usage == HID_DG_TWIST) {
|
||||
resolution_code = ABS_RZ;
|
||||
}
|
||||
|
||||
resolution = hidinput_calc_abs_res(field, resolution_code);
|
||||
|
||||
if (equivalent_usage == HID_GD_X) {
|
||||
fmin += features->offset_left;
|
||||
fmax -= features->offset_right;
|
||||
|
||||
@@ -182,8 +182,11 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
|
||||
swap(range[0], range[1]);
|
||||
}
|
||||
|
||||
fwnode_property_read_u32(child, "abs-fuzz", &fuzz);
|
||||
fwnode_property_read_u32(child, "abs-flat", &flat);
|
||||
if (fwnode_property_read_u32(child, "abs-fuzz", &fuzz))
|
||||
fuzz = 0;
|
||||
|
||||
if (fwnode_property_read_u32(child, "abs-flat", &flat))
|
||||
flat = 0;
|
||||
|
||||
input_set_abs_params(joy->input, axes[i].code,
|
||||
range[0], range[1], fuzz, flat);
|
||||
|
||||
@@ -417,6 +417,20 @@ static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Limit number of contacts to a reasonable value (100). This
|
||||
* ensures that we need less than 2 pages for struct input_mt
|
||||
* (we are not using in-kernel slot assignment so not going to
|
||||
* allocate memory for the "red" table), and we should have no
|
||||
* trouble getting this much memory.
|
||||
*/
|
||||
if (code == ABS_MT_SLOT && max > 99) {
|
||||
printk(KERN_DEBUG
|
||||
"%s: unreasonably large number of slots requested: %d\n",
|
||||
UINPUT_NAME, max);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,6 +189,7 @@ static const char * const smbus_pnp_ids[] = {
|
||||
"LEN2054", /* E480 */
|
||||
"LEN2055", /* E580 */
|
||||
"LEN2068", /* T14 Gen 1 */
|
||||
"SYN3015", /* HP EliteBook 840 G2 */
|
||||
"SYN3052", /* HP EliteBook 840 G4 */
|
||||
"SYN3221", /* HP 15-ay000 */
|
||||
"SYN323d", /* HP Spectre X360 13-w013dx */
|
||||
|
||||
@@ -83,6 +83,7 @@ static inline void i8042_write_command(int val)
|
||||
#define SERIO_QUIRK_KBDRESET BIT(12)
|
||||
#define SERIO_QUIRK_DRITEK BIT(13)
|
||||
#define SERIO_QUIRK_NOPNP BIT(14)
|
||||
#define SERIO_QUIRK_FORCENORESTORE BIT(15)
|
||||
|
||||
/* Quirk table for different mainboards. Options similar or identical to i8042
|
||||
* module parameters.
|
||||
@@ -626,6 +627,15 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX)
|
||||
},
|
||||
{
|
||||
/* Fujitsu Lifebook E756 */
|
||||
/* https://bugzilla.suse.com/show_bug.cgi?id=1229056 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E756"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX)
|
||||
},
|
||||
{
|
||||
/* Fujitsu Lifebook E5411 */
|
||||
.matches = {
|
||||
@@ -1149,18 +1159,10 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Setting SERIO_QUIRK_NOMUX or SERIO_QUIRK_RESET_ALWAYS makes
|
||||
* the keyboard very laggy for ~5 seconds after boot and
|
||||
* sometimes also after resume.
|
||||
* However both are required for the keyboard to not fail
|
||||
* completely sometimes after boot or resume.
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N150CU"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
@@ -1685,6 +1687,8 @@ static void __init i8042_check_quirks(void)
|
||||
if (quirks & SERIO_QUIRK_NOPNP)
|
||||
i8042_nopnp = true;
|
||||
#endif
|
||||
if (quirks & SERIO_QUIRK_FORCENORESTORE)
|
||||
i8042_forcenorestore = true;
|
||||
}
|
||||
#else
|
||||
static inline void i8042_check_quirks(void) {}
|
||||
@@ -1718,7 +1722,7 @@ static int __init i8042_platform_init(void)
|
||||
|
||||
i8042_check_quirks();
|
||||
|
||||
pr_debug("Active quirks (empty means none):%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
pr_debug("Active quirks (empty means none):%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
i8042_nokbd ? " nokbd" : "",
|
||||
i8042_noaux ? " noaux" : "",
|
||||
i8042_nomux ? " nomux" : "",
|
||||
@@ -1738,10 +1742,11 @@ static int __init i8042_platform_init(void)
|
||||
"",
|
||||
#endif
|
||||
#ifdef CONFIG_PNP
|
||||
i8042_nopnp ? " nopnp" : "");
|
||||
i8042_nopnp ? " nopnp" : "",
|
||||
#else
|
||||
"");
|
||||
"",
|
||||
#endif
|
||||
i8042_forcenorestore ? " forcenorestore" : "");
|
||||
|
||||
retval = i8042_pnp_init();
|
||||
if (retval)
|
||||
|
||||
@@ -115,6 +115,10 @@ module_param_named(nopnp, i8042_nopnp, bool, 0);
|
||||
MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
|
||||
#endif
|
||||
|
||||
static bool i8042_forcenorestore;
|
||||
module_param_named(forcenorestore, i8042_forcenorestore, bool, 0);
|
||||
MODULE_PARM_DESC(forcenorestore, "Force no restore on s3 resume, copying s2idle behaviour");
|
||||
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
static bool i8042_debug;
|
||||
@@ -1232,7 +1236,7 @@ static int i8042_pm_suspend(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pm_suspend_via_firmware())
|
||||
if (!i8042_forcenorestore && pm_suspend_via_firmware())
|
||||
i8042_controller_reset(true);
|
||||
|
||||
/* Set up serio interrupts for system wakeup. */
|
||||
@@ -1248,7 +1252,7 @@ static int i8042_pm_suspend(struct device *dev)
|
||||
|
||||
static int i8042_pm_resume_noirq(struct device *dev)
|
||||
{
|
||||
if (!pm_resume_via_firmware())
|
||||
if (i8042_forcenorestore || !pm_resume_via_firmware())
|
||||
i8042_interrupt(0, NULL);
|
||||
|
||||
return 0;
|
||||
@@ -1271,7 +1275,7 @@ static int i8042_pm_resume(struct device *dev)
|
||||
* not restore the controller state to whatever it had been at boot
|
||||
* time, so we do not need to do anything.
|
||||
*/
|
||||
if (!pm_suspend_via_firmware())
|
||||
if (i8042_forcenorestore || !pm_suspend_via_firmware())
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
||||
@@ -824,7 +824,7 @@ static void ads7846_read_state(struct ads7846 *ts)
|
||||
m = &ts->msg[msg_idx];
|
||||
error = spi_sync(ts->spi, m);
|
||||
if (error) {
|
||||
dev_err(&ts->spi->dev, "spi_sync --> %d\n", error);
|
||||
dev_err_ratelimited(&ts->spi->dev, "spi_sync --> %d\n", error);
|
||||
packet->ignore = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1474,6 +1474,10 @@ static const struct edt_i2c_chip_data edt_ft6236_data = {
|
||||
.max_support_points = 2,
|
||||
};
|
||||
|
||||
static const struct edt_i2c_chip_data edt_ft8201_data = {
|
||||
.max_support_points = 10,
|
||||
};
|
||||
|
||||
static const struct edt_i2c_chip_data edt_ft8719_data = {
|
||||
.max_support_points = 10,
|
||||
};
|
||||
@@ -1485,6 +1489,7 @@ static const struct i2c_device_id edt_ft5x06_ts_id[] = {
|
||||
{ .name = "ft5452", .driver_data = (long)&edt_ft5452_data },
|
||||
/* Note no edt- prefix for compatibility with the ft6236.c driver */
|
||||
{ .name = "ft6236", .driver_data = (long)&edt_ft6236_data },
|
||||
{ .name = "ft8201", .driver_data = (long)&edt_ft8201_data },
|
||||
{ .name = "ft8719", .driver_data = (long)&edt_ft8719_data },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
@@ -1500,6 +1505,7 @@ static const struct of_device_id edt_ft5x06_of_match[] = {
|
||||
{ .compatible = "focaltech,ft5452", .data = &edt_ft5452_data },
|
||||
/* Note focaltech vendor prefix for compatibility with ft6236.c */
|
||||
{ .compatible = "focaltech,ft6236", .data = &edt_ft6236_data },
|
||||
{ .compatible = "focaltech,ft8201", .data = &edt_ft8201_data },
|
||||
{ .compatible = "focaltech,ft8719", .data = &edt_ft8719_data },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
@@ -130,17 +130,6 @@ static int himax_bus_read(struct himax_ts_data *ts, u32 address, void *dst,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int himax_read_mcu(struct himax_ts_data *ts, u32 address, u32 *dst)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = himax_bus_read(ts, address, dst, sizeof(dst));
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void himax_reset(struct himax_ts_data *ts)
|
||||
{
|
||||
gpiod_set_value_cansleep(ts->gpiod_rst, 1);
|
||||
@@ -160,7 +149,8 @@ static int himax_read_product_id(struct himax_ts_data *ts, u32 *product_id)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = himax_read_mcu(ts, HIMAX_REG_ADDR_ICID, product_id);
|
||||
error = himax_bus_read(ts, HIMAX_REG_ADDR_ICID, product_id,
|
||||
sizeof(*product_id));
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
||||
@@ -526,7 +526,7 @@ iommufd_device_do_replace(struct iommufd_device *idev,
|
||||
err_unresv:
|
||||
if (hwpt_is_paging(hwpt))
|
||||
iommufd_group_remove_reserved_iova(igroup,
|
||||
to_hwpt_paging(old_hwpt));
|
||||
to_hwpt_paging(hwpt));
|
||||
err_unlock:
|
||||
mutex_unlock(&idev->igroup->lock);
|
||||
return ERR_PTR(rc);
|
||||
|
||||
@@ -273,7 +273,7 @@ static int mock_domain_read_and_clear_dirty(struct iommu_domain *domain,
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct iommu_dirty_ops dirty_ops = {
|
||||
static const struct iommu_dirty_ops dirty_ops = {
|
||||
.set_dirty_tracking = mock_domain_set_dirty_tracking,
|
||||
.read_and_clear_dirty = mock_domain_read_and_clear_dirty,
|
||||
};
|
||||
|
||||
@@ -3125,13 +3125,13 @@ static ssize_t mtf_test_write(struct file *file, const char __user *buf,
|
||||
test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL);
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
test->highmem = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, BUFFER_ORDER);
|
||||
if (!test->highmem) {
|
||||
count = -ENOMEM;
|
||||
goto free_test_buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
if (test->buffer && test->highmem) {
|
||||
#else
|
||||
if (test->buffer) {
|
||||
#endif
|
||||
mutex_lock(&mmc_test_lock);
|
||||
mmc_test_run(test, testcase);
|
||||
mutex_unlock(&mmc_test_lock);
|
||||
@@ -3139,6 +3139,7 @@ static ssize_t mtf_test_write(struct file *file, const char __user *buf,
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
__free_pages(test->highmem, BUFFER_ORDER);
|
||||
free_test_buffer:
|
||||
#endif
|
||||
kfree(test->buffer);
|
||||
kfree(test);
|
||||
|
||||
@@ -3299,6 +3299,10 @@ int dw_mci_probe(struct dw_mci *host)
|
||||
host->biu_clk = devm_clk_get(host->dev, "biu");
|
||||
if (IS_ERR(host->biu_clk)) {
|
||||
dev_dbg(host->dev, "biu clock not available\n");
|
||||
ret = PTR_ERR(host->biu_clk);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
|
||||
} else {
|
||||
ret = clk_prepare_enable(host->biu_clk);
|
||||
if (ret) {
|
||||
@@ -3310,6 +3314,10 @@ int dw_mci_probe(struct dw_mci *host)
|
||||
host->ciu_clk = devm_clk_get(host->dev, "ciu");
|
||||
if (IS_ERR(host->ciu_clk)) {
|
||||
dev_dbg(host->dev, "ciu clock not available\n");
|
||||
ret = PTR_ERR(host->ciu_clk);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
goto err_clk_biu;
|
||||
|
||||
host->bus_hz = host->pdata->bus_hz;
|
||||
} else {
|
||||
ret = clk_prepare_enable(host->ciu_clk);
|
||||
|
||||
@@ -1230,7 +1230,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
|
||||
}
|
||||
|
||||
if (!sbc_error && !(events & MSDC_INT_CMDRDY)) {
|
||||
if (events & MSDC_INT_CMDTMO ||
|
||||
if ((events & MSDC_INT_CMDTMO && !host->hs400_tuning) ||
|
||||
(!mmc_op_tuning(cmd->opcode) && !host->hs400_tuning))
|
||||
/*
|
||||
* should not clear fifo/interrupt as the tune data
|
||||
@@ -1323,9 +1323,9 @@ static void msdc_start_command(struct msdc_host *host,
|
||||
static void msdc_cmd_next(struct msdc_host *host,
|
||||
struct mmc_request *mrq, struct mmc_command *cmd)
|
||||
{
|
||||
if ((cmd->error &&
|
||||
!(cmd->error == -EILSEQ &&
|
||||
(mmc_op_tuning(cmd->opcode) || host->hs400_tuning))) ||
|
||||
if ((cmd->error && !host->hs400_tuning &&
|
||||
!(cmd->error == -EILSEQ &&
|
||||
mmc_op_tuning(cmd->opcode))) ||
|
||||
(mrq->sbc && mrq->sbc->error))
|
||||
msdc_request_done(host, mrq);
|
||||
else if (cmd == mrq->sbc)
|
||||
|
||||
@@ -582,7 +582,6 @@ static void bond_ipsec_del_sa_all(struct bonding *bond)
|
||||
} else {
|
||||
slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
|
||||
}
|
||||
ipsec->xs->xso.real_dev = NULL;
|
||||
}
|
||||
spin_unlock_bh(&bond->ipsec_lock);
|
||||
rcu_read_unlock();
|
||||
@@ -599,34 +598,30 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
|
||||
struct net_device *real_dev;
|
||||
struct slave *curr_active;
|
||||
struct bonding *bond;
|
||||
int err;
|
||||
bool ok = false;
|
||||
|
||||
bond = netdev_priv(bond_dev);
|
||||
rcu_read_lock();
|
||||
curr_active = rcu_dereference(bond->curr_active_slave);
|
||||
if (!curr_active)
|
||||
goto out;
|
||||
real_dev = curr_active->dev;
|
||||
|
||||
if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
|
||||
err = false;
|
||||
if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!xs->xso.real_dev) {
|
||||
err = false;
|
||||
if (!xs->xso.real_dev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!real_dev->xfrmdev_ops ||
|
||||
!real_dev->xfrmdev_ops->xdo_dev_offload_ok ||
|
||||
netif_is_bond_master(real_dev)) {
|
||||
err = false;
|
||||
netif_is_bond_master(real_dev))
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
|
||||
ok = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
return ok;
|
||||
}
|
||||
|
||||
static const struct xfrmdev_ops bond_xfrmdev_ops = {
|
||||
|
||||
@@ -936,7 +936,7 @@ static int bond_option_active_slave_set(struct bonding *bond,
|
||||
/* check to see if we are clearing active */
|
||||
if (!slave_dev) {
|
||||
netdev_dbg(bond->dev, "Clearing current active slave\n");
|
||||
RCU_INIT_POINTER(bond->curr_active_slave, NULL);
|
||||
bond_change_active_slave(bond, NULL);
|
||||
bond_select_active_slave(bond);
|
||||
} else {
|
||||
struct slave *old_active = rtnl_dereference(bond->curr_active_slave);
|
||||
|
||||
@@ -266,7 +266,6 @@ static int ksz_ptp_enable_mode(struct ksz_device *dev)
|
||||
struct ksz_port *prt;
|
||||
struct dsa_port *dp;
|
||||
bool tag_en = false;
|
||||
int ret;
|
||||
|
||||
dsa_switch_for_each_user_port(dp, dev->ds) {
|
||||
prt = &dev->ports[dp->index];
|
||||
@@ -277,9 +276,7 @@ static int ksz_ptp_enable_mode(struct ksz_device *dev)
|
||||
}
|
||||
|
||||
if (tag_en) {
|
||||
ret = ptp_schedule_worker(ptp_data->clock, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
ptp_schedule_worker(ptp_data->clock, 0);
|
||||
} else {
|
||||
ptp_cancel_worker_sync(ptp_data->clock);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user