mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
Merge 6.1.122 into android14-6.1-lts
Changes in 6.1.122 net: sched: fix ordering of qlen adjustment PCI/AER: Disable AER service on suspend PCI: Use preserve_config in place of pci_flags PCI: vmd: Create domain symlink before pci_bus_add_devices() usb: cdns3: Add quirk flag to enable suspend residency ASoC: Intel: sof_sdw: fix jack detection on ADL-N variant RVP ASoC: Intel: sof_sdw: add quirk for Dell SKU 0B8C PCI: Add ACS quirk for Broadcom BCM5760X NIC MIPS: Loongson64: DTS: Fix msi node for ls7a usb: dwc2: gadget: Don't write invalid mapped sg entries into dma_desc with iommu enabled PCI: Introduce pci_resource_n() platform/x86: p2sb: Make p2sb_get_devfn() return void p2sb: Factor out p2sb_read_from_cache() p2sb: Introduce the global flag p2sb_hidden_by_bios p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache() p2sb: Do not scan and remove the P2SB device when it is unhidden i2c: pnx: Fix timeout in wait functions cxl/region: Fix region creation for greater than x2 switches net/smc: protect link down work from execute after lgr freed net/smc: check sndbuf_space again after NOSPACE flag is set in smc_poll net/smc: check iparea_offset and ipv6_prefixes_cnt when receiving proposal msg net/smc: check smcd_v2_ext_offset when receiving proposal msg net/smc: check return value of sock_recvmsg when draining clc data net: mscc: ocelot: fix incorrect IFH SRC_PORT field in ocelot_ifh_set_basic() netdevsim: prevent bad user input in nsim_dev_health_break_write() ionic: Fix netdev notifier unregister on failure ionic: use ee->offset when returning sprom data net: hinic: Fix cleanup in create_rxqs/txqs() net: ethernet: bgmac-platform: fix an OF node reference leak netfilter: ipset: Fix for recursive locking warning net: mdiobus: fix an OF node reference leak mmc: sdhci-tegra: Remove SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC quirk KVM: x86: Cache CPUID.0xD XSTATE offsets+sizes during module init chelsio/chtls: prevent potential integer overflow on 32bit i2c: riic: Always round-up when calculating bus period efivarfs: Fix error on non-existent file hexagon: Disable constant extender optimization for LLVM prior to 19.1.0 USB: serial: option: add TCL IK512 MBIM & ECM USB: serial: option: add MeiG Smart SLM770A USB: serial: option: add Netprisma LCUK54 modules for WWAN Ready USB: serial: option: add MediaTek T7XX compositions USB: serial: option: add Telit FE910C04 rmnet compositions thunderbolt: Improve redrive mode handling drm/modes: Avoid divide by zero harder in drm_mode_vrefresh() drm/panel: novatek-nt35950: fix return value check in nt35950_probe() i915/guc: Reset engine utilization buffer before registration i915/guc: Ensure busyness counter increases motonically i915/guc: Accumulate active runtime on gt reset drm/amdgpu: don't access invalid sched hwmon: (tmp513) Don't use "proxy" headers hwmon: (tmp513) Simplify with dev_err_probe() hwmon: (tmp513) Use SI constants from units.h hwmon: (tmp513) Fix interpretation of values of Shunt Voltage and Limit Registers hwmon: (tmp513) Fix Current Register value interpretation hwmon: (tmp513) Fix interpretation of values of Temperature Result and Limit Registers sh: clk: Fix clk_enable() to return 0 on NULL clk zram: refuse to use zero sized block device as backing device zram: fix uninitialized ZRAM not releasing backing device btrfs: tree-checker: reject inline extent items with 0 ref count Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet KVM: x86: Play nice with protected guests in complete_hypercall_exit() tracing: Fix test_event_printk() to process entire print argument tracing: Add missing helper functions in event pointer dereference check tracing: Add "%s" check in test_event_printk() selftests/bpf: Use asm constraint "m" for LoongArch io_uring: Fix registered ring file refcount leak io_uring: check if iowq is killed before queuing NFS/pnfs: Fix a live lock between recalled layouts and layoutget of/irq: Fix interrupt-map cell length check in of_irq_parse_imap_parent() of/irq: Fix using uninitialized variable @addr_len in API of_irq_parse_one() nilfs2: fix buffer head leaks in calls to truncate_inode_pages() nilfs2: prevent use of deleted inode udmabuf: also check for F_SEAL_FUTURE_WRITE of: Fix error path in of_parse_phandle_with_args_map() of: Fix refcount leakage for OF node returned by __of_get_dma_parent() ceph: validate snapdirname option length when mounting udf: Fix directory iteration for longer tail extents epoll: Add synchronous wakeup support for ep_poll_callback io_uring/rw: split io_read() into a helper io_uring/rw: treat -EOPNOTSUPP for IOCB_NOWAIT like -EAGAIN io_uring/rw: avoid punting to io-wq directly drm/amdgpu: Handle NULL bo->tbo.resource (again) in amdgpu_vm_bo_update Linux 6.1.122 Change-Id: Ia881859701ca0ee38931de81327b1c1150aa8ab5 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
VERSION = 6
|
VERSION = 6
|
||||||
PATCHLEVEL = 1
|
PATCHLEVEL = 1
|
||||||
SUBLEVEL = 121
|
SUBLEVEL = 122
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Curry Ramen
|
NAME = Curry Ramen
|
||||||
|
|
||||||
|
|||||||
@@ -32,3 +32,9 @@ KBUILD_LDFLAGS += $(ldflags-y)
|
|||||||
TIR_NAME := r19
|
TIR_NAME := r19
|
||||||
KBUILD_CFLAGS += -ffixed-$(TIR_NAME) -DTHREADINFO_REG=$(TIR_NAME) -D__linux__
|
KBUILD_CFLAGS += -ffixed-$(TIR_NAME) -DTHREADINFO_REG=$(TIR_NAME) -D__linux__
|
||||||
KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME)
|
KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME)
|
||||||
|
|
||||||
|
# Disable HexagonConstExtenders pass for LLVM versions prior to 19.1.0
|
||||||
|
# https://github.com/llvm/llvm-project/issues/99714
|
||||||
|
ifneq ($(call clang-min-version, 190100),y)
|
||||||
|
KBUILD_CFLAGS += -mllvm -hexagon-cext=false
|
||||||
|
endif
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
compatible = "loongson,pch-msi-1.0";
|
compatible = "loongson,pch-msi-1.0";
|
||||||
reg = <0 0x2ff00000 0 0x8>;
|
reg = <0 0x2ff00000 0 0x8>;
|
||||||
interrupt-controller;
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
msi-controller;
|
msi-controller;
|
||||||
loongson,msi-base-vec = <64>;
|
loongson,msi-base-vec = <64>;
|
||||||
loongson,msi-num-vecs = <192>;
|
loongson,msi-num-vecs = <192>;
|
||||||
|
|||||||
@@ -33,6 +33,26 @@
|
|||||||
u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
|
u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
|
||||||
EXPORT_SYMBOL_GPL(kvm_cpu_caps);
|
EXPORT_SYMBOL_GPL(kvm_cpu_caps);
|
||||||
|
|
||||||
|
struct cpuid_xstate_sizes {
|
||||||
|
u32 eax;
|
||||||
|
u32 ebx;
|
||||||
|
u32 ecx;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct cpuid_xstate_sizes xstate_sizes[XFEATURE_MAX] __ro_after_init;
|
||||||
|
|
||||||
|
void __init kvm_init_xstate_sizes(void)
|
||||||
|
{
|
||||||
|
u32 ign;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = XFEATURE_YMM; i < ARRAY_SIZE(xstate_sizes); i++) {
|
||||||
|
struct cpuid_xstate_sizes *xs = &xstate_sizes[i];
|
||||||
|
|
||||||
|
cpuid_count(0xD, i, &xs->eax, &xs->ebx, &xs->ecx, &ign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32 xstate_required_size(u64 xstate_bv, bool compacted)
|
u32 xstate_required_size(u64 xstate_bv, bool compacted)
|
||||||
{
|
{
|
||||||
int feature_bit = 0;
|
int feature_bit = 0;
|
||||||
@@ -41,14 +61,15 @@ u32 xstate_required_size(u64 xstate_bv, bool compacted)
|
|||||||
xstate_bv &= XFEATURE_MASK_EXTEND;
|
xstate_bv &= XFEATURE_MASK_EXTEND;
|
||||||
while (xstate_bv) {
|
while (xstate_bv) {
|
||||||
if (xstate_bv & 0x1) {
|
if (xstate_bv & 0x1) {
|
||||||
u32 eax, ebx, ecx, edx, offset;
|
struct cpuid_xstate_sizes *xs = &xstate_sizes[feature_bit];
|
||||||
cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx);
|
u32 offset;
|
||||||
|
|
||||||
/* ECX[1]: 64B alignment in compacted form */
|
/* ECX[1]: 64B alignment in compacted form */
|
||||||
if (compacted)
|
if (compacted)
|
||||||
offset = (ecx & 0x2) ? ALIGN(ret, 64) : ret;
|
offset = (xs->ecx & 0x2) ? ALIGN(ret, 64) : ret;
|
||||||
else
|
else
|
||||||
offset = ebx;
|
offset = xs->ebx;
|
||||||
ret = max(ret, offset + eax);
|
ret = max(ret, offset + xs->eax);
|
||||||
}
|
}
|
||||||
|
|
||||||
xstate_bv >>= 1;
|
xstate_bv >>= 1;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
|
|||||||
bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
|
bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
|
||||||
u32 *ecx, u32 *edx, bool exact_only);
|
u32 *ecx, u32 *edx, bool exact_only);
|
||||||
|
|
||||||
|
void __init kvm_init_xstate_sizes(void);
|
||||||
u32 xstate_required_size(u64 xstate_bv, bool compacted);
|
u32 xstate_required_size(u64 xstate_bv, bool compacted);
|
||||||
|
|
||||||
int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu);
|
int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu);
|
||||||
|
|||||||
@@ -9712,7 +9712,7 @@ static int complete_hypercall_exit(struct kvm_vcpu *vcpu)
|
|||||||
{
|
{
|
||||||
u64 ret = vcpu->run->hypercall.ret;
|
u64 ret = vcpu->run->hypercall.ret;
|
||||||
|
|
||||||
if (!is_64_bit_mode(vcpu))
|
if (!is_64_bit_hypercall(vcpu))
|
||||||
ret = (u32)ret;
|
ret = (u32)ret;
|
||||||
kvm_rax_write(vcpu, ret);
|
kvm_rax_write(vcpu, ret);
|
||||||
++vcpu->stat.hypercalls;
|
++vcpu->stat.hypercalls;
|
||||||
@@ -13820,6 +13820,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_msr_protocol_exit);
|
|||||||
|
|
||||||
static int __init kvm_x86_init(void)
|
static int __init kvm_x86_init(void)
|
||||||
{
|
{
|
||||||
|
kvm_init_xstate_sizes();
|
||||||
|
|
||||||
kvm_mmu_x86_module_init();
|
kvm_mmu_x86_module_init();
|
||||||
mitigate_smt_rsb &= boot_cpu_has_bug(X86_BUG_SMT_RSB) && cpu_smt_possible();
|
mitigate_smt_rsb &= boot_cpu_has_bug(X86_BUG_SMT_RSB) && cpu_smt_possible();
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -530,6 +530,12 @@ static ssize_t backing_dev_store(struct device *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nr_pages = i_size_read(inode) >> PAGE_SHIFT;
|
nr_pages = i_size_read(inode) >> PAGE_SHIFT;
|
||||||
|
/* Refuse to use zero sized device (also prevents self reference) */
|
||||||
|
if (!nr_pages) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long);
|
bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long);
|
||||||
bitmap = kvzalloc(bitmap_sz, GFP_KERNEL);
|
bitmap = kvzalloc(bitmap_sz, GFP_KERNEL);
|
||||||
if (!bitmap) {
|
if (!bitmap) {
|
||||||
@@ -1162,12 +1168,16 @@ static void zram_meta_free(struct zram *zram, u64 disksize)
|
|||||||
size_t num_pages = disksize >> PAGE_SHIFT;
|
size_t num_pages = disksize >> PAGE_SHIFT;
|
||||||
size_t index;
|
size_t index;
|
||||||
|
|
||||||
|
if (!zram->table)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Free all pages that are still in this zram device */
|
/* Free all pages that are still in this zram device */
|
||||||
for (index = 0; index < num_pages; index++)
|
for (index = 0; index < num_pages; index++)
|
||||||
zram_free_page(zram, index);
|
zram_free_page(zram, index);
|
||||||
|
|
||||||
zs_destroy_pool(zram->mem_pool);
|
zs_destroy_pool(zram->mem_pool);
|
||||||
vfree(zram->table);
|
vfree(zram->table);
|
||||||
|
zram->table = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool zram_meta_alloc(struct zram *zram, u64 disksize)
|
static bool zram_meta_alloc(struct zram *zram, u64 disksize)
|
||||||
@@ -1717,11 +1727,6 @@ static void zram_reset_device(struct zram *zram)
|
|||||||
|
|
||||||
zram->limit_pages = 0;
|
zram->limit_pages = 0;
|
||||||
|
|
||||||
if (!init_done(zram)) {
|
|
||||||
up_write(&zram->init_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_capacity_and_notify(zram->disk, 0);
|
set_capacity_and_notify(zram->disk, 0);
|
||||||
part_stat_set_all(zram->disk->part0, 0);
|
part_stat_set_all(zram->disk->part0, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -974,6 +974,7 @@ static int cxl_port_setup_targets(struct cxl_port *port,
|
|||||||
struct cxl_region_params *p = &cxlr->params;
|
struct cxl_region_params *p = &cxlr->params;
|
||||||
struct cxl_decoder *cxld = cxl_rr->decoder;
|
struct cxl_decoder *cxld = cxl_rr->decoder;
|
||||||
struct cxl_switch_decoder *cxlsd;
|
struct cxl_switch_decoder *cxlsd;
|
||||||
|
struct cxl_port *iter = port;
|
||||||
u16 eig, peig;
|
u16 eig, peig;
|
||||||
u8 eiw, peiw;
|
u8 eiw, peiw;
|
||||||
|
|
||||||
@@ -990,16 +991,26 @@ static int cxl_port_setup_targets(struct cxl_port *port,
|
|||||||
|
|
||||||
cxlsd = to_cxl_switch_decoder(&cxld->dev);
|
cxlsd = to_cxl_switch_decoder(&cxld->dev);
|
||||||
if (cxl_rr->nr_targets_set) {
|
if (cxl_rr->nr_targets_set) {
|
||||||
int i, distance;
|
int i, distance = 1;
|
||||||
|
struct cxl_region_ref *cxl_rr_iter;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Passthrough decoders impose no distance requirements between
|
* The "distance" between peer downstream ports represents which
|
||||||
* peers
|
* endpoint positions in the region interleave a given port can
|
||||||
|
* host.
|
||||||
|
*
|
||||||
|
* For example, at the root of a hierarchy the distance is
|
||||||
|
* always 1 as every index targets a different host-bridge. At
|
||||||
|
* each subsequent switch level those ports map every Nth region
|
||||||
|
* position where N is the width of the switch == distance.
|
||||||
*/
|
*/
|
||||||
if (cxl_rr->nr_targets == 1)
|
do {
|
||||||
distance = 0;
|
cxl_rr_iter = cxl_rr_load(iter, cxlr);
|
||||||
else
|
distance *= cxl_rr_iter->nr_targets;
|
||||||
distance = p->nr_targets / cxl_rr->nr_targets;
|
iter = to_cxl_port(iter->dev.parent);
|
||||||
|
} while (!is_cxl_root(iter));
|
||||||
|
distance *= cxlrd->cxlsd.cxld.interleave_ways;
|
||||||
|
|
||||||
for (i = 0; i < cxl_rr->nr_targets_set; i++)
|
for (i = 0; i < cxl_rr->nr_targets_set; i++)
|
||||||
if (ep->dport == cxlsd->target[i]) {
|
if (ep->dport == cxlsd->target[i]) {
|
||||||
rc = check_last_peer(cxled, ep, cxl_rr,
|
rc = check_last_peer(cxled, ep, cxl_rr,
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ static const struct dma_buf_ops udmabuf_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define SEALS_WANTED (F_SEAL_SHRINK)
|
#define SEALS_WANTED (F_SEAL_SHRINK)
|
||||||
#define SEALS_DENIED (F_SEAL_WRITE)
|
#define SEALS_DENIED (F_SEAL_WRITE|F_SEAL_FUTURE_WRITE)
|
||||||
|
|
||||||
static long udmabuf_create(struct miscdevice *device,
|
static long udmabuf_create(struct miscdevice *device,
|
||||||
struct udmabuf_create_list *head,
|
struct udmabuf_create_list *head,
|
||||||
|
|||||||
@@ -150,7 +150,6 @@ void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
|
|||||||
|
|
||||||
void amdgpu_job_free_resources(struct amdgpu_job *job)
|
void amdgpu_job_free_resources(struct amdgpu_job *job)
|
||||||
{
|
{
|
||||||
struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
|
|
||||||
struct dma_fence *f;
|
struct dma_fence *f;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
@@ -163,7 +162,7 @@ void amdgpu_job_free_resources(struct amdgpu_job *job)
|
|||||||
f = NULL;
|
f = NULL;
|
||||||
|
|
||||||
for (i = 0; i < job->num_ibs; ++i)
|
for (i = 0; i < job->num_ibs; ++i)
|
||||||
amdgpu_ib_free(ring->adev, &job->ibs[i], f);
|
amdgpu_ib_free(NULL, &job->ibs[i], f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
|
static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
|
||||||
|
|||||||
@@ -1060,10 +1060,9 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
|
|||||||
* next command submission.
|
* next command submission.
|
||||||
*/
|
*/
|
||||||
if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv) {
|
if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv) {
|
||||||
uint32_t mem_type = bo->tbo.resource->mem_type;
|
if (bo->tbo.resource &&
|
||||||
|
!(bo->preferred_domains &
|
||||||
if (!(bo->preferred_domains &
|
amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type)))
|
||||||
amdgpu_mem_type_to_domain(mem_type)))
|
|
||||||
amdgpu_vm_bo_evicted(&bo_va->base);
|
amdgpu_vm_bo_evicted(&bo_va->base);
|
||||||
else
|
else
|
||||||
amdgpu_vm_bo_idle(&bo_va->base);
|
amdgpu_vm_bo_idle(&bo_va->base);
|
||||||
|
|||||||
@@ -808,14 +808,11 @@ EXPORT_SYMBOL(drm_mode_set_name);
|
|||||||
*/
|
*/
|
||||||
int drm_mode_vrefresh(const struct drm_display_mode *mode)
|
int drm_mode_vrefresh(const struct drm_display_mode *mode)
|
||||||
{
|
{
|
||||||
unsigned int num, den;
|
unsigned int num = 1, den = 1;
|
||||||
|
|
||||||
if (mode->htotal == 0 || mode->vtotal == 0)
|
if (mode->htotal == 0 || mode->vtotal == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
num = mode->clock;
|
|
||||||
den = mode->htotal * mode->vtotal;
|
|
||||||
|
|
||||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||||
num *= 2;
|
num *= 2;
|
||||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||||
@@ -823,6 +820,12 @@ int drm_mode_vrefresh(const struct drm_display_mode *mode)
|
|||||||
if (mode->vscan > 1)
|
if (mode->vscan > 1)
|
||||||
den *= mode->vscan;
|
den *= mode->vscan;
|
||||||
|
|
||||||
|
if (check_mul_overflow(mode->clock, num, &num))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (check_mul_overflow(mode->htotal * mode->vtotal, den, &den))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(num, 1000), den);
|
return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(num, 1000), den);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_mode_vrefresh);
|
EXPORT_SYMBOL(drm_mode_vrefresh);
|
||||||
|
|||||||
@@ -339,6 +339,11 @@ struct intel_engine_guc_stats {
|
|||||||
* @start_gt_clk: GT clock time of last idle to active transition.
|
* @start_gt_clk: GT clock time of last idle to active transition.
|
||||||
*/
|
*/
|
||||||
u64 start_gt_clk;
|
u64 start_gt_clk;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @total: The last value of total returned
|
||||||
|
*/
|
||||||
|
u64 total;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct intel_engine_cs {
|
struct intel_engine_cs {
|
||||||
|
|||||||
@@ -1213,6 +1213,21 @@ static void __get_engine_usage_record(struct intel_engine_cs *engine,
|
|||||||
} while (++i < 6);
|
} while (++i < 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __set_engine_usage_record(struct intel_engine_cs *engine,
|
||||||
|
u32 last_in, u32 id, u32 total)
|
||||||
|
{
|
||||||
|
struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine);
|
||||||
|
|
||||||
|
#define record_write(map_, field_, val_) \
|
||||||
|
iosys_map_wr_field(map_, 0, struct guc_engine_usage_record, field_, val_)
|
||||||
|
|
||||||
|
record_write(&rec_map, last_switch_in_stamp, last_in);
|
||||||
|
record_write(&rec_map, current_context_index, id);
|
||||||
|
record_write(&rec_map, total_runtime, total);
|
||||||
|
|
||||||
|
#undef record_write
|
||||||
|
}
|
||||||
|
|
||||||
static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
|
static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
struct intel_engine_guc_stats *stats = &engine->stats.guc;
|
struct intel_engine_guc_stats *stats = &engine->stats.guc;
|
||||||
@@ -1331,9 +1346,12 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now)
|
|||||||
total += intel_gt_clock_interval_to_ns(gt, clk);
|
total += intel_gt_clock_interval_to_ns(gt, clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (total > stats->total)
|
||||||
|
stats->total = total;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
|
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
|
||||||
|
|
||||||
return ns_to_ktime(total);
|
return ns_to_ktime(stats->total);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __reset_guc_busyness_stats(struct intel_guc *guc)
|
static void __reset_guc_busyness_stats(struct intel_guc *guc)
|
||||||
@@ -1350,8 +1368,21 @@ static void __reset_guc_busyness_stats(struct intel_guc *guc)
|
|||||||
|
|
||||||
guc_update_pm_timestamp(guc, &unused);
|
guc_update_pm_timestamp(guc, &unused);
|
||||||
for_each_engine(engine, gt, id) {
|
for_each_engine(engine, gt, id) {
|
||||||
|
struct intel_engine_guc_stats *stats = &engine->stats.guc;
|
||||||
|
|
||||||
guc_update_engine_gt_clks(engine);
|
guc_update_engine_gt_clks(engine);
|
||||||
engine->stats.guc.prev_total = 0;
|
|
||||||
|
/*
|
||||||
|
* If resetting a running context, accumulate the active
|
||||||
|
* time as well since there will be no context switch.
|
||||||
|
*/
|
||||||
|
if (stats->running) {
|
||||||
|
u64 clk = guc->timestamp.gt_stamp - stats->start_gt_clk;
|
||||||
|
|
||||||
|
stats->total_gt_clks += clk;
|
||||||
|
}
|
||||||
|
stats->prev_total = 0;
|
||||||
|
stats->running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
|
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
|
||||||
@@ -1404,6 +1435,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)
|
|||||||
|
|
||||||
static int guc_action_enable_usage_stats(struct intel_guc *guc)
|
static int guc_action_enable_usage_stats(struct intel_guc *guc)
|
||||||
{
|
{
|
||||||
|
struct intel_gt *gt = guc_to_gt(guc);
|
||||||
|
struct intel_engine_cs *engine;
|
||||||
|
enum intel_engine_id id;
|
||||||
u32 offset = intel_guc_engine_usage_offset(guc);
|
u32 offset = intel_guc_engine_usage_offset(guc);
|
||||||
u32 action[] = {
|
u32 action[] = {
|
||||||
INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF,
|
INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF,
|
||||||
@@ -1411,6 +1445,9 @@ static int guc_action_enable_usage_stats(struct intel_guc *guc)
|
|||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for_each_engine(engine, gt, id)
|
||||||
|
__set_engine_usage_record(engine, 0, 0xffffffff, 0);
|
||||||
|
|
||||||
return intel_guc_send(guc, action, ARRAY_SIZE(action));
|
return intel_guc_send(guc, action, ARRAY_SIZE(action));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -577,9 +577,9 @@ static int nt35950_probe(struct mipi_dsi_device *dsi)
|
|||||||
return dev_err_probe(dev, -EPROBE_DEFER, "Cannot get secondary DSI host\n");
|
return dev_err_probe(dev, -EPROBE_DEFER, "Cannot get secondary DSI host\n");
|
||||||
|
|
||||||
nt->dsi[1] = mipi_dsi_device_register_full(dsi_r_host, info);
|
nt->dsi[1] = mipi_dsi_device_register_full(dsi_r_host, info);
|
||||||
if (!nt->dsi[1]) {
|
if (IS_ERR(nt->dsi[1])) {
|
||||||
dev_err(dev, "Cannot get secondary DSI node\n");
|
dev_err(dev, "Cannot get secondary DSI node\n");
|
||||||
return -ENODEV;
|
return PTR_ERR(nt->dsi[1]);
|
||||||
}
|
}
|
||||||
num_dsis++;
|
num_dsis++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -767,6 +767,12 @@ hv_kvp_init(struct hv_util_service *srv)
|
|||||||
*/
|
*/
|
||||||
kvp_transaction.state = HVUTIL_DEVICE_INIT;
|
kvp_transaction.state = HVUTIL_DEVICE_INIT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hv_kvp_init_transport(void)
|
||||||
|
{
|
||||||
hvt = hvutil_transport_init(kvp_devname, CN_KVP_IDX, CN_KVP_VAL,
|
hvt = hvutil_transport_init(kvp_devname, CN_KVP_IDX, CN_KVP_VAL,
|
||||||
kvp_on_msg, kvp_on_reset);
|
kvp_on_msg, kvp_on_reset);
|
||||||
if (!hvt)
|
if (!hvt)
|
||||||
|
|||||||
@@ -388,6 +388,12 @@ hv_vss_init(struct hv_util_service *srv)
|
|||||||
*/
|
*/
|
||||||
vss_transaction.state = HVUTIL_DEVICE_INIT;
|
vss_transaction.state = HVUTIL_DEVICE_INIT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hv_vss_init_transport(void)
|
||||||
|
{
|
||||||
hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
|
hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
|
||||||
vss_on_msg, vss_on_reset);
|
vss_on_msg, vss_on_reset);
|
||||||
if (!hvt) {
|
if (!hvt) {
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ static struct hv_util_service util_heartbeat = {
|
|||||||
static struct hv_util_service util_kvp = {
|
static struct hv_util_service util_kvp = {
|
||||||
.util_cb = hv_kvp_onchannelcallback,
|
.util_cb = hv_kvp_onchannelcallback,
|
||||||
.util_init = hv_kvp_init,
|
.util_init = hv_kvp_init,
|
||||||
|
.util_init_transport = hv_kvp_init_transport,
|
||||||
.util_pre_suspend = hv_kvp_pre_suspend,
|
.util_pre_suspend = hv_kvp_pre_suspend,
|
||||||
.util_pre_resume = hv_kvp_pre_resume,
|
.util_pre_resume = hv_kvp_pre_resume,
|
||||||
.util_deinit = hv_kvp_deinit,
|
.util_deinit = hv_kvp_deinit,
|
||||||
@@ -149,6 +150,7 @@ static struct hv_util_service util_kvp = {
|
|||||||
static struct hv_util_service util_vss = {
|
static struct hv_util_service util_vss = {
|
||||||
.util_cb = hv_vss_onchannelcallback,
|
.util_cb = hv_vss_onchannelcallback,
|
||||||
.util_init = hv_vss_init,
|
.util_init = hv_vss_init,
|
||||||
|
.util_init_transport = hv_vss_init_transport,
|
||||||
.util_pre_suspend = hv_vss_pre_suspend,
|
.util_pre_suspend = hv_vss_pre_suspend,
|
||||||
.util_pre_resume = hv_vss_pre_resume,
|
.util_pre_resume = hv_vss_pre_resume,
|
||||||
.util_deinit = hv_vss_deinit,
|
.util_deinit = hv_vss_deinit,
|
||||||
@@ -592,6 +594,13 @@ static int util_probe(struct hv_device *dev,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (srv->util_init_transport) {
|
||||||
|
ret = srv->util_init_transport();
|
||||||
|
if (ret) {
|
||||||
|
vmbus_close(dev->channel);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|||||||
@@ -365,12 +365,14 @@ void vmbus_on_event(unsigned long data);
|
|||||||
void vmbus_on_msg_dpc(unsigned long data);
|
void vmbus_on_msg_dpc(unsigned long data);
|
||||||
|
|
||||||
int hv_kvp_init(struct hv_util_service *srv);
|
int hv_kvp_init(struct hv_util_service *srv);
|
||||||
|
int hv_kvp_init_transport(void);
|
||||||
void hv_kvp_deinit(void);
|
void hv_kvp_deinit(void);
|
||||||
int hv_kvp_pre_suspend(void);
|
int hv_kvp_pre_suspend(void);
|
||||||
int hv_kvp_pre_resume(void);
|
int hv_kvp_pre_resume(void);
|
||||||
void hv_kvp_onchannelcallback(void *context);
|
void hv_kvp_onchannelcallback(void *context);
|
||||||
|
|
||||||
int hv_vss_init(struct hv_util_service *srv);
|
int hv_vss_init(struct hv_util_service *srv);
|
||||||
|
int hv_vss_init_transport(void);
|
||||||
void hv_vss_deinit(void);
|
void hv_vss_deinit(void);
|
||||||
int hv_vss_pre_suspend(void);
|
int hv_vss_pre_suspend(void);
|
||||||
int hv_vss_pre_resume(void);
|
int hv_vss_pre_resume(void);
|
||||||
|
|||||||
@@ -19,15 +19,20 @@
|
|||||||
* the Free Software Foundation; version 2 of the License.
|
* the Free Software Foundation; version 2 of the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/bug.h>
|
||||||
|
#include <linux/device.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/hwmon.h>
|
#include <linux/hwmon.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/math.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/property.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/util_macros.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/units.h>
|
||||||
|
|
||||||
// Common register definition
|
// Common register definition
|
||||||
#define TMP51X_SHUNT_CONFIG 0x00
|
#define TMP51X_SHUNT_CONFIG 0x00
|
||||||
@@ -100,8 +105,8 @@
|
|||||||
#define TMP51X_REMOTE_TEMP_LIMIT_2_POS 8
|
#define TMP51X_REMOTE_TEMP_LIMIT_2_POS 8
|
||||||
#define TMP513_REMOTE_TEMP_LIMIT_3_POS 7
|
#define TMP513_REMOTE_TEMP_LIMIT_3_POS 7
|
||||||
|
|
||||||
#define TMP51X_VBUS_RANGE_32V 32000000
|
#define TMP51X_VBUS_RANGE_32V (32 * MICRO)
|
||||||
#define TMP51X_VBUS_RANGE_16V 16000000
|
#define TMP51X_VBUS_RANGE_16V (16 * MICRO)
|
||||||
|
|
||||||
// Max and Min value
|
// Max and Min value
|
||||||
#define MAX_BUS_VOLTAGE_32_LIMIT 32764
|
#define MAX_BUS_VOLTAGE_32_LIMIT 32764
|
||||||
@@ -173,7 +178,7 @@ struct tmp51x_data {
|
|||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set the shift based on the gain 8=4, 4=3, 2=2, 1=1
|
// Set the shift based on the gain: 8 -> 1, 4 -> 2, 2 -> 3, 1 -> 4
|
||||||
static inline u8 tmp51x_get_pga_shift(struct tmp51x_data *data)
|
static inline u8 tmp51x_get_pga_shift(struct tmp51x_data *data)
|
||||||
{
|
{
|
||||||
return 5 - ffs(data->pga_gain);
|
return 5 - ffs(data->pga_gain);
|
||||||
@@ -195,8 +200,10 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
|
|||||||
* 2's complement number shifted by one to four depending
|
* 2's complement number shifted by one to four depending
|
||||||
* on the pga gain setting. 1lsb = 10uV
|
* on the pga gain setting. 1lsb = 10uV
|
||||||
*/
|
*/
|
||||||
*val = sign_extend32(regval, 17 - tmp51x_get_pga_shift(data));
|
*val = sign_extend32(regval,
|
||||||
*val = DIV_ROUND_CLOSEST(*val * 10000, data->shunt_uohms);
|
reg == TMP51X_SHUNT_CURRENT_RESULT ?
|
||||||
|
16 - tmp51x_get_pga_shift(data) : 15);
|
||||||
|
*val = DIV_ROUND_CLOSEST(*val * 10 * MILLI, data->shunt_uohms);
|
||||||
break;
|
break;
|
||||||
case TMP51X_BUS_VOLTAGE_RESULT:
|
case TMP51X_BUS_VOLTAGE_RESULT:
|
||||||
case TMP51X_BUS_VOLTAGE_H_LIMIT:
|
case TMP51X_BUS_VOLTAGE_H_LIMIT:
|
||||||
@@ -211,8 +218,8 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
|
|||||||
break;
|
break;
|
||||||
case TMP51X_BUS_CURRENT_RESULT:
|
case TMP51X_BUS_CURRENT_RESULT:
|
||||||
// Current = (ShuntVoltage * CalibrationRegister) / 4096
|
// Current = (ShuntVoltage * CalibrationRegister) / 4096
|
||||||
*val = sign_extend32(regval, 16) * data->curr_lsb_ua;
|
*val = sign_extend32(regval, 15) * (long)data->curr_lsb_ua;
|
||||||
*val = DIV_ROUND_CLOSEST(*val, 1000);
|
*val = DIV_ROUND_CLOSEST(*val, MILLI);
|
||||||
break;
|
break;
|
||||||
case TMP51X_LOCAL_TEMP_RESULT:
|
case TMP51X_LOCAL_TEMP_RESULT:
|
||||||
case TMP51X_REMOTE_TEMP_RESULT_1:
|
case TMP51X_REMOTE_TEMP_RESULT_1:
|
||||||
@@ -223,7 +230,7 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
|
|||||||
case TMP51X_REMOTE_TEMP_LIMIT_2:
|
case TMP51X_REMOTE_TEMP_LIMIT_2:
|
||||||
case TMP513_REMOTE_TEMP_LIMIT_3:
|
case TMP513_REMOTE_TEMP_LIMIT_3:
|
||||||
// 1lsb = 0.0625 degrees centigrade
|
// 1lsb = 0.0625 degrees centigrade
|
||||||
*val = sign_extend32(regval, 16) >> TMP51X_TEMP_SHIFT;
|
*val = sign_extend32(regval, 15) >> TMP51X_TEMP_SHIFT;
|
||||||
*val = DIV_ROUND_CLOSEST(*val * 625, 10);
|
*val = DIV_ROUND_CLOSEST(*val * 625, 10);
|
||||||
break;
|
break;
|
||||||
case TMP51X_N_FACTOR_AND_HYST_1:
|
case TMP51X_N_FACTOR_AND_HYST_1:
|
||||||
@@ -252,7 +259,7 @@ static int tmp51x_set_value(struct tmp51x_data *data, u8 reg, long val)
|
|||||||
* The user enter current value and we convert it to
|
* The user enter current value and we convert it to
|
||||||
* voltage. 1lsb = 10uV
|
* voltage. 1lsb = 10uV
|
||||||
*/
|
*/
|
||||||
val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10000);
|
val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10 * MILLI);
|
||||||
max_val = U16_MAX >> tmp51x_get_pga_shift(data);
|
max_val = U16_MAX >> tmp51x_get_pga_shift(data);
|
||||||
regval = clamp_val(val, -max_val, max_val);
|
regval = clamp_val(val, -max_val, max_val);
|
||||||
break;
|
break;
|
||||||
@@ -542,18 +549,16 @@ static int tmp51x_calibrate(struct tmp51x_data *data)
|
|||||||
if (data->shunt_uohms == 0)
|
if (data->shunt_uohms == 0)
|
||||||
return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION, 0);
|
return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION, 0);
|
||||||
|
|
||||||
max_curr_ma = DIV_ROUND_CLOSEST_ULL(vshunt_max * 1000 * 1000,
|
max_curr_ma = DIV_ROUND_CLOSEST_ULL(vshunt_max * MICRO, data->shunt_uohms);
|
||||||
data->shunt_uohms);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the minimal bit resolution for the current and the power.
|
* Calculate the minimal bit resolution for the current and the power.
|
||||||
* Those values will be used during register interpretation.
|
* Those values will be used during register interpretation.
|
||||||
*/
|
*/
|
||||||
data->curr_lsb_ua = DIV_ROUND_CLOSEST_ULL(max_curr_ma * 1000, 32767);
|
data->curr_lsb_ua = DIV_ROUND_CLOSEST_ULL(max_curr_ma * MILLI, 32767);
|
||||||
data->pwr_lsb_uw = 20 * data->curr_lsb_ua;
|
data->pwr_lsb_uw = 20 * data->curr_lsb_ua;
|
||||||
|
|
||||||
div = DIV_ROUND_CLOSEST_ULL(data->curr_lsb_ua * data->shunt_uohms,
|
div = DIV_ROUND_CLOSEST_ULL(data->curr_lsb_ua * data->shunt_uohms, MICRO);
|
||||||
1000 * 1000);
|
|
||||||
|
|
||||||
return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION,
|
return regmap_write(data->regmap, TMP51X_SHUNT_CALIBRATION,
|
||||||
DIV_ROUND_CLOSEST(40960, div));
|
DIV_ROUND_CLOSEST(40960, div));
|
||||||
@@ -628,9 +633,9 @@ static int tmp51x_vbus_range_to_reg(struct device *dev,
|
|||||||
} else if (data->vbus_range_uvolt == TMP51X_VBUS_RANGE_16V) {
|
} else if (data->vbus_range_uvolt == TMP51X_VBUS_RANGE_16V) {
|
||||||
data->shunt_config &= ~TMP51X_BUS_VOLTAGE_MASK;
|
data->shunt_config &= ~TMP51X_BUS_VOLTAGE_MASK;
|
||||||
} else {
|
} else {
|
||||||
dev_err(dev, "ti,bus-range-microvolt is invalid: %u\n",
|
return dev_err_probe(dev, -EINVAL,
|
||||||
data->vbus_range_uvolt);
|
"ti,bus-range-microvolt is invalid: %u\n",
|
||||||
return -EINVAL;
|
data->vbus_range_uvolt);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -646,8 +651,8 @@ static int tmp51x_pga_gain_to_reg(struct device *dev, struct tmp51x_data *data)
|
|||||||
} else if (data->pga_gain == 1) {
|
} else if (data->pga_gain == 1) {
|
||||||
data->shunt_config |= CURRENT_SENSE_VOLTAGE_40_MASK;
|
data->shunt_config |= CURRENT_SENSE_VOLTAGE_40_MASK;
|
||||||
} else {
|
} else {
|
||||||
dev_err(dev, "ti,pga-gain is invalid: %u\n", data->pga_gain);
|
return dev_err_probe(dev, -EINVAL,
|
||||||
return -EINVAL;
|
"ti,pga-gain is invalid: %u\n", data->pga_gain);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -679,10 +684,10 @@ static int tmp51x_read_properties(struct device *dev, struct tmp51x_data *data)
|
|||||||
memcpy(data->nfactor, nfactor, (data->id == tmp513) ? 3 : 2);
|
memcpy(data->nfactor, nfactor, (data->id == tmp513) ? 3 : 2);
|
||||||
|
|
||||||
// Check if shunt value is compatible with pga-gain
|
// Check if shunt value is compatible with pga-gain
|
||||||
if (data->shunt_uohms > data->pga_gain * 40 * 1000 * 1000) {
|
if (data->shunt_uohms > data->pga_gain * 40 * MICRO) {
|
||||||
dev_err(dev, "shunt-resistor: %u too big for pga_gain: %u\n",
|
return dev_err_probe(dev, -EINVAL,
|
||||||
data->shunt_uohms, data->pga_gain);
|
"shunt-resistor: %u too big for pga_gain: %u\n",
|
||||||
return -EINVAL;
|
data->shunt_uohms, data->pga_gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -726,22 +731,17 @@ static int tmp51x_probe(struct i2c_client *client)
|
|||||||
data->id = i2c_match_id(tmp51x_id, client)->driver_data;
|
data->id = i2c_match_id(tmp51x_id, client)->driver_data;
|
||||||
|
|
||||||
ret = tmp51x_configure(dev, data);
|
ret = tmp51x_configure(dev, data);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
dev_err(dev, "error configuring the device: %d\n", ret);
|
return dev_err_probe(dev, ret, "error configuring the device\n");
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->regmap = devm_regmap_init_i2c(client, &tmp51x_regmap_config);
|
data->regmap = devm_regmap_init_i2c(client, &tmp51x_regmap_config);
|
||||||
if (IS_ERR(data->regmap)) {
|
if (IS_ERR(data->regmap))
|
||||||
dev_err(dev, "failed to allocate register map\n");
|
return dev_err_probe(dev, PTR_ERR(data->regmap),
|
||||||
return PTR_ERR(data->regmap);
|
"failed to allocate register map\n");
|
||||||
}
|
|
||||||
|
|
||||||
ret = tmp51x_init(data);
|
ret = tmp51x_init(data);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
dev_err(dev, "error configuring the device: %d\n", ret);
|
return dev_err_probe(dev, ret, "error configuring the device\n");
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
|
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
|
||||||
data,
|
data,
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ enum {
|
|||||||
|
|
||||||
static inline int wait_timeout(struct i2c_pnx_algo_data *data)
|
static inline int wait_timeout(struct i2c_pnx_algo_data *data)
|
||||||
{
|
{
|
||||||
long timeout = data->timeout;
|
long timeout = jiffies_to_msecs(data->timeout);
|
||||||
while (timeout > 0 &&
|
while (timeout > 0 &&
|
||||||
(ioread32(I2C_REG_STS(data)) & mstatus_active)) {
|
(ioread32(I2C_REG_STS(data)) & mstatus_active)) {
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
@@ -106,7 +106,7 @@ static inline int wait_timeout(struct i2c_pnx_algo_data *data)
|
|||||||
|
|
||||||
static inline int wait_reset(struct i2c_pnx_algo_data *data)
|
static inline int wait_reset(struct i2c_pnx_algo_data *data)
|
||||||
{
|
{
|
||||||
long timeout = data->timeout;
|
long timeout = jiffies_to_msecs(data->timeout);
|
||||||
while (timeout > 0 &&
|
while (timeout > 0 &&
|
||||||
(ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
|
(ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t)
|
|||||||
if (brl <= (0x1F + 3))
|
if (brl <= (0x1F + 3))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
total_ticks /= 2;
|
total_ticks = DIV_ROUND_UP(total_ticks, 2);
|
||||||
rate /= 2;
|
rate /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1520,7 +1520,6 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
|
|||||||
.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
|
.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
|
||||||
SDHCI_QUIRK_SINGLE_POWER_WRITE |
|
SDHCI_QUIRK_SINGLE_POWER_WRITE |
|
||||||
SDHCI_QUIRK_NO_HISPD_BIT |
|
SDHCI_QUIRK_NO_HISPD_BIT |
|
||||||
SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
|
|
||||||
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
|
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
|
||||||
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
|
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
|
||||||
SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER,
|
SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER,
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ static int platform_phy_connect(struct bgmac *bgmac)
|
|||||||
static int bgmac_probe(struct platform_device *pdev)
|
static int bgmac_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
struct device_node *phy_node;
|
||||||
struct bgmac *bgmac;
|
struct bgmac *bgmac;
|
||||||
struct resource *regs;
|
struct resource *regs;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -236,7 +237,9 @@ static int bgmac_probe(struct platform_device *pdev)
|
|||||||
bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset;
|
bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset;
|
||||||
bgmac->get_bus_clock = platform_bgmac_get_bus_clock;
|
bgmac->get_bus_clock = platform_bgmac_get_bus_clock;
|
||||||
bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32;
|
bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32;
|
||||||
if (of_parse_phandle(np, "phy-handle", 0)) {
|
phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||||
|
if (phy_node) {
|
||||||
|
of_node_put(phy_node);
|
||||||
bgmac->phy_connect = platform_phy_connect;
|
bgmac->phy_connect = platform_phy_connect;
|
||||||
} else {
|
} else {
|
||||||
bgmac->phy_connect = bgmac_phy_connect_direct;
|
bgmac->phy_connect = bgmac_phy_connect_direct;
|
||||||
|
|||||||
@@ -346,8 +346,9 @@ static struct sk_buff *copy_gl_to_skb_pkt(const struct pkt_gl *gl,
|
|||||||
* driver. Once driver synthesizes cpl_pass_accpet_req the skb will go
|
* driver. Once driver synthesizes cpl_pass_accpet_req the skb will go
|
||||||
* through the regular cpl_pass_accept_req processing in TOM.
|
* through the regular cpl_pass_accept_req processing in TOM.
|
||||||
*/
|
*/
|
||||||
skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req)
|
skb = alloc_skb(size_add(gl->tot_len,
|
||||||
- pktshift, GFP_ATOMIC);
|
sizeof(struct cpl_pass_accept_req)) -
|
||||||
|
pktshift, GFP_ATOMIC);
|
||||||
if (unlikely(!skb))
|
if (unlikely(!skb))
|
||||||
return NULL;
|
return NULL;
|
||||||
__skb_put(skb, gl->tot_len + sizeof(struct cpl_pass_accept_req)
|
__skb_put(skb, gl->tot_len + sizeof(struct cpl_pass_accept_req)
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ err_init_txq:
|
|||||||
hinic_sq_dbgfs_uninit(nic_dev);
|
hinic_sq_dbgfs_uninit(nic_dev);
|
||||||
|
|
||||||
devm_kfree(&netdev->dev, nic_dev->txqs);
|
devm_kfree(&netdev->dev, nic_dev->txqs);
|
||||||
|
nic_dev->txqs = NULL;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,6 +269,7 @@ err_init_rxq:
|
|||||||
hinic_rq_dbgfs_uninit(nic_dev);
|
hinic_rq_dbgfs_uninit(nic_dev);
|
||||||
|
|
||||||
devm_kfree(&netdev->dev, nic_dev->rxqs);
|
devm_kfree(&netdev->dev, nic_dev->rxqs);
|
||||||
|
nic_dev->rxqs = NULL;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1161,7 +1161,7 @@ void ocelot_ifh_set_basic(void *ifh, struct ocelot *ocelot, int port,
|
|||||||
|
|
||||||
memset(ifh, 0, OCELOT_TAG_LEN);
|
memset(ifh, 0, OCELOT_TAG_LEN);
|
||||||
ocelot_ifh_set_bypass(ifh, 1);
|
ocelot_ifh_set_bypass(ifh, 1);
|
||||||
ocelot_ifh_set_src(ifh, BIT_ULL(ocelot->num_phys_ports));
|
ocelot_ifh_set_src(ifh, ocelot->num_phys_ports);
|
||||||
ocelot_ifh_set_dest(ifh, BIT_ULL(port));
|
ocelot_ifh_set_dest(ifh, BIT_ULL(port));
|
||||||
ocelot_ifh_set_qos_class(ifh, qos_class);
|
ocelot_ifh_set_qos_class(ifh, qos_class);
|
||||||
ocelot_ifh_set_tag_type(ifh, tag_type);
|
ocelot_ifh_set_tag_type(ifh, tag_type);
|
||||||
|
|||||||
@@ -828,8 +828,8 @@ static int ionic_get_module_eeprom(struct net_device *netdev,
|
|||||||
len = min_t(u32, sizeof(xcvr->sprom), ee->len);
|
len = min_t(u32, sizeof(xcvr->sprom), ee->len);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
memcpy(data, xcvr->sprom, len);
|
memcpy(data, &xcvr->sprom[ee->offset], len);
|
||||||
memcpy(tbuf, xcvr->sprom, len);
|
memcpy(tbuf, &xcvr->sprom[ee->offset], len);
|
||||||
|
|
||||||
/* Let's make sure we got a consistent copy */
|
/* Let's make sure we got a consistent copy */
|
||||||
if (!memcmp(data, tbuf, len))
|
if (!memcmp(data, tbuf, len))
|
||||||
|
|||||||
@@ -3484,8 +3484,8 @@ int ionic_lif_register(struct ionic_lif *lif)
|
|||||||
/* only register LIF0 for now */
|
/* only register LIF0 for now */
|
||||||
err = register_netdev(lif->netdev);
|
err = register_netdev(lif->netdev);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(lif->ionic->dev, "Cannot register net device, aborting\n");
|
dev_err(lif->ionic->dev, "Cannot register net device: %d, aborting\n", err);
|
||||||
ionic_lif_unregister_phc(lif);
|
ionic_lif_unregister(lif);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ fwnode_find_pse_control(struct fwnode_handle *fwnode)
|
|||||||
static struct mii_timestamper *
|
static struct mii_timestamper *
|
||||||
fwnode_find_mii_timestamper(struct fwnode_handle *fwnode)
|
fwnode_find_mii_timestamper(struct fwnode_handle *fwnode)
|
||||||
{
|
{
|
||||||
|
struct mii_timestamper *mii_ts;
|
||||||
struct of_phandle_args arg;
|
struct of_phandle_args arg;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -51,10 +52,16 @@ fwnode_find_mii_timestamper(struct fwnode_handle *fwnode)
|
|||||||
else if (err)
|
else if (err)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
|
|
||||||
if (arg.args_count != 1)
|
if (arg.args_count != 1) {
|
||||||
return ERR_PTR(-EINVAL);
|
mii_ts = ERR_PTR(-EINVAL);
|
||||||
|
goto put_node;
|
||||||
|
}
|
||||||
|
|
||||||
return register_mii_timestamper(arg.np, arg.args[0]);
|
mii_ts = register_mii_timestamper(arg.np, arg.args[0]);
|
||||||
|
|
||||||
|
put_node:
|
||||||
|
of_node_put(arg.np);
|
||||||
|
return mii_ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
|
int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
|
||||||
|
|||||||
@@ -203,6 +203,8 @@ static ssize_t nsim_dev_health_break_write(struct file *file,
|
|||||||
char *break_msg;
|
char *break_msg;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (count == 0 || count > PAGE_SIZE)
|
||||||
|
return -EINVAL;
|
||||||
break_msg = memdup_user_nul(data, count);
|
break_msg = memdup_user_nul(data, count);
|
||||||
if (IS_ERR(break_msg))
|
if (IS_ERR(break_msg))
|
||||||
return PTR_ERR(break_msg);
|
return PTR_ERR(break_msg);
|
||||||
|
|||||||
@@ -595,7 +595,7 @@ struct device_node *__of_get_dma_parent(const struct device_node *np)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return of_get_parent(np);
|
return of_get_parent(np);
|
||||||
|
|
||||||
return of_node_get(args.np);
|
return args.np;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1597,8 +1597,10 @@ int of_parse_phandle_with_args_map(const struct device_node *np,
|
|||||||
map_len--;
|
map_len--;
|
||||||
|
|
||||||
/* Check if not found */
|
/* Check if not found */
|
||||||
if (!new)
|
if (!new) {
|
||||||
|
ret = -EINVAL;
|
||||||
goto put;
|
goto put;
|
||||||
|
}
|
||||||
|
|
||||||
if (!of_device_is_available(new))
|
if (!of_device_is_available(new))
|
||||||
match = 0;
|
match = 0;
|
||||||
@@ -1608,17 +1610,20 @@ int of_parse_phandle_with_args_map(const struct device_node *np,
|
|||||||
goto put;
|
goto put;
|
||||||
|
|
||||||
/* Check for malformed properties */
|
/* Check for malformed properties */
|
||||||
if (WARN_ON(new_size > MAX_PHANDLE_ARGS))
|
if (WARN_ON(new_size > MAX_PHANDLE_ARGS) ||
|
||||||
goto put;
|
map_len < new_size) {
|
||||||
if (map_len < new_size)
|
ret = -EINVAL;
|
||||||
goto put;
|
goto put;
|
||||||
|
}
|
||||||
|
|
||||||
/* Move forward by new node's #<list>-cells amount */
|
/* Move forward by new node's #<list>-cells amount */
|
||||||
map += new_size;
|
map += new_size;
|
||||||
map_len -= new_size;
|
map_len -= new_size;
|
||||||
}
|
}
|
||||||
if (!match)
|
if (!match) {
|
||||||
|
ret = -ENOENT;
|
||||||
goto put;
|
goto put;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the <list>-map-pass-thru property (optional) */
|
/* Get the <list>-map-pass-thru property (optional) */
|
||||||
pass = of_get_property(cur, pass_name, NULL);
|
pass = of_get_property(cur, pass_name, NULL);
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ const __be32 *of_irq_parse_imap_parent(const __be32 *imap, int len, struct of_ph
|
|||||||
else
|
else
|
||||||
np = of_find_node_by_phandle(be32_to_cpup(imap));
|
np = of_find_node_by_phandle(be32_to_cpup(imap));
|
||||||
imap++;
|
imap++;
|
||||||
|
len--;
|
||||||
|
|
||||||
/* Check if not found */
|
/* Check if not found */
|
||||||
if (!np) {
|
if (!np) {
|
||||||
@@ -354,6 +355,7 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
|
|||||||
return of_irq_parse_oldworld(device, index, out_irq);
|
return of_irq_parse_oldworld(device, index, out_irq);
|
||||||
|
|
||||||
/* Get the reg property (if any) */
|
/* Get the reg property (if any) */
|
||||||
|
addr_len = 0;
|
||||||
addr = of_get_property(device, "reg", &addr_len);
|
addr = of_get_property(device, "reg", &addr_len);
|
||||||
|
|
||||||
/* Prevent out-of-bounds read in case of longer interrupt parent address size */
|
/* Prevent out-of-bounds read in case of longer interrupt parent address size */
|
||||||
|
|||||||
@@ -73,10 +73,6 @@ int pci_host_common_probe(struct platform_device *pdev)
|
|||||||
if (IS_ERR(cfg))
|
if (IS_ERR(cfg))
|
||||||
return PTR_ERR(cfg);
|
return PTR_ERR(cfg);
|
||||||
|
|
||||||
/* Do not reassign resources if probe only */
|
|
||||||
if (!pci_has_flag(PCI_PROBE_ONLY))
|
|
||||||
pci_add_flags(PCI_REASSIGN_ALL_BUS);
|
|
||||||
|
|
||||||
bridge->sysdata = cfg;
|
bridge->sysdata = cfg;
|
||||||
bridge->ops = (struct pci_ops *)&ops->pci_ops;
|
bridge->ops = (struct pci_ops *)&ops->pci_ops;
|
||||||
bridge->msi_domain = true;
|
bridge->msi_domain = true;
|
||||||
|
|||||||
@@ -870,6 +870,9 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
|
|||||||
dev_set_msi_domain(&vmd->bus->dev,
|
dev_set_msi_domain(&vmd->bus->dev,
|
||||||
dev_get_msi_domain(&vmd->dev->dev));
|
dev_get_msi_domain(&vmd->dev->dev));
|
||||||
|
|
||||||
|
WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj,
|
||||||
|
"domain"), "Can't create symlink to domain\n");
|
||||||
|
|
||||||
vmd_acpi_begin();
|
vmd_acpi_begin();
|
||||||
|
|
||||||
pci_scan_child_bus(vmd->bus);
|
pci_scan_child_bus(vmd->bus);
|
||||||
@@ -907,9 +910,6 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
|
|||||||
pci_bus_add_devices(vmd->bus);
|
pci_bus_add_devices(vmd->bus);
|
||||||
|
|
||||||
vmd_acpi_end();
|
vmd_acpi_end();
|
||||||
|
|
||||||
WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj,
|
|
||||||
"domain"), "Can't create symlink to domain\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -985,8 +985,8 @@ static void vmd_remove(struct pci_dev *dev)
|
|||||||
{
|
{
|
||||||
struct vmd_dev *vmd = pci_get_drvdata(dev);
|
struct vmd_dev *vmd = pci_get_drvdata(dev);
|
||||||
|
|
||||||
sysfs_remove_link(&vmd->dev->dev.kobj, "domain");
|
|
||||||
pci_stop_root_bus(vmd->bus);
|
pci_stop_root_bus(vmd->bus);
|
||||||
|
sysfs_remove_link(&vmd->dev->dev.kobj, "domain");
|
||||||
pci_remove_root_bus(vmd->bus);
|
pci_remove_root_bus(vmd->bus);
|
||||||
vmd_cleanup_srcu(vmd);
|
vmd_cleanup_srcu(vmd);
|
||||||
vmd_detach_resources(vmd);
|
vmd_detach_resources(vmd);
|
||||||
|
|||||||
@@ -1384,6 +1384,22 @@ static int aer_probe(struct pcie_device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int aer_suspend(struct pcie_device *dev)
|
||||||
|
{
|
||||||
|
struct aer_rpc *rpc = get_service_data(dev);
|
||||||
|
|
||||||
|
aer_disable_rootport(rpc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aer_resume(struct pcie_device *dev)
|
||||||
|
{
|
||||||
|
struct aer_rpc *rpc = get_service_data(dev);
|
||||||
|
|
||||||
|
aer_enable_rootport(rpc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aer_root_reset - reset Root Port hierarchy, RCEC, or RCiEP
|
* aer_root_reset - reset Root Port hierarchy, RCEC, or RCiEP
|
||||||
* @dev: pointer to Root Port, RCEC, or RCiEP
|
* @dev: pointer to Root Port, RCEC, or RCiEP
|
||||||
@@ -1455,6 +1471,8 @@ static struct pcie_port_service_driver aerdriver = {
|
|||||||
.service = PCIE_PORT_SERVICE_AER,
|
.service = PCIE_PORT_SERVICE_AER,
|
||||||
|
|
||||||
.probe = aer_probe,
|
.probe = aer_probe,
|
||||||
|
.suspend = aer_suspend,
|
||||||
|
.resume = aer_resume,
|
||||||
.remove = aer_remove,
|
.remove = aer_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3075,20 +3075,18 @@ int pci_host_probe(struct pci_host_bridge *bridge)
|
|||||||
|
|
||||||
bus = bridge->bus;
|
bus = bridge->bus;
|
||||||
|
|
||||||
/*
|
/* If we must preserve the resource configuration, claim now */
|
||||||
* We insert PCI resources into the iomem_resource and
|
if (bridge->preserve_config)
|
||||||
* ioport_resource trees in either pci_bus_claim_resources()
|
|
||||||
* or pci_bus_assign_resources().
|
|
||||||
*/
|
|
||||||
if (pci_has_flag(PCI_PROBE_ONLY)) {
|
|
||||||
pci_bus_claim_resources(bus);
|
pci_bus_claim_resources(bus);
|
||||||
} else {
|
|
||||||
pci_bus_size_bridges(bus);
|
|
||||||
pci_bus_assign_resources(bus);
|
|
||||||
|
|
||||||
list_for_each_entry(child, &bus->children, node)
|
/*
|
||||||
pcie_bus_configure_settings(child);
|
* Assign whatever was left unassigned. If we didn't claim above,
|
||||||
}
|
* this will reassign everything.
|
||||||
|
*/
|
||||||
|
pci_assign_unassigned_root_bus_resources(bus);
|
||||||
|
|
||||||
|
list_for_each_entry(child, &bus->children, node)
|
||||||
|
pcie_bus_configure_settings(child);
|
||||||
|
|
||||||
pci_bus_add_devices(bus);
|
pci_bus_add_devices(bus);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -5008,6 +5008,10 @@ static const struct pci_dev_acs_enabled {
|
|||||||
{ PCI_VENDOR_ID_BROADCOM, 0x1750, pci_quirk_mf_endpoint_acs },
|
{ PCI_VENDOR_ID_BROADCOM, 0x1750, pci_quirk_mf_endpoint_acs },
|
||||||
{ PCI_VENDOR_ID_BROADCOM, 0x1751, pci_quirk_mf_endpoint_acs },
|
{ PCI_VENDOR_ID_BROADCOM, 0x1751, pci_quirk_mf_endpoint_acs },
|
||||||
{ PCI_VENDOR_ID_BROADCOM, 0x1752, pci_quirk_mf_endpoint_acs },
|
{ PCI_VENDOR_ID_BROADCOM, 0x1752, pci_quirk_mf_endpoint_acs },
|
||||||
|
{ PCI_VENDOR_ID_BROADCOM, 0x1760, pci_quirk_mf_endpoint_acs },
|
||||||
|
{ PCI_VENDOR_ID_BROADCOM, 0x1761, pci_quirk_mf_endpoint_acs },
|
||||||
|
{ PCI_VENDOR_ID_BROADCOM, 0x1762, pci_quirk_mf_endpoint_acs },
|
||||||
|
{ PCI_VENDOR_ID_BROADCOM, 0x1763, pci_quirk_mf_endpoint_acs },
|
||||||
{ PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs },
|
{ PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs },
|
||||||
/* Amazon Annapurna Labs */
|
/* Amazon Annapurna Labs */
|
||||||
{ PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs },
|
{ PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs },
|
||||||
|
|||||||
@@ -42,8 +42,9 @@ struct p2sb_res_cache {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE];
|
static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE];
|
||||||
|
static bool p2sb_hidden_by_bios;
|
||||||
|
|
||||||
static int p2sb_get_devfn(unsigned int *devfn)
|
static void p2sb_get_devfn(unsigned int *devfn)
|
||||||
{
|
{
|
||||||
unsigned int fn = P2SB_DEVFN_DEFAULT;
|
unsigned int fn = P2SB_DEVFN_DEFAULT;
|
||||||
const struct x86_cpu_id *id;
|
const struct x86_cpu_id *id;
|
||||||
@@ -53,7 +54,6 @@ static int p2sb_get_devfn(unsigned int *devfn)
|
|||||||
fn = (unsigned int)id->driver_data;
|
fn = (unsigned int)id->driver_data;
|
||||||
|
|
||||||
*devfn = fn;
|
*devfn = fn;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool p2sb_valid_resource(const struct resource *res)
|
static bool p2sb_valid_resource(const struct resource *res)
|
||||||
@@ -97,6 +97,12 @@ static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn)
|
|||||||
|
|
||||||
static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn)
|
static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* The BIOS prevents the P2SB device from being enumerated by the PCI
|
||||||
|
* subsystem, so we need to unhide and hide it back to lookup the BAR.
|
||||||
|
*/
|
||||||
|
pci_bus_write_config_dword(bus, devfn, P2SBC, 0);
|
||||||
|
|
||||||
/* Scan the P2SB device and cache its BAR0 */
|
/* Scan the P2SB device and cache its BAR0 */
|
||||||
p2sb_scan_and_cache_devfn(bus, devfn);
|
p2sb_scan_and_cache_devfn(bus, devfn);
|
||||||
|
|
||||||
@@ -104,6 +110,8 @@ static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn)
|
|||||||
if (devfn == P2SB_DEVFN_GOLDMONT)
|
if (devfn == P2SB_DEVFN_GOLDMONT)
|
||||||
p2sb_scan_and_cache_devfn(bus, SPI_DEVFN_GOLDMONT);
|
p2sb_scan_and_cache_devfn(bus, SPI_DEVFN_GOLDMONT);
|
||||||
|
|
||||||
|
pci_bus_write_config_dword(bus, devfn, P2SBC, P2SBC_HIDE);
|
||||||
|
|
||||||
if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res))
|
if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res))
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
@@ -129,12 +137,10 @@ static int p2sb_cache_resources(void)
|
|||||||
u32 value = P2SBC_HIDE;
|
u32 value = P2SBC_HIDE;
|
||||||
struct pci_bus *bus;
|
struct pci_bus *bus;
|
||||||
u16 class;
|
u16 class;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
/* Get devfn for P2SB device itself */
|
/* Get devfn for P2SB device itself */
|
||||||
ret = p2sb_get_devfn(&devfn_p2sb);
|
p2sb_get_devfn(&devfn_p2sb);
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
bus = p2sb_get_bus(NULL);
|
bus = p2sb_get_bus(NULL);
|
||||||
if (!bus)
|
if (!bus)
|
||||||
@@ -154,26 +160,57 @@ static int p2sb_cache_resources(void)
|
|||||||
*/
|
*/
|
||||||
pci_lock_rescan_remove();
|
pci_lock_rescan_remove();
|
||||||
|
|
||||||
/*
|
|
||||||
* The BIOS prevents the P2SB device from being enumerated by the PCI
|
|
||||||
* subsystem, so we need to unhide and hide it back to lookup the BAR.
|
|
||||||
* Unhide the P2SB device here, if needed.
|
|
||||||
*/
|
|
||||||
pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value);
|
pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value);
|
||||||
if (value & P2SBC_HIDE)
|
p2sb_hidden_by_bios = value & P2SBC_HIDE;
|
||||||
pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0);
|
|
||||||
|
|
||||||
ret = p2sb_scan_and_cache(bus, devfn_p2sb);
|
/*
|
||||||
|
* If the BIOS does not hide the P2SB device then its resources
|
||||||
/* Hide the P2SB device, if it was hidden */
|
* are accesilble. Cache them only if the P2SB device is hidden.
|
||||||
if (value & P2SBC_HIDE)
|
*/
|
||||||
pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, P2SBC_HIDE);
|
if (p2sb_hidden_by_bios)
|
||||||
|
ret = p2sb_scan_and_cache(bus, devfn_p2sb);
|
||||||
|
|
||||||
pci_unlock_rescan_remove();
|
pci_unlock_rescan_remove();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int p2sb_read_from_cache(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
struct resource *mem)
|
||||||
|
{
|
||||||
|
struct p2sb_res_cache *cache = &p2sb_resources[PCI_FUNC(devfn)];
|
||||||
|
|
||||||
|
if (cache->bus_dev_id != bus->dev.id)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (!p2sb_valid_resource(&cache->res))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
memcpy(mem, &cache->res, sizeof(*mem));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int p2sb_read_from_dev(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
struct resource *mem)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
pdev = pci_get_slot(bus, devfn);
|
||||||
|
if (!pdev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (p2sb_valid_resource(pci_resource_n(pdev, 0)))
|
||||||
|
p2sb_read_bar0(pdev, mem);
|
||||||
|
else
|
||||||
|
ret = -ENOENT;
|
||||||
|
|
||||||
|
pci_dev_put(pdev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR
|
* p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR
|
||||||
* @bus: PCI bus to communicate with
|
* @bus: PCI bus to communicate with
|
||||||
@@ -190,28 +227,17 @@ static int p2sb_cache_resources(void)
|
|||||||
*/
|
*/
|
||||||
int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)
|
int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)
|
||||||
{
|
{
|
||||||
struct p2sb_res_cache *cache;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bus = p2sb_get_bus(bus);
|
bus = p2sb_get_bus(bus);
|
||||||
if (!bus)
|
if (!bus)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (!devfn) {
|
if (!devfn)
|
||||||
ret = p2sb_get_devfn(&devfn);
|
p2sb_get_devfn(&devfn);
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
cache = &p2sb_resources[PCI_FUNC(devfn)];
|
if (p2sb_hidden_by_bios)
|
||||||
if (cache->bus_dev_id != bus->dev.id)
|
return p2sb_read_from_cache(bus, devfn, mem);
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
if (!p2sb_valid_resource(&cache->res))
|
return p2sb_read_from_dev(bus, devfn, mem);
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
memcpy(mem, &cache->res, sizeof(*mem));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(p2sb_bar);
|
EXPORT_SYMBOL_GPL(p2sb_bar);
|
||||||
|
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ int clk_enable(struct clk *clk)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!clk)
|
if (!clk)
|
||||||
return -EINVAL;
|
return 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&clock_lock, flags);
|
spin_lock_irqsave(&clock_lock, flags);
|
||||||
ret = __clk_enable(clk);
|
ret = __clk_enable(clk);
|
||||||
|
|||||||
@@ -1093,6 +1093,37 @@ static void tb_exit_redrive(struct tb_port *port)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tb_switch_enter_redrive(struct tb_switch *sw)
|
||||||
|
{
|
||||||
|
struct tb_port *port;
|
||||||
|
|
||||||
|
tb_switch_for_each_port(sw, port)
|
||||||
|
tb_enter_redrive(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called during system and runtime suspend to forcefully exit redrive
|
||||||
|
* mode without querying whether the resource is available.
|
||||||
|
*/
|
||||||
|
static void tb_switch_exit_redrive(struct tb_switch *sw)
|
||||||
|
{
|
||||||
|
struct tb_port *port;
|
||||||
|
|
||||||
|
if (!(sw->quirks & QUIRK_KEEP_POWER_IN_DP_REDRIVE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
tb_switch_for_each_port(sw, port) {
|
||||||
|
if (!tb_port_is_dpin(port))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (port->redrive) {
|
||||||
|
port->redrive = false;
|
||||||
|
pm_runtime_put(&sw->dev);
|
||||||
|
tb_port_dbg(port, "exit redrive mode\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void tb_dp_resource_unavailable(struct tb *tb, struct tb_port *port)
|
static void tb_dp_resource_unavailable(struct tb *tb, struct tb_port *port)
|
||||||
{
|
{
|
||||||
struct tb_port *in, *out;
|
struct tb_port *in, *out;
|
||||||
@@ -1548,6 +1579,7 @@ static int tb_start(struct tb *tb)
|
|||||||
tb_create_usb3_tunnels(tb->root_switch);
|
tb_create_usb3_tunnels(tb->root_switch);
|
||||||
/* Add DP IN resources for the root switch */
|
/* Add DP IN resources for the root switch */
|
||||||
tb_add_dp_resources(tb->root_switch);
|
tb_add_dp_resources(tb->root_switch);
|
||||||
|
tb_switch_enter_redrive(tb->root_switch);
|
||||||
/* Make the discovered switches available to the userspace */
|
/* Make the discovered switches available to the userspace */
|
||||||
device_for_each_child(&tb->root_switch->dev, NULL,
|
device_for_each_child(&tb->root_switch->dev, NULL,
|
||||||
tb_scan_finalize_switch);
|
tb_scan_finalize_switch);
|
||||||
@@ -1563,6 +1595,7 @@ static int tb_suspend_noirq(struct tb *tb)
|
|||||||
|
|
||||||
tb_dbg(tb, "suspending...\n");
|
tb_dbg(tb, "suspending...\n");
|
||||||
tb_disconnect_and_release_dp(tb);
|
tb_disconnect_and_release_dp(tb);
|
||||||
|
tb_switch_exit_redrive(tb->root_switch);
|
||||||
tb_switch_suspend(tb->root_switch, false);
|
tb_switch_suspend(tb->root_switch, false);
|
||||||
tcm->hotplug_active = false; /* signal tb_handle_hotplug to quit */
|
tcm->hotplug_active = false; /* signal tb_handle_hotplug to quit */
|
||||||
tb_dbg(tb, "suspend finished\n");
|
tb_dbg(tb, "suspend finished\n");
|
||||||
@@ -1665,6 +1698,7 @@ static int tb_resume_noirq(struct tb *tb)
|
|||||||
tb_dbg(tb, "tunnels restarted, sleeping for 100ms\n");
|
tb_dbg(tb, "tunnels restarted, sleeping for 100ms\n");
|
||||||
msleep(100);
|
msleep(100);
|
||||||
}
|
}
|
||||||
|
tb_switch_enter_redrive(tb->root_switch);
|
||||||
/* Allow tb_handle_hotplug to progress events */
|
/* Allow tb_handle_hotplug to progress events */
|
||||||
tcm->hotplug_active = true;
|
tcm->hotplug_active = true;
|
||||||
tb_dbg(tb, "resume finished\n");
|
tb_dbg(tb, "resume finished\n");
|
||||||
@@ -1728,6 +1762,12 @@ static int tb_runtime_suspend(struct tb *tb)
|
|||||||
struct tb_cm *tcm = tb_priv(tb);
|
struct tb_cm *tcm = tb_priv(tb);
|
||||||
|
|
||||||
mutex_lock(&tb->lock);
|
mutex_lock(&tb->lock);
|
||||||
|
/*
|
||||||
|
* The below call only releases DP resources to allow exiting and
|
||||||
|
* re-entering redrive mode.
|
||||||
|
*/
|
||||||
|
tb_disconnect_and_release_dp(tb);
|
||||||
|
tb_switch_exit_redrive(tb->root_switch);
|
||||||
tb_switch_suspend(tb->root_switch, true);
|
tb_switch_suspend(tb->root_switch, true);
|
||||||
tcm->hotplug_active = false;
|
tcm->hotplug_active = false;
|
||||||
mutex_unlock(&tb->lock);
|
mutex_unlock(&tb->lock);
|
||||||
@@ -1759,6 +1799,7 @@ static int tb_runtime_resume(struct tb *tb)
|
|||||||
tb_restore_children(tb->root_switch);
|
tb_restore_children(tb->root_switch);
|
||||||
list_for_each_entry_safe(tunnel, n, &tcm->tunnel_list, list)
|
list_for_each_entry_safe(tunnel, n, &tcm->tunnel_list, list)
|
||||||
tb_tunnel_restart(tunnel);
|
tb_tunnel_restart(tunnel);
|
||||||
|
tb_switch_enter_redrive(tb->root_switch);
|
||||||
tcm->hotplug_active = true;
|
tcm->hotplug_active = true;
|
||||||
mutex_unlock(&tb->lock);
|
mutex_unlock(&tb->lock);
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ struct cdns3_platform_data {
|
|||||||
bool suspend, bool wakeup);
|
bool suspend, bool wakeup);
|
||||||
unsigned long quirks;
|
unsigned long quirks;
|
||||||
#define CDNS3_DEFAULT_PM_RUNTIME_ALLOW BIT(0)
|
#define CDNS3_DEFAULT_PM_RUNTIME_ALLOW BIT(0)
|
||||||
|
#define CDNS3_DRD_SUSPEND_RESIDENCY_ENABLE BIT(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ static irqreturn_t cdns_drd_irq(int irq, void *data)
|
|||||||
int cdns_drd_init(struct cdns *cdns)
|
int cdns_drd_init(struct cdns *cdns)
|
||||||
{
|
{
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
u32 state;
|
u32 state, reg;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res);
|
regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res);
|
||||||
@@ -429,6 +429,14 @@ int cdns_drd_init(struct cdns *cdns)
|
|||||||
cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *)
|
cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *)
|
||||||
&cdns->otg_v1_regs->ien;
|
&cdns->otg_v1_regs->ien;
|
||||||
writel(1, &cdns->otg_v1_regs->simulate);
|
writel(1, &cdns->otg_v1_regs->simulate);
|
||||||
|
|
||||||
|
if (cdns->pdata &&
|
||||||
|
(cdns->pdata->quirks & CDNS3_DRD_SUSPEND_RESIDENCY_ENABLE)) {
|
||||||
|
reg = readl(&cdns->otg_v1_regs->susp_ctrl);
|
||||||
|
reg |= SUSP_CTRL_SUSPEND_RESIDENCY_ENABLE;
|
||||||
|
writel(reg, &cdns->otg_v1_regs->susp_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
cdns->version = CDNS3_CONTROLLER_V1;
|
cdns->version = CDNS3_CONTROLLER_V1;
|
||||||
} else {
|
} else {
|
||||||
dev_err(cdns->dev, "not supporte DID=0x%08x\n", state);
|
dev_err(cdns->dev, "not supporte DID=0x%08x\n", state);
|
||||||
|
|||||||
@@ -193,6 +193,9 @@ struct cdns_otg_irq_regs {
|
|||||||
/* OTGREFCLK - bitmasks */
|
/* OTGREFCLK - bitmasks */
|
||||||
#define OTGREFCLK_STB_CLK_SWITCH_EN BIT(31)
|
#define OTGREFCLK_STB_CLK_SWITCH_EN BIT(31)
|
||||||
|
|
||||||
|
/* SUPS_CTRL - bitmasks */
|
||||||
|
#define SUSP_CTRL_SUSPEND_RESIDENCY_ENABLE BIT(17)
|
||||||
|
|
||||||
/* OVERRIDE - bitmasks */
|
/* OVERRIDE - bitmasks */
|
||||||
#define OVERRIDE_IDPULLUP BIT(0)
|
#define OVERRIDE_IDPULLUP BIT(0)
|
||||||
/* Only for CDNS3_CONTROLLER_V0 version */
|
/* Only for CDNS3_CONTROLLER_V0 version */
|
||||||
|
|||||||
@@ -886,10 +886,10 @@ static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* DMA sg buffer */
|
/* DMA sg buffer */
|
||||||
for_each_sg(ureq->sg, sg, ureq->num_sgs, i) {
|
for_each_sg(ureq->sg, sg, ureq->num_mapped_sgs, i) {
|
||||||
dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &desc,
|
dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &desc,
|
||||||
sg_dma_address(sg) + sg->offset, sg_dma_len(sg),
|
sg_dma_address(sg) + sg->offset, sg_dma_len(sg),
|
||||||
sg_is_last(sg));
|
(i == (ureq->num_mapped_sgs - 1)));
|
||||||
desc_count += hs_ep->desc_count;
|
desc_count += hs_ep->desc_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -625,6 +625,8 @@ static void option_instat_callback(struct urb *urb);
|
|||||||
#define MEIGSMART_PRODUCT_SRM825L 0x4d22
|
#define MEIGSMART_PRODUCT_SRM825L 0x4d22
|
||||||
/* MeiG Smart SLM320 based on UNISOC UIS8910 */
|
/* MeiG Smart SLM320 based on UNISOC UIS8910 */
|
||||||
#define MEIGSMART_PRODUCT_SLM320 0x4d41
|
#define MEIGSMART_PRODUCT_SLM320 0x4d41
|
||||||
|
/* MeiG Smart SLM770A based on ASR1803 */
|
||||||
|
#define MEIGSMART_PRODUCT_SLM770A 0x4d57
|
||||||
|
|
||||||
/* Device flags */
|
/* Device flags */
|
||||||
|
|
||||||
@@ -1395,6 +1397,12 @@ static const struct usb_device_id option_ids[] = {
|
|||||||
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
|
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */
|
||||||
.driver_info = NCTRL(3) | RSVD(4) | RSVD(5) },
|
.driver_info = NCTRL(3) | RSVD(4) | RSVD(5) },
|
||||||
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c0, 0xff), /* Telit FE910C04 (rmnet) */
|
||||||
|
.driver_info = RSVD(0) | NCTRL(3) },
|
||||||
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c4, 0xff), /* Telit FE910C04 (rmnet) */
|
||||||
|
.driver_info = RSVD(0) | NCTRL(3) },
|
||||||
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */
|
||||||
|
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
|
||||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
|
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
|
||||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
|
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
|
||||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
||||||
@@ -2247,6 +2255,8 @@ static const struct usb_device_id option_ids[] = {
|
|||||||
.driver_info = NCTRL(2) },
|
.driver_info = NCTRL(2) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x7127, 0xff, 0x00, 0x00),
|
{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x7127, 0xff, 0x00, 0x00),
|
||||||
.driver_info = NCTRL(2) | NCTRL(3) | NCTRL(4) },
|
.driver_info = NCTRL(2) | NCTRL(3) | NCTRL(4) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x7129, 0xff, 0x00, 0x00), /* MediaTek T7XX */
|
||||||
|
.driver_info = NCTRL(2) | NCTRL(3) | NCTRL(4) },
|
||||||
{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
|
{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
|
||||||
{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MPL200),
|
{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MPL200),
|
||||||
.driver_info = RSVD(1) | RSVD(4) },
|
.driver_info = RSVD(1) | RSVD(4) },
|
||||||
@@ -2375,6 +2385,18 @@ static const struct usb_device_id option_ids[] = {
|
|||||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Golbal EDU */
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Golbal EDU */
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0x00, 0x40) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0x00, 0x40) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0xff, 0x40) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0xff, 0x40) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010a, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WRD for WWAN Ready */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010a, 0xff, 0x00, 0x40) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010a, 0xff, 0xff, 0x40) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010b, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for WWAN Ready */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010b, 0xff, 0x00, 0x40) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010b, 0xff, 0xff, 0x40) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010c, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WRD for WWAN Ready */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010c, 0xff, 0x00, 0x40) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010c, 0xff, 0xff, 0x40) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010d, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for WWAN Ready */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010d, 0xff, 0x00, 0x40) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x010d, 0xff, 0xff, 0x40) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
|
||||||
@@ -2382,9 +2404,14 @@ static const struct usb_device_id option_ids[] = {
|
|||||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) },
|
||||||
|
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
|
||||||
|
.driver_info = NCTRL(1) },
|
||||||
|
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */
|
||||||
|
.driver_info = NCTRL(3) },
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||||
|
|||||||
@@ -1433,6 +1433,11 @@ static int check_extent_item(struct extent_buffer *leaf,
|
|||||||
dref_offset, fs_info->sectorsize);
|
dref_offset, fs_info->sectorsize);
|
||||||
return -EUCLEAN;
|
return -EUCLEAN;
|
||||||
}
|
}
|
||||||
|
if (unlikely(btrfs_extent_data_ref_count(leaf, dref) == 0)) {
|
||||||
|
extent_err(leaf, slot,
|
||||||
|
"invalid data ref count, should have non-zero value");
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
inline_refs += btrfs_extent_data_ref_count(leaf, dref);
|
inline_refs += btrfs_extent_data_ref_count(leaf, dref);
|
||||||
break;
|
break;
|
||||||
/* Contains parent bytenr and ref count */
|
/* Contains parent bytenr and ref count */
|
||||||
@@ -1445,6 +1450,11 @@ static int check_extent_item(struct extent_buffer *leaf,
|
|||||||
inline_offset, fs_info->sectorsize);
|
inline_offset, fs_info->sectorsize);
|
||||||
return -EUCLEAN;
|
return -EUCLEAN;
|
||||||
}
|
}
|
||||||
|
if (unlikely(btrfs_shared_data_ref_count(leaf, sref) == 0)) {
|
||||||
|
extent_err(leaf, slot,
|
||||||
|
"invalid shared data ref count, should have non-zero value");
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
inline_refs += btrfs_shared_data_ref_count(leaf, sref);
|
inline_refs += btrfs_shared_data_ref_count(leaf, sref);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1496,8 +1506,18 @@ static int check_simple_keyed_refs(struct extent_buffer *leaf,
|
|||||||
{
|
{
|
||||||
u32 expect_item_size = 0;
|
u32 expect_item_size = 0;
|
||||||
|
|
||||||
if (key->type == BTRFS_SHARED_DATA_REF_KEY)
|
if (key->type == BTRFS_SHARED_DATA_REF_KEY) {
|
||||||
|
struct btrfs_shared_data_ref *sref;
|
||||||
|
|
||||||
|
sref = btrfs_item_ptr(leaf, slot, struct btrfs_shared_data_ref);
|
||||||
|
if (unlikely(btrfs_shared_data_ref_count(leaf, sref) == 0)) {
|
||||||
|
extent_err(leaf, slot,
|
||||||
|
"invalid shared data backref count, should have non-zero value");
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
|
|
||||||
expect_item_size = sizeof(struct btrfs_shared_data_ref);
|
expect_item_size = sizeof(struct btrfs_shared_data_ref);
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(btrfs_item_size(leaf, slot) != expect_item_size)) {
|
if (unlikely(btrfs_item_size(leaf, slot) != expect_item_size)) {
|
||||||
generic_err(leaf, slot,
|
generic_err(leaf, slot,
|
||||||
@@ -1557,6 +1577,11 @@ static int check_extent_data_ref(struct extent_buffer *leaf,
|
|||||||
offset, leaf->fs_info->sectorsize);
|
offset, leaf->fs_info->sectorsize);
|
||||||
return -EUCLEAN;
|
return -EUCLEAN;
|
||||||
}
|
}
|
||||||
|
if (unlikely(btrfs_extent_data_ref_count(leaf, dref) == 0)) {
|
||||||
|
extent_err(leaf, slot,
|
||||||
|
"invalid extent data backref count, should have non-zero value");
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -420,6 +420,8 @@ static int ceph_parse_mount_param(struct fs_context *fc,
|
|||||||
|
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case Opt_snapdirname:
|
case Opt_snapdirname:
|
||||||
|
if (strlen(param->string) > NAME_MAX)
|
||||||
|
return invalfc(fc, "snapdirname too long");
|
||||||
kfree(fsopt->snapdir_name);
|
kfree(fsopt->snapdir_name);
|
||||||
fsopt->snapdir_name = param->string;
|
fsopt->snapdir_name = param->string;
|
||||||
param->string = NULL;
|
param->string = NULL;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ struct inode *efivarfs_get_inode(struct super_block *sb,
|
|||||||
*
|
*
|
||||||
* VariableName-12345678-1234-1234-1234-1234567891bc
|
* VariableName-12345678-1234-1234-1234-1234567891bc
|
||||||
*/
|
*/
|
||||||
bool efivarfs_valid_name(const char *str, int len)
|
static bool efivarfs_valid_name(const char *str, int len)
|
||||||
{
|
{
|
||||||
const char *s = str + len - EFI_VARIABLE_GUID_LEN;
|
const char *s = str + len - EFI_VARIABLE_GUID_LEN;
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
|
|||||||
|
|
||||||
extern const struct file_operations efivarfs_file_operations;
|
extern const struct file_operations efivarfs_file_operations;
|
||||||
extern const struct inode_operations efivarfs_dir_inode_operations;
|
extern const struct inode_operations efivarfs_dir_inode_operations;
|
||||||
extern bool efivarfs_valid_name(const char *str, int len);
|
|
||||||
extern struct inode *efivarfs_get_inode(struct super_block *sb,
|
extern struct inode *efivarfs_get_inode(struct super_block *sb,
|
||||||
const struct inode *dir, int mode, dev_t dev,
|
const struct inode *dir, int mode, dev_t dev,
|
||||||
bool is_removable);
|
bool is_removable);
|
||||||
|
|||||||
@@ -64,9 +64,6 @@ static int efivarfs_d_hash(const struct dentry *dentry, struct qstr *qstr)
|
|||||||
const unsigned char *s = qstr->name;
|
const unsigned char *s = qstr->name;
|
||||||
unsigned int len = qstr->len;
|
unsigned int len = qstr->len;
|
||||||
|
|
||||||
if (!efivarfs_valid_name(s, len))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
while (len-- > EFI_VARIABLE_GUID_LEN)
|
while (len-- > EFI_VARIABLE_GUID_LEN)
|
||||||
hash = partial_name_hash(*s++, hash);
|
hash = partial_name_hash(*s++, hash);
|
||||||
|
|
||||||
|
|||||||
@@ -1278,7 +1278,10 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wake_up(&ep->wq);
|
if (sync)
|
||||||
|
wake_up_sync(&ep->wq);
|
||||||
|
else
|
||||||
|
wake_up(&ep->wq);
|
||||||
}
|
}
|
||||||
if (waitqueue_active(&ep->poll_wait))
|
if (waitqueue_active(&ep->poll_wait))
|
||||||
pwake++;
|
pwake++;
|
||||||
|
|||||||
@@ -1196,7 +1196,7 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo,
|
|||||||
enum pnfs_iomode *iomode)
|
enum pnfs_iomode *iomode)
|
||||||
{
|
{
|
||||||
/* Serialise LAYOUTGET/LAYOUTRETURN */
|
/* Serialise LAYOUTGET/LAYOUTRETURN */
|
||||||
if (atomic_read(&lo->plh_outstanding) != 0)
|
if (atomic_read(&lo->plh_outstanding) != 0 && lo->plh_return_seq == 0)
|
||||||
return false;
|
return false;
|
||||||
if (test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags))
|
if (test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags))
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ void nilfs_init_btnc_inode(struct inode *btnc_inode)
|
|||||||
ii->i_flags = 0;
|
ii->i_flags = 0;
|
||||||
memset(&ii->i_bmap_data, 0, sizeof(struct nilfs_bmap));
|
memset(&ii->i_bmap_data, 0, sizeof(struct nilfs_bmap));
|
||||||
mapping_set_gfp_mask(btnc_inode->i_mapping, GFP_NOFS);
|
mapping_set_gfp_mask(btnc_inode->i_mapping, GFP_NOFS);
|
||||||
|
btnc_inode->i_mapping->a_ops = &nilfs_buffer_cache_aops;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nilfs_btnode_cache_clear(struct address_space *btnc)
|
void nilfs_btnode_cache_clear(struct address_space *btnc)
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ int nilfs_init_gcinode(struct inode *inode)
|
|||||||
|
|
||||||
inode->i_mode = S_IFREG;
|
inode->i_mode = S_IFREG;
|
||||||
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
|
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
|
||||||
inode->i_mapping->a_ops = &empty_aops;
|
inode->i_mapping->a_ops = &nilfs_buffer_cache_aops;
|
||||||
|
|
||||||
ii->i_flags = 0;
|
ii->i_flags = 0;
|
||||||
nilfs_bmap_init_gc(ii->i_bmap);
|
nilfs_bmap_init_gc(ii->i_bmap);
|
||||||
|
|||||||
@@ -309,6 +309,10 @@ const struct address_space_operations nilfs_aops = {
|
|||||||
.is_partially_uptodate = block_is_partially_uptodate,
|
.is_partially_uptodate = block_is_partially_uptodate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct address_space_operations nilfs_buffer_cache_aops = {
|
||||||
|
.invalidate_folio = block_invalidate_folio,
|
||||||
|
};
|
||||||
|
|
||||||
static int nilfs_insert_inode_locked(struct inode *inode,
|
static int nilfs_insert_inode_locked(struct inode *inode,
|
||||||
struct nilfs_root *root,
|
struct nilfs_root *root,
|
||||||
unsigned long ino)
|
unsigned long ino)
|
||||||
@@ -614,8 +618,14 @@ struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root,
|
|||||||
inode = nilfs_iget_locked(sb, root, ino);
|
inode = nilfs_iget_locked(sb, root, ino);
|
||||||
if (unlikely(!inode))
|
if (unlikely(!inode))
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
if (!(inode->i_state & I_NEW))
|
|
||||||
|
if (!(inode->i_state & I_NEW)) {
|
||||||
|
if (!inode->i_nlink) {
|
||||||
|
iput(inode);
|
||||||
|
return ERR_PTR(-ESTALE);
|
||||||
|
}
|
||||||
return inode;
|
return inode;
|
||||||
|
}
|
||||||
|
|
||||||
err = __nilfs_read_inode(sb, root, ino, inode);
|
err = __nilfs_read_inode(sb, root, ino, inode);
|
||||||
if (unlikely(err)) {
|
if (unlikely(err)) {
|
||||||
@@ -748,6 +758,7 @@ struct inode *nilfs_iget_for_shadow(struct inode *inode)
|
|||||||
NILFS_I(s_inode)->i_flags = 0;
|
NILFS_I(s_inode)->i_flags = 0;
|
||||||
memset(NILFS_I(s_inode)->i_bmap, 0, sizeof(struct nilfs_bmap));
|
memset(NILFS_I(s_inode)->i_bmap, 0, sizeof(struct nilfs_bmap));
|
||||||
mapping_set_gfp_mask(s_inode->i_mapping, GFP_NOFS);
|
mapping_set_gfp_mask(s_inode->i_mapping, GFP_NOFS);
|
||||||
|
s_inode->i_mapping->a_ops = &nilfs_buffer_cache_aops;
|
||||||
|
|
||||||
err = nilfs_attach_btree_node_cache(s_inode);
|
err = nilfs_attach_btree_node_cache(s_inode);
|
||||||
if (unlikely(err)) {
|
if (unlikely(err)) {
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ nilfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
|||||||
inode = NULL;
|
inode = NULL;
|
||||||
} else {
|
} else {
|
||||||
inode = nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino);
|
inode = nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino);
|
||||||
|
if (inode == ERR_PTR(-ESTALE)) {
|
||||||
|
nilfs_error(dir->i_sb,
|
||||||
|
"deleted inode referenced: %lu", ino);
|
||||||
|
return ERR_PTR(-EIO);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return d_splice_alias(inode, dentry);
|
return d_splice_alias(inode, dentry);
|
||||||
|
|||||||
@@ -379,6 +379,7 @@ extern const struct file_operations nilfs_dir_operations;
|
|||||||
extern const struct inode_operations nilfs_file_inode_operations;
|
extern const struct inode_operations nilfs_file_inode_operations;
|
||||||
extern const struct file_operations nilfs_file_operations;
|
extern const struct file_operations nilfs_file_operations;
|
||||||
extern const struct address_space_operations nilfs_aops;
|
extern const struct address_space_operations nilfs_aops;
|
||||||
|
extern const struct address_space_operations nilfs_buffer_cache_aops;
|
||||||
extern const struct inode_operations nilfs_dir_inode_operations;
|
extern const struct inode_operations nilfs_dir_inode_operations;
|
||||||
extern const struct inode_operations nilfs_special_inode_operations;
|
extern const struct inode_operations nilfs_special_inode_operations;
|
||||||
extern const struct inode_operations nilfs_symlink_inode_operations;
|
extern const struct inode_operations nilfs_symlink_inode_operations;
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter)
|
|||||||
static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter)
|
static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter)
|
||||||
{
|
{
|
||||||
iter->loffset++;
|
iter->loffset++;
|
||||||
if (iter->loffset < iter->elen >> iter->dir->i_blkbits)
|
if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
iter->loffset = 0;
|
iter->loffset = 0;
|
||||||
|
|||||||
@@ -1567,6 +1567,7 @@ struct hv_util_service {
|
|||||||
void *channel;
|
void *channel;
|
||||||
void (*util_cb)(void *);
|
void (*util_cb)(void *);
|
||||||
int (*util_init)(struct hv_util_service *);
|
int (*util_init)(struct hv_util_service *);
|
||||||
|
int (*util_init_transport)(void);
|
||||||
void (*util_deinit)(void);
|
void (*util_deinit)(void);
|
||||||
int (*util_pre_suspend)(void);
|
int (*util_pre_suspend)(void);
|
||||||
int (*util_pre_resume)(void);
|
int (*util_pre_resume)(void);
|
||||||
|
|||||||
@@ -50,10 +50,8 @@ bool io_is_uring_fops(struct file *file);
|
|||||||
|
|
||||||
static inline void io_uring_files_cancel(void)
|
static inline void io_uring_files_cancel(void)
|
||||||
{
|
{
|
||||||
if (current->io_uring) {
|
if (current->io_uring)
|
||||||
io_uring_unreg_ringfd();
|
|
||||||
__io_uring_cancel(false);
|
__io_uring_cancel(false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
static inline void io_uring_task_cancel(void)
|
static inline void io_uring_task_cancel(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1974,14 +1974,13 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma);
|
|||||||
* These helpers provide future and backwards compatibility
|
* These helpers provide future and backwards compatibility
|
||||||
* for accessing popular PCI BAR info
|
* for accessing popular PCI BAR info
|
||||||
*/
|
*/
|
||||||
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
|
#define pci_resource_n(dev, bar) (&(dev)->resource[(bar)])
|
||||||
#define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end)
|
#define pci_resource_start(dev, bar) (pci_resource_n(dev, bar)->start)
|
||||||
#define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags)
|
#define pci_resource_end(dev, bar) (pci_resource_n(dev, bar)->end)
|
||||||
#define pci_resource_len(dev,bar) \
|
#define pci_resource_flags(dev, bar) (pci_resource_n(dev, bar)->flags)
|
||||||
((pci_resource_end((dev), (bar)) == 0) ? 0 : \
|
#define pci_resource_len(dev,bar) \
|
||||||
\
|
(pci_resource_end((dev), (bar)) ? \
|
||||||
(pci_resource_end((dev), (bar)) - \
|
resource_size(pci_resource_n((dev), (bar))) : 0)
|
||||||
pci_resource_start((dev), (bar)) + 1))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Similar to the helpers above, these manipulate per-pci_dev
|
* Similar to the helpers above, these manipulate per-pci_dev
|
||||||
|
|||||||
@@ -224,12 +224,12 @@ void __wake_up_pollfree(struct wait_queue_head *wq_head);
|
|||||||
#define wake_up_all(x) __wake_up(x, TASK_NORMAL, 0, NULL)
|
#define wake_up_all(x) __wake_up(x, TASK_NORMAL, 0, NULL)
|
||||||
#define wake_up_locked(x) __wake_up_locked((x), TASK_NORMAL, 1)
|
#define wake_up_locked(x) __wake_up_locked((x), TASK_NORMAL, 1)
|
||||||
#define wake_up_all_locked(x) __wake_up_locked((x), TASK_NORMAL, 0)
|
#define wake_up_all_locked(x) __wake_up_locked((x), TASK_NORMAL, 0)
|
||||||
|
#define wake_up_sync(x) __wake_up_sync(x, TASK_NORMAL)
|
||||||
|
|
||||||
#define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
|
#define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
|
||||||
#define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL)
|
#define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL)
|
||||||
#define wake_up_interruptible_all(x) __wake_up(x, TASK_INTERRUPTIBLE, 0, NULL)
|
#define wake_up_interruptible_all(x) __wake_up(x, TASK_INTERRUPTIBLE, 0, NULL)
|
||||||
#define wake_up_interruptible_sync(x) __wake_up_sync((x), TASK_INTERRUPTIBLE)
|
#define wake_up_interruptible_sync(x) __wake_up_sync((x), TASK_INTERRUPTIBLE)
|
||||||
#define wake_up_sync(x) __wake_up_sync((x), TASK_NORMAL)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wakeup macros to be used to report events to the targets.
|
* Wakeup macros to be used to report events to the targets.
|
||||||
|
|||||||
@@ -434,13 +434,17 @@ static void io_prep_async_link(struct io_kiocb *req)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_queue_iowq(struct io_kiocb *req, bool *dont_use)
|
static void io_queue_iowq(struct io_kiocb *req)
|
||||||
{
|
{
|
||||||
struct io_kiocb *link = io_prep_linked_timeout(req);
|
struct io_kiocb *link = io_prep_linked_timeout(req);
|
||||||
struct io_uring_task *tctx = req->task->io_uring;
|
struct io_uring_task *tctx = req->task->io_uring;
|
||||||
|
|
||||||
BUG_ON(!tctx);
|
BUG_ON(!tctx);
|
||||||
BUG_ON(!tctx->io_wq);
|
|
||||||
|
if ((current->flags & PF_KTHREAD) || !tctx->io_wq) {
|
||||||
|
io_req_task_queue_fail(req, -ECANCELED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* init ->work of the whole link before punting */
|
/* init ->work of the whole link before punting */
|
||||||
io_prep_async_link(req);
|
io_prep_async_link(req);
|
||||||
@@ -1909,7 +1913,7 @@ static void io_queue_async(struct io_kiocb *req, int ret)
|
|||||||
break;
|
break;
|
||||||
case IO_APOLL_ABORTED:
|
case IO_APOLL_ABORTED:
|
||||||
io_kbuf_recycle(req, 0);
|
io_kbuf_recycle(req, 0);
|
||||||
io_queue_iowq(req, NULL);
|
io_queue_iowq(req);
|
||||||
break;
|
break;
|
||||||
case IO_APOLL_OK:
|
case IO_APOLL_OK:
|
||||||
break;
|
break;
|
||||||
@@ -1958,7 +1962,7 @@ static void io_queue_sqe_fallback(struct io_kiocb *req)
|
|||||||
if (unlikely(req->ctx->drain_active))
|
if (unlikely(req->ctx->drain_active))
|
||||||
io_drain_req(req);
|
io_drain_req(req);
|
||||||
else
|
else
|
||||||
io_queue_iowq(req, NULL);
|
io_queue_iowq(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3085,6 +3089,7 @@ __cold void io_uring_cancel_generic(bool cancel_all, struct io_sq_data *sqd)
|
|||||||
|
|
||||||
void __io_uring_cancel(bool cancel_all)
|
void __io_uring_cancel(bool cancel_all)
|
||||||
{
|
{
|
||||||
|
io_uring_unreg_ringfd();
|
||||||
io_uring_cancel_generic(cancel_all, NULL);
|
io_uring_cancel_generic(cancel_all, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ static inline bool io_req_ffs_set(struct io_kiocb *req)
|
|||||||
void __io_req_task_work_add(struct io_kiocb *req, bool allow_local);
|
void __io_req_task_work_add(struct io_kiocb *req, bool allow_local);
|
||||||
bool io_alloc_async_data(struct io_kiocb *req);
|
bool io_alloc_async_data(struct io_kiocb *req);
|
||||||
void io_req_task_queue(struct io_kiocb *req);
|
void io_req_task_queue(struct io_kiocb *req);
|
||||||
void io_queue_iowq(struct io_kiocb *req, bool *dont_use);
|
|
||||||
void io_req_task_complete(struct io_kiocb *req, bool *locked);
|
void io_req_task_complete(struct io_kiocb *req, bool *locked);
|
||||||
void io_req_task_queue_fail(struct io_kiocb *req, int ret);
|
void io_req_task_queue_fail(struct io_kiocb *req, int ret);
|
||||||
void io_req_task_submit(struct io_kiocb *req, bool *locked);
|
void io_req_task_submit(struct io_kiocb *req, bool *locked);
|
||||||
|
|||||||
@@ -167,12 +167,6 @@ static inline loff_t *io_kiocb_update_pos(struct io_kiocb *req)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void io_req_task_queue_reissue(struct io_kiocb *req)
|
|
||||||
{
|
|
||||||
req->io_task_work.func = io_queue_iowq;
|
|
||||||
io_req_task_work_add(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_BLOCK
|
#ifdef CONFIG_BLOCK
|
||||||
static bool io_resubmit_prep(struct io_kiocb *req)
|
static bool io_resubmit_prep(struct io_kiocb *req)
|
||||||
{
|
{
|
||||||
@@ -341,7 +335,7 @@ static int kiocb_done(struct io_kiocb *req, ssize_t ret,
|
|||||||
if (req->flags & REQ_F_REISSUE) {
|
if (req->flags & REQ_F_REISSUE) {
|
||||||
req->flags &= ~REQ_F_REISSUE;
|
req->flags &= ~REQ_F_REISSUE;
|
||||||
if (io_resubmit_prep(req))
|
if (io_resubmit_prep(req))
|
||||||
io_req_task_queue_reissue(req);
|
return -EAGAIN;
|
||||||
else
|
else
|
||||||
io_req_task_queue_fail(req, final_ret);
|
io_req_task_queue_fail(req, final_ret);
|
||||||
}
|
}
|
||||||
@@ -691,7 +685,7 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int io_read(struct io_kiocb *req, unsigned int issue_flags)
|
static int __io_read(struct io_kiocb *req, unsigned int issue_flags)
|
||||||
{
|
{
|
||||||
struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
|
struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
|
||||||
struct io_rw_state __s, *s = &__s;
|
struct io_rw_state __s, *s = &__s;
|
||||||
@@ -757,6 +751,14 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags)
|
|||||||
|
|
||||||
ret = io_iter_do_read(rw, &s->iter);
|
ret = io_iter_do_read(rw, &s->iter);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some file systems like to return -EOPNOTSUPP for an IOCB_NOWAIT
|
||||||
|
* issue, even though they should be returning -EAGAIN. To be safe,
|
||||||
|
* retry from blocking context for either.
|
||||||
|
*/
|
||||||
|
if (ret == -EOPNOTSUPP && force_nonblock)
|
||||||
|
ret = -EAGAIN;
|
||||||
|
|
||||||
if (ret == -EAGAIN || (req->flags & REQ_F_REISSUE)) {
|
if (ret == -EAGAIN || (req->flags & REQ_F_REISSUE)) {
|
||||||
req->flags &= ~REQ_F_REISSUE;
|
req->flags &= ~REQ_F_REISSUE;
|
||||||
/* if we can poll, just do that */
|
/* if we can poll, just do that */
|
||||||
@@ -836,7 +838,18 @@ done:
|
|||||||
/* it's faster to check here then delegate to kfree */
|
/* it's faster to check here then delegate to kfree */
|
||||||
if (iovec)
|
if (iovec)
|
||||||
kfree(iovec);
|
kfree(iovec);
|
||||||
return kiocb_done(req, ret, issue_flags);
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int io_read(struct io_kiocb *req, unsigned int issue_flags)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = __io_read(req, issue_flags);
|
||||||
|
if (ret >= 0)
|
||||||
|
return kiocb_done(req, ret, issue_flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool io_kiocb_start_write(struct io_kiocb *req, struct kiocb *kiocb)
|
static bool io_kiocb_start_write(struct io_kiocb *req, struct kiocb *kiocb)
|
||||||
|
|||||||
@@ -242,19 +242,16 @@ int trace_event_get_offsets(struct trace_event_call *call)
|
|||||||
return tail->offset + tail->size;
|
return tail->offset + tail->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if the referenced field is an array and return true,
|
static struct trace_event_fields *find_event_field(const char *fmt,
|
||||||
* as arrays are OK to dereference.
|
struct trace_event_call *call)
|
||||||
*/
|
|
||||||
static bool test_field(const char *fmt, struct trace_event_call *call)
|
|
||||||
{
|
{
|
||||||
struct trace_event_fields *field = call->class->fields_array;
|
struct trace_event_fields *field = call->class->fields_array;
|
||||||
const char *array_descriptor;
|
|
||||||
const char *p = fmt;
|
const char *p = fmt;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (!(len = str_has_prefix(fmt, "REC->")))
|
if (!(len = str_has_prefix(fmt, "REC->")))
|
||||||
return false;
|
return NULL;
|
||||||
fmt += len;
|
fmt += len;
|
||||||
for (p = fmt; *p; p++) {
|
for (p = fmt; *p; p++) {
|
||||||
if (!isalnum(*p) && *p != '_')
|
if (!isalnum(*p) && *p != '_')
|
||||||
@@ -263,16 +260,120 @@ static bool test_field(const char *fmt, struct trace_event_call *call)
|
|||||||
len = p - fmt;
|
len = p - fmt;
|
||||||
|
|
||||||
for (; field->type; field++) {
|
for (; field->type; field++) {
|
||||||
if (strncmp(field->name, fmt, len) ||
|
if (strncmp(field->name, fmt, len) || field->name[len])
|
||||||
field->name[len])
|
|
||||||
continue;
|
continue;
|
||||||
array_descriptor = strchr(field->type, '[');
|
|
||||||
/* This is an array and is OK to dereference. */
|
return field;
|
||||||
return array_descriptor != NULL;
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the referenced field is an array and return true,
|
||||||
|
* as arrays are OK to dereference.
|
||||||
|
*/
|
||||||
|
static bool test_field(const char *fmt, struct trace_event_call *call)
|
||||||
|
{
|
||||||
|
struct trace_event_fields *field;
|
||||||
|
|
||||||
|
field = find_event_field(fmt, call);
|
||||||
|
if (!field)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* This is an array and is OK to dereference. */
|
||||||
|
return strchr(field->type, '[') != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look for a string within an argument */
|
||||||
|
static bool find_print_string(const char *arg, const char *str, const char *end)
|
||||||
|
{
|
||||||
|
const char *r;
|
||||||
|
|
||||||
|
r = strstr(arg, str);
|
||||||
|
return r && r < end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true if the argument pointer is safe */
|
||||||
|
static bool process_pointer(const char *fmt, int len, struct trace_event_call *call)
|
||||||
|
{
|
||||||
|
const char *r, *e, *a;
|
||||||
|
|
||||||
|
e = fmt + len;
|
||||||
|
|
||||||
|
/* Find the REC-> in the argument */
|
||||||
|
r = strstr(fmt, "REC->");
|
||||||
|
if (r && r < e) {
|
||||||
|
/*
|
||||||
|
* Addresses of events on the buffer, or an array on the buffer is
|
||||||
|
* OK to dereference. There's ways to fool this, but
|
||||||
|
* this is to catch common mistakes, not malicious code.
|
||||||
|
*/
|
||||||
|
a = strchr(fmt, '&');
|
||||||
|
if ((a && (a < r)) || test_field(r, call))
|
||||||
|
return true;
|
||||||
|
} else if (find_print_string(fmt, "__get_dynamic_array(", e)) {
|
||||||
|
return true;
|
||||||
|
} else if (find_print_string(fmt, "__get_rel_dynamic_array(", e)) {
|
||||||
|
return true;
|
||||||
|
} else if (find_print_string(fmt, "__get_dynamic_array_len(", e)) {
|
||||||
|
return true;
|
||||||
|
} else if (find_print_string(fmt, "__get_rel_dynamic_array_len(", e)) {
|
||||||
|
return true;
|
||||||
|
} else if (find_print_string(fmt, "__get_sockaddr(", e)) {
|
||||||
|
return true;
|
||||||
|
} else if (find_print_string(fmt, "__get_rel_sockaddr(", e)) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if the string is safe */
|
||||||
|
static bool process_string(const char *fmt, int len, struct trace_event_call *call)
|
||||||
|
{
|
||||||
|
const char *r, *e, *s;
|
||||||
|
|
||||||
|
e = fmt + len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are several helper functions that return strings.
|
||||||
|
* If the argument contains a function, then assume its field is valid.
|
||||||
|
* It is considered that the argument has a function if it has:
|
||||||
|
* alphanumeric or '_' before a parenthesis.
|
||||||
|
*/
|
||||||
|
s = fmt;
|
||||||
|
do {
|
||||||
|
r = strstr(s, "(");
|
||||||
|
if (!r || r >= e)
|
||||||
|
break;
|
||||||
|
for (int i = 1; r - i >= s; i++) {
|
||||||
|
char ch = *(r - i);
|
||||||
|
if (isspace(ch))
|
||||||
|
continue;
|
||||||
|
if (isalnum(ch) || ch == '_')
|
||||||
|
return true;
|
||||||
|
/* Anything else, this isn't a function */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* A function could be wrapped in parethesis, try the next one */
|
||||||
|
s = r + 1;
|
||||||
|
} while (s < e);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there's any strings in the argument consider this arg OK as it
|
||||||
|
* could be: REC->field ? "foo" : "bar" and we don't want to get into
|
||||||
|
* verifying that logic here.
|
||||||
|
*/
|
||||||
|
if (find_print_string(fmt, "\"", e))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Dereferenced strings are also valid like any other pointer */
|
||||||
|
if (process_pointer(fmt, len, call))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Make sure the field is found, and consider it OK for now if it is */
|
||||||
|
return find_event_field(fmt, call) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Examine the print fmt of the event looking for unsafe dereference
|
* Examine the print fmt of the event looking for unsafe dereference
|
||||||
* pointers using %p* that could be recorded in the trace event and
|
* pointers using %p* that could be recorded in the trace event and
|
||||||
@@ -282,13 +383,14 @@ static bool test_field(const char *fmt, struct trace_event_call *call)
|
|||||||
static void test_event_printk(struct trace_event_call *call)
|
static void test_event_printk(struct trace_event_call *call)
|
||||||
{
|
{
|
||||||
u64 dereference_flags = 0;
|
u64 dereference_flags = 0;
|
||||||
|
u64 string_flags = 0;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
const char *fmt, *c, *r, *a;
|
const char *fmt;
|
||||||
int parens = 0;
|
int parens = 0;
|
||||||
char in_quote = 0;
|
char in_quote = 0;
|
||||||
int start_arg = 0;
|
int start_arg = 0;
|
||||||
int arg = 0;
|
int arg = 0;
|
||||||
int i;
|
int i, e;
|
||||||
|
|
||||||
fmt = call->print_fmt;
|
fmt = call->print_fmt;
|
||||||
|
|
||||||
@@ -372,8 +474,16 @@ static void test_event_printk(struct trace_event_call *call)
|
|||||||
star = true;
|
star = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((fmt[i + j] == 's') && star)
|
if ((fmt[i + j] == 's')) {
|
||||||
arg++;
|
if (star)
|
||||||
|
arg++;
|
||||||
|
if (WARN_ONCE(arg == 63,
|
||||||
|
"Too many args for event: %s",
|
||||||
|
trace_event_name(call)))
|
||||||
|
return;
|
||||||
|
dereference_flags |= 1ULL << arg;
|
||||||
|
string_flags |= 1ULL << arg;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -401,42 +511,47 @@ static void test_event_printk(struct trace_event_call *call)
|
|||||||
case ',':
|
case ',':
|
||||||
if (in_quote || parens)
|
if (in_quote || parens)
|
||||||
continue;
|
continue;
|
||||||
|
e = i;
|
||||||
i++;
|
i++;
|
||||||
while (isspace(fmt[i]))
|
while (isspace(fmt[i]))
|
||||||
i++;
|
i++;
|
||||||
start_arg = i;
|
|
||||||
if (!(dereference_flags & (1ULL << arg)))
|
|
||||||
goto next_arg;
|
|
||||||
|
|
||||||
/* Find the REC-> in the argument */
|
/*
|
||||||
c = strchr(fmt + i, ',');
|
* If start_arg is zero, then this is the start of the
|
||||||
r = strstr(fmt + i, "REC->");
|
* first argument. The processing of the argument happens
|
||||||
if (r && (!c || r < c)) {
|
* when the end of the argument is found, as it needs to
|
||||||
/*
|
* handle paranthesis and such.
|
||||||
* Addresses of events on the buffer,
|
*/
|
||||||
* or an array on the buffer is
|
if (!start_arg) {
|
||||||
* OK to dereference.
|
start_arg = i;
|
||||||
* There's ways to fool this, but
|
/* Balance out the i++ in the for loop */
|
||||||
* this is to catch common mistakes,
|
i--;
|
||||||
* not malicious code.
|
continue;
|
||||||
*/
|
|
||||||
a = strchr(fmt + i, '&');
|
|
||||||
if ((a && (a < r)) || test_field(r, call))
|
|
||||||
dereference_flags &= ~(1ULL << arg);
|
|
||||||
} else if ((r = strstr(fmt + i, "__get_dynamic_array(")) &&
|
|
||||||
(!c || r < c)) {
|
|
||||||
dereference_flags &= ~(1ULL << arg);
|
|
||||||
} else if ((r = strstr(fmt + i, "__get_sockaddr(")) &&
|
|
||||||
(!c || r < c)) {
|
|
||||||
dereference_flags &= ~(1ULL << arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next_arg:
|
if (dereference_flags & (1ULL << arg)) {
|
||||||
i--;
|
if (string_flags & (1ULL << arg)) {
|
||||||
|
if (process_string(fmt + start_arg, e - start_arg, call))
|
||||||
|
dereference_flags &= ~(1ULL << arg);
|
||||||
|
} else if (process_pointer(fmt + start_arg, e - start_arg, call))
|
||||||
|
dereference_flags &= ~(1ULL << arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
start_arg = i;
|
||||||
arg++;
|
arg++;
|
||||||
|
/* Balance out the i++ in the for loop */
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dereference_flags & (1ULL << arg)) {
|
||||||
|
if (string_flags & (1ULL << arg)) {
|
||||||
|
if (process_string(fmt + start_arg, i - start_arg, call))
|
||||||
|
dereference_flags &= ~(1ULL << arg);
|
||||||
|
} else if (process_pointer(fmt + start_arg, i - start_arg, call))
|
||||||
|
dereference_flags &= ~(1ULL << arg);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you triggered the below warning, the trace event reported
|
* If you triggered the below warning, the trace event reported
|
||||||
* uses an unsafe dereference pointer %p*. As the data stored
|
* uses an unsafe dereference pointer %p*. As the data stored
|
||||||
|
|||||||
@@ -611,6 +611,8 @@ init_list_set(struct net *net, struct ip_set *set, u32 size)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct lock_class_key list_set_lockdep_key;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
list_set_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
|
list_set_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
|
||||||
u32 flags)
|
u32 flags)
|
||||||
@@ -627,6 +629,7 @@ list_set_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
|
|||||||
if (size < IP_SET_LIST_MIN_SIZE)
|
if (size < IP_SET_LIST_MIN_SIZE)
|
||||||
size = IP_SET_LIST_MIN_SIZE;
|
size = IP_SET_LIST_MIN_SIZE;
|
||||||
|
|
||||||
|
lockdep_set_class(&set->lock, &list_set_lockdep_key);
|
||||||
set->variant = &set_variant;
|
set->variant = &set_variant;
|
||||||
set->dsize = ip_set_elem_len(set, tb, sizeof(struct set_elem),
|
set->dsize = ip_set_elem_len(set, tb, sizeof(struct set_elem),
|
||||||
__alignof__(struct set_elem));
|
__alignof__(struct set_elem));
|
||||||
|
|||||||
@@ -1541,7 +1541,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)
|
|||||||
b->backlogs[idx] -= len;
|
b->backlogs[idx] -= len;
|
||||||
b->tin_backlog -= len;
|
b->tin_backlog -= len;
|
||||||
sch->qstats.backlog -= len;
|
sch->qstats.backlog -= len;
|
||||||
qdisc_tree_reduce_backlog(sch, 1, len);
|
|
||||||
|
|
||||||
flow->dropped++;
|
flow->dropped++;
|
||||||
b->tin_dropped++;
|
b->tin_dropped++;
|
||||||
@@ -1552,6 +1551,7 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)
|
|||||||
|
|
||||||
__qdisc_drop(skb, to_free);
|
__qdisc_drop(skb, to_free);
|
||||||
sch->q.qlen--;
|
sch->q.qlen--;
|
||||||
|
qdisc_tree_reduce_backlog(sch, 1, len);
|
||||||
|
|
||||||
cake_heapify(q, 0);
|
cake_heapify(q, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -123,10 +123,10 @@ static void choke_drop_by_idx(struct Qdisc *sch, unsigned int idx,
|
|||||||
if (idx == q->tail)
|
if (idx == q->tail)
|
||||||
choke_zap_tail_holes(q);
|
choke_zap_tail_holes(q);
|
||||||
|
|
||||||
|
--sch->q.qlen;
|
||||||
qdisc_qstats_backlog_dec(sch, skb);
|
qdisc_qstats_backlog_dec(sch, skb);
|
||||||
qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(skb));
|
qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(skb));
|
||||||
qdisc_drop(skb, sch, to_free);
|
qdisc_drop(skb, sch, to_free);
|
||||||
--sch->q.qlen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct choke_skb_cb {
|
struct choke_skb_cb {
|
||||||
|
|||||||
@@ -1988,6 +1988,8 @@ static int smc_listen_prfx_check(struct smc_sock *new_smc,
|
|||||||
if (pclc->hdr.typev1 == SMC_TYPE_N)
|
if (pclc->hdr.typev1 == SMC_TYPE_N)
|
||||||
return 0;
|
return 0;
|
||||||
pclc_prfx = smc_clc_proposal_get_prefix(pclc);
|
pclc_prfx = smc_clc_proposal_get_prefix(pclc);
|
||||||
|
if (!pclc_prfx)
|
||||||
|
return -EPROTO;
|
||||||
if (smc_clc_prfx_match(newclcsock, pclc_prfx))
|
if (smc_clc_prfx_match(newclcsock, pclc_prfx))
|
||||||
return SMC_CLC_DECL_DIFFPREFIX;
|
return SMC_CLC_DECL_DIFFPREFIX;
|
||||||
|
|
||||||
@@ -2094,6 +2096,8 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
|
|||||||
pclc_smcd = smc_get_clc_msg_smcd(pclc);
|
pclc_smcd = smc_get_clc_msg_smcd(pclc);
|
||||||
smc_v2_ext = smc_get_clc_v2_ext(pclc);
|
smc_v2_ext = smc_get_clc_v2_ext(pclc);
|
||||||
smcd_v2_ext = smc_get_clc_smcd_v2_ext(smc_v2_ext);
|
smcd_v2_ext = smc_get_clc_smcd_v2_ext(smc_v2_ext);
|
||||||
|
if (!pclc_smcd || !smc_v2_ext || !smcd_v2_ext)
|
||||||
|
goto not_found;
|
||||||
|
|
||||||
mutex_lock(&smcd_dev_list.mutex);
|
mutex_lock(&smcd_dev_list.mutex);
|
||||||
if (pclc_smcd->ism.chid)
|
if (pclc_smcd->ism.chid)
|
||||||
@@ -2153,7 +2157,9 @@ static void smc_find_ism_v1_device_serv(struct smc_sock *new_smc,
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* check if ISM V1 is available */
|
/* check if ISM V1 is available */
|
||||||
if (!(ini->smcd_version & SMC_V1) || !smcd_indicated(ini->smc_type_v1))
|
if (!(ini->smcd_version & SMC_V1) ||
|
||||||
|
!smcd_indicated(ini->smc_type_v1) ||
|
||||||
|
!pclc_smcd)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
ini->is_smcd = true; /* prepare ISM check */
|
ini->is_smcd = true; /* prepare ISM check */
|
||||||
ini->ism_peer_gid[0] = ntohll(pclc_smcd->ism.gid);
|
ini->ism_peer_gid[0] = ntohll(pclc_smcd->ism.gid);
|
||||||
@@ -2789,6 +2795,13 @@ static __poll_t smc_poll(struct file *file, struct socket *sock,
|
|||||||
} else {
|
} else {
|
||||||
sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
|
sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
|
||||||
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
|
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
|
||||||
|
|
||||||
|
if (sk->sk_state != SMC_INIT) {
|
||||||
|
/* Race breaker the same way as tcp_poll(). */
|
||||||
|
smp_mb__after_atomic();
|
||||||
|
if (atomic_read(&smc->conn.sndbuf_space))
|
||||||
|
mask |= EPOLLOUT | EPOLLWRNORM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (atomic_read(&smc->conn.bytes_to_rcv))
|
if (atomic_read(&smc->conn.bytes_to_rcv))
|
||||||
mask |= EPOLLIN | EPOLLRDNORM;
|
mask |= EPOLLIN | EPOLLRDNORM;
|
||||||
|
|||||||
@@ -354,6 +354,10 @@ static bool smc_clc_msg_prop_valid(struct smc_clc_msg_proposal *pclc)
|
|||||||
|
|
||||||
v2_ext = smc_get_clc_v2_ext(pclc);
|
v2_ext = smc_get_clc_v2_ext(pclc);
|
||||||
pclc_prfx = smc_clc_proposal_get_prefix(pclc);
|
pclc_prfx = smc_clc_proposal_get_prefix(pclc);
|
||||||
|
if (!pclc_prfx ||
|
||||||
|
pclc_prfx->ipv6_prefixes_cnt > SMC_CLC_MAX_V6_PREFIX)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (hdr->version == SMC_V1) {
|
if (hdr->version == SMC_V1) {
|
||||||
if (hdr->typev1 == SMC_TYPE_N)
|
if (hdr->typev1 == SMC_TYPE_N)
|
||||||
return false;
|
return false;
|
||||||
@@ -749,6 +753,11 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
|
|||||||
SMC_CLC_RECV_BUF_LEN : datlen;
|
SMC_CLC_RECV_BUF_LEN : datlen;
|
||||||
iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen);
|
iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen);
|
||||||
len = sock_recvmsg(smc->clcsock, &msg, krflags);
|
len = sock_recvmsg(smc->clcsock, &msg, krflags);
|
||||||
|
if (len < recvlen) {
|
||||||
|
smc->sk.sk_err = EPROTO;
|
||||||
|
reason_code = -EPROTO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
datlen -= len;
|
datlen -= len;
|
||||||
}
|
}
|
||||||
if (clcm->type == SMC_CLC_DECLINE) {
|
if (clcm->type == SMC_CLC_DECLINE) {
|
||||||
|
|||||||
@@ -303,8 +303,12 @@ struct smc_clc_msg_decline_v2 { /* clc decline message */
|
|||||||
static inline struct smc_clc_msg_proposal_prefix *
|
static inline struct smc_clc_msg_proposal_prefix *
|
||||||
smc_clc_proposal_get_prefix(struct smc_clc_msg_proposal *pclc)
|
smc_clc_proposal_get_prefix(struct smc_clc_msg_proposal *pclc)
|
||||||
{
|
{
|
||||||
|
u16 offset = ntohs(pclc->iparea_offset);
|
||||||
|
|
||||||
|
if (offset > sizeof(struct smc_clc_msg_smcd))
|
||||||
|
return NULL;
|
||||||
return (struct smc_clc_msg_proposal_prefix *)
|
return (struct smc_clc_msg_proposal_prefix *)
|
||||||
((u8 *)pclc + sizeof(*pclc) + ntohs(pclc->iparea_offset));
|
((u8 *)pclc + sizeof(*pclc) + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool smcr_indicated(int smc_type)
|
static inline bool smcr_indicated(int smc_type)
|
||||||
@@ -357,9 +361,15 @@ smc_get_clc_v2_ext(struct smc_clc_msg_proposal *prop)
|
|||||||
static inline struct smc_clc_smcd_v2_extension *
|
static inline struct smc_clc_smcd_v2_extension *
|
||||||
smc_get_clc_smcd_v2_ext(struct smc_clc_v2_extension *prop_v2ext)
|
smc_get_clc_smcd_v2_ext(struct smc_clc_v2_extension *prop_v2ext)
|
||||||
{
|
{
|
||||||
|
u16 max_offset = offsetof(struct smc_clc_msg_proposal_area, pclc_smcd_v2_ext) -
|
||||||
|
offsetof(struct smc_clc_msg_proposal_area, pclc_v2_ext) -
|
||||||
|
offsetof(struct smc_clc_v2_extension, hdr) -
|
||||||
|
offsetofend(struct smc_clnt_opts_area_hdr, smcd_v2_ext_offset);
|
||||||
|
|
||||||
if (!prop_v2ext)
|
if (!prop_v2ext)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!ntohs(prop_v2ext->hdr.smcd_v2_ext_offset))
|
if (!ntohs(prop_v2ext->hdr.smcd_v2_ext_offset) ||
|
||||||
|
ntohs(prop_v2ext->hdr.smcd_v2_ext_offset) > max_offset)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return (struct smc_clc_smcd_v2_extension *)
|
return (struct smc_clc_smcd_v2_extension *)
|
||||||
|
|||||||
@@ -1726,7 +1726,9 @@ void smcr_link_down_cond_sched(struct smc_link *lnk)
|
|||||||
{
|
{
|
||||||
if (smc_link_downing(&lnk->state)) {
|
if (smc_link_downing(&lnk->state)) {
|
||||||
trace_smcr_link_down(lnk, __builtin_return_address(0));
|
trace_smcr_link_down(lnk, __builtin_return_address(0));
|
||||||
schedule_work(&lnk->link_down_wrk);
|
smcr_link_hold(lnk); /* smcr_link_put in link_down_wrk */
|
||||||
|
if (!schedule_work(&lnk->link_down_wrk))
|
||||||
|
smcr_link_put(lnk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1758,11 +1760,14 @@ static void smc_link_down_work(struct work_struct *work)
|
|||||||
struct smc_link_group *lgr = link->lgr;
|
struct smc_link_group *lgr = link->lgr;
|
||||||
|
|
||||||
if (list_empty(&lgr->list))
|
if (list_empty(&lgr->list))
|
||||||
return;
|
goto out;
|
||||||
wake_up_all(&lgr->llc_msg_waiter);
|
wake_up_all(&lgr->llc_msg_waiter);
|
||||||
mutex_lock(&lgr->llc_conf_mutex);
|
mutex_lock(&lgr->llc_conf_mutex);
|
||||||
smcr_link_down(link);
|
smcr_link_down(link);
|
||||||
mutex_unlock(&lgr->llc_conf_mutex);
|
mutex_unlock(&lgr->llc_conf_mutex);
|
||||||
|
|
||||||
|
out:
|
||||||
|
smcr_link_put(link); /* smcr_link_hold by schedulers of link_down_work */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev,
|
static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev,
|
||||||
|
|||||||
@@ -267,6 +267,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
|
|||||||
SOF_BT_OFFLOAD_SSP(2) |
|
SOF_BT_OFFLOAD_SSP(2) |
|
||||||
SOF_SSP_BT_OFFLOAD_PRESENT),
|
SOF_SSP_BT_OFFLOAD_PRESENT),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = sof_sdw_quirk_cb,
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_SKU, "0000000000070000"),
|
||||||
|
},
|
||||||
|
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
|
||||||
|
RT711_JD2_100K),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.callback = sof_sdw_quirk_cb,
|
.callback = sof_sdw_quirk_cb,
|
||||||
.matches = {
|
.matches = {
|
||||||
@@ -378,6 +387,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
|
|||||||
RT711_JD2 |
|
RT711_JD2 |
|
||||||
SOF_SDW_FOUR_SPK),
|
SOF_SDW_FOUR_SPK),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = sof_sdw_quirk_cb,
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||||
|
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B8C"),
|
||||||
|
},
|
||||||
|
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
|
||||||
|
RT711_JD2),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.callback = sof_sdw_quirk_cb,
|
.callback = sof_sdw_quirk_cb,
|
||||||
.matches = {
|
.matches = {
|
||||||
|
|||||||
@@ -102,6 +102,8 @@
|
|||||||
# define STAP_SDT_ARG_CONSTRAINT nZr
|
# define STAP_SDT_ARG_CONSTRAINT nZr
|
||||||
# elif defined __arm__
|
# elif defined __arm__
|
||||||
# define STAP_SDT_ARG_CONSTRAINT g
|
# define STAP_SDT_ARG_CONSTRAINT g
|
||||||
|
# elif defined __loongarch__
|
||||||
|
# define STAP_SDT_ARG_CONSTRAINT nmr
|
||||||
# else
|
# else
|
||||||
# define STAP_SDT_ARG_CONSTRAINT nor
|
# define STAP_SDT_ARG_CONSTRAINT nor
|
||||||
# endif
|
# endif
|
||||||
|
|||||||
Reference in New Issue
Block a user