mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 05:55:44 +02:00
Linux 5.10-rc5
-----BEGIN PGP SIGNATURE----- iQFSBAABCAA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAl+69egeHHRvcnZhbGRz QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiGTSYH/ifRBlaxy5UiHFc0 2zdR7pkjWrYfDTTT3sazIAhdlzzcfnkUqgFxOP45F4ZIqeTzunH3sUY+5UlT9IX7 liUgnLxQ/1R9Gx8kPGQfu+tLCey78xVFydGsqJoW9sPRw2R+apMdGGa/lOrk+OXz DXIN+dDnGFqwCCNJpK+rxQQhFf++IPpSI8z6Y23moOFhsDZrEziHuVFy2FGyRM6z prZ/us/tcobE8ptCk1RmOxLoJ1DR6UxpA2vLimTE+JD8siOsSWPbjE0KudnWCnd5 BLqIjrsPJbSxyuzzK3v9dnO5wMv7tMDuMIuYM/MQTXDttNwtsqt/aP6gdnUCym7N 5eHEj5g= =MuO1 -----END PGP SIGNATURE----- Merge 5.10-rc5 into android-mainline Linux 5.10-rc5 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ia5b23cceb3e0212c1c841f1297ecfab65cc9aaa6
This commit is contained in:
commit
5acba58e59
|
|
@ -109,30 +109,6 @@ Description:
|
|||
When counting down the counter start from preset value
|
||||
and fire event when reach 0.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_count_quadrature_mode_available
|
||||
KernelVersion: 4.12
|
||||
Contact: benjamin.gaignard@st.com
|
||||
Description:
|
||||
Reading returns the list possible quadrature modes.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_count0_quadrature_mode
|
||||
KernelVersion: 4.12
|
||||
Contact: benjamin.gaignard@st.com
|
||||
Description:
|
||||
Configure the device counter quadrature modes:
|
||||
|
||||
channel_A:
|
||||
Encoder A input servers as the count input and B as
|
||||
the UP/DOWN direction control input.
|
||||
|
||||
channel_B:
|
||||
Encoder B input serves as the count input and A as
|
||||
the UP/DOWN direction control input.
|
||||
|
||||
quadrature:
|
||||
Encoder A and B inputs are mixed to get direction
|
||||
and count with a scale of 0.25.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_count_enable_mode_available
|
||||
KernelVersion: 4.12
|
||||
Contact: benjamin.gaignard@st.com
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -2,7 +2,7 @@
|
|||
VERSION = 5
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc4
|
||||
EXTRAVERSION = -rc5
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
|||
|
|
@ -1472,6 +1472,9 @@ ENTRY(efi_enter_kernel)
|
|||
@ issued from HYP mode take us to the correct handler code. We
|
||||
@ will disable the MMU before jumping to the kernel proper.
|
||||
@
|
||||
ARM( bic r1, r1, #(1 << 30) ) @ clear HSCTLR.TE
|
||||
THUMB( orr r1, r1, #(1 << 30) ) @ set HSCTLR.TE
|
||||
mcr p15, 4, r1, c1, c0, 0
|
||||
adr r0, __hyp_reentry_vectors
|
||||
mcr p15, 4, r0, c12, c0, 0 @ set HYP vector base (HVBAR)
|
||||
isb
|
||||
|
|
|
|||
|
|
@ -18,4 +18,10 @@
|
|||
#endif
|
||||
|
||||
#endif /* CONFIG_SPARSEMEM */
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
int memory_add_physaddr_to_nid(u64 addr);
|
||||
#define memory_add_physaddr_to_nid memory_add_physaddr_to_nid
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_IA64_SPARSEMEM_H */
|
||||
|
|
|
|||
|
|
@ -46,5 +46,10 @@ u64 memory_hotplug_max(void);
|
|||
#define __HAVE_ARCH_RESERVED_KERNEL_PAGES
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
extern int create_section_mapping(unsigned long start, unsigned long end,
|
||||
int nid, pgprot_t prot);
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_MMZONE_H_ */
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@
|
|||
#endif /* CONFIG_SPARSEMEM */
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
extern int create_section_mapping(unsigned long start, unsigned long end,
|
||||
int nid, pgprot_t prot);
|
||||
extern int remove_section_mapping(unsigned long start, unsigned long end);
|
||||
extern int memory_add_physaddr_to_nid(u64 start);
|
||||
#define memory_add_physaddr_to_nid memory_add_physaddr_to_nid
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
extern int hot_add_scn_to_nid(unsigned long scn_addr);
|
||||
|
|
@ -26,6 +26,5 @@ static inline int hot_add_scn_to_nid(unsigned long scn_addr)
|
|||
}
|
||||
#endif /* CONFIG_NUMA */
|
||||
#endif /* CONFIG_MEMORY_HOTPLUG */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_POWERPC_SPARSEMEM_H */
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include <asm/rtas.h>
|
||||
#include <asm/kasan.h>
|
||||
#include <asm/svm.h>
|
||||
#include <asm/mmzone.h>
|
||||
|
||||
#include <mm/mmu_decl.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -107,14 +107,14 @@
|
|||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \
|
||||
static ssize_t __cstate_##_var##_show(struct kobject *kobj, \
|
||||
struct kobj_attribute *attr, \
|
||||
static ssize_t __cstate_##_var##_show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *page) \
|
||||
{ \
|
||||
BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
|
||||
return sprintf(page, _format "\n"); \
|
||||
} \
|
||||
static struct kobj_attribute format_attr_##_var = \
|
||||
static struct device_attribute format_attr_##_var = \
|
||||
__ATTR(_name, 0444, __cstate_##_var##_show, NULL)
|
||||
|
||||
static ssize_t cstate_get_attr_cpumask(struct device *dev,
|
||||
|
|
|
|||
|
|
@ -94,8 +94,8 @@ struct pci2phy_map *__find_pci2phy_map(int segment)
|
|||
return map;
|
||||
}
|
||||
|
||||
ssize_t uncore_event_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
ssize_t uncore_event_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct uncore_event_desc *event =
|
||||
container_of(attr, struct uncore_event_desc, attr);
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ struct intel_uncore_box {
|
|||
#define UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS 2
|
||||
|
||||
struct uncore_event_desc {
|
||||
struct kobj_attribute attr;
|
||||
struct device_attribute attr;
|
||||
const char *config;
|
||||
};
|
||||
|
||||
|
|
@ -179,8 +179,8 @@ struct pci2phy_map {
|
|||
struct pci2phy_map *__find_pci2phy_map(int segment);
|
||||
int uncore_pcibus_to_physid(struct pci_bus *bus);
|
||||
|
||||
ssize_t uncore_event_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf);
|
||||
ssize_t uncore_event_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
|
||||
static inline struct intel_uncore_pmu *dev_to_uncore_pmu(struct device *dev)
|
||||
{
|
||||
|
|
@ -201,14 +201,14 @@ extern int __uncore_max_dies;
|
|||
}
|
||||
|
||||
#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \
|
||||
static ssize_t __uncore_##_var##_show(struct kobject *kobj, \
|
||||
struct kobj_attribute *attr, \
|
||||
static ssize_t __uncore_##_var##_show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *page) \
|
||||
{ \
|
||||
BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
|
||||
return sprintf(page, _format "\n"); \
|
||||
} \
|
||||
static struct kobj_attribute format_attr_##_var = \
|
||||
static struct device_attribute format_attr_##_var = \
|
||||
__ATTR(_name, 0444, __uncore_##_var##_show, NULL)
|
||||
|
||||
static inline bool uncore_pmc_fixed(int idx)
|
||||
|
|
|
|||
|
|
@ -93,18 +93,6 @@ static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
|
|||
* any other bit is reserved
|
||||
*/
|
||||
#define RAPL_EVENT_MASK 0xFFULL
|
||||
|
||||
#define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format) \
|
||||
static ssize_t __rapl_##_var##_show(struct kobject *kobj, \
|
||||
struct kobj_attribute *attr, \
|
||||
char *page) \
|
||||
{ \
|
||||
BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
|
||||
return sprintf(page, _format "\n"); \
|
||||
} \
|
||||
static struct kobj_attribute format_attr_##_var = \
|
||||
__ATTR(_name, 0444, __rapl_##_var##_show, NULL)
|
||||
|
||||
#define RAPL_CNTR_WIDTH 32
|
||||
|
||||
#define RAPL_EVENT_ATTR_STR(_name, v, str) \
|
||||
|
|
@ -441,7 +429,7 @@ static struct attribute_group rapl_pmu_events_group = {
|
|||
.attrs = attrs_empty,
|
||||
};
|
||||
|
||||
DEFINE_RAPL_FORMAT_ATTR(event, event, "config:0-7");
|
||||
PMU_FORMAT_ATTR(event, "config:0-7");
|
||||
static struct attribute *rapl_formats_attr[] = {
|
||||
&format_attr_event.attr,
|
||||
NULL,
|
||||
|
|
|
|||
|
|
@ -28,4 +28,14 @@
|
|||
#endif
|
||||
|
||||
#endif /* CONFIG_SPARSEMEM */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef CONFIG_NUMA_KEEP_MEMINFO
|
||||
extern int phys_to_target_node(phys_addr_t start);
|
||||
#define phys_to_target_node phys_to_target_node
|
||||
extern int memory_add_physaddr_to_nid(u64 start);
|
||||
#define memory_add_physaddr_to_nid memory_add_physaddr_to_nid
|
||||
#endif
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_X86_SPARSEMEM_H */
|
||||
|
|
|
|||
|
|
@ -100,53 +100,6 @@ static int has_newer_microcode(void *mc, unsigned int csig, int cpf, int new_rev
|
|||
return find_matching_signature(mc, csig, cpf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given CPU signature and a microcode patch, this function finds if the
|
||||
* microcode patch has matching family and model with the CPU.
|
||||
*
|
||||
* %true - if there's a match
|
||||
* %false - otherwise
|
||||
*/
|
||||
static bool microcode_matches(struct microcode_header_intel *mc_header,
|
||||
unsigned long sig)
|
||||
{
|
||||
unsigned long total_size = get_totalsize(mc_header);
|
||||
unsigned long data_size = get_datasize(mc_header);
|
||||
struct extended_sigtable *ext_header;
|
||||
unsigned int fam_ucode, model_ucode;
|
||||
struct extended_signature *ext_sig;
|
||||
unsigned int fam, model;
|
||||
int ext_sigcount, i;
|
||||
|
||||
fam = x86_family(sig);
|
||||
model = x86_model(sig);
|
||||
|
||||
fam_ucode = x86_family(mc_header->sig);
|
||||
model_ucode = x86_model(mc_header->sig);
|
||||
|
||||
if (fam == fam_ucode && model == model_ucode)
|
||||
return true;
|
||||
|
||||
/* Look for ext. headers: */
|
||||
if (total_size <= data_size + MC_HEADER_SIZE)
|
||||
return false;
|
||||
|
||||
ext_header = (void *) mc_header + data_size + MC_HEADER_SIZE;
|
||||
ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
|
||||
ext_sigcount = ext_header->count;
|
||||
|
||||
for (i = 0; i < ext_sigcount; i++) {
|
||||
fam_ucode = x86_family(ext_sig->sig);
|
||||
model_ucode = x86_model(ext_sig->sig);
|
||||
|
||||
if (fam == fam_ucode && model == model_ucode)
|
||||
return true;
|
||||
|
||||
ext_sig++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct ucode_patch *memdup_patch(void *data, unsigned int size)
|
||||
{
|
||||
struct ucode_patch *p;
|
||||
|
|
@ -164,7 +117,7 @@ static struct ucode_patch *memdup_patch(void *data, unsigned int size)
|
|||
return p;
|
||||
}
|
||||
|
||||
static void save_microcode_patch(void *data, unsigned int size)
|
||||
static void save_microcode_patch(struct ucode_cpu_info *uci, void *data, unsigned int size)
|
||||
{
|
||||
struct microcode_header_intel *mc_hdr, *mc_saved_hdr;
|
||||
struct ucode_patch *iter, *tmp, *p = NULL;
|
||||
|
|
@ -210,6 +163,9 @@ static void save_microcode_patch(void *data, unsigned int size)
|
|||
if (!p)
|
||||
return;
|
||||
|
||||
if (!find_matching_signature(p->data, uci->cpu_sig.sig, uci->cpu_sig.pf))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Save for early loading. On 32-bit, that needs to be a physical
|
||||
* address as the APs are running from physical addresses, before
|
||||
|
|
@ -344,13 +300,14 @@ scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save)
|
|||
|
||||
size -= mc_size;
|
||||
|
||||
if (!microcode_matches(mc_header, uci->cpu_sig.sig)) {
|
||||
if (!find_matching_signature(data, uci->cpu_sig.sig,
|
||||
uci->cpu_sig.pf)) {
|
||||
data += mc_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
save_microcode_patch(data, mc_size);
|
||||
save_microcode_patch(uci, data, mc_size);
|
||||
goto next;
|
||||
}
|
||||
|
||||
|
|
@ -483,14 +440,14 @@ static void show_saved_mc(void)
|
|||
* Save this microcode patch. It will be loaded early when a CPU is
|
||||
* hot-added or resumes.
|
||||
*/
|
||||
static void save_mc_for_early(u8 *mc, unsigned int size)
|
||||
static void save_mc_for_early(struct ucode_cpu_info *uci, u8 *mc, unsigned int size)
|
||||
{
|
||||
/* Synchronization during CPU hotplug. */
|
||||
static DEFINE_MUTEX(x86_cpu_microcode_mutex);
|
||||
|
||||
mutex_lock(&x86_cpu_microcode_mutex);
|
||||
|
||||
save_microcode_patch(mc, size);
|
||||
save_microcode_patch(uci, mc, size);
|
||||
show_saved_mc();
|
||||
|
||||
mutex_unlock(&x86_cpu_microcode_mutex);
|
||||
|
|
@ -935,7 +892,7 @@ static enum ucode_state generic_load_microcode(int cpu, struct iov_iter *iter)
|
|||
* permanent memory. So it will be loaded early when a CPU is hot added
|
||||
* or resumes.
|
||||
*/
|
||||
save_mc_for_early(new_mc, new_mc_size);
|
||||
save_mc_for_early(uci, new_mc, new_mc_size);
|
||||
|
||||
pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
|
||||
cpu, new_rev, uci->cpu_sig.rev);
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ static int copy_code(struct pt_regs *regs, u8 *buf, unsigned long src,
|
|||
if (!user_mode(regs))
|
||||
return copy_from_kernel_nofault(buf, (u8 *)src, nbytes);
|
||||
|
||||
/* The user space code from other tasks cannot be accessed. */
|
||||
if (regs != task_pt_regs(current))
|
||||
return -EPERM;
|
||||
/*
|
||||
* Make sure userspace isn't trying to trick us into dumping kernel
|
||||
* memory by pointing the userspace instruction pointer at it.
|
||||
|
|
@ -85,6 +88,12 @@ static int copy_code(struct pt_regs *regs, u8 *buf, unsigned long src,
|
|||
if (__chk_range_not_ok(src, nbytes, TASK_SIZE_MAX))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Even if named copy_from_user_nmi() this can be invoked from
|
||||
* other contexts and will not try to resolve a pagefault, which is
|
||||
* the correct thing to do here as this code can be called from any
|
||||
* context.
|
||||
*/
|
||||
return copy_from_user_nmi(buf, (void __user *)src, nbytes);
|
||||
}
|
||||
|
||||
|
|
@ -115,13 +124,19 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl)
|
|||
u8 opcodes[OPCODE_BUFSIZE];
|
||||
unsigned long prologue = regs->ip - PROLOGUE_SIZE;
|
||||
|
||||
if (copy_code(regs, opcodes, prologue, sizeof(opcodes))) {
|
||||
printk("%sCode: Unable to access opcode bytes at RIP 0x%lx.\n",
|
||||
loglvl, prologue);
|
||||
} else {
|
||||
switch (copy_code(regs, opcodes, prologue, sizeof(opcodes))) {
|
||||
case 0:
|
||||
printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %"
|
||||
__stringify(EPILOGUE_SIZE) "ph\n", loglvl, opcodes,
|
||||
opcodes[PROLOGUE_SIZE], opcodes + PROLOGUE_SIZE + 1);
|
||||
break;
|
||||
case -EPERM:
|
||||
/* No access to the user space stack of other tasks. Ignore. */
|
||||
break;
|
||||
default:
|
||||
printk("%sCode: Unable to access opcode bytes at RIP 0x%lx.\n",
|
||||
loglvl, prologue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -938,6 +938,7 @@ int phys_to_target_node(phys_addr_t start)
|
|||
|
||||
return meminfo_to_nid(&numa_reserved_meminfo, start);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phys_to_target_node);
|
||||
|
||||
int memory_add_physaddr_to_nid(u64 start)
|
||||
{
|
||||
|
|
@ -947,4 +948,5 @@ int memory_add_physaddr_to_nid(u64 start)
|
|||
nid = numa_meminfo.blk[0].nid;
|
||||
return nid;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -78,28 +78,30 @@ int __init efi_alloc_page_tables(void)
|
|||
gfp_mask = GFP_KERNEL | __GFP_ZERO;
|
||||
efi_pgd = (pgd_t *)__get_free_pages(gfp_mask, PGD_ALLOCATION_ORDER);
|
||||
if (!efi_pgd)
|
||||
return -ENOMEM;
|
||||
goto fail;
|
||||
|
||||
pgd = efi_pgd + pgd_index(EFI_VA_END);
|
||||
p4d = p4d_alloc(&init_mm, pgd, EFI_VA_END);
|
||||
if (!p4d) {
|
||||
free_page((unsigned long)efi_pgd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!p4d)
|
||||
goto free_pgd;
|
||||
|
||||
pud = pud_alloc(&init_mm, p4d, EFI_VA_END);
|
||||
if (!pud) {
|
||||
if (pgtable_l5_enabled())
|
||||
free_page((unsigned long) pgd_page_vaddr(*pgd));
|
||||
free_pages((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!pud)
|
||||
goto free_p4d;
|
||||
|
||||
efi_mm.pgd = efi_pgd;
|
||||
mm_init_cpumask(&efi_mm);
|
||||
init_new_context(NULL, &efi_mm);
|
||||
|
||||
return 0;
|
||||
|
||||
free_p4d:
|
||||
if (pgtable_l5_enabled())
|
||||
free_page((unsigned long)pgd_page_vaddr(*pgd));
|
||||
free_pgd:
|
||||
free_pages((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER);
|
||||
fail:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -49,15 +49,25 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty)
|
|||
|
||||
if (!tty->ops->write)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&speakup_tty_mutex);
|
||||
if (speakup_tty) {
|
||||
mutex_unlock(&speakup_tty_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
speakup_tty = tty;
|
||||
|
||||
ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL);
|
||||
if (!ldisc_data)
|
||||
if (!ldisc_data) {
|
||||
speakup_tty = NULL;
|
||||
mutex_unlock(&speakup_tty_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
init_completion(&ldisc_data->completion);
|
||||
ldisc_data->buf_free = true;
|
||||
speakup_tty->disc_data = ldisc_data;
|
||||
mutex_unlock(&speakup_tty_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ static const struct regmap_config ti_eqep_regmap32_config = {
|
|||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = 0x24,
|
||||
.max_register = QUPRD,
|
||||
};
|
||||
|
||||
static const struct regmap_config ti_eqep_regmap16_config = {
|
||||
|
|
@ -376,7 +376,7 @@ static const struct regmap_config ti_eqep_regmap16_config = {
|
|||
.reg_bits = 16,
|
||||
.val_bits = 16,
|
||||
.reg_stride = 2,
|
||||
.max_register = 0x1e,
|
||||
.max_register = QCPRDLAT,
|
||||
};
|
||||
|
||||
static int ti_eqep_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ config DEV_DAX_HMEM
|
|||
Say M if unsure.
|
||||
|
||||
config DEV_DAX_HMEM_DEVICES
|
||||
depends on NUMA_KEEP_MEMINFO # for phys_to_target_node()
|
||||
depends on DEV_DAX_HMEM && DAX=y
|
||||
def_bool y
|
||||
|
||||
|
|
|
|||
|
|
@ -23,19 +23,17 @@
|
|||
#define CP_2WHEEL_MOUSE_HACK 0x02
|
||||
#define CP_2WHEEL_MOUSE_HACK_ON 0x04
|
||||
|
||||
#define VA_INVAL_LOGICAL_BOUNDARY 0x08
|
||||
|
||||
/*
|
||||
* Some USB barcode readers from cypress have usage min and usage max in
|
||||
* the wrong order
|
||||
*/
|
||||
static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
static __u8 *cp_rdesc_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
unsigned int i;
|
||||
|
||||
if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
|
||||
return rdesc;
|
||||
|
||||
if (*rsize < 4)
|
||||
return rdesc;
|
||||
|
||||
|
|
@ -48,6 +46,40 @@ static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||
return rdesc;
|
||||
}
|
||||
|
||||
static __u8 *va_logical_boundary_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
/*
|
||||
* Varmilo VA104M (with VID Cypress and device ID 07B1) incorrectly
|
||||
* reports Logical Minimum of its Consumer Control device as 572
|
||||
* (0x02 0x3c). Fix this by setting its Logical Minimum to zero.
|
||||
*/
|
||||
if (*rsize == 25 &&
|
||||
rdesc[0] == 0x05 && rdesc[1] == 0x0c &&
|
||||
rdesc[2] == 0x09 && rdesc[3] == 0x01 &&
|
||||
rdesc[6] == 0x19 && rdesc[7] == 0x00 &&
|
||||
rdesc[11] == 0x16 && rdesc[12] == 0x3c && rdesc[13] == 0x02) {
|
||||
hid_info(hdev,
|
||||
"fixing up varmilo VA104M consumer control report descriptor\n");
|
||||
rdesc[12] = 0x00;
|
||||
rdesc[13] = 0x00;
|
||||
}
|
||||
return rdesc;
|
||||
}
|
||||
|
||||
static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
|
||||
if (quirks & CP_RDESC_SWAPPED_MIN_MAX)
|
||||
rdesc = cp_rdesc_fixup(hdev, rdesc, rsize);
|
||||
if (quirks & VA_INVAL_LOGICAL_BOUNDARY)
|
||||
rdesc = va_logical_boundary_fixup(hdev, rdesc, rsize);
|
||||
|
||||
return rdesc;
|
||||
}
|
||||
|
||||
static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
|
|
@ -128,6 +160,8 @@ static const struct hid_device_id cp_devices[] = {
|
|||
.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE),
|
||||
.driver_data = CP_2WHEEL_MOUSE_HACK },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1),
|
||||
.driver_data = VA_INVAL_LOGICAL_BOUNDARY },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, cp_devices);
|
||||
|
|
|
|||
|
|
@ -331,6 +331,8 @@
|
|||
#define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81
|
||||
#define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001
|
||||
|
||||
#define USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1 0X07b1
|
||||
|
||||
#define USB_VENDOR_ID_DATA_MODUL 0x7374
|
||||
#define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH 0x1201
|
||||
|
||||
|
|
@ -443,6 +445,10 @@
|
|||
#define USB_VENDOR_ID_FRUCTEL 0x25B6
|
||||
#define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002
|
||||
|
||||
#define USB_VENDOR_ID_GAMEVICE 0x27F8
|
||||
#define USB_DEVICE_ID_GAMEVICE_GV186 0x0BBE
|
||||
#define USB_DEVICE_ID_GAMEVICE_KISHI 0x0BBF
|
||||
|
||||
#define USB_VENDOR_ID_GAMERON 0x0810
|
||||
#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
|
||||
#define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002
|
||||
|
|
@ -485,6 +491,7 @@
|
|||
#define USB_DEVICE_ID_PENPOWER 0x00f4
|
||||
|
||||
#define USB_VENDOR_ID_GREENASIA 0x0e8f
|
||||
#define USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR 0x3010
|
||||
#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013
|
||||
|
||||
#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
|
||||
|
|
@ -743,6 +750,7 @@
|
|||
#define USB_VENDOR_ID_LOGITECH 0x046d
|
||||
#define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
|
||||
#define USB_DEVICE_ID_LOGITECH_T651 0xb00c
|
||||
#define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD 0xb309
|
||||
#define USB_DEVICE_ID_LOGITECH_C007 0xc007
|
||||
#define USB_DEVICE_ID_LOGITECH_C077 0xc077
|
||||
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
|
||||
|
|
@ -1301,6 +1309,7 @@
|
|||
|
||||
#define USB_VENDOR_ID_UGTIZER 0x2179
|
||||
#define USB_DEVICE_ID_UGTIZER_TABLET_GP0610 0x0053
|
||||
#define USB_DEVICE_ID_UGTIZER_TABLET_GT5040 0x0077
|
||||
|
||||
#define USB_VENDOR_ID_VIEWSONIC 0x0543
|
||||
#define USB_DEVICE_ID_VIEWSONIC_PD1011 0xe621
|
||||
|
|
|
|||
|
|
@ -319,6 +319,9 @@ static const struct hid_device_id hid_battery_quirks[] = {
|
|||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||
USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,48 @@
|
|||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define QUIRK_TOUCHPAD_ON_OFF_REPORT BIT(0)
|
||||
|
||||
static __u8 *ite_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
|
||||
if (quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) {
|
||||
if (*rsize == 188 && rdesc[162] == 0x81 && rdesc[163] == 0x02) {
|
||||
hid_info(hdev, "Fixing up ITE keyboard report descriptor\n");
|
||||
rdesc[163] = HID_MAIN_ITEM_RELATIVE;
|
||||
}
|
||||
}
|
||||
|
||||
return rdesc;
|
||||
}
|
||||
|
||||
static int ite_input_mapping(struct hid_device *hdev,
|
||||
struct hid_input *hi, struct hid_field *field,
|
||||
struct hid_usage *usage, unsigned long **bit,
|
||||
int *max)
|
||||
{
|
||||
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
|
||||
if ((quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) &&
|
||||
(usage->hid & HID_USAGE_PAGE) == 0x00880000) {
|
||||
if (usage->hid == 0x00880078) {
|
||||
/* Touchpad on, userspace expects F22 for this */
|
||||
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F22);
|
||||
return 1;
|
||||
}
|
||||
if (usage->hid == 0x00880079) {
|
||||
/* Touchpad off, userspace expects F23 for this */
|
||||
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F23);
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ite_event(struct hid_device *hdev, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
|
|
@ -37,13 +79,27 @@ static int ite_event(struct hid_device *hdev, struct hid_field *field,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ite_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
hid_set_drvdata(hdev, (void *)id->driver_data);
|
||||
|
||||
ret = hid_open_report(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
}
|
||||
|
||||
static const struct hid_device_id ite_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) },
|
||||
/* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_SYNAPTICS,
|
||||
USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) },
|
||||
USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012),
|
||||
.driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
|
||||
/* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_SYNAPTICS,
|
||||
|
|
@ -55,6 +111,9 @@ MODULE_DEVICE_TABLE(hid, ite_devices);
|
|||
static struct hid_driver ite_driver = {
|
||||
.name = "itetech",
|
||||
.id_table = ite_devices,
|
||||
.probe = ite_probe,
|
||||
.report_fixup = ite_report_fixup,
|
||||
.input_mapping = ite_input_mapping,
|
||||
.event = ite_event,
|
||||
};
|
||||
module_hid_driver(ite_driver);
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ static const char mse_bluetooth_descriptor[] = {
|
|||
0x25, 0x01, /* LOGICAL_MAX (1) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x95, 0x04, /* REPORT_COUNT (4) */
|
||||
0x81, 0x06, /* INPUT */
|
||||
0x81, 0x02, /* INPUT (Data,Var,Abs) */
|
||||
0xC0, /* END_COLLECTION */
|
||||
0xC0, /* END_COLLECTION */
|
||||
};
|
||||
|
|
@ -866,11 +866,24 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
|
|||
schedule_work(&djrcv_dev->work);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some quad/bluetooth keyboards have a builtin touchpad in this case we see
|
||||
* only 1 paired device with a device_type of REPORT_TYPE_KEYBOARD. For the
|
||||
* touchpad to work we must also forward mouse input reports to the dj_hiddev
|
||||
* created for the keyboard (instead of forwarding them to a second paired
|
||||
* device with a device_type of REPORT_TYPE_MOUSE as we normally would).
|
||||
*/
|
||||
static const u16 kbd_builtin_touchpad_ids[] = {
|
||||
0xb309, /* Dinovo Edge */
|
||||
0xb30c, /* Dinovo Mini */
|
||||
};
|
||||
|
||||
static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev,
|
||||
struct hidpp_event *hidpp_report,
|
||||
struct dj_workitem *workitem)
|
||||
{
|
||||
struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
|
||||
int i, id;
|
||||
|
||||
workitem->type = WORKITEM_TYPE_PAIRED;
|
||||
workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &
|
||||
|
|
@ -882,6 +895,13 @@ static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev,
|
|||
workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA |
|
||||
POWER_KEYS | MEDIA_CENTER |
|
||||
HIDPP;
|
||||
id = (workitem->quad_id_msb << 8) | workitem->quad_id_lsb;
|
||||
for (i = 0; i < ARRAY_SIZE(kbd_builtin_touchpad_ids); i++) {
|
||||
if (id == kbd_builtin_touchpad_ids[i]) {
|
||||
workitem->reports_supported |= STD_MOUSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case REPORT_TYPE_MOUSE:
|
||||
workitem->reports_supported |= STD_MOUSE | HIDPP;
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ MODULE_PARM_DESC(disable_tap_to_click,
|
|||
#define HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS BIT(3)
|
||||
#define HIDPP_CAPABILITY_BATTERY_VOLTAGE BIT(4)
|
||||
|
||||
#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
|
||||
|
||||
/*
|
||||
* There are two hidpp protocols in use, the first version hidpp10 is known
|
||||
* as register access protocol or RAP, the second version hidpp20 is known as
|
||||
|
|
@ -2950,6 +2952,26 @@ static int g920_get_config(struct hidpp_device *hidpp,
|
|||
return g920_ff_set_autocenter(hidpp, data);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Logitech Dinovo Mini keyboard with builtin touchpad */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#define DINOVO_MINI_PRODUCT_ID 0xb30c
|
||||
|
||||
static int lg_dinovo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x00d: lg_map_key_clear(KEY_MEDIA); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* HID++1.0 devices which use HID++ reports for their wheels */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
|
@ -3185,6 +3207,9 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
|||
field->application != HID_GD_MOUSE)
|
||||
return m560_input_mapping(hdev, hi, field, usage, bit, max);
|
||||
|
||||
if (hdev->product == DINOVO_MINI_PRODUCT_ID)
|
||||
return lg_dinovo_input_mapping(hdev, hi, field, usage, bit, max);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3947,6 +3972,7 @@ static const struct hid_device_id hidpp_devices[] = {
|
|||
LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
||||
{ /* Mouse Logitech MX Anywhere 2 */
|
||||
LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
||||
{ LDJ_DEVICE(0x4072), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
||||
{ LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
||||
{ LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
||||
{ LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
||||
|
|
@ -3971,6 +3997,9 @@ static const struct hid_device_id hidpp_devices[] = {
|
|||
{ /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */
|
||||
LDJ_DEVICE(0xb305),
|
||||
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
|
||||
{ /* Dinovo Edge (Bluetooth-receiver in HID proxy mode) */
|
||||
LDJ_DEVICE(0xb309),
|
||||
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
|
||||
{ /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */
|
||||
LDJ_DEVICE(0xb30b),
|
||||
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
|
||||
|
|
@ -4013,6 +4042,9 @@ static const struct hid_device_id hidpp_devices[] = {
|
|||
{ /* MX5000 keyboard over Bluetooth */
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305),
|
||||
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
|
||||
{ /* Dinovo Edge keyboard over Bluetooth */
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb309),
|
||||
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
|
||||
{ /* MX5500 keyboard over Bluetooth */
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b),
|
||||
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
|
||||
|
|
|
|||
|
|
@ -49,6 +49,36 @@ enum {
|
|||
MCP2221_ALT_F_NOT_GPIOD = 0xEF,
|
||||
};
|
||||
|
||||
/* MCP GPIO direction encoding */
|
||||
enum {
|
||||
MCP2221_DIR_OUT = 0x00,
|
||||
MCP2221_DIR_IN = 0x01,
|
||||
};
|
||||
|
||||
#define MCP_NGPIO 4
|
||||
|
||||
/* MCP GPIO set command layout */
|
||||
struct mcp_set_gpio {
|
||||
u8 cmd;
|
||||
u8 dummy;
|
||||
struct {
|
||||
u8 change_value;
|
||||
u8 value;
|
||||
u8 change_direction;
|
||||
u8 direction;
|
||||
} gpio[MCP_NGPIO];
|
||||
} __packed;
|
||||
|
||||
/* MCP GPIO get command layout */
|
||||
struct mcp_get_gpio {
|
||||
u8 cmd;
|
||||
u8 dummy;
|
||||
struct {
|
||||
u8 direction;
|
||||
u8 value;
|
||||
} gpio[MCP_NGPIO];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* There is no way to distinguish responses. Therefore next command
|
||||
* is sent only after response to previous has been received. Mutex
|
||||
|
|
@ -542,7 +572,7 @@ static int mcp_gpio_get(struct gpio_chip *gc,
|
|||
|
||||
mcp->txbuf[0] = MCP2221_GPIO_GET;
|
||||
|
||||
mcp->gp_idx = (offset + 1) * 2;
|
||||
mcp->gp_idx = offsetof(struct mcp_get_gpio, gpio[offset].value);
|
||||
|
||||
mutex_lock(&mcp->lock);
|
||||
ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
|
||||
|
|
@ -559,7 +589,7 @@ static void mcp_gpio_set(struct gpio_chip *gc,
|
|||
memset(mcp->txbuf, 0, 18);
|
||||
mcp->txbuf[0] = MCP2221_GPIO_SET;
|
||||
|
||||
mcp->gp_idx = ((offset + 1) * 4) - 1;
|
||||
mcp->gp_idx = offsetof(struct mcp_set_gpio, gpio[offset].value);
|
||||
|
||||
mcp->txbuf[mcp->gp_idx - 1] = 1;
|
||||
mcp->txbuf[mcp->gp_idx] = !!value;
|
||||
|
|
@ -575,7 +605,7 @@ static int mcp_gpio_dir_set(struct mcp2221 *mcp,
|
|||
memset(mcp->txbuf, 0, 18);
|
||||
mcp->txbuf[0] = MCP2221_GPIO_SET;
|
||||
|
||||
mcp->gp_idx = (offset + 1) * 5;
|
||||
mcp->gp_idx = offsetof(struct mcp_set_gpio, gpio[offset].direction);
|
||||
|
||||
mcp->txbuf[mcp->gp_idx - 1] = 1;
|
||||
mcp->txbuf[mcp->gp_idx] = val;
|
||||
|
|
@ -590,7 +620,7 @@ static int mcp_gpio_direction_input(struct gpio_chip *gc,
|
|||
struct mcp2221 *mcp = gpiochip_get_data(gc);
|
||||
|
||||
mutex_lock(&mcp->lock);
|
||||
ret = mcp_gpio_dir_set(mcp, offset, 0);
|
||||
ret = mcp_gpio_dir_set(mcp, offset, MCP2221_DIR_IN);
|
||||
mutex_unlock(&mcp->lock);
|
||||
|
||||
return ret;
|
||||
|
|
@ -603,7 +633,7 @@ static int mcp_gpio_direction_output(struct gpio_chip *gc,
|
|||
struct mcp2221 *mcp = gpiochip_get_data(gc);
|
||||
|
||||
mutex_lock(&mcp->lock);
|
||||
ret = mcp_gpio_dir_set(mcp, offset, 1);
|
||||
ret = mcp_gpio_dir_set(mcp, offset, MCP2221_DIR_OUT);
|
||||
mutex_unlock(&mcp->lock);
|
||||
|
||||
/* Can't configure as output, bailout early */
|
||||
|
|
@ -623,7 +653,7 @@ static int mcp_gpio_get_direction(struct gpio_chip *gc,
|
|||
|
||||
mcp->txbuf[0] = MCP2221_GPIO_GET;
|
||||
|
||||
mcp->gp_idx = (offset + 1) * 2;
|
||||
mcp->gp_idx = offsetof(struct mcp_get_gpio, gpio[offset].direction);
|
||||
|
||||
mutex_lock(&mcp->lock);
|
||||
ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
|
||||
|
|
@ -632,7 +662,7 @@ static int mcp_gpio_get_direction(struct gpio_chip *gc,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mcp->gpio_dir)
|
||||
if (mcp->gpio_dir == MCP2221_DIR_IN)
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
|
||||
return GPIO_LINE_DIRECTION_OUT;
|
||||
|
|
@ -758,7 +788,7 @@ static int mcp2221_raw_event(struct hid_device *hdev,
|
|||
mcp->status = -ENOENT;
|
||||
} else {
|
||||
mcp->status = !!data[mcp->gp_idx];
|
||||
mcp->gpio_dir = !!data[mcp->gp_idx + 1];
|
||||
mcp->gpio_dir = data[mcp->gp_idx + 1];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -860,7 +890,7 @@ static int mcp2221_probe(struct hid_device *hdev,
|
|||
mcp->gc->get_direction = mcp_gpio_get_direction;
|
||||
mcp->gc->set = mcp_gpio_set;
|
||||
mcp->gc->get = mcp_gpio_get;
|
||||
mcp->gc->ngpio = 4;
|
||||
mcp->gc->ngpio = MCP_NGPIO;
|
||||
mcp->gc->base = -1;
|
||||
mcp->gc->can_sleep = 1;
|
||||
mcp->gc->parent = &hdev->dev;
|
||||
|
|
|
|||
|
|
@ -83,7 +83,12 @@ static const struct hid_device_id hid_quirks[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER), HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28), HID_QUIRK_NOGET },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY), HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR), HID_QUIRK_MULTI_INPUT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD), HID_QUIRK_MULTI_INPUT },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_GV186),
|
||||
HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_KISHI),
|
||||
HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
|
||||
|
|
|
|||
|
|
@ -483,7 +483,8 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
|
|||
return 1;
|
||||
|
||||
ptr = raw_data;
|
||||
ptr++; /* Skip report id */
|
||||
if (report->id)
|
||||
ptr++; /* Skip report id */
|
||||
|
||||
spin_lock_irqsave(&pdata->lock, flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -385,6 +385,8 @@ static const struct hid_device_id uclogic_devices[] = {
|
|||
USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER,
|
||||
USB_DEVICE_ID_UGTIZER_TABLET_GP0610) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER,
|
||||
USB_DEVICE_ID_UGTIZER_TABLET_GT5040) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||
USB_DEVICE_ID_UGEE_TABLET_G5) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||
|
|
|
|||
|
|
@ -997,6 +997,8 @@ int uclogic_params_init(struct uclogic_params *params,
|
|||
break;
|
||||
case VID_PID(USB_VENDOR_ID_UGTIZER,
|
||||
USB_DEVICE_ID_UGTIZER_TABLET_GP0610):
|
||||
case VID_PID(USB_VENDOR_ID_UGTIZER,
|
||||
USB_DEVICE_ID_UGTIZER_TABLET_GT5040):
|
||||
case VID_PID(USB_VENDOR_ID_UGEE,
|
||||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540):
|
||||
case VID_PID(USB_VENDOR_ID_UGEE,
|
||||
|
|
|
|||
|
|
@ -943,6 +943,11 @@ static void i2c_hid_acpi_enable_wakeup(struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void i2c_hid_acpi_shutdown(struct device *dev)
|
||||
{
|
||||
acpi_device_set_power(ACPI_COMPANION(dev), ACPI_STATE_D3_COLD);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id i2c_hid_acpi_match[] = {
|
||||
{"ACPI0C50", 0 },
|
||||
{"PNP0C50", 0 },
|
||||
|
|
@ -959,6 +964,8 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
|
|||
static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {}
|
||||
|
||||
static inline void i2c_hid_acpi_enable_wakeup(struct device *dev) {}
|
||||
|
||||
static inline void i2c_hid_acpi_shutdown(struct device *dev) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
|
@ -1175,6 +1182,8 @@ static void i2c_hid_shutdown(struct i2c_client *client)
|
|||
|
||||
i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
|
||||
free_irq(client->irq, ihid);
|
||||
|
||||
i2c_hid_acpi_shutdown(&client->dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
|
|
|||
|
|
@ -126,6 +126,12 @@ enum kx_chipset {
|
|||
KX_MAX_CHIPS /* this must be last */
|
||||
};
|
||||
|
||||
enum kx_acpi_type {
|
||||
ACPI_GENERIC,
|
||||
ACPI_SMO8500,
|
||||
ACPI_KIOX010A,
|
||||
};
|
||||
|
||||
struct kxcjk1013_data {
|
||||
struct i2c_client *client;
|
||||
struct iio_trigger *dready_trig;
|
||||
|
|
@ -143,7 +149,7 @@ struct kxcjk1013_data {
|
|||
bool motion_trigger_on;
|
||||
int64_t timestamp;
|
||||
enum kx_chipset chipset;
|
||||
bool is_smo8500_device;
|
||||
enum kx_acpi_type acpi_type;
|
||||
};
|
||||
|
||||
enum kxcjk1013_axis {
|
||||
|
|
@ -270,6 +276,32 @@ static const struct {
|
|||
{19163, 1, 0},
|
||||
{38326, 0, 1} };
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
enum kiox010a_fn_index {
|
||||
KIOX010A_SET_LAPTOP_MODE = 1,
|
||||
KIOX010A_SET_TABLET_MODE = 2,
|
||||
};
|
||||
|
||||
static int kiox010a_dsm(struct device *dev, int fn_index)
|
||||
{
|
||||
acpi_handle handle = ACPI_HANDLE(dev);
|
||||
guid_t kiox010a_dsm_guid;
|
||||
union acpi_object *obj;
|
||||
|
||||
if (!handle)
|
||||
return -ENODEV;
|
||||
|
||||
guid_parse("1f339696-d475-4e26-8cad-2e9f8e6d7a91", &kiox010a_dsm_guid);
|
||||
|
||||
obj = acpi_evaluate_dsm(handle, &kiox010a_dsm_guid, 1, fn_index, NULL);
|
||||
if (!obj)
|
||||
return -EIO;
|
||||
|
||||
ACPI_FREE(obj);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int kxcjk1013_set_mode(struct kxcjk1013_data *data,
|
||||
enum kxcjk1013_mode mode)
|
||||
{
|
||||
|
|
@ -347,6 +379,13 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
|
|||
{
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
if (data->acpi_type == ACPI_KIOX010A) {
|
||||
/* Make sure the kbd and touchpad on 2-in-1s using 2 KXCJ91008-s work */
|
||||
kiox010a_dsm(&data->client->dev, KIOX010A_SET_LAPTOP_MODE);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_WHO_AM_I);
|
||||
if (ret < 0) {
|
||||
dev_err(&data->client->dev, "Error reading who_am_i\n");
|
||||
|
|
@ -1247,7 +1286,7 @@ static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private)
|
|||
|
||||
static const char *kxcjk1013_match_acpi_device(struct device *dev,
|
||||
enum kx_chipset *chipset,
|
||||
bool *is_smo8500_device)
|
||||
enum kx_acpi_type *acpi_type)
|
||||
{
|
||||
const struct acpi_device_id *id;
|
||||
|
||||
|
|
@ -1256,7 +1295,9 @@ static const char *kxcjk1013_match_acpi_device(struct device *dev,
|
|||
return NULL;
|
||||
|
||||
if (strcmp(id->id, "SMO8500") == 0)
|
||||
*is_smo8500_device = true;
|
||||
*acpi_type = ACPI_SMO8500;
|
||||
else if (strcmp(id->id, "KIOX010A") == 0)
|
||||
*acpi_type = ACPI_KIOX010A;
|
||||
|
||||
*chipset = (enum kx_chipset)id->driver_data;
|
||||
|
||||
|
|
@ -1299,7 +1340,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
|
|||
} else if (ACPI_HANDLE(&client->dev)) {
|
||||
name = kxcjk1013_match_acpi_device(&client->dev,
|
||||
&data->chipset,
|
||||
&data->is_smo8500_device);
|
||||
&data->acpi_type);
|
||||
} else
|
||||
return -ENODEV;
|
||||
|
||||
|
|
@ -1316,7 +1357,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
|
|||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->info = &kxcjk1013_info;
|
||||
|
||||
if (client->irq > 0 && !data->is_smo8500_device) {
|
||||
if (client->irq > 0 && data->acpi_type != ACPI_SMO8500) {
|
||||
ret = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
kxcjk1013_data_rdy_trig_poll,
|
||||
kxcjk1013_event_handler,
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@
|
|||
#define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10
|
||||
#define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986)
|
||||
#define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12
|
||||
#define JZ4770_ADC_BATTERY_VREF 6600
|
||||
#define JZ4770_ADC_BATTERY_VREF 1200
|
||||
#define JZ4770_ADC_BATTERY_VREF_BITS 12
|
||||
|
||||
#define JZ_ADC_IRQ_AUX BIT(0)
|
||||
|
|
@ -177,13 +177,12 @@ static void ingenic_adc_set_config(struct ingenic_adc *adc,
|
|||
mutex_unlock(&adc->lock);
|
||||
}
|
||||
|
||||
static void ingenic_adc_enable(struct ingenic_adc *adc,
|
||||
int engine,
|
||||
bool enabled)
|
||||
static void ingenic_adc_enable_unlocked(struct ingenic_adc *adc,
|
||||
int engine,
|
||||
bool enabled)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
mutex_lock(&adc->lock);
|
||||
val = readb(adc->base + JZ_ADC_REG_ENABLE);
|
||||
|
||||
if (enabled)
|
||||
|
|
@ -192,20 +191,41 @@ static void ingenic_adc_enable(struct ingenic_adc *adc,
|
|||
val &= ~BIT(engine);
|
||||
|
||||
writeb(val, adc->base + JZ_ADC_REG_ENABLE);
|
||||
}
|
||||
|
||||
static void ingenic_adc_enable(struct ingenic_adc *adc,
|
||||
int engine,
|
||||
bool enabled)
|
||||
{
|
||||
mutex_lock(&adc->lock);
|
||||
ingenic_adc_enable_unlocked(adc, engine, enabled);
|
||||
mutex_unlock(&adc->lock);
|
||||
}
|
||||
|
||||
static int ingenic_adc_capture(struct ingenic_adc *adc,
|
||||
int engine)
|
||||
{
|
||||
u32 cfg;
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ingenic_adc_enable(adc, engine, true);
|
||||
/*
|
||||
* Disable CMD_SEL temporarily, because it causes wrong VBAT readings,
|
||||
* probably due to the switch of VREF. We must keep the lock here to
|
||||
* avoid races with the buffer enable/disable functions.
|
||||
*/
|
||||
mutex_lock(&adc->lock);
|
||||
cfg = readl(adc->base + JZ_ADC_REG_CFG);
|
||||
writel(cfg & ~JZ_ADC_REG_CFG_CMD_SEL, adc->base + JZ_ADC_REG_CFG);
|
||||
|
||||
ingenic_adc_enable_unlocked(adc, engine, true);
|
||||
ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val,
|
||||
!(val & BIT(engine)), 250, 1000);
|
||||
if (ret)
|
||||
ingenic_adc_enable(adc, engine, false);
|
||||
ingenic_adc_enable_unlocked(adc, engine, false);
|
||||
|
||||
writel(cfg, adc->base + JZ_ADC_REG_CFG);
|
||||
mutex_unlock(&adc->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iio/iio.h>
|
||||
|
|
@ -276,6 +276,8 @@ static int mt6577_auxadc_probe(struct platform_device *pdev)
|
|||
goto err_disable_clk;
|
||||
}
|
||||
|
||||
adc_dev->dev_comp = device_get_match_data(&pdev->dev);
|
||||
|
||||
mutex_init(&adc_dev->lock);
|
||||
|
||||
mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
|
||||
|
|
|
|||
|
|
@ -41,18 +41,16 @@
|
|||
* struct stm32_adc_common_regs - stm32 common registers
|
||||
* @csr: common status register offset
|
||||
* @ccr: common control register offset
|
||||
* @eoc1_msk: adc1 end of conversion flag in @csr
|
||||
* @eoc2_msk: adc2 end of conversion flag in @csr
|
||||
* @eoc3_msk: adc3 end of conversion flag in @csr
|
||||
* @eoc_msk: array of eoc (end of conversion flag) masks in csr for adc1..n
|
||||
* @ovr_msk: array of ovr (overrun flag) masks in csr for adc1..n
|
||||
* @ier: interrupt enable register offset for each adc
|
||||
* @eocie_msk: end of conversion interrupt enable mask in @ier
|
||||
*/
|
||||
struct stm32_adc_common_regs {
|
||||
u32 csr;
|
||||
u32 ccr;
|
||||
u32 eoc1_msk;
|
||||
u32 eoc2_msk;
|
||||
u32 eoc3_msk;
|
||||
u32 eoc_msk[STM32_ADC_MAX_ADCS];
|
||||
u32 ovr_msk[STM32_ADC_MAX_ADCS];
|
||||
u32 ier;
|
||||
u32 eocie_msk;
|
||||
};
|
||||
|
|
@ -282,21 +280,20 @@ static int stm32h7_adc_clk_sel(struct platform_device *pdev,
|
|||
static const struct stm32_adc_common_regs stm32f4_adc_common_regs = {
|
||||
.csr = STM32F4_ADC_CSR,
|
||||
.ccr = STM32F4_ADC_CCR,
|
||||
.eoc1_msk = STM32F4_EOC1 | STM32F4_OVR1,
|
||||
.eoc2_msk = STM32F4_EOC2 | STM32F4_OVR2,
|
||||
.eoc3_msk = STM32F4_EOC3 | STM32F4_OVR3,
|
||||
.eoc_msk = { STM32F4_EOC1, STM32F4_EOC2, STM32F4_EOC3},
|
||||
.ovr_msk = { STM32F4_OVR1, STM32F4_OVR2, STM32F4_OVR3},
|
||||
.ier = STM32F4_ADC_CR1,
|
||||
.eocie_msk = STM32F4_EOCIE | STM32F4_OVRIE,
|
||||
.eocie_msk = STM32F4_EOCIE,
|
||||
};
|
||||
|
||||
/* STM32H7 common registers definitions */
|
||||
static const struct stm32_adc_common_regs stm32h7_adc_common_regs = {
|
||||
.csr = STM32H7_ADC_CSR,
|
||||
.ccr = STM32H7_ADC_CCR,
|
||||
.eoc1_msk = STM32H7_EOC_MST | STM32H7_OVR_MST,
|
||||
.eoc2_msk = STM32H7_EOC_SLV | STM32H7_OVR_SLV,
|
||||
.eoc_msk = { STM32H7_EOC_MST, STM32H7_EOC_SLV},
|
||||
.ovr_msk = { STM32H7_OVR_MST, STM32H7_OVR_SLV},
|
||||
.ier = STM32H7_ADC_IER,
|
||||
.eocie_msk = STM32H7_EOCIE | STM32H7_OVRIE,
|
||||
.eocie_msk = STM32H7_EOCIE,
|
||||
};
|
||||
|
||||
static const unsigned int stm32_adc_offset[STM32_ADC_MAX_ADCS] = {
|
||||
|
|
@ -318,6 +315,7 @@ static void stm32_adc_irq_handler(struct irq_desc *desc)
|
|||
{
|
||||
struct stm32_adc_priv *priv = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
int i;
|
||||
u32 status;
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
|
@ -335,17 +333,12 @@ static void stm32_adc_irq_handler(struct irq_desc *desc)
|
|||
* before invoking the interrupt handler (e.g. call ISR only for
|
||||
* IRQ-enabled ADCs).
|
||||
*/
|
||||
if (status & priv->cfg->regs->eoc1_msk &&
|
||||
stm32_adc_eoc_enabled(priv, 0))
|
||||
generic_handle_irq(irq_find_mapping(priv->domain, 0));
|
||||
|
||||
if (status & priv->cfg->regs->eoc2_msk &&
|
||||
stm32_adc_eoc_enabled(priv, 1))
|
||||
generic_handle_irq(irq_find_mapping(priv->domain, 1));
|
||||
|
||||
if (status & priv->cfg->regs->eoc3_msk &&
|
||||
stm32_adc_eoc_enabled(priv, 2))
|
||||
generic_handle_irq(irq_find_mapping(priv->domain, 2));
|
||||
for (i = 0; i < priv->cfg->num_irqs; i++) {
|
||||
if ((status & priv->cfg->regs->eoc_msk[i] &&
|
||||
stm32_adc_eoc_enabled(priv, i)) ||
|
||||
(status & priv->cfg->regs->ovr_msk[i]))
|
||||
generic_handle_irq(irq_find_mapping(priv->domain, i));
|
||||
}
|
||||
|
||||
chained_irq_exit(chip, desc);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ struct stm32_adc;
|
|||
* @start_conv: routine to start conversions
|
||||
* @stop_conv: routine to stop conversions
|
||||
* @unprepare: optional unprepare routine (disable, power-down)
|
||||
* @irq_clear: routine to clear irqs
|
||||
* @smp_cycles: programmable sampling time (ADC clock cycles)
|
||||
*/
|
||||
struct stm32_adc_cfg {
|
||||
|
|
@ -166,6 +167,7 @@ struct stm32_adc_cfg {
|
|||
void (*start_conv)(struct iio_dev *, bool dma);
|
||||
void (*stop_conv)(struct iio_dev *);
|
||||
void (*unprepare)(struct iio_dev *);
|
||||
void (*irq_clear)(struct iio_dev *indio_dev, u32 msk);
|
||||
const unsigned int *smp_cycles;
|
||||
};
|
||||
|
||||
|
|
@ -621,6 +623,13 @@ static void stm32f4_adc_stop_conv(struct iio_dev *indio_dev)
|
|||
STM32F4_ADON | STM32F4_DMA | STM32F4_DDS);
|
||||
}
|
||||
|
||||
static void stm32f4_adc_irq_clear(struct iio_dev *indio_dev, u32 msk)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
|
||||
stm32_adc_clr_bits(adc, adc->cfg->regs->isr_eoc.reg, msk);
|
||||
}
|
||||
|
||||
static void stm32h7_adc_start_conv(struct iio_dev *indio_dev, bool dma)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
|
|
@ -659,6 +668,13 @@ static void stm32h7_adc_stop_conv(struct iio_dev *indio_dev)
|
|||
stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR, STM32H7_DMNGT_MASK);
|
||||
}
|
||||
|
||||
static void stm32h7_adc_irq_clear(struct iio_dev *indio_dev, u32 msk)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
/* On STM32H7 IRQs are cleared by writing 1 into ISR register */
|
||||
stm32_adc_set_bits(adc, adc->cfg->regs->isr_eoc.reg, msk);
|
||||
}
|
||||
|
||||
static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
|
|
@ -1235,17 +1251,40 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev,
|
|||
}
|
||||
}
|
||||
|
||||
static void stm32_adc_irq_clear(struct iio_dev *indio_dev, u32 msk)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
|
||||
adc->cfg->irq_clear(indio_dev, msk);
|
||||
}
|
||||
|
||||
static irqreturn_t stm32_adc_threaded_isr(int irq, void *data)
|
||||
{
|
||||
struct iio_dev *indio_dev = data;
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
const struct stm32_adc_regspec *regs = adc->cfg->regs;
|
||||
u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg);
|
||||
u32 mask = stm32_adc_readl(adc, regs->ier_eoc.reg);
|
||||
|
||||
if (status & regs->isr_ovr.mask)
|
||||
/* Check ovr status right now, as ovr mask should be already disabled */
|
||||
if (status & regs->isr_ovr.mask) {
|
||||
/*
|
||||
* Clear ovr bit to avoid subsequent calls to IRQ handler.
|
||||
* This requires to stop ADC first. OVR bit state in ISR,
|
||||
* is propaged to CSR register by hardware.
|
||||
*/
|
||||
adc->cfg->stop_conv(indio_dev);
|
||||
stm32_adc_irq_clear(indio_dev, regs->isr_ovr.mask);
|
||||
dev_err(&indio_dev->dev, "Overrun, stopping: restart needed\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
if (!(status & mask))
|
||||
dev_err_ratelimited(&indio_dev->dev,
|
||||
"Unexpected IRQ: IER=0x%08x, ISR=0x%08x\n",
|
||||
mask, status);
|
||||
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static irqreturn_t stm32_adc_isr(int irq, void *data)
|
||||
|
|
@ -1254,6 +1293,10 @@ static irqreturn_t stm32_adc_isr(int irq, void *data)
|
|||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
const struct stm32_adc_regspec *regs = adc->cfg->regs;
|
||||
u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg);
|
||||
u32 mask = stm32_adc_readl(adc, regs->ier_eoc.reg);
|
||||
|
||||
if (!(status & mask))
|
||||
return IRQ_WAKE_THREAD;
|
||||
|
||||
if (status & regs->isr_ovr.mask) {
|
||||
/*
|
||||
|
|
@ -2046,6 +2089,7 @@ static const struct stm32_adc_cfg stm32f4_adc_cfg = {
|
|||
.start_conv = stm32f4_adc_start_conv,
|
||||
.stop_conv = stm32f4_adc_stop_conv,
|
||||
.smp_cycles = stm32f4_adc_smp_cycles,
|
||||
.irq_clear = stm32f4_adc_irq_clear,
|
||||
};
|
||||
|
||||
static const struct stm32_adc_cfg stm32h7_adc_cfg = {
|
||||
|
|
@ -2057,6 +2101,7 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = {
|
|||
.prepare = stm32h7_adc_prepare,
|
||||
.unprepare = stm32h7_adc_unprepare,
|
||||
.smp_cycles = stm32h7_adc_smp_cycles,
|
||||
.irq_clear = stm32h7_adc_irq_clear,
|
||||
};
|
||||
|
||||
static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
|
||||
|
|
@ -2069,6 +2114,7 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
|
|||
.prepare = stm32h7_adc_prepare,
|
||||
.unprepare = stm32h7_adc_unprepare,
|
||||
.smp_cycles = stm32h7_adc_smp_cycles,
|
||||
.irq_clear = stm32h7_adc_irq_clear,
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32_adc_of_match[] = {
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
|
|||
struct cros_ec_sensorhub *sensor_hub = dev_get_drvdata(dev->parent);
|
||||
struct cros_ec_dev *ec = sensor_hub->ec;
|
||||
struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev);
|
||||
u32 ver_mask;
|
||||
u32 ver_mask, temp;
|
||||
int frequencies[ARRAY_SIZE(state->frequencies) / 2] = { 0 };
|
||||
int ret, i;
|
||||
|
||||
|
|
@ -311,10 +311,16 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
|
|||
&frequencies[2],
|
||||
&state->fifo_max_event_count);
|
||||
} else {
|
||||
frequencies[1] = state->resp->info_3.min_frequency;
|
||||
frequencies[2] = state->resp->info_3.max_frequency;
|
||||
state->fifo_max_event_count =
|
||||
state->resp->info_3.fifo_max_event_count;
|
||||
if (state->resp->info_3.max_frequency == 0) {
|
||||
get_default_min_max_freq(state->resp->info.type,
|
||||
&frequencies[1],
|
||||
&frequencies[2],
|
||||
&temp);
|
||||
} else {
|
||||
frequencies[1] = state->resp->info_3.min_frequency;
|
||||
frequencies[2] = state->resp->info_3.max_frequency;
|
||||
}
|
||||
state->fifo_max_event_count = state->resp->info_3.fifo_max_event_count;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(frequencies); i++) {
|
||||
state->frequencies[2 * i] = frequencies[i] / 1000;
|
||||
|
|
|
|||
|
|
@ -156,11 +156,13 @@ static const struct st_lsm6dsx_ext_dev_settings st_lsm6dsx_ext_dev_table[] = {
|
|||
static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw)
|
||||
{
|
||||
struct st_lsm6dsx_sensor *sensor;
|
||||
u32 odr;
|
||||
u32 odr, timeout;
|
||||
|
||||
sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
|
||||
odr = (hw->enable_mask & BIT(ST_LSM6DSX_ID_ACC)) ? sensor->odr : 12500;
|
||||
msleep((2000000U / odr) + 1);
|
||||
/* set 10ms as minimum timeout for i2c slave configuration */
|
||||
timeout = max_t(u32, 2000000U / odr + 1, 10);
|
||||
msleep(timeout);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -544,6 +544,7 @@ config VCNL4000
|
|||
|
||||
config VCNL4035
|
||||
tristate "VCNL4035 combined ALS and proximity sensor"
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
select REGMAP_I2C
|
||||
depends on I2C
|
||||
|
|
|
|||
|
|
@ -653,16 +653,11 @@ static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mt7621_pcie_request_resources(struct mt7621_pcie *pcie,
|
||||
struct list_head *res)
|
||||
static void mt7621_pcie_add_resources(struct mt7621_pcie *pcie,
|
||||
struct list_head *res)
|
||||
{
|
||||
struct device *dev = pcie->dev;
|
||||
|
||||
pci_add_resource_offset(res, &pcie->io, pcie->offset.io);
|
||||
pci_add_resource_offset(res, &pcie->mem, pcie->offset.mem);
|
||||
pci_add_resource(res, &pcie->busn);
|
||||
|
||||
return devm_request_pci_bus_resources(dev, res);
|
||||
}
|
||||
|
||||
static int mt7621_pcie_register_host(struct pci_host_bridge *host,
|
||||
|
|
@ -738,11 +733,7 @@ static int mt7621_pci_probe(struct platform_device *pdev)
|
|||
|
||||
setup_cm_memory_region(pcie);
|
||||
|
||||
err = mt7621_pcie_request_resources(pcie, &res);
|
||||
if (err) {
|
||||
dev_err(dev, "Error requesting resources\n");
|
||||
return err;
|
||||
}
|
||||
mt7621_pcie_add_resources(pcie, &res);
|
||||
|
||||
err = mt7621_pcie_register_host(bridge, &res);
|
||||
if (err) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
config DMA_RALINK
|
||||
tristate "RALINK DMA support"
|
||||
depends on RALINK && !SOC_RT288X
|
||||
depends on DMADEVICES
|
||||
select DMA_ENGINE
|
||||
select DMA_VIRTUAL_CHANNELS
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ static const struct sdio_device_id sdio_ids[] = {
|
|||
{ SDIO_DEVICE(0x024c, 0x0525), },
|
||||
{ SDIO_DEVICE(0x024c, 0x0623), },
|
||||
{ SDIO_DEVICE(0x024c, 0x0626), },
|
||||
{ SDIO_DEVICE(0x024c, 0x0627), },
|
||||
{ SDIO_DEVICE(0x024c, 0xb723), },
|
||||
{ /* end: all zeroes */ },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -789,8 +789,10 @@ static int ar933x_uart_probe(struct platform_device *pdev)
|
|||
goto err_disable_clk;
|
||||
|
||||
up->gpios = mctrl_gpio_init(port, 0);
|
||||
if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
|
||||
return PTR_ERR(up->gpios);
|
||||
if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS) {
|
||||
ret = PTR_ERR(up->gpios);
|
||||
goto err_disable_clk;
|
||||
}
|
||||
|
||||
up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS);
|
||||
|
||||
|
|
|
|||
|
|
@ -942,8 +942,14 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
|
|||
struct imx_port *sport = dev_id;
|
||||
unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
unsigned long flags = 0;
|
||||
|
||||
spin_lock(&sport->port.lock);
|
||||
/*
|
||||
* IRQs might not be disabled upon entering this interrupt handler,
|
||||
* e.g. when interrupt handlers are forced to be threaded. To support
|
||||
* this scenario as well, disable IRQs when acquiring the spinlock.
|
||||
*/
|
||||
spin_lock_irqsave(&sport->port.lock, flags);
|
||||
|
||||
usr1 = imx_uart_readl(sport, USR1);
|
||||
usr2 = imx_uart_readl(sport, USR2);
|
||||
|
|
@ -1013,7 +1019,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
|
|||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
spin_unlock(&sport->port.lock);
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2002,16 +2008,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
|
|||
unsigned int ucr1;
|
||||
unsigned long flags = 0;
|
||||
int locked = 1;
|
||||
int retval;
|
||||
|
||||
retval = clk_enable(sport->clk_per);
|
||||
if (retval)
|
||||
return;
|
||||
retval = clk_enable(sport->clk_ipg);
|
||||
if (retval) {
|
||||
clk_disable(sport->clk_per);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sport->port.sysrq)
|
||||
locked = 0;
|
||||
|
|
@ -2047,9 +2043,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
|
|||
|
||||
if (locked)
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
|
||||
clk_disable(sport->clk_ipg);
|
||||
clk_disable(sport->clk_per);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2150,15 +2143,14 @@ imx_uart_console_setup(struct console *co, char *options)
|
|||
|
||||
retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
|
||||
|
||||
clk_disable(sport->clk_ipg);
|
||||
if (retval) {
|
||||
clk_unprepare(sport->clk_ipg);
|
||||
clk_disable_unprepare(sport->clk_ipg);
|
||||
goto error_console;
|
||||
}
|
||||
|
||||
retval = clk_prepare(sport->clk_per);
|
||||
retval = clk_prepare_enable(sport->clk_per);
|
||||
if (retval)
|
||||
clk_unprepare(sport->clk_ipg);
|
||||
clk_disable_unprepare(sport->clk_ipg);
|
||||
|
||||
error_console:
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -823,6 +823,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
|
|||
vp->cb_break_before = afs_calc_vnode_cb_break(vnode);
|
||||
vp->vnode = vnode;
|
||||
vp->put_vnode = true;
|
||||
vp->speculative = true; /* vnode not locked */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,6 +294,13 @@ void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *v
|
|||
op->flags &= ~AFS_OPERATION_DIR_CONFLICT;
|
||||
}
|
||||
} else if (vp->scb.have_status) {
|
||||
if (vp->dv_before + vp->dv_delta != vp->scb.status.data_version &&
|
||||
vp->speculative)
|
||||
/* Ignore the result of a speculative bulk status fetch
|
||||
* if it splits around a modification op, thereby
|
||||
* appearing to regress the data version.
|
||||
*/
|
||||
goto out;
|
||||
afs_apply_status(op, vp);
|
||||
if (vp->scb.have_cb)
|
||||
afs_apply_callback(op, vp);
|
||||
|
|
@ -305,6 +312,7 @@ void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *v
|
|||
}
|
||||
}
|
||||
|
||||
out:
|
||||
write_sequnlock(&vnode->cb_lock);
|
||||
|
||||
if (vp->scb.have_status)
|
||||
|
|
|
|||
|
|
@ -755,6 +755,7 @@ struct afs_vnode_param {
|
|||
bool update_ctime:1; /* Need to update the ctime */
|
||||
bool set_size:1; /* Must update i_size */
|
||||
bool op_unlinked:1; /* True if file was unlinked by op */
|
||||
bool speculative:1; /* T if speculative status fetch (no vnode lock) */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ LIST_HEAD(efivarfs_list);
|
|||
static void efivarfs_evict_inode(struct inode *inode)
|
||||
{
|
||||
clear_inode(inode);
|
||||
kfree(inode->i_private);
|
||||
}
|
||||
|
||||
static const struct super_operations efivarfs_ops = {
|
||||
|
|
|
|||
|
|
@ -2740,7 +2740,8 @@ void ext4_insert_dentry(struct inode *dir, struct inode *inode,
|
|||
struct ext4_filename *fname);
|
||||
static inline void ext4_update_dx_flag(struct inode *inode)
|
||||
{
|
||||
if (!ext4_has_feature_dir_index(inode->i_sb)) {
|
||||
if (!ext4_has_feature_dir_index(inode->i_sb) &&
|
||||
ext4_test_inode_flag(inode, EXT4_INODE_INDEX)) {
|
||||
/* ext4_iget() should have caught this... */
|
||||
WARN_ON_ONCE(ext4_has_feature_metadata_csum(inode->i_sb));
|
||||
ext4_clear_inode_flag(inode, EXT4_INODE_INDEX);
|
||||
|
|
|
|||
|
|
@ -2638,10 +2638,6 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
|
|||
} else if (test_opt2(sb, DAX_INODE)) {
|
||||
SEQ_OPTS_PUTS("dax=inode");
|
||||
}
|
||||
|
||||
if (test_opt2(sb, JOURNAL_FAST_COMMIT))
|
||||
SEQ_OPTS_PUTS("fast_commit");
|
||||
|
||||
ext4_show_quota_options(seq, sb);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -566,12 +566,14 @@ static int __jbd2_journal_force_commit(journal_t *journal)
|
|||
}
|
||||
|
||||
/**
|
||||
* Force and wait upon a commit if the calling process is not within
|
||||
* transaction. This is used for forcing out undo-protected data which contains
|
||||
* bitmaps, when the fs is running out of space.
|
||||
* jbd2_journal_force_commit_nested - Force and wait upon a commit if the
|
||||
* calling process is not within transaction.
|
||||
*
|
||||
* @journal: journal to force
|
||||
* Returns true if progress was made.
|
||||
*
|
||||
* This is used for forcing out undo-protected data which contains
|
||||
* bitmaps, when the fs is running out of space.
|
||||
*/
|
||||
int jbd2_journal_force_commit_nested(journal_t *journal)
|
||||
{
|
||||
|
|
@ -582,7 +584,7 @@ int jbd2_journal_force_commit_nested(journal_t *journal)
|
|||
}
|
||||
|
||||
/**
|
||||
* int journal_force_commit() - force any uncommitted transactions
|
||||
* jbd2_journal_force_commit() - force any uncommitted transactions
|
||||
* @journal: journal to force
|
||||
*
|
||||
* Caller want unconditional commit. We can only force the running transaction
|
||||
|
|
@ -1881,7 +1883,7 @@ static int load_superblock(journal_t *journal)
|
|||
|
||||
|
||||
/**
|
||||
* int jbd2_journal_load() - Read journal from disk.
|
||||
* jbd2_journal_load() - Read journal from disk.
|
||||
* @journal: Journal to act on.
|
||||
*
|
||||
* Given a journal_t structure which tells us which disk blocks contain
|
||||
|
|
@ -1951,7 +1953,7 @@ int jbd2_journal_load(journal_t *journal)
|
|||
}
|
||||
|
||||
/**
|
||||
* void jbd2_journal_destroy() - Release a journal_t structure.
|
||||
* jbd2_journal_destroy() - Release a journal_t structure.
|
||||
* @journal: Journal to act on.
|
||||
*
|
||||
* Release a journal_t structure once it is no longer in use by the
|
||||
|
|
@ -2028,7 +2030,7 @@ int jbd2_journal_destroy(journal_t *journal)
|
|||
|
||||
|
||||
/**
|
||||
*int jbd2_journal_check_used_features() - Check if features specified are used.
|
||||
* jbd2_journal_check_used_features() - Check if features specified are used.
|
||||
* @journal: Journal to check.
|
||||
* @compat: bitmask of compatible features
|
||||
* @ro: bitmask of features that force read-only mount
|
||||
|
|
@ -2063,7 +2065,7 @@ int jbd2_journal_check_used_features(journal_t *journal, unsigned long compat,
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_check_available_features() - Check feature set in journalling layer
|
||||
* jbd2_journal_check_available_features() - Check feature set in journalling layer
|
||||
* @journal: Journal to check.
|
||||
* @compat: bitmask of compatible features
|
||||
* @ro: bitmask of features that force read-only mount
|
||||
|
|
@ -2126,7 +2128,7 @@ jbd2_journal_initialize_fast_commit(journal_t *journal)
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_set_features() - Mark a given journal feature in the superblock
|
||||
* jbd2_journal_set_features() - Mark a given journal feature in the superblock
|
||||
* @journal: Journal to act on.
|
||||
* @compat: bitmask of compatible features
|
||||
* @ro: bitmask of features that force read-only mount
|
||||
|
|
@ -2217,7 +2219,7 @@ int jbd2_journal_set_features(journal_t *journal, unsigned long compat,
|
|||
}
|
||||
|
||||
/*
|
||||
* jbd2_journal_clear_features () - Clear a given journal feature in the
|
||||
* jbd2_journal_clear_features() - Clear a given journal feature in the
|
||||
* superblock
|
||||
* @journal: Journal to act on.
|
||||
* @compat: bitmask of compatible features
|
||||
|
|
@ -2246,7 +2248,7 @@ void jbd2_journal_clear_features(journal_t *journal, unsigned long compat,
|
|||
EXPORT_SYMBOL(jbd2_journal_clear_features);
|
||||
|
||||
/**
|
||||
* int jbd2_journal_flush () - Flush journal
|
||||
* jbd2_journal_flush() - Flush journal
|
||||
* @journal: Journal to act on.
|
||||
*
|
||||
* Flush all data for a given journal to disk and empty the journal.
|
||||
|
|
@ -2321,7 +2323,7 @@ int jbd2_journal_flush(journal_t *journal)
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_wipe() - Wipe journal contents
|
||||
* jbd2_journal_wipe() - Wipe journal contents
|
||||
* @journal: Journal to act on.
|
||||
* @write: flag (see below)
|
||||
*
|
||||
|
|
@ -2362,7 +2364,7 @@ int jbd2_journal_wipe(journal_t *journal, int write)
|
|||
}
|
||||
|
||||
/**
|
||||
* void jbd2_journal_abort () - Shutdown the journal immediately.
|
||||
* jbd2_journal_abort () - Shutdown the journal immediately.
|
||||
* @journal: the journal to shutdown.
|
||||
* @errno: an error number to record in the journal indicating
|
||||
* the reason for the shutdown.
|
||||
|
|
@ -2453,7 +2455,7 @@ void jbd2_journal_abort(journal_t *journal, int errno)
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_errno () - returns the journal's error state.
|
||||
* jbd2_journal_errno() - returns the journal's error state.
|
||||
* @journal: journal to examine.
|
||||
*
|
||||
* This is the errno number set with jbd2_journal_abort(), the last
|
||||
|
|
@ -2477,7 +2479,7 @@ int jbd2_journal_errno(journal_t *journal)
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_clear_err () - clears the journal's error state
|
||||
* jbd2_journal_clear_err() - clears the journal's error state
|
||||
* @journal: journal to act on.
|
||||
*
|
||||
* An error must be cleared or acked to take a FS out of readonly
|
||||
|
|
@ -2497,7 +2499,7 @@ int jbd2_journal_clear_err(journal_t *journal)
|
|||
}
|
||||
|
||||
/**
|
||||
* void jbd2_journal_ack_err() - Ack journal err.
|
||||
* jbd2_journal_ack_err() - Ack journal err.
|
||||
* @journal: journal to act on.
|
||||
*
|
||||
* An error must be cleared or acked to take a FS out of readonly
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ EXPORT_SYMBOL(jbd2__journal_start);
|
|||
|
||||
|
||||
/**
|
||||
* handle_t *jbd2_journal_start() - Obtain a new handle.
|
||||
* jbd2_journal_start() - Obtain a new handle.
|
||||
* @journal: Journal to start transaction on.
|
||||
* @nblocks: number of block buffer we might modify
|
||||
*
|
||||
|
|
@ -566,7 +566,7 @@ void jbd2_journal_free_reserved(handle_t *handle)
|
|||
EXPORT_SYMBOL(jbd2_journal_free_reserved);
|
||||
|
||||
/**
|
||||
* int jbd2_journal_start_reserved() - start reserved handle
|
||||
* jbd2_journal_start_reserved() - start reserved handle
|
||||
* @handle: handle to start
|
||||
* @type: for handle statistics
|
||||
* @line_no: for handle statistics
|
||||
|
|
@ -620,7 +620,7 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type,
|
|||
EXPORT_SYMBOL(jbd2_journal_start_reserved);
|
||||
|
||||
/**
|
||||
* int jbd2_journal_extend() - extend buffer credits.
|
||||
* jbd2_journal_extend() - extend buffer credits.
|
||||
* @handle: handle to 'extend'
|
||||
* @nblocks: nr blocks to try to extend by.
|
||||
* @revoke_records: number of revoke records to try to extend by.
|
||||
|
|
@ -745,7 +745,7 @@ static void stop_this_handle(handle_t *handle)
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_restart() - restart a handle .
|
||||
* jbd2__journal_restart() - restart a handle .
|
||||
* @handle: handle to restart
|
||||
* @nblocks: nr credits requested
|
||||
* @revoke_records: number of revoke record credits requested
|
||||
|
|
@ -815,7 +815,7 @@ int jbd2_journal_restart(handle_t *handle, int nblocks)
|
|||
EXPORT_SYMBOL(jbd2_journal_restart);
|
||||
|
||||
/**
|
||||
* void jbd2_journal_lock_updates () - establish a transaction barrier.
|
||||
* jbd2_journal_lock_updates () - establish a transaction barrier.
|
||||
* @journal: Journal to establish a barrier on.
|
||||
*
|
||||
* This locks out any further updates from being started, and blocks
|
||||
|
|
@ -874,7 +874,7 @@ void jbd2_journal_lock_updates(journal_t *journal)
|
|||
}
|
||||
|
||||
/**
|
||||
* void jbd2_journal_unlock_updates (journal_t* journal) - release barrier
|
||||
* jbd2_journal_unlock_updates () - release barrier
|
||||
* @journal: Journal to release the barrier on.
|
||||
*
|
||||
* Release a transaction barrier obtained with jbd2_journal_lock_updates().
|
||||
|
|
@ -1182,7 +1182,8 @@ static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh,
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update.
|
||||
* jbd2_journal_get_write_access() - notify intent to modify a buffer
|
||||
* for metadata (not data) update.
|
||||
* @handle: transaction to add buffer modifications to
|
||||
* @bh: bh to be used for metadata writes
|
||||
*
|
||||
|
|
@ -1226,7 +1227,7 @@ int jbd2_journal_get_write_access(handle_t *handle, struct buffer_head *bh)
|
|||
* unlocked buffer beforehand. */
|
||||
|
||||
/**
|
||||
* int jbd2_journal_get_create_access () - notify intent to use newly created bh
|
||||
* jbd2_journal_get_create_access () - notify intent to use newly created bh
|
||||
* @handle: transaction to new buffer to
|
||||
* @bh: new buffer.
|
||||
*
|
||||
|
|
@ -1306,7 +1307,7 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_get_undo_access() - Notify intent to modify metadata with
|
||||
* jbd2_journal_get_undo_access() - Notify intent to modify metadata with
|
||||
* non-rewindable consequences
|
||||
* @handle: transaction
|
||||
* @bh: buffer to undo
|
||||
|
|
@ -1383,7 +1384,7 @@ int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh)
|
|||
}
|
||||
|
||||
/**
|
||||
* void jbd2_journal_set_triggers() - Add triggers for commit writeout
|
||||
* jbd2_journal_set_triggers() - Add triggers for commit writeout
|
||||
* @bh: buffer to trigger on
|
||||
* @type: struct jbd2_buffer_trigger_type containing the trigger(s).
|
||||
*
|
||||
|
|
@ -1425,7 +1426,7 @@ void jbd2_buffer_abort_trigger(struct journal_head *jh,
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata
|
||||
* jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata
|
||||
* @handle: transaction to add buffer to.
|
||||
* @bh: buffer to mark
|
||||
*
|
||||
|
|
@ -1593,7 +1594,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
|
|||
}
|
||||
|
||||
/**
|
||||
* void jbd2_journal_forget() - bforget() for potentially-journaled buffers.
|
||||
* jbd2_journal_forget() - bforget() for potentially-journaled buffers.
|
||||
* @handle: transaction handle
|
||||
* @bh: bh to 'forget'
|
||||
*
|
||||
|
|
@ -1762,7 +1763,7 @@ int jbd2_journal_forget(handle_t *handle, struct buffer_head *bh)
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_stop() - complete a transaction
|
||||
* jbd2_journal_stop() - complete a transaction
|
||||
* @handle: transaction to complete.
|
||||
*
|
||||
* All done for a particular handle.
|
||||
|
|
@ -2080,7 +2081,7 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
|
|||
}
|
||||
|
||||
/**
|
||||
* int jbd2_journal_try_to_free_buffers() - try to free page buffers.
|
||||
* jbd2_journal_try_to_free_buffers() - try to free page buffers.
|
||||
* @journal: journal for operation
|
||||
* @page: to try and free
|
||||
*
|
||||
|
|
@ -2411,7 +2412,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,
|
|||
}
|
||||
|
||||
/**
|
||||
* void jbd2_journal_invalidatepage()
|
||||
* jbd2_journal_invalidatepage()
|
||||
* @journal: journal to use for flush...
|
||||
* @page: page to flush
|
||||
* @offset: start of the range to invalidate
|
||||
|
|
|
|||
|
|
@ -959,7 +959,7 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
|
|||
size_t len, loff_t *ppos)
|
||||
{
|
||||
struct simple_attr *attr;
|
||||
u64 val;
|
||||
unsigned long long val;
|
||||
size_t size;
|
||||
ssize_t ret;
|
||||
|
||||
|
|
@ -977,7 +977,9 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
|
|||
goto out;
|
||||
|
||||
attr->set_buf[size] = '\0';
|
||||
val = simple_strtoll(attr->set_buf, NULL, 0);
|
||||
ret = kstrtoull(attr->set_buf, 0, &val);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = attr->set(attr->data, val);
|
||||
if (ret == 0)
|
||||
ret = len; /* on success, claim we got the whole input */
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@
|
|||
+ __clang_patchlevel__)
|
||||
|
||||
#if CLANG_VERSION < 100001
|
||||
#ifndef __BPF_TRACING__
|
||||
# error Sorry, your version of Clang is too old - please use 10.0.1 or newer.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Compiler specific definitions for Clang compiler */
|
||||
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh)
|
|||
#define JI_WAIT_DATA (1 << __JI_WAIT_DATA)
|
||||
|
||||
/**
|
||||
* struct jbd_inode - The jbd_inode type is the structure linking inodes in
|
||||
* struct jbd2_inode - The jbd_inode type is the structure linking inodes in
|
||||
* ordered mode present in a transaction so that we can sync them during commit.
|
||||
*/
|
||||
struct jbd2_inode {
|
||||
|
|
|
|||
|
|
@ -281,20 +281,6 @@ static inline bool movable_node_is_enabled(void)
|
|||
}
|
||||
#endif /* ! CONFIG_MEMORY_HOTPLUG */
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
extern int memory_add_physaddr_to_nid(u64 start);
|
||||
extern int phys_to_target_node(u64 start);
|
||||
#else
|
||||
static inline int memory_add_physaddr_to_nid(u64 start)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int phys_to_target_node(u64 start)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT)
|
||||
/*
|
||||
* pgdat resizing functions
|
||||
|
|
|
|||
|
|
@ -21,13 +21,41 @@
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
#include <linux/printk.h>
|
||||
#include <asm/sparsemem.h>
|
||||
|
||||
/* Generic implementation available */
|
||||
int numa_map_to_online_node(int node);
|
||||
#else
|
||||
|
||||
#ifndef memory_add_physaddr_to_nid
|
||||
static inline int memory_add_physaddr_to_nid(u64 start)
|
||||
{
|
||||
pr_info_once("Unknown online node for memory at 0x%llx, assuming node 0\n",
|
||||
start);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef phys_to_target_node
|
||||
static inline int phys_to_target_node(u64 start)
|
||||
{
|
||||
pr_info_once("Unknown target node for memory at 0x%llx, assuming node 0\n",
|
||||
start);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#else /* !CONFIG_NUMA */
|
||||
static inline int numa_map_to_online_node(int node)
|
||||
{
|
||||
return NUMA_NO_NODE;
|
||||
}
|
||||
static inline int memory_add_physaddr_to_nid(u64 start)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int phys_to_target_node(u64 start)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LINUX_NUMA_H */
|
||||
|
|
|
|||
|
|
@ -906,6 +906,8 @@ static inline unsigned int __readahead_batch(struct readahead_control *rac,
|
|||
xas_set(&xas, rac->_index);
|
||||
rcu_read_lock();
|
||||
xas_for_each(&xas, page, rac->_index + rac->_nr_pages - 1) {
|
||||
if (xas_retry(&xas, page))
|
||||
continue;
|
||||
VM_BUG_ON_PAGE(!PageLocked(page), page);
|
||||
VM_BUG_ON_PAGE(PageTail(page), page);
|
||||
array[i++] = page;
|
||||
|
|
|
|||
|
|
@ -553,7 +553,6 @@ struct sched_dl_entity {
|
|||
* overruns.
|
||||
*/
|
||||
unsigned int dl_throttled : 1;
|
||||
unsigned int dl_boosted : 1;
|
||||
unsigned int dl_yielded : 1;
|
||||
unsigned int dl_non_contending : 1;
|
||||
unsigned int dl_overrun : 1;
|
||||
|
|
@ -572,6 +571,15 @@ struct sched_dl_entity {
|
|||
* time.
|
||||
*/
|
||||
struct hrtimer inactive_timer;
|
||||
|
||||
#ifdef CONFIG_RT_MUTEXES
|
||||
/*
|
||||
* Priority Inheritance. When a DEADLINE scheduling entity is boosted
|
||||
* pi_se points to the donor, otherwise points to the dl_se it belongs
|
||||
* to (the original one/itself).
|
||||
*/
|
||||
struct sched_dl_entity *pi_se;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_UCLAMP_TASK
|
||||
|
|
@ -771,7 +779,6 @@ struct task_struct {
|
|||
unsigned sched_reset_on_fork:1;
|
||||
unsigned sched_contributes_to_load:1;
|
||||
unsigned sched_migrated:1;
|
||||
unsigned sched_remote_wakeup:1;
|
||||
#ifdef CONFIG_PSI
|
||||
unsigned sched_psi_wake_requeue:1;
|
||||
#endif
|
||||
|
|
@ -781,6 +788,21 @@ struct task_struct {
|
|||
|
||||
/* Unserialized, strictly 'current' */
|
||||
|
||||
/*
|
||||
* This field must not be in the scheduler word above due to wakelist
|
||||
* queueing no longer being serialized by p->on_cpu. However:
|
||||
*
|
||||
* p->XXX = X; ttwu()
|
||||
* schedule() if (p->on_rq && ..) // false
|
||||
* smp_mb__after_spinlock(); if (smp_load_acquire(&p->on_cpu) && //true
|
||||
* deactivate_task() ttwu_queue_wakelist())
|
||||
* p->on_rq = 0; p->sched_remote_wakeup = Y;
|
||||
*
|
||||
* guarantees all stores of 'current' are visible before
|
||||
* ->sched_remote_wakeup gets used, so it can be in this word.
|
||||
*/
|
||||
unsigned sched_remote_wakeup:1;
|
||||
|
||||
/* Bit to tell LSMs we're in execve(): */
|
||||
unsigned in_execve:1;
|
||||
unsigned in_iowait:1;
|
||||
|
|
|
|||
|
|
@ -108,19 +108,21 @@ static inline void lockdep_lock(void)
|
|||
{
|
||||
DEBUG_LOCKS_WARN_ON(!irqs_disabled());
|
||||
|
||||
__this_cpu_inc(lockdep_recursion);
|
||||
arch_spin_lock(&__lock);
|
||||
__owner = current;
|
||||
__this_cpu_inc(lockdep_recursion);
|
||||
}
|
||||
|
||||
static inline void lockdep_unlock(void)
|
||||
{
|
||||
DEBUG_LOCKS_WARN_ON(!irqs_disabled());
|
||||
|
||||
if (debug_locks && DEBUG_LOCKS_WARN_ON(__owner != current))
|
||||
return;
|
||||
|
||||
__this_cpu_dec(lockdep_recursion);
|
||||
__owner = NULL;
|
||||
arch_spin_unlock(&__lock);
|
||||
__this_cpu_dec(lockdep_recursion);
|
||||
}
|
||||
|
||||
static inline bool lockdep_assert_locked(void)
|
||||
|
|
|
|||
|
|
@ -2517,7 +2517,12 @@ ttwu_do_activate(struct rq *rq, struct task_struct *p, int wake_flags,
|
|||
#ifdef CONFIG_SMP
|
||||
if (wake_flags & WF_MIGRATED)
|
||||
en_flags |= ENQUEUE_MIGRATED;
|
||||
else
|
||||
#endif
|
||||
if (p->in_iowait) {
|
||||
delayacct_blkio_end(p);
|
||||
atomic_dec(&task_rq(p)->nr_iowait);
|
||||
}
|
||||
|
||||
activate_task(rq, p, en_flags);
|
||||
ttwu_do_wakeup(rq, p, wake_flags, rf);
|
||||
|
|
@ -2905,11 +2910,6 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
|
|||
if (READ_ONCE(p->on_rq) && ttwu_runnable(p, wake_flags))
|
||||
goto unlock;
|
||||
|
||||
if (p->in_iowait) {
|
||||
delayacct_blkio_end(p);
|
||||
atomic_dec(&task_rq(p)->nr_iowait);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Ensure we load p->on_cpu _after_ p->on_rq, otherwise it would be
|
||||
|
|
@ -2980,6 +2980,11 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
|
|||
|
||||
cpu = select_task_rq(p, p->wake_cpu, SD_BALANCE_WAKE, wake_flags);
|
||||
if (task_cpu(p) != cpu) {
|
||||
if (p->in_iowait) {
|
||||
delayacct_blkio_end(p);
|
||||
atomic_dec(&task_rq(p)->nr_iowait);
|
||||
}
|
||||
|
||||
wake_flags |= WF_MIGRATED;
|
||||
psi_ttwu_dequeue(p);
|
||||
set_task_cpu(p, cpu);
|
||||
|
|
@ -4929,20 +4934,21 @@ void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task)
|
|||
if (!dl_prio(p->normal_prio) ||
|
||||
(pi_task && dl_prio(pi_task->prio) &&
|
||||
dl_entity_preempt(&pi_task->dl, &p->dl))) {
|
||||
p->dl.dl_boosted = 1;
|
||||
p->dl.pi_se = pi_task->dl.pi_se;
|
||||
queue_flag |= ENQUEUE_REPLENISH;
|
||||
} else
|
||||
p->dl.dl_boosted = 0;
|
||||
} else {
|
||||
p->dl.pi_se = &p->dl;
|
||||
}
|
||||
p->sched_class = &dl_sched_class;
|
||||
} else if (rt_prio(prio)) {
|
||||
if (dl_prio(oldprio))
|
||||
p->dl.dl_boosted = 0;
|
||||
p->dl.pi_se = &p->dl;
|
||||
if (oldprio < prio)
|
||||
queue_flag |= ENQUEUE_HEAD;
|
||||
p->sched_class = &rt_sched_class;
|
||||
} else {
|
||||
if (dl_prio(oldprio))
|
||||
p->dl.dl_boosted = 0;
|
||||
p->dl.pi_se = &p->dl;
|
||||
if (rt_prio(oldprio))
|
||||
p->rt.timeout = 0;
|
||||
p->sched_class = &fair_sched_class;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,28 @@ static inline int on_dl_rq(struct sched_dl_entity *dl_se)
|
|||
return !RB_EMPTY_NODE(&dl_se->rb_node);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT_MUTEXES
|
||||
static inline struct sched_dl_entity *pi_of(struct sched_dl_entity *dl_se)
|
||||
{
|
||||
return dl_se->pi_se;
|
||||
}
|
||||
|
||||
static inline bool is_dl_boosted(struct sched_dl_entity *dl_se)
|
||||
{
|
||||
return pi_of(dl_se) != dl_se;
|
||||
}
|
||||
#else
|
||||
static inline struct sched_dl_entity *pi_of(struct sched_dl_entity *dl_se)
|
||||
{
|
||||
return dl_se;
|
||||
}
|
||||
|
||||
static inline bool is_dl_boosted(struct sched_dl_entity *dl_se)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static inline struct dl_bw *dl_bw_of(int i)
|
||||
{
|
||||
|
|
@ -698,7 +720,7 @@ static inline void setup_new_dl_entity(struct sched_dl_entity *dl_se)
|
|||
struct dl_rq *dl_rq = dl_rq_of_se(dl_se);
|
||||
struct rq *rq = rq_of_dl_rq(dl_rq);
|
||||
|
||||
WARN_ON(dl_se->dl_boosted);
|
||||
WARN_ON(is_dl_boosted(dl_se));
|
||||
WARN_ON(dl_time_before(rq_clock(rq), dl_se->deadline));
|
||||
|
||||
/*
|
||||
|
|
@ -736,21 +758,20 @@ static inline void setup_new_dl_entity(struct sched_dl_entity *dl_se)
|
|||
* could happen are, typically, a entity voluntarily trying to overcome its
|
||||
* runtime, or it just underestimated it during sched_setattr().
|
||||
*/
|
||||
static void replenish_dl_entity(struct sched_dl_entity *dl_se,
|
||||
struct sched_dl_entity *pi_se)
|
||||
static void replenish_dl_entity(struct sched_dl_entity *dl_se)
|
||||
{
|
||||
struct dl_rq *dl_rq = dl_rq_of_se(dl_se);
|
||||
struct rq *rq = rq_of_dl_rq(dl_rq);
|
||||
|
||||
BUG_ON(pi_se->dl_runtime <= 0);
|
||||
BUG_ON(pi_of(dl_se)->dl_runtime <= 0);
|
||||
|
||||
/*
|
||||
* This could be the case for a !-dl task that is boosted.
|
||||
* Just go with full inherited parameters.
|
||||
*/
|
||||
if (dl_se->dl_deadline == 0) {
|
||||
dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline;
|
||||
dl_se->runtime = pi_se->dl_runtime;
|
||||
dl_se->deadline = rq_clock(rq) + pi_of(dl_se)->dl_deadline;
|
||||
dl_se->runtime = pi_of(dl_se)->dl_runtime;
|
||||
}
|
||||
|
||||
if (dl_se->dl_yielded && dl_se->runtime > 0)
|
||||
|
|
@ -763,8 +784,8 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se,
|
|||
* arbitrary large.
|
||||
*/
|
||||
while (dl_se->runtime <= 0) {
|
||||
dl_se->deadline += pi_se->dl_period;
|
||||
dl_se->runtime += pi_se->dl_runtime;
|
||||
dl_se->deadline += pi_of(dl_se)->dl_period;
|
||||
dl_se->runtime += pi_of(dl_se)->dl_runtime;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -778,8 +799,8 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se,
|
|||
*/
|
||||
if (dl_time_before(dl_se->deadline, rq_clock(rq))) {
|
||||
printk_deferred_once("sched: DL replenish lagged too much\n");
|
||||
dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline;
|
||||
dl_se->runtime = pi_se->dl_runtime;
|
||||
dl_se->deadline = rq_clock(rq) + pi_of(dl_se)->dl_deadline;
|
||||
dl_se->runtime = pi_of(dl_se)->dl_runtime;
|
||||
}
|
||||
|
||||
if (dl_se->dl_yielded)
|
||||
|
|
@ -812,8 +833,7 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se,
|
|||
* task with deadline equal to period this is the same of using
|
||||
* dl_period instead of dl_deadline in the equation above.
|
||||
*/
|
||||
static bool dl_entity_overflow(struct sched_dl_entity *dl_se,
|
||||
struct sched_dl_entity *pi_se, u64 t)
|
||||
static bool dl_entity_overflow(struct sched_dl_entity *dl_se, u64 t)
|
||||
{
|
||||
u64 left, right;
|
||||
|
||||
|
|
@ -835,9 +855,9 @@ static bool dl_entity_overflow(struct sched_dl_entity *dl_se,
|
|||
* of anything below microseconds resolution is actually fiction
|
||||
* (but still we want to give the user that illusion >;).
|
||||
*/
|
||||
left = (pi_se->dl_deadline >> DL_SCALE) * (dl_se->runtime >> DL_SCALE);
|
||||
left = (pi_of(dl_se)->dl_deadline >> DL_SCALE) * (dl_se->runtime >> DL_SCALE);
|
||||
right = ((dl_se->deadline - t) >> DL_SCALE) *
|
||||
(pi_se->dl_runtime >> DL_SCALE);
|
||||
(pi_of(dl_se)->dl_runtime >> DL_SCALE);
|
||||
|
||||
return dl_time_before(right, left);
|
||||
}
|
||||
|
|
@ -922,24 +942,23 @@ static inline bool dl_is_implicit(struct sched_dl_entity *dl_se)
|
|||
* Please refer to the comments update_dl_revised_wakeup() function to find
|
||||
* more about the Revised CBS rule.
|
||||
*/
|
||||
static void update_dl_entity(struct sched_dl_entity *dl_se,
|
||||
struct sched_dl_entity *pi_se)
|
||||
static void update_dl_entity(struct sched_dl_entity *dl_se)
|
||||
{
|
||||
struct dl_rq *dl_rq = dl_rq_of_se(dl_se);
|
||||
struct rq *rq = rq_of_dl_rq(dl_rq);
|
||||
|
||||
if (dl_time_before(dl_se->deadline, rq_clock(rq)) ||
|
||||
dl_entity_overflow(dl_se, pi_se, rq_clock(rq))) {
|
||||
dl_entity_overflow(dl_se, rq_clock(rq))) {
|
||||
|
||||
if (unlikely(!dl_is_implicit(dl_se) &&
|
||||
!dl_time_before(dl_se->deadline, rq_clock(rq)) &&
|
||||
!dl_se->dl_boosted)){
|
||||
!is_dl_boosted(dl_se))) {
|
||||
update_dl_revised_wakeup(dl_se, rq);
|
||||
return;
|
||||
}
|
||||
|
||||
dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline;
|
||||
dl_se->runtime = pi_se->dl_runtime;
|
||||
dl_se->deadline = rq_clock(rq) + pi_of(dl_se)->dl_deadline;
|
||||
dl_se->runtime = pi_of(dl_se)->dl_runtime;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1038,7 +1057,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
|
|||
* The task might have been boosted by someone else and might be in the
|
||||
* boosting/deboosting path, its not throttled.
|
||||
*/
|
||||
if (dl_se->dl_boosted)
|
||||
if (is_dl_boosted(dl_se))
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
|
|
@ -1066,7 +1085,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
|
|||
* but do not enqueue -- wait for our wakeup to do that.
|
||||
*/
|
||||
if (!task_on_rq_queued(p)) {
|
||||
replenish_dl_entity(dl_se, dl_se);
|
||||
replenish_dl_entity(dl_se);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
|
|
@ -1156,7 +1175,7 @@ static inline void dl_check_constrained_dl(struct sched_dl_entity *dl_se)
|
|||
|
||||
if (dl_time_before(dl_se->deadline, rq_clock(rq)) &&
|
||||
dl_time_before(rq_clock(rq), dl_next_period(dl_se))) {
|
||||
if (unlikely(dl_se->dl_boosted || !start_dl_timer(p)))
|
||||
if (unlikely(is_dl_boosted(dl_se) || !start_dl_timer(p)))
|
||||
return;
|
||||
dl_se->dl_throttled = 1;
|
||||
if (dl_se->runtime > 0)
|
||||
|
|
@ -1287,7 +1306,7 @@ static void update_curr_dl(struct rq *rq)
|
|||
dl_se->dl_overrun = 1;
|
||||
|
||||
__dequeue_task_dl(rq, curr, 0);
|
||||
if (unlikely(dl_se->dl_boosted || !start_dl_timer(curr)))
|
||||
if (unlikely(is_dl_boosted(dl_se) || !start_dl_timer(curr)))
|
||||
enqueue_task_dl(rq, curr, ENQUEUE_REPLENISH);
|
||||
|
||||
if (!is_leftmost(curr, &rq->dl))
|
||||
|
|
@ -1481,8 +1500,7 @@ static void __dequeue_dl_entity(struct sched_dl_entity *dl_se)
|
|||
}
|
||||
|
||||
static void
|
||||
enqueue_dl_entity(struct sched_dl_entity *dl_se,
|
||||
struct sched_dl_entity *pi_se, int flags)
|
||||
enqueue_dl_entity(struct sched_dl_entity *dl_se, int flags)
|
||||
{
|
||||
BUG_ON(on_dl_rq(dl_se));
|
||||
|
||||
|
|
@ -1493,9 +1511,9 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se,
|
|||
*/
|
||||
if (flags & ENQUEUE_WAKEUP) {
|
||||
task_contending(dl_se, flags);
|
||||
update_dl_entity(dl_se, pi_se);
|
||||
update_dl_entity(dl_se);
|
||||
} else if (flags & ENQUEUE_REPLENISH) {
|
||||
replenish_dl_entity(dl_se, pi_se);
|
||||
replenish_dl_entity(dl_se);
|
||||
} else if ((flags & ENQUEUE_RESTORE) &&
|
||||
dl_time_before(dl_se->deadline,
|
||||
rq_clock(rq_of_dl_rq(dl_rq_of_se(dl_se))))) {
|
||||
|
|
@ -1512,19 +1530,7 @@ static void dequeue_dl_entity(struct sched_dl_entity *dl_se)
|
|||
|
||||
static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)
|
||||
{
|
||||
struct task_struct *pi_task = rt_mutex_get_top_task(p);
|
||||
struct sched_dl_entity *pi_se = &p->dl;
|
||||
|
||||
/*
|
||||
* Use the scheduling parameters of the top pi-waiter task if:
|
||||
* - we have a top pi-waiter which is a SCHED_DEADLINE task AND
|
||||
* - our dl_boosted is set (i.e. the pi-waiter's (absolute) deadline is
|
||||
* smaller than our deadline OR we are a !SCHED_DEADLINE task getting
|
||||
* boosted due to a SCHED_DEADLINE pi-waiter).
|
||||
* Otherwise we keep our runtime and deadline.
|
||||
*/
|
||||
if (pi_task && dl_prio(pi_task->normal_prio) && p->dl.dl_boosted) {
|
||||
pi_se = &pi_task->dl;
|
||||
if (is_dl_boosted(&p->dl)) {
|
||||
/*
|
||||
* Because of delays in the detection of the overrun of a
|
||||
* thread's runtime, it might be the case that a thread
|
||||
|
|
@ -1557,7 +1563,7 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)
|
|||
* the throttle.
|
||||
*/
|
||||
p->dl.dl_throttled = 0;
|
||||
BUG_ON(!p->dl.dl_boosted || flags != ENQUEUE_REPLENISH);
|
||||
BUG_ON(!is_dl_boosted(&p->dl) || flags != ENQUEUE_REPLENISH);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1594,7 +1600,7 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)
|
|||
return;
|
||||
}
|
||||
|
||||
enqueue_dl_entity(&p->dl, pi_se, flags);
|
||||
enqueue_dl_entity(&p->dl, flags);
|
||||
|
||||
if (!task_current(rq, p) && p->nr_cpus_allowed > 1)
|
||||
enqueue_pushable_dl_task(rq, p);
|
||||
|
|
@ -2787,11 +2793,14 @@ void __dl_clear_params(struct task_struct *p)
|
|||
dl_se->dl_bw = 0;
|
||||
dl_se->dl_density = 0;
|
||||
|
||||
dl_se->dl_boosted = 0;
|
||||
dl_se->dl_throttled = 0;
|
||||
dl_se->dl_yielded = 0;
|
||||
dl_se->dl_non_contending = 0;
|
||||
dl_se->dl_overrun = 0;
|
||||
|
||||
#ifdef CONFIG_RT_MUTEXES
|
||||
dl_se->pi_se = dl_se;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr)
|
||||
|
|
|
|||
|
|
@ -5480,6 +5480,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
|||
struct cfs_rq *cfs_rq;
|
||||
struct sched_entity *se = &p->se;
|
||||
int idle_h_nr_running = task_has_idle_policy(p);
|
||||
int task_new = !(flags & ENQUEUE_WAKEUP);
|
||||
|
||||
/*
|
||||
* The code below (indirectly) updates schedutil which looks at
|
||||
|
|
@ -5552,7 +5553,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
|||
* into account, but that is not straightforward to implement,
|
||||
* and the following generally works well enough in practice.
|
||||
*/
|
||||
if (flags & ENQUEUE_WAKEUP)
|
||||
if (!task_new)
|
||||
update_overutilized_status(rq);
|
||||
|
||||
enqueue_throttle:
|
||||
|
|
|
|||
|
|
@ -710,7 +710,6 @@ vm_fault_t do_huge_pmd_anonymous_page(struct vm_fault *vmf)
|
|||
transparent_hugepage_use_zero_page()) {
|
||||
pgtable_t pgtable;
|
||||
struct page *zero_page;
|
||||
bool set;
|
||||
vm_fault_t ret;
|
||||
pgtable = pte_alloc_one(vma->vm_mm);
|
||||
if (unlikely(!pgtable))
|
||||
|
|
@ -723,25 +722,25 @@ vm_fault_t do_huge_pmd_anonymous_page(struct vm_fault *vmf)
|
|||
}
|
||||
vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);
|
||||
ret = 0;
|
||||
set = false;
|
||||
if (pmd_none(*vmf->pmd)) {
|
||||
ret = check_stable_address_space(vma->vm_mm);
|
||||
if (ret) {
|
||||
spin_unlock(vmf->ptl);
|
||||
pte_free(vma->vm_mm, pgtable);
|
||||
} else if (userfaultfd_missing(vma)) {
|
||||
spin_unlock(vmf->ptl);
|
||||
pte_free(vma->vm_mm, pgtable);
|
||||
ret = handle_userfault(vmf, VM_UFFD_MISSING);
|
||||
VM_BUG_ON(ret & VM_FAULT_FALLBACK);
|
||||
} else {
|
||||
set_huge_zero_page(pgtable, vma->vm_mm, vma,
|
||||
haddr, vmf->pmd, zero_page);
|
||||
spin_unlock(vmf->ptl);
|
||||
set = true;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
spin_unlock(vmf->ptl);
|
||||
if (!set)
|
||||
pte_free(vma->vm_mm, pgtable);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
gfp = alloc_hugepage_direct_gfpmask(vma);
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ static void force_shm_swapin_readahead(struct vm_area_struct *vma,
|
|||
struct address_space *mapping)
|
||||
{
|
||||
XA_STATE(xas, &mapping->i_pages, linear_page_index(vma, start));
|
||||
pgoff_t end_index = end / PAGE_SIZE;
|
||||
pgoff_t end_index = linear_page_index(vma, end + PAGE_SIZE - 1);
|
||||
struct page *page;
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
@ -1231,8 +1231,6 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec,
|
|||
ret = total_len - iov_iter_count(&iter);
|
||||
|
||||
mmput(mm);
|
||||
return ret;
|
||||
|
||||
release_task:
|
||||
put_task_struct(task);
|
||||
put_pid:
|
||||
|
|
|
|||
|
|
@ -867,8 +867,13 @@ void __mod_lruvec_slab_state(void *p, enum node_stat_item idx, int val)
|
|||
rcu_read_lock();
|
||||
memcg = mem_cgroup_from_obj(p);
|
||||
|
||||
/* Untracked pages have no memcg, no lruvec. Update only the node */
|
||||
if (!memcg || memcg == root_mem_cgroup) {
|
||||
/*
|
||||
* Untracked pages have no memcg, no lruvec. Update only the
|
||||
* node. If we reparent the slab objects to the root memcg,
|
||||
* when we free the slab object, we need to update the per-memcg
|
||||
* vmstats to keep it correct for the root memcg.
|
||||
*/
|
||||
if (!memcg) {
|
||||
__mod_node_page_state(pgdat, idx, val);
|
||||
} else {
|
||||
lruvec = mem_cgroup_lruvec(memcg, pgdat);
|
||||
|
|
|
|||
|
|
@ -350,24 +350,6 @@ int __ref __add_pages(int nid, unsigned long pfn, unsigned long nr_pages,
|
|||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
int __weak memory_add_physaddr_to_nid(u64 start)
|
||||
{
|
||||
pr_info_once("Unknown online node for memory at 0x%llx, assuming node 0\n",
|
||||
start);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
|
||||
|
||||
int __weak phys_to_target_node(u64 start)
|
||||
{
|
||||
pr_info_once("Unknown target node for memory at 0x%llx, assuming node 0\n",
|
||||
start);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phys_to_target_node);
|
||||
#endif
|
||||
|
||||
/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
|
||||
static unsigned long find_smallest_section_pfn(int nid, struct zone *zone,
|
||||
unsigned long start_pfn,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user