Merge 6.12.8 into android16-6.12
GKI (arm64) relevant 24 out of 115 changes, affecting 34 files +169/-94f4ab7d7424bpf: Fix bpf_get_smp_processor_id() on !CONFIG_SMP [1 file, +5/-1]8cdfb06569fork: avoid inappropriate uprobe access to invalid mm [1 file, +6/-7]2175b66c7fmm/vmstat: fix a W=1 clang compiler warning [1 file, +1/-1]35727f4506tcp_bpf: Charge receive socket buffer in bpf_tcp_ingress() [2 files, +9/-3]4aa5dcb389tcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress redirection [3 files, +16/-5]997cf2d8c2bpf: Check negative offsets in __bpf_skb_min_len() [1 file, +15/-6]a817e938a0phy: core: Fix an OF node refcount leakage in _of_phy_get() [1 file, +5/-2]479b6c2a5fphy: core: Fix an OF node refcount leakage in of_phy_provider_lookup() [1 file, +3/-1]09f17bfb36phy: core: Fix that API devm_phy_put() fails to release the phy [1 file, +1/-1]f797151e84phy: core: Fix that API devm_of_phy_provider_unregister() fails to unregister the phy provider [1 file, +3/-3]7e7c8ffc01phy: core: Fix that API devm_phy_destroy() fails to destroy the phy [1 file, +1/-1]c180c3f42dALSA: memalloc: prefer dma_mapping_error() over explicit address checking [1 file, +1/-1]a39ff5bf23stddef: make __struct_group() UAPI C++-friendly [2 files, +21/-7]68662d78aftracing/kprobe: Make trace_kprobe's module callback called after jump_label update [1 file, +1/-1]ca5995f805regmap: Use correct format specifier for logging range errors [1 file, +2/-2]fdaaf92943bpf: Zero index arg error string for dynptr and iter [6 files, +29/-29]92d5139b91virtio-blk: don't keep queue frozen during system suspend [1 file, +5/-2]16b54ee81dblk-mq: register cpuhp callback after hctx is added to xarray table [1 file, +7/-8]7d680f2f76ublk: detach gendisk from ublk device if add_disk() fails [1 file, +17/-9]79a47fd0f1freezer, sched: Report frozen tasks as 'D' instead of 'R' [1 file, +2/-1]a744146969tracing: Constify string literal data member in struct trace_event_call [1 file, +1/-1]1cca920af1tracing: Prevent bad count for tracing_cpumask_write [1 file, +3/-0]8e8494c83cio_uring/sqpoll: fix sqpoll error handling races [1 file, +6/-0]aed157301cPCI/MSI: Handle lack of irqdomain gracefully [2 files, +9/-2] Changes in 6.12.8 media: dvb-frontends: dib3000mb: fix uninit-value in dib3000_write_reg ceph: allocate sparse_ext map only for sparse reads arm64: dts: broadcom: Fix L2 linesize for Raspberry Pi 5 bpf: Fix bpf_get_smp_processor_id() on !CONFIG_SMP fork: avoid inappropriate uprobe access to invalid mm mm/vmstat: fix a W=1 clang compiler warning selftests/bpf: Fix compilation error in get_uprobe_offset() smb: client: Deduplicate "select NETFS_SUPPORT" in Kconfig smb: fix bytes written value in /proc/fs/cifs/Stats tcp_bpf: Charge receive socket buffer in bpf_tcp_ingress() tcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress redirection bpf: Check negative offsets in __bpf_skb_min_len() nfsd: Revert "nfsd: release svc_expkey/svc_export with rcu_work" nfsd: restore callback functionality for NFSv4.0 mtd: diskonchip: Cast an operand to prevent potential overflow mtd: rawnand: arasan: Fix double assertion of chip-select mtd: rawnand: arasan: Fix missing de-registration of NAND phy: qcom-qmp: Fix register name in RX Lane config of SC8280XP phy: core: Fix an OF node refcount leakage in _of_phy_get() phy: core: Fix an OF node refcount leakage in of_phy_provider_lookup() phy: core: Fix that API devm_phy_put() fails to release the phy phy: core: Fix that API devm_of_phy_provider_unregister() fails to unregister the phy provider phy: core: Fix that API devm_phy_destroy() fails to destroy the phy phy: usb: Toggle the PHY power during init phy: rockchip: samsung-hdptx: Set drvdata before enabling runtime PM phy: rockchip: naneng-combphy: fix phy reset ALSA: memalloc: prefer dma_mapping_error() over explicit address checking dmaengine: mv_xor: fix child node refcount handling in early exit dmaengine: dw: Select only supported masters for ACPI devices dmaengine: tegra: Return correct DMA status when paused dmaengine: amd: qdma: Remove using the private get and set dma_ops APIs dmaengine: fsl-edma: implement the cleanup path of fsl_edma3_attach_pd() dmaengine: apple-admac: Avoid accessing registers in probe dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset ASoC: SOF: Intel: hda-dai: Do not release the link DMA on STOP platform/chrome: cros_ec_lpc: fix product identity for early Framework Laptops mtd: rawnand: fix double free in atmel_pmecc_create_user() ASoC: amd: ps: Fix for enabling DMIC on acp63 platform via _DSD entry ASoC: Intel: sof_sdw: Fix DMI match for Lenovo 21QA and 21QB ASoC: dt-bindings: realtek,rt5645: Fix CPVDD voltage comment ASoC: Intel: sof_sdw: Fix DMI match for Lenovo 21Q6 and 21Q7 powerpc/pseries/vas: Add close() callback in vas_vm_ops struct power: supply: bq24190: Fix BQ24296 Vbus regulator support stddef: make __struct_group() UAPI C++-friendly tracing/kprobe: Make trace_kprobe's module callback called after jump_label update watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04 watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler Revert "watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs" watchdog: mediatek: Add support for MT6735 TOPRGU/WDT scsi: qla1280: Fix hw revision numbering for ISP1020/1040 scsi: megaraid_sas: Fix for a potential deadlock udf: Skip parent dir link count update if corrupted udf: Verify inode link counts before performing rename ALSA: ump: Don't open legacy substream for an inactive group ALSA: ump: Indicate the inactive group in legacy substream names ALSA: ump: Update legacy substream names upon FB info update ALSA: hda/conexant: fix Z60MR100 startup pop issue ALSA: sh: Use standard helper for buffer accesses smb: server: Fix building with GCC 15 regmap: Use correct format specifier for logging range errors LoongArch: Fix reserving screen info memory for above-4G firmware LoongArch: BPF: Adjust the parameter of emit_jirl() platform/x86: asus-nb-wmi: Ignore unknown event 0xCF bpf: Zero index arg error string for dynptr and iter spi: intel: Add Panther Lake SPI controller support scsi: mpt3sas: Diag-Reset when Doorbell-In-Use bit is set during driver load time scsi: mpi3mr: Synchronize access to ioctl data buffer scsi: mpi3mr: Fix corrupt config pages PHY state is switched in sysfs scsi: mpi3mr: Start controller indexing from 0 scsi: mpi3mr: Handling of fault code for insufficient power scsi: storvsc: Do not flag MAINTENANCE_IN return of SRB_STATUS_DATA_OVERRUN as an error ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A spi: omap2-mcspi: Fix the IS_ERR() bug for devm_clk_get_optional_enabled() drm/dp_mst: Ensure mst_primary pointer is valid in drm_dp_mst_handle_up_req() virtio-blk: don't keep queue frozen during system suspend blk-mq: register cpuhp callback after hctx is added to xarray table wifi: iwlwifi: be less noisy if the NIC is dead in S3 ublk: detach gendisk from ublk device if add_disk() fails drm/xe: Take PM ref in delayed snapshot capture worker drm/xe: Move the coredump registration to the worker thread objtool: Add bch2_trans_unlocked_error() to bcachefs noreturns freezer, sched: Report frozen tasks as 'D' instead of 'R' dmaengine: loongson2-apb: Change GENMASK to GENMASK_ULL perf/x86/intel/uncore: Add Clearwater Forest support tracing: Constify string literal data member in struct trace_event_call tracing: Prevent bad count for tracing_cpumask_write rtla/timerlat: Fix histogram ALL for zero samples io_uring/sqpoll: fix sqpoll error handling races i2c: microchip-core: actually use repeated sends x86/fred: Clear WFE in missing-ENDBRANCH #CPs virt: tdx-guest: Just leak decrypted memory on unrecoverable errors PCI/MSI: Handle lack of irqdomain gracefully perf/x86/intel: Fix bitmask of OCR and FRONTEND events for LNC i2c: imx: add imx7d compatible string for applying erratum ERR007805 i2c: microchip-core: fix "ghost" detections perf/x86/intel/ds: Add PEBS format 6 power: supply: cros_charge-control: add mutex for driver data power: supply: cros_charge-control: allow start_threshold == end_threshold power: supply: cros_charge-control: hide start threshold on v2 cmd power: supply: gpio-charger: Fix set charge current limits btrfs: fix race with memory mapped writes when activating swap file btrfs: avoid monopolizing a core when activating a swap file btrfs: fix swap file activation failure due to extents that used to be shared btrfs: fix transaction atomicity bug when enabling simple quotas btrfs: sysfs: fix direct super block member reads btrfs: fix use-after-free when COWing tree bock and tracing is enabled btrfs: check folio mapping after unlock in put_file_data() btrfs: check folio mapping after unlock in relocate_one_folio() Bluetooth: btusb: mediatek: move Bluetooth power off command position Bluetooth: btusb: mediatek: add callback function in btusb_disconnect Bluetooth: btusb: mediatek: add intf release flow when usb disconnect Bluetooth: btusb: mediatek: change the conditions for ISO interface ALSA: ump: Shut up truncated string warning ALSA: sh: Fix wrong argument order for copy_from_iter() Linux 6.12.8 Change-Id: I2f5b46453984dde6ed8c381109655261a6bc3596 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -255,8 +255,9 @@ stable kernels.
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Hisilicon | Hip{08,09,10,10C| #162001900 | N/A |
|
||||
| | ,11} SMMU PMCG | | |
|
||||
| Hisilicon | Hip{08,09,09A,10| #162001900 | N/A |
|
||||
| | ,10C,11} | | |
|
||||
| | SMMU PMCG | | |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_162100801 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
|
||||
@@ -51,7 +51,7 @@ properties:
|
||||
description: Power supply for AVDD, providing 1.8V.
|
||||
|
||||
cpvdd-supply:
|
||||
description: Power supply for CPVDD, providing 3.5V.
|
||||
description: Power supply for CPVDD, providing 1.8V.
|
||||
|
||||
hp-detect-gpios:
|
||||
description:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 12
|
||||
SUBLEVEL = 7
|
||||
SUBLEVEL = 8
|
||||
EXTRAVERSION =
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
l2_cache_l0: l2-cache-l0 {
|
||||
compatible = "cache";
|
||||
cache-size = <0x80000>;
|
||||
cache-line-size = <128>;
|
||||
cache-line-size = <64>;
|
||||
cache-sets = <1024>; //512KiB(size)/64(line-size)=8192ways/8-way set
|
||||
cache-level = <2>;
|
||||
cache-unified;
|
||||
@@ -91,7 +91,7 @@
|
||||
l2_cache_l1: l2-cache-l1 {
|
||||
compatible = "cache";
|
||||
cache-size = <0x80000>;
|
||||
cache-line-size = <128>;
|
||||
cache-line-size = <64>;
|
||||
cache-sets = <1024>; //512KiB(size)/64(line-size)=8192ways/8-way set
|
||||
cache-level = <2>;
|
||||
cache-unified;
|
||||
@@ -115,7 +115,7 @@
|
||||
l2_cache_l2: l2-cache-l2 {
|
||||
compatible = "cache";
|
||||
cache-size = <0x80000>;
|
||||
cache-line-size = <128>;
|
||||
cache-line-size = <64>;
|
||||
cache-sets = <1024>; //512KiB(size)/64(line-size)=8192ways/8-way set
|
||||
cache-level = <2>;
|
||||
cache-unified;
|
||||
@@ -139,7 +139,7 @@
|
||||
l2_cache_l3: l2-cache-l3 {
|
||||
compatible = "cache";
|
||||
cache-size = <0x80000>;
|
||||
cache-line-size = <128>;
|
||||
cache-line-size = <64>;
|
||||
cache-sets = <1024>; //512KiB(size)/64(line-size)=8192ways/8-way set
|
||||
cache-level = <2>;
|
||||
cache-unified;
|
||||
|
||||
@@ -683,7 +683,17 @@ DEF_EMIT_REG2I16_FORMAT(blt, blt_op)
|
||||
DEF_EMIT_REG2I16_FORMAT(bge, bge_op)
|
||||
DEF_EMIT_REG2I16_FORMAT(bltu, bltu_op)
|
||||
DEF_EMIT_REG2I16_FORMAT(bgeu, bgeu_op)
|
||||
DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op)
|
||||
|
||||
static inline void emit_jirl(union loongarch_instruction *insn,
|
||||
enum loongarch_gpr rd,
|
||||
enum loongarch_gpr rj,
|
||||
int offset)
|
||||
{
|
||||
insn->reg2i16_format.opcode = jirl_op;
|
||||
insn->reg2i16_format.immediate = offset;
|
||||
insn->reg2i16_format.rd = rd;
|
||||
insn->reg2i16_format.rj = rj;
|
||||
}
|
||||
|
||||
#define DEF_EMIT_REG2BSTRD_FORMAT(NAME, OP) \
|
||||
static inline void emit_##NAME(union loongarch_instruction *insn, \
|
||||
|
||||
@@ -95,7 +95,7 @@ static void __init init_screen_info(void)
|
||||
memset(si, 0, sizeof(*si));
|
||||
early_memunmap(si, sizeof(*si));
|
||||
|
||||
memblock_reserve(screen_info.lfb_base, screen_info.lfb_size);
|
||||
memblock_reserve(__screen_info_lfb_base(&screen_info), screen_info.lfb_size);
|
||||
}
|
||||
|
||||
void __init efi_init(void)
|
||||
|
||||
@@ -332,7 +332,7 @@ u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm)
|
||||
return INSN_BREAK;
|
||||
}
|
||||
|
||||
emit_jirl(&insn, rj, rd, imm >> 2);
|
||||
emit_jirl(&insn, rd, rj, imm >> 2);
|
||||
|
||||
return insn.word;
|
||||
}
|
||||
|
||||
@@ -181,13 +181,13 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call)
|
||||
/* Set return value */
|
||||
emit_insn(ctx, addiw, LOONGARCH_GPR_A0, regmap[BPF_REG_0], 0);
|
||||
/* Return to the caller */
|
||||
emit_insn(ctx, jirl, LOONGARCH_GPR_RA, LOONGARCH_GPR_ZERO, 0);
|
||||
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0);
|
||||
} else {
|
||||
/*
|
||||
* Call the next bpf prog and skip the first instruction
|
||||
* of TCC initialization.
|
||||
*/
|
||||
emit_insn(ctx, jirl, LOONGARCH_GPR_T3, LOONGARCH_GPR_ZERO, 1);
|
||||
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -904,7 +904,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
||||
return ret;
|
||||
|
||||
move_addr(ctx, t1, func_addr);
|
||||
emit_insn(ctx, jirl, t1, LOONGARCH_GPR_RA, 0);
|
||||
emit_insn(ctx, jirl, LOONGARCH_GPR_RA, t1, 0);
|
||||
move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_A0);
|
||||
break;
|
||||
|
||||
|
||||
@@ -464,7 +464,43 @@ static vm_fault_t vas_mmap_fault(struct vm_fault *vmf)
|
||||
return VM_FAULT_SIGBUS;
|
||||
}
|
||||
|
||||
/*
|
||||
* During mmap() paste address, mapping VMA is saved in VAS window
|
||||
* struct which is used to unmap during migration if the window is
|
||||
* still open. But the user space can remove this mapping with
|
||||
* munmap() before closing the window and the VMA address will
|
||||
* be invalid. Set VAS window VMA to NULL in this function which
|
||||
* is called before VMA free.
|
||||
*/
|
||||
static void vas_mmap_close(struct vm_area_struct *vma)
|
||||
{
|
||||
struct file *fp = vma->vm_file;
|
||||
struct coproc_instance *cp_inst = fp->private_data;
|
||||
struct vas_window *txwin;
|
||||
|
||||
/* Should not happen */
|
||||
if (!cp_inst || !cp_inst->txwin) {
|
||||
pr_err("No attached VAS window for the paste address mmap\n");
|
||||
return;
|
||||
}
|
||||
|
||||
txwin = cp_inst->txwin;
|
||||
/*
|
||||
* task_ref.vma is set in coproc_mmap() during mmap paste
|
||||
* address. So it has to be the same VMA that is getting freed.
|
||||
*/
|
||||
if (WARN_ON(txwin->task_ref.vma != vma)) {
|
||||
pr_err("Invalid paste address mmaping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&txwin->task_ref.mmap_mutex);
|
||||
txwin->task_ref.vma = NULL;
|
||||
mutex_unlock(&txwin->task_ref.mmap_mutex);
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct vas_vm_ops = {
|
||||
.close = vas_mmap_close,
|
||||
.fault = vas_mmap_fault,
|
||||
};
|
||||
|
||||
|
||||
@@ -429,6 +429,16 @@ static struct event_constraint intel_lnc_event_constraints[] = {
|
||||
EVENT_CONSTRAINT_END
|
||||
};
|
||||
|
||||
static struct extra_reg intel_lnc_extra_regs[] __read_mostly = {
|
||||
INTEL_UEVENT_EXTRA_REG(0x012a, MSR_OFFCORE_RSP_0, 0xfffffffffffull, RSP_0),
|
||||
INTEL_UEVENT_EXTRA_REG(0x012b, MSR_OFFCORE_RSP_1, 0xfffffffffffull, RSP_1),
|
||||
INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
|
||||
INTEL_UEVENT_EXTRA_REG(0x02c6, MSR_PEBS_FRONTEND, 0x9, FE),
|
||||
INTEL_UEVENT_EXTRA_REG(0x03c6, MSR_PEBS_FRONTEND, 0x7fff1f, FE),
|
||||
INTEL_UEVENT_EXTRA_REG(0x40ad, MSR_PEBS_FRONTEND, 0xf, FE),
|
||||
INTEL_UEVENT_EXTRA_REG(0x04c2, MSR_PEBS_FRONTEND, 0x8, FE),
|
||||
EVENT_EXTRA_END
|
||||
};
|
||||
|
||||
EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3");
|
||||
EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3");
|
||||
@@ -6344,7 +6354,7 @@ static __always_inline void intel_pmu_init_lnc(struct pmu *pmu)
|
||||
intel_pmu_init_glc(pmu);
|
||||
hybrid(pmu, event_constraints) = intel_lnc_event_constraints;
|
||||
hybrid(pmu, pebs_constraints) = intel_lnc_pebs_event_constraints;
|
||||
hybrid(pmu, extra_regs) = intel_rwc_extra_regs;
|
||||
hybrid(pmu, extra_regs) = intel_lnc_extra_regs;
|
||||
}
|
||||
|
||||
static __always_inline void intel_pmu_init_skt(struct pmu *pmu)
|
||||
|
||||
@@ -2496,6 +2496,7 @@ void __init intel_ds_init(void)
|
||||
x86_pmu.large_pebs_flags |= PERF_SAMPLE_TIME;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case 5:
|
||||
x86_pmu.pebs_ept = 1;
|
||||
fallthrough;
|
||||
|
||||
@@ -1910,6 +1910,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
|
||||
X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &adl_uncore_init),
|
||||
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &gnr_uncore_init),
|
||||
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, &gnr_uncore_init),
|
||||
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, &gnr_uncore_init),
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
|
||||
|
||||
@@ -81,6 +81,34 @@ static void do_user_cp_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
static __ro_after_init bool ibt_fatal = true;
|
||||
|
||||
/*
|
||||
* By definition, all missing-ENDBRANCH #CPs are a result of WFE && !ENDBR.
|
||||
*
|
||||
* For the kernel IBT no ENDBR selftest where #CPs are deliberately triggered,
|
||||
* the WFE state of the interrupted context needs to be cleared to let execution
|
||||
* continue. Otherwise when the CPU resumes from the instruction that just
|
||||
* caused the previous #CP, another missing-ENDBRANCH #CP is raised and the CPU
|
||||
* enters a dead loop.
|
||||
*
|
||||
* This is not a problem with IDT because it doesn't preserve WFE and IRET doesn't
|
||||
* set WFE. But FRED provides space on the entry stack (in an expanded CS area)
|
||||
* to save and restore the WFE state, thus the WFE state is no longer clobbered,
|
||||
* so software must clear it.
|
||||
*/
|
||||
static void ibt_clear_fred_wfe(struct pt_regs *regs)
|
||||
{
|
||||
/*
|
||||
* No need to do any FRED checks.
|
||||
*
|
||||
* For IDT event delivery, the high-order 48 bits of CS are pushed
|
||||
* as 0s into the stack, and later IRET ignores these bits.
|
||||
*
|
||||
* For FRED, a test to check if fred_cs.wfe is set would be dropped
|
||||
* by compilers.
|
||||
*/
|
||||
regs->fred_cs.wfe = 0;
|
||||
}
|
||||
|
||||
static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
if ((error_code & CP_EC) != CP_ENDBR) {
|
||||
@@ -90,6 +118,7 @@ static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
if (unlikely(regs->ip == (unsigned long)&ibt_selftest_noendbr)) {
|
||||
regs->ax = 0;
|
||||
ibt_clear_fred_wfe(regs);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -97,6 +126,7 @@ static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
if (!ibt_fatal) {
|
||||
printk(KERN_DEFAULT CUT_HERE);
|
||||
__warn(__FILE__, __LINE__, (void *)regs->ip, TAINT_WARN, regs, NULL);
|
||||
ibt_clear_fred_wfe(regs);
|
||||
return;
|
||||
}
|
||||
BUG();
|
||||
|
||||
+7
-8
@@ -3903,16 +3903,11 @@ static int blk_mq_init_hctx(struct request_queue *q,
|
||||
{
|
||||
hctx->queue_num = hctx_idx;
|
||||
|
||||
if (!(hctx->flags & BLK_MQ_F_STACKING))
|
||||
cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
|
||||
&hctx->cpuhp_online);
|
||||
cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead);
|
||||
|
||||
hctx->tags = set->tags[hctx_idx];
|
||||
|
||||
if (set->ops->init_hctx &&
|
||||
set->ops->init_hctx(hctx, set->driver_data, hctx_idx))
|
||||
goto unregister_cpu_notifier;
|
||||
goto fail;
|
||||
|
||||
if (blk_mq_init_request(set, hctx->fq->flush_rq, hctx_idx,
|
||||
hctx->numa_node))
|
||||
@@ -3921,6 +3916,11 @@ static int blk_mq_init_hctx(struct request_queue *q,
|
||||
if (xa_insert(&q->hctx_table, hctx_idx, hctx, GFP_KERNEL))
|
||||
goto exit_flush_rq;
|
||||
|
||||
if (!(hctx->flags & BLK_MQ_F_STACKING))
|
||||
cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
|
||||
&hctx->cpuhp_online);
|
||||
cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_flush_rq:
|
||||
@@ -3929,8 +3929,7 @@ static int blk_mq_init_hctx(struct request_queue *q,
|
||||
exit_hctx:
|
||||
if (set->ops->exit_hctx)
|
||||
set->ops->exit_hctx(hctx, hctx_idx);
|
||||
unregister_cpu_notifier:
|
||||
blk_mq_remove_cpuhp(hctx);
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1703,6 +1703,8 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = {
|
||||
/* HiSilicon Hip09 Platform */
|
||||
{"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
|
||||
"Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
|
||||
{"HISI ", "HIP09A ", 0, ACPI_SIG_IORT, greater_than_or_equal,
|
||||
"Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
|
||||
/* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */
|
||||
{"HISI ", "HIP10 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
|
||||
"Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
|
||||
|
||||
@@ -1063,13 +1063,13 @@ skip_format_initialization:
|
||||
|
||||
/* Sanity check */
|
||||
if (range_cfg->range_max < range_cfg->range_min) {
|
||||
dev_err(map->dev, "Invalid range %d: %d < %d\n", i,
|
||||
dev_err(map->dev, "Invalid range %d: %u < %u\n", i,
|
||||
range_cfg->range_max, range_cfg->range_min);
|
||||
goto err_range;
|
||||
}
|
||||
|
||||
if (range_cfg->range_max > map->max_register) {
|
||||
dev_err(map->dev, "Invalid range %d: %d > %d\n", i,
|
||||
dev_err(map->dev, "Invalid range %d: %u > %u\n", i,
|
||||
range_cfg->range_max, map->max_register);
|
||||
goto err_range;
|
||||
}
|
||||
|
||||
@@ -1599,6 +1599,21 @@ static void ublk_unquiesce_dev(struct ublk_device *ub)
|
||||
blk_mq_kick_requeue_list(ub->ub_disk->queue);
|
||||
}
|
||||
|
||||
static struct gendisk *ublk_detach_disk(struct ublk_device *ub)
|
||||
{
|
||||
struct gendisk *disk;
|
||||
|
||||
/* Sync with ublk_abort_queue() by holding the lock */
|
||||
spin_lock(&ub->lock);
|
||||
disk = ub->ub_disk;
|
||||
ub->dev_info.state = UBLK_S_DEV_DEAD;
|
||||
ub->dev_info.ublksrv_pid = -1;
|
||||
ub->ub_disk = NULL;
|
||||
spin_unlock(&ub->lock);
|
||||
|
||||
return disk;
|
||||
}
|
||||
|
||||
static void ublk_stop_dev(struct ublk_device *ub)
|
||||
{
|
||||
struct gendisk *disk;
|
||||
@@ -1612,14 +1627,7 @@ static void ublk_stop_dev(struct ublk_device *ub)
|
||||
ublk_unquiesce_dev(ub);
|
||||
}
|
||||
del_gendisk(ub->ub_disk);
|
||||
|
||||
/* Sync with ublk_abort_queue() by holding the lock */
|
||||
spin_lock(&ub->lock);
|
||||
disk = ub->ub_disk;
|
||||
ub->dev_info.state = UBLK_S_DEV_DEAD;
|
||||
ub->dev_info.ublksrv_pid = -1;
|
||||
ub->ub_disk = NULL;
|
||||
spin_unlock(&ub->lock);
|
||||
disk = ublk_detach_disk(ub);
|
||||
put_disk(disk);
|
||||
unlock:
|
||||
mutex_unlock(&ub->mutex);
|
||||
@@ -2295,7 +2303,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
|
||||
|
||||
out_put_cdev:
|
||||
if (ret) {
|
||||
ub->dev_info.state = UBLK_S_DEV_DEAD;
|
||||
ublk_detach_disk(ub);
|
||||
ublk_put_device(ub);
|
||||
}
|
||||
if (ret)
|
||||
|
||||
@@ -1587,9 +1587,12 @@ static void virtblk_remove(struct virtio_device *vdev)
|
||||
static int virtblk_freeze(struct virtio_device *vdev)
|
||||
{
|
||||
struct virtio_blk *vblk = vdev->priv;
|
||||
struct request_queue *q = vblk->disk->queue;
|
||||
|
||||
/* Ensure no requests in virtqueues before deleting vqs. */
|
||||
blk_mq_freeze_queue(vblk->disk->queue);
|
||||
blk_mq_freeze_queue(q);
|
||||
blk_mq_quiesce_queue_nowait(q);
|
||||
blk_mq_unfreeze_queue(q);
|
||||
|
||||
/* Ensure we don't receive any more interrupts */
|
||||
virtio_reset_device(vdev);
|
||||
@@ -1613,8 +1616,8 @@ static int virtblk_restore(struct virtio_device *vdev)
|
||||
return ret;
|
||||
|
||||
virtio_device_ready(vdev);
|
||||
blk_mq_unquiesce_queue(vblk->disk->queue);
|
||||
|
||||
blk_mq_unfreeze_queue(vblk->disk->queue);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
+29
-12
@@ -870,6 +870,7 @@ struct btusb_data {
|
||||
|
||||
int (*suspend)(struct hci_dev *hdev);
|
||||
int (*resume)(struct hci_dev *hdev);
|
||||
int (*disconnect)(struct hci_dev *hdev);
|
||||
|
||||
int oob_wake_irq; /* irq for out-of-band wake-on-bt */
|
||||
unsigned cmd_timeout_cnt;
|
||||
@@ -2643,11 +2644,11 @@ static void btusb_mtk_claim_iso_intf(struct btusb_data *data)
|
||||
init_usb_anchor(&btmtk_data->isopkt_anchor);
|
||||
}
|
||||
|
||||
static void btusb_mtk_release_iso_intf(struct btusb_data *data)
|
||||
static void btusb_mtk_release_iso_intf(struct hci_dev *hdev)
|
||||
{
|
||||
struct btmtk_data *btmtk_data = hci_get_priv(data->hdev);
|
||||
struct btmtk_data *btmtk_data = hci_get_priv(hdev);
|
||||
|
||||
if (btmtk_data->isopkt_intf) {
|
||||
if (test_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags)) {
|
||||
usb_kill_anchored_urbs(&btmtk_data->isopkt_anchor);
|
||||
clear_bit(BTMTK_ISOPKT_RUNNING, &btmtk_data->flags);
|
||||
|
||||
@@ -2661,6 +2662,16 @@ static void btusb_mtk_release_iso_intf(struct btusb_data *data)
|
||||
clear_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags);
|
||||
}
|
||||
|
||||
static int btusb_mtk_disconnect(struct hci_dev *hdev)
|
||||
{
|
||||
/* This function describes the specific additional steps taken by MediaTek
|
||||
* when Bluetooth usb driver's resume function is called.
|
||||
*/
|
||||
btusb_mtk_release_iso_intf(hdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
@@ -2677,8 +2688,8 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (test_bit(BTMTK_ISOPKT_RUNNING, &btmtk_data->flags))
|
||||
btusb_mtk_release_iso_intf(data);
|
||||
/* Release MediaTek ISO data interface */
|
||||
btusb_mtk_release_iso_intf(hdev);
|
||||
|
||||
btusb_stop_traffic(data);
|
||||
usb_kill_anchored_urbs(&data->tx_anchor);
|
||||
@@ -2723,22 +2734,24 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
|
||||
btmtk_data->reset_sync = btusb_mtk_reset;
|
||||
|
||||
/* Claim ISO data interface and endpoint */
|
||||
btmtk_data->isopkt_intf = usb_ifnum_to_if(data->udev, MTK_ISO_IFNUM);
|
||||
if (btmtk_data->isopkt_intf)
|
||||
if (!test_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags)) {
|
||||
btmtk_data->isopkt_intf = usb_ifnum_to_if(data->udev, MTK_ISO_IFNUM);
|
||||
btusb_mtk_claim_iso_intf(data);
|
||||
}
|
||||
|
||||
return btmtk_usb_setup(hdev);
|
||||
}
|
||||
|
||||
static int btusb_mtk_shutdown(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct btmtk_data *btmtk_data = hci_get_priv(hdev);
|
||||
int ret;
|
||||
|
||||
if (test_bit(BTMTK_ISOPKT_RUNNING, &btmtk_data->flags))
|
||||
btusb_mtk_release_iso_intf(data);
|
||||
ret = btmtk_usb_shutdown(hdev);
|
||||
|
||||
return btmtk_usb_shutdown(hdev);
|
||||
/* Release MediaTek iso interface after shutdown */
|
||||
btusb_mtk_release_iso_intf(hdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
@@ -3850,6 +3863,7 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
data->recv_acl = btmtk_usb_recv_acl;
|
||||
data->suspend = btmtk_usb_suspend;
|
||||
data->resume = btmtk_usb_resume;
|
||||
data->disconnect = btusb_mtk_disconnect;
|
||||
}
|
||||
|
||||
if (id->driver_info & BTUSB_SWAVE) {
|
||||
@@ -4040,6 +4054,9 @@ static void btusb_disconnect(struct usb_interface *intf)
|
||||
if (data->diag)
|
||||
usb_set_intfdata(data->diag, NULL);
|
||||
|
||||
if (data->disconnect)
|
||||
data->disconnect(hdev);
|
||||
|
||||
hci_unregister_dev(hdev);
|
||||
|
||||
if (intf == data->intf) {
|
||||
|
||||
+12
-16
@@ -7,9 +7,9 @@
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/dma-map-ops.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/amd_qdma.h>
|
||||
#include <linux/regmap.h>
|
||||
@@ -492,18 +492,9 @@ static int qdma_device_verify(struct qdma_device *qdev)
|
||||
|
||||
static int qdma_device_setup(struct qdma_device *qdev)
|
||||
{
|
||||
struct device *dev = &qdev->pdev->dev;
|
||||
u32 ring_sz = QDMA_DEFAULT_RING_SIZE;
|
||||
int ret = 0;
|
||||
|
||||
while (dev && get_dma_ops(dev))
|
||||
dev = dev->parent;
|
||||
if (!dev) {
|
||||
qdma_err(qdev, "dma device not found");
|
||||
return -EINVAL;
|
||||
}
|
||||
set_dma_ops(&qdev->pdev->dev, get_dma_ops(dev));
|
||||
|
||||
ret = qdma_setup_fmap_context(qdev);
|
||||
if (ret) {
|
||||
qdma_err(qdev, "Failed setup fmap context");
|
||||
@@ -548,11 +539,12 @@ static void qdma_free_queue_resources(struct dma_chan *chan)
|
||||
{
|
||||
struct qdma_queue *queue = to_qdma_queue(chan);
|
||||
struct qdma_device *qdev = queue->qdev;
|
||||
struct device *dev = qdev->dma_dev.dev;
|
||||
struct qdma_platdata *pdata;
|
||||
|
||||
qdma_clear_queue_context(queue);
|
||||
vchan_free_chan_resources(&queue->vchan);
|
||||
dma_free_coherent(dev, queue->ring_size * QDMA_MM_DESC_SIZE,
|
||||
pdata = dev_get_platdata(&qdev->pdev->dev);
|
||||
dma_free_coherent(pdata->dma_dev, queue->ring_size * QDMA_MM_DESC_SIZE,
|
||||
queue->desc_base, queue->dma_desc_base);
|
||||
}
|
||||
|
||||
@@ -565,6 +557,7 @@ static int qdma_alloc_queue_resources(struct dma_chan *chan)
|
||||
struct qdma_queue *queue = to_qdma_queue(chan);
|
||||
struct qdma_device *qdev = queue->qdev;
|
||||
struct qdma_ctxt_sw_desc desc;
|
||||
struct qdma_platdata *pdata;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
@@ -572,8 +565,9 @@ static int qdma_alloc_queue_resources(struct dma_chan *chan)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pdata = dev_get_platdata(&qdev->pdev->dev);
|
||||
size = queue->ring_size * QDMA_MM_DESC_SIZE;
|
||||
queue->desc_base = dma_alloc_coherent(qdev->dma_dev.dev, size,
|
||||
queue->desc_base = dma_alloc_coherent(pdata->dma_dev, size,
|
||||
&queue->dma_desc_base,
|
||||
GFP_KERNEL);
|
||||
if (!queue->desc_base) {
|
||||
@@ -588,7 +582,7 @@ static int qdma_alloc_queue_resources(struct dma_chan *chan)
|
||||
if (ret) {
|
||||
qdma_err(qdev, "Failed to setup SW desc ctxt for %s",
|
||||
chan->name);
|
||||
dma_free_coherent(qdev->dma_dev.dev, size, queue->desc_base,
|
||||
dma_free_coherent(pdata->dma_dev, size, queue->desc_base,
|
||||
queue->dma_desc_base);
|
||||
return ret;
|
||||
}
|
||||
@@ -948,8 +942,9 @@ static int qdma_init_error_irq(struct qdma_device *qdev)
|
||||
|
||||
static int qdmam_alloc_qintr_rings(struct qdma_device *qdev)
|
||||
{
|
||||
u32 ctxt[QDMA_CTXT_REGMAP_LEN];
|
||||
struct qdma_platdata *pdata = dev_get_platdata(&qdev->pdev->dev);
|
||||
struct device *dev = &qdev->pdev->dev;
|
||||
u32 ctxt[QDMA_CTXT_REGMAP_LEN];
|
||||
struct qdma_intr_ring *ring;
|
||||
struct qdma_ctxt_intr intr_ctxt;
|
||||
u32 vector;
|
||||
@@ -969,7 +964,8 @@ static int qdmam_alloc_qintr_rings(struct qdma_device *qdev)
|
||||
ring->msix_id = qdev->err_irq_idx + i + 1;
|
||||
ring->ridx = i;
|
||||
ring->color = 1;
|
||||
ring->base = dmam_alloc_coherent(dev, QDMA_INTR_RING_SIZE,
|
||||
ring->base = dmam_alloc_coherent(pdata->dma_dev,
|
||||
QDMA_INTR_RING_SIZE,
|
||||
&ring->dev_base, GFP_KERNEL);
|
||||
if (!ring->base) {
|
||||
qdma_err(qdev, "Failed to alloc intr ring %d", i);
|
||||
|
||||
@@ -153,6 +153,8 @@ static int admac_alloc_sram_carveout(struct admac_data *ad,
|
||||
{
|
||||
struct admac_sram *sram;
|
||||
int i, ret = 0, nblocks;
|
||||
ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
|
||||
ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
|
||||
|
||||
if (dir == DMA_MEM_TO_DEV)
|
||||
sram = &ad->txcache;
|
||||
@@ -912,12 +914,7 @@ static int admac_probe(struct platform_device *pdev)
|
||||
goto free_irq;
|
||||
}
|
||||
|
||||
ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
|
||||
ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
|
||||
|
||||
dev_info(&pdev->dev, "Audio DMA Controller\n");
|
||||
dev_info(&pdev->dev, "imprint %x TX cache %u RX cache %u\n",
|
||||
readl_relaxed(ad->base + REG_IMPRINT), ad->txcache.size, ad->rxcache.size);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1363,6 +1363,8 @@ at_xdmac_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value,
|
||||
return NULL;
|
||||
|
||||
desc = at_xdmac_memset_create_desc(chan, atchan, dest, len, value);
|
||||
if (!desc)
|
||||
return NULL;
|
||||
list_add_tail(&desc->desc_node, &desc->descs_list);
|
||||
|
||||
desc->tx_dma_desc.cookie = -EBUSY;
|
||||
|
||||
@@ -8,13 +8,15 @@
|
||||
|
||||
static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
|
||||
{
|
||||
struct dw_dma *dw = to_dw_dma(chan->device);
|
||||
struct dw_dma_chip_pdata *data = dev_get_drvdata(dw->dma.dev);
|
||||
struct acpi_dma_spec *dma_spec = param;
|
||||
struct dw_dma_slave slave = {
|
||||
.dma_dev = dma_spec->dev,
|
||||
.src_id = dma_spec->slave_id,
|
||||
.dst_id = dma_spec->slave_id,
|
||||
.m_master = 0,
|
||||
.p_master = 1,
|
||||
.m_master = data->m_master,
|
||||
.p_master = data->p_master,
|
||||
};
|
||||
|
||||
return dw_dma_filter(chan, &slave);
|
||||
|
||||
@@ -51,11 +51,15 @@ struct dw_dma_chip_pdata {
|
||||
int (*probe)(struct dw_dma_chip *chip);
|
||||
int (*remove)(struct dw_dma_chip *chip);
|
||||
struct dw_dma_chip *chip;
|
||||
u8 m_master;
|
||||
u8 p_master;
|
||||
};
|
||||
|
||||
static __maybe_unused const struct dw_dma_chip_pdata dw_dma_chip_pdata = {
|
||||
.probe = dw_dma_probe,
|
||||
.remove = dw_dma_remove,
|
||||
.m_master = 0,
|
||||
.p_master = 1,
|
||||
};
|
||||
|
||||
static const struct dw_dma_platform_data idma32_pdata = {
|
||||
@@ -72,6 +76,8 @@ static __maybe_unused const struct dw_dma_chip_pdata idma32_chip_pdata = {
|
||||
.pdata = &idma32_pdata,
|
||||
.probe = idma32_dma_probe,
|
||||
.remove = idma32_dma_remove,
|
||||
.m_master = 0,
|
||||
.p_master = 0,
|
||||
};
|
||||
|
||||
static const struct dw_dma_platform_data xbar_pdata = {
|
||||
@@ -88,6 +94,8 @@ static __maybe_unused const struct dw_dma_chip_pdata xbar_chip_pdata = {
|
||||
.pdata = &xbar_pdata,
|
||||
.probe = idma32_dma_probe,
|
||||
.remove = idma32_dma_remove,
|
||||
.m_master = 0,
|
||||
.p_master = 0,
|
||||
};
|
||||
|
||||
#endif /* _DMA_DW_INTERNAL_H */
|
||||
|
||||
@@ -56,10 +56,10 @@ static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dw_dma_acpi_controller_register(chip->dw);
|
||||
|
||||
pci_set_drvdata(pdev, data);
|
||||
|
||||
dw_dma_acpi_controller_register(chip->dw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,6 +166,7 @@ struct fsl_edma_chan {
|
||||
struct work_struct issue_worker;
|
||||
struct platform_device *pdev;
|
||||
struct device *pd_dev;
|
||||
struct device_link *pd_dev_link;
|
||||
u32 srcid;
|
||||
struct clk *clk;
|
||||
int priority;
|
||||
|
||||
@@ -417,10 +417,33 @@ static const struct of_device_id fsl_edma_dt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
|
||||
|
||||
static void fsl_edma3_detach_pd(struct fsl_edma_engine *fsl_edma)
|
||||
{
|
||||
struct fsl_edma_chan *fsl_chan;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fsl_edma->n_chans; i++) {
|
||||
if (fsl_edma->chan_masked & BIT(i))
|
||||
continue;
|
||||
fsl_chan = &fsl_edma->chans[i];
|
||||
if (fsl_chan->pd_dev_link)
|
||||
device_link_del(fsl_chan->pd_dev_link);
|
||||
if (fsl_chan->pd_dev) {
|
||||
dev_pm_domain_detach(fsl_chan->pd_dev, false);
|
||||
pm_runtime_dont_use_autosuspend(fsl_chan->pd_dev);
|
||||
pm_runtime_set_suspended(fsl_chan->pd_dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void devm_fsl_edma3_detach_pd(void *data)
|
||||
{
|
||||
fsl_edma3_detach_pd(data);
|
||||
}
|
||||
|
||||
static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma)
|
||||
{
|
||||
struct fsl_edma_chan *fsl_chan;
|
||||
struct device_link *link;
|
||||
struct device *pd_chan;
|
||||
struct device *dev;
|
||||
int i;
|
||||
@@ -436,15 +459,16 @@ static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_eng
|
||||
pd_chan = dev_pm_domain_attach_by_id(dev, i);
|
||||
if (IS_ERR_OR_NULL(pd_chan)) {
|
||||
dev_err(dev, "Failed attach pd %d\n", i);
|
||||
return -EINVAL;
|
||||
goto detach;
|
||||
}
|
||||
|
||||
link = device_link_add(dev, pd_chan, DL_FLAG_STATELESS |
|
||||
fsl_chan->pd_dev_link = device_link_add(dev, pd_chan, DL_FLAG_STATELESS |
|
||||
DL_FLAG_PM_RUNTIME |
|
||||
DL_FLAG_RPM_ACTIVE);
|
||||
if (!link) {
|
||||
if (!fsl_chan->pd_dev_link) {
|
||||
dev_err(dev, "Failed to add device_link to %d\n", i);
|
||||
return -EINVAL;
|
||||
dev_pm_domain_detach(pd_chan, false);
|
||||
goto detach;
|
||||
}
|
||||
|
||||
fsl_chan->pd_dev = pd_chan;
|
||||
@@ -455,6 +479,10 @@ static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_eng
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
detach:
|
||||
fsl_edma3_detach_pd(fsl_edma);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int fsl_edma_probe(struct platform_device *pdev)
|
||||
@@ -544,6 +572,9 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
||||
ret = fsl_edma3_attach_pd(pdev, fsl_edma);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = devm_add_action_or_reset(&pdev->dev, devm_fsl_edma3_detach_pd, fsl_edma);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drvdata->flags & FSL_EDMA_DRV_TCD64)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#define LDMA_ASK_VALID BIT(2)
|
||||
#define LDMA_START BIT(3) /* DMA start operation */
|
||||
#define LDMA_STOP BIT(4) /* DMA stop operation */
|
||||
#define LDMA_CONFIG_MASK GENMASK(4, 0) /* DMA controller config bits mask */
|
||||
#define LDMA_CONFIG_MASK GENMASK_ULL(4, 0) /* DMA controller config bits mask */
|
||||
|
||||
/* Bitfields in ndesc_addr field of HW descriptor */
|
||||
#define LDMA_DESC_EN BIT(0) /*1: The next descriptor is valid */
|
||||
|
||||
@@ -1388,6 +1388,7 @@ static int mv_xor_probe(struct platform_device *pdev)
|
||||
irq = irq_of_parse_and_map(np, 0);
|
||||
if (!irq) {
|
||||
ret = -ENODEV;
|
||||
of_node_put(np);
|
||||
goto err_channel_add;
|
||||
}
|
||||
|
||||
@@ -1396,6 +1397,7 @@ static int mv_xor_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(chan)) {
|
||||
ret = PTR_ERR(chan);
|
||||
irq_dispose_mapping(irq);
|
||||
of_node_put(np);
|
||||
goto err_channel_add;
|
||||
}
|
||||
|
||||
|
||||
@@ -231,6 +231,7 @@ struct tegra_dma_channel {
|
||||
bool config_init;
|
||||
char name[30];
|
||||
enum dma_transfer_direction sid_dir;
|
||||
enum dma_status status;
|
||||
int id;
|
||||
int irq;
|
||||
int slave_id;
|
||||
@@ -393,6 +394,8 @@ static int tegra_dma_pause(struct tegra_dma_channel *tdc)
|
||||
tegra_dma_dump_chan_regs(tdc);
|
||||
}
|
||||
|
||||
tdc->status = DMA_PAUSED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -419,6 +422,8 @@ static void tegra_dma_resume(struct tegra_dma_channel *tdc)
|
||||
val = tdc_read(tdc, TEGRA_GPCDMA_CHAN_CSRE);
|
||||
val &= ~TEGRA_GPCDMA_CHAN_CSRE_PAUSE;
|
||||
tdc_write(tdc, TEGRA_GPCDMA_CHAN_CSRE, val);
|
||||
|
||||
tdc->status = DMA_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static int tegra_dma_device_resume(struct dma_chan *dc)
|
||||
@@ -544,6 +549,7 @@ static void tegra_dma_xfer_complete(struct tegra_dma_channel *tdc)
|
||||
|
||||
tegra_dma_sid_free(tdc);
|
||||
tdc->dma_desc = NULL;
|
||||
tdc->status = DMA_COMPLETE;
|
||||
}
|
||||
|
||||
static void tegra_dma_chan_decode_error(struct tegra_dma_channel *tdc,
|
||||
@@ -716,6 +722,7 @@ static int tegra_dma_terminate_all(struct dma_chan *dc)
|
||||
tdc->dma_desc = NULL;
|
||||
}
|
||||
|
||||
tdc->status = DMA_COMPLETE;
|
||||
tegra_dma_sid_free(tdc);
|
||||
vchan_get_all_descriptors(&tdc->vc, &head);
|
||||
spin_unlock_irqrestore(&tdc->vc.lock, flags);
|
||||
@@ -769,6 +776,9 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
|
||||
if (ret == DMA_COMPLETE)
|
||||
return ret;
|
||||
|
||||
if (tdc->status == DMA_PAUSED)
|
||||
ret = DMA_PAUSED;
|
||||
|
||||
spin_lock_irqsave(&tdc->vc.lock, flags);
|
||||
vd = vchan_find_desc(&tdc->vc, cookie);
|
||||
if (vd) {
|
||||
|
||||
@@ -4108,9 +4108,10 @@ static void drm_dp_mst_up_req_work(struct work_struct *work)
|
||||
static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
{
|
||||
struct drm_dp_pending_up_req *up_req;
|
||||
struct drm_dp_mst_branch *mst_primary;
|
||||
|
||||
if (!drm_dp_get_one_sb_msg(mgr, true, NULL))
|
||||
goto out;
|
||||
goto out_clear_reply;
|
||||
|
||||
if (!mgr->up_req_recv.have_eomt)
|
||||
return 0;
|
||||
@@ -4128,10 +4129,19 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
drm_dbg_kms(mgr->dev, "Received unknown up req type, ignoring: %x\n",
|
||||
up_req->msg.req_type);
|
||||
kfree(up_req);
|
||||
goto out;
|
||||
goto out_clear_reply;
|
||||
}
|
||||
|
||||
drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, up_req->msg.req_type,
|
||||
mutex_lock(&mgr->lock);
|
||||
mst_primary = mgr->mst_primary;
|
||||
if (!mst_primary || !drm_dp_mst_topology_try_get_mstb(mst_primary)) {
|
||||
mutex_unlock(&mgr->lock);
|
||||
kfree(up_req);
|
||||
goto out_clear_reply;
|
||||
}
|
||||
mutex_unlock(&mgr->lock);
|
||||
|
||||
drm_dp_send_up_ack_reply(mgr, mst_primary, up_req->msg.req_type,
|
||||
false);
|
||||
|
||||
if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
|
||||
@@ -4148,13 +4158,13 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
conn_stat->peer_device_type);
|
||||
|
||||
mutex_lock(&mgr->probe_lock);
|
||||
handle_csn = mgr->mst_primary->link_address_sent;
|
||||
handle_csn = mst_primary->link_address_sent;
|
||||
mutex_unlock(&mgr->probe_lock);
|
||||
|
||||
if (!handle_csn) {
|
||||
drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it.");
|
||||
kfree(up_req);
|
||||
goto out;
|
||||
goto out_put_primary;
|
||||
}
|
||||
} else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
|
||||
const struct drm_dp_resource_status_notify *res_stat =
|
||||
@@ -4171,7 +4181,9 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
mutex_unlock(&mgr->up_req_lock);
|
||||
queue_work(system_long_wq, &mgr->up_req_work);
|
||||
|
||||
out:
|
||||
out_put_primary:
|
||||
drm_dp_mst_topology_put_mstb(mst_primary);
|
||||
out_clear_reply:
|
||||
memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "xe_guc_ct.h"
|
||||
#include "xe_guc_submit.h"
|
||||
#include "xe_hw_engine.h"
|
||||
#include "xe_pm.h"
|
||||
#include "xe_sched_job.h"
|
||||
#include "xe_vm.h"
|
||||
|
||||
@@ -143,31 +144,6 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
|
||||
ss->vm = NULL;
|
||||
}
|
||||
|
||||
static void xe_devcoredump_deferred_snap_work(struct work_struct *work)
|
||||
{
|
||||
struct xe_devcoredump_snapshot *ss = container_of(work, typeof(*ss), work);
|
||||
struct xe_devcoredump *coredump = container_of(ss, typeof(*coredump), snapshot);
|
||||
unsigned int fw_ref;
|
||||
|
||||
/* keep going if fw fails as we still want to save the memory and SW data */
|
||||
fw_ref = xe_force_wake_get(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL);
|
||||
if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL))
|
||||
xe_gt_info(ss->gt, "failed to get forcewake for coredump capture\n");
|
||||
xe_vm_snapshot_capture_delayed(ss->vm);
|
||||
xe_guc_exec_queue_snapshot_capture_delayed(ss->ge);
|
||||
xe_force_wake_put(gt_to_fw(ss->gt), fw_ref);
|
||||
|
||||
/* Calculate devcoredump size */
|
||||
ss->read.size = __xe_devcoredump_read(NULL, INT_MAX, coredump);
|
||||
|
||||
ss->read.buffer = kvmalloc(ss->read.size, GFP_USER);
|
||||
if (!ss->read.buffer)
|
||||
return;
|
||||
|
||||
__xe_devcoredump_read(ss->read.buffer, ss->read.size, coredump);
|
||||
xe_devcoredump_snapshot_free(ss);
|
||||
}
|
||||
|
||||
static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
||||
size_t count, void *data, size_t datalen)
|
||||
{
|
||||
@@ -216,6 +192,45 @@ static void xe_devcoredump_free(void *data)
|
||||
"Xe device coredump has been deleted.\n");
|
||||
}
|
||||
|
||||
static void xe_devcoredump_deferred_snap_work(struct work_struct *work)
|
||||
{
|
||||
struct xe_devcoredump_snapshot *ss = container_of(work, typeof(*ss), work);
|
||||
struct xe_devcoredump *coredump = container_of(ss, typeof(*coredump), snapshot);
|
||||
struct xe_device *xe = coredump_to_xe(coredump);
|
||||
unsigned int fw_ref;
|
||||
|
||||
/*
|
||||
* NB: Despite passing a GFP_ flags parameter here, more allocations are done
|
||||
* internally using GFP_KERNEL expliictly. Hence this call must be in the worker
|
||||
* thread and not in the initial capture call.
|
||||
*/
|
||||
dev_coredumpm_timeout(gt_to_xe(ss->gt)->drm.dev, THIS_MODULE, coredump, 0, GFP_KERNEL,
|
||||
xe_devcoredump_read, xe_devcoredump_free,
|
||||
XE_COREDUMP_TIMEOUT_JIFFIES);
|
||||
|
||||
xe_pm_runtime_get(xe);
|
||||
|
||||
/* keep going if fw fails as we still want to save the memory and SW data */
|
||||
fw_ref = xe_force_wake_get(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL);
|
||||
if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL))
|
||||
xe_gt_info(ss->gt, "failed to get forcewake for coredump capture\n");
|
||||
xe_vm_snapshot_capture_delayed(ss->vm);
|
||||
xe_guc_exec_queue_snapshot_capture_delayed(ss->ge);
|
||||
xe_force_wake_put(gt_to_fw(ss->gt), fw_ref);
|
||||
|
||||
xe_pm_runtime_put(xe);
|
||||
|
||||
/* Calculate devcoredump size */
|
||||
ss->read.size = __xe_devcoredump_read(NULL, INT_MAX, coredump);
|
||||
|
||||
ss->read.buffer = kvmalloc(ss->read.size, GFP_USER);
|
||||
if (!ss->read.buffer)
|
||||
return;
|
||||
|
||||
__xe_devcoredump_read(ss->read.buffer, ss->read.size, coredump);
|
||||
xe_devcoredump_snapshot_free(ss);
|
||||
}
|
||||
|
||||
static void devcoredump_snapshot(struct xe_devcoredump *coredump,
|
||||
struct xe_sched_job *job)
|
||||
{
|
||||
@@ -299,10 +314,6 @@ void xe_devcoredump(struct xe_sched_job *job)
|
||||
drm_info(&xe->drm, "Xe device coredump has been created\n");
|
||||
drm_info(&xe->drm, "Check your /sys/class/drm/card%d/device/devcoredump/data\n",
|
||||
xe->drm.primary->index);
|
||||
|
||||
dev_coredumpm_timeout(xe->drm.dev, THIS_MODULE, coredump, 0, GFP_KERNEL,
|
||||
xe_devcoredump_read, xe_devcoredump_free,
|
||||
XE_COREDUMP_TIMEOUT_JIFFIES);
|
||||
}
|
||||
|
||||
static void xe_driver_devcoredump_fini(void *arg)
|
||||
|
||||
@@ -282,6 +282,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx6sll-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx6sx-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx6ul-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx7d-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx7s-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx8mm-i2c", .data = &imx6_i2c_hwdata, },
|
||||
{ .compatible = "fsl,imx8mn-i2c", .data = &imx6_i2c_hwdata, },
|
||||
|
||||
@@ -93,27 +93,35 @@
|
||||
* @base: pointer to register struct
|
||||
* @dev: device reference
|
||||
* @i2c_clk: clock reference for i2c input clock
|
||||
* @msg_queue: pointer to the messages requiring sending
|
||||
* @buf: pointer to msg buffer for easier use
|
||||
* @msg_complete: xfer completion object
|
||||
* @adapter: core i2c abstraction
|
||||
* @msg_err: error code for completed message
|
||||
* @bus_clk_rate: current i2c bus clock rate
|
||||
* @isr_status: cached copy of local ISR status
|
||||
* @total_num: total number of messages to be sent/received
|
||||
* @current_num: index of the current message being sent/received
|
||||
* @msg_len: number of bytes transferred in msg
|
||||
* @addr: address of the current slave
|
||||
* @restart_needed: whether or not a repeated start is required after current message
|
||||
*/
|
||||
struct mchp_corei2c_dev {
|
||||
void __iomem *base;
|
||||
struct device *dev;
|
||||
struct clk *i2c_clk;
|
||||
struct i2c_msg *msg_queue;
|
||||
u8 *buf;
|
||||
struct completion msg_complete;
|
||||
struct i2c_adapter adapter;
|
||||
int msg_err;
|
||||
int total_num;
|
||||
int current_num;
|
||||
u32 bus_clk_rate;
|
||||
u32 isr_status;
|
||||
u16 msg_len;
|
||||
u8 addr;
|
||||
bool restart_needed;
|
||||
};
|
||||
|
||||
static void mchp_corei2c_core_disable(struct mchp_corei2c_dev *idev)
|
||||
@@ -222,6 +230,47 @@ static int mchp_corei2c_fill_tx(struct mchp_corei2c_dev *idev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mchp_corei2c_next_msg(struct mchp_corei2c_dev *idev)
|
||||
{
|
||||
struct i2c_msg *this_msg;
|
||||
u8 ctrl;
|
||||
|
||||
if (idev->current_num >= idev->total_num) {
|
||||
complete(&idev->msg_complete);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there's been an error, the isr needs to return control
|
||||
* to the "main" part of the driver, so as not to keep sending
|
||||
* messages once it completes and clears the SI bit.
|
||||
*/
|
||||
if (idev->msg_err) {
|
||||
complete(&idev->msg_complete);
|
||||
return;
|
||||
}
|
||||
|
||||
this_msg = idev->msg_queue++;
|
||||
|
||||
if (idev->current_num < (idev->total_num - 1)) {
|
||||
struct i2c_msg *next_msg = idev->msg_queue;
|
||||
|
||||
idev->restart_needed = next_msg->flags & I2C_M_RD;
|
||||
} else {
|
||||
idev->restart_needed = false;
|
||||
}
|
||||
|
||||
idev->addr = i2c_8bit_addr_from_msg(this_msg);
|
||||
idev->msg_len = this_msg->len;
|
||||
idev->buf = this_msg->buf;
|
||||
|
||||
ctrl = readb(idev->base + CORE_I2C_CTRL);
|
||||
ctrl |= CTRL_STA;
|
||||
writeb(ctrl, idev->base + CORE_I2C_CTRL);
|
||||
|
||||
idev->current_num++;
|
||||
}
|
||||
|
||||
static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
|
||||
{
|
||||
u32 status = idev->isr_status;
|
||||
@@ -238,8 +287,6 @@ static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
|
||||
ctrl &= ~CTRL_STA;
|
||||
writeb(idev->addr, idev->base + CORE_I2C_DATA);
|
||||
writeb(ctrl, idev->base + CORE_I2C_CTRL);
|
||||
if (idev->msg_len == 0)
|
||||
finished = true;
|
||||
break;
|
||||
case STATUS_M_ARB_LOST:
|
||||
idev->msg_err = -EAGAIN;
|
||||
@@ -247,10 +294,14 @@ static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
|
||||
break;
|
||||
case STATUS_M_SLAW_ACK:
|
||||
case STATUS_M_TX_DATA_ACK:
|
||||
if (idev->msg_len > 0)
|
||||
if (idev->msg_len > 0) {
|
||||
mchp_corei2c_fill_tx(idev);
|
||||
else
|
||||
last_byte = true;
|
||||
} else {
|
||||
if (idev->restart_needed)
|
||||
finished = true;
|
||||
else
|
||||
last_byte = true;
|
||||
}
|
||||
break;
|
||||
case STATUS_M_TX_DATA_NACK:
|
||||
case STATUS_M_SLAR_NACK:
|
||||
@@ -287,7 +338,7 @@ static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
|
||||
mchp_corei2c_stop(idev);
|
||||
|
||||
if (last_byte || finished)
|
||||
complete(&idev->msg_complete);
|
||||
mchp_corei2c_next_msg(idev);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -311,21 +362,48 @@ static irqreturn_t mchp_corei2c_isr(int irq, void *_dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mchp_corei2c_xfer_msg(struct mchp_corei2c_dev *idev,
|
||||
struct i2c_msg *msg)
|
||||
static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
int num)
|
||||
{
|
||||
u8 ctrl;
|
||||
struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap);
|
||||
struct i2c_msg *this_msg = msgs;
|
||||
unsigned long time_left;
|
||||
|
||||
idev->addr = i2c_8bit_addr_from_msg(msg);
|
||||
idev->msg_len = msg->len;
|
||||
idev->buf = msg->buf;
|
||||
idev->msg_err = 0;
|
||||
|
||||
reinit_completion(&idev->msg_complete);
|
||||
u8 ctrl;
|
||||
|
||||
mchp_corei2c_core_enable(idev);
|
||||
|
||||
/*
|
||||
* The isr controls the flow of a transfer, this info needs to be saved
|
||||
* to a location that it can access the queue information from.
|
||||
*/
|
||||
idev->restart_needed = false;
|
||||
idev->msg_queue = msgs;
|
||||
idev->total_num = num;
|
||||
idev->current_num = 0;
|
||||
|
||||
/*
|
||||
* But the first entry to the isr is triggered by the start in this
|
||||
* function, so the first message needs to be "dequeued".
|
||||
*/
|
||||
idev->addr = i2c_8bit_addr_from_msg(this_msg);
|
||||
idev->msg_len = this_msg->len;
|
||||
idev->buf = this_msg->buf;
|
||||
idev->msg_err = 0;
|
||||
|
||||
if (idev->total_num > 1) {
|
||||
struct i2c_msg *next_msg = msgs + 1;
|
||||
|
||||
idev->restart_needed = next_msg->flags & I2C_M_RD;
|
||||
}
|
||||
|
||||
idev->current_num++;
|
||||
idev->msg_queue++;
|
||||
|
||||
reinit_completion(&idev->msg_complete);
|
||||
|
||||
/*
|
||||
* Send the first start to pass control to the isr
|
||||
*/
|
||||
ctrl = readb(idev->base + CORE_I2C_CTRL);
|
||||
ctrl |= CTRL_STA;
|
||||
writeb(ctrl, idev->base + CORE_I2C_CTRL);
|
||||
@@ -335,20 +413,8 @@ static int mchp_corei2c_xfer_msg(struct mchp_corei2c_dev *idev,
|
||||
if (!time_left)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return idev->msg_err;
|
||||
}
|
||||
|
||||
static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
int num)
|
||||
{
|
||||
struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap);
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret = mchp_corei2c_xfer_msg(idev, msgs++);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (idev->msg_err)
|
||||
return idev->msg_err;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-a
|
||||
static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
|
||||
{
|
||||
u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
|
||||
u8 rb[2];
|
||||
u8 rb[2] = {};
|
||||
struct i2c_msg msg[] = {
|
||||
{ .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
|
||||
{ .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
|
||||
|
||||
@@ -1409,8 +1409,8 @@ static int anfc_parse_cs(struct arasan_nfc *nfc)
|
||||
* case, the "not" chosen CS is assigned to nfc->spare_cs and selected
|
||||
* whenever a GPIO CS must be asserted.
|
||||
*/
|
||||
if (nfc->cs_array && nfc->ncs > 2) {
|
||||
if (!nfc->cs_array[0] && !nfc->cs_array[1]) {
|
||||
if (nfc->cs_array) {
|
||||
if (nfc->ncs > 2 && !nfc->cs_array[0] && !nfc->cs_array[1]) {
|
||||
dev_err(nfc->dev,
|
||||
"Assign a single native CS when using GPIOs\n");
|
||||
return -EINVAL;
|
||||
@@ -1478,8 +1478,15 @@ static int anfc_probe(struct platform_device *pdev)
|
||||
|
||||
static void anfc_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
struct arasan_nfc *nfc = platform_get_drvdata(pdev);
|
||||
|
||||
for (i = 0; i < nfc->ncs; i++) {
|
||||
if (nfc->cs_array[i]) {
|
||||
gpiod_put(nfc->cs_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
anfc_chips_cleanup(nfc);
|
||||
}
|
||||
|
||||
|
||||
@@ -380,10 +380,8 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
|
||||
user->delta = user->dmu + req->ecc.strength + 1;
|
||||
|
||||
gf_tables = atmel_pmecc_get_gf_tables(req);
|
||||
if (IS_ERR(gf_tables)) {
|
||||
kfree(user);
|
||||
if (IS_ERR(gf_tables))
|
||||
return ERR_CAST(gf_tables);
|
||||
}
|
||||
|
||||
user->gf_tables = gf_tables;
|
||||
|
||||
|
||||
@@ -1098,7 +1098,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti
|
||||
(i == 0) && (ip->firstUnit > 0)) {
|
||||
parts[0].name = " DiskOnChip IPL / Media Header partition";
|
||||
parts[0].offset = 0;
|
||||
parts[0].size = mtd->erasesize * ip->firstUnit;
|
||||
parts[0].size = (uint64_t)mtd->erasesize * ip->firstUnit;
|
||||
numparts = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1074,12 +1074,13 @@ int iwl_trans_read_config32(struct iwl_trans *trans, u32 ofs,
|
||||
void iwl_trans_debugfs_cleanup(struct iwl_trans *trans);
|
||||
#endif
|
||||
|
||||
#define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize) \
|
||||
do { \
|
||||
if (__builtin_constant_p(bufsize)) \
|
||||
BUILD_BUG_ON((bufsize) % sizeof(u32)); \
|
||||
iwl_trans_read_mem(trans, addr, buf, (bufsize) / sizeof(u32));\
|
||||
} while (0)
|
||||
#define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize) \
|
||||
({ \
|
||||
if (__builtin_constant_p(bufsize)) \
|
||||
BUILD_BUG_ON((bufsize) % sizeof(u32)); \
|
||||
iwl_trans_read_mem(trans, addr, buf, \
|
||||
(bufsize) / sizeof(u32)); \
|
||||
})
|
||||
|
||||
int iwl_trans_write_imr_mem(struct iwl_trans *trans, u32 dst_addr,
|
||||
u64 src_addr, u32 byte_cnt);
|
||||
|
||||
@@ -3032,13 +3032,18 @@ static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
|
||||
/* cf. struct iwl_error_event_table */
|
||||
u32 valid;
|
||||
__le32 err_id;
|
||||
} err_info;
|
||||
} err_info = {};
|
||||
int ret;
|
||||
|
||||
if (!base)
|
||||
return false;
|
||||
|
||||
iwl_trans_read_mem_bytes(trans, base,
|
||||
&err_info, sizeof(err_info));
|
||||
ret = iwl_trans_read_mem_bytes(trans, base,
|
||||
&err_info, sizeof(err_info));
|
||||
|
||||
if (ret)
|
||||
return true;
|
||||
|
||||
if (err_info.valid && err_id)
|
||||
*err_id = le32_to_cpu(err_info.err_id);
|
||||
|
||||
@@ -3635,22 +3640,31 @@ int iwl_mvm_fast_resume(struct iwl_mvm *mvm)
|
||||
iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
|
||||
|
||||
if (iwl_mvm_check_rt_status(mvm, NULL)) {
|
||||
IWL_ERR(mvm,
|
||||
"iwl_mvm_check_rt_status failed, device is gone during suspend\n");
|
||||
set_bit(STATUS_FW_ERROR, &mvm->trans->status);
|
||||
iwl_mvm_dump_nic_error_log(mvm);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt,
|
||||
IWL_FW_INI_TIME_POINT_FW_ASSERT, NULL);
|
||||
iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
|
||||
false, 0);
|
||||
return -ENODEV;
|
||||
mvm->trans->state = IWL_TRANS_NO_FW;
|
||||
ret = -ENODEV;
|
||||
|
||||
goto out;
|
||||
}
|
||||
ret = iwl_mvm_d3_notif_wait(mvm, &d3_data);
|
||||
|
||||
if (ret) {
|
||||
IWL_ERR(mvm, "Couldn't get the d3 notif %d\n", ret);
|
||||
mvm->trans->state = IWL_TRANS_NO_FW;
|
||||
}
|
||||
|
||||
out:
|
||||
clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
|
||||
mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
|
||||
mvm->fast_resume = false;
|
||||
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "Couldn't get the d3 notif %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1643,6 +1643,8 @@ int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
|
||||
out:
|
||||
if (*status == IWL_D3_STATUS_ALIVE)
|
||||
ret = iwl_pcie_d3_handshake(trans, false);
|
||||
else
|
||||
trans->state = IWL_TRANS_NO_FW;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -350,8 +350,11 @@ bool pci_msi_domain_supports(struct pci_dev *pdev, unsigned int feature_mask,
|
||||
|
||||
domain = dev_get_msi_domain(&pdev->dev);
|
||||
|
||||
if (!domain || !irq_domain_is_hierarchy(domain))
|
||||
return mode == ALLOW_LEGACY;
|
||||
if (!domain || !irq_domain_is_hierarchy(domain)) {
|
||||
if (IS_ENABLED(CONFIG_PCI_MSI_ARCH_FALLBACKS))
|
||||
return mode == ALLOW_LEGACY;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!irq_domain_is_msi_parent(domain)) {
|
||||
/*
|
||||
|
||||
@@ -433,6 +433,10 @@ int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
|
||||
if (WARN_ON_ONCE(dev->msi_enabled))
|
||||
return -EINVAL;
|
||||
|
||||
/* Test for the availability of MSI support */
|
||||
if (!pci_msi_domain_supports(dev, 0, ALLOW_LEGACY))
|
||||
return -ENOTSUPP;
|
||||
|
||||
nvec = pci_msi_vec_count(dev);
|
||||
if (nvec < 0)
|
||||
return nvec;
|
||||
|
||||
@@ -325,6 +325,12 @@ static void usb_init_common_7216(struct brcm_usb_init_params *params)
|
||||
void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
|
||||
|
||||
USB_CTRL_UNSET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
|
||||
|
||||
/*
|
||||
* The PHY might be in a bad state if it is already powered
|
||||
* up. Toggle the power just in case.
|
||||
*/
|
||||
USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
|
||||
USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
|
||||
|
||||
/* 1 millisecond - for USB clocks to settle down */
|
||||
|
||||
+13
-8
@@ -145,8 +145,10 @@ static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
|
||||
return phy_provider;
|
||||
|
||||
for_each_child_of_node(phy_provider->children, child)
|
||||
if (child == node)
|
||||
if (child == node) {
|
||||
of_node_put(child);
|
||||
return phy_provider;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
@@ -629,8 +631,10 @@ static struct phy *_of_phy_get(struct device_node *np, int index)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
/* This phy type handled by the usb-phy subsystem for now */
|
||||
if (of_device_is_compatible(args.np, "usb-nop-xceiv"))
|
||||
return ERR_PTR(-ENODEV);
|
||||
if (of_device_is_compatible(args.np, "usb-nop-xceiv")) {
|
||||
phy = ERR_PTR(-ENODEV);
|
||||
goto out_put_node;
|
||||
}
|
||||
|
||||
mutex_lock(&phy_provider_mutex);
|
||||
phy_provider = of_phy_provider_lookup(args.np);
|
||||
@@ -652,6 +656,7 @@ out_put_module:
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&phy_provider_mutex);
|
||||
out_put_node:
|
||||
of_node_put(args.np);
|
||||
|
||||
return phy;
|
||||
@@ -737,7 +742,7 @@ void devm_phy_put(struct device *dev, struct phy *phy)
|
||||
if (!phy)
|
||||
return;
|
||||
|
||||
r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy);
|
||||
r = devres_release(dev, devm_phy_release, devm_phy_match, phy);
|
||||
dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_phy_put);
|
||||
@@ -1121,7 +1126,7 @@ void devm_phy_destroy(struct device *dev, struct phy *phy)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy);
|
||||
r = devres_release(dev, devm_phy_consume, devm_phy_match, phy);
|
||||
dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_phy_destroy);
|
||||
@@ -1259,12 +1264,12 @@ EXPORT_SYMBOL_GPL(of_phy_provider_unregister);
|
||||
* of_phy_provider_unregister to unregister the phy provider.
|
||||
*/
|
||||
void devm_of_phy_provider_unregister(struct device *dev,
|
||||
struct phy_provider *phy_provider)
|
||||
struct phy_provider *phy_provider)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match,
|
||||
phy_provider);
|
||||
r = devres_release(dev, devm_phy_provider_release, devm_phy_match,
|
||||
phy_provider);
|
||||
dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister);
|
||||
|
||||
@@ -1008,7 +1008,7 @@ static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
|
||||
|
||||
@@ -309,7 +309,7 @@ static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy
|
||||
|
||||
priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk");
|
||||
|
||||
priv->phy_rst = devm_reset_control_array_get_exclusive(dev);
|
||||
priv->phy_rst = devm_reset_control_get(dev, "phy");
|
||||
if (IS_ERR(priv->phy_rst))
|
||||
return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n");
|
||||
|
||||
|
||||
@@ -1116,6 +1116,8 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
|
||||
return dev_err_probe(dev, PTR_ERR(hdptx->grf),
|
||||
"Could not get GRF syscon\n");
|
||||
|
||||
platform_set_drvdata(pdev, hdptx);
|
||||
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
|
||||
@@ -1125,7 +1127,6 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
|
||||
return dev_err_probe(dev, PTR_ERR(hdptx->phy),
|
||||
"Failed to create HDMI PHY\n");
|
||||
|
||||
platform_set_drvdata(pdev, hdptx);
|
||||
phy_set_drvdata(hdptx->phy, hdptx);
|
||||
phy_set_bus_width(hdptx->phy, 8);
|
||||
|
||||
|
||||
@@ -707,7 +707,7 @@ static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = {
|
||||
/* Framework Laptop (12th Gen Intel Core) */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "12th Gen Intel Core"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Laptop (12th Gen Intel Core)"),
|
||||
},
|
||||
.driver_data = (void *)&framework_laptop_mec_lpc_driver_data,
|
||||
},
|
||||
@@ -715,7 +715,7 @@ static const struct dmi_system_id cros_ec_lpc_dmi_table[] __initconst = {
|
||||
/* Framework Laptop (13th Gen Intel Core) */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "13th Gen Intel Core"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Laptop (13th Gen Intel Core)"),
|
||||
},
|
||||
.driver_data = (void *)&framework_laptop_mec_lpc_driver_data,
|
||||
},
|
||||
|
||||
@@ -623,6 +623,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
|
||||
{ KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
|
||||
{ KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
|
||||
{ KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */
|
||||
{ KE_IGNORE, 0xCF, }, /* AC mode */
|
||||
{ KE_KEY, 0xFA, { KEY_PROG2 } }, /* Lid flip action */
|
||||
{ KE_KEY, 0xBD, { KEY_PROG2 } }, /* Lid flip action on ROG xflow laptops */
|
||||
{ KE_END, 0},
|
||||
|
||||
@@ -567,6 +567,7 @@ static int bq24190_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
|
||||
|
||||
static int bq24296_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
|
||||
{
|
||||
union power_supply_propval val = { .intval = bdi->charge_type };
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(bdi->dev);
|
||||
@@ -587,13 +588,18 @@ static int bq24296_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
|
||||
|
||||
ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
|
||||
BQ24296_REG_POC_OTG_CONFIG_MASK,
|
||||
BQ24296_REG_POC_CHG_CONFIG_SHIFT,
|
||||
BQ24296_REG_POC_OTG_CONFIG_SHIFT,
|
||||
BQ24296_REG_POC_OTG_CONFIG_OTG);
|
||||
} else
|
||||
} else {
|
||||
ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
|
||||
BQ24296_REG_POC_OTG_CONFIG_MASK,
|
||||
BQ24296_REG_POC_CHG_CONFIG_SHIFT,
|
||||
BQ24296_REG_POC_OTG_CONFIG_SHIFT,
|
||||
BQ24296_REG_POC_OTG_CONFIG_DISABLE);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = bq24190_charger_set_charge_type(bdi, &val);
|
||||
}
|
||||
|
||||
out:
|
||||
pm_runtime_mark_last_busy(bdi->dev);
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
#include <acpi/battery.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_data/cros_ec_commands.h>
|
||||
#include <linux/platform_data/cros_ec_proto.h>
|
||||
#include <linux/platform_device.h>
|
||||
@@ -49,6 +51,7 @@ struct cros_chctl_priv {
|
||||
struct attribute *attributes[_CROS_CHCTL_ATTR_COUNT];
|
||||
struct attribute_group group;
|
||||
|
||||
struct mutex lock; /* protects fields below and cros_ec */
|
||||
enum power_supply_charge_behaviour current_behaviour;
|
||||
u8 current_start_threshold, current_end_threshold;
|
||||
};
|
||||
@@ -85,6 +88,8 @@ static int cros_chctl_configure_ec(struct cros_chctl_priv *priv)
|
||||
{
|
||||
struct ec_params_charge_control req = {};
|
||||
|
||||
lockdep_assert_held(&priv->lock);
|
||||
|
||||
req.cmd = EC_CHARGE_CONTROL_CMD_SET;
|
||||
|
||||
switch (priv->current_behaviour) {
|
||||
@@ -134,11 +139,15 @@ static ssize_t cros_chctl_store_threshold(struct device *dev, struct cros_chctl_
|
||||
return -EINVAL;
|
||||
|
||||
if (is_end_threshold) {
|
||||
if (val <= priv->current_start_threshold)
|
||||
/* Start threshold is not exposed, use fixed value */
|
||||
if (priv->cmd_version == 2)
|
||||
priv->current_start_threshold = val == 100 ? 0 : val;
|
||||
|
||||
if (val < priv->current_start_threshold)
|
||||
return -EINVAL;
|
||||
priv->current_end_threshold = val;
|
||||
} else {
|
||||
if (val >= priv->current_end_threshold)
|
||||
if (val > priv->current_end_threshold)
|
||||
return -EINVAL;
|
||||
priv->current_start_threshold = val;
|
||||
}
|
||||
@@ -159,6 +168,7 @@ static ssize_t charge_control_start_threshold_show(struct device *dev,
|
||||
struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr,
|
||||
CROS_CHCTL_ATTR_START_THRESHOLD);
|
||||
|
||||
guard(mutex)(&priv->lock);
|
||||
return sysfs_emit(buf, "%u\n", (unsigned int)priv->current_start_threshold);
|
||||
}
|
||||
|
||||
@@ -169,6 +179,7 @@ static ssize_t charge_control_start_threshold_store(struct device *dev,
|
||||
struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr,
|
||||
CROS_CHCTL_ATTR_START_THRESHOLD);
|
||||
|
||||
guard(mutex)(&priv->lock);
|
||||
return cros_chctl_store_threshold(dev, priv, 0, buf, count);
|
||||
}
|
||||
|
||||
@@ -178,6 +189,7 @@ static ssize_t charge_control_end_threshold_show(struct device *dev, struct devi
|
||||
struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr,
|
||||
CROS_CHCTL_ATTR_END_THRESHOLD);
|
||||
|
||||
guard(mutex)(&priv->lock);
|
||||
return sysfs_emit(buf, "%u\n", (unsigned int)priv->current_end_threshold);
|
||||
}
|
||||
|
||||
@@ -187,6 +199,7 @@ static ssize_t charge_control_end_threshold_store(struct device *dev, struct dev
|
||||
struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr,
|
||||
CROS_CHCTL_ATTR_END_THRESHOLD);
|
||||
|
||||
guard(mutex)(&priv->lock);
|
||||
return cros_chctl_store_threshold(dev, priv, 1, buf, count);
|
||||
}
|
||||
|
||||
@@ -195,6 +208,7 @@ static ssize_t charge_behaviour_show(struct device *dev, struct device_attribute
|
||||
struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(&attr->attr,
|
||||
CROS_CHCTL_ATTR_CHARGE_BEHAVIOUR);
|
||||
|
||||
guard(mutex)(&priv->lock);
|
||||
return power_supply_charge_behaviour_show(dev, EC_CHARGE_CONTROL_BEHAVIOURS,
|
||||
priv->current_behaviour, buf);
|
||||
}
|
||||
@@ -210,6 +224,7 @@ static ssize_t charge_behaviour_store(struct device *dev, struct device_attribut
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
guard(mutex)(&priv->lock);
|
||||
priv->current_behaviour = ret;
|
||||
|
||||
ret = cros_chctl_configure_ec(priv);
|
||||
@@ -223,12 +238,10 @@ static umode_t cros_chtl_attr_is_visible(struct kobject *kobj, struct attribute
|
||||
{
|
||||
struct cros_chctl_priv *priv = cros_chctl_attr_to_priv(attr, n);
|
||||
|
||||
if (priv->cmd_version < 2) {
|
||||
if (n == CROS_CHCTL_ATTR_START_THRESHOLD)
|
||||
return 0;
|
||||
if (n == CROS_CHCTL_ATTR_END_THRESHOLD)
|
||||
return 0;
|
||||
}
|
||||
if (n == CROS_CHCTL_ATTR_START_THRESHOLD && priv->cmd_version < 3)
|
||||
return 0;
|
||||
else if (n == CROS_CHCTL_ATTR_END_THRESHOLD && priv->cmd_version < 2)
|
||||
return 0;
|
||||
|
||||
return attr->mode;
|
||||
}
|
||||
@@ -290,6 +303,10 @@ static int cros_chctl_probe(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = devm_mutex_init(dev, &priv->lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cros_ec_get_cmd_versions(cros_ec, EC_CMD_CHARGE_CONTROL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -327,7 +344,8 @@ static int cros_chctl_probe(struct platform_device *pdev)
|
||||
priv->current_end_threshold = 100;
|
||||
|
||||
/* Bring EC into well-known state */
|
||||
ret = cros_chctl_configure_ec(priv);
|
||||
scoped_guard(mutex, &priv->lock)
|
||||
ret = cros_chctl_configure_ec(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -67,6 +67,14 @@ static int set_charge_current_limit(struct gpio_charger *gpio_charger, int val)
|
||||
if (gpio_charger->current_limit_map[i].limit_ua <= val)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a valid charge current limit isn't found, default to smallest
|
||||
* current limitation for safety reasons.
|
||||
*/
|
||||
if (i >= gpio_charger->current_limit_map_size)
|
||||
i = gpio_charger->current_limit_map_size - 1;
|
||||
|
||||
mapping = gpio_charger->current_limit_map[i];
|
||||
|
||||
for (i = 0; i < ndescs; i++) {
|
||||
|
||||
@@ -8907,8 +8907,11 @@ megasas_aen_polling(struct work_struct *work)
|
||||
(ld_target_id / MEGASAS_MAX_DEV_PER_CHANNEL),
|
||||
(ld_target_id % MEGASAS_MAX_DEV_PER_CHANNEL),
|
||||
0);
|
||||
if (sdev1)
|
||||
if (sdev1) {
|
||||
mutex_unlock(&instance->reset_mutex);
|
||||
megasas_remove_scsi_device(sdev1);
|
||||
mutex_lock(&instance->reset_mutex);
|
||||
}
|
||||
|
||||
event_type = SCAN_VD_CHANNEL;
|
||||
break;
|
||||
|
||||
@@ -134,8 +134,6 @@ extern atomic64_t event_counter;
|
||||
|
||||
#define MPI3MR_WATCHDOG_INTERVAL 1000 /* in milli seconds */
|
||||
|
||||
#define MPI3MR_DEFAULT_CFG_PAGE_SZ 1024 /* in bytes */
|
||||
|
||||
#define MPI3MR_RESET_TOPOLOGY_SETTLE_TIME 10
|
||||
|
||||
#define MPI3MR_SCMD_TIMEOUT (60 * HZ)
|
||||
@@ -1133,9 +1131,6 @@ struct scmd_priv {
|
||||
* @io_throttle_low: I/O size to stop throttle in 512b blocks
|
||||
* @num_io_throttle_group: Maximum number of throttle groups
|
||||
* @throttle_groups: Pointer to throttle group info structures
|
||||
* @cfg_page: Default memory for configuration pages
|
||||
* @cfg_page_dma: Configuration page DMA address
|
||||
* @cfg_page_sz: Default configuration page memory size
|
||||
* @sas_transport_enabled: SAS transport enabled or not
|
||||
* @scsi_device_channel: Channel ID for SCSI devices
|
||||
* @transport_cmds: Command tracker for SAS transport commands
|
||||
@@ -1332,10 +1327,6 @@ struct mpi3mr_ioc {
|
||||
u16 num_io_throttle_group;
|
||||
struct mpi3mr_throttle_group_info *throttle_groups;
|
||||
|
||||
void *cfg_page;
|
||||
dma_addr_t cfg_page_dma;
|
||||
u16 cfg_page_sz;
|
||||
|
||||
u8 sas_transport_enabled;
|
||||
u8 scsi_device_channel;
|
||||
struct mpi3mr_drv_cmd transport_cmds;
|
||||
|
||||
@@ -2329,6 +2329,15 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
if (!mrioc)
|
||||
return -ENODEV;
|
||||
|
||||
if (mutex_lock_interruptible(&mrioc->bsg_cmds.mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (mrioc->bsg_cmds.state & MPI3MR_CMD_PENDING) {
|
||||
dprint_bsg_err(mrioc, "%s: command is in use\n", __func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (!mrioc->ioctl_sges_allocated) {
|
||||
dprint_bsg_err(mrioc, "%s: DMA memory was not allocated\n",
|
||||
__func__);
|
||||
@@ -2339,13 +2348,16 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
karg->timeout = MPI3MR_APP_DEFAULT_TIMEOUT;
|
||||
|
||||
mpi_req = kzalloc(MPI3MR_ADMIN_REQ_FRAME_SZ, GFP_KERNEL);
|
||||
if (!mpi_req)
|
||||
if (!mpi_req) {
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mpi_header = (struct mpi3_request_header *)mpi_req;
|
||||
|
||||
bufcnt = karg->buf_entry_list.num_of_entries;
|
||||
drv_bufs = kzalloc((sizeof(*drv_bufs) * bufcnt), GFP_KERNEL);
|
||||
if (!drv_bufs) {
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -2353,6 +2365,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dout_buf = kzalloc(job->request_payload.payload_len,
|
||||
GFP_KERNEL);
|
||||
if (!dout_buf) {
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -2360,6 +2373,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
din_buf = kzalloc(job->reply_payload.payload_len,
|
||||
GFP_KERNEL);
|
||||
if (!din_buf) {
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -2435,6 +2449,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
(mpi_msg_size > MPI3MR_ADMIN_REQ_FRAME_SZ)) {
|
||||
dprint_bsg_err(mrioc, "%s: invalid MPI message size\n",
|
||||
__func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2447,6 +2462,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
if (invalid_be) {
|
||||
dprint_bsg_err(mrioc, "%s: invalid buffer entries passed\n",
|
||||
__func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2454,12 +2470,14 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
if (sgl_dout_iter > (dout_buf + job->request_payload.payload_len)) {
|
||||
dprint_bsg_err(mrioc, "%s: data_out buffer length mismatch\n",
|
||||
__func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (sgl_din_iter > (din_buf + job->reply_payload.payload_len)) {
|
||||
dprint_bsg_err(mrioc, "%s: data_in buffer length mismatch\n",
|
||||
__func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2472,6 +2490,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dprint_bsg_err(mrioc, "%s:%d: invalid data transfer size passed for function 0x%x din_size = %d, dout_size = %d\n",
|
||||
__func__, __LINE__, mpi_header->function, din_size,
|
||||
dout_size);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2480,6 +2499,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dprint_bsg_err(mrioc,
|
||||
"%s:%d: invalid data transfer size passed for function 0x%x din_size=%d\n",
|
||||
__func__, __LINE__, mpi_header->function, din_size);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2487,6 +2507,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dprint_bsg_err(mrioc,
|
||||
"%s:%d: invalid data transfer size passed for function 0x%x dout_size = %d\n",
|
||||
__func__, __LINE__, mpi_header->function, dout_size);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2497,6 +2518,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dprint_bsg_err(mrioc, "%s:%d: invalid message size passed:%d:%d:%d:%d\n",
|
||||
__func__, __LINE__, din_cnt, dout_cnt, din_size,
|
||||
dout_size);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2544,6 +2566,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
continue;
|
||||
if (mpi3mr_map_data_buffer_dma(mrioc, drv_buf_iter, desc_count)) {
|
||||
rval = -ENOMEM;
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
dprint_bsg_err(mrioc, "%s:%d: mapping data buffers failed\n",
|
||||
__func__, __LINE__);
|
||||
goto out;
|
||||
@@ -2556,20 +2579,11 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
sense_buff_k = kzalloc(erbsz, GFP_KERNEL);
|
||||
if (!sense_buff_k) {
|
||||
rval = -ENOMEM;
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (mutex_lock_interruptible(&mrioc->bsg_cmds.mutex)) {
|
||||
rval = -ERESTARTSYS;
|
||||
goto out;
|
||||
}
|
||||
if (mrioc->bsg_cmds.state & MPI3MR_CMD_PENDING) {
|
||||
rval = -EAGAIN;
|
||||
dprint_bsg_err(mrioc, "%s: command is in use\n", __func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
goto out;
|
||||
}
|
||||
if (mrioc->unrecoverable) {
|
||||
dprint_bsg_err(mrioc, "%s: unrecoverable controller\n",
|
||||
__func__);
|
||||
|
||||
@@ -1035,6 +1035,36 @@ static const char *mpi3mr_reset_type_name(u16 reset_type)
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpi3mr_is_fault_recoverable - Read fault code and decide
|
||||
* whether the controller can be recoverable
|
||||
* @mrioc: Adapter instance reference
|
||||
* Return: true if fault is recoverable, false otherwise.
|
||||
*/
|
||||
static inline bool mpi3mr_is_fault_recoverable(struct mpi3mr_ioc *mrioc)
|
||||
{
|
||||
u32 fault;
|
||||
|
||||
fault = (readl(&mrioc->sysif_regs->fault) &
|
||||
MPI3_SYSIF_FAULT_CODE_MASK);
|
||||
|
||||
switch (fault) {
|
||||
case MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED:
|
||||
case MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED:
|
||||
ioc_warn(mrioc,
|
||||
"controller requires system power cycle, marking controller as unrecoverable\n");
|
||||
return false;
|
||||
case MPI3_SYSIF_FAULT_CODE_INSUFFICIENT_PCI_SLOT_POWER:
|
||||
ioc_warn(mrioc,
|
||||
"controller faulted due to insufficient power,\n"
|
||||
" try by connecting it to a different slot\n");
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpi3mr_print_fault_info - Display fault information
|
||||
* @mrioc: Adapter instance reference
|
||||
@@ -1373,6 +1403,11 @@ retry_bring_ioc_ready:
|
||||
ioc_info(mrioc, "ioc_status(0x%08x), ioc_config(0x%08x), ioc_info(0x%016llx) at the bringup\n",
|
||||
ioc_status, ioc_config, base_info);
|
||||
|
||||
if (!mpi3mr_is_fault_recoverable(mrioc)) {
|
||||
mrioc->unrecoverable = 1;
|
||||
goto out_device_not_present;
|
||||
}
|
||||
|
||||
/*The timeout value is in 2sec unit, changing it to seconds*/
|
||||
mrioc->ready_timeout =
|
||||
((base_info & MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_MASK) >>
|
||||
@@ -2734,6 +2769,11 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
|
||||
mpi3mr_print_fault_info(mrioc);
|
||||
mrioc->diagsave_timeout = 0;
|
||||
|
||||
if (!mpi3mr_is_fault_recoverable(mrioc)) {
|
||||
mrioc->unrecoverable = 1;
|
||||
goto schedule_work;
|
||||
}
|
||||
|
||||
switch (trigger_data.fault) {
|
||||
case MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED:
|
||||
case MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED:
|
||||
@@ -4186,17 +4226,6 @@ retry_init:
|
||||
mpi3mr_read_tsu_interval(mrioc);
|
||||
mpi3mr_print_ioc_info(mrioc);
|
||||
|
||||
if (!mrioc->cfg_page) {
|
||||
dprint_init(mrioc, "allocating config page buffers\n");
|
||||
mrioc->cfg_page_sz = MPI3MR_DEFAULT_CFG_PAGE_SZ;
|
||||
mrioc->cfg_page = dma_alloc_coherent(&mrioc->pdev->dev,
|
||||
mrioc->cfg_page_sz, &mrioc->cfg_page_dma, GFP_KERNEL);
|
||||
if (!mrioc->cfg_page) {
|
||||
retval = -1;
|
||||
goto out_failed_noretry;
|
||||
}
|
||||
}
|
||||
|
||||
dprint_init(mrioc, "allocating host diag buffers\n");
|
||||
mpi3mr_alloc_diag_bufs(mrioc);
|
||||
|
||||
@@ -4768,11 +4797,7 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
|
||||
mrioc->admin_req_base, mrioc->admin_req_dma);
|
||||
mrioc->admin_req_base = NULL;
|
||||
}
|
||||
if (mrioc->cfg_page) {
|
||||
dma_free_coherent(&mrioc->pdev->dev, mrioc->cfg_page_sz,
|
||||
mrioc->cfg_page, mrioc->cfg_page_dma);
|
||||
mrioc->cfg_page = NULL;
|
||||
}
|
||||
|
||||
if (mrioc->pel_seqnum_virt) {
|
||||
dma_free_coherent(&mrioc->pdev->dev, mrioc->pel_seqnum_sz,
|
||||
mrioc->pel_seqnum_virt, mrioc->pel_seqnum_dma);
|
||||
@@ -5392,55 +5417,6 @@ out:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mpi3mr_free_config_dma_memory - free memory for config page
|
||||
* @mrioc: Adapter instance reference
|
||||
* @mem_desc: memory descriptor structure
|
||||
*
|
||||
* Check whether the size of the buffer specified by the memory
|
||||
* descriptor is greater than the default page size if so then
|
||||
* free the memory pointed by the descriptor.
|
||||
*
|
||||
* Return: Nothing.
|
||||
*/
|
||||
static void mpi3mr_free_config_dma_memory(struct mpi3mr_ioc *mrioc,
|
||||
struct dma_memory_desc *mem_desc)
|
||||
{
|
||||
if ((mem_desc->size > mrioc->cfg_page_sz) && mem_desc->addr) {
|
||||
dma_free_coherent(&mrioc->pdev->dev, mem_desc->size,
|
||||
mem_desc->addr, mem_desc->dma_addr);
|
||||
mem_desc->addr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mpi3mr_alloc_config_dma_memory - Alloc memory for config page
|
||||
* @mrioc: Adapter instance reference
|
||||
* @mem_desc: Memory descriptor to hold dma memory info
|
||||
*
|
||||
* This function allocates new dmaable memory or provides the
|
||||
* default config page dmaable memory based on the memory size
|
||||
* described by the descriptor.
|
||||
*
|
||||
* Return: 0 on success, non-zero on failure.
|
||||
*/
|
||||
static int mpi3mr_alloc_config_dma_memory(struct mpi3mr_ioc *mrioc,
|
||||
struct dma_memory_desc *mem_desc)
|
||||
{
|
||||
if (mem_desc->size > mrioc->cfg_page_sz) {
|
||||
mem_desc->addr = dma_alloc_coherent(&mrioc->pdev->dev,
|
||||
mem_desc->size, &mem_desc->dma_addr, GFP_KERNEL);
|
||||
if (!mem_desc->addr)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
mem_desc->addr = mrioc->cfg_page;
|
||||
mem_desc->dma_addr = mrioc->cfg_page_dma;
|
||||
memset(mem_desc->addr, 0, mrioc->cfg_page_sz);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpi3mr_post_cfg_req - Issue config requests and wait
|
||||
* @mrioc: Adapter instance reference
|
||||
@@ -5596,8 +5572,12 @@ static int mpi3mr_process_cfg_req(struct mpi3mr_ioc *mrioc,
|
||||
cfg_req->page_length = cfg_hdr->page_length;
|
||||
cfg_req->page_version = cfg_hdr->page_version;
|
||||
}
|
||||
if (mpi3mr_alloc_config_dma_memory(mrioc, &mem_desc))
|
||||
goto out;
|
||||
|
||||
mem_desc.addr = dma_alloc_coherent(&mrioc->pdev->dev,
|
||||
mem_desc.size, &mem_desc.dma_addr, GFP_KERNEL);
|
||||
|
||||
if (!mem_desc.addr)
|
||||
return retval;
|
||||
|
||||
mpi3mr_add_sg_single(&cfg_req->sgl, sgl_flags, mem_desc.size,
|
||||
mem_desc.dma_addr);
|
||||
@@ -5626,7 +5606,12 @@ static int mpi3mr_process_cfg_req(struct mpi3mr_ioc *mrioc,
|
||||
}
|
||||
|
||||
out:
|
||||
mpi3mr_free_config_dma_memory(mrioc, &mem_desc);
|
||||
if (mem_desc.addr) {
|
||||
dma_free_coherent(&mrioc->pdev->dev, mem_desc.size,
|
||||
mem_desc.addr, mem_desc.dma_addr);
|
||||
mem_desc.addr = NULL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -5215,7 +5215,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
}
|
||||
|
||||
mrioc = shost_priv(shost);
|
||||
retval = ida_alloc_range(&mrioc_ida, 1, U8_MAX, GFP_KERNEL);
|
||||
retval = ida_alloc_range(&mrioc_ida, 0, U8_MAX, GFP_KERNEL);
|
||||
if (retval < 0)
|
||||
goto id_alloc_failed;
|
||||
mrioc->id = (u8)retval;
|
||||
|
||||
@@ -7041,11 +7041,12 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes,
|
||||
int i;
|
||||
u8 failed;
|
||||
__le32 *mfp;
|
||||
int ret_val;
|
||||
|
||||
/* make sure doorbell is not in use */
|
||||
if ((ioc->base_readl_ext_retry(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) {
|
||||
ioc_err(ioc, "doorbell is in use (line=%d)\n", __LINE__);
|
||||
return -EFAULT;
|
||||
goto doorbell_diag_reset;
|
||||
}
|
||||
|
||||
/* clear pending doorbell interrupts from previous state changes */
|
||||
@@ -7135,6 +7136,10 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes,
|
||||
le32_to_cpu(mfp[i]));
|
||||
}
|
||||
return 0;
|
||||
|
||||
doorbell_diag_reset:
|
||||
ret_val = _base_diag_reset(ioc);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -116,12 +116,12 @@ struct device_reg {
|
||||
uint16_t id_h; /* ID high */
|
||||
uint16_t cfg_0; /* Configuration 0 */
|
||||
#define ISP_CFG0_HWMSK 0x000f /* Hardware revision mask */
|
||||
#define ISP_CFG0_1020 BIT_0 /* ISP1020 */
|
||||
#define ISP_CFG0_1020A BIT_1 /* ISP1020A */
|
||||
#define ISP_CFG0_1040 BIT_2 /* ISP1040 */
|
||||
#define ISP_CFG0_1040A BIT_3 /* ISP1040A */
|
||||
#define ISP_CFG0_1040B BIT_4 /* ISP1040B */
|
||||
#define ISP_CFG0_1040C BIT_5 /* ISP1040C */
|
||||
#define ISP_CFG0_1020 1 /* ISP1020 */
|
||||
#define ISP_CFG0_1020A 2 /* ISP1020A */
|
||||
#define ISP_CFG0_1040 3 /* ISP1040 */
|
||||
#define ISP_CFG0_1040A 4 /* ISP1040A */
|
||||
#define ISP_CFG0_1040B 5 /* ISP1040B */
|
||||
#define ISP_CFG0_1040C 6 /* ISP1040C */
|
||||
uint16_t cfg_1; /* Configuration 1 */
|
||||
#define ISP_CFG1_F128 BIT_6 /* 128-byte FIFO threshold */
|
||||
#define ISP_CFG1_F64 BIT_4|BIT_5 /* 128-byte FIFO threshold */
|
||||
|
||||
@@ -149,6 +149,8 @@ struct hv_fc_wwn_packet {
|
||||
*/
|
||||
static int vmstor_proto_version;
|
||||
|
||||
static bool hv_dev_is_fc(struct hv_device *hv_dev);
|
||||
|
||||
#define STORVSC_LOGGING_NONE 0
|
||||
#define STORVSC_LOGGING_ERROR 1
|
||||
#define STORVSC_LOGGING_WARN 2
|
||||
@@ -1138,6 +1140,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
|
||||
* not correctly handle:
|
||||
* INQUIRY command with page code parameter set to 0x80
|
||||
* MODE_SENSE command with cmd[2] == 0x1c
|
||||
* MAINTENANCE_IN is not supported by HyperV FC passthrough
|
||||
*
|
||||
* Setup srb and scsi status so this won't be fatal.
|
||||
* We do this so we can distinguish truly fatal failues
|
||||
@@ -1145,7 +1148,9 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
|
||||
*/
|
||||
|
||||
if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
|
||||
(stor_pkt->vm_srb.cdb[0] == MODE_SENSE)) {
|
||||
(stor_pkt->vm_srb.cdb[0] == MODE_SENSE) ||
|
||||
(stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN &&
|
||||
hv_dev_is_fc(device))) {
|
||||
vstor_packet->vm_srb.scsi_status = 0;
|
||||
vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,8 @@ static const struct pci_device_id intel_spi_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa823), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xe323), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xe423), (unsigned long)&cnl_info },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);
|
||||
|
||||
@@ -1561,10 +1561,10 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
mcspi->ref_clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
|
||||
if (mcspi->ref_clk)
|
||||
mcspi->ref_clk_hz = clk_get_rate(mcspi->ref_clk);
|
||||
else
|
||||
if (IS_ERR(mcspi->ref_clk))
|
||||
mcspi->ref_clk_hz = OMAP2_MCSPI_MAX_FREQ;
|
||||
else
|
||||
mcspi->ref_clk_hz = clk_get_rate(mcspi->ref_clk);
|
||||
ctlr->max_speed_hz = mcspi->ref_clk_hz;
|
||||
ctlr->min_speed_hz = mcspi->ref_clk_hz >> 15;
|
||||
|
||||
|
||||
@@ -124,10 +124,8 @@ static void *alloc_quote_buf(void)
|
||||
if (!addr)
|
||||
return NULL;
|
||||
|
||||
if (set_memory_decrypted((unsigned long)addr, count)) {
|
||||
free_pages_exact(addr, len);
|
||||
if (set_memory_decrypted((unsigned long)addr, count))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -549,6 +549,7 @@ config S3C2410_WATCHDOG
|
||||
tristate "S3C6410/S5Pv210/Exynos Watchdog"
|
||||
depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
|
||||
select WATCHDOG_CORE
|
||||
select MFD_SYSCON if ARCH_EXYNOS
|
||||
help
|
||||
Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
|
||||
SoCs. This will reboot the system when the timer expires with
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -40,6 +42,7 @@
|
||||
#define VAL 0x2f
|
||||
|
||||
/* Logical device Numbers LDN */
|
||||
#define EC 0x04
|
||||
#define GPIO 0x07
|
||||
|
||||
/* Configuration Registers and Functions */
|
||||
@@ -73,6 +76,12 @@
|
||||
#define IT8784_ID 0x8784
|
||||
#define IT8786_ID 0x8786
|
||||
|
||||
/* Environment Controller Configuration Registers LDN=0x04 */
|
||||
#define SCR1 0xfa
|
||||
|
||||
/* Environment Controller Bits SCR1 */
|
||||
#define WDT_PWRGD 0x20
|
||||
|
||||
/* GPIO Configuration Registers LDN=0x07 */
|
||||
#define WDTCTRL 0x71
|
||||
#define WDTCFG 0x72
|
||||
@@ -240,6 +249,21 @@ static int wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
|
||||
return ret;
|
||||
}
|
||||
|
||||
enum {
|
||||
IT87_WDT_OUTPUT_THROUGH_PWRGD = BIT(0),
|
||||
};
|
||||
|
||||
static const struct dmi_system_id it87_quirks[] = {
|
||||
{
|
||||
/* Qotom Q30900P (IT8786) */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "QCML04"),
|
||||
},
|
||||
.driver_data = (void *)IT87_WDT_OUTPUT_THROUGH_PWRGD,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct watchdog_info ident = {
|
||||
.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
|
||||
.firmware_version = 1,
|
||||
@@ -261,8 +285,10 @@ static struct watchdog_device wdt_dev = {
|
||||
|
||||
static int __init it87_wdt_init(void)
|
||||
{
|
||||
const struct dmi_system_id *dmi_id;
|
||||
u8 chip_rev;
|
||||
u8 ctrl;
|
||||
int quirks = 0;
|
||||
int rc;
|
||||
|
||||
rc = superio_enter();
|
||||
@@ -273,6 +299,10 @@ static int __init it87_wdt_init(void)
|
||||
chip_rev = superio_inb(CHIPREV) & 0x0f;
|
||||
superio_exit();
|
||||
|
||||
dmi_id = dmi_first_match(it87_quirks);
|
||||
if (dmi_id)
|
||||
quirks = (long)dmi_id->driver_data;
|
||||
|
||||
switch (chip_type) {
|
||||
case IT8702_ID:
|
||||
max_units = 255;
|
||||
@@ -333,6 +363,15 @@ static int __init it87_wdt_init(void)
|
||||
superio_outb(0x00, WDTCTRL);
|
||||
}
|
||||
|
||||
if (quirks & IT87_WDT_OUTPUT_THROUGH_PWRGD) {
|
||||
superio_select(EC);
|
||||
ctrl = superio_inb(SCR1);
|
||||
if (!(ctrl & WDT_PWRGD)) {
|
||||
ctrl |= WDT_PWRGD;
|
||||
superio_outb(ctrl, SCR1);
|
||||
}
|
||||
}
|
||||
|
||||
superio_exit();
|
||||
|
||||
if (timeout < 1 || timeout > max_units * 60) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <dt-bindings/reset/mt2712-resets.h>
|
||||
#include <dt-bindings/reset/mediatek,mt6735-wdt.h>
|
||||
#include <dt-bindings/reset/mediatek,mt6795-resets.h>
|
||||
#include <dt-bindings/reset/mt7986-resets.h>
|
||||
#include <dt-bindings/reset/mt8183-resets.h>
|
||||
@@ -87,6 +88,10 @@ static const struct mtk_wdt_data mt2712_data = {
|
||||
.toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
|
||||
};
|
||||
|
||||
static const struct mtk_wdt_data mt6735_data = {
|
||||
.toprgu_sw_rst_num = MT6735_TOPRGU_RST_NUM,
|
||||
};
|
||||
|
||||
static const struct mtk_wdt_data mt6795_data = {
|
||||
.toprgu_sw_rst_num = MT6795_TOPRGU_SW_RST_NUM,
|
||||
};
|
||||
@@ -489,6 +494,7 @@ static int mtk_wdt_resume(struct device *dev)
|
||||
static const struct of_device_id mtk_wdt_dt_ids[] = {
|
||||
{ .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
|
||||
{ .compatible = "mediatek,mt6589-wdt" },
|
||||
{ .compatible = "mediatek,mt6735-wdt", .data = &mt6735_data },
|
||||
{ .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data },
|
||||
{ .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
|
||||
{ .compatible = "mediatek,mt7988-wdt", .data = &mt7988_data },
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/units.h>
|
||||
@@ -166,8 +167,22 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev,
|
||||
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||
int ret;
|
||||
|
||||
clk_prepare_enable(priv->pclk);
|
||||
clk_prepare_enable(priv->osc_clk);
|
||||
/*
|
||||
* In case of RZ/G3S the watchdog device may be part of an IRQ safe power
|
||||
* domain that is currently powered off. In this case we need to power
|
||||
* it on before accessing registers. Along with this the clocks will be
|
||||
* enabled. We don't undo the pm_runtime_resume_and_get() as the device
|
||||
* need to be on for the reboot to happen.
|
||||
*
|
||||
* For the rest of SoCs not registering a watchdog IRQ safe power
|
||||
* domain it is safe to call pm_runtime_resume_and_get() as the
|
||||
* irq_safe_dev_in_sleep_domain() call in genpd_runtime_resume()
|
||||
* returns non zero value and the genpd_lock() is avoided, thus, there
|
||||
* will be no invalid wait context reported by lockdep.
|
||||
*/
|
||||
ret = pm_runtime_resume_and_get(wdev->parent);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (priv->devtype == WDT_RZG2L) {
|
||||
ret = reset_control_deassert(priv->rstc);
|
||||
@@ -275,6 +290,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
|
||||
|
||||
priv->devtype = (uintptr_t)of_device_get_match_data(dev);
|
||||
|
||||
pm_runtime_irq_safe(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
priv->wdev.info = &rzg2l_wdt_ident;
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/soc/samsung/exynos-pmu.h>
|
||||
|
||||
#define S3C2410_WTCON 0x00
|
||||
#define S3C2410_WTDAT 0x04
|
||||
@@ -699,11 +699,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
|
||||
if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
|
||||
wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
|
||||
"samsung,syscon-phandle");
|
||||
wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
"samsung,syscon-phandle");
|
||||
if (IS_ERR(wdt->pmureg))
|
||||
return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
|
||||
"PMU regmap lookup failed.\n");
|
||||
"syscon regmap lookup failed.\n");
|
||||
}
|
||||
|
||||
wdt_irq = platform_get_irq(pdev, 0);
|
||||
|
||||
+4
-7
@@ -654,6 +654,8 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
|
||||
goto error_unlock_cow;
|
||||
}
|
||||
}
|
||||
|
||||
trace_btrfs_cow_block(root, buf, cow);
|
||||
if (unlock_orig)
|
||||
btrfs_tree_unlock(buf);
|
||||
free_extent_buffer_stale(buf);
|
||||
@@ -710,7 +712,6 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
u64 search_start;
|
||||
int ret;
|
||||
|
||||
if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) {
|
||||
btrfs_abort_transaction(trans, -EUCLEAN);
|
||||
@@ -751,12 +752,8 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
* Also We don't care about the error, as it's handled internally.
|
||||
*/
|
||||
btrfs_qgroup_trace_subtree_after_cow(trans, root, buf);
|
||||
ret = btrfs_force_cow_block(trans, root, buf, parent, parent_slot,
|
||||
cow_ret, search_start, 0, nest);
|
||||
|
||||
trace_btrfs_cow_block(root, buf, *cow_ret);
|
||||
|
||||
return ret;
|
||||
return btrfs_force_cow_block(trans, root, buf, parent, parent_slot,
|
||||
cow_ret, search_start, 0, nest);
|
||||
}
|
||||
ALLOW_ERROR_INJECTION(btrfs_cow_block, ERRNO);
|
||||
|
||||
|
||||
+95
-34
@@ -7117,6 +7117,8 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
if (file_extent)
|
||||
@@ -9780,15 +9782,25 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
|
||||
struct extent_state *cached_state = NULL;
|
||||
struct extent_map *em = NULL;
|
||||
struct btrfs_chunk_map *map = NULL;
|
||||
struct btrfs_device *device = NULL;
|
||||
struct btrfs_swap_info bsi = {
|
||||
.lowest_ppage = (sector_t)-1ULL,
|
||||
};
|
||||
struct btrfs_backref_share_check_ctx *backref_ctx = NULL;
|
||||
struct btrfs_path *path = NULL;
|
||||
int ret = 0;
|
||||
u64 isize;
|
||||
u64 start;
|
||||
u64 prev_extent_end = 0;
|
||||
|
||||
/*
|
||||
* Acquire the inode's mmap lock to prevent races with memory mapped
|
||||
* writes, as they could happen after we flush delalloc below and before
|
||||
* we lock the extent range further below. The inode was already locked
|
||||
* up in the call chain.
|
||||
*/
|
||||
btrfs_assert_inode_locked(BTRFS_I(inode));
|
||||
down_write(&BTRFS_I(inode)->i_mmap_lock);
|
||||
|
||||
/*
|
||||
* If the swap file was just created, make sure delalloc is done. If the
|
||||
@@ -9797,22 +9809,32 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
|
||||
*/
|
||||
ret = btrfs_wait_ordered_range(BTRFS_I(inode), 0, (u64)-1);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_unlock_mmap;
|
||||
|
||||
/*
|
||||
* The inode is locked, so these flags won't change after we check them.
|
||||
*/
|
||||
if (BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS) {
|
||||
btrfs_warn(fs_info, "swapfile must not be compressed");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto out_unlock_mmap;
|
||||
}
|
||||
if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW)) {
|
||||
btrfs_warn(fs_info, "swapfile must not be copy-on-write");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto out_unlock_mmap;
|
||||
}
|
||||
if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
|
||||
btrfs_warn(fs_info, "swapfile must not be checksummed");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto out_unlock_mmap;
|
||||
}
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
backref_ctx = btrfs_alloc_backref_share_check_ctx();
|
||||
if (!path || !backref_ctx) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unlock_mmap;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9827,7 +9849,8 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
|
||||
if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_SWAP_ACTIVATE)) {
|
||||
btrfs_warn(fs_info,
|
||||
"cannot activate swapfile while exclusive operation is running");
|
||||
return -EBUSY;
|
||||
ret = -EBUSY;
|
||||
goto out_unlock_mmap;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9841,7 +9864,8 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
|
||||
btrfs_exclop_finish(fs_info);
|
||||
btrfs_warn(fs_info,
|
||||
"cannot activate swapfile because snapshot creation is in progress");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto out_unlock_mmap;
|
||||
}
|
||||
/*
|
||||
* Snapshots can create extents which require COW even if NODATACOW is
|
||||
@@ -9862,7 +9886,8 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
|
||||
btrfs_warn(fs_info,
|
||||
"cannot activate swapfile because subvolume %llu is being deleted",
|
||||
btrfs_root_id(root));
|
||||
return -EPERM;
|
||||
ret = -EPERM;
|
||||
goto out_unlock_mmap;
|
||||
}
|
||||
atomic_inc(&root->nr_swapfiles);
|
||||
spin_unlock(&root->root_item_lock);
|
||||
@@ -9870,24 +9895,39 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
|
||||
isize = ALIGN_DOWN(inode->i_size, fs_info->sectorsize);
|
||||
|
||||
lock_extent(io_tree, 0, isize - 1, &cached_state);
|
||||
start = 0;
|
||||
while (start < isize) {
|
||||
u64 logical_block_start, physical_block_start;
|
||||
while (prev_extent_end < isize) {
|
||||
struct btrfs_key key;
|
||||
struct extent_buffer *leaf;
|
||||
struct btrfs_file_extent_item *ei;
|
||||
struct btrfs_block_group *bg;
|
||||
u64 len = isize - start;
|
||||
u64 logical_block_start;
|
||||
u64 physical_block_start;
|
||||
u64 extent_gen;
|
||||
u64 disk_bytenr;
|
||||
u64 len;
|
||||
|
||||
em = btrfs_get_extent(BTRFS_I(inode), NULL, start, len);
|
||||
if (IS_ERR(em)) {
|
||||
ret = PTR_ERR(em);
|
||||
key.objectid = btrfs_ino(BTRFS_I(inode));
|
||||
key.type = BTRFS_EXTENT_DATA_KEY;
|
||||
key.offset = prev_extent_end;
|
||||
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (em->disk_bytenr == EXTENT_MAP_HOLE) {
|
||||
/*
|
||||
* If key not found it means we have an implicit hole (NO_HOLES
|
||||
* is enabled).
|
||||
*/
|
||||
if (ret > 0) {
|
||||
btrfs_warn(fs_info, "swapfile must not have holes");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (em->disk_bytenr == EXTENT_MAP_INLINE) {
|
||||
|
||||
leaf = path->nodes[0];
|
||||
ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
|
||||
|
||||
if (btrfs_file_extent_type(leaf, ei) == BTRFS_FILE_EXTENT_INLINE) {
|
||||
/*
|
||||
* It's unlikely we'll ever actually find ourselves
|
||||
* here, as a file small enough to fit inline won't be
|
||||
@@ -9899,23 +9939,45 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (extent_map_is_compressed(em)) {
|
||||
|
||||
if (btrfs_file_extent_compression(leaf, ei) != BTRFS_COMPRESS_NONE) {
|
||||
btrfs_warn(fs_info, "swapfile must not be compressed");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
logical_block_start = extent_map_block_start(em) + (start - em->start);
|
||||
len = min(len, em->len - (start - em->start));
|
||||
free_extent_map(em);
|
||||
em = NULL;
|
||||
disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, ei);
|
||||
if (disk_bytenr == 0) {
|
||||
btrfs_warn(fs_info, "swapfile must not have holes");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = can_nocow_extent(inode, start, &len, NULL, false, true);
|
||||
logical_block_start = disk_bytenr + btrfs_file_extent_offset(leaf, ei);
|
||||
extent_gen = btrfs_file_extent_generation(leaf, ei);
|
||||
prev_extent_end = btrfs_file_extent_end(path);
|
||||
|
||||
if (prev_extent_end > isize)
|
||||
len = isize - key.offset;
|
||||
else
|
||||
len = btrfs_file_extent_num_bytes(leaf, ei);
|
||||
|
||||
backref_ctx->curr_leaf_bytenr = leaf->start;
|
||||
|
||||
/*
|
||||
* Don't need the path anymore, release to avoid deadlocks when
|
||||
* calling btrfs_is_data_extent_shared() because when joining a
|
||||
* transaction it can block waiting for the current one's commit
|
||||
* which in turn may be trying to lock the same leaf to flush
|
||||
* delayed items for example.
|
||||
*/
|
||||
btrfs_release_path(path);
|
||||
|
||||
ret = btrfs_is_data_extent_shared(BTRFS_I(inode), disk_bytenr,
|
||||
extent_gen, backref_ctx);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
} else if (ret) {
|
||||
ret = 0;
|
||||
} else {
|
||||
} else if (ret > 0) {
|
||||
btrfs_warn(fs_info,
|
||||
"swapfile must not be copy-on-write");
|
||||
ret = -EINVAL;
|
||||
@@ -9950,7 +10012,6 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
|
||||
|
||||
physical_block_start = (map->stripes[0].physical +
|
||||
(logical_block_start - map->start));
|
||||
len = min(len, map->chunk_len - (logical_block_start - map->start));
|
||||
btrfs_free_chunk_map(map);
|
||||
map = NULL;
|
||||
|
||||
@@ -9991,20 +10052,16 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
bsi.start = start;
|
||||
bsi.start = key.offset;
|
||||
bsi.block_start = physical_block_start;
|
||||
bsi.block_len = len;
|
||||
}
|
||||
|
||||
start += len;
|
||||
}
|
||||
|
||||
if (bsi.block_len)
|
||||
ret = btrfs_add_swap_extent(sis, &bsi);
|
||||
|
||||
out:
|
||||
if (!IS_ERR_OR_NULL(em))
|
||||
free_extent_map(em);
|
||||
if (!IS_ERR_OR_NULL(map))
|
||||
btrfs_free_chunk_map(map);
|
||||
|
||||
@@ -10017,6 +10074,10 @@ out:
|
||||
|
||||
btrfs_exclop_finish(fs_info);
|
||||
|
||||
out_unlock_mmap:
|
||||
up_write(&BTRFS_I(inode)->i_mmap_lock);
|
||||
btrfs_free_backref_share_ctx(backref_ctx);
|
||||
btrfs_free_path(path);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
+1
-2
@@ -1122,6 +1122,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info,
|
||||
fs_info->qgroup_flags = BTRFS_QGROUP_STATUS_FLAG_ON;
|
||||
if (simple) {
|
||||
fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE;
|
||||
btrfs_set_fs_incompat(fs_info, SIMPLE_QUOTA);
|
||||
btrfs_set_qgroup_status_enable_gen(leaf, ptr, trans->transid);
|
||||
} else {
|
||||
fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
|
||||
@@ -1255,8 +1256,6 @@ out_add_root:
|
||||
spin_lock(&fs_info->qgroup_lock);
|
||||
fs_info->quota_root = quota_root;
|
||||
set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
|
||||
if (simple)
|
||||
btrfs_set_fs_incompat(fs_info, SIMPLE_QUOTA);
|
||||
spin_unlock(&fs_info->qgroup_lock);
|
||||
|
||||
/* Skip rescan for simple qgroups. */
|
||||
|
||||
@@ -2902,6 +2902,7 @@ static int relocate_one_folio(struct reloc_control *rc,
|
||||
const bool use_rst = btrfs_need_stripe_tree_update(fs_info, rc->block_group->flags);
|
||||
|
||||
ASSERT(index <= last_index);
|
||||
again:
|
||||
folio = filemap_lock_folio(inode->i_mapping, index);
|
||||
if (IS_ERR(folio)) {
|
||||
|
||||
@@ -2937,6 +2938,11 @@ static int relocate_one_folio(struct reloc_control *rc,
|
||||
ret = -EIO;
|
||||
goto release_folio;
|
||||
}
|
||||
if (folio->mapping != inode->i_mapping) {
|
||||
folio_unlock(folio);
|
||||
folio_put(folio);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -5291,6 +5291,7 @@ static int put_file_data(struct send_ctx *sctx, u64 offset, u32 len)
|
||||
unsigned cur_len = min_t(unsigned, len,
|
||||
PAGE_SIZE - pg_offset);
|
||||
|
||||
again:
|
||||
folio = filemap_lock_folio(mapping, index);
|
||||
if (IS_ERR(folio)) {
|
||||
page_cache_sync_readahead(mapping,
|
||||
@@ -5323,6 +5324,11 @@ static int put_file_data(struct send_ctx *sctx, u64 offset, u32 len)
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
if (folio->mapping != mapping) {
|
||||
folio_unlock(folio);
|
||||
folio_put(folio);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy_from_folio(sctx->send_buf + sctx->send_size, folio,
|
||||
|
||||
+3
-3
@@ -1118,7 +1118,7 @@ static ssize_t btrfs_nodesize_show(struct kobject *kobj,
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = to_fs_info(kobj);
|
||||
|
||||
return sysfs_emit(buf, "%u\n", fs_info->super_copy->nodesize);
|
||||
return sysfs_emit(buf, "%u\n", fs_info->nodesize);
|
||||
}
|
||||
|
||||
BTRFS_ATTR(, nodesize, btrfs_nodesize_show);
|
||||
@@ -1128,7 +1128,7 @@ static ssize_t btrfs_sectorsize_show(struct kobject *kobj,
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = to_fs_info(kobj);
|
||||
|
||||
return sysfs_emit(buf, "%u\n", fs_info->super_copy->sectorsize);
|
||||
return sysfs_emit(buf, "%u\n", fs_info->sectorsize);
|
||||
}
|
||||
|
||||
BTRFS_ATTR(, sectorsize, btrfs_sectorsize_show);
|
||||
@@ -1180,7 +1180,7 @@ static ssize_t btrfs_clone_alignment_show(struct kobject *kobj,
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = to_fs_info(kobj);
|
||||
|
||||
return sysfs_emit(buf, "%u\n", fs_info->super_copy->sectorsize);
|
||||
return sysfs_emit(buf, "%u\n", fs_info->sectorsize);
|
||||
}
|
||||
|
||||
BTRFS_ATTR(, clone_alignment, btrfs_clone_alignment_show);
|
||||
|
||||
+1
-1
@@ -1552,7 +1552,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
|
||||
}
|
||||
|
||||
op = &req->r_ops[0];
|
||||
if (sparse) {
|
||||
if (!write && sparse) {
|
||||
extent_cnt = __ceph_sparse_read_ext_count(inode, size);
|
||||
ret = ceph_alloc_sparse_ext_map(op, extent_cnt);
|
||||
if (ret) {
|
||||
|
||||
+6
-25
@@ -40,24 +40,15 @@
|
||||
#define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
|
||||
#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
|
||||
|
||||
static void expkey_put_work(struct work_struct *work)
|
||||
static void expkey_put(struct kref *ref)
|
||||
{
|
||||
struct svc_expkey *key =
|
||||
container_of(to_rcu_work(work), struct svc_expkey, ek_rcu_work);
|
||||
struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
|
||||
|
||||
if (test_bit(CACHE_VALID, &key->h.flags) &&
|
||||
!test_bit(CACHE_NEGATIVE, &key->h.flags))
|
||||
path_put(&key->ek_path);
|
||||
auth_domain_put(key->ek_client);
|
||||
kfree(key);
|
||||
}
|
||||
|
||||
static void expkey_put(struct kref *ref)
|
||||
{
|
||||
struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
|
||||
|
||||
INIT_RCU_WORK(&key->ek_rcu_work, expkey_put_work);
|
||||
queue_rcu_work(system_wq, &key->ek_rcu_work);
|
||||
kfree_rcu(key, ek_rcu);
|
||||
}
|
||||
|
||||
static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
|
||||
@@ -364,26 +355,16 @@ static void export_stats_destroy(struct export_stats *stats)
|
||||
EXP_STATS_COUNTERS_NUM);
|
||||
}
|
||||
|
||||
static void svc_export_put_work(struct work_struct *work)
|
||||
static void svc_export_put(struct kref *ref)
|
||||
{
|
||||
struct svc_export *exp =
|
||||
container_of(to_rcu_work(work), struct svc_export, ex_rcu_work);
|
||||
|
||||
struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
|
||||
path_put(&exp->ex_path);
|
||||
auth_domain_put(exp->ex_client);
|
||||
nfsd4_fslocs_free(&exp->ex_fslocs);
|
||||
export_stats_destroy(exp->ex_stats);
|
||||
kfree(exp->ex_stats);
|
||||
kfree(exp->ex_uuid);
|
||||
kfree(exp);
|
||||
}
|
||||
|
||||
static void svc_export_put(struct kref *ref)
|
||||
{
|
||||
struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
|
||||
|
||||
INIT_RCU_WORK(&exp->ex_rcu_work, svc_export_put_work);
|
||||
queue_rcu_work(system_wq, &exp->ex_rcu_work);
|
||||
kfree_rcu(exp, ex_rcu);
|
||||
}
|
||||
|
||||
static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
|
||||
|
||||
+2
-2
@@ -75,7 +75,7 @@ struct svc_export {
|
||||
u32 ex_layout_types;
|
||||
struct nfsd4_deviceid_map *ex_devid_map;
|
||||
struct cache_detail *cd;
|
||||
struct rcu_work ex_rcu_work;
|
||||
struct rcu_head ex_rcu;
|
||||
unsigned long ex_xprtsec_modes;
|
||||
struct export_stats *ex_stats;
|
||||
};
|
||||
@@ -92,7 +92,7 @@ struct svc_expkey {
|
||||
u32 ek_fsid[6];
|
||||
|
||||
struct path ek_path;
|
||||
struct rcu_work ek_rcu_work;
|
||||
struct rcu_head ek_rcu;
|
||||
};
|
||||
|
||||
#define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
|
||||
|
||||
@@ -1058,7 +1058,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
|
||||
args.authflavor = clp->cl_cred.cr_flavor;
|
||||
clp->cl_cb_ident = conn->cb_ident;
|
||||
} else {
|
||||
if (!conn->cb_xprt)
|
||||
if (!conn->cb_xprt || !ses)
|
||||
return -EINVAL;
|
||||
clp->cl_cb_session = ses;
|
||||
args.bc_xprt = conn->cb_xprt;
|
||||
@@ -1461,8 +1461,6 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
|
||||
ses = c->cn_session;
|
||||
}
|
||||
spin_unlock(&clp->cl_lock);
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
err = setup_callback_client(clp, &conn, ses);
|
||||
if (err) {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
config CIFS
|
||||
tristate "SMB3 and CIFS support (advanced network filesystem)"
|
||||
depends on INET
|
||||
select NETFS_SUPPORT
|
||||
select NLS
|
||||
select NLS_UCS2_UTILS
|
||||
select CRYPTO
|
||||
|
||||
@@ -4855,6 +4855,8 @@ smb2_writev_callback(struct mid_q_entry *mid)
|
||||
if (written > wdata->subreq.len)
|
||||
written &= 0xFFFF;
|
||||
|
||||
cifs_stats_bytes_written(tcon, written);
|
||||
|
||||
if (written < wdata->subreq.len)
|
||||
wdata->result = -ENOSPC;
|
||||
else
|
||||
@@ -5171,6 +5173,7 @@ replay_again:
|
||||
cifs_dbg(VFS, "Send error in write = %d\n", rc);
|
||||
} else {
|
||||
*nbytes = le32_to_cpu(rsp->DataLength);
|
||||
cifs_stats_bytes_written(io_parms->tcon, *nbytes);
|
||||
trace_smb3_write_done(0, 0, xid,
|
||||
req->PersistentFileId,
|
||||
io_parms->tcon->tid,
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#include "mgmt/share_config.h"
|
||||
|
||||
/*for shortname implementation */
|
||||
static const char basechars[43] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
|
||||
#define MANGLE_BASE (sizeof(basechars) / sizeof(char) - 1)
|
||||
static const char *basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
|
||||
#define MANGLE_BASE (strlen(basechars) - 1)
|
||||
#define MAGIC_CHAR '~'
|
||||
#define PERIOD '.'
|
||||
#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
|
||||
|
||||
+15
-1
@@ -517,7 +517,11 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
inode->i_nlink);
|
||||
clear_nlink(inode);
|
||||
inode->i_size = 0;
|
||||
inode_dec_link_count(dir);
|
||||
if (dir->i_nlink >= 3)
|
||||
inode_dec_link_count(dir);
|
||||
else
|
||||
udf_warn(inode->i_sb, "parent dir link count too low (%u)\n",
|
||||
dir->i_nlink);
|
||||
udf_add_fid_counter(dir->i_sb, true, -1);
|
||||
inode_set_mtime_to_ts(dir,
|
||||
inode_set_ctime_to_ts(dir, inode_set_ctime_current(inode)));
|
||||
@@ -787,8 +791,18 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir,
|
||||
retval = -ENOTEMPTY;
|
||||
if (!empty_dir(new_inode))
|
||||
goto out_oiter;
|
||||
retval = -EFSCORRUPTED;
|
||||
if (new_inode->i_nlink != 2)
|
||||
goto out_oiter;
|
||||
}
|
||||
retval = -EFSCORRUPTED;
|
||||
if (old_dir->i_nlink < 3)
|
||||
goto out_oiter;
|
||||
is_dir = true;
|
||||
} else if (new_inode) {
|
||||
retval = -EFSCORRUPTED;
|
||||
if (new_inode->i_nlink < 1)
|
||||
goto out_oiter;
|
||||
}
|
||||
if (is_dir && old_dir != new_dir) {
|
||||
retval = udf_fiiter_find_entry(old_inode, &dotdot_name,
|
||||
|
||||
@@ -26,11 +26,13 @@ struct dma_slave_map;
|
||||
* @max_mm_channels: Maximum number of MM DMA channels in each direction
|
||||
* @device_map: DMA slave map
|
||||
* @irq_index: The index of first IRQ
|
||||
* @dma_dev: The device pointer for dma operations
|
||||
*/
|
||||
struct qdma_platdata {
|
||||
u32 max_mm_channels;
|
||||
u32 irq_index;
|
||||
struct dma_slave_map *device_map;
|
||||
struct device *dma_dev;
|
||||
};
|
||||
|
||||
#endif /* _PLATDATA_AMD_QDMA_H */
|
||||
|
||||
@@ -1671,8 +1671,9 @@ static inline unsigned int __task_state_index(unsigned int tsk_state,
|
||||
* We're lying here, but rather than expose a completely new task state
|
||||
* to userspace, we can make this appear as if the task has gone through
|
||||
* a regular rt_mutex_lock() call.
|
||||
* Report frozen tasks as uninterruptible.
|
||||
*/
|
||||
if (tsk_state & TASK_RTLOCK_WAIT)
|
||||
if ((tsk_state & TASK_RTLOCK_WAIT) || (tsk_state & TASK_FROZEN))
|
||||
state = TASK_UNINTERRUPTIBLE;
|
||||
|
||||
return fls(state);
|
||||
|
||||
@@ -317,17 +317,22 @@ static inline void sock_drop(struct sock *sk, struct sk_buff *skb)
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
static inline void sk_psock_queue_msg(struct sk_psock *psock,
|
||||
static inline bool sk_psock_queue_msg(struct sk_psock *psock,
|
||||
struct sk_msg *msg)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
spin_lock_bh(&psock->ingress_lock);
|
||||
if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED))
|
||||
if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) {
|
||||
list_add_tail(&msg->list, &psock->ingress_msg);
|
||||
else {
|
||||
ret = true;
|
||||
} else {
|
||||
sk_msg_free(psock->sk, msg);
|
||||
kfree(msg);
|
||||
ret = false;
|
||||
}
|
||||
spin_unlock_bh(&psock->ingress_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline struct sk_msg *sk_psock_dequeue_msg(struct sk_psock *psock)
|
||||
|
||||
@@ -379,7 +379,7 @@ struct trace_event_call {
|
||||
struct list_head list;
|
||||
struct trace_event_class *class;
|
||||
union {
|
||||
char *name;
|
||||
const char *name;
|
||||
/* Set TRACE_EVENT_FL_TRACEPOINT flag when using "tp" */
|
||||
struct tracepoint *tp;
|
||||
};
|
||||
|
||||
@@ -515,7 +515,7 @@ static inline const char *node_stat_name(enum node_stat_item item)
|
||||
|
||||
static inline const char *lru_list_name(enum lru_list lru)
|
||||
{
|
||||
return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
|
||||
return node_stat_name(NR_LRU_BASE + (enum node_stat_item)lru) + 3; // skip "nr_"
|
||||
}
|
||||
|
||||
#if defined(CONFIG_VM_EVENT_COUNTERS) || defined(CONFIG_MEMCG)
|
||||
|
||||
+8
-2
@@ -1521,7 +1521,7 @@ static inline bool sk_wmem_schedule(struct sock *sk, int size)
|
||||
}
|
||||
|
||||
static inline bool
|
||||
sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
|
||||
__sk_rmem_schedule(struct sock *sk, int size, bool pfmemalloc)
|
||||
{
|
||||
int delta;
|
||||
|
||||
@@ -1529,7 +1529,13 @@ sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
|
||||
return true;
|
||||
delta = size - sk->sk_forward_alloc;
|
||||
return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_RECV) ||
|
||||
skb_pfmemalloc(skb);
|
||||
pfmemalloc;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
|
||||
{
|
||||
return __sk_rmem_schedule(sk, size, skb_pfmemalloc(skb));
|
||||
}
|
||||
|
||||
static inline int sk_unused_reserved_mem(const struct sock *sk)
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
#define __always_inline inline
|
||||
#endif
|
||||
|
||||
/* Not all C++ standards support type declarations inside an anonymous union */
|
||||
#ifndef __cplusplus
|
||||
#define __struct_group_tag(TAG) TAG
|
||||
#else
|
||||
#define __struct_group_tag(TAG)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* __struct_group() - Create a mirrored named and anonyomous struct
|
||||
*
|
||||
@@ -20,13 +27,13 @@
|
||||
* and size: one anonymous and one named. The former's members can be used
|
||||
* normally without sub-struct naming, and the latter can be used to
|
||||
* reason about the start, end, and size of the group of struct members.
|
||||
* The named struct can also be explicitly tagged for layer reuse, as well
|
||||
* as both having struct attributes appended.
|
||||
* The named struct can also be explicitly tagged for layer reuse (C only),
|
||||
* as well as both having struct attributes appended.
|
||||
*/
|
||||
#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
|
||||
union { \
|
||||
struct { MEMBERS } ATTRS; \
|
||||
struct TAG { MEMBERS } ATTRS NAME; \
|
||||
struct __struct_group_tag(TAG) { MEMBERS } ATTRS NAME; \
|
||||
} ATTRS
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -412,6 +412,7 @@ void io_sqpoll_wait_sq(struct io_ring_ctx *ctx)
|
||||
__cold int io_sq_offload_create(struct io_ring_ctx *ctx,
|
||||
struct io_uring_params *p)
|
||||
{
|
||||
struct task_struct *task_to_put = NULL;
|
||||
int ret;
|
||||
|
||||
/* Retain compatibility with failing for an invalid attach attempt */
|
||||
@@ -492,6 +493,7 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
|
||||
}
|
||||
|
||||
sqd->thread = tsk;
|
||||
task_to_put = get_task_struct(tsk);
|
||||
ret = io_uring_alloc_task_context(tsk, ctx);
|
||||
wake_up_new_task(tsk);
|
||||
if (ret)
|
||||
@@ -502,11 +504,15 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (task_to_put)
|
||||
put_task_struct(task_to_put);
|
||||
return 0;
|
||||
err_sqpoll:
|
||||
complete(&ctx->sq_data->exited);
|
||||
err:
|
||||
io_sq_thread_finish(ctx);
|
||||
if (task_to_put)
|
||||
put_task_struct(task_to_put);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+11
-7
@@ -7868,7 +7868,7 @@ static int process_dynptr_func(struct bpf_verifier_env *env, int regno, int insn
|
||||
if (reg->type != PTR_TO_STACK && reg->type != CONST_PTR_TO_DYNPTR) {
|
||||
verbose(env,
|
||||
"arg#%d expected pointer to stack or const struct bpf_dynptr\n",
|
||||
regno);
|
||||
regno - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -7922,7 +7922,7 @@ static int process_dynptr_func(struct bpf_verifier_env *env, int regno, int insn
|
||||
if (!is_dynptr_reg_valid_init(env, reg)) {
|
||||
verbose(env,
|
||||
"Expected an initialized dynptr as arg #%d\n",
|
||||
regno);
|
||||
regno - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -7930,7 +7930,7 @@ static int process_dynptr_func(struct bpf_verifier_env *env, int regno, int insn
|
||||
if (!is_dynptr_type_expected(env, reg, arg_type & ~MEM_RDONLY)) {
|
||||
verbose(env,
|
||||
"Expected a dynptr of type %s as arg #%d\n",
|
||||
dynptr_type_str(arg_to_dynptr_type(arg_type)), regno);
|
||||
dynptr_type_str(arg_to_dynptr_type(arg_type)), regno - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -7999,7 +7999,7 @@ static int process_iter_arg(struct bpf_verifier_env *env, int regno, int insn_id
|
||||
*/
|
||||
btf_id = btf_check_iter_arg(meta->btf, meta->func_proto, regno - 1);
|
||||
if (btf_id < 0) {
|
||||
verbose(env, "expected valid iter pointer as arg #%d\n", regno);
|
||||
verbose(env, "expected valid iter pointer as arg #%d\n", regno - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
t = btf_type_by_id(meta->btf, btf_id);
|
||||
@@ -8009,7 +8009,7 @@ static int process_iter_arg(struct bpf_verifier_env *env, int regno, int insn_id
|
||||
/* bpf_iter_<type>_new() expects pointer to uninit iter state */
|
||||
if (!is_iter_reg_valid_uninit(env, reg, nr_slots)) {
|
||||
verbose(env, "expected uninitialized iter_%s as arg #%d\n",
|
||||
iter_type_str(meta->btf, btf_id), regno);
|
||||
iter_type_str(meta->btf, btf_id), regno - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -8033,7 +8033,7 @@ static int process_iter_arg(struct bpf_verifier_env *env, int regno, int insn_id
|
||||
break;
|
||||
case -EINVAL:
|
||||
verbose(env, "expected an initialized iter_%s as arg #%d\n",
|
||||
iter_type_str(meta->btf, btf_id), regno);
|
||||
iter_type_str(meta->btf, btf_id), regno - 1);
|
||||
return err;
|
||||
case -EPROTO:
|
||||
verbose(env, "expected an RCU CS when using %s\n", meta->func_name);
|
||||
@@ -21085,11 +21085,15 @@ patch_map_ops_generic:
|
||||
* changed in some incompatible and hard to support
|
||||
* way, it's fine to back out this inlining logic
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
insn_buf[0] = BPF_MOV32_IMM(BPF_REG_0, (u32)(unsigned long)&pcpu_hot.cpu_number);
|
||||
insn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0);
|
||||
insn_buf[2] = BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0);
|
||||
cnt = 3;
|
||||
|
||||
#else
|
||||
insn_buf[0] = BPF_ALU32_REG(BPF_XOR, BPF_REG_0, BPF_REG_0);
|
||||
cnt = 1;
|
||||
#endif
|
||||
new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
|
||||
if (!new_prog)
|
||||
return -ENOMEM;
|
||||
|
||||
+6
-7
@@ -648,11 +648,8 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
|
||||
LIST_HEAD(uf);
|
||||
VMA_ITERATOR(vmi, mm, 0);
|
||||
|
||||
uprobe_start_dup_mmap();
|
||||
if (mmap_write_lock_killable(oldmm)) {
|
||||
retval = -EINTR;
|
||||
goto fail_uprobe_end;
|
||||
}
|
||||
if (mmap_write_lock_killable(oldmm))
|
||||
return -EINTR;
|
||||
flush_cache_dup_mm(oldmm);
|
||||
uprobe_dup_mmap(oldmm, mm);
|
||||
/*
|
||||
@@ -791,8 +788,6 @@ out:
|
||||
dup_userfaultfd_complete(&uf);
|
||||
else
|
||||
dup_userfaultfd_fail(&uf);
|
||||
fail_uprobe_end:
|
||||
uprobe_end_dup_mmap();
|
||||
return retval;
|
||||
|
||||
fail_nomem_anon_vma_fork:
|
||||
@@ -1704,9 +1699,11 @@ static struct mm_struct *dup_mm(struct task_struct *tsk,
|
||||
if (!mm_init(mm, tsk, mm->user_ns))
|
||||
goto fail_nomem;
|
||||
|
||||
uprobe_start_dup_mmap();
|
||||
err = dup_mmap(mm, oldmm);
|
||||
if (err)
|
||||
goto free_pt;
|
||||
uprobe_end_dup_mmap();
|
||||
|
||||
mm->hiwater_rss = get_mm_rss(mm);
|
||||
mm->hiwater_vm = mm->total_vm;
|
||||
@@ -1721,6 +1718,8 @@ free_pt:
|
||||
mm->binfmt = NULL;
|
||||
mm_init_owner(mm, NULL);
|
||||
mmput(mm);
|
||||
if (err)
|
||||
uprobe_end_dup_mmap();
|
||||
|
||||
fail_nomem:
|
||||
return NULL;
|
||||
|
||||
@@ -5110,6 +5110,9 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf,
|
||||
cpumask_var_t tracing_cpumask_new;
|
||||
int err;
|
||||
|
||||
if (count == 0 || count > KMALLOC_MAX_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (!zalloc_cpumask_var(&tracing_cpumask_new, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -725,7 +725,7 @@ static int trace_kprobe_module_callback(struct notifier_block *nb,
|
||||
|
||||
static struct notifier_block trace_kprobe_module_nb = {
|
||||
.notifier_call = trace_kprobe_module_callback,
|
||||
.priority = 1 /* Invoked after kprobe module callback */
|
||||
.priority = 2 /* Invoked after kprobe and jump_label module callback */
|
||||
};
|
||||
static int trace_kprobe_register_module_notifier(void)
|
||||
{
|
||||
|
||||
@@ -1173,6 +1173,8 @@ EXPORT_SYMBOL(ceph_osdc_new_request);
|
||||
|
||||
int __ceph_alloc_sparse_ext_map(struct ceph_osd_req_op *op, int cnt)
|
||||
{
|
||||
WARN_ON(op->op != CEPH_OSD_OP_SPARSE_READ);
|
||||
|
||||
op->extent.sparse_ext_cnt = cnt;
|
||||
op->extent.sparse_ext = kmalloc_array(cnt,
|
||||
sizeof(*op->extent.sparse_ext),
|
||||
|
||||
+15
-6
@@ -3751,13 +3751,22 @@ static const struct bpf_func_proto bpf_skb_adjust_room_proto = {
|
||||
|
||||
static u32 __bpf_skb_min_len(const struct sk_buff *skb)
|
||||
{
|
||||
u32 min_len = skb_network_offset(skb);
|
||||
int offset = skb_network_offset(skb);
|
||||
u32 min_len = 0;
|
||||
|
||||
if (skb_transport_header_was_set(skb))
|
||||
min_len = skb_transport_offset(skb);
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL)
|
||||
min_len = skb_checksum_start_offset(skb) +
|
||||
skb->csum_offset + sizeof(__sum16);
|
||||
if (offset > 0)
|
||||
min_len = offset;
|
||||
if (skb_transport_header_was_set(skb)) {
|
||||
offset = skb_transport_offset(skb);
|
||||
if (offset > 0)
|
||||
min_len = offset;
|
||||
}
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
offset = skb_checksum_start_offset(skb) +
|
||||
skb->csum_offset + sizeof(__sum16);
|
||||
if (offset > 0)
|
||||
min_len = offset;
|
||||
}
|
||||
return min_len;
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -445,8 +445,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
|
||||
if (likely(!peek)) {
|
||||
sge->offset += copy;
|
||||
sge->length -= copy;
|
||||
if (!msg_rx->skb)
|
||||
if (!msg_rx->skb) {
|
||||
sk_mem_uncharge(sk, copy);
|
||||
atomic_sub(copy, &sk->sk_rmem_alloc);
|
||||
}
|
||||
msg_rx->sg.size -= copy;
|
||||
|
||||
if (!sge->length) {
|
||||
@@ -772,6 +774,8 @@ static void __sk_psock_purge_ingress_msg(struct sk_psock *psock)
|
||||
|
||||
list_for_each_entry_safe(msg, tmp, &psock->ingress_msg, list) {
|
||||
list_del(&msg->list);
|
||||
if (!msg->skb)
|
||||
atomic_sub(msg->sg.size, &psock->sk->sk_rmem_alloc);
|
||||
sk_msg_free(psock->sk, msg);
|
||||
kfree(msg);
|
||||
}
|
||||
|
||||
+4
-2
@@ -49,13 +49,14 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
|
||||
sge = sk_msg_elem(msg, i);
|
||||
size = (apply && apply_bytes < sge->length) ?
|
||||
apply_bytes : sge->length;
|
||||
if (!sk_wmem_schedule(sk, size)) {
|
||||
if (!__sk_rmem_schedule(sk, size, false)) {
|
||||
if (!copied)
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
sk_mem_charge(sk, size);
|
||||
atomic_add(size, &sk->sk_rmem_alloc);
|
||||
sk_msg_xfer(tmp, msg, i, size);
|
||||
copied += size;
|
||||
if (sge->length)
|
||||
@@ -74,7 +75,8 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
|
||||
|
||||
if (!ret) {
|
||||
msg->sg.start = i;
|
||||
sk_psock_queue_msg(psock, tmp);
|
||||
if (!sk_psock_queue_msg(psock, tmp))
|
||||
atomic_sub(copied, &sk->sk_rmem_alloc);
|
||||
sk_psock_data_ready(sk, psock);
|
||||
} else {
|
||||
sk_msg_free(sk, tmp);
|
||||
|
||||
@@ -505,7 +505,7 @@ static void *snd_dma_wc_alloc(struct snd_dma_buffer *dmab, size_t size)
|
||||
if (!p)
|
||||
return NULL;
|
||||
dmab->addr = dma_map_single(dmab->dev.dev, p, size, DMA_BIDIRECTIONAL);
|
||||
if (dmab->addr == DMA_MAPPING_ERROR) {
|
||||
if (dma_mapping_error(dmab->dev.dev, dmab->addr)) {
|
||||
do_free_pages(dmab->area, size, true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user