Merge tag 'v5.18-rc7' into android-mainline
Linux 5.18-rc7 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I3a54ae75c03a63020742d792be103e3b9f4d294f
This commit is contained in:
@@ -251,6 +251,7 @@ Mark Yao <markyao0591@gmail.com> <mark.yao@rock-chips.com>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@ginzinger.com>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@puri.sm>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
|
||||
Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com> <martyna.szapar-mudlaw@intel.com>
|
||||
Mathieu Othacehe <m.othacehe@gmail.com>
|
||||
Matthew Wilcox <willy@infradead.org> <matthew.r.wilcox@intel.com>
|
||||
Matthew Wilcox <willy@infradead.org> <matthew@wil.cx>
|
||||
|
||||
@@ -189,6 +189,9 @@ stable kernels.
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Qualcomm Tech. | Kryo4xx Silver | N/A | ARM64_ERRATUM_1024718 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Qualcomm Tech. | Kryo4xx Gold | N/A | ARM64_ERRATUM_1286807 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
|
||||
@@ -244,10 +244,11 @@ disclosure of a particular issue, unless requested by a response team or by
|
||||
an involved disclosed party. The current ambassadors list:
|
||||
|
||||
============= ========================================================
|
||||
ARM Grant Likely <grant.likely@arm.com>
|
||||
AMD Tom Lendacky <tom.lendacky@amd.com>
|
||||
IBM Z Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
IBM Power Anton Blanchard <anton@linux.ibm.com>
|
||||
Ampere Darren Hart <darren@os.amperecomputing.com>
|
||||
ARM Catalin Marinas <catalin.marinas@arm.com>
|
||||
IBM Power Anton Blanchard <anton@linux.ibm.com>
|
||||
IBM Z Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
Intel Tony Luck <tony.luck@intel.com>
|
||||
Qualcomm Trilok Soni <tsoni@codeaurora.org>
|
||||
|
||||
|
||||
+3
-1
@@ -5440,6 +5440,7 @@ F: net/ax25/sysctl_net_ax25.c
|
||||
|
||||
DATA ACCESS MONITOR
|
||||
M: SeongJae Park <sj@kernel.org>
|
||||
L: damon@lists.linux.dev
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-kernel-mm-damon
|
||||
@@ -15483,7 +15484,8 @@ F: tools/perf/
|
||||
PERFORMANCE EVENTS TOOLING ARM64
|
||||
R: John Garry <john.garry@huawei.com>
|
||||
R: Will Deacon <will@kernel.org>
|
||||
R: Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
R: James Clark <james.clark@arm.com>
|
||||
R: Mike Leach <mike.leach@linaro.org>
|
||||
R: Leo Yan <leo.yan@linaro.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 18
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Superb Owl
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -440,6 +440,9 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
|
||||
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
|
||||
extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
|
||||
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
|
||||
extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
|
||||
unsigned long flags);
|
||||
#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -493,3 +493,11 @@ void __init early_ioremap_init(void)
|
||||
{
|
||||
early_ioremap_setup();
|
||||
}
|
||||
|
||||
bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
|
||||
unsigned long flags)
|
||||
{
|
||||
unsigned long pfn = PHYS_PFN(offset);
|
||||
|
||||
return memblock_is_map_memory(pfn);
|
||||
}
|
||||
|
||||
@@ -192,4 +192,8 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
|
||||
extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
|
||||
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
|
||||
|
||||
extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
|
||||
unsigned long flags);
|
||||
#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap
|
||||
|
||||
#endif /* __ASM_IO_H */
|
||||
|
||||
@@ -75,6 +75,10 @@ obj-$(CONFIG_ARM64_MTE) += mte.o
|
||||
obj-y += vdso-wrap.o
|
||||
obj-$(CONFIG_COMPAT_VDSO) += vdso32-wrap.o
|
||||
|
||||
# Force dependency (vdso*-wrap.S includes vdso.so through incbin)
|
||||
$(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so
|
||||
$(obj)/vdso32-wrap.o: $(obj)/vdso32/vdso.so
|
||||
|
||||
obj-y += probes/
|
||||
head-y := head.o
|
||||
extra-y += $(head-y) vmlinux.lds
|
||||
|
||||
@@ -208,6 +208,8 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1286807
|
||||
{
|
||||
ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0),
|
||||
/* Kryo4xx Gold (rcpe to rfpe) => (r0p0 to r3p0) */
|
||||
ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe),
|
||||
},
|
||||
#endif
|
||||
{},
|
||||
|
||||
@@ -654,7 +654,6 @@ static const struct __ftr_reg_entry {
|
||||
ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0),
|
||||
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1,
|
||||
&id_aa64isar1_override),
|
||||
ARM64_FTR_REG(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2),
|
||||
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2,
|
||||
&id_aa64isar2_override),
|
||||
|
||||
@@ -810,7 +809,7 @@ static void __init sort_ftr_regs(void)
|
||||
* to sys_id for subsequent binary search in get_arm64_ftr_reg()
|
||||
* to work correctly.
|
||||
*/
|
||||
BUG_ON(arm64_ftr_regs[i].sys_id < arm64_ftr_regs[i - 1].sys_id);
|
||||
BUG_ON(arm64_ftr_regs[i].sys_id <= arm64_ftr_regs[i - 1].sys_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,9 +52,6 @@ GCOV_PROFILE := n
|
||||
targets += vdso.lds
|
||||
CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
|
||||
|
||||
# Force dependency (incbin is bad)
|
||||
$(obj)/vdso.o : $(obj)/vdso.so
|
||||
|
||||
# Link rule for the .so file, .lds has to be first
|
||||
$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
|
||||
$(call if_changed,vdsold_and_vdso_check)
|
||||
|
||||
@@ -131,9 +131,6 @@ obj-vdso := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso)
|
||||
targets += vdso.lds
|
||||
CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
|
||||
|
||||
# Force dependency (vdso.s includes vdso.so through incbin)
|
||||
$(obj)/vdso.o: $(obj)/vdso.so
|
||||
|
||||
include/generated/vdso32-offsets.h: $(obj)/vdso.so.dbg FORCE
|
||||
$(call if_changed,vdsosym)
|
||||
|
||||
|
||||
@@ -99,3 +99,11 @@ void __init early_ioremap_init(void)
|
||||
{
|
||||
early_ioremap_setup();
|
||||
}
|
||||
|
||||
bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
|
||||
unsigned long flags)
|
||||
{
|
||||
unsigned long pfn = PHYS_PFN(offset);
|
||||
|
||||
return pfn_is_map_memory(pfn);
|
||||
}
|
||||
|
||||
@@ -122,11 +122,27 @@
|
||||
|
||||
/* 0x0 - 0xb */
|
||||
|
||||
/* 'current->mm' needs to be in r4 */
|
||||
tophys(r4, r2)
|
||||
lwz r4, MM(r4)
|
||||
tophys(r4, r4)
|
||||
/* This only clobbers r0, r3, r4 and r5 */
|
||||
/* switch_mmu_context() needs paging, let's enable it */
|
||||
mfmsr r9
|
||||
ori r11, r9, MSR_DR
|
||||
mtmsr r11
|
||||
sync
|
||||
|
||||
/* switch_mmu_context() clobbers r12, rescue it */
|
||||
SAVE_GPR(12, r1)
|
||||
|
||||
/* Calling switch_mmu_context(<inv>, current->mm, <inv>); */
|
||||
lwz r4, MM(r2)
|
||||
bl switch_mmu_context
|
||||
|
||||
/* restore r12 */
|
||||
REST_GPR(12, r1)
|
||||
|
||||
/* Disable paging again */
|
||||
mfmsr r9
|
||||
li r6, MSR_DR
|
||||
andc r9, r9, r6
|
||||
mtmsr r9
|
||||
sync
|
||||
|
||||
.endm
|
||||
|
||||
@@ -902,6 +902,8 @@ static void __meminit vmemmap_use_sub_pmd(unsigned long start, unsigned long end
|
||||
|
||||
static void __meminit vmemmap_use_new_sub_pmd(unsigned long start, unsigned long end)
|
||||
{
|
||||
const unsigned long page = ALIGN_DOWN(start, PMD_SIZE);
|
||||
|
||||
vmemmap_flush_unused_pmd();
|
||||
|
||||
/*
|
||||
@@ -914,8 +916,7 @@ static void __meminit vmemmap_use_new_sub_pmd(unsigned long start, unsigned long
|
||||
* Mark with PAGE_UNUSED the unused parts of the new memmap range
|
||||
*/
|
||||
if (!IS_ALIGNED(start, PMD_SIZE))
|
||||
memset((void *)start, PAGE_UNUSED,
|
||||
start - ALIGN_DOWN(start, PMD_SIZE));
|
||||
memset((void *)page, PAGE_UNUSED, start - page);
|
||||
|
||||
/*
|
||||
* We want to avoid memset(PAGE_UNUSED) when populating the vmemmap of
|
||||
|
||||
@@ -735,6 +735,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
||||
size_t offset, u32 opt_flags)
|
||||
{
|
||||
struct firmware *fw = NULL;
|
||||
struct cred *kern_cred = NULL;
|
||||
const struct cred *old_cred;
|
||||
bool nondirect = false;
|
||||
int ret;
|
||||
|
||||
@@ -751,6 +753,18 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
||||
if (ret <= 0) /* error or already assigned */
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* We are about to try to access the firmware file. Because we may have been
|
||||
* called by a driver when serving an unrelated request from userland, we use
|
||||
* the kernel credentials to read the file.
|
||||
*/
|
||||
kern_cred = prepare_kernel_cred(NULL);
|
||||
if (!kern_cred) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
old_cred = override_creds(kern_cred);
|
||||
|
||||
ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);
|
||||
|
||||
/* Only full reads can support decompression, platform, and sysfs. */
|
||||
@@ -776,6 +790,9 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
||||
} else
|
||||
ret = assign_fw(fw, device);
|
||||
|
||||
revert_creds(old_cred);
|
||||
put_cred(kern_cred);
|
||||
|
||||
out:
|
||||
if (ret < 0) {
|
||||
fw_abort_batch_reqs(fw);
|
||||
|
||||
@@ -543,10 +543,6 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
file->f_mode |= FMODE_LSEEK;
|
||||
dmabuf->file = file;
|
||||
|
||||
ret = dma_buf_stats_setup(dmabuf);
|
||||
if (ret)
|
||||
goto err_sysfs;
|
||||
|
||||
mutex_init(&dmabuf->lock);
|
||||
INIT_LIST_HEAD(&dmabuf->attachments);
|
||||
|
||||
@@ -554,6 +550,10 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
list_add(&dmabuf->list_node, &db_list.head);
|
||||
mutex_unlock(&db_list.lock);
|
||||
|
||||
ret = dma_buf_stats_setup(dmabuf);
|
||||
if (ret)
|
||||
goto err_sysfs;
|
||||
|
||||
return dmabuf;
|
||||
|
||||
err_sysfs:
|
||||
|
||||
@@ -296,6 +296,7 @@ static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
|
||||
{
|
||||
struct amdgpu_device *adev = ctx->adev;
|
||||
enum amd_dpm_forced_level level;
|
||||
u32 current_stable_pstate;
|
||||
int r;
|
||||
|
||||
mutex_lock(&adev->pm.stable_pstate_ctx_lock);
|
||||
@@ -304,6 +305,10 @@ static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
r = amdgpu_ctx_get_stable_pstate(ctx, ¤t_stable_pstate);
|
||||
if (r || (stable_pstate == current_stable_pstate))
|
||||
goto done;
|
||||
|
||||
switch (stable_pstate) {
|
||||
case AMDGPU_CTX_STABLE_PSTATE_NONE:
|
||||
level = AMD_DPM_FORCED_LEVEL_AUTO;
|
||||
|
||||
@@ -81,6 +81,10 @@
|
||||
#include "mxgpu_vi.h"
|
||||
#include "amdgpu_dm.h"
|
||||
|
||||
#if IS_ENABLED(CONFIG_X86)
|
||||
#include <asm/intel-family.h>
|
||||
#endif
|
||||
|
||||
#define ixPCIE_LC_L1_PM_SUBSTATE 0x100100C6
|
||||
#define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK 0x00000001L
|
||||
#define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK 0x00000002L
|
||||
@@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct amdgpu_device *adev)
|
||||
WREG32_PCIE(ixPCIE_LC_CNTL, data);
|
||||
}
|
||||
|
||||
static bool aspm_support_quirk_check(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_X86)
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vi_program_aspm(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 data, data1, orig;
|
||||
bool bL1SS = false;
|
||||
bool bClkReqSupport = true;
|
||||
|
||||
if (!amdgpu_device_should_use_aspm(adev))
|
||||
if (!amdgpu_device_should_use_aspm(adev) || !aspm_support_quirk_check())
|
||||
return;
|
||||
|
||||
if (adev->flags & AMD_IS_APU ||
|
||||
|
||||
@@ -153,9 +153,4 @@ void dcn31_hw_sequencer_construct(struct dc *dc)
|
||||
dc->hwss.init_hw = dcn20_fpga_init_hw;
|
||||
dc->hwseq->funcs.init_pipes = NULL;
|
||||
}
|
||||
if (dc->debug.disable_z10) {
|
||||
/*hw not support z10 or sw disable it*/
|
||||
dc->hwss.z10_restore = NULL;
|
||||
dc->hwss.z10_save_init = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1351,14 +1351,8 @@ static int smu_disable_dpms(struct smu_context *smu)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
int ret = 0;
|
||||
/*
|
||||
* TODO: (adev->in_suspend && !adev->in_s0ix) is added to pair
|
||||
* the workaround which always reset the asic in suspend.
|
||||
* It's likely that workaround will be dropped in the future.
|
||||
* Then the change here should be dropped together.
|
||||
*/
|
||||
bool use_baco = !smu->is_apu &&
|
||||
(((amdgpu_in_reset(adev) || (adev->in_suspend && !adev->in_s0ix)) &&
|
||||
((amdgpu_in_reset(adev) &&
|
||||
(amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) ||
|
||||
((adev->in_runpm || adev->in_s4) && amdgpu_asic_supports_baco(adev)));
|
||||
|
||||
|
||||
@@ -1605,17 +1605,17 @@ void i915_vma_close(struct i915_vma *vma)
|
||||
|
||||
static void __i915_vma_remove_closed(struct i915_vma *vma)
|
||||
{
|
||||
struct intel_gt *gt = vma->vm->gt;
|
||||
|
||||
spin_lock_irq(>->closed_lock);
|
||||
list_del_init(&vma->closed_link);
|
||||
spin_unlock_irq(>->closed_lock);
|
||||
}
|
||||
|
||||
void i915_vma_reopen(struct i915_vma *vma)
|
||||
{
|
||||
struct intel_gt *gt = vma->vm->gt;
|
||||
|
||||
spin_lock_irq(>->closed_lock);
|
||||
if (i915_vma_is_closed(vma))
|
||||
__i915_vma_remove_closed(vma);
|
||||
spin_unlock_irq(>->closed_lock);
|
||||
}
|
||||
|
||||
void i915_vma_release(struct kref *ref)
|
||||
@@ -1641,6 +1641,7 @@ static void force_unbind(struct i915_vma *vma)
|
||||
static void release_references(struct i915_vma *vma)
|
||||
{
|
||||
struct drm_i915_gem_object *obj = vma->obj;
|
||||
struct intel_gt *gt = vma->vm->gt;
|
||||
|
||||
GEM_BUG_ON(i915_vma_is_active(vma));
|
||||
|
||||
@@ -1650,7 +1651,9 @@ static void release_references(struct i915_vma *vma)
|
||||
rb_erase(&vma->obj_node, &obj->vma.tree);
|
||||
spin_unlock(&obj->vma.lock);
|
||||
|
||||
spin_lock_irq(>->closed_lock);
|
||||
__i915_vma_remove_closed(vma);
|
||||
spin_unlock_irq(>->closed_lock);
|
||||
|
||||
__i915_vma_put(vma);
|
||||
}
|
||||
|
||||
@@ -46,8 +46,9 @@ static bool
|
||||
nouveau_get_backlight_name(char backlight_name[BL_NAME_SIZE],
|
||||
struct nouveau_backlight *bl)
|
||||
{
|
||||
const int nb = ida_simple_get(&bl_ida, 0, 0, GFP_KERNEL);
|
||||
if (nb < 0 || nb >= 100)
|
||||
const int nb = ida_alloc_max(&bl_ida, 99, GFP_KERNEL);
|
||||
|
||||
if (nb < 0)
|
||||
return false;
|
||||
if (nb > 0)
|
||||
snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", nb);
|
||||
@@ -414,7 +415,7 @@ nouveau_backlight_init(struct drm_connector *connector)
|
||||
nv_encoder, ops, &props);
|
||||
if (IS_ERR(bl->dev)) {
|
||||
if (bl->id >= 0)
|
||||
ida_simple_remove(&bl_ida, bl->id);
|
||||
ida_free(&bl_ida, bl->id);
|
||||
ret = PTR_ERR(bl->dev);
|
||||
goto fail_alloc;
|
||||
}
|
||||
@@ -442,7 +443,7 @@ nouveau_backlight_fini(struct drm_connector *connector)
|
||||
return;
|
||||
|
||||
if (bl->id >= 0)
|
||||
ida_simple_remove(&bl_ida, bl->id);
|
||||
ida_free(&bl_ida, bl->id);
|
||||
|
||||
backlight_device_unregister(bl->dev);
|
||||
nv_conn->backlight = NULL;
|
||||
|
||||
@@ -123,7 +123,7 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
|
||||
|
||||
mutex_init(&tdev->iommu.mutex);
|
||||
|
||||
if (iommu_present(&platform_bus_type)) {
|
||||
if (device_iommu_mapped(dev)) {
|
||||
tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type);
|
||||
if (!tdev->iommu.domain)
|
||||
goto error;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <drm/drm_scdc_helper.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
@@ -528,7 +528,7 @@ int vmw_cmd_send_fence(struct vmw_private *dev_priv, uint32_t *seqno)
|
||||
*seqno = atomic_add_return(1, &dev_priv->marker_seq);
|
||||
} while (*seqno == 0);
|
||||
|
||||
if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE)) {
|
||||
if (!vmw_has_fences(dev_priv)) {
|
||||
|
||||
/*
|
||||
* Don't request hardware to send a fence. The
|
||||
@@ -675,11 +675,14 @@ int vmw_cmd_emit_dummy_query(struct vmw_private *dev_priv,
|
||||
*/
|
||||
bool vmw_cmd_supported(struct vmw_private *vmw)
|
||||
{
|
||||
if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
|
||||
SVGA_CAP_CMD_BUFFERS_2)) != 0)
|
||||
return true;
|
||||
bool has_cmdbufs =
|
||||
(vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
|
||||
SVGA_CAP_CMD_BUFFERS_2)) != 0;
|
||||
if (vmw_is_svga_v3(vmw))
|
||||
return (has_cmdbufs &&
|
||||
(vmw->capabilities & SVGA_CAP_GBOBJECTS) != 0);
|
||||
/*
|
||||
* We have FIFO cmd's
|
||||
*/
|
||||
return vmw->fifo_mem != NULL;
|
||||
return has_cmdbufs || vmw->fifo_mem != NULL;
|
||||
}
|
||||
|
||||
@@ -1679,4 +1679,12 @@ static inline void vmw_irq_status_write(struct vmw_private *vmw,
|
||||
outl(status, vmw->io_start + SVGA_IRQSTATUS_PORT);
|
||||
}
|
||||
|
||||
static inline bool vmw_has_fences(struct vmw_private *vmw)
|
||||
{
|
||||
if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
|
||||
SVGA_CAP_CMD_BUFFERS_2)) != 0)
|
||||
return true;
|
||||
return (vmw_fifo_caps(vmw) & SVGA_FIFO_CAP_FENCE) != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -483,7 +483,7 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
|
||||
|
||||
static int vmw_fb_kms_framebuffer(struct fb_info *info)
|
||||
{
|
||||
struct drm_mode_fb_cmd2 mode_cmd;
|
||||
struct drm_mode_fb_cmd2 mode_cmd = {0};
|
||||
struct vmw_fb_par *par = info->par;
|
||||
struct fb_var_screeninfo *var = &info->var;
|
||||
struct drm_framebuffer *cur_fb;
|
||||
|
||||
@@ -82,6 +82,22 @@ fman_from_fence(struct vmw_fence_obj *fence)
|
||||
return container_of(fence->base.lock, struct vmw_fence_manager, lock);
|
||||
}
|
||||
|
||||
static u32 vmw_fence_goal_read(struct vmw_private *vmw)
|
||||
{
|
||||
if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
|
||||
return vmw_read(vmw, SVGA_REG_FENCE_GOAL);
|
||||
else
|
||||
return vmw_fifo_mem_read(vmw, SVGA_FIFO_FENCE_GOAL);
|
||||
}
|
||||
|
||||
static void vmw_fence_goal_write(struct vmw_private *vmw, u32 value)
|
||||
{
|
||||
if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
|
||||
vmw_write(vmw, SVGA_REG_FENCE_GOAL, value);
|
||||
else
|
||||
vmw_fifo_mem_write(vmw, SVGA_FIFO_FENCE_GOAL, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note on fencing subsystem usage of irqs:
|
||||
* Typically the vmw_fences_update function is called
|
||||
@@ -392,7 +408,7 @@ static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman,
|
||||
if (likely(!fman->seqno_valid))
|
||||
return false;
|
||||
|
||||
goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL);
|
||||
goal_seqno = vmw_fence_goal_read(fman->dev_priv);
|
||||
if (likely(passed_seqno - goal_seqno >= VMW_FENCE_WRAP))
|
||||
return false;
|
||||
|
||||
@@ -400,9 +416,8 @@ static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman,
|
||||
list_for_each_entry(fence, &fman->fence_list, head) {
|
||||
if (!list_empty(&fence->seq_passed_actions)) {
|
||||
fman->seqno_valid = true;
|
||||
vmw_fifo_mem_write(fman->dev_priv,
|
||||
SVGA_FIFO_FENCE_GOAL,
|
||||
fence->base.seqno);
|
||||
vmw_fence_goal_write(fman->dev_priv,
|
||||
fence->base.seqno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -434,13 +449,12 @@ static bool vmw_fence_goal_check_locked(struct vmw_fence_obj *fence)
|
||||
if (dma_fence_is_signaled_locked(&fence->base))
|
||||
return false;
|
||||
|
||||
goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL);
|
||||
goal_seqno = vmw_fence_goal_read(fman->dev_priv);
|
||||
if (likely(fman->seqno_valid &&
|
||||
goal_seqno - fence->base.seqno < VMW_FENCE_WRAP))
|
||||
return false;
|
||||
|
||||
vmw_fifo_mem_write(fman->dev_priv, SVGA_FIFO_FENCE_GOAL,
|
||||
fence->base.seqno);
|
||||
vmw_fence_goal_write(fman->dev_priv, fence->base.seqno);
|
||||
fman->seqno_valid = true;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -32,6 +32,14 @@
|
||||
|
||||
#define VMW_FENCE_WRAP (1 << 24)
|
||||
|
||||
static u32 vmw_irqflag_fence_goal(struct vmw_private *vmw)
|
||||
{
|
||||
if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
|
||||
return SVGA_IRQFLAG_REG_FENCE_GOAL;
|
||||
else
|
||||
return SVGA_IRQFLAG_FENCE_GOAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_thread_fn - Deferred (process context) irq handler
|
||||
*
|
||||
@@ -96,7 +104,7 @@ static irqreturn_t vmw_irq_handler(int irq, void *arg)
|
||||
wake_up_all(&dev_priv->fifo_queue);
|
||||
|
||||
if ((masked_status & (SVGA_IRQFLAG_ANY_FENCE |
|
||||
SVGA_IRQFLAG_FENCE_GOAL)) &&
|
||||
vmw_irqflag_fence_goal(dev_priv))) &&
|
||||
!test_and_set_bit(VMW_IRQTHREAD_FENCE, dev_priv->irqthread_pending))
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
|
||||
@@ -137,8 +145,7 @@ bool vmw_seqno_passed(struct vmw_private *dev_priv,
|
||||
if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP))
|
||||
return true;
|
||||
|
||||
if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE) &&
|
||||
vmw_fifo_idle(dev_priv, seqno))
|
||||
if (!vmw_has_fences(dev_priv) && vmw_fifo_idle(dev_priv, seqno))
|
||||
return true;
|
||||
|
||||
/**
|
||||
@@ -160,6 +167,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv,
|
||||
unsigned long timeout)
|
||||
{
|
||||
struct vmw_fifo_state *fifo_state = dev_priv->fifo;
|
||||
bool fifo_down = false;
|
||||
|
||||
uint32_t count = 0;
|
||||
uint32_t signal_seq;
|
||||
@@ -176,12 +184,14 @@ int vmw_fallback_wait(struct vmw_private *dev_priv,
|
||||
*/
|
||||
|
||||
if (fifo_idle) {
|
||||
down_read(&fifo_state->rwsem);
|
||||
if (dev_priv->cman) {
|
||||
ret = vmw_cmdbuf_idle(dev_priv->cman, interruptible,
|
||||
10*HZ);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
} else if (fifo_state) {
|
||||
down_read(&fifo_state->rwsem);
|
||||
fifo_down = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,12 +228,12 @@ int vmw_fallback_wait(struct vmw_private *dev_priv,
|
||||
}
|
||||
}
|
||||
finish_wait(&dev_priv->fence_queue, &__wait);
|
||||
if (ret == 0 && fifo_idle)
|
||||
if (ret == 0 && fifo_idle && fifo_state)
|
||||
vmw_fence_write(dev_priv, signal_seq);
|
||||
|
||||
wake_up_all(&dev_priv->fence_queue);
|
||||
out_err:
|
||||
if (fifo_idle)
|
||||
if (fifo_down)
|
||||
up_read(&fifo_state->rwsem);
|
||||
|
||||
return ret;
|
||||
@@ -266,13 +276,13 @@ void vmw_seqno_waiter_remove(struct vmw_private *dev_priv)
|
||||
|
||||
void vmw_goal_waiter_add(struct vmw_private *dev_priv)
|
||||
{
|
||||
vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_FENCE_GOAL,
|
||||
vmw_generic_waiter_add(dev_priv, vmw_irqflag_fence_goal(dev_priv),
|
||||
&dev_priv->goal_queue_waiters);
|
||||
}
|
||||
|
||||
void vmw_goal_waiter_remove(struct vmw_private *dev_priv)
|
||||
{
|
||||
vmw_generic_waiter_remove(dev_priv, SVGA_IRQFLAG_FENCE_GOAL,
|
||||
vmw_generic_waiter_remove(dev_priv, vmw_irqflag_fence_goal(dev_priv),
|
||||
&dev_priv->goal_queue_waiters);
|
||||
}
|
||||
|
||||
|
||||
@@ -1344,7 +1344,6 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
|
||||
ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
|
||||
mode_cmd,
|
||||
is_bo_proxy);
|
||||
|
||||
/*
|
||||
* vmw_create_bo_proxy() adds a reference that is no longer
|
||||
* needed
|
||||
@@ -1385,13 +1384,16 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
|
||||
ret = vmw_user_lookup_handle(dev_priv, file_priv,
|
||||
mode_cmd->handles[0],
|
||||
&surface, &bo);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_ERROR("Invalid buffer object handle %u (0x%x).\n",
|
||||
mode_cmd->handles[0], mode_cmd->handles[0]);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
|
||||
if (!bo &&
|
||||
!vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) {
|
||||
DRM_ERROR("Surface size cannot exceed %dx%d",
|
||||
DRM_ERROR("Surface size cannot exceed %dx%d\n",
|
||||
dev_priv->texture_max_width,
|
||||
dev_priv->texture_max_height);
|
||||
goto err_out;
|
||||
|
||||
@@ -960,7 +960,7 @@ config SENSORS_LTC4261
|
||||
|
||||
config SENSORS_LTQ_CPUTEMP
|
||||
bool "Lantiq cpu temperature sensor driver"
|
||||
depends on LANTIQ
|
||||
depends on SOC_XWAY
|
||||
help
|
||||
If you say yes here you get support for the temperature
|
||||
sensor inside your CPU.
|
||||
|
||||
@@ -708,10 +708,21 @@ static int tmp401_probe(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id __maybe_unused tmp4xx_of_match[] = {
|
||||
{ .compatible = "ti,tmp401", },
|
||||
{ .compatible = "ti,tmp411", },
|
||||
{ .compatible = "ti,tmp431", },
|
||||
{ .compatible = "ti,tmp432", },
|
||||
{ .compatible = "ti,tmp435", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tmp4xx_of_match);
|
||||
|
||||
static struct i2c_driver tmp401_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.driver = {
|
||||
.name = "tmp401",
|
||||
.of_match_table = of_match_ptr(tmp4xx_of_match),
|
||||
},
|
||||
.probe_new = tmp401_probe,
|
||||
.id_table = tmp401_id,
|
||||
|
||||
@@ -1087,9 +1087,15 @@ static int of_count_icc_providers(struct device_node *np)
|
||||
{
|
||||
struct device_node *child;
|
||||
int count = 0;
|
||||
const struct of_device_id __maybe_unused ignore_list[] = {
|
||||
{ .compatible = "qcom,sc7180-ipa-virt" },
|
||||
{ .compatible = "qcom,sdx55-ipa-virt" },
|
||||
{}
|
||||
};
|
||||
|
||||
for_each_available_child_of_node(np, child) {
|
||||
if (of_property_read_bool(child, "#interconnect-cells"))
|
||||
if (of_property_read_bool(child, "#interconnect-cells") &&
|
||||
likely(!of_match_node(ignore_list, child)))
|
||||
count++;
|
||||
count += of_count_icc_providers(child);
|
||||
}
|
||||
|
||||
@@ -1172,9 +1172,8 @@ static blk_status_t alua_prep_fn(struct scsi_device *sdev, struct request *req)
|
||||
case SCSI_ACCESS_STATE_OPTIMAL:
|
||||
case SCSI_ACCESS_STATE_ACTIVE:
|
||||
case SCSI_ACCESS_STATE_LBA:
|
||||
return BLK_STS_OK;
|
||||
case SCSI_ACCESS_STATE_TRANSITIONING:
|
||||
return BLK_STS_AGAIN;
|
||||
return BLK_STS_OK;
|
||||
default:
|
||||
req->rq_flags |= RQF_QUIET;
|
||||
return BLK_STS_IOERR;
|
||||
|
||||
@@ -1330,7 +1330,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
|
||||
LPFC_SLI_INTF_IF_TYPE_0) {
|
||||
/* FLOGI needs to be 3 for WQE FCFI */
|
||||
ct = ((SLI4_CT_FCFI >> 1) & 1) | (SLI4_CT_FCFI & 1);
|
||||
ct = SLI4_CT_FCFI;
|
||||
bf_set(wqe_ct, &wqe->els_req.wqe_com, ct);
|
||||
|
||||
/* Set the fcfi to the fcfi we registered with */
|
||||
|
||||
@@ -10720,10 +10720,10 @@ __lpfc_sli_prep_gen_req_s4(struct lpfc_iocbq *cmdiocbq, struct lpfc_dmabuf *bmp,
|
||||
|
||||
/* Words 0 - 2 */
|
||||
bde = (struct ulp_bde64_le *)&cmdwqe->generic.bde;
|
||||
bde->addr_low = cpu_to_le32(putPaddrLow(bmp->phys));
|
||||
bde->addr_high = cpu_to_le32(putPaddrHigh(bmp->phys));
|
||||
bde->addr_low = bpl->addr_low;
|
||||
bde->addr_high = bpl->addr_high;
|
||||
bde->type_size = cpu_to_le32(xmit_len);
|
||||
bde->type_size |= cpu_to_le32(ULP_BDE64_TYPE_BLP_64);
|
||||
bde->type_size |= cpu_to_le32(ULP_BDE64_TYPE_BDE_64);
|
||||
|
||||
/* Word 3 */
|
||||
cmdwqe->gen_req.request_payload_len = xmit_len;
|
||||
|
||||
@@ -3826,6 +3826,9 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
|
||||
|
||||
spin_lock_irqsave(&cmd->cmd_lock, flags);
|
||||
if (cmd->aborted) {
|
||||
if (cmd->sg_mapped)
|
||||
qlt_unmap_sg(vha, cmd);
|
||||
|
||||
spin_unlock_irqrestore(&cmd->cmd_lock, flags);
|
||||
/*
|
||||
* It's normal to see 2 calls in this path:
|
||||
|
||||
@@ -510,9 +510,9 @@ static int qcom_slim_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
ctrl->irq = platform_get_irq(pdev, 0);
|
||||
if (!ctrl->irq) {
|
||||
if (ctrl->irq < 0) {
|
||||
dev_err(&pdev->dev, "no slimbus IRQ\n");
|
||||
return -ENODEV;
|
||||
return ctrl->irq;
|
||||
}
|
||||
|
||||
sctrl = &ctrl->ctrl;
|
||||
|
||||
+12
-8
@@ -137,6 +137,7 @@ struct gsm_dlci {
|
||||
int retries;
|
||||
/* Uplink tty if active */
|
||||
struct tty_port port; /* The tty bound to this DLCI if there is one */
|
||||
#define TX_SIZE 4096 /* Must be power of 2. */
|
||||
struct kfifo fifo; /* Queue fifo for the DLCI */
|
||||
int adaption; /* Adaption layer in use */
|
||||
int prev_adaption;
|
||||
@@ -1658,6 +1659,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, const u8 *data, int clen)
|
||||
if (len == 0)
|
||||
return;
|
||||
}
|
||||
len--;
|
||||
slen++;
|
||||
tty = tty_port_tty_get(port);
|
||||
if (tty) {
|
||||
@@ -1730,7 +1732,7 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
|
||||
return NULL;
|
||||
spin_lock_init(&dlci->lock);
|
||||
mutex_init(&dlci->mutex);
|
||||
if (kfifo_alloc(&dlci->fifo, 4096, GFP_KERNEL) < 0) {
|
||||
if (kfifo_alloc(&dlci->fifo, TX_SIZE, GFP_KERNEL) < 0) {
|
||||
kfree(dlci);
|
||||
return NULL;
|
||||
}
|
||||
@@ -2351,6 +2353,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm,
|
||||
|
||||
static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
|
||||
{
|
||||
int ret = 0;
|
||||
int need_close = 0;
|
||||
int need_restart = 0;
|
||||
|
||||
@@ -2418,10 +2421,13 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
|
||||
* FIXME: We need to separate activation/deactivation from adding
|
||||
* and removing from the mux array
|
||||
*/
|
||||
if (need_restart)
|
||||
gsm_activate_mux(gsm);
|
||||
if (gsm->initiator && need_close)
|
||||
gsm_dlci_begin_open(gsm->dlci[0]);
|
||||
if (gsm->dead) {
|
||||
ret = gsm_activate_mux(gsm);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (gsm->initiator)
|
||||
gsm_dlci_begin_open(gsm->dlci[0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2971,8 +2977,6 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
|
||||
* Virtual tty side
|
||||
*/
|
||||
|
||||
#define TX_SIZE 512
|
||||
|
||||
/**
|
||||
* gsm_modem_upd_via_data - send modem bits via convergence layer
|
||||
* @dlci: channel
|
||||
@@ -3212,7 +3216,7 @@ static unsigned int gsmtty_write_room(struct tty_struct *tty)
|
||||
struct gsm_dlci *dlci = tty->driver_data;
|
||||
if (dlci->state == DLCI_CLOSED)
|
||||
return 0;
|
||||
return TX_SIZE - kfifo_len(&dlci->fifo);
|
||||
return kfifo_avail(&dlci->fifo);
|
||||
}
|
||||
|
||||
static unsigned int gsmtty_chars_in_buffer(struct tty_struct *tty)
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */
|
||||
#define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */
|
||||
|
||||
#define MTK_UART_EFR 38 /* I/O: Extended Features Register */
|
||||
#define MTK_UART_EFR_EN 0x10 /* Enable enhancement feature */
|
||||
#define MTK_UART_EFR_RTS 0x40 /* Enable hardware rx flow control */
|
||||
#define MTK_UART_EFR_CTS 0x80 /* Enable hardware tx flow control */
|
||||
@@ -53,6 +54,12 @@
|
||||
#define MTK_UART_TX_TRIGGER 1
|
||||
#define MTK_UART_RX_TRIGGER MTK_UART_RX_SIZE
|
||||
|
||||
#define MTK_UART_FEATURE_SEL 39 /* Feature Selection register */
|
||||
#define MTK_UART_FEAT_NEWRMAP BIT(0) /* Use new register map */
|
||||
|
||||
#define MTK_UART_XON1 40 /* I/O: Xon character 1 */
|
||||
#define MTK_UART_XOFF1 42 /* I/O: Xoff character 1 */
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_DMA
|
||||
enum dma_rx_status {
|
||||
DMA_RX_START = 0,
|
||||
@@ -169,7 +176,7 @@ static void mtk8250_dma_enable(struct uart_8250_port *up)
|
||||
MTK_UART_DMA_EN_RX | MTK_UART_DMA_EN_TX);
|
||||
|
||||
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
|
||||
serial_out(up, UART_EFR, UART_EFR_ECB);
|
||||
serial_out(up, MTK_UART_EFR, UART_EFR_ECB);
|
||||
serial_out(up, UART_LCR, lcr);
|
||||
|
||||
if (dmaengine_slave_config(dma->rxchan, &dma->rxconf) != 0)
|
||||
@@ -232,7 +239,7 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
|
||||
int lcr = serial_in(up, UART_LCR);
|
||||
|
||||
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
|
||||
serial_out(up, UART_EFR, UART_EFR_ECB);
|
||||
serial_out(up, MTK_UART_EFR, UART_EFR_ECB);
|
||||
serial_out(up, UART_LCR, lcr);
|
||||
lcr = serial_in(up, UART_LCR);
|
||||
|
||||
@@ -241,7 +248,7 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
|
||||
serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);
|
||||
serial_out(up, MTK_UART_ESCAPE_EN, 0x00);
|
||||
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
|
||||
serial_out(up, UART_EFR, serial_in(up, UART_EFR) &
|
||||
serial_out(up, MTK_UART_EFR, serial_in(up, MTK_UART_EFR) &
|
||||
(~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)));
|
||||
serial_out(up, UART_LCR, lcr);
|
||||
mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI |
|
||||
@@ -255,8 +262,8 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
|
||||
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
|
||||
|
||||
/*enable hw flow control*/
|
||||
serial_out(up, UART_EFR, MTK_UART_EFR_HW_FC |
|
||||
(serial_in(up, UART_EFR) &
|
||||
serial_out(up, MTK_UART_EFR, MTK_UART_EFR_HW_FC |
|
||||
(serial_in(up, MTK_UART_EFR) &
|
||||
(~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))));
|
||||
|
||||
serial_out(up, UART_LCR, lcr);
|
||||
@@ -270,12 +277,12 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
|
||||
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
|
||||
|
||||
/*enable sw flow control */
|
||||
serial_out(up, UART_EFR, MTK_UART_EFR_XON1_XOFF1 |
|
||||
(serial_in(up, UART_EFR) &
|
||||
serial_out(up, MTK_UART_EFR, MTK_UART_EFR_XON1_XOFF1 |
|
||||
(serial_in(up, MTK_UART_EFR) &
|
||||
(~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))));
|
||||
|
||||
serial_out(up, UART_XON1, START_CHAR(port->state->port.tty));
|
||||
serial_out(up, UART_XOFF1, STOP_CHAR(port->state->port.tty));
|
||||
serial_out(up, MTK_UART_XON1, START_CHAR(port->state->port.tty));
|
||||
serial_out(up, MTK_UART_XOFF1, STOP_CHAR(port->state->port.tty));
|
||||
serial_out(up, UART_LCR, lcr);
|
||||
mtk8250_disable_intrs(up, MTK_UART_IER_CTSI|MTK_UART_IER_RTSI);
|
||||
mtk8250_enable_intrs(up, MTK_UART_IER_XOFFI);
|
||||
@@ -568,6 +575,10 @@ static int mtk8250_probe(struct platform_device *pdev)
|
||||
uart.dma = data->dma;
|
||||
#endif
|
||||
|
||||
/* Set AP UART new register map */
|
||||
writel(MTK_UART_FEAT_NEWRMAP, uart.port.membase +
|
||||
(MTK_UART_FEATURE_SEL << uart.port.regshift));
|
||||
|
||||
/* Disable Rate Fix function */
|
||||
writel(0x0, uart.port.membase +
|
||||
(MTK_UART_RATE_FIX << uart.port.regshift));
|
||||
|
||||
@@ -471,11 +471,10 @@ static int digicolor_uart_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(uart_clk))
|
||||
return PTR_ERR(uart_clk);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
dp->port.mapbase = res->start;
|
||||
dp->port.membase = devm_ioremap_resource(&pdev->dev, res);
|
||||
dp->port.membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(dp->port.membase))
|
||||
return PTR_ERR(dp->port.membase);
|
||||
dp->port.mapbase = res->start;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
|
||||
@@ -2664,6 +2664,7 @@ static int lpuart_probe(struct platform_device *pdev)
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct lpuart_port *sport;
|
||||
struct resource *res;
|
||||
irq_handler_t handler;
|
||||
int ret;
|
||||
|
||||
sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
|
||||
@@ -2741,17 +2742,11 @@ static int lpuart_probe(struct platform_device *pdev)
|
||||
|
||||
if (lpuart_is_32(sport)) {
|
||||
lpuart_reg.cons = LPUART32_CONSOLE;
|
||||
ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0,
|
||||
DRIVER_NAME, sport);
|
||||
handler = lpuart32_int;
|
||||
} else {
|
||||
lpuart_reg.cons = LPUART_CONSOLE;
|
||||
ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart_int, 0,
|
||||
DRIVER_NAME, sport);
|
||||
handler = lpuart_int;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto failed_irq_request;
|
||||
|
||||
ret = uart_add_one_port(&lpuart_reg, &sport->port);
|
||||
if (ret)
|
||||
goto failed_attach_port;
|
||||
@@ -2773,13 +2768,18 @@ static int lpuart_probe(struct platform_device *pdev)
|
||||
|
||||
sport->port.rs485_config(&sport->port, &sport->port.rs485);
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, sport->port.irq, handler, 0,
|
||||
DRIVER_NAME, sport);
|
||||
if (ret)
|
||||
goto failed_irq_request;
|
||||
|
||||
return 0;
|
||||
|
||||
failed_irq_request:
|
||||
failed_get_rs485:
|
||||
failed_reset:
|
||||
uart_remove_one_port(&lpuart_reg, &sport->port);
|
||||
failed_attach_port:
|
||||
failed_irq_request:
|
||||
lpuart_disable_clks(sport);
|
||||
failed_clock_enable:
|
||||
failed_out_of_range:
|
||||
|
||||
@@ -774,6 +774,7 @@ static int wdm_release(struct inode *inode, struct file *file)
|
||||
poison_urbs(desc);
|
||||
spin_lock_irq(&desc->iuspin);
|
||||
desc->resp_count = 0;
|
||||
clear_bit(WDM_RESPONDING, &desc->flags);
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
desc->manage_power(desc->intf, 0);
|
||||
unpoison_urbs(desc);
|
||||
|
||||
@@ -890,13 +890,37 @@ static void uvc_function_unbind(struct usb_configuration *c,
|
||||
{
|
||||
struct usb_composite_dev *cdev = c->cdev;
|
||||
struct uvc_device *uvc = to_uvc(f);
|
||||
long wait_ret = 1;
|
||||
|
||||
uvcg_info(f, "%s()\n", __func__);
|
||||
|
||||
/* If we know we're connected via v4l2, then there should be a cleanup
|
||||
* of the device from userspace either via UVC_EVENT_DISCONNECT or
|
||||
* though the video device removal uevent. Allow some time for the
|
||||
* application to close out before things get deleted.
|
||||
*/
|
||||
if (uvc->func_connected) {
|
||||
uvcg_dbg(f, "waiting for clean disconnect\n");
|
||||
wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue,
|
||||
uvc->func_connected == false, msecs_to_jiffies(500));
|
||||
uvcg_dbg(f, "done waiting with ret: %ld\n", wait_ret);
|
||||
}
|
||||
|
||||
device_remove_file(&uvc->vdev.dev, &dev_attr_function_name);
|
||||
video_unregister_device(&uvc->vdev);
|
||||
v4l2_device_unregister(&uvc->v4l2_dev);
|
||||
|
||||
if (uvc->func_connected) {
|
||||
/* Wait for the release to occur to ensure there are no longer any
|
||||
* pending operations that may cause panics when resources are cleaned
|
||||
* up.
|
||||
*/
|
||||
uvcg_warn(f, "%s no clean disconnect, wait for release\n", __func__);
|
||||
wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue,
|
||||
uvc->func_connected == false, msecs_to_jiffies(1000));
|
||||
uvcg_dbg(f, "done waiting for release with ret: %ld\n", wait_ret);
|
||||
}
|
||||
|
||||
usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
|
||||
kfree(uvc->control_buf);
|
||||
|
||||
@@ -915,6 +939,7 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
|
||||
|
||||
mutex_init(&uvc->video.mutex);
|
||||
uvc->state = UVC_STATE_DISCONNECTED;
|
||||
init_waitqueue_head(&uvc->func_connected_queue);
|
||||
opts = fi_to_f_uvc_opts(fi);
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/usb/composite.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-dev.h>
|
||||
@@ -129,6 +130,7 @@ struct uvc_device {
|
||||
struct usb_function func;
|
||||
struct uvc_video video;
|
||||
bool func_connected;
|
||||
wait_queue_head_t func_connected_queue;
|
||||
|
||||
/* Descriptors */
|
||||
struct {
|
||||
|
||||
@@ -253,10 +253,11 @@ uvc_v4l2_subscribe_event(struct v4l2_fh *fh,
|
||||
|
||||
static void uvc_v4l2_disable(struct uvc_device *uvc)
|
||||
{
|
||||
uvc->func_connected = false;
|
||||
uvc_function_disconnect(uvc);
|
||||
uvcg_video_enable(&uvc->video, 0);
|
||||
uvcg_free_buffers(&uvc->video.queue);
|
||||
uvc->func_connected = false;
|
||||
wake_up_interruptible(&uvc->func_connected_queue);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -145,6 +145,7 @@ enum dev_state {
|
||||
STATE_DEV_INVALID = 0,
|
||||
STATE_DEV_OPENED,
|
||||
STATE_DEV_INITIALIZED,
|
||||
STATE_DEV_REGISTERING,
|
||||
STATE_DEV_RUNNING,
|
||||
STATE_DEV_CLOSED,
|
||||
STATE_DEV_FAILED
|
||||
@@ -508,6 +509,7 @@ static int raw_ioctl_run(struct raw_dev *dev, unsigned long value)
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
dev->state = STATE_DEV_REGISTERING;
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
|
||||
ret = usb_gadget_probe_driver(&dev->driver);
|
||||
|
||||
@@ -19,11 +19,6 @@
|
||||
#define HS_BW_BOUNDARY 6144
|
||||
/* usb2 spec section11.18.1: at most 188 FS bytes per microframe */
|
||||
#define FS_PAYLOAD_MAX 188
|
||||
/*
|
||||
* max number of microframes for split transfer,
|
||||
* for fs isoc in : 1 ss + 1 idle + 7 cs
|
||||
*/
|
||||
#define TT_MICROFRAMES_MAX 9
|
||||
|
||||
#define DBG_BUF_EN 64
|
||||
|
||||
@@ -242,28 +237,17 @@ static void drop_tt(struct usb_device *udev)
|
||||
|
||||
static struct mu3h_sch_ep_info *
|
||||
create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx)
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
struct mu3h_sch_ep_info *sch_ep;
|
||||
struct mu3h_sch_bw_info *bw_info;
|
||||
struct mu3h_sch_tt *tt = NULL;
|
||||
u32 len_bw_budget_table;
|
||||
|
||||
bw_info = get_bw_info(mtk, udev, ep);
|
||||
if (!bw_info)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
if (is_fs_or_ls(udev->speed))
|
||||
len_bw_budget_table = TT_MICROFRAMES_MAX;
|
||||
else if ((udev->speed >= USB_SPEED_SUPER)
|
||||
&& usb_endpoint_xfer_isoc(&ep->desc))
|
||||
len_bw_budget_table = get_esit(ep_ctx);
|
||||
else
|
||||
len_bw_budget_table = 1;
|
||||
|
||||
sch_ep = kzalloc(struct_size(sch_ep, bw_budget_table,
|
||||
len_bw_budget_table),
|
||||
GFP_KERNEL);
|
||||
sch_ep = kzalloc(sizeof(*sch_ep), GFP_KERNEL);
|
||||
if (!sch_ep)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -295,8 +279,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
u32 mult;
|
||||
u32 esit_pkts;
|
||||
u32 max_esit_payload;
|
||||
u32 *bwb_table = sch_ep->bw_budget_table;
|
||||
int i;
|
||||
|
||||
ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
|
||||
maxpkt = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
|
||||
@@ -332,7 +314,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
*/
|
||||
sch_ep->pkts = max_burst + 1;
|
||||
sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
|
||||
bwb_table[0] = sch_ep->bw_cost_per_microframe;
|
||||
} else if (sch_ep->speed >= USB_SPEED_SUPER) {
|
||||
/* usb3_r1 spec section4.4.7 & 4.4.8 */
|
||||
sch_ep->cs_count = 0;
|
||||
@@ -349,7 +330,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
|
||||
sch_ep->pkts = esit_pkts;
|
||||
sch_ep->num_budget_microframes = 1;
|
||||
bwb_table[0] = maxpkt * sch_ep->pkts;
|
||||
}
|
||||
|
||||
if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) {
|
||||
@@ -366,15 +346,8 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
DIV_ROUND_UP(esit_pkts, sch_ep->pkts);
|
||||
|
||||
sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1);
|
||||
sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
|
||||
|
||||
for (i = 0; i < sch_ep->num_budget_microframes - 1; i++)
|
||||
bwb_table[i] = sch_ep->bw_cost_per_microframe;
|
||||
|
||||
/* last one <= bw_cost_per_microframe */
|
||||
bwb_table[i] = maxpkt * esit_pkts
|
||||
- i * sch_ep->bw_cost_per_microframe;
|
||||
}
|
||||
sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
|
||||
} else if (is_fs_or_ls(sch_ep->speed)) {
|
||||
sch_ep->pkts = 1; /* at most one packet for each microframe */
|
||||
|
||||
@@ -384,28 +357,7 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
*/
|
||||
sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX);
|
||||
sch_ep->num_budget_microframes = sch_ep->cs_count;
|
||||
sch_ep->bw_cost_per_microframe =
|
||||
(maxpkt < FS_PAYLOAD_MAX) ? maxpkt : FS_PAYLOAD_MAX;
|
||||
|
||||
/* init budget table */
|
||||
if (ep_type == ISOC_OUT_EP) {
|
||||
for (i = 0; i < sch_ep->num_budget_microframes; i++)
|
||||
bwb_table[i] = sch_ep->bw_cost_per_microframe;
|
||||
} else if (ep_type == INT_OUT_EP) {
|
||||
/* only first one consumes bandwidth, others as zero */
|
||||
bwb_table[0] = sch_ep->bw_cost_per_microframe;
|
||||
} else { /* INT_IN_EP or ISOC_IN_EP */
|
||||
bwb_table[0] = 0; /* start split */
|
||||
bwb_table[1] = 0; /* idle */
|
||||
/*
|
||||
* due to cs_count will be updated according to cs
|
||||
* position, assign all remainder budget array
|
||||
* elements as @bw_cost_per_microframe, but only first
|
||||
* @num_budget_microframes elements will be used later
|
||||
*/
|
||||
for (i = 2; i < TT_MICROFRAMES_MAX; i++)
|
||||
bwb_table[i] = sch_ep->bw_cost_per_microframe;
|
||||
}
|
||||
sch_ep->bw_cost_per_microframe = min_t(u32, maxpkt, FS_PAYLOAD_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,7 +374,7 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++) {
|
||||
k = XHCI_MTK_BW_INDEX(base + j);
|
||||
bw = sch_bw->bus_bw[k] + sch_ep->bw_budget_table[j];
|
||||
bw = sch_bw->bus_bw[k] + sch_ep->bw_cost_per_microframe;
|
||||
if (bw > max_bw)
|
||||
max_bw = bw;
|
||||
}
|
||||
@@ -433,18 +385,16 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
struct mu3h_sch_ep_info *sch_ep, bool used)
|
||||
{
|
||||
int bw_updated;
|
||||
u32 base;
|
||||
int i, j, k;
|
||||
int i, j;
|
||||
|
||||
bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1);
|
||||
|
||||
for (i = 0; i < sch_ep->num_esit; i++) {
|
||||
base = sch_ep->offset + i * sch_ep->esit;
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++) {
|
||||
k = XHCI_MTK_BW_INDEX(base + j);
|
||||
if (used)
|
||||
sch_bw->bus_bw[k] += sch_ep->bw_budget_table[j];
|
||||
else
|
||||
sch_bw->bus_bw[k] -= sch_ep->bw_budget_table[j];
|
||||
}
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++)
|
||||
sch_bw->bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,7 +414,7 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
|
||||
*/
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++) {
|
||||
k = XHCI_MTK_BW_INDEX(base + j);
|
||||
tmp = tt->fs_bus_bw[k] + sch_ep->bw_budget_table[j];
|
||||
tmp = tt->fs_bus_bw[k] + sch_ep->bw_cost_per_microframe;
|
||||
if (tmp > FS_PAYLOAD_MAX)
|
||||
return -ESCH_BW_OVERFLOW;
|
||||
}
|
||||
@@ -538,19 +488,17 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
|
||||
static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
|
||||
{
|
||||
struct mu3h_sch_tt *tt = sch_ep->sch_tt;
|
||||
int bw_updated;
|
||||
u32 base;
|
||||
int i, j, k;
|
||||
int i, j;
|
||||
|
||||
bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1);
|
||||
|
||||
for (i = 0; i < sch_ep->num_esit; i++) {
|
||||
base = sch_ep->offset + i * sch_ep->esit;
|
||||
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++) {
|
||||
k = XHCI_MTK_BW_INDEX(base + j);
|
||||
if (used)
|
||||
tt->fs_bus_bw[k] += sch_ep->bw_budget_table[j];
|
||||
else
|
||||
tt->fs_bus_bw[k] -= sch_ep->bw_budget_table[j];
|
||||
}
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++)
|
||||
tt->fs_bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated;
|
||||
}
|
||||
|
||||
if (used)
|
||||
@@ -710,7 +658,7 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
|
||||
xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
|
||||
|
||||
sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx);
|
||||
sch_ep = create_sch_ep(mtk, udev, ep);
|
||||
if (IS_ERR_OR_NULL(sch_ep))
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -83,7 +83,6 @@ struct mu3h_sch_bw_info {
|
||||
* times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets
|
||||
* according to @pkts and @repeat. normal mode is used by
|
||||
* default
|
||||
* @bw_budget_table: table to record bandwidth budget per microframe
|
||||
*/
|
||||
struct mu3h_sch_ep_info {
|
||||
u32 esit;
|
||||
@@ -109,7 +108,6 @@ struct mu3h_sch_ep_info {
|
||||
u32 pkts;
|
||||
u32 cs_count;
|
||||
u32 burst_mode;
|
||||
u32 bw_budget_table[];
|
||||
};
|
||||
|
||||
#define MU3C_U3_PORT_MAX 4
|
||||
|
||||
@@ -2123,10 +2123,14 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = RSVD(3) },
|
||||
{ USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */
|
||||
.driver_info = RSVD(4) | RSVD(5) | RSVD(6) },
|
||||
{ USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x1782, 0x4d11, 0xff) }, /* Fibocom L610 (ECM/RNDIS mode) */
|
||||
{ USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */
|
||||
.driver_info = RSVD(4) | RSVD(5) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */
|
||||
.driver_info = RSVD(6) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0106, 0xff) }, /* Fibocom MA510 (ECM mode w/ diag intf.) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x010a, 0xff) }, /* Fibocom MA510 (ECM mode) */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
|
||||
|
||||
@@ -106,6 +106,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LM920_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LM930_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LM940_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_TD620_PRODUCT_ID) },
|
||||
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
#define HP_TD620_PRODUCT_ID 0x0956
|
||||
#define HP_LD960_PRODUCT_ID 0x0b39
|
||||
#define HP_LD381_PRODUCT_ID 0x0f7f
|
||||
#define HP_LM930_PRODUCT_ID 0x0f9b
|
||||
#define HP_LCM220_PRODUCT_ID 0x3139
|
||||
#define HP_LCM960_PRODUCT_ID 0x3239
|
||||
#define HP_LD220_PRODUCT_ID 0x3524
|
||||
|
||||
@@ -166,6 +166,8 @@ static const struct usb_device_id id_table[] = {
|
||||
{DEVICE_SWI(0x1199, 0x9090)}, /* Sierra Wireless EM7565 QDL */
|
||||
{DEVICE_SWI(0x1199, 0x9091)}, /* Sierra Wireless EM7565 */
|
||||
{DEVICE_SWI(0x1199, 0x90d2)}, /* Sierra Wireless EM9191 QDL */
|
||||
{DEVICE_SWI(0x1199, 0xc080)}, /* Sierra Wireless EM7590 QDL */
|
||||
{DEVICE_SWI(0x1199, 0xc081)}, /* Sierra Wireless EM7590 */
|
||||
{DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
|
||||
|
||||
@@ -877,7 +877,7 @@ static int tcpci_remove(struct i2c_client *client)
|
||||
/* Disable chip interrupts before unregistering port */
|
||||
err = tcpci_write16(chip->tcpci, TCPC_ALERT_MASK, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
dev_warn(&client->dev, "Failed to disable irqs (%pe)\n", ERR_PTR(err));
|
||||
|
||||
tcpci_unregister_port(chip->tcpci);
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
|
||||
#include "tcpci.h"
|
||||
|
||||
#define MT6360_REG_PHYCTRL1 0x80
|
||||
#define MT6360_REG_PHYCTRL3 0x82
|
||||
#define MT6360_REG_PHYCTRL7 0x86
|
||||
#define MT6360_REG_VCONNCTRL1 0x8C
|
||||
#define MT6360_REG_MODECTRL2 0x8F
|
||||
#define MT6360_REG_SWRESET 0xA0
|
||||
@@ -22,6 +25,8 @@
|
||||
#define MT6360_REG_DRPCTRL1 0xA2
|
||||
#define MT6360_REG_DRPCTRL2 0xA3
|
||||
#define MT6360_REG_I2CTORST 0xBF
|
||||
#define MT6360_REG_PHYCTRL11 0xCA
|
||||
#define MT6360_REG_RXCTRL1 0xCE
|
||||
#define MT6360_REG_RXCTRL2 0xCF
|
||||
#define MT6360_REG_CTDCTRL2 0xEC
|
||||
|
||||
@@ -106,6 +111,27 @@ static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* BMC PHY */
|
||||
ret = mt6360_tcpc_write16(regmap, MT6360_REG_PHYCTRL1, 0x3A70);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write(regmap, MT6360_REG_PHYCTRL3, 0x82);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write(regmap, MT6360_REG_PHYCTRL7, 0x36);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mt6360_tcpc_write16(regmap, MT6360_REG_PHYCTRL11, 0x3C60);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write(regmap, MT6360_REG_RXCTRL1, 0xE8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set shipping mode off, AUTOIDLE on */
|
||||
return regmap_write(regmap, MT6360_REG_MODECTRL2, 0x7A);
|
||||
}
|
||||
|
||||
@@ -1434,10 +1434,7 @@ fb_release(struct inode *inode, struct file *file)
|
||||
__acquires(&info->lock)
|
||||
__releases(&info->lock)
|
||||
{
|
||||
struct fb_info * const info = file_fb_info(file);
|
||||
|
||||
if (!info)
|
||||
return -ENODEV;
|
||||
struct fb_info * const info = file->private_data;
|
||||
|
||||
lock_fb_info(info);
|
||||
if (info->fbops->fb_release)
|
||||
|
||||
@@ -80,6 +80,10 @@ void framebuffer_release(struct fb_info *info)
|
||||
{
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (WARN_ON(refcount_read(&info->count)))
|
||||
return;
|
||||
|
||||
kfree(info->apertures);
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
@@ -243,6 +243,10 @@ error:
|
||||
static inline void efifb_show_boot_graphics(struct fb_info *info) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fb_ops.fb_destroy is called by the last put_fb_info() call at the end
|
||||
* of unregister_framebuffer() or fb_release(). Do any cleanup here.
|
||||
*/
|
||||
static void efifb_destroy(struct fb_info *info)
|
||||
{
|
||||
if (efifb_pci_dev)
|
||||
@@ -254,10 +258,13 @@ static void efifb_destroy(struct fb_info *info)
|
||||
else
|
||||
memunmap(info->screen_base);
|
||||
}
|
||||
|
||||
if (request_mem_succeeded)
|
||||
release_mem_region(info->apertures->ranges[0].base,
|
||||
info->apertures->ranges[0].size);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
|
||||
framebuffer_release(info);
|
||||
}
|
||||
|
||||
static const struct fb_ops efifb_ops = {
|
||||
@@ -620,9 +627,9 @@ static int efifb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fb_info *info = platform_get_drvdata(pdev);
|
||||
|
||||
/* efifb_destroy takes care of info cleanup */
|
||||
unregister_framebuffer(info);
|
||||
sysfs_remove_groups(&pdev->dev.kobj, efifb_groups);
|
||||
framebuffer_release(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -84,6 +84,10 @@ struct simplefb_par {
|
||||
static void simplefb_clocks_destroy(struct simplefb_par *par);
|
||||
static void simplefb_regulators_destroy(struct simplefb_par *par);
|
||||
|
||||
/*
|
||||
* fb_ops.fb_destroy is called by the last put_fb_info() call at the end
|
||||
* of unregister_framebuffer() or fb_release(). Do any cleanup here.
|
||||
*/
|
||||
static void simplefb_destroy(struct fb_info *info)
|
||||
{
|
||||
struct simplefb_par *par = info->par;
|
||||
@@ -94,6 +98,8 @@ static void simplefb_destroy(struct fb_info *info)
|
||||
if (info->screen_base)
|
||||
iounmap(info->screen_base);
|
||||
|
||||
framebuffer_release(info);
|
||||
|
||||
if (mem)
|
||||
release_mem_region(mem->start, resource_size(mem));
|
||||
}
|
||||
@@ -545,8 +551,8 @@ static int simplefb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fb_info *info = platform_get_drvdata(pdev);
|
||||
|
||||
/* simplefb_destroy takes care of info cleanup */
|
||||
unregister_framebuffer(info);
|
||||
framebuffer_release(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -179,6 +179,10 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* fb_ops.fb_destroy is called by the last put_fb_info() call at the end
|
||||
* of unregister_framebuffer() or fb_release(). Do any cleanup here.
|
||||
*/
|
||||
static void vesafb_destroy(struct fb_info *info)
|
||||
{
|
||||
struct vesafb_par *par = info->par;
|
||||
@@ -188,6 +192,8 @@ static void vesafb_destroy(struct fb_info *info)
|
||||
if (info->screen_base)
|
||||
iounmap(info->screen_base);
|
||||
release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size);
|
||||
|
||||
framebuffer_release(info);
|
||||
}
|
||||
|
||||
static struct fb_ops vesafb_ops = {
|
||||
@@ -484,10 +490,10 @@ static int vesafb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fb_info *info = platform_get_drvdata(pdev);
|
||||
|
||||
/* vesafb_destroy takes care of info cleanup */
|
||||
unregister_framebuffer(info);
|
||||
if (((struct vesafb_par *)(info->par))->region)
|
||||
release_region(0x3c0, 32);
|
||||
framebuffer_release(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+7
-4
@@ -85,7 +85,7 @@ static bool ceph_dirty_folio(struct address_space *mapping, struct folio *folio)
|
||||
if (folio_test_dirty(folio)) {
|
||||
dout("%p dirty_folio %p idx %lu -- already dirty\n",
|
||||
mapping->host, folio, folio->index);
|
||||
BUG_ON(!folio_get_private(folio));
|
||||
VM_BUG_ON_FOLIO(!folio_test_private(folio), folio);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ static bool ceph_dirty_folio(struct address_space *mapping, struct folio *folio)
|
||||
* Reference snap context in folio->private. Also set
|
||||
* PagePrivate so that we get invalidate_folio callback.
|
||||
*/
|
||||
BUG_ON(folio_get_private(folio));
|
||||
VM_BUG_ON_FOLIO(folio_test_private(folio), folio);
|
||||
folio_attach_private(folio, snapc);
|
||||
|
||||
return ceph_fscache_dirty_folio(mapping, folio);
|
||||
@@ -150,7 +150,7 @@ static void ceph_invalidate_folio(struct folio *folio, size_t offset,
|
||||
}
|
||||
|
||||
WARN_ON(!folio_test_locked(folio));
|
||||
if (folio_get_private(folio)) {
|
||||
if (folio_test_private(folio)) {
|
||||
dout("%p invalidate_folio idx %lu full dirty page\n",
|
||||
inode, folio->index);
|
||||
|
||||
@@ -729,8 +729,11 @@ static void writepages_finish(struct ceph_osd_request *req)
|
||||
|
||||
/* clean all pages */
|
||||
for (i = 0; i < req->r_num_ops; i++) {
|
||||
if (req->r_ops[i].op != CEPH_OSD_OP_WRITE)
|
||||
if (req->r_ops[i].op != CEPH_OSD_OP_WRITE) {
|
||||
pr_warn("%s incorrect op %d req %p index %d tid %llu\n",
|
||||
__func__, req->r_ops[i].op, req, i, req->r_tid);
|
||||
break;
|
||||
}
|
||||
|
||||
osd_data = osd_req_op_extent_osd_data(req, i);
|
||||
BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_PAGES);
|
||||
|
||||
+13
-3
@@ -629,9 +629,15 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
|
||||
iinfo.change_attr = 1;
|
||||
ceph_encode_timespec64(&iinfo.btime, &now);
|
||||
|
||||
iinfo.xattr_len = ARRAY_SIZE(xattr_buf);
|
||||
iinfo.xattr_data = xattr_buf;
|
||||
memset(iinfo.xattr_data, 0, iinfo.xattr_len);
|
||||
if (req->r_pagelist) {
|
||||
iinfo.xattr_len = req->r_pagelist->length;
|
||||
iinfo.xattr_data = req->r_pagelist->mapped_tail;
|
||||
} else {
|
||||
/* fake it */
|
||||
iinfo.xattr_len = ARRAY_SIZE(xattr_buf);
|
||||
iinfo.xattr_data = xattr_buf;
|
||||
memset(iinfo.xattr_data, 0, iinfo.xattr_len);
|
||||
}
|
||||
|
||||
in.ino = cpu_to_le64(vino.ino);
|
||||
in.snapid = cpu_to_le64(CEPH_NOSNAP);
|
||||
@@ -743,6 +749,10 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||
err = ceph_security_init_secctx(dentry, mode, &as_ctx);
|
||||
if (err < 0)
|
||||
goto out_ctx;
|
||||
/* Async create can't handle more than a page of xattrs */
|
||||
if (as_ctx.pagelist &&
|
||||
!list_is_singular(&as_ctx.pagelist->head))
|
||||
try_async = false;
|
||||
} else if (!d_in_lookup(dentry)) {
|
||||
/* If it's not being looked up, it's negative */
|
||||
return -ENOENT;
|
||||
|
||||
+5
-6
@@ -1153,13 +1153,12 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
|
||||
|
||||
if (length != written && (iomap->flags & IOMAP_F_NEW)) {
|
||||
/* Deallocate blocks that were just allocated. */
|
||||
loff_t blockmask = i_blocksize(inode) - 1;
|
||||
loff_t end = (pos + length) & ~blockmask;
|
||||
loff_t hstart = round_up(pos + written, i_blocksize(inode));
|
||||
loff_t hend = iomap->offset + iomap->length;
|
||||
|
||||
pos = (pos + written + blockmask) & ~blockmask;
|
||||
if (pos < end) {
|
||||
truncate_pagecache_range(inode, pos, end - 1);
|
||||
punch_hole(ip, pos, end - pos);
|
||||
if (hstart < hend) {
|
||||
truncate_pagecache_range(inode, hstart, hend - 1);
|
||||
punch_hole(ip, hstart, hend - hstart);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+65
-78
@@ -770,30 +770,27 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
|
||||
return ret ? ret : ret1;
|
||||
}
|
||||
|
||||
static inline bool should_fault_in_pages(ssize_t ret, struct iov_iter *i,
|
||||
static inline bool should_fault_in_pages(struct iov_iter *i,
|
||||
struct kiocb *iocb,
|
||||
size_t *prev_count,
|
||||
size_t *window_size)
|
||||
{
|
||||
size_t count = iov_iter_count(i);
|
||||
size_t size, offs;
|
||||
|
||||
if (likely(!count))
|
||||
return false;
|
||||
if (ret <= 0 && ret != -EFAULT)
|
||||
if (!count)
|
||||
return false;
|
||||
if (!iter_is_iovec(i))
|
||||
return false;
|
||||
|
||||
size = PAGE_SIZE;
|
||||
offs = offset_in_page(i->iov[0].iov_base + i->iov_offset);
|
||||
offs = offset_in_page(iocb->ki_pos);
|
||||
if (*prev_count != count || !*window_size) {
|
||||
size_t nr_dirtied;
|
||||
|
||||
size = ALIGN(offs + count, PAGE_SIZE);
|
||||
size = min_t(size_t, size, SZ_1M);
|
||||
nr_dirtied = max(current->nr_dirtied_pause -
|
||||
current->nr_dirtied, 8);
|
||||
size = min(size, nr_dirtied << PAGE_SHIFT);
|
||||
size = min_t(size_t, SZ_1M, nr_dirtied << PAGE_SHIFT);
|
||||
}
|
||||
|
||||
*prev_count = count;
|
||||
@@ -807,7 +804,7 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
|
||||
size_t prev_count = 0, window_size = 0;
|
||||
size_t written = 0;
|
||||
size_t read = 0;
|
||||
ssize_t ret;
|
||||
|
||||
/*
|
||||
@@ -835,35 +832,31 @@ retry:
|
||||
ret = gfs2_glock_nq(gh);
|
||||
if (ret)
|
||||
goto out_uninit;
|
||||
retry_under_glock:
|
||||
pagefault_disable();
|
||||
to->nofault = true;
|
||||
ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL,
|
||||
IOMAP_DIO_PARTIAL, written);
|
||||
IOMAP_DIO_PARTIAL, read);
|
||||
to->nofault = false;
|
||||
pagefault_enable();
|
||||
if (ret <= 0 && ret != -EFAULT)
|
||||
goto out_unlock;
|
||||
if (ret > 0)
|
||||
written = ret;
|
||||
read = ret;
|
||||
|
||||
if (should_fault_in_pages(ret, to, &prev_count, &window_size)) {
|
||||
size_t leftover;
|
||||
|
||||
gfs2_holder_allow_demote(gh);
|
||||
leftover = fault_in_iov_iter_writeable(to, window_size);
|
||||
gfs2_holder_disallow_demote(gh);
|
||||
if (leftover != window_size) {
|
||||
if (gfs2_holder_queued(gh))
|
||||
goto retry_under_glock;
|
||||
if (should_fault_in_pages(to, iocb, &prev_count, &window_size)) {
|
||||
gfs2_glock_dq(gh);
|
||||
window_size -= fault_in_iov_iter_writeable(to, window_size);
|
||||
if (window_size)
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
out_unlock:
|
||||
if (gfs2_holder_queued(gh))
|
||||
gfs2_glock_dq(gh);
|
||||
out_uninit:
|
||||
gfs2_holder_uninit(gh);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return written;
|
||||
return read;
|
||||
}
|
||||
|
||||
static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
|
||||
@@ -873,7 +866,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
struct gfs2_inode *ip = GFS2_I(inode);
|
||||
size_t prev_count = 0, window_size = 0;
|
||||
size_t read = 0;
|
||||
size_t written = 0;
|
||||
ssize_t ret;
|
||||
|
||||
/*
|
||||
@@ -901,39 +894,35 @@ retry:
|
||||
goto out_uninit;
|
||||
/* Silently fall back to buffered I/O when writing beyond EOF */
|
||||
if (iocb->ki_pos + iov_iter_count(from) > i_size_read(&ip->i_inode))
|
||||
goto out;
|
||||
retry_under_glock:
|
||||
goto out_unlock;
|
||||
|
||||
from->nofault = true;
|
||||
ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL,
|
||||
IOMAP_DIO_PARTIAL, read);
|
||||
IOMAP_DIO_PARTIAL, written);
|
||||
from->nofault = false;
|
||||
|
||||
if (ret == -ENOTBLK)
|
||||
ret = 0;
|
||||
if (ret > 0)
|
||||
read = ret;
|
||||
|
||||
if (should_fault_in_pages(ret, from, &prev_count, &window_size)) {
|
||||
size_t leftover;
|
||||
|
||||
gfs2_holder_allow_demote(gh);
|
||||
leftover = fault_in_iov_iter_readable(from, window_size);
|
||||
gfs2_holder_disallow_demote(gh);
|
||||
if (leftover != window_size) {
|
||||
if (gfs2_holder_queued(gh))
|
||||
goto retry_under_glock;
|
||||
goto retry;
|
||||
}
|
||||
if (ret <= 0) {
|
||||
if (ret == -ENOTBLK)
|
||||
ret = 0;
|
||||
if (ret != -EFAULT)
|
||||
goto out_unlock;
|
||||
}
|
||||
out:
|
||||
if (ret > 0)
|
||||
written = ret;
|
||||
|
||||
if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
|
||||
gfs2_glock_dq(gh);
|
||||
window_size -= fault_in_iov_iter_readable(from, window_size);
|
||||
if (window_size)
|
||||
goto retry;
|
||||
}
|
||||
out_unlock:
|
||||
if (gfs2_holder_queued(gh))
|
||||
gfs2_glock_dq(gh);
|
||||
out_uninit:
|
||||
gfs2_holder_uninit(gh);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return read;
|
||||
return written;
|
||||
}
|
||||
|
||||
static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
@@ -941,7 +930,7 @@ static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
struct gfs2_inode *ip;
|
||||
struct gfs2_holder gh;
|
||||
size_t prev_count = 0, window_size = 0;
|
||||
size_t written = 0;
|
||||
size_t read = 0;
|
||||
ssize_t ret;
|
||||
|
||||
/*
|
||||
@@ -962,7 +951,7 @@ static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
if (ret >= 0) {
|
||||
if (!iov_iter_count(to))
|
||||
return ret;
|
||||
written = ret;
|
||||
read = ret;
|
||||
} else if (ret != -EFAULT) {
|
||||
if (ret != -EAGAIN)
|
||||
return ret;
|
||||
@@ -975,30 +964,26 @@ retry:
|
||||
ret = gfs2_glock_nq(&gh);
|
||||
if (ret)
|
||||
goto out_uninit;
|
||||
retry_under_glock:
|
||||
pagefault_disable();
|
||||
ret = generic_file_read_iter(iocb, to);
|
||||
pagefault_enable();
|
||||
if (ret <= 0 && ret != -EFAULT)
|
||||
goto out_unlock;
|
||||
if (ret > 0)
|
||||
written += ret;
|
||||
read += ret;
|
||||
|
||||
if (should_fault_in_pages(ret, to, &prev_count, &window_size)) {
|
||||
size_t leftover;
|
||||
|
||||
gfs2_holder_allow_demote(&gh);
|
||||
leftover = fault_in_iov_iter_writeable(to, window_size);
|
||||
gfs2_holder_disallow_demote(&gh);
|
||||
if (leftover != window_size) {
|
||||
if (gfs2_holder_queued(&gh))
|
||||
goto retry_under_glock;
|
||||
if (should_fault_in_pages(to, iocb, &prev_count, &window_size)) {
|
||||
gfs2_glock_dq(&gh);
|
||||
window_size -= fault_in_iov_iter_writeable(to, window_size);
|
||||
if (window_size)
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
out_unlock:
|
||||
if (gfs2_holder_queued(&gh))
|
||||
gfs2_glock_dq(&gh);
|
||||
out_uninit:
|
||||
gfs2_holder_uninit(&gh);
|
||||
return written ? written : ret;
|
||||
return read ? read : ret;
|
||||
}
|
||||
|
||||
static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
|
||||
@@ -1012,7 +997,7 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
|
||||
struct gfs2_holder *statfs_gh = NULL;
|
||||
size_t prev_count = 0, window_size = 0;
|
||||
size_t orig_count = iov_iter_count(from);
|
||||
size_t read = 0;
|
||||
size_t written = 0;
|
||||
ssize_t ret;
|
||||
|
||||
/*
|
||||
@@ -1030,10 +1015,18 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
|
||||
|
||||
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, gh);
|
||||
retry:
|
||||
if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
|
||||
window_size -= fault_in_iov_iter_readable(from, window_size);
|
||||
if (!window_size) {
|
||||
ret = -EFAULT;
|
||||
goto out_uninit;
|
||||
}
|
||||
from->count = min(from->count, window_size);
|
||||
}
|
||||
ret = gfs2_glock_nq(gh);
|
||||
if (ret)
|
||||
goto out_uninit;
|
||||
retry_under_glock:
|
||||
|
||||
if (inode == sdp->sd_rindex) {
|
||||
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
|
||||
|
||||
@@ -1050,25 +1043,19 @@ retry_under_glock:
|
||||
current->backing_dev_info = NULL;
|
||||
if (ret > 0) {
|
||||
iocb->ki_pos += ret;
|
||||
read += ret;
|
||||
written += ret;
|
||||
}
|
||||
|
||||
if (inode == sdp->sd_rindex)
|
||||
gfs2_glock_dq_uninit(statfs_gh);
|
||||
|
||||
from->count = orig_count - read;
|
||||
if (should_fault_in_pages(ret, from, &prev_count, &window_size)) {
|
||||
size_t leftover;
|
||||
if (ret <= 0 && ret != -EFAULT)
|
||||
goto out_unlock;
|
||||
|
||||
gfs2_holder_allow_demote(gh);
|
||||
leftover = fault_in_iov_iter_readable(from, window_size);
|
||||
gfs2_holder_disallow_demote(gh);
|
||||
if (leftover != window_size) {
|
||||
from->count = min(from->count, window_size - leftover);
|
||||
if (gfs2_holder_queued(gh))
|
||||
goto retry_under_glock;
|
||||
goto retry;
|
||||
}
|
||||
from->count = orig_count - written;
|
||||
if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
|
||||
gfs2_glock_dq(gh);
|
||||
goto retry;
|
||||
}
|
||||
out_unlock:
|
||||
if (gfs2_holder_queued(gh))
|
||||
@@ -1077,8 +1064,8 @@ out_uninit:
|
||||
gfs2_holder_uninit(gh);
|
||||
if (statfs_gh)
|
||||
kfree(statfs_gh);
|
||||
from->count = orig_count - read;
|
||||
return read ? read : ret;
|
||||
from->count = orig_count - written;
|
||||
return written ? written : ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -517,7 +517,7 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
|
||||
if (result.negated)
|
||||
ctx->flags &= ~NFS_MOUNT_SOFTREVAL;
|
||||
else
|
||||
ctx->flags &= NFS_MOUNT_SOFTREVAL;
|
||||
ctx->flags |= NFS_MOUNT_SOFTREVAL;
|
||||
break;
|
||||
case Opt_posix:
|
||||
if (result.negated)
|
||||
|
||||
+22
-1
@@ -72,7 +72,7 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int seq_fdinfo_open(struct inode *inode, struct file *file)
|
||||
static int proc_fdinfo_access_allowed(struct inode *inode)
|
||||
{
|
||||
bool allowed = false;
|
||||
struct task_struct *task = get_proc_task(inode);
|
||||
@@ -86,6 +86,16 @@ static int seq_fdinfo_open(struct inode *inode, struct file *file)
|
||||
if (!allowed)
|
||||
return -EACCES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int seq_fdinfo_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret = proc_fdinfo_access_allowed(inode);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return single_open(file, seq_show, inode);
|
||||
}
|
||||
|
||||
@@ -348,12 +358,23 @@ static int proc_readfdinfo(struct file *file, struct dir_context *ctx)
|
||||
proc_fdinfo_instantiate);
|
||||
}
|
||||
|
||||
static int proc_open_fdinfo(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret = proc_fdinfo_access_allowed(inode);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct inode_operations proc_fdinfo_inode_operations = {
|
||||
.lookup = proc_lookupfdinfo,
|
||||
.setattr = proc_setattr,
|
||||
};
|
||||
|
||||
const struct file_operations proc_fdinfo_operations = {
|
||||
.open = proc_open_fdinfo,
|
||||
.read = generic_read_dir,
|
||||
.iterate_shared = proc_readfdinfo,
|
||||
.llseek = generic_file_llseek,
|
||||
|
||||
@@ -160,7 +160,7 @@ struct rpc_add_xprt_test {
|
||||
#define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9)
|
||||
#define RPC_CLNT_CREATE_SOFTERR (1UL << 10)
|
||||
#define RPC_CLNT_CREATE_REUSEPORT (1UL << 11)
|
||||
#define RPC_CLNT_CREATE_IGNORE_NULL_UNAVAIL (1UL << 12)
|
||||
#define RPC_CLNT_CREATE_CONNECTED (1UL << 12)
|
||||
|
||||
struct rpc_clnt *rpc_create(struct rpc_create_args *args);
|
||||
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
|
||||
|
||||
@@ -222,11 +222,11 @@ static inline long __trace_sched_switch_state(bool preempt,
|
||||
TRACE_EVENT(sched_switch,
|
||||
|
||||
TP_PROTO(bool preempt,
|
||||
unsigned int prev_state,
|
||||
struct task_struct *prev,
|
||||
struct task_struct *next),
|
||||
struct task_struct *next,
|
||||
unsigned int prev_state),
|
||||
|
||||
TP_ARGS(preempt, prev_state, prev, next),
|
||||
TP_ARGS(preempt, prev, next, prev_state),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__array( char, prev_comm, TASK_COMM_LEN )
|
||||
|
||||
@@ -699,7 +699,6 @@ EXPORT_SYMBOL_GPL(generic_handle_irq_safe);
|
||||
*/
|
||||
int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq)
|
||||
{
|
||||
WARN_ON_ONCE(!in_hardirq());
|
||||
return handle_irq_desc(irq_resolve_mapping(domain, hwirq));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(generic_handle_domain_irq);
|
||||
|
||||
+1
-1
@@ -6457,7 +6457,7 @@ static void __sched notrace __schedule(unsigned int sched_mode)
|
||||
migrate_disable_switch(rq, prev);
|
||||
psi_sched_switch(prev, next, !task_on_rq_queued(prev));
|
||||
|
||||
trace_sched_switch(sched_mode & SM_MASK_PREEMPT, prev_state, prev, next);
|
||||
trace_sched_switch(sched_mode & SM_MASK_PREEMPT, prev, next, prev_state);
|
||||
|
||||
/* Also unlocks the rq: */
|
||||
rq = context_switch(rq, prev, next, &rf);
|
||||
|
||||
@@ -404,9 +404,9 @@ free:
|
||||
|
||||
static void
|
||||
ftrace_graph_probe_sched_switch(void *ignore, bool preempt,
|
||||
unsigned int prev_state,
|
||||
struct task_struct *prev,
|
||||
struct task_struct *next)
|
||||
struct task_struct *next,
|
||||
unsigned int prev_state)
|
||||
{
|
||||
unsigned long long timestamp;
|
||||
int index;
|
||||
|
||||
@@ -7420,9 +7420,9 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops)
|
||||
|
||||
static void
|
||||
ftrace_filter_pid_sched_switch_probe(void *data, bool preempt,
|
||||
unsigned int prev_state,
|
||||
struct task_struct *prev,
|
||||
struct task_struct *next)
|
||||
struct task_struct *next,
|
||||
unsigned int prev_state)
|
||||
{
|
||||
struct trace_array *tr = data;
|
||||
struct trace_pid_list *pid_list;
|
||||
|
||||
@@ -773,9 +773,9 @@ void trace_event_follow_fork(struct trace_array *tr, bool enable)
|
||||
|
||||
static void
|
||||
event_filter_pid_sched_switch_probe_pre(void *data, bool preempt,
|
||||
unsigned int prev_state,
|
||||
struct task_struct *prev,
|
||||
struct task_struct *next)
|
||||
struct task_struct *next,
|
||||
unsigned int prev_state)
|
||||
{
|
||||
struct trace_array *tr = data;
|
||||
struct trace_pid_list *no_pid_list;
|
||||
@@ -799,9 +799,9 @@ event_filter_pid_sched_switch_probe_pre(void *data, bool preempt,
|
||||
|
||||
static void
|
||||
event_filter_pid_sched_switch_probe_post(void *data, bool preempt,
|
||||
unsigned int prev_state,
|
||||
struct task_struct *prev,
|
||||
struct task_struct *next)
|
||||
struct task_struct *next,
|
||||
unsigned int prev_state)
|
||||
{
|
||||
struct trace_array *tr = data;
|
||||
struct trace_pid_list *no_pid_list;
|
||||
|
||||
@@ -1168,9 +1168,9 @@ thread_exit(struct osnoise_variables *osn_var, struct task_struct *t)
|
||||
*/
|
||||
static void
|
||||
trace_sched_switch_callback(void *data, bool preempt,
|
||||
unsigned int prev_state,
|
||||
struct task_struct *p,
|
||||
struct task_struct *n)
|
||||
struct task_struct *n,
|
||||
unsigned int prev_state)
|
||||
{
|
||||
struct osnoise_variables *osn_var = this_cpu_osn_var();
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ static DEFINE_MUTEX(sched_register_mutex);
|
||||
|
||||
static void
|
||||
probe_sched_switch(void *ignore, bool preempt,
|
||||
unsigned int prev_state,
|
||||
struct task_struct *prev, struct task_struct *next)
|
||||
struct task_struct *prev, struct task_struct *next,
|
||||
unsigned int prev_state)
|
||||
{
|
||||
int flags;
|
||||
|
||||
|
||||
@@ -426,8 +426,8 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
|
||||
|
||||
static void notrace
|
||||
probe_wakeup_sched_switch(void *ignore, bool preempt,
|
||||
unsigned int prev_state,
|
||||
struct task_struct *prev, struct task_struct *next)
|
||||
struct task_struct *prev, struct task_struct *next,
|
||||
unsigned int prev_state)
|
||||
{
|
||||
struct trace_array_cpu *data;
|
||||
u64 T0, T1, delta;
|
||||
|
||||
+6
-1
@@ -2495,11 +2495,16 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
|
||||
struct address_space *mapping = NULL;
|
||||
int extra_pins, ret;
|
||||
pgoff_t end;
|
||||
bool is_hzp;
|
||||
|
||||
VM_BUG_ON_PAGE(is_huge_zero_page(head), head);
|
||||
VM_BUG_ON_PAGE(!PageLocked(head), head);
|
||||
VM_BUG_ON_PAGE(!PageCompound(head), head);
|
||||
|
||||
is_hzp = is_huge_zero_page(head);
|
||||
VM_WARN_ON_ONCE_PAGE(is_hzp, head);
|
||||
if (is_hzp)
|
||||
return -EBUSY;
|
||||
|
||||
if (PageWriteback(head))
|
||||
return -EBUSY;
|
||||
|
||||
|
||||
@@ -621,6 +621,16 @@ static bool __init kfence_init_pool_early(void)
|
||||
* fails for the first page, and therefore expect addr==__kfence_pool in
|
||||
* most failure cases.
|
||||
*/
|
||||
for (char *p = (char *)addr; p < __kfence_pool + KFENCE_POOL_SIZE; p += PAGE_SIZE) {
|
||||
struct slab *slab = virt_to_slab(p);
|
||||
|
||||
if (!slab)
|
||||
continue;
|
||||
#ifdef CONFIG_MEMCG
|
||||
slab->memcg_data = 0;
|
||||
#endif
|
||||
__folio_clear_slab(slab_folio(slab));
|
||||
}
|
||||
memblock_free_late(__pa(addr), KFENCE_POOL_SIZE - (addr - (unsigned long)__kfence_pool));
|
||||
__kfence_pool = NULL;
|
||||
return false;
|
||||
|
||||
+1
-14
@@ -1274,7 +1274,7 @@ try_again:
|
||||
}
|
||||
out:
|
||||
if (ret == -EIO)
|
||||
dump_page(p, "hwpoison: unhandlable page");
|
||||
pr_err("Memory failure: %#lx: unhandlable page.\n", page_to_pfn(p));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1860,19 +1860,6 @@ try_again:
|
||||
}
|
||||
|
||||
if (PageTransHuge(hpage)) {
|
||||
/*
|
||||
* Bail out before SetPageHasHWPoisoned() if hpage is
|
||||
* huge_zero_page, although PG_has_hwpoisoned is not
|
||||
* checked in set_huge_zero_page().
|
||||
*
|
||||
* TODO: Handle memory failure of huge_zero_page thoroughly.
|
||||
*/
|
||||
if (is_huge_zero_page(hpage)) {
|
||||
action_result(pfn, MF_MSG_UNSPLIT_THP, MF_IGNORED);
|
||||
res = -EBUSY;
|
||||
goto unlock_mutex;
|
||||
}
|
||||
|
||||
/*
|
||||
* The flag must be set after the refcount is bumped
|
||||
* otherwise it may race with THP split.
|
||||
|
||||
+1
-1
@@ -947,7 +947,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
|
||||
return -EINTR;
|
||||
vma = vma_lookup(mm, addr);
|
||||
if (!vma) {
|
||||
ret = EFAULT;
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,8 @@ static int gssp_rpc_create(struct net *net, struct rpc_clnt **_clnt)
|
||||
* timeout, which would result in reconnections being
|
||||
* done without the correct namespace:
|
||||
*/
|
||||
.flags = RPC_CLNT_CREATE_IGNORE_NULL_UNAVAIL |
|
||||
.flags = RPC_CLNT_CREATE_NOPING |
|
||||
RPC_CLNT_CREATE_CONNECTED |
|
||||
RPC_CLNT_CREATE_NO_IDLE_TIMEOUT
|
||||
};
|
||||
struct rpc_clnt *clnt;
|
||||
|
||||
+33
-3
@@ -76,6 +76,7 @@ static int rpc_encode_header(struct rpc_task *task,
|
||||
static int rpc_decode_header(struct rpc_task *task,
|
||||
struct xdr_stream *xdr);
|
||||
static int rpc_ping(struct rpc_clnt *clnt);
|
||||
static int rpc_ping_noreply(struct rpc_clnt *clnt);
|
||||
static void rpc_check_timeout(struct rpc_task *task);
|
||||
|
||||
static void rpc_register_client(struct rpc_clnt *clnt)
|
||||
@@ -479,9 +480,12 @@ static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
|
||||
|
||||
if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
|
||||
int err = rpc_ping(clnt);
|
||||
if ((args->flags & RPC_CLNT_CREATE_IGNORE_NULL_UNAVAIL) &&
|
||||
err == -EOPNOTSUPP)
|
||||
err = 0;
|
||||
if (err != 0) {
|
||||
rpc_shutdown_client(clnt);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
} else if (args->flags & RPC_CLNT_CREATE_CONNECTED) {
|
||||
int err = rpc_ping_noreply(clnt);
|
||||
if (err != 0) {
|
||||
rpc_shutdown_client(clnt);
|
||||
return ERR_PTR(err);
|
||||
@@ -2712,6 +2716,10 @@ static const struct rpc_procinfo rpcproc_null = {
|
||||
.p_decode = rpcproc_decode_null,
|
||||
};
|
||||
|
||||
static const struct rpc_procinfo rpcproc_null_noreply = {
|
||||
.p_encode = rpcproc_encode_null,
|
||||
};
|
||||
|
||||
static void
|
||||
rpc_null_call_prepare(struct rpc_task *task, void *data)
|
||||
{
|
||||
@@ -2765,6 +2773,28 @@ static int rpc_ping(struct rpc_clnt *clnt)
|
||||
return status;
|
||||
}
|
||||
|
||||
static int rpc_ping_noreply(struct rpc_clnt *clnt)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &rpcproc_null_noreply,
|
||||
};
|
||||
struct rpc_task_setup task_setup_data = {
|
||||
.rpc_client = clnt,
|
||||
.rpc_message = &msg,
|
||||
.callback_ops = &rpc_null_ops,
|
||||
.flags = RPC_TASK_SOFT | RPC_TASK_SOFTCONN | RPC_TASK_NULLCREDS,
|
||||
};
|
||||
struct rpc_task *task;
|
||||
int status;
|
||||
|
||||
task = rpc_run_task(&task_setup_data);
|
||||
if (IS_ERR(task))
|
||||
return PTR_ERR(task);
|
||||
status = task->tk_status;
|
||||
rpc_put_task(task);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct rpc_cb_add_xprt_calldata {
|
||||
struct rpc_xprt_switch *xps;
|
||||
struct rpc_xprt *xprt;
|
||||
|
||||
@@ -25,11 +25,11 @@ TRACE_CUSTOM_EVENT(sched_switch,
|
||||
* that the custom event is using.
|
||||
*/
|
||||
TP_PROTO(bool preempt,
|
||||
unsigned int prev_state,
|
||||
struct task_struct *prev,
|
||||
struct task_struct *next),
|
||||
struct task_struct *next,
|
||||
unsigned int prev_state),
|
||||
|
||||
TP_ARGS(preempt, prev_state, prev, next),
|
||||
TP_ARGS(preempt, prev, next, prev_state),
|
||||
|
||||
/*
|
||||
* The next fields are where the customization happens.
|
||||
|
||||
@@ -445,7 +445,13 @@ struct kvm_run {
|
||||
#define KVM_SYSTEM_EVENT_RESET 2
|
||||
#define KVM_SYSTEM_EVENT_CRASH 3
|
||||
__u32 type;
|
||||
__u64 flags;
|
||||
__u32 ndata;
|
||||
union {
|
||||
#ifndef __KERNEL__
|
||||
__u64 flags;
|
||||
#endif
|
||||
__u64 data[16];
|
||||
};
|
||||
} system_event;
|
||||
/* KVM_EXIT_S390_STSI */
|
||||
struct {
|
||||
@@ -1144,6 +1150,8 @@ struct kvm_ppc_resize_hpt {
|
||||
#define KVM_CAP_S390_MEM_OP_EXTENSION 211
|
||||
#define KVM_CAP_PMU_CAPABILITY 212
|
||||
#define KVM_CAP_DISABLE_QUIRKS2 213
|
||||
/* #define KVM_CAP_VM_TSC_CONTROL 214 */
|
||||
#define KVM_CAP_SYSTEM_EVENT_DATA 215
|
||||
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
|
||||
|
||||
@@ -311,6 +311,7 @@ err_out:
|
||||
|
||||
/* BUG_ON due to failure in allocation of orig_mask/mask */
|
||||
BUG_ON(-1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static cpu_set_t *bind_to_node(int target_node)
|
||||
@@ -364,6 +365,7 @@ err_out:
|
||||
|
||||
/* BUG_ON due to failure in allocation of orig_mask/mask */
|
||||
BUG_ON(-1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void bind_to_cpumask(cpu_set_t *mask)
|
||||
|
||||
@@ -29,7 +29,6 @@ cleanup_files()
|
||||
rm -f ${file}
|
||||
rm -f "${perfdata}.old"
|
||||
trap - exit term int
|
||||
kill -2 $$
|
||||
exit $glb_err
|
||||
}
|
||||
|
||||
|
||||
@@ -57,9 +57,9 @@ CAN_BUILD_I386 := $(shell ./../x86/check_cc.sh "$(CC)" ../x86/trivial_32bit_prog
|
||||
CAN_BUILD_X86_64 := $(shell ./../x86/check_cc.sh "$(CC)" ../x86/trivial_64bit_program.c)
|
||||
CAN_BUILD_WITH_NOPIE := $(shell ./../x86/check_cc.sh "$(CC)" ../x86/trivial_program.c -no-pie)
|
||||
|
||||
TARGETS := protection_keys
|
||||
BINARIES_32 := $(TARGETS:%=%_32)
|
||||
BINARIES_64 := $(TARGETS:%=%_64)
|
||||
VMTARGETS := protection_keys
|
||||
BINARIES_32 := $(VMTARGETS:%=%_32)
|
||||
BINARIES_64 := $(VMTARGETS:%=%_64)
|
||||
|
||||
ifeq ($(CAN_BUILD_WITH_NOPIE),1)
|
||||
CFLAGS += -no-pie
|
||||
@@ -112,7 +112,7 @@ $(BINARIES_32): CFLAGS += -m32 -mxsave
|
||||
$(BINARIES_32): LDLIBS += -lrt -ldl -lm
|
||||
$(BINARIES_32): $(OUTPUT)/%_32: %.c
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(notdir $^) $(LDLIBS) -o $@
|
||||
$(foreach t,$(TARGETS),$(eval $(call gen-target-rule-32,$(t))))
|
||||
$(foreach t,$(VMTARGETS),$(eval $(call gen-target-rule-32,$(t))))
|
||||
endif
|
||||
|
||||
ifeq ($(CAN_BUILD_X86_64),1)
|
||||
@@ -120,7 +120,7 @@ $(BINARIES_64): CFLAGS += -m64 -mxsave
|
||||
$(BINARIES_64): LDLIBS += -lrt -ldl
|
||||
$(BINARIES_64): $(OUTPUT)/%_64: %.c
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(notdir $^) $(LDLIBS) -o $@
|
||||
$(foreach t,$(TARGETS),$(eval $(call gen-target-rule-64,$(t))))
|
||||
$(foreach t,$(VMTARGETS),$(eval $(call gen-target-rule-64,$(t))))
|
||||
endif
|
||||
|
||||
# x86_64 users should be encouraged to install 32-bit libraries
|
||||
|
||||
Reference in New Issue
Block a user