mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 11:31:31 +00:00
Merge branch 'torvalds:master' into master
This commit is contained in:
commit
05689d7f87
@ -11,10 +11,18 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pm8058-vib
|
||||
- qcom,pm8916-vib
|
||||
- qcom,pm8921-vib
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,pm8058-vib
|
||||
- qcom,pm8916-vib
|
||||
- qcom,pm8921-vib
|
||||
- qcom,pmi632-vib
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,pm7250b-vib
|
||||
- qcom,pm7325b-vib
|
||||
- qcom,pm7550ba-vib
|
||||
- const: qcom,pmi632-vib
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -39,7 +39,9 @@ properties:
|
||||
- edt,edt-ft5406
|
||||
- edt,edt-ft5506
|
||||
- evervision,ev-ft5726
|
||||
- focaltech,ft5452
|
||||
- focaltech,ft6236
|
||||
- focaltech,ft8719
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -72,7 +72,7 @@ patternProperties:
|
||||
properties:
|
||||
compatible:
|
||||
description: Compatible for SAI sub-block A or B.
|
||||
pattern: "st,stm32-sai-sub-[ab]"
|
||||
pattern: "^st,stm32-sai-sub-[ab]$"
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
@ -15,7 +15,7 @@ problem is broken BIOS, and the rest is the driver implementation.
|
||||
This document explains the brief trouble-shooting and debugging
|
||||
methods for the HD-audio hardware.
|
||||
|
||||
The HD-audio component consists of two parts: the controller chip and
|
||||
The HD-audio component consists of two parts: the controller chip and
|
||||
the codec chips on the HD-audio bus. Linux provides a single driver
|
||||
for all controllers, snd-hda-intel. Although the driver name contains
|
||||
a word of a well-known hardware vendor, it's not specific to it but for
|
||||
@ -81,7 +81,7 @@ the wake-up timing. It wakes up a few samples before actually
|
||||
processing the data on the buffer. This caused a lot of problems, for
|
||||
example, with ALSA dmix or JACK. Since 2.6.27 kernel, the driver puts
|
||||
an artificial delay to the wake up timing. This delay is controlled
|
||||
via ``bdl_pos_adj`` option.
|
||||
via ``bdl_pos_adj`` option.
|
||||
|
||||
When ``bdl_pos_adj`` is a negative value (as default), it's assigned to
|
||||
an appropriate value depending on the controller chip. For Intel
|
||||
@ -144,7 +144,7 @@ see a regression wrt the sound quality (stuttering, etc) or a lock-up
|
||||
in the recent kernel, try to pass ``enable_msi=0`` option to disable
|
||||
MSI. If it works, you can add the known bad device to the blacklist
|
||||
defined in hda_intel.c. In such a case, please report and give the
|
||||
patch back to the upstream developer.
|
||||
patch back to the upstream developer.
|
||||
|
||||
|
||||
HD-Audio Codec
|
||||
@ -375,7 +375,7 @@ HD-Audio Reconfiguration
|
||||
------------------------
|
||||
This is an experimental feature to allow you re-configure the HD-audio
|
||||
codec dynamically without reloading the driver. The following sysfs
|
||||
files are available under each codec-hwdep device directory (e.g.
|
||||
files are available under each codec-hwdep device directory (e.g.
|
||||
/sys/class/sound/hwC0D0):
|
||||
|
||||
vendor_id
|
||||
@ -433,7 +433,7 @@ re-configure based on that state, run like below:
|
||||
::
|
||||
|
||||
# echo 0x14 0x9993013f > /sys/class/sound/hwC0D0/user_pin_configs
|
||||
# echo 1 > /sys/class/sound/hwC0D0/reconfig
|
||||
# echo 1 > /sys/class/sound/hwC0D0/reconfig
|
||||
|
||||
|
||||
Hint Strings
|
||||
@ -494,7 +494,7 @@ indep_hp (bool)
|
||||
mixer control, if available
|
||||
add_stereo_mix_input (bool)
|
||||
add the stereo mix (analog-loopback mix) to the input mux if
|
||||
available
|
||||
available
|
||||
add_jack_modes (bool)
|
||||
add "xxx Jack Mode" enum controls to each I/O jack for allowing to
|
||||
change the headphone amp and mic bias VREF capabilities
|
||||
@ -504,7 +504,7 @@ power_save_node (bool)
|
||||
stream states
|
||||
power_down_unused (bool)
|
||||
power down the unused widgets, a subset of power_save_node, and
|
||||
will be dropped in future
|
||||
will be dropped in future
|
||||
add_hp_mic (bool)
|
||||
add the headphone to capture source if possible
|
||||
hp_mic_detect (bool)
|
||||
@ -603,7 +603,7 @@ present.
|
||||
|
||||
The patch module option is specific to each card instance, and you
|
||||
need to give one file name for each instance, separated by commas.
|
||||
For example, if you have two cards, one for an on-board analog and one
|
||||
For example, if you have two cards, one for an on-board analog and one
|
||||
for an HDMI video board, you may pass patch option like below:
|
||||
::
|
||||
|
||||
|
@ -129,7 +129,7 @@ config RISCV
|
||||
select HAVE_DMA_CONTIGUOUS if MMU
|
||||
select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
|
||||
@ -141,6 +141,13 @@ config RISCV
|
||||
select HAVE_GCC_PLUGINS
|
||||
select HAVE_GENERIC_VDSO if MMU && 64BIT
|
||||
select HAVE_IRQ_TIME_ACCOUNTING
|
||||
select HAVE_KERNEL_BZIP2 if !XIP_KERNEL && !EFI_ZBOOT
|
||||
select HAVE_KERNEL_GZIP if !XIP_KERNEL && !EFI_ZBOOT
|
||||
select HAVE_KERNEL_LZ4 if !XIP_KERNEL && !EFI_ZBOOT
|
||||
select HAVE_KERNEL_LZMA if !XIP_KERNEL && !EFI_ZBOOT
|
||||
select HAVE_KERNEL_LZO if !XIP_KERNEL && !EFI_ZBOOT
|
||||
select HAVE_KERNEL_UNCOMPRESSED if !XIP_KERNEL && !EFI_ZBOOT
|
||||
select HAVE_KERNEL_ZSTD if !XIP_KERNEL && !EFI_ZBOOT
|
||||
select HAVE_KPROBES if !XIP_KERNEL
|
||||
select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
|
||||
select HAVE_KRETPROBES if !XIP_KERNEL
|
||||
@ -170,7 +177,6 @@ config RISCV
|
||||
select LOCK_MM_AND_FIND_VMA
|
||||
select MMU_GATHER_RCU_TABLE_FREE if SMP && MMU
|
||||
select MODULES_USE_ELF_RELA if MODULES
|
||||
select MODULE_SECTIONS if MODULES
|
||||
select OF
|
||||
select OF_EARLY_FLATTREE
|
||||
select OF_IRQ
|
||||
@ -861,6 +867,7 @@ config PARAVIRT_TIME_ACCOUNTING
|
||||
config RELOCATABLE
|
||||
bool "Build a relocatable kernel"
|
||||
depends on MMU && 64BIT && !XIP_KERNEL
|
||||
select MODULE_SECTIONS if MODULES
|
||||
help
|
||||
This builds a kernel as a Position Independent Executable (PIE),
|
||||
which retains all relocation metadata required to relocate the
|
||||
|
@ -154,6 +154,21 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
boot := arch/riscv/boot
|
||||
boot-image-y := Image
|
||||
boot-image-$(CONFIG_KERNEL_BZIP2) := Image.bz2
|
||||
boot-image-$(CONFIG_KERNEL_GZIP) := Image.gz
|
||||
boot-image-$(CONFIG_KERNEL_LZ4) := Image.lz4
|
||||
boot-image-$(CONFIG_KERNEL_LZMA) := Image.lzma
|
||||
boot-image-$(CONFIG_KERNEL_LZO) := Image.lzo
|
||||
boot-image-$(CONFIG_KERNEL_ZSTD) := Image.zst
|
||||
ifdef CONFIG_RISCV_M_MODE
|
||||
boot-image-$(CONFIG_ARCH_CANAAN) := loader.bin
|
||||
endif
|
||||
boot-image-$(CONFIG_EFI_ZBOOT) := vmlinuz.efi
|
||||
boot-image-$(CONFIG_XIP_KERNEL) := xipImage
|
||||
KBUILD_IMAGE := $(boot)/$(boot-image-y)
|
||||
|
||||
libs-y += arch/riscv/lib/
|
||||
libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
|
||||
|
||||
@ -171,21 +186,19 @@ endif
|
||||
vdso-install-y += arch/riscv/kernel/vdso/vdso.so.dbg
|
||||
vdso-install-$(CONFIG_COMPAT) += arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg
|
||||
|
||||
BOOT_TARGETS := Image Image.gz loader loader.bin xipImage vmlinuz.efi
|
||||
BOOT_TARGETS := Image Image.gz Image.bz2 Image.lz4 Image.lzma Image.lzo Image.zst loader loader.bin xipImage vmlinuz.efi
|
||||
|
||||
all: $(notdir $(KBUILD_IMAGE))
|
||||
|
||||
loader.bin: loader
|
||||
Image.gz loader vmlinuz.efi: Image
|
||||
Image.gz Image.bz2 Image.lz4 Image.lzma Image.lzo Image.zst loader xipImage vmlinuz.efi: Image
|
||||
|
||||
$(BOOT_TARGETS): vmlinux
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
@$(kecho) ' Kernel: $(boot)/$@ is ready'
|
||||
|
||||
Image.%: Image
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
install: KBUILD_IMAGE := $(boot)/Image
|
||||
zinstall: KBUILD_IMAGE := $(boot)/Image.gz
|
||||
# the install target always installs KBUILD_IMAGE (which may be compressed)
|
||||
# but keep the zinstall target for compatibility with older releases
|
||||
install zinstall:
|
||||
$(call cmd,install)
|
||||
|
||||
@ -206,3 +219,20 @@ rv32_defconfig:
|
||||
PHONY += rv32_nommu_virt_defconfig
|
||||
rv32_nommu_virt_defconfig:
|
||||
$(Q)$(MAKE) -f $(srctree)/Makefile nommu_virt_defconfig 32-bit.config
|
||||
|
||||
define archhelp
|
||||
echo ' Image - Uncompressed kernel image (arch/riscv/boot/Image)'
|
||||
echo ' Image.gz - Compressed kernel image (arch/riscv/boot/Image.gz)'
|
||||
echo ' Image.bz2 - Compressed kernel image (arch/riscv/boot/Image.bz2)'
|
||||
echo ' Image.lz4 - Compressed kernel image (arch/riscv/boot/Image.lz4)'
|
||||
echo ' Image.lzma - Compressed kernel image (arch/riscv/boot/Image.lzma)'
|
||||
echo ' Image.lzo - Compressed kernel image (arch/riscv/boot/Image.lzo)'
|
||||
echo ' Image.zst - Compressed kernel image (arch/riscv/boot/Image.zst)'
|
||||
echo ' vmlinuz.efi - Compressed EFI kernel image (arch/riscv/boot/vmlinuz.efi)'
|
||||
echo ' Default when CONFIG_EFI_ZBOOT=y'
|
||||
echo ' xipImage - Execute-in-place kernel image (arch/riscv/boot/xipImage)'
|
||||
echo ' Default when CONFIG_XIP_KERNEL=y'
|
||||
echo ' install - Install kernel using (your) ~/bin/$(INSTALLKERNEL) or'
|
||||
echo ' (distribution) /sbin/$(INSTALLKERNEL) or install to '
|
||||
echo ' $$(INSTALL_PATH)'
|
||||
endef
|
||||
|
@ -17,15 +17,18 @@
|
||||
# $3 - kernel map file
|
||||
# $4 - default install path (blank if root directory)
|
||||
|
||||
if [ "$(basename $2)" = "Image.gz" ]; then
|
||||
case "${2##*/}" in
|
||||
# Compressed install
|
||||
Image.*|vmlinuz.efi)
|
||||
echo "Installing compressed kernel"
|
||||
base=vmlinuz
|
||||
else
|
||||
;;
|
||||
# Normal install
|
||||
*)
|
||||
echo "Installing normal kernel"
|
||||
base=vmlinux
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -f $4/$base-$1 ]; then
|
||||
mv $4/$base-$1 $4/$base-$1.old
|
||||
|
@ -13,6 +13,12 @@ static inline void local_flush_icache_all(void)
|
||||
asm volatile ("fence.i" ::: "memory");
|
||||
}
|
||||
|
||||
static inline void local_flush_icache_range(unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
local_flush_icache_all();
|
||||
}
|
||||
|
||||
#define PG_dcache_clean PG_arch_1
|
||||
|
||||
static inline void flush_dcache_folio(struct folio *folio)
|
||||
|
@ -124,20 +124,82 @@ struct dyn_ftrace;
|
||||
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
|
||||
#define ftrace_init_nop ftrace_init_nop
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
|
||||
#define arch_ftrace_get_regs(regs) NULL
|
||||
struct ftrace_ops;
|
||||
struct ftrace_regs;
|
||||
struct ftrace_regs {
|
||||
unsigned long epc;
|
||||
unsigned long ra;
|
||||
unsigned long sp;
|
||||
unsigned long s0;
|
||||
unsigned long t1;
|
||||
union {
|
||||
unsigned long args[8];
|
||||
struct {
|
||||
unsigned long a0;
|
||||
unsigned long a1;
|
||||
unsigned long a2;
|
||||
unsigned long a3;
|
||||
unsigned long a4;
|
||||
unsigned long a5;
|
||||
unsigned long a6;
|
||||
unsigned long a7;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
static __always_inline unsigned long ftrace_regs_get_instruction_pointer(const struct ftrace_regs
|
||||
*fregs)
|
||||
{
|
||||
return fregs->epc;
|
||||
}
|
||||
|
||||
static __always_inline void ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
|
||||
unsigned long pc)
|
||||
{
|
||||
fregs->epc = pc;
|
||||
}
|
||||
|
||||
static __always_inline unsigned long ftrace_regs_get_stack_pointer(const struct ftrace_regs *fregs)
|
||||
{
|
||||
return fregs->sp;
|
||||
}
|
||||
|
||||
static __always_inline unsigned long ftrace_regs_get_argument(struct ftrace_regs *fregs,
|
||||
unsigned int n)
|
||||
{
|
||||
if (n < 8)
|
||||
return fregs->args[n];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __always_inline unsigned long ftrace_regs_get_return_value(const struct ftrace_regs *fregs)
|
||||
{
|
||||
return fregs->a0;
|
||||
}
|
||||
|
||||
static __always_inline void ftrace_regs_set_return_value(struct ftrace_regs *fregs,
|
||||
unsigned long ret)
|
||||
{
|
||||
fregs->a0 = ret;
|
||||
}
|
||||
|
||||
static __always_inline void ftrace_override_function_with_return(struct ftrace_regs *fregs)
|
||||
{
|
||||
fregs->epc = fregs->ra;
|
||||
}
|
||||
|
||||
int ftrace_regs_query_register_offset(const char *name);
|
||||
|
||||
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
|
||||
struct ftrace_ops *op, struct ftrace_regs *fregs);
|
||||
#define ftrace_graph_func ftrace_graph_func
|
||||
|
||||
static inline void __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr)
|
||||
static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, unsigned long addr)
|
||||
{
|
||||
regs->t1 = addr;
|
||||
fregs->t1 = addr;
|
||||
}
|
||||
#define arch_ftrace_set_direct_caller(fregs, addr) \
|
||||
__arch_ftrace_set_direct_caller(&(fregs)->regs, addr)
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
@ -16,8 +16,6 @@ extern bool pgtable_l5_enabled;
|
||||
#define PGDIR_SHIFT_L3 30
|
||||
#define PGDIR_SHIFT_L4 39
|
||||
#define PGDIR_SHIFT_L5 48
|
||||
#define PGDIR_SIZE_L3 (_AC(1, UL) << PGDIR_SHIFT_L3)
|
||||
|
||||
#define PGDIR_SHIFT (pgtable_l5_enabled ? PGDIR_SHIFT_L5 : \
|
||||
(pgtable_l4_enabled ? PGDIR_SHIFT_L4 : PGDIR_SHIFT_L3))
|
||||
/* Size of region mapped by a page global directory */
|
||||
|
@ -880,7 +880,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
|
||||
*/
|
||||
#ifdef CONFIG_64BIT
|
||||
#define TASK_SIZE_64 (PGDIR_SIZE * PTRS_PER_PGD / 2)
|
||||
#define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)
|
||||
#define TASK_SIZE_MAX LONG_MAX
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE)
|
||||
@ -892,7 +892,6 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
|
||||
|
||||
#else
|
||||
#define TASK_SIZE FIXADDR_START
|
||||
#define TASK_SIZE_MIN TASK_SIZE
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_MMU */
|
||||
|
@ -382,6 +382,8 @@ static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1
|
||||
static inline void sbi_init(void) {}
|
||||
#endif /* CONFIG_RISCV_SBI */
|
||||
|
||||
unsigned long riscv_get_mvendorid(void);
|
||||
unsigned long riscv_get_marchid(void);
|
||||
unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
|
||||
unsigned long riscv_cached_marchid(unsigned int cpu_id);
|
||||
unsigned long riscv_cached_mimpid(unsigned int cpu_id);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/kbuild.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <asm/kvm_host.h>
|
||||
#include <asm/thread_info.h>
|
||||
@ -488,4 +489,21 @@ void asm_offsets(void)
|
||||
DEFINE(STACKFRAME_SIZE_ON_STACK, ALIGN(sizeof(struct stackframe), STACK_ALIGN));
|
||||
OFFSET(STACKFRAME_FP, stackframe, fp);
|
||||
OFFSET(STACKFRAME_RA, stackframe, ra);
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
|
||||
DEFINE(FREGS_SIZE_ON_STACK, ALIGN(sizeof(struct ftrace_regs), STACK_ALIGN));
|
||||
DEFINE(FREGS_EPC, offsetof(struct ftrace_regs, epc));
|
||||
DEFINE(FREGS_RA, offsetof(struct ftrace_regs, ra));
|
||||
DEFINE(FREGS_SP, offsetof(struct ftrace_regs, sp));
|
||||
DEFINE(FREGS_S0, offsetof(struct ftrace_regs, s0));
|
||||
DEFINE(FREGS_T1, offsetof(struct ftrace_regs, t1));
|
||||
DEFINE(FREGS_A0, offsetof(struct ftrace_regs, a0));
|
||||
DEFINE(FREGS_A1, offsetof(struct ftrace_regs, a1));
|
||||
DEFINE(FREGS_A2, offsetof(struct ftrace_regs, a2));
|
||||
DEFINE(FREGS_A3, offsetof(struct ftrace_regs, a3));
|
||||
DEFINE(FREGS_A4, offsetof(struct ftrace_regs, a4));
|
||||
DEFINE(FREGS_A5, offsetof(struct ftrace_regs, a5));
|
||||
DEFINE(FREGS_A6, offsetof(struct ftrace_regs, a6));
|
||||
DEFINE(FREGS_A7, offsetof(struct ftrace_regs, a7));
|
||||
#endif
|
||||
}
|
||||
|
@ -139,6 +139,34 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long __init riscv_get_marchid(void)
|
||||
{
|
||||
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
|
||||
|
||||
#if IS_ENABLED(CONFIG_RISCV_SBI)
|
||||
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
|
||||
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
|
||||
ci->marchid = csr_read(CSR_MARCHID);
|
||||
#else
|
||||
ci->marchid = 0;
|
||||
#endif
|
||||
return ci->marchid;
|
||||
}
|
||||
|
||||
unsigned long __init riscv_get_mvendorid(void)
|
||||
{
|
||||
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
|
||||
|
||||
#if IS_ENABLED(CONFIG_RISCV_SBI)
|
||||
ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
|
||||
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
|
||||
ci->mvendorid = csr_read(CSR_MVENDORID);
|
||||
#else
|
||||
ci->mvendorid = 0;
|
||||
#endif
|
||||
return ci->mvendorid;
|
||||
}
|
||||
|
||||
DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
|
||||
|
||||
unsigned long riscv_cached_mvendorid(unsigned int cpu_id)
|
||||
@ -170,12 +198,16 @@ static int riscv_cpuinfo_starting(unsigned int cpu)
|
||||
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
|
||||
|
||||
#if IS_ENABLED(CONFIG_RISCV_SBI)
|
||||
ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
|
||||
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
|
||||
if (!ci->mvendorid)
|
||||
ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
|
||||
if (!ci->marchid)
|
||||
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
|
||||
ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid();
|
||||
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
|
||||
ci->mvendorid = csr_read(CSR_MVENDORID);
|
||||
ci->marchid = csr_read(CSR_MARCHID);
|
||||
if (!ci->mvendorid)
|
||||
ci->mvendorid = csr_read(CSR_MVENDORID);
|
||||
if (!ci->marchid)
|
||||
ci->marchid = csr_read(CSR_MARCHID);
|
||||
ci->mimpid = csr_read(CSR_MIMPID);
|
||||
#else
|
||||
ci->mvendorid = 0;
|
||||
|
@ -490,6 +490,8 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
|
||||
struct acpi_table_header *rhct;
|
||||
acpi_status status;
|
||||
unsigned int cpu;
|
||||
u64 boot_vendorid;
|
||||
u64 boot_archid;
|
||||
|
||||
if (!acpi_disabled) {
|
||||
status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
|
||||
@ -497,6 +499,9 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
|
||||
return;
|
||||
}
|
||||
|
||||
boot_vendorid = riscv_get_mvendorid();
|
||||
boot_archid = riscv_get_marchid();
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct riscv_isainfo *isainfo = &hart_isa[cpu];
|
||||
unsigned long this_hwcap = 0;
|
||||
@ -544,8 +549,7 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
|
||||
* CPU cores with the ratified spec will contain non-zero
|
||||
* marchid.
|
||||
*/
|
||||
if (acpi_disabled && riscv_cached_mvendorid(cpu) == THEAD_VENDOR_ID &&
|
||||
riscv_cached_marchid(cpu) == 0x0) {
|
||||
if (acpi_disabled && boot_vendorid == THEAD_VENDOR_ID && boot_archid == 0x0) {
|
||||
this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v];
|
||||
clear_bit(RISCV_ISA_EXT_v, isainfo->isa);
|
||||
}
|
||||
@ -599,7 +603,7 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
|
||||
|
||||
if (ext->subset_ext_size) {
|
||||
for (int j = 0; j < ext->subset_ext_size; j++) {
|
||||
if (riscv_isa_extension_check(ext->subset_ext_ids[i]))
|
||||
if (riscv_isa_extension_check(ext->subset_ext_ids[j]))
|
||||
set_bit(ext->subset_ext_ids[j], isainfo->isa);
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ SYM_FUNC_START(put_f64_reg)
|
||||
SYM_FUNC_END(put_f64_reg)
|
||||
|
||||
/*
|
||||
* put_f64_reg - Get a 64 bits FP register value and returned it or store it to
|
||||
* get_f64_reg - Get a 64 bits FP register value and returned it or store it to
|
||||
* a pointer.
|
||||
* a0 = FP register index to be retrieved
|
||||
* a1 = If xlen == 32, pointer which should be loaded with the FP register value
|
||||
|
@ -120,6 +120,9 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
|
||||
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
|
||||
mutex_unlock(&text_mutex);
|
||||
|
||||
if (!mod)
|
||||
local_flush_icache_range(rec->ip, rec->ip + MCOUNT_INSN_SIZE);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -127,10 +130,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
|
||||
{
|
||||
int ret = __ftrace_modify_call((unsigned long)&ftrace_call,
|
||||
(unsigned long)func, true, true);
|
||||
if (!ret) {
|
||||
ret = __ftrace_modify_call((unsigned long)&ftrace_regs_call,
|
||||
(unsigned long)func, true, true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -172,7 +171,7 @@ void arch_ftrace_update_code(int command)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
||||
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
|
||||
unsigned long addr)
|
||||
{
|
||||
@ -214,16 +213,13 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
|
||||
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
|
||||
struct ftrace_ops *op, struct ftrace_regs *fregs)
|
||||
{
|
||||
struct pt_regs *regs = arch_ftrace_get_regs(fregs);
|
||||
unsigned long *parent = (unsigned long *)®s->ra;
|
||||
|
||||
prepare_ftrace_return(parent, ip, frame_pointer(regs));
|
||||
prepare_ftrace_return(&fregs->ra, ip, fregs->s0);
|
||||
}
|
||||
#else /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
|
||||
#else /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
|
||||
extern void ftrace_graph_call(void);
|
||||
int ftrace_enable_ftrace_graph_caller(void)
|
||||
{
|
||||
@ -236,6 +232,6 @@ int ftrace_disable_ftrace_graph_caller(void)
|
||||
return __ftrace_modify_call((unsigned long)&ftrace_graph_call,
|
||||
(unsigned long)&prepare_ftrace_return, false, true);
|
||||
}
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE */
|
||||
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
||||
|
@ -56,138 +56,77 @@
|
||||
addi sp, sp, ABI_SIZE_ON_STACK
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
|
||||
|
||||
/**
|
||||
* SAVE_ABI_REGS - save regs against the pt_regs struct
|
||||
*
|
||||
* @all: tell if saving all the regs
|
||||
*
|
||||
* If all is set, all the regs will be saved, otherwise only ABI
|
||||
* related regs (a0-a7,epc,ra and optional s0) will be saved.
|
||||
* SAVE_ABI_REGS - save regs against the ftrace_regs struct
|
||||
*
|
||||
* After the stack is established,
|
||||
*
|
||||
* 0(sp) stores the PC of the traced function which can be accessed
|
||||
* by &(fregs)->regs->epc in tracing function. Note that the real
|
||||
* by &(fregs)->epc in tracing function. Note that the real
|
||||
* function entry address should be computed with -FENTRY_RA_OFFSET.
|
||||
*
|
||||
* 8(sp) stores the function return address (i.e. parent IP) that
|
||||
* can be accessed by &(fregs)->regs->ra in tracing function.
|
||||
* can be accessed by &(fregs)->ra in tracing function.
|
||||
*
|
||||
* The other regs are saved at the respective localtion and accessed
|
||||
* by the respective pt_regs member.
|
||||
* by the respective ftrace_regs member.
|
||||
*
|
||||
* Here is the layout of stack for your reference.
|
||||
*
|
||||
* PT_SIZE_ON_STACK -> +++++++++
|
||||
* + ..... +
|
||||
* + t3-t6 +
|
||||
* + s2-s11+
|
||||
* + a0-a7 + --++++-> ftrace_caller saved
|
||||
* + s1 + +
|
||||
* + s0 + --+
|
||||
* + t0-t2 + +
|
||||
* + tp + +
|
||||
* + gp + +
|
||||
* + t1 + --++++-> direct tramp address
|
||||
* + s0 + --+ // frame pointer
|
||||
* + sp + +
|
||||
* + ra + --+ // parent IP
|
||||
* sp -> + epc + --+ // PC
|
||||
* +++++++++
|
||||
**/
|
||||
.macro SAVE_ABI_REGS, all=0
|
||||
addi sp, sp, -PT_SIZE_ON_STACK
|
||||
.macro SAVE_ABI_REGS
|
||||
mv t4, sp // Save original SP in T4
|
||||
addi sp, sp, -FREGS_SIZE_ON_STACK
|
||||
|
||||
REG_S t0, PT_EPC(sp)
|
||||
REG_S x1, PT_RA(sp)
|
||||
|
||||
// save the ABI regs
|
||||
|
||||
REG_S x10, PT_A0(sp)
|
||||
REG_S x11, PT_A1(sp)
|
||||
REG_S x12, PT_A2(sp)
|
||||
REG_S x13, PT_A3(sp)
|
||||
REG_S x14, PT_A4(sp)
|
||||
REG_S x15, PT_A5(sp)
|
||||
REG_S x16, PT_A6(sp)
|
||||
REG_S x17, PT_A7(sp)
|
||||
|
||||
// save the leftover regs
|
||||
|
||||
.if \all == 1
|
||||
REG_S x2, PT_SP(sp)
|
||||
REG_S x3, PT_GP(sp)
|
||||
REG_S x4, PT_TP(sp)
|
||||
REG_S x5, PT_T0(sp)
|
||||
REG_S x6, PT_T1(sp)
|
||||
REG_S x7, PT_T2(sp)
|
||||
REG_S x8, PT_S0(sp)
|
||||
REG_S x9, PT_S1(sp)
|
||||
REG_S x18, PT_S2(sp)
|
||||
REG_S x19, PT_S3(sp)
|
||||
REG_S x20, PT_S4(sp)
|
||||
REG_S x21, PT_S5(sp)
|
||||
REG_S x22, PT_S6(sp)
|
||||
REG_S x23, PT_S7(sp)
|
||||
REG_S x24, PT_S8(sp)
|
||||
REG_S x25, PT_S9(sp)
|
||||
REG_S x26, PT_S10(sp)
|
||||
REG_S x27, PT_S11(sp)
|
||||
REG_S x28, PT_T3(sp)
|
||||
REG_S x29, PT_T4(sp)
|
||||
REG_S x30, PT_T5(sp)
|
||||
REG_S x31, PT_T6(sp)
|
||||
|
||||
// save s0 if FP_TEST defined
|
||||
|
||||
.else
|
||||
REG_S t0, FREGS_EPC(sp)
|
||||
REG_S x1, FREGS_RA(sp)
|
||||
REG_S t4, FREGS_SP(sp) // Put original SP on stack
|
||||
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
|
||||
REG_S x8, PT_S0(sp)
|
||||
REG_S x8, FREGS_S0(sp)
|
||||
#endif
|
||||
.endif
|
||||
REG_S x6, FREGS_T1(sp)
|
||||
|
||||
// save the arguments
|
||||
REG_S x10, FREGS_A0(sp)
|
||||
REG_S x11, FREGS_A1(sp)
|
||||
REG_S x12, FREGS_A2(sp)
|
||||
REG_S x13, FREGS_A3(sp)
|
||||
REG_S x14, FREGS_A4(sp)
|
||||
REG_S x15, FREGS_A5(sp)
|
||||
REG_S x16, FREGS_A6(sp)
|
||||
REG_S x17, FREGS_A7(sp)
|
||||
.endm
|
||||
|
||||
.macro RESTORE_ABI_REGS, all=0
|
||||
REG_L t0, PT_EPC(sp)
|
||||
REG_L x1, PT_RA(sp)
|
||||
REG_L x10, PT_A0(sp)
|
||||
REG_L x11, PT_A1(sp)
|
||||
REG_L x12, PT_A2(sp)
|
||||
REG_L x13, PT_A3(sp)
|
||||
REG_L x14, PT_A4(sp)
|
||||
REG_L x15, PT_A5(sp)
|
||||
REG_L x16, PT_A6(sp)
|
||||
REG_L x17, PT_A7(sp)
|
||||
|
||||
.if \all == 1
|
||||
REG_L x2, PT_SP(sp)
|
||||
REG_L x3, PT_GP(sp)
|
||||
REG_L x4, PT_TP(sp)
|
||||
REG_L x6, PT_T1(sp)
|
||||
REG_L x7, PT_T2(sp)
|
||||
REG_L x8, PT_S0(sp)
|
||||
REG_L x9, PT_S1(sp)
|
||||
REG_L x18, PT_S2(sp)
|
||||
REG_L x19, PT_S3(sp)
|
||||
REG_L x20, PT_S4(sp)
|
||||
REG_L x21, PT_S5(sp)
|
||||
REG_L x22, PT_S6(sp)
|
||||
REG_L x23, PT_S7(sp)
|
||||
REG_L x24, PT_S8(sp)
|
||||
REG_L x25, PT_S9(sp)
|
||||
REG_L x26, PT_S10(sp)
|
||||
REG_L x27, PT_S11(sp)
|
||||
REG_L x28, PT_T3(sp)
|
||||
REG_L x29, PT_T4(sp)
|
||||
REG_L x30, PT_T5(sp)
|
||||
REG_L x31, PT_T6(sp)
|
||||
|
||||
.else
|
||||
REG_L t0, FREGS_EPC(sp)
|
||||
REG_L x1, FREGS_RA(sp)
|
||||
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
|
||||
REG_L x8, PT_S0(sp)
|
||||
REG_L x8, FREGS_S0(sp)
|
||||
#endif
|
||||
.endif
|
||||
addi sp, sp, PT_SIZE_ON_STACK
|
||||
REG_L x6, FREGS_T1(sp)
|
||||
|
||||
// restore the arguments
|
||||
REG_L x10, FREGS_A0(sp)
|
||||
REG_L x11, FREGS_A1(sp)
|
||||
REG_L x12, FREGS_A2(sp)
|
||||
REG_L x13, FREGS_A3(sp)
|
||||
REG_L x14, FREGS_A4(sp)
|
||||
REG_L x15, FREGS_A5(sp)
|
||||
REG_L x16, FREGS_A6(sp)
|
||||
REG_L x17, FREGS_A7(sp)
|
||||
|
||||
addi sp, sp, FREGS_SIZE_ON_STACK
|
||||
.endm
|
||||
|
||||
.macro PREPARE_ARGS
|
||||
@ -198,9 +137,9 @@
|
||||
mv a3, sp
|
||||
.endm
|
||||
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
|
||||
|
||||
#ifndef CONFIG_DYNAMIC_FTRACE_WITH_REGS
|
||||
#ifndef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
|
||||
SYM_FUNC_START(ftrace_caller)
|
||||
SAVE_ABI
|
||||
|
||||
@ -227,33 +166,23 @@ SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
|
||||
jr t0
|
||||
SYM_FUNC_END(ftrace_caller)
|
||||
|
||||
#else /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
|
||||
SYM_FUNC_START(ftrace_regs_caller)
|
||||
mv t1, zero
|
||||
SAVE_ABI_REGS 1
|
||||
PREPARE_ARGS
|
||||
|
||||
SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL)
|
||||
call ftrace_stub
|
||||
|
||||
RESTORE_ABI_REGS 1
|
||||
bnez t1, .Ldirect
|
||||
jr t0
|
||||
.Ldirect:
|
||||
jr t1
|
||||
SYM_FUNC_END(ftrace_regs_caller)
|
||||
|
||||
#else /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
|
||||
SYM_FUNC_START(ftrace_caller)
|
||||
SAVE_ABI_REGS 0
|
||||
mv t1, zero
|
||||
SAVE_ABI_REGS
|
||||
PREPARE_ARGS
|
||||
|
||||
SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
|
||||
call ftrace_stub
|
||||
|
||||
RESTORE_ABI_REGS 0
|
||||
RESTORE_ABI_REGS
|
||||
bnez t1, .Ldirect
|
||||
jr t0
|
||||
.Ldirect:
|
||||
jr t1
|
||||
SYM_FUNC_END(ftrace_caller)
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
|
||||
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
||||
SYM_CODE_START(ftrace_stub_direct_tramp)
|
||||
|
@ -224,7 +224,7 @@ asmlinkage __visible void smp_callin(void)
|
||||
riscv_ipi_enable();
|
||||
|
||||
numa_add_cpu(curr_cpuid);
|
||||
set_cpu_online(curr_cpuid, 1);
|
||||
set_cpu_online(curr_cpuid, true);
|
||||
|
||||
if (has_vector()) {
|
||||
if (riscv_v_setup_vsize())
|
||||
|
@ -18,6 +18,16 @@
|
||||
|
||||
extern asmlinkage void ret_from_exception(void);
|
||||
|
||||
static inline int fp_is_valid(unsigned long fp, unsigned long sp)
|
||||
{
|
||||
unsigned long low, high;
|
||||
|
||||
low = sp + sizeof(struct stackframe);
|
||||
high = ALIGN(sp, THREAD_SIZE);
|
||||
|
||||
return !(fp < low || fp > high || fp & 0x07);
|
||||
}
|
||||
|
||||
void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
|
||||
bool (*fn)(void *, unsigned long), void *arg)
|
||||
{
|
||||
@ -41,21 +51,19 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
unsigned long low, high;
|
||||
struct stackframe *frame;
|
||||
|
||||
if (unlikely(!__kernel_text_address(pc) || (level++ >= 0 && !fn(arg, pc))))
|
||||
break;
|
||||
|
||||
/* Validate frame pointer */
|
||||
low = sp + sizeof(struct stackframe);
|
||||
high = ALIGN(sp, THREAD_SIZE);
|
||||
if (unlikely(fp < low || fp > high || fp & 0x7))
|
||||
if (unlikely(!fp_is_valid(fp, sp)))
|
||||
break;
|
||||
|
||||
/* Unwind stack frame */
|
||||
frame = (struct stackframe *)fp - 1;
|
||||
sp = fp;
|
||||
if (regs && (regs->epc == pc) && (frame->fp & 0x7)) {
|
||||
if (regs && (regs->epc == pc) && fp_is_valid(frame->ra, sp)) {
|
||||
/* We hit function where ra is not saved on the stack */
|
||||
fp = frame->ra;
|
||||
pc = regs->ra;
|
||||
} else {
|
||||
|
@ -44,7 +44,7 @@ SYM_FUNC_START(fallback_scalar_usercopy)
|
||||
* Use byte copy only if too small.
|
||||
* SZREG holds 4 for RV32 and 8 for RV64
|
||||
*/
|
||||
li a3, 9*SZREG /* size must be larger than size in word_copy */
|
||||
li a3, 9*SZREG-1 /* size must >= (word_copy stride + SZREG-1) */
|
||||
bltu a2, a3, .Lbyte_copy_tail
|
||||
|
||||
/*
|
||||
@ -103,7 +103,7 @@ SYM_FUNC_START(fallback_scalar_usercopy)
|
||||
fixup REG_S t4, 7*SZREG(a0), 10f
|
||||
addi a0, a0, 8*SZREG
|
||||
addi a1, a1, 8*SZREG
|
||||
bltu a0, t0, 2b
|
||||
bleu a0, t0, 2b
|
||||
|
||||
addi t0, t0, 8*SZREG /* revert to original value */
|
||||
j .Lbyte_copy_tail
|
||||
|
@ -293,8 +293,8 @@ void handle_page_fault(struct pt_regs *regs)
|
||||
if (unlikely(access_error(cause, vma))) {
|
||||
vma_end_read(vma);
|
||||
count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
|
||||
tsk->thread.bad_cause = cause;
|
||||
bad_area_nosemaphore(regs, SEGV_ACCERR, addr);
|
||||
tsk->thread.bad_cause = SEGV_ACCERR;
|
||||
bad_area_nosemaphore(regs, code, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -683,6 +683,9 @@ void __init create_pgd_mapping(pgd_t *pgdp,
|
||||
static uintptr_t __init best_map_size(phys_addr_t pa, uintptr_t va,
|
||||
phys_addr_t size)
|
||||
{
|
||||
if (debug_pagealloc_enabled())
|
||||
return PAGE_SIZE;
|
||||
|
||||
if (pgtable_l5_enabled &&
|
||||
!(pa & (P4D_SIZE - 1)) && !(va & (P4D_SIZE - 1)) && size >= P4D_SIZE)
|
||||
return P4D_SIZE;
|
||||
|
@ -387,17 +387,33 @@ int set_direct_map_default_noflush(struct page *page)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_PAGEALLOC
|
||||
static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data)
|
||||
{
|
||||
int enable = *(int *)data;
|
||||
|
||||
unsigned long val = pte_val(ptep_get(pte));
|
||||
|
||||
if (enable)
|
||||
val |= _PAGE_PRESENT;
|
||||
else
|
||||
val &= ~_PAGE_PRESENT;
|
||||
|
||||
set_pte(pte, __pte(val));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __kernel_map_pages(struct page *page, int numpages, int enable)
|
||||
{
|
||||
if (!debug_pagealloc_enabled())
|
||||
return;
|
||||
|
||||
if (enable)
|
||||
__set_memory((unsigned long)page_address(page), numpages,
|
||||
__pgprot(_PAGE_PRESENT), __pgprot(0));
|
||||
else
|
||||
__set_memory((unsigned long)page_address(page), numpages,
|
||||
__pgprot(0), __pgprot(_PAGE_PRESENT));
|
||||
unsigned long start = (unsigned long)page_address(page);
|
||||
unsigned long size = PAGE_SIZE * numpages;
|
||||
|
||||
apply_to_existing_page_range(&init_mm, start, size, debug_pagealloc_set_page, &enable);
|
||||
|
||||
flush_tlb_kernel_range(start, start + size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -379,3 +379,36 @@ void __init xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns)
|
||||
|
||||
memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XEN_UNPOPULATED_ALLOC
|
||||
int __init arch_xen_unpopulated_init(struct resource **res)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!xen_domain())
|
||||
return -ENODEV;
|
||||
|
||||
/* Must be set strictly before calling xen_free_unpopulated_pages(). */
|
||||
*res = &iomem_resource;
|
||||
|
||||
/*
|
||||
* Initialize with pages from the extra memory regions (see
|
||||
* arch/x86/xen/setup.c).
|
||||
*/
|
||||
for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
|
||||
unsigned int j;
|
||||
|
||||
for (j = 0; j < xen_extra_mem[i].n_pfns; j++) {
|
||||
struct page *pg =
|
||||
pfn_to_page(xen_extra_mem[i].start_pfn + j);
|
||||
|
||||
xen_free_unpopulated_pages(1, &pg);
|
||||
}
|
||||
|
||||
/* Zero so region is not also added to the balloon driver. */
|
||||
xen_extra_mem[i].n_pfns = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -555,7 +555,6 @@ int xen_alloc_p2m_entry(unsigned long pfn)
|
||||
/* Separately check the mid mfn level */
|
||||
unsigned long missing_mfn;
|
||||
unsigned long mid_mfn_mfn;
|
||||
unsigned long old_mfn;
|
||||
|
||||
mid_mfn = alloc_p2m_page();
|
||||
if (!mid_mfn)
|
||||
@ -565,12 +564,12 @@ int xen_alloc_p2m_entry(unsigned long pfn)
|
||||
|
||||
missing_mfn = virt_to_mfn(p2m_mid_missing_mfn);
|
||||
mid_mfn_mfn = virt_to_mfn(mid_mfn);
|
||||
old_mfn = cmpxchg(top_mfn_p, missing_mfn, mid_mfn_mfn);
|
||||
if (old_mfn != missing_mfn) {
|
||||
free_p2m_page(mid_mfn);
|
||||
mid_mfn = mfn_to_virt(old_mfn);
|
||||
} else {
|
||||
/* try_cmpxchg() updates missing_mfn on failure. */
|
||||
if (try_cmpxchg(top_mfn_p, &missing_mfn, mid_mfn_mfn)) {
|
||||
p2m_top_mfn_p[topidx] = mid_mfn;
|
||||
} else {
|
||||
free_p2m_page(mid_mfn);
|
||||
mid_mfn = mfn_to_virt(missing_mfn);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -322,6 +322,7 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct gendisk *disk,
|
||||
blkg->q = disk->queue;
|
||||
INIT_LIST_HEAD(&blkg->q_node);
|
||||
blkg->blkcg = blkcg;
|
||||
blkg->iostat.blkg = blkg;
|
||||
#ifdef CONFIG_BLK_CGROUP_PUNT_BIO
|
||||
spin_lock_init(&blkg->async_bio_lock);
|
||||
bio_list_init(&blkg->async_bios);
|
||||
@ -618,12 +619,45 @@ restart:
|
||||
spin_unlock_irq(&q->queue_lock);
|
||||
}
|
||||
|
||||
static void blkg_iostat_set(struct blkg_iostat *dst, struct blkg_iostat *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BLKG_IOSTAT_NR; i++) {
|
||||
dst->bytes[i] = src->bytes[i];
|
||||
dst->ios[i] = src->ios[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void __blkg_clear_stat(struct blkg_iostat_set *bis)
|
||||
{
|
||||
struct blkg_iostat cur = {0};
|
||||
unsigned long flags;
|
||||
|
||||
flags = u64_stats_update_begin_irqsave(&bis->sync);
|
||||
blkg_iostat_set(&bis->cur, &cur);
|
||||
blkg_iostat_set(&bis->last, &cur);
|
||||
u64_stats_update_end_irqrestore(&bis->sync, flags);
|
||||
}
|
||||
|
||||
static void blkg_clear_stat(struct blkcg_gq *blkg)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct blkg_iostat_set *s = per_cpu_ptr(blkg->iostat_cpu, cpu);
|
||||
|
||||
__blkg_clear_stat(s);
|
||||
}
|
||||
__blkg_clear_stat(&blkg->iostat);
|
||||
}
|
||||
|
||||
static int blkcg_reset_stats(struct cgroup_subsys_state *css,
|
||||
struct cftype *cftype, u64 val)
|
||||
{
|
||||
struct blkcg *blkcg = css_to_blkcg(css);
|
||||
struct blkcg_gq *blkg;
|
||||
int i, cpu;
|
||||
int i;
|
||||
|
||||
mutex_lock(&blkcg_pol_mutex);
|
||||
spin_lock_irq(&blkcg->lock);
|
||||
@ -634,18 +668,7 @@ static int blkcg_reset_stats(struct cgroup_subsys_state *css,
|
||||
* anyway. If you get hit by a race, retry.
|
||||
*/
|
||||
hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct blkg_iostat_set *bis =
|
||||
per_cpu_ptr(blkg->iostat_cpu, cpu);
|
||||
memset(bis, 0, sizeof(*bis));
|
||||
|
||||
/* Re-initialize the cleared blkg_iostat_set */
|
||||
u64_stats_init(&bis->sync);
|
||||
bis->blkg = blkg;
|
||||
}
|
||||
memset(&blkg->iostat, 0, sizeof(blkg->iostat));
|
||||
u64_stats_init(&blkg->iostat.sync);
|
||||
|
||||
blkg_clear_stat(blkg);
|
||||
for (i = 0; i < BLKCG_MAX_POLS; i++) {
|
||||
struct blkcg_policy *pol = blkcg_policy[i];
|
||||
|
||||
@ -948,16 +971,6 @@ void blkg_conf_exit(struct blkg_conf_ctx *ctx)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkg_conf_exit);
|
||||
|
||||
static void blkg_iostat_set(struct blkg_iostat *dst, struct blkg_iostat *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BLKG_IOSTAT_NR; i++) {
|
||||
dst->bytes[i] = src->bytes[i];
|
||||
dst->ios[i] = src->ios[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void blkg_iostat_add(struct blkg_iostat *dst, struct blkg_iostat *src)
|
||||
{
|
||||
int i;
|
||||
@ -1023,7 +1036,19 @@ static void __blkcg_rstat_flush(struct blkcg *blkcg, int cpu)
|
||||
struct blkg_iostat cur;
|
||||
unsigned int seq;
|
||||
|
||||
/*
|
||||
* Order assignment of `next_bisc` from `bisc->lnode.next` in
|
||||
* llist_for_each_entry_safe and clearing `bisc->lqueued` for
|
||||
* avoiding to assign `next_bisc` with new next pointer added
|
||||
* in blk_cgroup_bio_start() in case of re-ordering.
|
||||
*
|
||||
* The pair barrier is implied in llist_add() in blk_cgroup_bio_start().
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
WRITE_ONCE(bisc->lqueued, false);
|
||||
if (bisc == &blkg->iostat)
|
||||
goto propagate_up; /* propagate up to parent only */
|
||||
|
||||
/* fetch the current per-cpu values */
|
||||
do {
|
||||
@ -1033,10 +1058,24 @@ static void __blkcg_rstat_flush(struct blkcg *blkcg, int cpu)
|
||||
|
||||
blkcg_iostat_update(blkg, &cur, &bisc->last);
|
||||
|
||||
propagate_up:
|
||||
/* propagate global delta to parent (unless that's root) */
|
||||
if (parent && parent->parent)
|
||||
if (parent && parent->parent) {
|
||||
blkcg_iostat_update(parent, &blkg->iostat.cur,
|
||||
&blkg->iostat.last);
|
||||
/*
|
||||
* Queue parent->iostat to its blkcg's lockless
|
||||
* list to propagate up to the grandparent if the
|
||||
* iostat hasn't been queued yet.
|
||||
*/
|
||||
if (!parent->iostat.lqueued) {
|
||||
struct llist_head *plhead;
|
||||
|
||||
plhead = per_cpu_ptr(parent->blkcg->lhead, cpu);
|
||||
llist_add(&parent->iostat.lnode, plhead);
|
||||
parent->iostat.lqueued = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
raw_spin_unlock_irqrestore(&blkg_stat_lock, flags);
|
||||
out:
|
||||
|
@ -615,9 +615,14 @@ static inline blk_status_t blk_check_zone_append(struct request_queue *q,
|
||||
|
||||
static void __submit_bio(struct bio *bio)
|
||||
{
|
||||
/* If plug is not used, add new plug here to cache nsecs time. */
|
||||
struct blk_plug plug;
|
||||
|
||||
if (unlikely(!blk_crypto_bio_prep(&bio)))
|
||||
return;
|
||||
|
||||
blk_start_plug(&plug);
|
||||
|
||||
if (!bdev_test_flag(bio->bi_bdev, BD_HAS_SUBMIT_BIO)) {
|
||||
blk_mq_submit_bio(bio);
|
||||
} else if (likely(bio_queue_enter(bio) == 0)) {
|
||||
@ -626,6 +631,8 @@ static void __submit_bio(struct bio *bio)
|
||||
disk->fops->submit_bio(bio);
|
||||
blk_queue_exit(disk->queue);
|
||||
}
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -650,13 +657,11 @@ static void __submit_bio(struct bio *bio)
|
||||
static void __submit_bio_noacct(struct bio *bio)
|
||||
{
|
||||
struct bio_list bio_list_on_stack[2];
|
||||
struct blk_plug plug;
|
||||
|
||||
BUG_ON(bio->bi_next);
|
||||
|
||||
bio_list_init(&bio_list_on_stack[0]);
|
||||
current->bio_list = bio_list_on_stack;
|
||||
blk_start_plug(&plug);
|
||||
|
||||
do {
|
||||
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
||||
@ -690,23 +695,19 @@ static void __submit_bio_noacct(struct bio *bio)
|
||||
bio_list_merge(&bio_list_on_stack[0], &bio_list_on_stack[1]);
|
||||
} while ((bio = bio_list_pop(&bio_list_on_stack[0])));
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
current->bio_list = NULL;
|
||||
}
|
||||
|
||||
static void __submit_bio_noacct_mq(struct bio *bio)
|
||||
{
|
||||
struct bio_list bio_list[2] = { };
|
||||
struct blk_plug plug;
|
||||
|
||||
current->bio_list = bio_list;
|
||||
blk_start_plug(&plug);
|
||||
|
||||
do {
|
||||
__submit_bio(bio);
|
||||
} while ((bio = bio_list_pop(&bio_list[0])));
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
current->bio_list = NULL;
|
||||
}
|
||||
|
||||
|
@ -3545,12 +3545,28 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if one CPU is mapped to the specified hctx
|
||||
*
|
||||
* Isolated CPUs have been ruled out from hctx->cpumask, which is supposed
|
||||
* to be used for scheduling kworker only. For other usage, please call this
|
||||
* helper for checking if one CPU belongs to the specified hctx
|
||||
*/
|
||||
static bool blk_mq_cpu_mapped_to_hctx(unsigned int cpu,
|
||||
const struct blk_mq_hw_ctx *hctx)
|
||||
{
|
||||
struct blk_mq_hw_ctx *mapped_hctx = blk_mq_map_queue_type(hctx->queue,
|
||||
hctx->type, cpu);
|
||||
|
||||
return mapped_hctx == hctx;
|
||||
}
|
||||
|
||||
static int blk_mq_hctx_notify_online(unsigned int cpu, struct hlist_node *node)
|
||||
{
|
||||
struct blk_mq_hw_ctx *hctx = hlist_entry_safe(node,
|
||||
struct blk_mq_hw_ctx, cpuhp_online);
|
||||
|
||||
if (cpumask_test_cpu(cpu, hctx->cpumask))
|
||||
if (blk_mq_cpu_mapped_to_hctx(cpu, hctx))
|
||||
clear_bit(BLK_MQ_S_INACTIVE, &hctx->state);
|
||||
return 0;
|
||||
}
|
||||
@ -3568,7 +3584,7 @@ static int blk_mq_hctx_notify_dead(unsigned int cpu, struct hlist_node *node)
|
||||
enum hctx_type type;
|
||||
|
||||
hctx = hlist_entry_safe(node, struct blk_mq_hw_ctx, cpuhp_dead);
|
||||
if (!cpumask_test_cpu(cpu, hctx->cpumask))
|
||||
if (!blk_mq_cpu_mapped_to_hctx(cpu, hctx))
|
||||
return 0;
|
||||
|
||||
ctx = __blk_mq_get_ctx(hctx->queue, cpu);
|
||||
|
@ -39,11 +39,6 @@ struct latency_bucket {
|
||||
int samples;
|
||||
};
|
||||
|
||||
struct avg_latency_bucket {
|
||||
unsigned long latency; /* ns / 1024 */
|
||||
bool valid;
|
||||
};
|
||||
|
||||
struct throtl_data
|
||||
{
|
||||
/* service tree for active throtl groups */
|
||||
|
@ -495,5 +495,5 @@ const struct blk_integrity_profile ext_pi_type3_crc64 = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ext_pi_type3_crc64);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("T10 Protection Information module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -574,7 +574,7 @@ static u_long get_word(struct vc_data *vc)
|
||||
}
|
||||
attr_ch = get_char(vc, (u_short *)tmp_pos, &spk_attr);
|
||||
buf[cnt++] = attr_ch;
|
||||
while (tmpx < vc->vc_cols - 1 && cnt < sizeof(buf) - 1) {
|
||||
while (tmpx < vc->vc_cols - 1 && cnt < ARRAY_SIZE(buf) - 1) {
|
||||
tmp_pos += 2;
|
||||
tmpx++;
|
||||
ch = get_char(vc, (u_short *)tmp_pos, &temp);
|
||||
|
@ -609,12 +609,19 @@ static void stride(struct kunit *test)
|
||||
config.reg_stride = 2;
|
||||
config.num_reg_defaults = BLOCK_TEST_SIZE / 2;
|
||||
|
||||
/*
|
||||
* Allow one extra register so that the read/written arrays
|
||||
* are sized big enough to include an entry for the odd
|
||||
* address past the final reg_default register.
|
||||
*/
|
||||
config.max_register = BLOCK_TEST_SIZE;
|
||||
|
||||
map = gen_regmap(test, &config, &data);
|
||||
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
|
||||
if (IS_ERR(map))
|
||||
return;
|
||||
|
||||
/* Only even registers can be accessed, try both read and write */
|
||||
/* Only even addresses can be accessed, try both read and write */
|
||||
for (i = 0; i < BLOCK_TEST_SIZE; i++) {
|
||||
data->read[i] = false;
|
||||
data->written[i] = false;
|
||||
|
@ -222,6 +222,23 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void brd_do_discard(struct brd_device *brd, sector_t sector, u32 size)
|
||||
{
|
||||
sector_t aligned_sector = (sector + PAGE_SECTORS) & ~PAGE_SECTORS;
|
||||
struct page *page;
|
||||
|
||||
size -= (aligned_sector - sector) * SECTOR_SIZE;
|
||||
xa_lock(&brd->brd_pages);
|
||||
while (size >= PAGE_SIZE && aligned_sector < rd_size * 2) {
|
||||
page = __xa_erase(&brd->brd_pages, aligned_sector >> PAGE_SECTORS_SHIFT);
|
||||
if (page)
|
||||
__free_page(page);
|
||||
aligned_sector += PAGE_SECTORS;
|
||||
size -= PAGE_SIZE;
|
||||
}
|
||||
xa_unlock(&brd->brd_pages);
|
||||
}
|
||||
|
||||
static void brd_submit_bio(struct bio *bio)
|
||||
{
|
||||
struct brd_device *brd = bio->bi_bdev->bd_disk->private_data;
|
||||
@ -229,6 +246,12 @@ static void brd_submit_bio(struct bio *bio)
|
||||
struct bio_vec bvec;
|
||||
struct bvec_iter iter;
|
||||
|
||||
if (unlikely(op_is_discard(bio->bi_opf))) {
|
||||
brd_do_discard(brd, sector, bio->bi_iter.bi_size);
|
||||
bio_endio(bio);
|
||||
return;
|
||||
}
|
||||
|
||||
bio_for_each_segment(bvec, bio, iter) {
|
||||
unsigned int len = bvec.bv_len;
|
||||
int err;
|
||||
@ -309,6 +332,9 @@ static int brd_alloc(int i)
|
||||
* is harmless)
|
||||
*/
|
||||
.physical_block_size = PAGE_SIZE,
|
||||
.max_hw_discard_sectors = UINT_MAX,
|
||||
.max_discard_segments = 1,
|
||||
.discard_granularity = PAGE_SIZE,
|
||||
};
|
||||
|
||||
list_for_each_entry(brd, &brd_devices, brd_list)
|
||||
|
@ -222,7 +222,7 @@ static ssize_t pid_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct gendisk *disk = dev_to_disk(dev);
|
||||
struct nbd_device *nbd = (struct nbd_device *)disk->private_data;
|
||||
struct nbd_device *nbd = disk->private_data;
|
||||
|
||||
return sprintf(buf, "%d\n", nbd->pid);
|
||||
}
|
||||
@ -236,7 +236,7 @@ static ssize_t backend_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct gendisk *disk = dev_to_disk(dev);
|
||||
struct nbd_device *nbd = (struct nbd_device *)disk->private_data;
|
||||
struct nbd_device *nbd = disk->private_data;
|
||||
|
||||
return sprintf(buf, "%s\n", nbd->backend ?: "");
|
||||
}
|
||||
@ -588,7 +588,10 @@ static inline int was_interrupted(int result)
|
||||
return result == -ERESTARTSYS || result == -EINTR;
|
||||
}
|
||||
|
||||
/* always call with the tx_lock held */
|
||||
/*
|
||||
* Returns BLK_STS_RESOURCE if the caller should retry after a delay. Returns
|
||||
* -EAGAIN if the caller should requeue @cmd. Returns -EIO if sending failed.
|
||||
*/
|
||||
static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
|
||||
{
|
||||
struct request *req = blk_mq_rq_from_pdu(cmd);
|
||||
@ -598,13 +601,15 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
|
||||
struct nbd_request request = {.magic = htonl(NBD_REQUEST_MAGIC)};
|
||||
struct kvec iov = {.iov_base = &request, .iov_len = sizeof(request)};
|
||||
struct iov_iter from;
|
||||
unsigned long size = blk_rq_bytes(req);
|
||||
struct bio *bio;
|
||||
u64 handle;
|
||||
u32 type;
|
||||
u32 nbd_cmd_flags = 0;
|
||||
int sent = nsock->sent, skip = 0;
|
||||
|
||||
lockdep_assert_held(&cmd->lock);
|
||||
lockdep_assert_held(&nsock->tx_lock);
|
||||
|
||||
iov_iter_kvec(&from, ITER_SOURCE, &iov, 1, sizeof(request));
|
||||
|
||||
type = req_to_nbd_cmd_type(req);
|
||||
@ -644,7 +649,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
|
||||
request.type = htonl(type | nbd_cmd_flags);
|
||||
if (type != NBD_CMD_FLUSH) {
|
||||
request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
|
||||
request.len = htonl(size);
|
||||
request.len = htonl(blk_rq_bytes(req));
|
||||
}
|
||||
handle = nbd_cmd_handle(cmd);
|
||||
request.cookie = cpu_to_be64(handle);
|
||||
@ -669,7 +674,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
|
||||
nsock->sent = sent;
|
||||
}
|
||||
set_bit(NBD_CMD_REQUEUED, &cmd->flags);
|
||||
return BLK_STS_RESOURCE;
|
||||
return (__force int)BLK_STS_RESOURCE;
|
||||
}
|
||||
dev_err_ratelimited(disk_to_dev(nbd->disk),
|
||||
"Send control failed (result %d)\n", result);
|
||||
@ -710,7 +715,7 @@ send_pages:
|
||||
nsock->pending = req;
|
||||
nsock->sent = sent;
|
||||
set_bit(NBD_CMD_REQUEUED, &cmd->flags);
|
||||
return BLK_STS_RESOURCE;
|
||||
return (__force int)BLK_STS_RESOURCE;
|
||||
}
|
||||
dev_err(disk_to_dev(nbd->disk),
|
||||
"Send data failed (result %d)\n",
|
||||
@ -1007,7 +1012,7 @@ static int wait_for_reconnect(struct nbd_device *nbd)
|
||||
return !test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags);
|
||||
}
|
||||
|
||||
static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
|
||||
static blk_status_t nbd_handle_cmd(struct nbd_cmd *cmd, int index)
|
||||
{
|
||||
struct request *req = blk_mq_rq_from_pdu(cmd);
|
||||
struct nbd_device *nbd = cmd->nbd;
|
||||
@ -1015,18 +1020,20 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
|
||||
struct nbd_sock *nsock;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&cmd->lock);
|
||||
|
||||
config = nbd_get_config_unlocked(nbd);
|
||||
if (!config) {
|
||||
dev_err_ratelimited(disk_to_dev(nbd->disk),
|
||||
"Socks array is empty\n");
|
||||
return -EINVAL;
|
||||
return BLK_STS_IOERR;
|
||||
}
|
||||
|
||||
if (index >= config->num_connections) {
|
||||
dev_err_ratelimited(disk_to_dev(nbd->disk),
|
||||
"Attempted send on invalid socket\n");
|
||||
nbd_config_put(nbd);
|
||||
return -EINVAL;
|
||||
return BLK_STS_IOERR;
|
||||
}
|
||||
cmd->status = BLK_STS_OK;
|
||||
again:
|
||||
@ -1049,7 +1056,7 @@ again:
|
||||
*/
|
||||
sock_shutdown(nbd);
|
||||
nbd_config_put(nbd);
|
||||
return -EIO;
|
||||
return BLK_STS_IOERR;
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
@ -1062,7 +1069,7 @@ again:
|
||||
blk_mq_start_request(req);
|
||||
if (unlikely(nsock->pending && nsock->pending != req)) {
|
||||
nbd_requeue_cmd(cmd);
|
||||
ret = 0;
|
||||
ret = BLK_STS_OK;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
@ -1081,19 +1088,19 @@ again:
|
||||
"Request send failed, requeueing\n");
|
||||
nbd_mark_nsock_dead(nbd, nsock, 1);
|
||||
nbd_requeue_cmd(cmd);
|
||||
ret = 0;
|
||||
ret = BLK_STS_OK;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&nsock->tx_lock);
|
||||
nbd_config_put(nbd);
|
||||
return ret;
|
||||
return ret < 0 ? BLK_STS_IOERR : (__force blk_status_t)ret;
|
||||
}
|
||||
|
||||
static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
const struct blk_mq_queue_data *bd)
|
||||
{
|
||||
struct nbd_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
|
||||
int ret;
|
||||
blk_status_t ret;
|
||||
|
||||
/*
|
||||
* Since we look at the bio's to send the request over the network we
|
||||
@ -1113,10 +1120,6 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
* appropriate.
|
||||
*/
|
||||
ret = nbd_handle_cmd(cmd, hctx->queue_num);
|
||||
if (ret < 0)
|
||||
ret = BLK_STS_IOERR;
|
||||
else if (!ret)
|
||||
ret = BLK_STS_OK;
|
||||
mutex_unlock(&cmd->lock);
|
||||
|
||||
return ret;
|
||||
|
@ -413,13 +413,25 @@ static int nullb_update_nr_hw_queues(struct nullb_device *dev,
|
||||
static int nullb_apply_submit_queues(struct nullb_device *dev,
|
||||
unsigned int submit_queues)
|
||||
{
|
||||
return nullb_update_nr_hw_queues(dev, submit_queues, dev->poll_queues);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&lock);
|
||||
ret = nullb_update_nr_hw_queues(dev, submit_queues, dev->poll_queues);
|
||||
mutex_unlock(&lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nullb_apply_poll_queues(struct nullb_device *dev,
|
||||
unsigned int poll_queues)
|
||||
{
|
||||
return nullb_update_nr_hw_queues(dev, dev->submit_queues, poll_queues);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&lock);
|
||||
ret = nullb_update_nr_hw_queues(dev, dev->submit_queues, poll_queues);
|
||||
mutex_unlock(&lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NULLB_DEVICE_ATTR(size, ulong, NULL);
|
||||
@ -468,28 +480,31 @@ static ssize_t nullb_device_power_store(struct config_item *item,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = count;
|
||||
mutex_lock(&lock);
|
||||
if (!dev->power && newp) {
|
||||
if (test_and_set_bit(NULLB_DEV_FL_UP, &dev->flags))
|
||||
return count;
|
||||
goto out;
|
||||
|
||||
ret = null_add_dev(dev);
|
||||
if (ret) {
|
||||
clear_bit(NULLB_DEV_FL_UP, &dev->flags);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
set_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags);
|
||||
dev->power = newp;
|
||||
} else if (dev->power && !newp) {
|
||||
if (test_and_clear_bit(NULLB_DEV_FL_UP, &dev->flags)) {
|
||||
mutex_lock(&lock);
|
||||
dev->power = newp;
|
||||
null_del_dev(dev->nullb);
|
||||
mutex_unlock(&lock);
|
||||
}
|
||||
clear_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags);
|
||||
}
|
||||
|
||||
return count;
|
||||
out:
|
||||
mutex_unlock(&lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CONFIGFS_ATTR(nullb_device_, power);
|
||||
@ -1218,7 +1233,7 @@ static int null_transfer(struct nullb *nullb, struct page *page,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int null_handle_rq(struct nullb_cmd *cmd)
|
||||
static blk_status_t null_handle_rq(struct nullb_cmd *cmd)
|
||||
{
|
||||
struct request *rq = blk_mq_rq_from_pdu(cmd);
|
||||
struct nullb *nullb = cmd->nq->dev->nullb;
|
||||
@ -1932,15 +1947,12 @@ static int null_add_dev(struct nullb_device *dev)
|
||||
nullb->q->queuedata = nullb;
|
||||
blk_queue_flag_set(QUEUE_FLAG_NONROT, nullb->q);
|
||||
|
||||
mutex_lock(&lock);
|
||||
rv = ida_alloc(&nullb_indexes, GFP_KERNEL);
|
||||
if (rv < 0) {
|
||||
mutex_unlock(&lock);
|
||||
if (rv < 0)
|
||||
goto out_cleanup_disk;
|
||||
}
|
||||
|
||||
nullb->index = rv;
|
||||
dev->index = rv;
|
||||
mutex_unlock(&lock);
|
||||
|
||||
if (config_item_name(&dev->group.cg_item)) {
|
||||
/* Use configfs dir name as the device name */
|
||||
@ -1969,9 +1981,7 @@ static int null_add_dev(struct nullb_device *dev)
|
||||
if (rv)
|
||||
goto out_ida_free;
|
||||
|
||||
mutex_lock(&lock);
|
||||
list_add_tail(&nullb->list, &nullb_list);
|
||||
mutex_unlock(&lock);
|
||||
|
||||
pr_info("disk %s created\n", nullb->disk_name);
|
||||
|
||||
@ -2020,7 +2030,9 @@ static int null_create_dev(void)
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&lock);
|
||||
ret = null_add_dev(dev);
|
||||
mutex_unlock(&lock);
|
||||
if (ret) {
|
||||
null_free_dev(dev);
|
||||
return ret;
|
||||
|
@ -36,7 +36,12 @@ TRACE_EVENT(nullb_zone_op,
|
||||
TP_ARGS(cmd, zone_no, zone_cond),
|
||||
TP_STRUCT__entry(
|
||||
__array(char, disk, DISK_NAME_LEN)
|
||||
__field(enum req_op, op)
|
||||
/*
|
||||
* __field() uses is_signed_type(). is_signed_type() does not
|
||||
* support bitwise types. Use __field_struct() instead because
|
||||
* it does not use is_signed_type().
|
||||
*/
|
||||
__field_struct(enum req_op, op)
|
||||
__field(unsigned int, zone_no)
|
||||
__field(unsigned int, zone_cond)
|
||||
),
|
||||
|
@ -2178,6 +2178,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
|
||||
.virt_boundary_mask = p->virt_boundary_mask,
|
||||
.max_segments = USHRT_MAX,
|
||||
.max_segment_size = UINT_MAX,
|
||||
.dma_alignment = 3,
|
||||
};
|
||||
struct gendisk *disk;
|
||||
int ret = -EINVAL;
|
||||
|
@ -2358,7 +2358,7 @@ static int cdrom_ioctl_timed_media_change(struct cdrom_device_info *cdi,
|
||||
return -EFAULT;
|
||||
|
||||
tmp_info.media_flags = 0;
|
||||
if (tmp_info.last_media_change - cdi->last_media_change_ms < 0)
|
||||
if (cdi->last_media_change_ms > tmp_info.last_media_change)
|
||||
tmp_info.media_flags |= MEDIA_CHANGED_FLAG;
|
||||
|
||||
tmp_info.last_media_change = cdi->last_media_change_ms;
|
||||
|
@ -9,8 +9,10 @@
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
@ -315,9 +317,8 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ff_dev_size = sizeof(struct ff_device) +
|
||||
max_effects * sizeof(struct file *);
|
||||
if (ff_dev_size < max_effects) /* overflow */
|
||||
ff_dev_size = struct_size(ff, effect_owners, max_effects);
|
||||
if (ff_dev_size == SIZE_MAX) /* overflow */
|
||||
return -EINVAL;
|
||||
|
||||
ff = kzalloc(ff_dev_size, GFP_KERNEL);
|
||||
|
@ -1378,19 +1378,19 @@ static int input_print_modalias_bits(char *buf, int size,
|
||||
char name, const unsigned long *bm,
|
||||
unsigned int min_bit, unsigned int max_bit)
|
||||
{
|
||||
int len = 0, i;
|
||||
int bit = min_bit;
|
||||
int len = 0;
|
||||
|
||||
len += snprintf(buf, max(size, 0), "%c", name);
|
||||
for (i = min_bit; i < max_bit; i++)
|
||||
if (bm[BIT_WORD(i)] & BIT_MASK(i))
|
||||
len += snprintf(buf + len, max(size - len, 0), "%X,", i);
|
||||
for_each_set_bit_from(bit, bm, max_bit)
|
||||
len += snprintf(buf + len, max(size - len, 0), "%X,", bit);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int input_print_modalias(char *buf, int size, const struct input_dev *id,
|
||||
int add_cr)
|
||||
static int input_print_modalias_parts(char *buf, int size, int full_len,
|
||||
const struct input_dev *id)
|
||||
{
|
||||
int len;
|
||||
int len, klen, remainder, space;
|
||||
|
||||
len = snprintf(buf, max(size, 0),
|
||||
"input:b%04Xv%04Xp%04Xe%04X-",
|
||||
@ -1399,8 +1399,48 @@ static int input_print_modalias(char *buf, int size, const struct input_dev *id,
|
||||
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'e', id->evbit, 0, EV_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
|
||||
/*
|
||||
* Calculate the remaining space in the buffer making sure we
|
||||
* have place for the terminating 0.
|
||||
*/
|
||||
space = max(size - (len + 1), 0);
|
||||
|
||||
klen = input_print_modalias_bits(buf + len, size - len,
|
||||
'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
|
||||
len += klen;
|
||||
|
||||
/*
|
||||
* If we have more data than we can fit in the buffer, check
|
||||
* if we can trim key data to fit in the rest. We will indicate
|
||||
* that key data is incomplete by adding "+" sign at the end, like
|
||||
* this: * "k1,2,3,45,+,".
|
||||
*
|
||||
* Note that we shortest key info (if present) is "k+," so we
|
||||
* can only try to trim if key data is longer than that.
|
||||
*/
|
||||
if (full_len && size < full_len + 1 && klen > 3) {
|
||||
remainder = full_len - len;
|
||||
/*
|
||||
* We can only trim if we have space for the remainder
|
||||
* and also for at least "k+," which is 3 more characters.
|
||||
*/
|
||||
if (remainder <= space - 3) {
|
||||
/*
|
||||
* We are guaranteed to have 'k' in the buffer, so
|
||||
* we need at least 3 additional bytes for storing
|
||||
* "+," in addition to the remainder.
|
||||
*/
|
||||
for (int i = size - 1 - remainder - 3; i >= 0; i--) {
|
||||
if (buf[i] == 'k' || buf[i] == ',') {
|
||||
strcpy(buf + i + 1, "+,");
|
||||
len = i + 3; /* Not counting '\0' */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'r', id->relbit, 0, REL_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
@ -1416,12 +1456,25 @@ static int input_print_modalias(char *buf, int size, const struct input_dev *id,
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'w', id->swbit, 0, SW_MAX);
|
||||
|
||||
if (add_cr)
|
||||
len += snprintf(buf + len, max(size - len, 0), "\n");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int input_print_modalias(char *buf, int size, const struct input_dev *id)
|
||||
{
|
||||
int full_len;
|
||||
|
||||
/*
|
||||
* Printing is done in 2 passes: first one figures out total length
|
||||
* needed for the modalias string, second one will try to trim key
|
||||
* data in case when buffer is too small for the entire modalias.
|
||||
* If the buffer is too small regardless, it will fill as much as it
|
||||
* can (without trimming key data) into the buffer and leave it to
|
||||
* the caller to figure out what to do with the result.
|
||||
*/
|
||||
full_len = input_print_modalias_parts(NULL, 0, 0, id);
|
||||
return input_print_modalias_parts(buf, size, full_len, id);
|
||||
}
|
||||
|
||||
static ssize_t input_dev_show_modalias(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
@ -1429,7 +1482,9 @@ static ssize_t input_dev_show_modalias(struct device *dev,
|
||||
struct input_dev *id = to_input_dev(dev);
|
||||
ssize_t len;
|
||||
|
||||
len = input_print_modalias(buf, PAGE_SIZE, id, 1);
|
||||
len = input_print_modalias(buf, PAGE_SIZE, id);
|
||||
if (len < PAGE_SIZE - 2)
|
||||
len += snprintf(buf + len, PAGE_SIZE - len, "\n");
|
||||
|
||||
return min_t(int, len, PAGE_SIZE);
|
||||
}
|
||||
@ -1641,6 +1696,23 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a pretty gross hack. When building uevent data the driver core
|
||||
* may try adding more environment variables to kobj_uevent_env without
|
||||
* telling us, so we have no idea how much of the buffer we can use to
|
||||
* avoid overflows/-ENOMEM elsewhere. To work around this let's artificially
|
||||
* reduce amount of memory we will use for the modalias environment variable.
|
||||
*
|
||||
* The potential additions are:
|
||||
*
|
||||
* SEQNUM=18446744073709551615 - (%llu - 28 bytes)
|
||||
* HOME=/ (6 bytes)
|
||||
* PATH=/sbin:/bin:/usr/sbin:/usr/bin (34 bytes)
|
||||
*
|
||||
* 68 bytes total. Allow extra buffer - 96 bytes
|
||||
*/
|
||||
#define UEVENT_ENV_EXTRA_LEN 96
|
||||
|
||||
static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
|
||||
const struct input_dev *dev)
|
||||
{
|
||||
@ -1650,9 +1722,11 @@ static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
|
||||
return -ENOMEM;
|
||||
|
||||
len = input_print_modalias(&env->buf[env->buflen - 1],
|
||||
sizeof(env->buf) - env->buflen,
|
||||
dev, 0);
|
||||
if (len >= (sizeof(env->buf) - env->buflen))
|
||||
(int)sizeof(env->buf) - env->buflen -
|
||||
UEVENT_ENV_EXTRA_LEN,
|
||||
dev);
|
||||
if (len >= ((int)sizeof(env->buf) - env->buflen -
|
||||
UEVENT_ENV_EXTRA_LEN))
|
||||
return -ENOMEM;
|
||||
|
||||
env->buflen += len;
|
||||
|
@ -56,7 +56,7 @@
|
||||
#define SEESAW_GAMEPAD_POLL_MIN 8
|
||||
#define SEESAW_GAMEPAD_POLL_MAX 32
|
||||
|
||||
static const unsigned long SEESAW_BUTTON_MASK =
|
||||
static const u32 SEESAW_BUTTON_MASK =
|
||||
BIT(SEESAW_BUTTON_A) | BIT(SEESAW_BUTTON_B) | BIT(SEESAW_BUTTON_X) |
|
||||
BIT(SEESAW_BUTTON_Y) | BIT(SEESAW_BUTTON_START) |
|
||||
BIT(SEESAW_BUTTON_SELECT);
|
||||
@ -64,6 +64,7 @@ static const unsigned long SEESAW_BUTTON_MASK =
|
||||
struct seesaw_gamepad {
|
||||
struct input_dev *input_dev;
|
||||
struct i2c_client *i2c_client;
|
||||
u32 button_state;
|
||||
};
|
||||
|
||||
struct seesaw_data {
|
||||
@ -178,10 +179,20 @@ static int seesaw_read_data(struct i2c_client *client, struct seesaw_data *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int seesaw_open(struct input_dev *input)
|
||||
{
|
||||
struct seesaw_gamepad *private = input_get_drvdata(input);
|
||||
|
||||
private->button_state = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void seesaw_poll(struct input_dev *input)
|
||||
{
|
||||
struct seesaw_gamepad *private = input_get_drvdata(input);
|
||||
struct seesaw_data data;
|
||||
unsigned long changed;
|
||||
int err, i;
|
||||
|
||||
err = seesaw_read_data(private->i2c_client, &data);
|
||||
@ -194,8 +205,11 @@ static void seesaw_poll(struct input_dev *input)
|
||||
input_report_abs(input, ABS_X, data.x);
|
||||
input_report_abs(input, ABS_Y, data.y);
|
||||
|
||||
for_each_set_bit(i, &SEESAW_BUTTON_MASK,
|
||||
BITS_PER_TYPE(SEESAW_BUTTON_MASK)) {
|
||||
data.button_state &= SEESAW_BUTTON_MASK;
|
||||
changed = private->button_state ^ data.button_state;
|
||||
private->button_state = data.button_state;
|
||||
|
||||
for_each_set_bit(i, &changed, fls(SEESAW_BUTTON_MASK)) {
|
||||
if (!sparse_keymap_report_event(input, i,
|
||||
data.button_state & BIT(i),
|
||||
false))
|
||||
@ -253,6 +267,7 @@ static int seesaw_probe(struct i2c_client *client)
|
||||
seesaw->input_dev->id.bustype = BUS_I2C;
|
||||
seesaw->input_dev->name = "Adafruit Seesaw Gamepad";
|
||||
seesaw->input_dev->phys = "i2c/" SEESAW_DEVICE_NAME;
|
||||
seesaw->input_dev->open = seesaw_open;
|
||||
input_set_drvdata(seesaw->input_dev, seesaw);
|
||||
input_set_abs_params(seesaw->input_dev, ABS_X,
|
||||
0, SEESAW_JOYSTICK_MAX_AXIS,
|
||||
|
@ -337,7 +337,7 @@ static void as5011_remove(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id as5011_id[] = {
|
||||
{ MODULE_DEVICE_ALIAS, 0 },
|
||||
{ MODULE_DEVICE_ALIAS },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, as5011_id);
|
||||
|
@ -126,8 +126,8 @@ MODULE_DEVICE_TABLE(of, of_qwiic_match);
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static const struct i2c_device_id qwiic_id_table[] = {
|
||||
{ KBUILD_MODNAME, 0 },
|
||||
{ },
|
||||
{ KBUILD_MODNAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, qwiic_id_table);
|
||||
|
||||
|
@ -342,6 +342,7 @@ static const struct xpad_device {
|
||||
{ 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE },
|
||||
{ 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE },
|
||||
{ 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 },
|
||||
{ 0x2345, 0xe00b, "Machenike G5 Pro Controller", 0, XTYPE_XBOX360 },
|
||||
{ 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
||||
{ 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
|
||||
{ 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
|
||||
@ -512,6 +513,7 @@ static const struct usb_device_id xpad_table[] = {
|
||||
XPAD_XBOX360_VENDOR(0x1bad), /* Harmonix Rock Band guitar and drums */
|
||||
XPAD_XBOX360_VENDOR(0x20d6), /* PowerA controllers */
|
||||
XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA controllers */
|
||||
XPAD_XBOX360_VENDOR(0x2345), /* Machenike Controllers */
|
||||
XPAD_XBOX360_VENDOR(0x24c6), /* PowerA controllers */
|
||||
XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA controllers */
|
||||
XPAD_XBOX360_VENDOR(0x2563), /* OneXPlayer Gamepad */
|
||||
|
@ -832,8 +832,8 @@ static int adp5588_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(adp5588_dev_pm_ops, adp5588_suspend, adp5588_resume);
|
||||
|
||||
static const struct i2c_device_id adp5588_id[] = {
|
||||
{ "adp5588-keys", 0 },
|
||||
{ "adp5587-keys", 0 },
|
||||
{ "adp5588-keys" },
|
||||
{ "adp5587-keys" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, adp5588_id);
|
||||
|
@ -35,7 +35,6 @@
|
||||
* @rows: Number of rows in the keypad
|
||||
* @cols: Number of columns in the keypad
|
||||
* @row_shift: log2 or number of rows, rounded up
|
||||
* @keymap_data: Matrix keymap data used to convert to keyscan values
|
||||
* @ghost_filter: true to enable the matrix key-ghosting filter
|
||||
* @valid_keys: bitmap of existing keys for each matrix column
|
||||
* @old_kb_state: bitmap of keys pressed last scan
|
||||
@ -50,7 +49,6 @@ struct cros_ec_keyb {
|
||||
unsigned int rows;
|
||||
unsigned int cols;
|
||||
int row_shift;
|
||||
const struct matrix_keymap_data *keymap_data;
|
||||
bool ghost_filter;
|
||||
uint8_t *valid_keys;
|
||||
uint8_t *old_kb_state;
|
||||
|
@ -209,7 +209,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(cypress_sf_pm_ops,
|
||||
cypress_sf_suspend, cypress_sf_resume);
|
||||
|
||||
static struct i2c_device_id cypress_sf_id_table[] = {
|
||||
{ CYPRESS_SF_DEV_NAME, 0 },
|
||||
{ CYPRESS_SF_DEV_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cypress_sf_id_table);
|
||||
|
@ -127,7 +127,7 @@ static int dir685_tk_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id dir685_tk_id[] = {
|
||||
{ "dir685tk", 0 },
|
||||
{ "dir685tk" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, dir685_tk_id);
|
||||
|
@ -792,7 +792,7 @@ static int lm8323_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(lm8323_pm_ops, lm8323_suspend, lm8323_resume);
|
||||
|
||||
static const struct i2c_device_id lm8323_id[] = {
|
||||
{ "lm8323", 0 },
|
||||
{ "lm8323" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -194,7 +194,7 @@ static int lm8333_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id lm8333_id[] = {
|
||||
{ "lm8333", 0 },
|
||||
{ "lm8333" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, lm8333_id);
|
||||
|
@ -57,14 +57,13 @@ struct lpc32xx_kscan_drv {
|
||||
struct input_dev *input;
|
||||
struct clk *clk;
|
||||
void __iomem *kscan_base;
|
||||
unsigned int irq;
|
||||
|
||||
u32 matrix_sz; /* Size of matrix in XxY, ie. 3 = 3x3 */
|
||||
u32 deb_clks; /* Debounce clocks (based on 32KHz clock) */
|
||||
u32 scan_delay; /* Scan delay (based on 32KHz clock) */
|
||||
|
||||
unsigned short *keymap; /* Pointer to key map for the scan matrix */
|
||||
unsigned int row_shift;
|
||||
unsigned short *keymap; /* Pointer to key map for the scan matrix */
|
||||
|
||||
u8 lastkeystates[8];
|
||||
};
|
||||
|
@ -37,7 +37,6 @@ struct matrix_keypad {
|
||||
spinlock_t lock;
|
||||
bool scan_pending;
|
||||
bool stopped;
|
||||
bool gpio_all_disabled;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -270,7 +270,7 @@ static int max7359_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(max7359_pm, max7359_suspend, max7359_resume);
|
||||
|
||||
static const struct i2c_device_id max7359_ids[] = {
|
||||
{ "max7359", 0 },
|
||||
{ "max7359" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max7359_ids);
|
||||
|
@ -369,7 +369,7 @@ static int mpr_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume);
|
||||
|
||||
static const struct i2c_device_id mpr121_id[] = {
|
||||
{ "mpr121_touchkey", 0 },
|
||||
{ "mpr121_touchkey" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mpr121_id);
|
||||
|
@ -234,8 +234,8 @@ static int qt1070_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(qt1070_pm_ops, qt1070_suspend, qt1070_resume);
|
||||
|
||||
static const struct i2c_device_id qt1070_id[] = {
|
||||
{ "qt1070", 0 },
|
||||
{ },
|
||||
{ "qt1070" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, qt1070_id);
|
||||
|
||||
|
@ -393,7 +393,7 @@ static int qt2160_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id qt2160_idtable[] = {
|
||||
{ "qt2160", 0, },
|
||||
{ "qt2160" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -413,7 +413,6 @@ static void stmpe_keypad_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver stmpe_keypad_driver = {
|
||||
.driver.name = "stmpe-keypad",
|
||||
.driver.owner = THIS_MODULE,
|
||||
.probe = stmpe_keypad_probe,
|
||||
.remove_new = stmpe_keypad_remove,
|
||||
};
|
||||
|
@ -32,11 +32,6 @@ static const struct i2c_device_id tca6416_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tca6416_id);
|
||||
|
||||
struct tca6416_drv_data {
|
||||
struct input_dev *input;
|
||||
struct tca6416_button data[];
|
||||
};
|
||||
|
||||
struct tca6416_keypad_chip {
|
||||
uint16_t reg_output;
|
||||
uint16_t reg_direction;
|
||||
@ -45,7 +40,6 @@ struct tca6416_keypad_chip {
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input;
|
||||
int io_size;
|
||||
int irqnum;
|
||||
u16 pinmask;
|
||||
bool use_polling;
|
||||
struct tca6416_button buttons[];
|
||||
|
@ -326,8 +326,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops,
|
||||
tm2_touchkey_suspend, tm2_touchkey_resume);
|
||||
|
||||
static const struct i2c_device_id tm2_touchkey_id_table[] = {
|
||||
{ TM2_TOUCHKEY_DEV_NAME, 0 },
|
||||
{ },
|
||||
{ TM2_TOUCHKEY_DEV_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tm2_touchkey_id_table);
|
||||
|
||||
|
@ -72,11 +72,11 @@ static int ad714x_i2c_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ad714x_id[] = {
|
||||
{ "ad7142_captouch", 0 },
|
||||
{ "ad7143_captouch", 0 },
|
||||
{ "ad7147_captouch", 0 },
|
||||
{ "ad7147a_captouch", 0 },
|
||||
{ "ad7148_captouch", 0 },
|
||||
{ "ad7142_captouch" },
|
||||
{ "ad7143_captouch" },
|
||||
{ "ad7147_captouch" },
|
||||
{ "ad7147a_captouch" },
|
||||
{ "ad7148_captouch" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ad714x_id);
|
||||
|
@ -106,7 +106,7 @@ static void adxl34x_i2c_remove(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id adxl34x_id[] = {
|
||||
{ "adxl34x", 0 },
|
||||
{ "adxl34x" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -192,7 +192,7 @@ static void apanel_shutdown(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id apanel_id[] = {
|
||||
{ "fujitsu_apanel", 0 },
|
||||
{ "fujitsu_apanel" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, apanel_id);
|
||||
|
@ -257,7 +257,7 @@ static const struct of_device_id atmel_captouch_of_id[] = {
|
||||
MODULE_DEVICE_TABLE(of, atmel_captouch_of_id);
|
||||
|
||||
static const struct i2c_device_id atmel_captouch_id[] = {
|
||||
{ "atmel_captouch", 0 },
|
||||
{ "atmel_captouch" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, atmel_captouch_id);
|
||||
|
@ -536,9 +536,9 @@ static int __maybe_unused bma150_resume(struct device *dev)
|
||||
static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL);
|
||||
|
||||
static const struct i2c_device_id bma150_id[] = {
|
||||
{ "bma150", 0 },
|
||||
{ "smb380", 0 },
|
||||
{ "bma023", 0 },
|
||||
{ "bma150" },
|
||||
{ "smb380" },
|
||||
{ "bma023" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -90,8 +90,8 @@ static const struct dev_pm_ops cma3000_i2c_pm_ops = {
|
||||
};
|
||||
|
||||
static const struct i2c_device_id cma3000_i2c_id[] = {
|
||||
{ "cma3000_d01", 0 },
|
||||
{ },
|
||||
{ "cma3000_d01" },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, cma3000_i2c_id);
|
||||
|
@ -230,7 +230,6 @@ struct da7280_haptic {
|
||||
struct i2c_client *client;
|
||||
struct pwm_device *pwm_dev;
|
||||
|
||||
bool legacy;
|
||||
struct work_struct work;
|
||||
int val;
|
||||
u16 gain;
|
||||
|
@ -600,7 +600,7 @@ out:
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume);
|
||||
|
||||
static const struct i2c_device_id drv260x_id[] = {
|
||||
{ "drv2605l", 0 },
|
||||
{ "drv2605l" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, drv260x_id);
|
||||
|
@ -283,7 +283,7 @@ out:
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(drv2665_pm_ops, drv2665_suspend, drv2665_resume);
|
||||
|
||||
static const struct i2c_device_id drv2665_id[] = {
|
||||
{ "drv2665", 0 },
|
||||
{ "drv2665" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, drv2665_id);
|
||||
|
@ -460,7 +460,7 @@ out:
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(drv2667_pm_ops, drv2667_suspend, drv2667_resume);
|
||||
|
||||
static const struct i2c_device_id drv2667_id[] = {
|
||||
{ "drv2667", 0 },
|
||||
{ "drv2667" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, drv2667_id);
|
||||
|
@ -42,8 +42,8 @@ struct ims_pcu_backlight {
|
||||
#define IMS_PCU_PART_NUMBER_LEN 15
|
||||
#define IMS_PCU_SERIAL_NUMBER_LEN 8
|
||||
#define IMS_PCU_DOM_LEN 8
|
||||
#define IMS_PCU_FW_VERSION_LEN (9 + 1)
|
||||
#define IMS_PCU_BL_VERSION_LEN (9 + 1)
|
||||
#define IMS_PCU_FW_VERSION_LEN 16
|
||||
#define IMS_PCU_BL_VERSION_LEN 16
|
||||
#define IMS_PCU_BL_RESET_REASON_LEN (2 + 1)
|
||||
|
||||
#define IMS_PCU_PCU_B_DEVICE_ID 5
|
||||
|
@ -531,8 +531,8 @@ static int kxtj9_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume);
|
||||
|
||||
static const struct i2c_device_id kxtj9_id[] = {
|
||||
{ NAME, 0 },
|
||||
{ },
|
||||
{ NAME },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, kxtj9_id);
|
||||
|
@ -186,8 +186,8 @@ static int mma8450_probe(struct i2c_client *c)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id mma8450_id[] = {
|
||||
{ MMA8450_DRV_NAME, 0 },
|
||||
{ },
|
||||
{ MMA8450_DRV_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mma8450_id);
|
||||
|
||||
|
@ -189,7 +189,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(pcf8574_kp_pm_ops,
|
||||
pcf8574_kp_suspend, pcf8574_kp_resume);
|
||||
|
||||
static const struct i2c_device_id pcf8574_kp_id[] = {
|
||||
{ DRV_NAME, 0 },
|
||||
{ DRV_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, pcf8574_kp_id);
|
||||
|
@ -11,36 +11,57 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define VIB_MAX_LEVEL_mV (3100)
|
||||
#define VIB_MIN_LEVEL_mV (1200)
|
||||
#define VIB_MAX_LEVELS (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
|
||||
#define VIB_MAX_LEVEL_mV(vib) (vib->drv2_addr ? 3544 : 3100)
|
||||
#define VIB_MIN_LEVEL_mV(vib) (vib->drv2_addr ? 1504 : 1200)
|
||||
#define VIB_PER_STEP_mV(vib) (vib->drv2_addr ? 8 : 100)
|
||||
#define VIB_MAX_LEVELS(vib) \
|
||||
(VIB_MAX_LEVEL_mV(vib) - VIB_MIN_LEVEL_mV(vib) + VIB_PER_STEP_mV(vib))
|
||||
|
||||
#define MAX_FF_SPEED 0xff
|
||||
|
||||
struct pm8xxx_regs {
|
||||
unsigned int enable_addr;
|
||||
unsigned int enable_offset;
|
||||
unsigned int enable_mask;
|
||||
|
||||
unsigned int drv_addr;
|
||||
unsigned int drv_offset;
|
||||
unsigned int drv_mask;
|
||||
unsigned int drv_shift;
|
||||
unsigned int drv2_offset;
|
||||
unsigned int drv2_mask;
|
||||
unsigned int drv2_shift;
|
||||
unsigned int drv_en_manual_mask;
|
||||
bool drv_in_step;
|
||||
};
|
||||
|
||||
static const struct pm8xxx_regs pm8058_regs = {
|
||||
.drv_addr = 0x4A,
|
||||
.drv_mask = 0xf8,
|
||||
.drv_offset = 0,
|
||||
.drv_mask = GENMASK(7, 3),
|
||||
.drv_shift = 3,
|
||||
.drv_en_manual_mask = 0xfc,
|
||||
.drv_in_step = true,
|
||||
};
|
||||
|
||||
static struct pm8xxx_regs pm8916_regs = {
|
||||
.enable_addr = 0xc046,
|
||||
.enable_offset = 0x46,
|
||||
.enable_mask = BIT(7),
|
||||
.drv_addr = 0xc041,
|
||||
.drv_mask = 0x1F,
|
||||
.drv_offset = 0x41,
|
||||
.drv_mask = GENMASK(4, 0),
|
||||
.drv_shift = 0,
|
||||
.drv_en_manual_mask = 0,
|
||||
.drv_in_step = true,
|
||||
};
|
||||
|
||||
static struct pm8xxx_regs pmi632_regs = {
|
||||
.enable_offset = 0x46,
|
||||
.enable_mask = BIT(7),
|
||||
.drv_offset = 0x40,
|
||||
.drv_mask = GENMASK(7, 0),
|
||||
.drv_shift = 0,
|
||||
.drv2_offset = 0x41,
|
||||
.drv2_mask = GENMASK(3, 0),
|
||||
.drv2_shift = 8,
|
||||
.drv_en_manual_mask = 0,
|
||||
.drv_in_step = false,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -49,6 +70,9 @@ static struct pm8xxx_regs pm8916_regs = {
|
||||
* @work: work structure to set the vibration parameters
|
||||
* @regmap: regmap for register read/write
|
||||
* @regs: registers' info
|
||||
* @enable_addr: vibrator enable register
|
||||
* @drv_addr: vibrator drive strength register
|
||||
* @drv2_addr: vibrator drive strength upper byte register
|
||||
* @speed: speed of vibration set from userland
|
||||
* @active: state of vibrator
|
||||
* @level: level of vibration to set in the chip
|
||||
@ -59,6 +83,9 @@ struct pm8xxx_vib {
|
||||
struct work_struct work;
|
||||
struct regmap *regmap;
|
||||
const struct pm8xxx_regs *regs;
|
||||
unsigned int enable_addr;
|
||||
unsigned int drv_addr;
|
||||
unsigned int drv2_addr;
|
||||
int speed;
|
||||
int level;
|
||||
bool active;
|
||||
@ -76,20 +103,31 @@ static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
|
||||
unsigned int val = vib->reg_vib_drv;
|
||||
const struct pm8xxx_regs *regs = vib->regs;
|
||||
|
||||
if (regs->drv_in_step)
|
||||
vib->level /= VIB_PER_STEP_mV(vib);
|
||||
|
||||
if (on)
|
||||
val |= (vib->level << regs->drv_shift) & regs->drv_mask;
|
||||
else
|
||||
val &= ~regs->drv_mask;
|
||||
|
||||
rc = regmap_write(vib->regmap, regs->drv_addr, val);
|
||||
rc = regmap_write(vib->regmap, vib->drv_addr, val);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
vib->reg_vib_drv = val;
|
||||
|
||||
if (regs->drv2_mask) {
|
||||
val = vib->level << regs->drv2_shift;
|
||||
rc = regmap_write_bits(vib->regmap, vib->drv2_addr,
|
||||
regs->drv2_mask, on ? val : 0);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (regs->enable_mask)
|
||||
rc = regmap_update_bits(vib->regmap, regs->enable_addr,
|
||||
regs->enable_mask, on ? ~0 : 0);
|
||||
rc = regmap_update_bits(vib->regmap, vib->enable_addr,
|
||||
regs->enable_mask, on ? regs->enable_mask : 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -101,26 +139,24 @@ static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
|
||||
static void pm8xxx_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
|
||||
const struct pm8xxx_regs *regs = vib->regs;
|
||||
int rc;
|
||||
unsigned int val;
|
||||
int rc;
|
||||
|
||||
rc = regmap_read(vib->regmap, regs->drv_addr, &val);
|
||||
rc = regmap_read(vib->regmap, vib->drv_addr, &val);
|
||||
if (rc < 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* pmic vibrator supports voltage ranges from 1.2 to 3.1V, so
|
||||
* pmic vibrator supports voltage ranges from MIN_LEVEL to MAX_LEVEL, so
|
||||
* scale the level to fit into these ranges.
|
||||
*/
|
||||
if (vib->speed) {
|
||||
vib->active = true;
|
||||
vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) +
|
||||
VIB_MIN_LEVEL_mV;
|
||||
vib->level /= 100;
|
||||
vib->level = VIB_MIN_LEVEL_mV(vib);
|
||||
vib->level += mult_frac(VIB_MAX_LEVELS(vib), vib->speed, MAX_FF_SPEED);
|
||||
} else {
|
||||
vib->active = false;
|
||||
vib->level = VIB_MIN_LEVEL_mV / 100;
|
||||
vib->level = VIB_MIN_LEVEL_mV(vib);
|
||||
}
|
||||
|
||||
pm8xxx_vib_set(vib, vib->active);
|
||||
@ -168,7 +204,7 @@ static int pm8xxx_vib_probe(struct platform_device *pdev)
|
||||
struct pm8xxx_vib *vib;
|
||||
struct input_dev *input_dev;
|
||||
int error;
|
||||
unsigned int val;
|
||||
unsigned int val, reg_base = 0;
|
||||
const struct pm8xxx_regs *regs;
|
||||
|
||||
vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL);
|
||||
@ -186,15 +222,22 @@ static int pm8xxx_vib_probe(struct platform_device *pdev)
|
||||
INIT_WORK(&vib->work, pm8xxx_work_handler);
|
||||
vib->vib_input_dev = input_dev;
|
||||
|
||||
error = fwnode_property_read_u32(pdev->dev.fwnode, "reg", ®_base);
|
||||
if (error < 0)
|
||||
return dev_err_probe(&pdev->dev, error, "Failed to read reg address\n");
|
||||
|
||||
regs = of_device_get_match_data(&pdev->dev);
|
||||
vib->enable_addr = reg_base + regs->enable_offset;
|
||||
vib->drv_addr = reg_base + regs->drv_offset;
|
||||
vib->drv2_addr = reg_base + regs->drv2_offset;
|
||||
|
||||
/* operate in manual mode */
|
||||
error = regmap_read(vib->regmap, regs->drv_addr, &val);
|
||||
error = regmap_read(vib->regmap, vib->drv_addr, &val);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
val &= regs->drv_en_manual_mask;
|
||||
error = regmap_write(vib->regmap, regs->drv_addr, val);
|
||||
error = regmap_write(vib->regmap, vib->drv_addr, val);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
@ -241,6 +284,7 @@ static const struct of_device_id pm8xxx_vib_id_table[] = {
|
||||
{ .compatible = "qcom,pm8058-vib", .data = &pm8058_regs },
|
||||
{ .compatible = "qcom,pm8921-vib", .data = &pm8058_regs },
|
||||
{ .compatible = "qcom,pm8916-vib", .data = &pm8916_regs },
|
||||
{ .compatible = "qcom,pmi632-vib", .data = &pmi632_regs },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pm8xxx_vib_id_table);
|
||||
|
@ -1347,10 +1347,16 @@ static int cyapa_suspend(struct device *dev)
|
||||
u8 power_mode;
|
||||
int error;
|
||||
|
||||
error = mutex_lock_interruptible(&cyapa->state_sync_lock);
|
||||
error = mutex_lock_interruptible(&cyapa->input->mutex);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = mutex_lock_interruptible(&cyapa->state_sync_lock);
|
||||
if (error) {
|
||||
mutex_unlock(&cyapa->input->mutex);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Runtime PM is enable only when device is in operational mode and
|
||||
* users in use, so need check it before disable it to
|
||||
@ -1385,6 +1391,8 @@ static int cyapa_suspend(struct device *dev)
|
||||
cyapa->irq_wake = (enable_irq_wake(client->irq) == 0);
|
||||
|
||||
mutex_unlock(&cyapa->state_sync_lock);
|
||||
mutex_unlock(&cyapa->input->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1394,6 +1402,7 @@ static int cyapa_resume(struct device *dev)
|
||||
struct cyapa *cyapa = i2c_get_clientdata(client);
|
||||
int error;
|
||||
|
||||
mutex_lock(&cyapa->input->mutex);
|
||||
mutex_lock(&cyapa->state_sync_lock);
|
||||
|
||||
if (device_may_wakeup(dev) && cyapa->irq_wake) {
|
||||
@ -1412,6 +1421,7 @@ static int cyapa_resume(struct device *dev)
|
||||
enable_irq(client->irq);
|
||||
|
||||
mutex_unlock(&cyapa->state_sync_lock);
|
||||
mutex_unlock(&cyapa->input->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1449,8 +1459,8 @@ static const struct dev_pm_ops cyapa_pm_ops = {
|
||||
};
|
||||
|
||||
static const struct i2c_device_id cyapa_id_table[] = {
|
||||
{ "cyapa", 0 },
|
||||
{ },
|
||||
{ "cyapa" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cyapa_id_table);
|
||||
|
||||
|
@ -1392,8 +1392,8 @@ err:
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume);
|
||||
|
||||
static const struct i2c_device_id elan_id[] = {
|
||||
{ DRIVER_NAME, 0 },
|
||||
{ },
|
||||
{ DRIVER_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, elan_id);
|
||||
|
||||
|
@ -630,8 +630,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(synaptics_i2c_pm, synaptics_i2c_suspend,
|
||||
synaptics_i2c_resume);
|
||||
|
||||
static const struct i2c_device_id synaptics_i2c_id_table[] = {
|
||||
{ "synaptics_i2c", 0 },
|
||||
{ },
|
||||
{ "synaptics_i2c" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, synaptics_i2c_id_table);
|
||||
|
||||
|
@ -365,7 +365,7 @@ static const struct dev_pm_ops rmi_i2c_pm = {
|
||||
};
|
||||
|
||||
static const struct i2c_device_id rmi_id[] = {
|
||||
{ "rmi4_i2c", 0 },
|
||||
{ "rmi4_i2c" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rmi_id);
|
||||
|
@ -413,7 +413,7 @@ static const struct dev_pm_ops rmi_smb_pm = {
|
||||
};
|
||||
|
||||
static const struct i2c_device_id rmi_id[] = {
|
||||
{ "rmi4_smbus", 0 },
|
||||
{ "rmi4_smbus" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rmi_id);
|
||||
|
@ -200,9 +200,16 @@ static void ioc3kbd_remove(struct platform_device *pdev)
|
||||
serio_unregister_port(d->aux);
|
||||
}
|
||||
|
||||
static const struct platform_device_id ioc3kbd_id_table[] = {
|
||||
{ "ioc3-kbd", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, ioc3kbd_id_table);
|
||||
|
||||
static struct platform_driver ioc3kbd_driver = {
|
||||
.probe = ioc3kbd_probe,
|
||||
.remove_new = ioc3kbd_remove,
|
||||
.id_table = ioc3kbd_id_table,
|
||||
.driver = {
|
||||
.name = "ioc3-kbd",
|
||||
},
|
||||
|
@ -42,8 +42,8 @@ static int ad7879_i2c_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ad7879_id[] = {
|
||||
{ "ad7879", 0 },
|
||||
{ "ad7889", 0 },
|
||||
{ "ad7879" },
|
||||
{ "ad7889" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ad7879_id);
|
||||
|
@ -164,8 +164,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(ar1021_i2c_pm,
|
||||
ar1021_i2c_suspend, ar1021_i2c_resume);
|
||||
|
||||
static const struct i2c_device_id ar1021_i2c_id[] = {
|
||||
{ "ar1021", 0 },
|
||||
{ },
|
||||
{ "ar1021" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id);
|
||||
|
||||
|
@ -3443,11 +3443,11 @@ MODULE_DEVICE_TABLE(acpi, mxt_acpi_id);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id mxt_id[] = {
|
||||
{ "qt602240_ts", 0 },
|
||||
{ "atmel_mxt_ts", 0 },
|
||||
{ "atmel_mxt_tp", 0 },
|
||||
{ "maxtouch", 0 },
|
||||
{ "mXT224", 0 },
|
||||
{ "qt602240_ts" },
|
||||
{ "atmel_mxt_ts" },
|
||||
{ "atmel_mxt_tp" },
|
||||
{ "maxtouch" },
|
||||
{ "mXT224" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mxt_id);
|
||||
|
@ -617,7 +617,7 @@ static int auo_pixcir_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id auo_pixcir_idtable[] = {
|
||||
{ "auo_pixcir_ts", 0 },
|
||||
{ "auo_pixcir_ts" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, auo_pixcir_idtable);
|
||||
|
@ -597,7 +597,7 @@ static int bu21013_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(bu21013_dev_pm_ops, bu21013_suspend, bu21013_resume);
|
||||
|
||||
static const struct i2c_device_id bu21013_id[] = {
|
||||
{ DRIVER_TP, 0 },
|
||||
{ DRIVER_TP },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, bu21013_id);
|
||||
|
@ -441,7 +441,7 @@ static int bu21029_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(bu21029_pm_ops, bu21029_suspend, bu21029_resume);
|
||||
|
||||
static const struct i2c_device_id bu21029_ids[] = {
|
||||
{ DRIVER_NAME, 0 },
|
||||
{ DRIVER_NAME },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, bu21029_ids);
|
||||
|
@ -68,7 +68,6 @@ struct icn8505_touch_data {
|
||||
struct icn8505_data {
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input;
|
||||
struct gpio_desc *wake_gpio;
|
||||
struct touchscreen_properties prop;
|
||||
char firmware_name[32];
|
||||
};
|
||||
|
@ -322,7 +322,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(cy8ctma140_pm,
|
||||
cy8ctma140_suspend, cy8ctma140_resume);
|
||||
|
||||
static const struct i2c_device_id cy8ctma140_idtable[] = {
|
||||
{ CY8CTMA140_NAME, 0 },
|
||||
{ CY8CTMA140_NAME },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cy8ctma140_idtable);
|
||||
|
@ -50,7 +50,7 @@ static void cyttsp4_i2c_remove(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id cyttsp4_i2c_id[] = {
|
||||
{ CYTTSP4_I2C_NAME, 0 },
|
||||
{ CYTTSP4_I2C_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cyttsp4_i2c_id);
|
||||
|
@ -935,7 +935,7 @@ static const struct of_device_id cyttsp5_of_match[] = {
|
||||
MODULE_DEVICE_TABLE(of, cyttsp5_of_match);
|
||||
|
||||
static const struct i2c_device_id cyttsp5_i2c_id[] = {
|
||||
{ CYTTSP5_NAME, 0, },
|
||||
{ CYTTSP5_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cyttsp5_i2c_id);
|
||||
|
@ -48,7 +48,7 @@ static int cyttsp_i2c_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id cyttsp_i2c_id[] = {
|
||||
{ CY_I2C_NAME, 0 },
|
||||
{ CY_I2C_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cyttsp_i2c_id);
|
||||
|
@ -1462,6 +1462,10 @@ static const struct edt_i2c_chip_data edt_ft5x06_data = {
|
||||
.max_support_points = 5,
|
||||
};
|
||||
|
||||
static const struct edt_i2c_chip_data edt_ft5452_data = {
|
||||
.max_support_points = 5,
|
||||
};
|
||||
|
||||
static const struct edt_i2c_chip_data edt_ft5506_data = {
|
||||
.max_support_points = 10,
|
||||
};
|
||||
@ -1470,12 +1474,18 @@ static const struct edt_i2c_chip_data edt_ft6236_data = {
|
||||
.max_support_points = 2,
|
||||
};
|
||||
|
||||
static const struct edt_i2c_chip_data edt_ft8719_data = {
|
||||
.max_support_points = 10,
|
||||
};
|
||||
|
||||
static const struct i2c_device_id edt_ft5x06_ts_id[] = {
|
||||
{ .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },
|
||||
{ .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data },
|
||||
{ .name = "ev-ft5726", .driver_data = (long)&edt_ft5506_data },
|
||||
{ .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 = "ft8719", .driver_data = (long)&edt_ft8719_data },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
|
||||
@ -1486,8 +1496,10 @@ static const struct of_device_id edt_ft5x06_of_match[] = {
|
||||
{ .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data },
|
||||
{ .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data },
|
||||
{ .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data },
|
||||
{ .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,ft8719", .data = &edt_ft8719_data },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
|
||||
|
@ -273,7 +273,7 @@ static int eeti_ts_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume);
|
||||
|
||||
static const struct i2c_device_id eeti_ts_id[] = {
|
||||
{ "eeti_ts", 0 },
|
||||
{ "eeti_ts" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, eeti_ts_id);
|
||||
|
@ -218,7 +218,7 @@ static int egalax_ts_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id egalax_ts_id[] = {
|
||||
{ "egalax_ts", 0 },
|
||||
{ "egalax_ts" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, egalax_ts_id);
|
||||
|
@ -335,8 +335,8 @@ MODULE_DEVICE_TABLE(of, ektf2127_of_match);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id ektf2127_i2c_id[] = {
|
||||
{ "ektf2127", 0 },
|
||||
{ "ektf2132", 0 },
|
||||
{ "ektf2127" },
|
||||
{ "ektf2132" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ektf2127_i2c_id);
|
||||
|
@ -1510,7 +1510,7 @@ static int goodix_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(goodix_pm_ops, goodix_suspend, goodix_resume);
|
||||
|
||||
static const struct i2c_device_id goodix_ts_id[] = {
|
||||
{ "GDIX1001:00", 0 },
|
||||
{ "GDIX1001:00" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, goodix_ts_id);
|
||||
|
@ -47,7 +47,7 @@ static int goodix_berlin_i2c_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id goodix_berlin_i2c_id[] = {
|
||||
{ "gt9916", 0 },
|
||||
{ "gt9916" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -1095,7 +1095,7 @@ static int hideep_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id hideep_i2c_id[] = {
|
||||
{ HIDEEP_I2C_NAME, 0 },
|
||||
{ HIDEEP_I2C_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, hideep_i2c_id);
|
||||
|
@ -335,7 +335,7 @@ static int himax_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(himax_pm_ops, himax_suspend, himax_resume);
|
||||
|
||||
static const struct i2c_device_id himax_ts_id[] = {
|
||||
{ "hx83112b", 0 },
|
||||
{ "hx83112b" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, himax_ts_id);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user