Merge 06d65a6f64 ("Merge tag 'mips_6.2_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux") into android-mainline
Steps on the way to 6.2-rc1 Change-Id: I2b13f60cea84b31b1e42eb5c00db32f1478260d8 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -35,6 +35,7 @@ properties:
|
||||
- renesas,pwm-r8a77980 # R-Car V3H
|
||||
- renesas,pwm-r8a77990 # R-Car E3
|
||||
- renesas,pwm-r8a77995 # R-Car D3
|
||||
- renesas,pwm-r8a779g0 # R-Car V4H
|
||||
- const: renesas,pwm-rcar
|
||||
|
||||
reg:
|
||||
|
||||
@@ -40,6 +40,7 @@ properties:
|
||||
- renesas,tpu-r8a77970 # R-Car V3M
|
||||
- renesas,tpu-r8a77980 # R-Car V3H
|
||||
- renesas,tpu-r8a779a0 # R-Car V3U
|
||||
- renesas,tpu-r8a779g0 # R-Car V4H
|
||||
- const: renesas,tpu
|
||||
|
||||
reg:
|
||||
|
||||
@@ -25,6 +25,11 @@ versions up to 3.1. File system type to use on mount is *ntfs3*.
|
||||
Note: Applied to empty files, this allows to switch type between
|
||||
sparse(0x200), compressed(0x800) and normal.
|
||||
|
||||
- *system.ntfs_attrib_be* gets/sets ntfs file/dir attributes.
|
||||
|
||||
Same value as system.ntfs_attrib but always represent as big-endian
|
||||
(endianness of system.ntfs_attrib is the same as of the CPU).
|
||||
|
||||
Mount Options
|
||||
=============
|
||||
|
||||
@@ -75,6 +80,20 @@ this table marked with no it means default is without **no**.
|
||||
- Files with the Windows-specific SYSTEM (FILE_ATTRIBUTE_SYSTEM) attribute
|
||||
will be marked as system immutable files.
|
||||
|
||||
* - hide_dot_files
|
||||
- Updates the Windows-specific HIDDEN (FILE_ATTRIBUTE_HIDDEN) attribute
|
||||
when creating and moving or renaming files. Files whose names start
|
||||
with a dot will have the HIDDEN attribute set and files whose names
|
||||
do not start with a dot will have it unset.
|
||||
|
||||
* - windows_names
|
||||
- Prevents the creation of files and directories with a name not allowed
|
||||
by Windows, either because it contains some not allowed character (which
|
||||
are the characters " * / : < > ? \\ | and those whose code is less than
|
||||
0x20), because the name (with or without extension) is a reserved file
|
||||
name (CON, AUX, NUL, PRN, LPT1-9, COM1-9) or because the last character
|
||||
is a space or a dot. Existing such files can still be read and renamed.
|
||||
|
||||
* - discard
|
||||
- Enable support of the TRIM command for improved performance on delete
|
||||
operations, which is recommended for use with the solid-state drives
|
||||
|
||||
@@ -131,8 +131,7 @@ For example, if the function is non-recursive and is called with a
|
||||
spinlock held, maxactive = 1 should be enough. If the function is
|
||||
non-recursive and can never relinquish the CPU (e.g., via a semaphore
|
||||
or preemption), NR_CPUS should be enough. If maxactive <= 0, it is
|
||||
set to a default value. If CONFIG_PREEMPT is enabled, the default
|
||||
is max(10, 2*NR_CPUS). Otherwise, the default is NR_CPUS.
|
||||
set to a default value: max(10, 2*NR_CPUS).
|
||||
|
||||
It's not a disaster if you set maxactive too low; you'll just miss
|
||||
some probes. In the kretprobe struct, the nmissed field is set to
|
||||
|
||||
@@ -58,8 +58,8 @@ Synopsis of kprobe_events
|
||||
NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
|
||||
FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
|
||||
(u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
|
||||
(x8/x16/x32/x64), "string", "ustring" and bitfield
|
||||
are supported.
|
||||
(x8/x16/x32/x64), "string", "ustring", "symbol", "symstr"
|
||||
and bitfield are supported.
|
||||
|
||||
(\*1) only for the probe on function entry (offs == 0).
|
||||
(\*2) only for return probe.
|
||||
@@ -96,6 +96,10 @@ offset, and container-size (usually 32). The syntax is::
|
||||
|
||||
Symbol type('symbol') is an alias of u32 or u64 type (depends on BITS_PER_LONG)
|
||||
which shows given pointer in "symbol+offset" style.
|
||||
On the other hand, symbol-string type ('symstr') converts the given address to
|
||||
"symbol+offset/symbolsize" style and stores it as a null-terminated string.
|
||||
With 'symstr' type, you can filter the event with wildcard pattern of the
|
||||
symbols, and you don't need to solve symbol name by yourself.
|
||||
For $comm, the default type is "string"; any other type is invalid.
|
||||
|
||||
.. _user_mem_access:
|
||||
|
||||
@@ -10885,6 +10885,7 @@ T: git git://git.kernel.dk/liburing
|
||||
F: io_uring/
|
||||
F: include/linux/io_uring.h
|
||||
F: include/linux/io_uring_types.h
|
||||
F: include/trace/events/io_uring.h
|
||||
F: include/uapi/linux/io_uring.h
|
||||
F: tools/io_uring/
|
||||
|
||||
|
||||
@@ -109,6 +109,8 @@
|
||||
compatible = "brcm,bcm7038-twd", "simple-mfd", "syscon";
|
||||
reg = <0x10000080 0x30>;
|
||||
ranges = <0x0 0x10000080 0x30>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
timer@0 {
|
||||
compatible = "brcm,bcm6345-timer";
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -81,7 +82,8 @@ static int __init plat_of_setup(void)
|
||||
__dt_register_buses(soc_info.compatible, "palmbus");
|
||||
|
||||
/* make sure that the reset controller is setup early */
|
||||
ralink_rst_init();
|
||||
if (ralink_soc != MT762X_SOC_MT7621AT)
|
||||
ralink_rst_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
#include <linux/kvm.h>
|
||||
#include <linux/kvm_types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/hwcap.h>
|
||||
#include <asm/kvm_vcpu_fp.h>
|
||||
#include <asm/kvm_vcpu_insn.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
#include <asm/kvm_vcpu_timer.h>
|
||||
|
||||
#define KVM_MAX_VCPUS 1024
|
||||
@@ -95,10 +95,6 @@ struct kvm_arch {
|
||||
struct kvm_guest_timer timer;
|
||||
};
|
||||
|
||||
struct kvm_sbi_context {
|
||||
int return_handled;
|
||||
};
|
||||
|
||||
struct kvm_cpu_trap {
|
||||
unsigned long sepc;
|
||||
unsigned long scause;
|
||||
@@ -169,6 +165,11 @@ struct kvm_vcpu_arch {
|
||||
/* ISA feature bits (similar to MISA) */
|
||||
DECLARE_BITMAP(isa, RISCV_ISA_EXT_MAX);
|
||||
|
||||
/* Vendor, Arch, and Implementation details */
|
||||
unsigned long mvendorid;
|
||||
unsigned long marchid;
|
||||
unsigned long mimpid;
|
||||
|
||||
/* SSCRATCH, STVEC, and SCOUNTEREN of Host */
|
||||
unsigned long host_sscratch;
|
||||
unsigned long host_stvec;
|
||||
@@ -217,7 +218,7 @@ struct kvm_vcpu_arch {
|
||||
struct kvm_csr_decode csr_decode;
|
||||
|
||||
/* SBI context */
|
||||
struct kvm_sbi_context sbi_context;
|
||||
struct kvm_vcpu_sbi_context sbi_context;
|
||||
|
||||
/* Cache pages needed to program page tables with spinlock held */
|
||||
struct kvm_mmu_memory_cache mmu_page_cache;
|
||||
@@ -327,7 +328,4 @@ bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, unsigned long mask);
|
||||
void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu);
|
||||
void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu);
|
||||
|
||||
int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
|
||||
#endif /* __RISCV_KVM_HOST_H__ */
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#define KVM_SBI_VERSION_MAJOR 1
|
||||
#define KVM_SBI_VERSION_MINOR 0
|
||||
|
||||
struct kvm_vcpu_sbi_context {
|
||||
int return_handled;
|
||||
};
|
||||
|
||||
struct kvm_vcpu_sbi_extension {
|
||||
unsigned long extid_start;
|
||||
unsigned long extid_end;
|
||||
@@ -31,7 +35,9 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
|
||||
struct kvm_run *run,
|
||||
u32 type, u64 flags);
|
||||
int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid);
|
||||
int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
|
||||
#ifdef CONFIG_RISCV_SBI_V01
|
||||
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01;
|
||||
|
||||
@@ -49,6 +49,9 @@ struct kvm_sregs {
|
||||
struct kvm_riscv_config {
|
||||
unsigned long isa;
|
||||
unsigned long zicbom_block_size;
|
||||
unsigned long mvendorid;
|
||||
unsigned long marchid;
|
||||
unsigned long mimpid;
|
||||
};
|
||||
|
||||
/* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
|
||||
|
||||
@@ -627,16 +627,19 @@ long sbi_get_mvendorid(void)
|
||||
{
|
||||
return __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbi_get_mvendorid);
|
||||
|
||||
long sbi_get_marchid(void)
|
||||
{
|
||||
return __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbi_get_marchid);
|
||||
|
||||
long sbi_get_mimpid(void)
|
||||
{
|
||||
return __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbi_get_mimpid);
|
||||
|
||||
static void sbi_send_cpumask_ipi(const struct cpumask *target)
|
||||
{
|
||||
|
||||
@@ -127,3 +127,9 @@ static int __init riscv_kvm_init(void)
|
||||
return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
||||
}
|
||||
module_init(riscv_kvm_init);
|
||||
|
||||
static void __exit riscv_kvm_exit(void)
|
||||
{
|
||||
kvm_exit();
|
||||
}
|
||||
module_exit(riscv_kvm_exit);
|
||||
|
||||
@@ -537,10 +537,8 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
||||
if (change == KVM_MR_FLAGS_ONLY)
|
||||
goto out;
|
||||
|
||||
spin_lock(&kvm->mmu_lock);
|
||||
if (ret)
|
||||
gstage_unmap_range(kvm, base_gpa, size, false);
|
||||
spin_unlock(&kvm->mmu_lock);
|
||||
kvm_riscv_gstage_iounmap(kvm, base_gpa, size);
|
||||
|
||||
out:
|
||||
mmap_read_unlock(current->mm);
|
||||
@@ -632,7 +630,7 @@ int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu,
|
||||
|
||||
mmap_read_lock(current->mm);
|
||||
|
||||
vma = find_vma_intersection(current->mm, hva, hva + 1);
|
||||
vma = vma_lookup(current->mm, hva);
|
||||
if (unlikely(!vma)) {
|
||||
kvm_err("Failed to find VMA for hva 0x%lx\n", hva);
|
||||
mmap_read_unlock(current->mm);
|
||||
|
||||
+65
-20
@@ -21,6 +21,7 @@
|
||||
#include <asm/csr.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hwcap.h>
|
||||
#include <asm/sbi.h>
|
||||
|
||||
const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
|
||||
KVM_GENERIC_VCPU_STATS(),
|
||||
@@ -171,6 +172,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
||||
set_bit(host_isa, vcpu->arch.isa);
|
||||
}
|
||||
|
||||
/* Setup vendor, arch, and implementation details */
|
||||
vcpu->arch.mvendorid = sbi_get_mvendorid();
|
||||
vcpu->arch.marchid = sbi_get_marchid();
|
||||
vcpu->arch.mimpid = sbi_get_mimpid();
|
||||
|
||||
/* Setup VCPU hfence queue */
|
||||
spin_lock_init(&vcpu->arch.hfence_lock);
|
||||
|
||||
@@ -270,6 +276,15 @@ static int kvm_riscv_vcpu_get_reg_config(struct kvm_vcpu *vcpu,
|
||||
return -EINVAL;
|
||||
reg_val = riscv_cbom_block_size;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(mvendorid):
|
||||
reg_val = vcpu->arch.mvendorid;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(marchid):
|
||||
reg_val = vcpu->arch.marchid;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(mimpid):
|
||||
reg_val = vcpu->arch.mimpid;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -296,12 +311,15 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
|
||||
if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id)))
|
||||
return -EFAULT;
|
||||
|
||||
/* This ONE REG interface is only defined for single letter extensions */
|
||||
if (fls(reg_val) >= RISCV_ISA_EXT_BASE)
|
||||
return -EINVAL;
|
||||
|
||||
switch (reg_num) {
|
||||
case KVM_REG_RISCV_CONFIG_REG(isa):
|
||||
/*
|
||||
* This ONE REG interface is only defined for
|
||||
* single letter extensions.
|
||||
*/
|
||||
if (fls(reg_val) >= RISCV_ISA_EXT_BASE)
|
||||
return -EINVAL;
|
||||
|
||||
if (!vcpu->arch.ran_atleast_once) {
|
||||
/* Ignore the enable/disable request for certain extensions */
|
||||
for (i = 0; i < RISCV_ISA_EXT_BASE; i++) {
|
||||
@@ -329,6 +347,24 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
|
||||
return -EOPNOTSUPP;
|
||||
case KVM_REG_RISCV_CONFIG_REG(mvendorid):
|
||||
if (!vcpu->arch.ran_atleast_once)
|
||||
vcpu->arch.mvendorid = reg_val;
|
||||
else
|
||||
return -EBUSY;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(marchid):
|
||||
if (!vcpu->arch.ran_atleast_once)
|
||||
vcpu->arch.marchid = reg_val;
|
||||
else
|
||||
return -EBUSY;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(mimpid):
|
||||
if (!vcpu->arch.ran_atleast_once)
|
||||
vcpu->arch.mimpid = reg_val;
|
||||
else
|
||||
return -EBUSY;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -541,22 +577,26 @@ static int kvm_riscv_vcpu_set_reg_isa_ext(struct kvm_vcpu *vcpu,
|
||||
static int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_one_reg *reg)
|
||||
{
|
||||
if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CONFIG)
|
||||
switch (reg->id & KVM_REG_RISCV_TYPE_MASK) {
|
||||
case KVM_REG_RISCV_CONFIG:
|
||||
return kvm_riscv_vcpu_set_reg_config(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CORE)
|
||||
case KVM_REG_RISCV_CORE:
|
||||
return kvm_riscv_vcpu_set_reg_core(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CSR)
|
||||
case KVM_REG_RISCV_CSR:
|
||||
return kvm_riscv_vcpu_set_reg_csr(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_TIMER)
|
||||
case KVM_REG_RISCV_TIMER:
|
||||
return kvm_riscv_vcpu_set_reg_timer(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_F)
|
||||
case KVM_REG_RISCV_FP_F:
|
||||
return kvm_riscv_vcpu_set_reg_fp(vcpu, reg,
|
||||
KVM_REG_RISCV_FP_F);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_D)
|
||||
case KVM_REG_RISCV_FP_D:
|
||||
return kvm_riscv_vcpu_set_reg_fp(vcpu, reg,
|
||||
KVM_REG_RISCV_FP_D);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_ISA_EXT)
|
||||
case KVM_REG_RISCV_ISA_EXT:
|
||||
return kvm_riscv_vcpu_set_reg_isa_ext(vcpu, reg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -564,22 +604,26 @@ static int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *vcpu,
|
||||
static int kvm_riscv_vcpu_get_reg(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_one_reg *reg)
|
||||
{
|
||||
if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CONFIG)
|
||||
switch (reg->id & KVM_REG_RISCV_TYPE_MASK) {
|
||||
case KVM_REG_RISCV_CONFIG:
|
||||
return kvm_riscv_vcpu_get_reg_config(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CORE)
|
||||
case KVM_REG_RISCV_CORE:
|
||||
return kvm_riscv_vcpu_get_reg_core(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CSR)
|
||||
case KVM_REG_RISCV_CSR:
|
||||
return kvm_riscv_vcpu_get_reg_csr(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_TIMER)
|
||||
case KVM_REG_RISCV_TIMER:
|
||||
return kvm_riscv_vcpu_get_reg_timer(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_F)
|
||||
case KVM_REG_RISCV_FP_F:
|
||||
return kvm_riscv_vcpu_get_reg_fp(vcpu, reg,
|
||||
KVM_REG_RISCV_FP_F);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_D)
|
||||
case KVM_REG_RISCV_FP_D:
|
||||
return kvm_riscv_vcpu_get_reg_fp(vcpu, reg,
|
||||
KVM_REG_RISCV_FP_D);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_ISA_EXT)
|
||||
case KVM_REG_RISCV_ISA_EXT:
|
||||
return kvm_riscv_vcpu_get_reg_isa_ext(vcpu, reg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -984,8 +1028,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
|
||||
while (ret > 0) {
|
||||
/* Check conditions before entering the guest */
|
||||
ret = xfer_to_guest_mode_handle_work(vcpu);
|
||||
if (!ret)
|
||||
ret = 1;
|
||||
if (ret)
|
||||
continue;
|
||||
ret = 1;
|
||||
|
||||
kvm_riscv_gstage_vmid_update(vcpu);
|
||||
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <linux/version.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/kvm_vcpu_timer.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
|
||||
static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||
@@ -21,7 +19,6 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||
{
|
||||
int ret = 0;
|
||||
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
|
||||
struct sbiret ecall_ret;
|
||||
|
||||
switch (cp->a6) {
|
||||
case SBI_EXT_BASE_GET_SPEC_VERSION:
|
||||
@@ -50,13 +47,13 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||
*out_val = kvm_vcpu_sbi_find_ext(cp->a0) ? 1 : 0;
|
||||
break;
|
||||
case SBI_EXT_BASE_GET_MVENDORID:
|
||||
*out_val = vcpu->arch.mvendorid;
|
||||
break;
|
||||
case SBI_EXT_BASE_GET_MARCHID:
|
||||
*out_val = vcpu->arch.marchid;
|
||||
break;
|
||||
case SBI_EXT_BASE_GET_MIMPID:
|
||||
ecall_ret = sbi_ecall(SBI_EXT_BASE, cp->a6, 0, 0, 0, 0, 0, 0);
|
||||
if (!ecall_ret.error)
|
||||
*out_val = ecall_ret.value;
|
||||
/*TODO: We are unnecessarily converting the error twice */
|
||||
ret = sbi_err_map_linux_errno(ecall_ret.error);
|
||||
*out_val = vcpu->arch.mimpid;
|
||||
break;
|
||||
default:
|
||||
ret = -EOPNOTSUPP;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/kvm_vcpu_timer.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/kvm_vcpu_timer.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
|
||||
+7
-9
@@ -724,19 +724,19 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
* sure that the reference to cgroup is valid across the call (see
|
||||
* comments in bfq_bic_update_cgroup on this issue)
|
||||
*/
|
||||
static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
|
||||
struct bfq_io_cq *bic,
|
||||
struct bfq_group *bfqg)
|
||||
static void __bfq_bic_change_cgroup(struct bfq_data *bfqd,
|
||||
struct bfq_io_cq *bic,
|
||||
struct bfq_group *bfqg)
|
||||
{
|
||||
struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0);
|
||||
struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1);
|
||||
struct bfq_queue *async_bfqq = bic_to_bfqq(bic, false);
|
||||
struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, true);
|
||||
struct bfq_entity *entity;
|
||||
|
||||
if (async_bfqq) {
|
||||
entity = &async_bfqq->entity;
|
||||
|
||||
if (entity->sched_data != &bfqg->sched_data) {
|
||||
bic_set_bfqq(bic, NULL, 0);
|
||||
bic_set_bfqq(bic, NULL, false);
|
||||
bfq_release_process_ref(bfqd, async_bfqq);
|
||||
}
|
||||
}
|
||||
@@ -772,12 +772,10 @@ static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
|
||||
*/
|
||||
bfq_put_cooperator(sync_bfqq);
|
||||
bfq_release_process_ref(bfqd, sync_bfqq);
|
||||
bic_set_bfqq(bic, NULL, 1);
|
||||
bic_set_bfqq(bic, NULL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bfqg;
|
||||
}
|
||||
|
||||
void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
|
||||
|
||||
+10
-3
@@ -386,6 +386,12 @@ static void bfq_put_stable_ref(struct bfq_queue *bfqq);
|
||||
|
||||
void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync)
|
||||
{
|
||||
struct bfq_queue *old_bfqq = bic->bfqq[is_sync];
|
||||
|
||||
/* Clear bic pointer if bfqq is detached from this bic */
|
||||
if (old_bfqq && old_bfqq->bic == bic)
|
||||
old_bfqq->bic = NULL;
|
||||
|
||||
/*
|
||||
* If bfqq != NULL, then a non-stable queue merge between
|
||||
* bic->bfqq and bfqq is happening here. This causes troubles
|
||||
@@ -3108,7 +3114,7 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
|
||||
/*
|
||||
* Merge queues (that is, let bic redirect its requests to new_bfqq)
|
||||
*/
|
||||
bic_set_bfqq(bic, new_bfqq, 1);
|
||||
bic_set_bfqq(bic, new_bfqq, true);
|
||||
bfq_mark_bfqq_coop(new_bfqq);
|
||||
/*
|
||||
* new_bfqq now belongs to at least two bics (it is a shared queue):
|
||||
@@ -5311,7 +5317,6 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bfqd->lock, flags);
|
||||
bfqq->bic = NULL;
|
||||
bfq_exit_bfqq(bfqd, bfqq);
|
||||
bic_set_bfqq(bic, NULL, is_sync);
|
||||
spin_unlock_irqrestore(&bfqd->lock, flags);
|
||||
@@ -6557,7 +6562,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
|
||||
return bfqq;
|
||||
}
|
||||
|
||||
bic_set_bfqq(bic, NULL, 1);
|
||||
bic_set_bfqq(bic, NULL, true);
|
||||
|
||||
bfq_put_cooperator(bfqq);
|
||||
|
||||
@@ -7058,7 +7063,9 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
|
||||
bfqd->idle_slice_timer.function = bfq_idle_slice_timer;
|
||||
|
||||
bfqd->queue_weights_tree = RB_ROOT_CACHED;
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
bfqd->num_groups_with_pending_reqs = 0;
|
||||
#endif
|
||||
|
||||
INIT_LIST_HEAD(&bfqd->active_list);
|
||||
INIT_LIST_HEAD(&bfqd->idle_list);
|
||||
|
||||
@@ -197,8 +197,10 @@ struct bfq_entity {
|
||||
/* flag, set to request a weight, ioprio or ioprio_class change */
|
||||
int prio_changed;
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
/* flag, set if the entity is counted in groups_with_pending_reqs */
|
||||
bool in_groups_with_pending_reqs;
|
||||
#endif
|
||||
|
||||
/* last child queue of entity created (for non-leaf entities) */
|
||||
struct bfq_queue *last_bfqq_created;
|
||||
@@ -491,6 +493,7 @@ struct bfq_data {
|
||||
*/
|
||||
struct rb_root_cached queue_weights_tree;
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
/*
|
||||
* Number of groups with at least one process that
|
||||
* has at least one request waiting for completion. Note that
|
||||
@@ -538,6 +541,7 @@ struct bfq_data {
|
||||
* with no request waiting for completion.
|
||||
*/
|
||||
unsigned int num_groups_with_pending_reqs;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Per-class (RT, BE, IDLE) number of bfq_queues containing
|
||||
|
||||
+4
-4
@@ -1612,28 +1612,28 @@ void bfq_requeue_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
|
||||
void bfq_add_bfqq_in_groups_with_pending_reqs(struct bfq_queue *bfqq)
|
||||
{
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
struct bfq_entity *entity = &bfqq->entity;
|
||||
|
||||
if (!entity->in_groups_with_pending_reqs) {
|
||||
entity->in_groups_with_pending_reqs = true;
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
if (!(bfqq_group(bfqq)->num_queues_with_pending_reqs++))
|
||||
bfqq->bfqd->num_groups_with_pending_reqs++;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void bfq_del_bfqq_in_groups_with_pending_reqs(struct bfq_queue *bfqq)
|
||||
{
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
struct bfq_entity *entity = &bfqq->entity;
|
||||
|
||||
if (entity->in_groups_with_pending_reqs) {
|
||||
entity->in_groups_with_pending_reqs = false;
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
if (!(--bfqq_group(bfqq)->num_queues_with_pending_reqs))
|
||||
bfqq->bfqd->num_groups_with_pending_reqs--;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "blk-cgroup.h"
|
||||
#include "blk-ioprio.h"
|
||||
#include "blk-throttle.h"
|
||||
#include "blk-rq-qos.h"
|
||||
|
||||
/*
|
||||
* blkcg_pol_mutex protects blkcg_policy[] and policy [de]activation.
|
||||
@@ -1322,6 +1323,7 @@ err_unlock:
|
||||
void blkcg_exit_disk(struct gendisk *disk)
|
||||
{
|
||||
blkg_destroy_all(disk);
|
||||
rq_qos_exit(disk->queue);
|
||||
blk_throtl_exit(disk);
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -254,14 +254,15 @@ EXPORT_SYMBOL_GPL(blk_clear_pm_only);
|
||||
|
||||
static void blk_free_queue_rcu(struct rcu_head *rcu_head)
|
||||
{
|
||||
kmem_cache_free(blk_requestq_cachep,
|
||||
container_of(rcu_head, struct request_queue, rcu_head));
|
||||
struct request_queue *q = container_of(rcu_head,
|
||||
struct request_queue, rcu_head);
|
||||
|
||||
percpu_ref_exit(&q->q_usage_counter);
|
||||
kmem_cache_free(blk_requestq_cachep, q);
|
||||
}
|
||||
|
||||
static void blk_free_queue(struct request_queue *q)
|
||||
{
|
||||
percpu_ref_exit(&q->q_usage_counter);
|
||||
|
||||
if (q->poll_stat)
|
||||
blk_stat_remove_callback(q, q->poll_cb);
|
||||
blk_stat_free_callback(q->poll_cb);
|
||||
|
||||
@@ -232,7 +232,9 @@ enum {
|
||||
|
||||
/* 1/64k is granular enough and can easily be handled w/ u32 */
|
||||
WEIGHT_ONE = 1 << 16,
|
||||
};
|
||||
|
||||
enum {
|
||||
/*
|
||||
* As vtime is used to calculate the cost of each IO, it needs to
|
||||
* be fairly high precision. For example, it should be able to
|
||||
|
||||
+12
-16
@@ -1773,7 +1773,16 @@ static const struct block_device_operations lo_fops = {
|
||||
/*
|
||||
* And now the modules code and kernel interface.
|
||||
*/
|
||||
static int max_loop;
|
||||
|
||||
/*
|
||||
* If max_loop is specified, create that many devices upfront.
|
||||
* This also becomes a hard limit. If max_loop is not specified,
|
||||
* create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
|
||||
* init time. Loop devices can be requested on-demand with the
|
||||
* /dev/loop-control interface, or be instantiated by accessing
|
||||
* a 'dead' device node.
|
||||
*/
|
||||
static int max_loop = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
|
||||
module_param(max_loop, int, 0444);
|
||||
MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
|
||||
module_param(max_part, int, 0444);
|
||||
@@ -2181,7 +2190,7 @@ MODULE_ALIAS("devname:loop-control");
|
||||
|
||||
static int __init loop_init(void)
|
||||
{
|
||||
int i, nr;
|
||||
int i;
|
||||
int err;
|
||||
|
||||
part_shift = 0;
|
||||
@@ -2209,19 +2218,6 @@ static int __init loop_init(void)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If max_loop is specified, create that many devices upfront.
|
||||
* This also becomes a hard limit. If max_loop is not specified,
|
||||
* create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
|
||||
* init time. Loop devices can be requested on-demand with the
|
||||
* /dev/loop-control interface, or be instantiated by accessing
|
||||
* a 'dead' device node.
|
||||
*/
|
||||
if (max_loop)
|
||||
nr = max_loop;
|
||||
else
|
||||
nr = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
|
||||
|
||||
err = misc_register(&loop_misc);
|
||||
if (err < 0)
|
||||
goto err_out;
|
||||
@@ -2233,7 +2229,7 @@ static int __init loop_init(void)
|
||||
}
|
||||
|
||||
/* pre-create number of devices given by config or max_loop */
|
||||
for (i = 0; i < nr; i++)
|
||||
for (i = 0; i < max_loop; i++)
|
||||
loop_add(i);
|
||||
|
||||
printk(KERN_INFO "loop: module loaded\n");
|
||||
|
||||
@@ -657,9 +657,10 @@ static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
spin_unlock_irqrestore(&mvpwm->lock, flags);
|
||||
}
|
||||
|
||||
static void mvebu_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state) {
|
||||
static int mvebu_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
|
||||
struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
|
||||
struct mvebu_gpio_chip *mvchip = mvpwm->mvchip;
|
||||
@@ -693,6 +694,8 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
|
||||
state->enabled = false;
|
||||
|
||||
spin_unlock_irqrestore(&mvpwm->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
@@ -1500,8 +1500,8 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ti_sn_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int ti_sn_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct ti_sn65dsi86 *pdata = pwm_chip_to_ti_sn_bridge(chip);
|
||||
unsigned int pwm_en_inv;
|
||||
@@ -1512,19 +1512,19 @@ static void ti_sn_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
ret = regmap_read(pdata->regmap, SN_PWM_EN_INV_REG, &pwm_en_inv);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
ret = ti_sn65dsi86_read_u16(pdata, SN_BACKLIGHT_SCALE_REG, &scale);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
ret = ti_sn65dsi86_read_u16(pdata, SN_BACKLIGHT_REG, &backlight);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(pdata->regmap, SN_PWM_PRE_DIV_REG, &pre_div);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
state->enabled = FIELD_GET(SN_PWM_EN_MASK, pwm_en_inv);
|
||||
if (FIELD_GET(SN_PWM_INV_MASK, pwm_en_inv))
|
||||
@@ -1539,6 +1539,8 @@ static void ti_sn_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
if (state->duty_cycle > state->period)
|
||||
state->duty_cycle = state->period;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops ti_sn_pwm_ops = {
|
||||
|
||||
+1
-1
@@ -897,7 +897,7 @@ config HID_PLAYSTATION
|
||||
select CRC32
|
||||
select POWER_SUPPLY
|
||||
help
|
||||
Provides support for Sony PS5 controllers including support for
|
||||
Provides support for Sony PS4/PS5 controllers including support for
|
||||
its special functionalities e.g. touchpad, lights and motion
|
||||
sensors.
|
||||
|
||||
|
||||
@@ -237,6 +237,10 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
|
||||
in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
|
||||
&cl_data->sensor_dma_addr[i],
|
||||
GFP_KERNEL);
|
||||
if (!in_data->sensor_virt_addr[i]) {
|
||||
rc = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
cl_data->sensor_sts[i] = SENSOR_DISABLED;
|
||||
cl_data->sensor_requested_cnt[i] = 0;
|
||||
cl_data->cur_hid_dev = i;
|
||||
|
||||
@@ -412,6 +412,7 @@
|
||||
#define USB_DEVICE_ID_HP_X2_10_COVER 0x0755
|
||||
#define I2C_DEVICE_ID_HP_ENVY_X360_15 0x2d05
|
||||
#define I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100 0x29CF
|
||||
#define I2C_DEVICE_ID_HP_ENVY_X360_EU0009NV 0x2CF9
|
||||
#define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817
|
||||
#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
|
||||
#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
|
||||
@@ -995,7 +996,10 @@
|
||||
#define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S 0x8003
|
||||
|
||||
#define USB_VENDOR_ID_PLANTRONICS 0x047f
|
||||
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES 0xc055
|
||||
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056
|
||||
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057
|
||||
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058
|
||||
|
||||
#define USB_VENDOR_ID_PANASONIC 0x04da
|
||||
#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
|
||||
|
||||
@@ -380,6 +380,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_EU0009NV),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN),
|
||||
|
||||
@@ -2548,12 +2548,17 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
|
||||
struct hid_device *hid = hidpp->hid_dev;
|
||||
struct hid_input *hidinput;
|
||||
struct input_dev *dev;
|
||||
const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
|
||||
const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
|
||||
struct usb_device_descriptor *udesc;
|
||||
u16 bcdDevice;
|
||||
struct ff_device *ff;
|
||||
int error, j, num_slots = data->num_effects;
|
||||
u8 version;
|
||||
|
||||
if (!hid_is_usb(hid)) {
|
||||
hid_err(hid, "device is not USB\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (list_empty(&hid->inputs)) {
|
||||
hid_err(hid, "no inputs found\n");
|
||||
return -ENODEV;
|
||||
@@ -2567,6 +2572,8 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
|
||||
}
|
||||
|
||||
/* Get firmware release */
|
||||
udesc = &(hid_to_usb_dev(hid)->descriptor);
|
||||
bcdDevice = le16_to_cpu(udesc->bcdDevice);
|
||||
version = bcdDevice & 255;
|
||||
|
||||
/* Set supported force feedback capabilities */
|
||||
|
||||
@@ -1110,12 +1110,19 @@ static int mcp2221_probe(struct hid_device *hdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
|
||||
/*
|
||||
* This driver uses the .raw_event callback and therefore does not need any
|
||||
* HID_CONNECT_xxx flags.
|
||||
*/
|
||||
ret = hid_hw_start(hdev, 0);
|
||||
if (ret) {
|
||||
hid_err(hdev, "can't start hardware\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
hid_info(hdev, "USB HID v%x.%02x Device [%s] on %s\n", hdev->version >> 8,
|
||||
hdev->version & 0xff, hdev->name, hdev->phys);
|
||||
|
||||
ret = hid_hw_open(hdev);
|
||||
if (ret) {
|
||||
hid_err(hdev, "can't open device\n");
|
||||
@@ -1145,8 +1152,7 @@ static int mcp2221_probe(struct hid_device *hdev,
|
||||
mcp->adapter.retries = 1;
|
||||
mcp->adapter.dev.parent = &hdev->dev;
|
||||
snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
|
||||
"MCP2221 usb-i2c bridge on hidraw%d",
|
||||
((struct hidraw *)hdev->hidraw)->minor);
|
||||
"MCP2221 usb-i2c bridge");
|
||||
|
||||
ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter);
|
||||
if (ret) {
|
||||
|
||||
@@ -1967,6 +1967,10 @@ static const struct hid_device_id mt_devices[] = {
|
||||
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_ELAN, 0x313a) },
|
||||
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
|
||||
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_ELAN, 0x3148) },
|
||||
|
||||
/* Elitegroup panel */
|
||||
{ .driver_data = MT_CLS_SERIAL,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
|
||||
|
||||
@@ -198,9 +198,18 @@ err:
|
||||
}
|
||||
|
||||
static const struct hid_device_id plantronics_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
||||
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
|
||||
.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
||||
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
|
||||
.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
||||
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
|
||||
.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
||||
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
|
||||
.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -1916,7 +1916,7 @@ static int dualshock4_get_mac_address(struct dualshock4 *ds4)
|
||||
if (ret != sizeof(ds4->base.mac_address))
|
||||
return -EINVAL;
|
||||
|
||||
ret = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
err_free:
|
||||
|
||||
@@ -2355,11 +2355,13 @@ static void motion_send_output_report(struct sony_sc *sc)
|
||||
hid_hw_output_report(hdev, (u8 *)report, MOTION_REPORT_0x02_SIZE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SONY_FF
|
||||
static inline void sony_send_output_report(struct sony_sc *sc)
|
||||
{
|
||||
if (sc->send_output_report)
|
||||
sc->send_output_report(sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void sony_state_worker(struct work_struct *work)
|
||||
{
|
||||
|
||||
@@ -155,6 +155,9 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
|
||||
{
|
||||
struct wacom *wacom = hid_get_drvdata(hdev);
|
||||
|
||||
if (wacom->wacom_wac.features.type == BOOTLOADER)
|
||||
return 0;
|
||||
|
||||
if (size > WACOM_PKGLEN_MAX)
|
||||
return 1;
|
||||
|
||||
@@ -2785,6 +2788,11 @@ static int wacom_probe(struct hid_device *hdev,
|
||||
return error;
|
||||
}
|
||||
|
||||
if (features->type == BOOTLOADER) {
|
||||
hid_warn(hdev, "Using device in hidraw-only mode");
|
||||
return hid_hw_start(hdev, HID_CONNECT_HIDRAW);
|
||||
}
|
||||
|
||||
error = wacom_parse_and_register(wacom, false);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -4882,6 +4882,9 @@ static const struct wacom_features wacom_features_0x3dd =
|
||||
static const struct wacom_features wacom_features_HID_ANY_ID =
|
||||
{ "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
|
||||
|
||||
static const struct wacom_features wacom_features_0x94 =
|
||||
{ "Wacom Bootloader", .type = BOOTLOADER };
|
||||
|
||||
#define USB_DEVICE_WACOM(prod) \
|
||||
HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
|
||||
.driver_data = (kernel_ulong_t)&wacom_features_##prod
|
||||
@@ -4955,6 +4958,7 @@ const struct hid_device_id wacom_ids[] = {
|
||||
{ USB_DEVICE_WACOM(0x84) },
|
||||
{ USB_DEVICE_WACOM(0x90) },
|
||||
{ USB_DEVICE_WACOM(0x93) },
|
||||
{ USB_DEVICE_WACOM(0x94) },
|
||||
{ USB_DEVICE_WACOM(0x97) },
|
||||
{ USB_DEVICE_WACOM(0x9A) },
|
||||
{ USB_DEVICE_WACOM(0x9F) },
|
||||
|
||||
@@ -243,6 +243,7 @@ enum {
|
||||
MTTPC,
|
||||
MTTPC_B,
|
||||
HID_GENERIC,
|
||||
BOOTLOADER,
|
||||
MAX_TYPE
|
||||
};
|
||||
|
||||
|
||||
@@ -972,8 +972,8 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct lpg *lpg = container_of(chip, struct lpg, pwm);
|
||||
struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
|
||||
@@ -986,20 +986,20 @@ static void lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
ret = regmap_read(lpg->map, chan->base + LPG_SIZE_CLK_REG, &val);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
refclk = lpg_clk_rates[val & PWM_CLK_SELECT_MASK];
|
||||
if (refclk) {
|
||||
ret = regmap_read(lpg->map, chan->base + LPG_PREDIV_CLK_REG, &val);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
pre_div = lpg_pre_divs[FIELD_GET(PWM_FREQ_PRE_DIV_MASK, val)];
|
||||
m = FIELD_GET(PWM_FREQ_EXP_MASK, val);
|
||||
|
||||
ret = regmap_bulk_read(lpg->map, chan->base + PWM_VALUE_REG, &pwm_value, sizeof(pwm_value));
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * LPG_RESOLUTION * pre_div * (1 << m), refclk);
|
||||
state->duty_cycle = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pwm_value * pre_div * (1 << m), refclk);
|
||||
@@ -1010,13 +1010,15 @@ static void lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
ret = regmap_read(lpg->map, chan->base + PWM_ENABLE_CONTROL_REG, &val);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
state->enabled = FIELD_GET(LPG_ENABLE_CONTROL_OUTPUT, val);
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
if (state->duty_cycle > state->period)
|
||||
state->duty_cycle = state->period;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops lpg_pwm_ops = {
|
||||
|
||||
@@ -663,7 +663,7 @@ sun6i_csi_bridge_notifier_bound(struct v4l2_async_notifier *notifier,
|
||||
enabled = !bridge->source_parallel.expected;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
source->subdev = remote_subdev;
|
||||
|
||||
@@ -832,7 +832,7 @@ static int sun6i_csi_capture_open(struct file *file)
|
||||
{
|
||||
struct sun6i_csi_device *csi_dev = video_drvdata(file);
|
||||
struct sun6i_csi_capture *capture = &csi_dev->capture;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&capture->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
@@ -188,7 +188,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
|
||||
return -ENODEV;
|
||||
|
||||
if (!on) {
|
||||
ret = v4l2_subdev_call(source_subdev, video, s_stream, 0);
|
||||
v4l2_subdev_call(source_subdev, video, s_stream, 0);
|
||||
ret = 0;
|
||||
goto disable;
|
||||
}
|
||||
|
||||
@@ -280,8 +281,6 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
|
||||
return 0;
|
||||
|
||||
disable:
|
||||
if (!on)
|
||||
ret = 0;
|
||||
phy_power_off(dphy);
|
||||
sun6i_mipi_csi2_disable(csi2_dev);
|
||||
|
||||
|
||||
@@ -220,7 +220,8 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
|
||||
return -ENODEV;
|
||||
|
||||
if (!on) {
|
||||
ret = v4l2_subdev_call(source_subdev, video, s_stream, 0);
|
||||
v4l2_subdev_call(source_subdev, video, s_stream, 0);
|
||||
ret = 0;
|
||||
goto disable;
|
||||
}
|
||||
|
||||
@@ -312,8 +313,6 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
|
||||
return 0;
|
||||
|
||||
disable:
|
||||
if (!on)
|
||||
ret = 0;
|
||||
phy_power_off(dphy);
|
||||
sun8i_a83t_mipi_csi2_disable(csi2_dev);
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
|
||||
* then return an error.
|
||||
*/
|
||||
if (strlen(ctrl->p_new.p_char) == ctrl->maximum && last)
|
||||
ctrl->is_new = 1;
|
||||
return -ERANGE;
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -2117,11 +2117,34 @@ static int nvme_send_ns_pr_command(struct nvme_ns *ns, struct nvme_command *c,
|
||||
return nvme_submit_sync_cmd(ns->queue, c, data, 16);
|
||||
}
|
||||
|
||||
static int nvme_sc_to_pr_err(int nvme_sc)
|
||||
{
|
||||
if (nvme_is_path_error(nvme_sc))
|
||||
return PR_STS_PATH_FAILED;
|
||||
|
||||
switch (nvme_sc) {
|
||||
case NVME_SC_SUCCESS:
|
||||
return PR_STS_SUCCESS;
|
||||
case NVME_SC_RESERVATION_CONFLICT:
|
||||
return PR_STS_RESERVATION_CONFLICT;
|
||||
case NVME_SC_ONCS_NOT_SUPPORTED:
|
||||
return -EOPNOTSUPP;
|
||||
case NVME_SC_BAD_ATTRIBUTES:
|
||||
case NVME_SC_INVALID_OPCODE:
|
||||
case NVME_SC_INVALID_FIELD:
|
||||
case NVME_SC_INVALID_NS:
|
||||
return -EINVAL;
|
||||
default:
|
||||
return PR_STS_IOERR;
|
||||
}
|
||||
}
|
||||
|
||||
static int nvme_pr_command(struct block_device *bdev, u32 cdw10,
|
||||
u64 key, u64 sa_key, u8 op)
|
||||
{
|
||||
struct nvme_command c = { };
|
||||
u8 data[16] = { 0, };
|
||||
int ret;
|
||||
|
||||
put_unaligned_le64(key, &data[0]);
|
||||
put_unaligned_le64(sa_key, &data[8]);
|
||||
@@ -2131,8 +2154,14 @@ static int nvme_pr_command(struct block_device *bdev, u32 cdw10,
|
||||
|
||||
if (IS_ENABLED(CONFIG_NVME_MULTIPATH) &&
|
||||
bdev->bd_disk->fops == &nvme_ns_head_ops)
|
||||
return nvme_send_ns_head_pr_command(bdev, &c, data);
|
||||
return nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c, data);
|
||||
ret = nvme_send_ns_head_pr_command(bdev, &c, data);
|
||||
else
|
||||
ret = nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c,
|
||||
data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return nvme_sc_to_pr_err(ret);
|
||||
}
|
||||
|
||||
static int nvme_pr_register(struct block_device *bdev, u64 old,
|
||||
|
||||
+3
-3
@@ -282,8 +282,8 @@ config PWM_IQS620A
|
||||
|
||||
config PWM_JZ4740
|
||||
tristate "Ingenic JZ47xx PWM support"
|
||||
depends on MIPS || COMPILE_TEST
|
||||
depends on COMMON_CLK
|
||||
depends on MACH_INGENIC || COMPILE_TEST
|
||||
depends on COMMON_CLK && OF
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Generic PWM framework driver for Ingenic JZ47xx based
|
||||
@@ -434,7 +434,7 @@ config PWM_PCA9685
|
||||
|
||||
config PWM_PXA
|
||||
tristate "PXA PWM support"
|
||||
depends on ARCH_PXA || COMPILE_TEST
|
||||
depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
Generic PWM framework driver for PXA.
|
||||
|
||||
+38
-30
@@ -27,7 +27,10 @@
|
||||
|
||||
static DEFINE_MUTEX(pwm_lookup_lock);
|
||||
static LIST_HEAD(pwm_lookup_list);
|
||||
|
||||
/* protects access to pwm_chips, allocated_pwms, and pwm_tree */
|
||||
static DEFINE_MUTEX(pwm_lock);
|
||||
|
||||
static LIST_HEAD(pwm_chips);
|
||||
static DECLARE_BITMAP(allocated_pwms, MAX_PWMS);
|
||||
static RADIX_TREE(pwm_tree, GFP_KERNEL);
|
||||
@@ -37,6 +40,7 @@ static struct pwm_device *pwm_to_device(unsigned int pwm)
|
||||
return radix_tree_lookup(&pwm_tree, pwm);
|
||||
}
|
||||
|
||||
/* Called with pwm_lock held */
|
||||
static int alloc_pwms(unsigned int count)
|
||||
{
|
||||
unsigned int start;
|
||||
@@ -47,9 +51,12 @@ static int alloc_pwms(unsigned int count)
|
||||
if (start + count > MAX_PWMS)
|
||||
return -ENOSPC;
|
||||
|
||||
bitmap_set(allocated_pwms, start, count);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
/* Called with pwm_lock held */
|
||||
static void free_pwms(struct pwm_chip *chip)
|
||||
{
|
||||
unsigned int i;
|
||||
@@ -108,8 +115,13 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
|
||||
}
|
||||
|
||||
if (pwm->chip->ops->get_state) {
|
||||
pwm->chip->ops->get_state(pwm->chip, pwm, &pwm->state);
|
||||
trace_pwm_get(pwm, &pwm->state);
|
||||
struct pwm_state state;
|
||||
|
||||
err = pwm->chip->ops->get_state(pwm->chip, pwm, &state);
|
||||
trace_pwm_get(pwm, &state, err);
|
||||
|
||||
if (!err)
|
||||
pwm->state = state;
|
||||
|
||||
if (IS_ENABLED(CONFIG_PWM_DEBUG))
|
||||
pwm->last = pwm->state;
|
||||
@@ -267,20 +279,21 @@ int pwmchip_add(struct pwm_chip *chip)
|
||||
if (!pwm_ops_check(chip))
|
||||
return -EINVAL;
|
||||
|
||||
chip->pwms = kcalloc(chip->npwm, sizeof(*pwm), GFP_KERNEL);
|
||||
if (!chip->pwms)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&pwm_lock);
|
||||
|
||||
ret = alloc_pwms(chip->npwm);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&pwm_lock);
|
||||
kfree(chip->pwms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
chip->base = ret;
|
||||
|
||||
chip->pwms = kcalloc(chip->npwm, sizeof(*pwm), GFP_KERNEL);
|
||||
if (!chip->pwms) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < chip->npwm; i++) {
|
||||
pwm = &chip->pwms[i];
|
||||
|
||||
@@ -291,23 +304,16 @@ int pwmchip_add(struct pwm_chip *chip)
|
||||
radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
|
||||
}
|
||||
|
||||
bitmap_set(allocated_pwms, chip->base, chip->npwm);
|
||||
|
||||
INIT_LIST_HEAD(&chip->list);
|
||||
list_add(&chip->list, &pwm_chips);
|
||||
|
||||
ret = 0;
|
||||
mutex_unlock(&pwm_lock);
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF))
|
||||
of_pwmchip_add(chip);
|
||||
|
||||
out:
|
||||
mutex_unlock(&pwm_lock);
|
||||
pwmchip_sysfs_export(chip);
|
||||
|
||||
if (!ret)
|
||||
pwmchip_sysfs_export(chip);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pwmchip_add);
|
||||
|
||||
@@ -457,8 +463,11 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
|
||||
* checks.
|
||||
*/
|
||||
|
||||
chip->ops->get_state(chip, pwm, &s1);
|
||||
trace_pwm_get(pwm, &s1);
|
||||
err = chip->ops->get_state(chip, pwm, &s1);
|
||||
trace_pwm_get(pwm, &s1, err);
|
||||
if (err)
|
||||
/* If that failed there isn't much to debug */
|
||||
return;
|
||||
|
||||
/*
|
||||
* The lowlevel driver either ignored .polarity (which is a bug) or as
|
||||
@@ -514,16 +523,17 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
|
||||
|
||||
/* reapply the state that the driver reported being configured. */
|
||||
err = chip->ops->apply(chip, pwm, &s1);
|
||||
trace_pwm_apply(pwm, &s1, err);
|
||||
if (err) {
|
||||
*last = s1;
|
||||
dev_err(chip->dev, "failed to reapply current setting\n");
|
||||
return;
|
||||
}
|
||||
|
||||
trace_pwm_apply(pwm, &s1);
|
||||
|
||||
chip->ops->get_state(chip, pwm, last);
|
||||
trace_pwm_get(pwm, last);
|
||||
err = chip->ops->get_state(chip, pwm, last);
|
||||
trace_pwm_get(pwm, last, err);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
/* reapplication of the current state should give an exact match */
|
||||
if (s1.enabled != last->enabled ||
|
||||
@@ -571,11 +581,10 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
|
||||
return 0;
|
||||
|
||||
err = chip->ops->apply(chip, pwm, state);
|
||||
trace_pwm_apply(pwm, state, err);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
trace_pwm_apply(pwm, state);
|
||||
|
||||
pwm->state = *state;
|
||||
|
||||
/*
|
||||
@@ -1179,8 +1188,7 @@ DEFINE_SEQ_ATTRIBUTE(pwm_debugfs);
|
||||
|
||||
static int __init pwm_debugfs_init(void)
|
||||
{
|
||||
debugfs_create_file("pwm", S_IFREG | 0444, NULL, NULL,
|
||||
&pwm_debugfs_fops);
|
||||
debugfs_create_file("pwm", 0444, NULL, NULL, &pwm_debugfs_fops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -356,8 +356,8 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
|
||||
u32 sr, cmr;
|
||||
@@ -396,6 +396,8 @@ static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
state->polarity = PWM_POLARITY_INVERSED;
|
||||
else
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops atmel_pwm_ops = {
|
||||
|
||||
@@ -68,8 +68,8 @@ static void iproc_pwmc_disable(struct iproc_pwmc *ip, unsigned int channel)
|
||||
ndelay(400);
|
||||
}
|
||||
|
||||
static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct iproc_pwmc *ip = to_iproc_pwmc(chip);
|
||||
u64 tmp, multi, rate;
|
||||
@@ -91,7 +91,7 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
if (rate == 0) {
|
||||
state->period = 0;
|
||||
state->duty_cycle = 0;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET);
|
||||
@@ -107,6 +107,8 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
value = readl(ip->base + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm));
|
||||
tmp = (value & IPROC_PWM_PERIOD_MAX) * multi;
|
||||
state->duty_cycle = div64_u64(tmp, rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
@@ -121,8 +121,8 @@ static int crc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct crystalcove_pwm *crc_pwm = to_crc_pwm(chip);
|
||||
struct device *dev = crc_pwm->chip.dev;
|
||||
@@ -132,13 +132,13 @@ static void crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
error = regmap_read(crc_pwm->regmap, PWM0_CLK_DIV, &clk_div_reg);
|
||||
if (error) {
|
||||
dev_err(dev, "Error reading PWM0_CLK_DIV %d\n", error);
|
||||
return;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = regmap_read(crc_pwm->regmap, PWM0_DUTY_CYCLE, &duty_cycle_reg);
|
||||
if (error) {
|
||||
dev_err(dev, "Error reading PWM0_DUTY_CYCLE %d\n", error);
|
||||
return;
|
||||
return error;
|
||||
}
|
||||
|
||||
clk_div = (clk_div_reg & ~PWM_OUTPUT_ENABLE) + 1;
|
||||
@@ -149,6 +149,8 @@ static void crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
DIV_ROUND_UP_ULL(duty_cycle_reg * state->period, PWM_MAX_LEVEL);
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
state->enabled = !!(clk_div_reg & PWM_OUTPUT_ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops crc_pwm_ops = {
|
||||
|
||||
@@ -183,8 +183,8 @@ static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct cros_ec_pwm_device *ec_pwm = pwm_to_cros_ec_pwm(chip);
|
||||
struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
|
||||
@@ -193,7 +193,7 @@ static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
ret = cros_ec_pwm_get_duty(ec_pwm, pwm->hwpwm);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "error getting initial duty: %d\n", ret);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
state->enabled = (ret > 0);
|
||||
@@ -212,6 +212,8 @@ static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
state->duty_cycle = channel->duty_cycle;
|
||||
else
|
||||
state->duty_cycle = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pwm_device *
|
||||
|
||||
@@ -163,8 +163,8 @@ static int dwc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct dwc_pwm *dwc = to_dwc_pwm(chip);
|
||||
u64 duty, period;
|
||||
@@ -188,6 +188,8 @@ static void dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
state->polarity = PWM_POLARITY_INVERSED;
|
||||
|
||||
pm_runtime_put_sync(chip->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops dwc_pwm_ops = {
|
||||
|
||||
@@ -65,13 +65,12 @@ static void ftm_clear_write_protection(struct fsl_pwm_chip *fpc)
|
||||
|
||||
regmap_read(fpc->regmap, FTM_FMS, &val);
|
||||
if (val & FTM_FMS_WPEN)
|
||||
regmap_update_bits(fpc->regmap, FTM_MODE, FTM_MODE_WPDIS,
|
||||
FTM_MODE_WPDIS);
|
||||
regmap_set_bits(fpc->regmap, FTM_MODE, FTM_MODE_WPDIS);
|
||||
}
|
||||
|
||||
static void ftm_set_write_protection(struct fsl_pwm_chip *fpc)
|
||||
{
|
||||
regmap_update_bits(fpc->regmap, FTM_FMS, FTM_FMS_WPEN, FTM_FMS_WPEN);
|
||||
regmap_set_bits(fpc->regmap, FTM_FMS, FTM_FMS_WPEN);
|
||||
}
|
||||
|
||||
static bool fsl_pwm_periodcfg_are_equal(const struct fsl_pwm_periodcfg *a,
|
||||
@@ -94,8 +93,7 @@ static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
ret = clk_prepare_enable(fpc->ipg_clk);
|
||||
if (!ret && fpc->soc->has_enable_bits) {
|
||||
mutex_lock(&fpc->lock);
|
||||
regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
|
||||
BIT(pwm->hwpwm + 16));
|
||||
regmap_set_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16));
|
||||
mutex_unlock(&fpc->lock);
|
||||
}
|
||||
|
||||
@@ -108,8 +106,7 @@ static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
|
||||
if (fpc->soc->has_enable_bits) {
|
||||
mutex_lock(&fpc->lock);
|
||||
regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
|
||||
0);
|
||||
regmap_clear_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16));
|
||||
mutex_unlock(&fpc->lock);
|
||||
}
|
||||
|
||||
@@ -317,8 +314,8 @@ static int fsl_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
if (!newstate->enabled) {
|
||||
if (oldstate->enabled) {
|
||||
regmap_update_bits(fpc->regmap, FTM_OUTMASK,
|
||||
BIT(pwm->hwpwm), BIT(pwm->hwpwm));
|
||||
regmap_set_bits(fpc->regmap, FTM_OUTMASK,
|
||||
BIT(pwm->hwpwm));
|
||||
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
|
||||
clk_disable_unprepare(fpc->clk[fpc->period.clk_select]);
|
||||
}
|
||||
@@ -342,8 +339,7 @@ static int fsl_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
goto end_mutex;
|
||||
}
|
||||
|
||||
regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm),
|
||||
0);
|
||||
regmap_clear_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm));
|
||||
}
|
||||
|
||||
end_mutex:
|
||||
|
||||
@@ -128,8 +128,8 @@ static void hibvt_pwm_set_polarity(struct pwm_chip *chip,
|
||||
PWM_POLARITY_MASK, (0x0 << PWM_POLARITY_SHIFT));
|
||||
}
|
||||
|
||||
static void hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
|
||||
void __iomem *base;
|
||||
@@ -146,6 +146,8 @@ static void hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm));
|
||||
state->enabled = (PWM_ENABLE_MASK & value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
@@ -161,9 +161,9 @@ static int img_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
val |= BIT(pwm->hwpwm);
|
||||
img_pwm_writel(imgchip, PWM_CTRL_CFG, val);
|
||||
|
||||
regmap_update_bits(imgchip->periph_regs, PERIP_PWM_PDM_CONTROL,
|
||||
PERIP_PWM_PDM_CONTROL_CH_MASK <<
|
||||
PERIP_PWM_PDM_CONTROL_CH_SHIFT(pwm->hwpwm), 0);
|
||||
regmap_clear_bits(imgchip->periph_regs, PERIP_PWM_PDM_CONTROL,
|
||||
PERIP_PWM_PDM_CONTROL_CH_MASK <<
|
||||
PERIP_PWM_PDM_CONTROL_CH_SHIFT(pwm->hwpwm));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -397,11 +397,10 @@ static int img_pwm_resume(struct device *dev)
|
||||
|
||||
for (i = 0; i < imgchip->chip.npwm; i++)
|
||||
if (imgchip->suspend_ctrl_cfg & BIT(i))
|
||||
regmap_update_bits(imgchip->periph_regs,
|
||||
PERIP_PWM_PDM_CONTROL,
|
||||
PERIP_PWM_PDM_CONTROL_CH_MASK <<
|
||||
PERIP_PWM_PDM_CONTROL_CH_SHIFT(i),
|
||||
0);
|
||||
regmap_clear_bits(imgchip->periph_regs,
|
||||
PERIP_PWM_PDM_CONTROL,
|
||||
PERIP_PWM_PDM_CONTROL_CH_MASK <<
|
||||
PERIP_PWM_PDM_CONTROL_CH_SHIFT(i));
|
||||
|
||||
if (pm_runtime_status_suspended(dev))
|
||||
img_pwm_runtime_suspend(dev);
|
||||
|
||||
@@ -132,9 +132,9 @@ static int pwm_imx_tpm_round_state(struct pwm_chip *chip,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pwm_imx_tpm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int pwm_imx_tpm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip);
|
||||
u32 rate, val, prescale;
|
||||
@@ -164,6 +164,8 @@ static void pwm_imx_tpm_get_state(struct pwm_chip *chip,
|
||||
|
||||
/* get channel status */
|
||||
state->enabled = FIELD_GET(PWM_IMX_TPM_CnSC_ELS, val) ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this function is supposed to be called with mutex hold */
|
||||
|
||||
@@ -118,8 +118,8 @@ static void pwm_imx27_clk_disable_unprepare(struct pwm_imx27_chip *imx)
|
||||
clk_disable_unprepare(imx->clk_ipg);
|
||||
}
|
||||
|
||||
static void pwm_imx27_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm, struct pwm_state *state)
|
||||
static int pwm_imx27_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm, struct pwm_state *state)
|
||||
{
|
||||
struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
|
||||
u32 period, prescaler, pwm_clk, val;
|
||||
@@ -128,7 +128,7 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
|
||||
|
||||
ret = pwm_imx27_clk_prepare_enable(imx);
|
||||
if (ret < 0)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
val = readl(imx->mmio_base + MX3_PWMCR);
|
||||
|
||||
@@ -170,6 +170,8 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
|
||||
state->duty_cycle = DIV_ROUND_UP_ULL(tmp, pwm_clk);
|
||||
|
||||
pwm_imx27_clk_disable_unprepare(imx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pwm_imx27_sw_reset(struct pwm_chip *chip)
|
||||
|
||||
@@ -86,8 +86,8 @@ static int lgm_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return lgm_pwm_enable(chip, 1);
|
||||
}
|
||||
|
||||
static void lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
|
||||
u32 duty, val;
|
||||
@@ -100,6 +100,8 @@ static void lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
regmap_read(pc->regmap, LGM_PWM_FAN_CON0, &val);
|
||||
duty = FIELD_GET(LGM_PWM_FAN_DC_MSK, val);
|
||||
state->duty_cycle = DIV_ROUND_UP(duty * pc->period, LGM_PWM_MAX_DUTY_CYCLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops lgm_pwm_ops = {
|
||||
|
||||
@@ -47,8 +47,8 @@ static int iqs620_pwm_init(struct iqs620_pwm_private *iqs620_pwm,
|
||||
int ret;
|
||||
|
||||
if (!duty_scale)
|
||||
return regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
|
||||
IQS620_PWR_SETTINGS_PWM_OUT, 0);
|
||||
return regmap_clear_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
|
||||
IQS620_PWR_SETTINGS_PWM_OUT);
|
||||
|
||||
ret = regmap_write(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE,
|
||||
duty_scale - 1);
|
||||
@@ -104,8 +104,8 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct iqs620_pwm_private *iqs620_pwm;
|
||||
|
||||
@@ -126,6 +126,8 @@ static void iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
mutex_unlock(&iqs620_pwm->lock);
|
||||
|
||||
state->period = IQS620_PWM_PERIOD_NS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iqs620_pwm_notifier(struct notifier_block *notifier,
|
||||
|
||||
@@ -88,8 +88,7 @@ static int jz4740_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
struct jz4740_pwm_chip *jz = to_jz4740(chip);
|
||||
|
||||
/* Enable PWM output */
|
||||
regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
|
||||
TCU_TCSR_PWM_EN, TCU_TCSR_PWM_EN);
|
||||
regmap_set_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm), TCU_TCSR_PWM_EN);
|
||||
|
||||
/* Start counter */
|
||||
regmap_write(jz->map, TCU_REG_TESR, BIT(pwm->hwpwm));
|
||||
@@ -113,8 +112,7 @@ static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
* In TCU2 mode (channel 1/2 on JZ4750+), this must be done before the
|
||||
* counter is stopped, while in TCU1 mode the order does not matter.
|
||||
*/
|
||||
regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
|
||||
TCU_TCSR_PWM_EN, 0);
|
||||
regmap_clear_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm), TCU_TCSR_PWM_EN);
|
||||
|
||||
/* Stop counter */
|
||||
regmap_write(jz->map, TCU_REG_TECR, BIT(pwm->hwpwm));
|
||||
@@ -184,8 +182,8 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
regmap_write(jz4740->map, TCU_REG_TDFRc(pwm->hwpwm), period);
|
||||
|
||||
/* Set abrupt shutdown */
|
||||
regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
|
||||
TCU_TCSR_PWM_SD, TCU_TCSR_PWM_SD);
|
||||
regmap_set_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
|
||||
TCU_TCSR_PWM_SD);
|
||||
|
||||
/*
|
||||
* Set polarity.
|
||||
@@ -248,19 +246,18 @@ static int jz4740_pwm_probe(struct platform_device *pdev)
|
||||
return devm_pwmchip_add(dev, &jz4740->chip);
|
||||
}
|
||||
|
||||
static const struct soc_info __maybe_unused jz4740_soc_info = {
|
||||
static const struct soc_info jz4740_soc_info = {
|
||||
.num_pwms = 8,
|
||||
};
|
||||
|
||||
static const struct soc_info __maybe_unused jz4725b_soc_info = {
|
||||
static const struct soc_info jz4725b_soc_info = {
|
||||
.num_pwms = 6,
|
||||
};
|
||||
|
||||
static const struct soc_info __maybe_unused x1000_soc_info = {
|
||||
static const struct soc_info x1000_soc_info = {
|
||||
.num_pwms = 5,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id jz4740_pwm_dt_ids[] = {
|
||||
{ .compatible = "ingenic,jz4740-pwm", .data = &jz4740_soc_info },
|
||||
{ .compatible = "ingenic,jz4725b-pwm", .data = &jz4725b_soc_info },
|
||||
@@ -268,12 +265,11 @@ static const struct of_device_id jz4740_pwm_dt_ids[] = {
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, jz4740_pwm_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct platform_driver jz4740_pwm_driver = {
|
||||
.driver = {
|
||||
.name = "jz4740-pwm",
|
||||
.of_match_table = of_match_ptr(jz4740_pwm_dt_ids),
|
||||
.of_match_table = jz4740_pwm_dt_ids,
|
||||
},
|
||||
.probe = jz4740_pwm_probe,
|
||||
};
|
||||
|
||||
@@ -89,8 +89,8 @@ static void keembay_pwm_disable(struct keembay_pwm *priv, int ch)
|
||||
KMB_PWM_LEADIN_OFFSET(ch));
|
||||
}
|
||||
|
||||
static void keembay_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int keembay_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct keembay_pwm *priv = to_keembay_pwm_dev(chip);
|
||||
unsigned long long high, low;
|
||||
@@ -113,6 +113,8 @@ static void keembay_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
state->duty_cycle = DIV_ROUND_UP_ULL(high, clk_rate);
|
||||
state->period = DIV_ROUND_UP_ULL(high + low, clk_rate);
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int keembay_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
@@ -175,7 +175,7 @@ static void lpc18xx_pwm_config_duty(struct pwm_chip *chip,
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* With clk_rate < NSEC_PER_SEC this cannot overflow.
|
||||
* With clk_rate <= NSEC_PER_SEC this cannot overflow.
|
||||
* With duty_ns <= period_ns < max_period_ns this also fits into an u32.
|
||||
*/
|
||||
val = mul_u64_u64_div_u64(duty_ns, lpc18xx_pwm->clk_rate, NSEC_PER_SEC);
|
||||
|
||||
@@ -205,8 +205,8 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct pwm_lpss_chip *lpwm = to_lpwm(chip);
|
||||
unsigned long base_unit_range;
|
||||
@@ -236,6 +236,8 @@ static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
state->enabled = !!(ctrl & PWM_ENABLE);
|
||||
|
||||
pm_runtime_put(chip->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops pwm_lpss_ops = {
|
||||
|
||||
@@ -296,7 +296,7 @@ static const struct pwm_mediatek_of_data mt6795_pwm_data = {
|
||||
static const struct pwm_mediatek_of_data mt7622_pwm_data = {
|
||||
.num_pwms = 6,
|
||||
.pwm45_fixup = false,
|
||||
.has_ck_26m_sel = false,
|
||||
.has_ck_26m_sel = true,
|
||||
};
|
||||
|
||||
static const struct pwm_mediatek_of_data mt7623_pwm_data = {
|
||||
@@ -329,6 +329,12 @@ static const struct pwm_mediatek_of_data mt8365_pwm_data = {
|
||||
.has_ck_26m_sel = true,
|
||||
};
|
||||
|
||||
static const struct pwm_mediatek_of_data mt7986_pwm_data = {
|
||||
.num_pwms = 2,
|
||||
.pwm45_fixup = false,
|
||||
.has_ck_26m_sel = true,
|
||||
};
|
||||
|
||||
static const struct pwm_mediatek_of_data mt8516_pwm_data = {
|
||||
.num_pwms = 5,
|
||||
.pwm45_fixup = false,
|
||||
@@ -342,6 +348,7 @@ static const struct of_device_id pwm_mediatek_of_match[] = {
|
||||
{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
|
||||
{ .compatible = "mediatek,mt7628-pwm", .data = &mt7628_pwm_data },
|
||||
{ .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
|
||||
{ .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
|
||||
{ .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
|
||||
{ .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
|
||||
{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
|
||||
|
||||
@@ -318,8 +318,8 @@ static unsigned int meson_pwm_cnt_to_ns(struct pwm_chip *chip,
|
||||
return cnt * fin_ns * (channel->pre_div + 1);
|
||||
}
|
||||
|
||||
static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct meson_pwm *meson = to_meson_pwm(chip);
|
||||
struct meson_pwm_channel_data *channel_data;
|
||||
@@ -327,7 +327,7 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
u32 value, tmp;
|
||||
|
||||
if (!state)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
channel = &meson->channels[pwm->hwpwm];
|
||||
channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
|
||||
@@ -357,6 +357,8 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
state->period = 0;
|
||||
state->duty_cycle = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops meson_pwm_ops = {
|
||||
|
||||
@@ -172,32 +172,33 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int mtk_disp_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
|
||||
u64 rate, period, high_width;
|
||||
u32 clk_div, con0, con1;
|
||||
u32 clk_div, pwm_en, con0, con1;
|
||||
int err;
|
||||
|
||||
err = clk_prepare_enable(mdp->clk_main);
|
||||
if (err < 0) {
|
||||
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
|
||||
return;
|
||||
return err;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(mdp->clk_mm);
|
||||
if (err < 0) {
|
||||
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
|
||||
clk_disable_unprepare(mdp->clk_main);
|
||||
return;
|
||||
return err;
|
||||
}
|
||||
|
||||
rate = clk_get_rate(mdp->clk_main);
|
||||
con0 = readl(mdp->base + mdp->data->con0);
|
||||
con1 = readl(mdp->base + mdp->data->con1);
|
||||
state->enabled = !!(con0 & BIT(0));
|
||||
pwm_en = readl(mdp->base + DISP_PWM_EN);
|
||||
state->enabled = !!(pwm_en & mdp->data->enable_mask);
|
||||
clk_div = FIELD_GET(PWM_CLKDIV_MASK, con0);
|
||||
period = FIELD_GET(PWM_PERIOD_MASK, con1);
|
||||
/*
|
||||
@@ -211,6 +212,8 @@ static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
clk_disable_unprepare(mdp->clk_mm);
|
||||
clk_disable_unprepare(mdp->clk_main);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops mtk_disp_pwm_ops = {
|
||||
|
||||
@@ -431,8 +431,8 @@ static int pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct pca9685 *pca = to_pca(chip);
|
||||
unsigned long long duty;
|
||||
@@ -458,12 +458,14 @@ static void pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
*/
|
||||
state->duty_cycle = 0;
|
||||
state->enabled = false;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
state->enabled = true;
|
||||
duty = pca9685_pwm_get_duty(pca, pwm->hwpwm);
|
||||
state->duty_cycle = DIV_ROUND_DOWN_ULL(duty * state->period, PCA9685_COUNTER_RANGE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
@@ -513,8 +515,7 @@ static const struct regmap_config pca9685_regmap_i2c_config = {
|
||||
.cache_type = REGCACHE_NONE,
|
||||
};
|
||||
|
||||
static int pca9685_pwm_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int pca9685_pwm_probe(struct i2c_client *client)
|
||||
{
|
||||
struct pca9685 *pca;
|
||||
unsigned int reg;
|
||||
@@ -664,7 +665,7 @@ static struct i2c_driver pca9685_i2c_driver = {
|
||||
.of_match_table = of_match_ptr(pca9685_dt_ids),
|
||||
.pm = &pca9685_pwm_pm,
|
||||
},
|
||||
.probe = pca9685_pwm_probe,
|
||||
.probe_new = pca9685_pwm_probe,
|
||||
.remove = pca9685_pwm_remove,
|
||||
.id_table = pca9685_id,
|
||||
};
|
||||
|
||||
+26
-34
@@ -6,6 +6,13 @@
|
||||
*
|
||||
* 2008-02-13 initial version
|
||||
* eric miao <eric.miao@marvell.com>
|
||||
*
|
||||
* Links to reference manuals for some of the supported PWM chips can be found
|
||||
* in Documentation/arm/marvell.rst.
|
||||
*
|
||||
* Limitations:
|
||||
* - When PWM is stopped, the current PWM period stops abruptly at the next
|
||||
* input clock (PWMCR_SD is set) and the output is driven to inactive.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -64,7 +71,6 @@ static int pxa_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
unsigned long long c;
|
||||
unsigned long period_cycles, prescale, pv, dc;
|
||||
unsigned long offset;
|
||||
int rc;
|
||||
|
||||
offset = pwm->hwpwm ? 0x10 : 0;
|
||||
|
||||
@@ -86,56 +92,42 @@ static int pxa_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
else
|
||||
dc = mul_u64_u64_div_u64(pv + 1, duty_ns, period_ns);
|
||||
|
||||
/* NOTE: the clock to PWM has to be enabled first
|
||||
* before writing to the registers
|
||||
*/
|
||||
rc = clk_prepare_enable(pc->clk);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
writel(prescale, pc->mmio_base + offset + PWMCR);
|
||||
writel(prescale | PWMCR_SD, pc->mmio_base + offset + PWMCR);
|
||||
writel(dc, pc->mmio_base + offset + PWMDCR);
|
||||
writel(pv, pc->mmio_base + offset + PWMPCR);
|
||||
|
||||
clk_disable_unprepare(pc->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pxa_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
{
|
||||
struct pxa_pwm_chip *pc = to_pxa_pwm_chip(chip);
|
||||
|
||||
return clk_prepare_enable(pc->clk);
|
||||
}
|
||||
|
||||
static void pxa_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
{
|
||||
struct pxa_pwm_chip *pc = to_pxa_pwm_chip(chip);
|
||||
|
||||
clk_disable_unprepare(pc->clk);
|
||||
}
|
||||
|
||||
static int pxa_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
const struct pwm_state *state)
|
||||
{
|
||||
struct pxa_pwm_chip *pc = to_pxa_pwm_chip(chip);
|
||||
u64 duty_cycle;
|
||||
int err;
|
||||
|
||||
if (state->polarity != PWM_POLARITY_NORMAL)
|
||||
return -EINVAL;
|
||||
|
||||
if (!state->enabled) {
|
||||
if (pwm->state.enabled)
|
||||
pxa_pwm_disable(chip, pwm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = pxa_pwm_config(chip, pwm, state->duty_cycle, state->period);
|
||||
err = clk_prepare_enable(pc->clk);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!pwm->state.enabled)
|
||||
return pxa_pwm_enable(chip, pwm);
|
||||
duty_cycle = state->enabled ? state->duty_cycle : 0;
|
||||
|
||||
err = pxa_pwm_config(chip, pwm, duty_cycle, state->period);
|
||||
if (err) {
|
||||
clk_disable_unprepare(pc->clk);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (state->enabled && !pwm->state.enabled)
|
||||
return 0;
|
||||
|
||||
clk_disable_unprepare(pc->clk);
|
||||
|
||||
if (!state->enabled && pwm->state.enabled)
|
||||
clk_disable_unprepare(pc->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -82,9 +82,9 @@ static int raspberrypi_pwm_get_property(struct rpi_firmware *firmware,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void raspberrypi_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int raspberrypi_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct raspberrypi_pwm *rpipwm = raspberrypi_pwm_from_chip(chip);
|
||||
|
||||
@@ -93,6 +93,8 @@ static void raspberrypi_pwm_get_state(struct pwm_chip *chip,
|
||||
RPI_PWM_MAX_DUTY);
|
||||
state->enabled = !!(rpipwm->duty_cycle);
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int raspberrypi_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
@@ -57,9 +57,9 @@ static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
|
||||
return container_of(c, struct rockchip_pwm_chip, chip);
|
||||
}
|
||||
|
||||
static void rockchip_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int rockchip_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
|
||||
u32 enable_conf = pc->data->enable_conf;
|
||||
@@ -70,11 +70,11 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
|
||||
|
||||
ret = clk_enable(pc->pclk);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
ret = clk_enable(pc->clk);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
clk_rate = clk_get_rate(pc->clk);
|
||||
|
||||
@@ -96,6 +96,8 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
|
||||
|
||||
clk_disable(pc->clk);
|
||||
clk_disable(pc->pclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
@@ -105,8 +105,8 @@ static void pwm_sifive_update_clock(struct pwm_sifive_ddata *ddata,
|
||||
"New real_period = %u ns\n", ddata->real_period);
|
||||
}
|
||||
|
||||
static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct pwm_sifive_ddata *ddata = pwm_sifive_chip_to_ddata(chip);
|
||||
u32 duty, val;
|
||||
@@ -123,6 +123,8 @@ static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
state->duty_cycle =
|
||||
(u64)duty * ddata->real_period >> PWM_SIFIVE_CMPWIDTH;
|
||||
state->polarity = PWM_POLARITY_INVERSED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
@@ -204,8 +206,11 @@ static int pwm_sifive_clock_notifier(struct notifier_block *nb,
|
||||
struct pwm_sifive_ddata *ddata =
|
||||
container_of(nb, struct pwm_sifive_ddata, notifier);
|
||||
|
||||
if (event == POST_RATE_CHANGE)
|
||||
if (event == POST_RATE_CHANGE) {
|
||||
mutex_lock(&ddata->lock);
|
||||
pwm_sifive_update_clock(ddata, ndata->new_rate);
|
||||
mutex_unlock(&ddata->lock);
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
@@ -87,9 +87,9 @@ struct sl28cpld_pwm {
|
||||
#define sl28cpld_pwm_from_chip(_chip) \
|
||||
container_of(_chip, struct sl28cpld_pwm, pwm_chip)
|
||||
|
||||
static void sl28cpld_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int sl28cpld_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct sl28cpld_pwm *priv = sl28cpld_pwm_from_chip(chip);
|
||||
unsigned int reg;
|
||||
@@ -115,6 +115,8 @@ static void sl28cpld_pwm_get_state(struct pwm_chip *chip,
|
||||
* the PWM core.
|
||||
*/
|
||||
state->duty_cycle = min(state->duty_cycle, state->period);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sl28cpld_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
@@ -65,8 +65,8 @@ static void sprd_pwm_write(struct sprd_pwm_chip *spc, u32 hwid,
|
||||
writel_relaxed(val, spc->base + offset);
|
||||
}
|
||||
|
||||
static void sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct sprd_pwm_chip *spc =
|
||||
container_of(chip, struct sprd_pwm_chip, chip);
|
||||
@@ -83,7 +83,7 @@ static void sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
if (ret) {
|
||||
dev_err(spc->dev, "failed to enable pwm%u clocks\n",
|
||||
pwm->hwpwm);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_ENABLE);
|
||||
@@ -113,6 +113,8 @@ static void sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
/* Disable PWM clocks if the PWM channel is not in enable state. */
|
||||
if (!state->enabled)
|
||||
clk_bulk_disable_unprepare(SPRD_PWM_CHN_CLKS_NUM, chn->clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sprd_pwm_config(struct sprd_pwm_chip *spc, struct pwm_device *pwm,
|
||||
|
||||
@@ -140,9 +140,8 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
if (reenable) {
|
||||
/* Start LP timer in continuous mode */
|
||||
ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
|
||||
STM32_LPTIM_CNTSTRT,
|
||||
STM32_LPTIM_CNTSTRT);
|
||||
ret = regmap_set_bits(priv->regmap, STM32_LPTIM_CR,
|
||||
STM32_LPTIM_CNTSTRT);
|
||||
if (ret) {
|
||||
regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
|
||||
goto err;
|
||||
@@ -157,9 +156,9 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void stm32_pwm_lp_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip);
|
||||
unsigned long rate = clk_get_rate(priv->clk);
|
||||
@@ -185,6 +184,8 @@ static void stm32_pwm_lp_get_state(struct pwm_chip *chip,
|
||||
tmp = prd - val;
|
||||
tmp = (tmp << presc) * NSEC_PER_SEC;
|
||||
state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops stm32_pwm_lp_ops = {
|
||||
|
||||
+16
-18
@@ -115,14 +115,14 @@ static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm,
|
||||
int ret;
|
||||
|
||||
/* Ensure registers have been updated, enable counter and capture */
|
||||
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
|
||||
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
|
||||
regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG);
|
||||
regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
|
||||
|
||||
/* Use cc1 or cc3 DMA resp for PWM input channels 1 & 2 or 3 & 4 */
|
||||
dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3;
|
||||
ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E;
|
||||
ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3;
|
||||
regmap_update_bits(priv->regmap, TIM_CCER, ccen, ccen);
|
||||
regmap_set_bits(priv->regmap, TIM_CCER, ccen);
|
||||
|
||||
/*
|
||||
* Timer DMA burst mode. Request 2 registers, 2 bursts, to get both
|
||||
@@ -160,8 +160,8 @@ static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm,
|
||||
}
|
||||
|
||||
stop:
|
||||
regmap_update_bits(priv->regmap, TIM_CCER, ccen, 0);
|
||||
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
|
||||
regmap_clear_bits(priv->regmap, TIM_CCER, ccen);
|
||||
regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -359,7 +359,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch,
|
||||
|
||||
regmap_write(priv->regmap, TIM_PSC, prescaler);
|
||||
regmap_write(priv->regmap, TIM_ARR, prd - 1);
|
||||
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
|
||||
regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE);
|
||||
|
||||
/* Calculate the duty cycles */
|
||||
dty = prd * duty_ns;
|
||||
@@ -377,7 +377,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch,
|
||||
else
|
||||
regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr);
|
||||
|
||||
regmap_update_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE, TIM_BDTR_MOE);
|
||||
regmap_set_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -411,13 +411,13 @@ static int stm32_pwm_enable(struct stm32_pwm *priv, int ch)
|
||||
if (priv->have_complementary_output)
|
||||
mask |= TIM_CCER_CC1NE << (ch * 4);
|
||||
|
||||
regmap_update_bits(priv->regmap, TIM_CCER, mask, mask);
|
||||
regmap_set_bits(priv->regmap, TIM_CCER, mask);
|
||||
|
||||
/* Make sure that registers are updated */
|
||||
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
|
||||
regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG);
|
||||
|
||||
/* Enable controller */
|
||||
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
|
||||
regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -431,11 +431,11 @@ static void stm32_pwm_disable(struct stm32_pwm *priv, int ch)
|
||||
if (priv->have_complementary_output)
|
||||
mask |= TIM_CCER_CC1NE << (ch * 4);
|
||||
|
||||
regmap_update_bits(priv->regmap, TIM_CCER, mask, 0);
|
||||
regmap_clear_bits(priv->regmap, TIM_CCER, mask);
|
||||
|
||||
/* When all channels are disabled, we can disable the controller */
|
||||
if (!active_channels(priv))
|
||||
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
|
||||
regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
|
||||
|
||||
clk_disable(priv->clk);
|
||||
}
|
||||
@@ -568,10 +568,9 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
|
||||
* If complementary bit doesn't exist writing 1 will have no
|
||||
* effect so we can detect it.
|
||||
*/
|
||||
regmap_update_bits(priv->regmap,
|
||||
TIM_CCER, TIM_CCER_CC1NE, TIM_CCER_CC1NE);
|
||||
regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE);
|
||||
regmap_read(priv->regmap, TIM_CCER, &ccer);
|
||||
regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE, 0);
|
||||
regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE);
|
||||
|
||||
priv->have_complementary_output = (ccer != 0);
|
||||
}
|
||||
@@ -585,10 +584,9 @@ static int stm32_pwm_detect_channels(struct stm32_pwm *priv)
|
||||
* If channels enable bits don't exist writing 1 will have no
|
||||
* effect so we can detect and count them.
|
||||
*/
|
||||
regmap_update_bits(priv->regmap,
|
||||
TIM_CCER, TIM_CCER_CCXE, TIM_CCER_CCXE);
|
||||
regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE);
|
||||
regmap_read(priv->regmap, TIM_CCER, &ccer);
|
||||
regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE, 0);
|
||||
regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE);
|
||||
|
||||
if (ccer & TIM_CCER_CC1E)
|
||||
npwm++;
|
||||
|
||||
@@ -108,9 +108,9 @@ static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
|
||||
writel(val, chip->base + offset);
|
||||
}
|
||||
|
||||
static void sun4i_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int sun4i_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
|
||||
u64 clk_rate, tmp;
|
||||
@@ -118,6 +118,8 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
|
||||
unsigned int prescaler;
|
||||
|
||||
clk_rate = clk_get_rate(sun4i_pwm->clk);
|
||||
if (!clk_rate)
|
||||
return -EINVAL;
|
||||
|
||||
val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
|
||||
|
||||
@@ -132,7 +134,7 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
|
||||
state->duty_cycle = DIV_ROUND_UP_ULL(state->period, 2);
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
state->enabled = true;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((PWM_REG_PRESCAL(val, pwm->hwpwm) == PWM_PRESCAL_MASK) &&
|
||||
@@ -142,7 +144,7 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
|
||||
prescaler = prescaler_table[PWM_REG_PRESCAL(val, pwm->hwpwm)];
|
||||
|
||||
if (prescaler == 0)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
if (val & BIT_CH(PWM_ACT_STATE, pwm->hwpwm))
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
@@ -162,6 +164,8 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
|
||||
|
||||
tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_PRD(val);
|
||||
state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
|
||||
|
||||
@@ -124,8 +124,8 @@ static int sunplus_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sunplus_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int sunplus_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct sunplus_pwm *priv = to_sunplus_pwm(chip);
|
||||
u32 mode0, dd_freq, duty;
|
||||
@@ -155,6 +155,8 @@ static void sunplus_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
}
|
||||
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops sunplus_pwm_ops = {
|
||||
|
||||
+13
-2
@@ -145,8 +145,19 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
* source clock rate as required_clk_rate, PWM controller will
|
||||
* be able to configure the requested period.
|
||||
*/
|
||||
required_clk_rate =
|
||||
(NSEC_PER_SEC / period_ns) << PWM_DUTY_WIDTH;
|
||||
required_clk_rate = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC << PWM_DUTY_WIDTH,
|
||||
period_ns);
|
||||
|
||||
if (required_clk_rate > clk_round_rate(pc->clk, required_clk_rate))
|
||||
/*
|
||||
* required_clk_rate is a lower bound for the input
|
||||
* rate; for lower rates there is no value for PWM_SCALE
|
||||
* that yields a period less than or equal to the
|
||||
* requested period. Hence, for lower rates, double the
|
||||
* required_clk_rate to get a clock rate that can meet
|
||||
* the requested period.
|
||||
*/
|
||||
required_clk_rate *= 2;
|
||||
|
||||
err = dev_pm_opp_set_rate(pc->dev, required_clk_rate);
|
||||
if (err < 0)
|
||||
|
||||
@@ -103,8 +103,8 @@ static int visconti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void visconti_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
static int visconti_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct visconti_pwm_chip *priv = visconti_pwm_from_chip(chip);
|
||||
u32 period, duty, pwmc0, pwmc0_clk;
|
||||
@@ -122,6 +122,8 @@ static void visconti_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
state->enabled = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops visconti_pwm_ops = {
|
||||
|
||||
@@ -169,9 +169,9 @@ static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xilinx_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *unused,
|
||||
struct pwm_state *state)
|
||||
static int xilinx_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *unused,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
|
||||
u32 tlr0, tlr1, tcsr0, tcsr1;
|
||||
@@ -191,6 +191,8 @@ static void xilinx_pwm_get_state(struct pwm_chip *chip,
|
||||
*/
|
||||
if (state->period == state->duty_cycle)
|
||||
state->duty_cycle = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops xilinx_pwm_ops = {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ static void qla24xx_abort_iocb_timeout(void *data)
|
||||
struct qla_qpair *qpair = sp->qpair;
|
||||
u32 handle;
|
||||
unsigned long flags;
|
||||
int sp_found = 0, cmdsp_found = 0;
|
||||
|
||||
if (sp->cmd_sp)
|
||||
ql_dbg(ql_dbg_async, sp->vha, 0x507c,
|
||||
@@ -124,18 +125,21 @@ static void qla24xx_abort_iocb_timeout(void *data)
|
||||
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
|
||||
for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
|
||||
if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
|
||||
sp->cmd_sp))
|
||||
sp->cmd_sp)) {
|
||||
qpair->req->outstanding_cmds[handle] = NULL;
|
||||
cmdsp_found = 1;
|
||||
}
|
||||
|
||||
/* removing the abort */
|
||||
if (qpair->req->outstanding_cmds[handle] == sp) {
|
||||
qpair->req->outstanding_cmds[handle] = NULL;
|
||||
sp_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
|
||||
|
||||
if (sp->cmd_sp) {
|
||||
if (cmdsp_found && sp->cmd_sp) {
|
||||
/*
|
||||
* This done function should take care of
|
||||
* original command ref: INIT
|
||||
@@ -143,8 +147,10 @@ static void qla24xx_abort_iocb_timeout(void *data)
|
||||
sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
|
||||
}
|
||||
|
||||
abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
|
||||
sp->done(sp, QLA_OS_TIMER_EXPIRED);
|
||||
if (sp_found) {
|
||||
abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
|
||||
sp->done(sp, QLA_OS_TIMER_EXPIRED);
|
||||
}
|
||||
}
|
||||
|
||||
static void qla24xx_abort_sp_done(srb_t *sp, int res)
|
||||
|
||||
@@ -376,7 +376,7 @@ static int scsi_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
|
||||
* fill in all the output members
|
||||
*/
|
||||
hdr->status = scmd->result & 0xff;
|
||||
hdr->masked_status = status_byte(scmd->result);
|
||||
hdr->masked_status = sg_status_byte(scmd->result);
|
||||
hdr->msg_status = COMMAND_COMPLETE;
|
||||
hdr->host_status = host_byte(scmd->result);
|
||||
hdr->driver_status = 0;
|
||||
|
||||
+34
-1
@@ -1709,6 +1709,36 @@ static char sd_pr_type(enum pr_type type)
|
||||
}
|
||||
};
|
||||
|
||||
static int sd_scsi_to_pr_err(struct scsi_sense_hdr *sshdr, int result)
|
||||
{
|
||||
switch (host_byte(result)) {
|
||||
case DID_TRANSPORT_MARGINAL:
|
||||
case DID_TRANSPORT_DISRUPTED:
|
||||
case DID_BUS_BUSY:
|
||||
return PR_STS_RETRY_PATH_FAILURE;
|
||||
case DID_NO_CONNECT:
|
||||
return PR_STS_PATH_FAILED;
|
||||
case DID_TRANSPORT_FAILFAST:
|
||||
return PR_STS_PATH_FAST_FAILED;
|
||||
}
|
||||
|
||||
switch (status_byte(result)) {
|
||||
case SAM_STAT_RESERVATION_CONFLICT:
|
||||
return PR_STS_RESERVATION_CONFLICT;
|
||||
case SAM_STAT_CHECK_CONDITION:
|
||||
if (!scsi_sense_valid(sshdr))
|
||||
return PR_STS_IOERR;
|
||||
|
||||
if (sshdr->sense_key == ILLEGAL_REQUEST &&
|
||||
(sshdr->asc == 0x26 || sshdr->asc == 0x24))
|
||||
return -EINVAL;
|
||||
|
||||
fallthrough;
|
||||
default:
|
||||
return PR_STS_IOERR;
|
||||
}
|
||||
}
|
||||
|
||||
static int sd_pr_command(struct block_device *bdev, u8 sa,
|
||||
u64 key, u64 sa_key, u8 type, u8 flags)
|
||||
{
|
||||
@@ -1737,7 +1767,10 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
|
||||
scsi_print_sense_hdr(sdev, NULL, &sshdr);
|
||||
}
|
||||
|
||||
return result;
|
||||
if (result <= 0)
|
||||
return result;
|
||||
|
||||
return sd_scsi_to_pr_err(&sshdr, result);
|
||||
}
|
||||
|
||||
static int sd_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 Western Digital Corporation or its affiliates.
|
||||
*/
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM sd
|
||||
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE sd_trace
|
||||
|
||||
#if !defined(_SD_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
TRACE_EVENT(scsi_prepare_zone_append,
|
||||
|
||||
TP_PROTO(struct scsi_cmnd *cmnd, sector_t lba,
|
||||
unsigned int wp_offset),
|
||||
|
||||
TP_ARGS(cmnd, lba, wp_offset),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field( unsigned int, host_no )
|
||||
__field( unsigned int, channel )
|
||||
__field( unsigned int, id )
|
||||
__field( unsigned int, lun )
|
||||
__field( sector_t, lba )
|
||||
__field( unsigned int, wp_offset )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->host_no = cmnd->device->host->host_no;
|
||||
__entry->channel = cmnd->device->channel;
|
||||
__entry->id = cmnd->device->id;
|
||||
__entry->lun = cmnd->device->lun;
|
||||
__entry->lba = lba;
|
||||
__entry->wp_offset = wp_offset;
|
||||
),
|
||||
|
||||
TP_printk("host_no=%u, channel=%u id=%u lun=%u lba=%llu wp_offset=%u",
|
||||
__entry->host_no, __entry->channel, __entry->id,
|
||||
__entry->lun, __entry->lba, __entry->wp_offset)
|
||||
);
|
||||
|
||||
TRACE_EVENT(scsi_zone_wp_update,
|
||||
|
||||
TP_PROTO(struct scsi_cmnd *cmnd, sector_t rq_sector,
|
||||
unsigned int wp_offset, unsigned int good_bytes),
|
||||
|
||||
TP_ARGS(cmnd, rq_sector, wp_offset, good_bytes),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field( unsigned int, host_no )
|
||||
__field( unsigned int, channel )
|
||||
__field( unsigned int, id )
|
||||
__field( unsigned int, lun )
|
||||
__field( sector_t, rq_sector )
|
||||
__field( unsigned int, wp_offset )
|
||||
__field( unsigned int, good_bytes )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->host_no = cmnd->device->host->host_no;
|
||||
__entry->channel = cmnd->device->channel;
|
||||
__entry->id = cmnd->device->id;
|
||||
__entry->lun = cmnd->device->lun;
|
||||
__entry->rq_sector = rq_sector;
|
||||
__entry->wp_offset = wp_offset;
|
||||
__entry->good_bytes = good_bytes;
|
||||
),
|
||||
|
||||
TP_printk("host_no=%u, channel=%u id=%u lun=%u rq_sector=%llu" \
|
||||
" wp_offset=%u good_bytes=%u",
|
||||
__entry->host_no, __entry->channel, __entry->id,
|
||||
__entry->lun, __entry->rq_sector, __entry->wp_offset,
|
||||
__entry->good_bytes)
|
||||
);
|
||||
#endif /* _SD_TRACE_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH ../../drivers/scsi
|
||||
#include <trace/define_trace.h>
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
#include "sd.h"
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "sd_trace.h"
|
||||
|
||||
/**
|
||||
* sd_zbc_get_zone_wp_offset - Get zone write pointer offset.
|
||||
* @zone: Zone for which to return the write pointer offset.
|
||||
@@ -450,6 +453,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba,
|
||||
break;
|
||||
}
|
||||
|
||||
trace_scsi_prepare_zone_append(cmd, *lba, wp_offset);
|
||||
*lba += wp_offset;
|
||||
}
|
||||
spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags);
|
||||
@@ -558,6 +562,8 @@ static unsigned int sd_zbc_zone_wp_update(struct scsi_cmnd *cmd,
|
||||
|
||||
switch (op) {
|
||||
case REQ_OP_ZONE_APPEND:
|
||||
trace_scsi_zone_wp_update(cmd, rq->__sector,
|
||||
sdkp->zones_wp_offset[zno], good_bytes);
|
||||
rq->__sector += sdkp->zones_wp_offset[zno];
|
||||
fallthrough;
|
||||
case REQ_OP_WRITE_ZEROES:
|
||||
|
||||
+1
-1
@@ -1349,7 +1349,7 @@ sg_rq_end_io(struct request *rq, blk_status_t status)
|
||||
struct scsi_sense_hdr sshdr;
|
||||
|
||||
srp->header.status = 0xff & result;
|
||||
srp->header.masked_status = status_byte(result);
|
||||
srp->header.masked_status = sg_status_byte(result);
|
||||
srp->header.msg_status = COMMAND_COMPLETE;
|
||||
srp->header.host_status = host_byte(result);
|
||||
srp->header.driver_status = driver_byte(result);
|
||||
|
||||
@@ -183,8 +183,8 @@ void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev)
|
||||
if (state->configured)
|
||||
goto complete;
|
||||
|
||||
sun6i_isp_params_configure_modules(isp_dev,
|
||||
&sun6i_isp_params_config_default);
|
||||
sun6i_isp_params_configure_modules(isp_dev,
|
||||
&sun6i_isp_params_config_default);
|
||||
|
||||
state->configured = true;
|
||||
|
||||
@@ -208,6 +208,8 @@ static void sun6i_isp_params_state_cleanup(struct sun6i_isp_device *isp_dev,
|
||||
vb2_buffer = &state->pending->v4l2_buffer.vb2_buf;
|
||||
vb2_buffer_done(vb2_buffer, error ? VB2_BUF_STATE_ERROR :
|
||||
VB2_BUF_STATE_QUEUED);
|
||||
|
||||
state->pending = NULL;
|
||||
}
|
||||
|
||||
list_for_each_entry(isp_buffer, &state->queue, list) {
|
||||
|
||||
@@ -173,8 +173,7 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
|
||||
struct sun6i_isp_proc_source *source;
|
||||
struct v4l2_subdev *source_subdev;
|
||||
struct media_pad *remote_pad;
|
||||
/* Initialize to 0 to use both in disable label (ret != 0) and off. */
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
/* Source */
|
||||
|
||||
@@ -195,6 +194,7 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
|
||||
if (!on) {
|
||||
sun6i_isp_proc_irq_disable(isp_dev);
|
||||
v4l2_subdev_call(source_subdev, video, s_stream, 0);
|
||||
ret = 0;
|
||||
goto disable;
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ static const struct v4l2_subdev_pad_ops sun6i_isp_proc_pad_ops = {
|
||||
.set_fmt = sun6i_isp_proc_set_fmt,
|
||||
};
|
||||
|
||||
const struct v4l2_subdev_ops sun6i_isp_proc_subdev_ops = {
|
||||
static const struct v4l2_subdev_ops sun6i_isp_proc_subdev_ops = {
|
||||
.video = &sun6i_isp_proc_video_ops,
|
||||
.pad = &sun6i_isp_proc_pad_ops,
|
||||
};
|
||||
@@ -416,7 +416,7 @@ static int sun6i_isp_proc_notifier_bound(struct v4l2_async_notifier *notifier,
|
||||
enabled = !proc->source_csi0.expected;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
source->subdev = remote_subdev;
|
||||
|
||||
@@ -77,6 +77,7 @@ const struct address_space_operations afs_dir_aops = {
|
||||
.dirty_folio = afs_dir_dirty_folio,
|
||||
.release_folio = afs_dir_release_folio,
|
||||
.invalidate_folio = afs_dir_invalidate_folio,
|
||||
.migrate_folio = filemap_migrate_folio,
|
||||
};
|
||||
|
||||
const struct dentry_operations afs_fs_dentry_operations = {
|
||||
|
||||
+2
-1
@@ -58,14 +58,15 @@ const struct address_space_operations afs_file_aops = {
|
||||
.invalidate_folio = afs_invalidate_folio,
|
||||
.write_begin = afs_write_begin,
|
||||
.write_end = afs_write_end,
|
||||
.writepage = afs_writepage,
|
||||
.writepages = afs_writepages,
|
||||
.migrate_folio = filemap_migrate_folio,
|
||||
};
|
||||
|
||||
const struct address_space_operations afs_symlink_aops = {
|
||||
.read_folio = afs_symlink_read_folio,
|
||||
.release_folio = afs_release_folio,
|
||||
.invalidate_folio = afs_invalidate_folio,
|
||||
.migrate_folio = filemap_migrate_folio,
|
||||
};
|
||||
|
||||
static const struct vm_operations_struct afs_vm_ops = {
|
||||
|
||||
+4
-1
@@ -366,12 +366,15 @@ void afs_fs_probe_dispatcher(struct work_struct *work)
|
||||
unsigned long nowj, timer_at, poll_at;
|
||||
bool first_pass = true, set_timer = false;
|
||||
|
||||
if (!net->live)
|
||||
if (!net->live) {
|
||||
afs_dec_servers_outstanding(net);
|
||||
return;
|
||||
}
|
||||
|
||||
_enter("");
|
||||
|
||||
if (list_empty(&net->fs_probe_fast) && list_empty(&net->fs_probe_slow)) {
|
||||
afs_dec_servers_outstanding(net);
|
||||
_leave(" [none]");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -971,13 +971,6 @@ extern int afs_end_cursor(struct afs_addr_cursor *);
|
||||
extern void afs_merge_fs_addr4(struct afs_addr_list *, __be32, u16);
|
||||
extern void afs_merge_fs_addr6(struct afs_addr_list *, __be32 *, u16);
|
||||
|
||||
/*
|
||||
* cache.c
|
||||
*/
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
extern struct fscache_netfs afs_cache_netfs;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* callback.c
|
||||
*/
|
||||
@@ -1391,7 +1384,6 @@ extern void afs_put_permits(struct afs_permits *);
|
||||
extern void afs_clear_permits(struct afs_vnode *);
|
||||
extern void afs_cache_permit(struct afs_vnode *, struct key *, unsigned int,
|
||||
struct afs_status_cb *);
|
||||
extern void afs_zap_permits(struct rcu_head *);
|
||||
extern struct key *afs_request_key(struct afs_cell *);
|
||||
extern struct key *afs_request_key_rcu(struct afs_cell *);
|
||||
extern int afs_check_permit(struct afs_vnode *, struct key *, afs_access_t *);
|
||||
|
||||
+1
-5
@@ -70,11 +70,7 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params,
|
||||
{
|
||||
struct afs_server_list *slist;
|
||||
struct afs_volume *volume;
|
||||
int ret = -ENOMEM, nr_servers = 0, i;
|
||||
|
||||
for (i = 0; i < vldb->nr_servers; i++)
|
||||
if (vldb->fs_mask[i] & type_mask)
|
||||
nr_servers++;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
volume = kzalloc(sizeof(struct afs_volume), GFP_KERNEL);
|
||||
if (!volume)
|
||||
|
||||
+47
-36
@@ -14,6 +14,11 @@
|
||||
#include <linux/netfs.h>
|
||||
#include "internal.h"
|
||||
|
||||
static int afs_writepages_region(struct address_space *mapping,
|
||||
struct writeback_control *wbc,
|
||||
loff_t start, loff_t end, loff_t *_next,
|
||||
bool max_one_loop);
|
||||
|
||||
static void afs_write_to_cache(struct afs_vnode *vnode, loff_t start, size_t len,
|
||||
loff_t i_size, bool caching);
|
||||
|
||||
@@ -38,6 +43,25 @@ static void afs_folio_start_fscache(bool caching, struct folio *folio)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flush out a conflicting write. This may extend the write to the surrounding
|
||||
* pages if also dirty and contiguous to the conflicting region..
|
||||
*/
|
||||
static int afs_flush_conflicting_write(struct address_space *mapping,
|
||||
struct folio *folio)
|
||||
{
|
||||
struct writeback_control wbc = {
|
||||
.sync_mode = WB_SYNC_ALL,
|
||||
.nr_to_write = LONG_MAX,
|
||||
.range_start = folio_pos(folio),
|
||||
.range_end = LLONG_MAX,
|
||||
};
|
||||
loff_t next;
|
||||
|
||||
return afs_writepages_region(mapping, &wbc, folio_pos(folio), LLONG_MAX,
|
||||
&next, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* prepare to perform part of a write to a page
|
||||
*/
|
||||
@@ -80,7 +104,8 @@ try_again:
|
||||
|
||||
if (folio_test_writeback(folio)) {
|
||||
trace_afs_folio_dirty(vnode, tracepoint_string("alrdy"), folio);
|
||||
goto flush_conflicting_write;
|
||||
folio_unlock(folio);
|
||||
goto wait_for_writeback;
|
||||
}
|
||||
/* If the file is being filled locally, allow inter-write
|
||||
* spaces to be merged into writes. If it's not, only write
|
||||
@@ -99,8 +124,15 @@ try_again:
|
||||
* flush the page out.
|
||||
*/
|
||||
flush_conflicting_write:
|
||||
_debug("flush conflict");
|
||||
ret = folio_write_one(folio);
|
||||
trace_afs_folio_dirty(vnode, tracepoint_string("confl"), folio);
|
||||
folio_unlock(folio);
|
||||
|
||||
ret = afs_flush_conflicting_write(mapping, folio);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
wait_for_writeback:
|
||||
ret = folio_wait_writeback_killable(folio);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
@@ -663,40 +695,13 @@ static ssize_t afs_write_back_from_locked_folio(struct address_space *mapping,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* write a page back to the server
|
||||
* - the caller locked the page for us
|
||||
*/
|
||||
int afs_writepage(struct page *subpage, struct writeback_control *wbc)
|
||||
{
|
||||
struct folio *folio = page_folio(subpage);
|
||||
ssize_t ret;
|
||||
loff_t start;
|
||||
|
||||
_enter("{%lx},", folio_index(folio));
|
||||
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
folio_wait_fscache(folio);
|
||||
#endif
|
||||
|
||||
start = folio_index(folio) * PAGE_SIZE;
|
||||
ret = afs_write_back_from_locked_folio(folio_mapping(folio), wbc,
|
||||
folio, start, LLONG_MAX - start);
|
||||
if (ret < 0) {
|
||||
_leave(" = %zd", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_leave(" = 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* write a region of pages back to the server
|
||||
*/
|
||||
static int afs_writepages_region(struct address_space *mapping,
|
||||
struct writeback_control *wbc,
|
||||
loff_t start, loff_t end, loff_t *_next)
|
||||
loff_t start, loff_t end, loff_t *_next,
|
||||
bool max_one_loop)
|
||||
{
|
||||
struct folio *folio;
|
||||
struct page *head_page;
|
||||
@@ -775,6 +780,9 @@ static int afs_writepages_region(struct address_space *mapping,
|
||||
|
||||
start += ret;
|
||||
|
||||
if (max_one_loop)
|
||||
break;
|
||||
|
||||
cond_resched();
|
||||
} while (wbc->nr_to_write > 0);
|
||||
|
||||
@@ -806,24 +814,27 @@ int afs_writepages(struct address_space *mapping,
|
||||
|
||||
if (wbc->range_cyclic) {
|
||||
start = mapping->writeback_index * PAGE_SIZE;
|
||||
ret = afs_writepages_region(mapping, wbc, start, LLONG_MAX, &next);
|
||||
ret = afs_writepages_region(mapping, wbc, start, LLONG_MAX,
|
||||
&next, false);
|
||||
if (ret == 0) {
|
||||
mapping->writeback_index = next / PAGE_SIZE;
|
||||
if (start > 0 && wbc->nr_to_write > 0) {
|
||||
ret = afs_writepages_region(mapping, wbc, 0,
|
||||
start, &next);
|
||||
start, &next, false);
|
||||
if (ret == 0)
|
||||
mapping->writeback_index =
|
||||
next / PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
} else if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) {
|
||||
ret = afs_writepages_region(mapping, wbc, 0, LLONG_MAX, &next);
|
||||
ret = afs_writepages_region(mapping, wbc, 0, LLONG_MAX,
|
||||
&next, false);
|
||||
if (wbc->nr_to_write > 0 && ret == 0)
|
||||
mapping->writeback_index = next / PAGE_SIZE;
|
||||
} else {
|
||||
ret = afs_writepages_region(mapping, wbc,
|
||||
wbc->range_start, wbc->range_end, &next);
|
||||
wbc->range_start, wbc->range_end,
|
||||
&next, false);
|
||||
}
|
||||
|
||||
up_read(&vnode->validate_lock);
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ cifs-$(CONFIG_CIFS_XATTR) += xattr.o
|
||||
|
||||
cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
|
||||
|
||||
cifs-$(CONFIG_CIFS_DFS_UPCALL) += cifs_dfs_ref.o dfs_cache.o
|
||||
cifs-$(CONFIG_CIFS_DFS_UPCALL) += cifs_dfs_ref.o dfs_cache.o dfs.o
|
||||
|
||||
cifs-$(CONFIG_CIFS_SWN_UPCALL) += netlink.o cifs_swn.o
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user