mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
Merge 6.1.108 into android14-6.1-lts
Changes in 6.1.108 drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc LoongArch: Remove the unused dma-direct.h btrfs: run delayed iputs when flushing delalloc smb/client: avoid dereferencing rdata=NULL in smb2_new_read_req() pinctrl: rockchip: correct RK3328 iomux width flag for GPIO2-B pins pinctrl: single: fix potential NULL dereference in pcs_get_function() of: Add cleanup.h based auto release via __free(device_node) markings wifi: wfx: repair open network AP mode wifi: mwifiex: duplicate static structs used in driver instances net: mana: Fix race of mana_hwc_post_rx_wqe and new hwc response mptcp: close subflow when receiving TCP+FIN mptcp: sched: check both backup in retrans mptcp: pm: skip connecting to already established sf mptcp: pm: reset MPC endp ID when re-added mptcp: pm: send ACK on an active subflow mptcp: pm: do not remove already closed subflows mptcp: pm: ADD_ADDR 0 is not a new address drm/amdgpu: align pp_power_profile_mode with kernel docs drm/amdgpu/swsmu: always force a state reprogram on init ata: libata-core: Fix null pointer dereference on error usb: typec: fix up incorrectly backported "usb: typec: tcpm: unregister existing source caps before re-registration" mmc: Avoid open coding by using mmc_op_tuning() mmc: mtk-sd: receive cmd8 data when hs400 tuning fail mptcp: unify pm get_local_id interfaces mptcp: pm: remove mptcp_pm_remove_subflow() mptcp: pm: only mark 'subflow' endp as available mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR of: Introduce for_each_*_child_of_node_scoped() to automate of_node_put() handling thermal: of: Fix OF node leak in thermal_of_trips_init() error path thermal: of: Fix OF node leak in of_thermal_zone_find() error paths ASoC: amd: acp: fix module autoloading ASoC: SOF: amd: Fix for acp init sequence pinctrl: mediatek: common-v2: Fix broken bias-disable for PULL_PU_PD_RSEL_TYPE mm: Fix missing folio invalidation calls during truncation btrfs: fix extent map use-after-free when adding pages to compressed bio soundwire: stream: fix programming slave ports for non-continous port maps phy: xilinx: add runtime PM support phy: xilinx: phy-zynqmp: dynamic clock support for power-save phy: xilinx: phy-zynqmp: Fix SGMII linkup failure on resume dmaengine: dw: Add peripheral bus width verification dmaengine: dw: Add memory bus width verification Bluetooth: hci_core: Fix not handling hibernation actions iommu: Do not return 0 from map_pages if it doesn't do anything netfilter: nf_tables: restore IP sanity checks for netdev/egress wifi: iwlwifi: fw: fix wgds rev 3 exact size ethtool: check device is present when getting link settings netfilter: nf_tables_ipv6: consider network offset in netdev/egress validation selftests: forwarding: no_forwarding: Down ports on cleanup selftests: forwarding: local_termination: Down ports on cleanup bonding: implement xdo_dev_state_free and call it after deletion gtp: fix a potential NULL pointer dereference sctp: fix association labeling in the duplicate COOKIE-ECHO case drm/amd/display: avoid using null object of framebuffer net: busy-poll: use ktime_get_ns() instead of local_clock() nfc: pn533: Add poll mod list filling check soc: qcom: cmd-db: Map shared memory as WC, not WB cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller USB: serial: option: add MeiG Smart SRM825L usb: dwc3: omap: add missing depopulate in probe error path usb: dwc3: core: Prevent USB core invalid event buffer address access usb: dwc3: st: fix probed platform device ref count on probe error path usb: dwc3: st: add missing depopulate in probe error path usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in remove_power_attributes() usb: cdnsp: fix incorrect index in cdnsp_get_hw_deq function usb: cdnsp: fix for Link TRB with TC phy: zynqmp: Enable reference clock correctly igc: Fix reset adapter logics when tx mode change igc: Fix qbv tx latency by setting gtxoffset scsi: aacraid: Fix double-free on probe failure apparmor: fix policy_unpack_test on big endian systems fbdev: offb: fix up missing cleanup.h Linux 6.1.108 Change-Id: I8ef0e85c12e4e2ecccaf467f40d86c559db7d007 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 107
|
||||
SUBLEVEL = 108
|
||||
EXTRAVERSION =
|
||||
NAME = Curry Ramen
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#ifndef _LOONGARCH_DMA_DIRECT_H
|
||||
#define _LOONGARCH_DMA_DIRECT_H
|
||||
|
||||
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
|
||||
phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
|
||||
|
||||
#endif /* _LOONGARCH_DMA_DIRECT_H */
|
||||
@@ -5471,6 +5471,9 @@ static void ata_host_release(struct kref *kref)
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
|
||||
if (!ap)
|
||||
continue;
|
||||
|
||||
kfree(ap->pmp_link);
|
||||
kfree(ap->slave_link);
|
||||
kfree(ap);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -621,12 +622,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
struct dw_desc *prev;
|
||||
struct dw_desc *first;
|
||||
u32 ctllo, ctlhi;
|
||||
u8 m_master = dwc->dws.m_master;
|
||||
u8 lms = DWC_LLP_LMS(m_master);
|
||||
u8 lms = DWC_LLP_LMS(dwc->dws.m_master);
|
||||
dma_addr_t reg;
|
||||
unsigned int reg_width;
|
||||
unsigned int mem_width;
|
||||
unsigned int data_width = dw->pdata->data_width[m_master];
|
||||
unsigned int i;
|
||||
struct scatterlist *sg;
|
||||
size_t total_len = 0;
|
||||
@@ -660,7 +659,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
mem = sg_dma_address(sg);
|
||||
len = sg_dma_len(sg);
|
||||
|
||||
mem_width = __ffs(data_width | mem | len);
|
||||
mem_width = __ffs(sconfig->src_addr_width | mem | len);
|
||||
|
||||
slave_sg_todev_fill_desc:
|
||||
desc = dwc_desc_get(dwc);
|
||||
@@ -720,7 +719,7 @@ slave_sg_fromdev_fill_desc:
|
||||
lli_write(desc, sar, reg);
|
||||
lli_write(desc, dar, mem);
|
||||
lli_write(desc, ctlhi, ctlhi);
|
||||
mem_width = __ffs(data_width | mem);
|
||||
mem_width = __ffs(sconfig->dst_addr_width | mem);
|
||||
lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width));
|
||||
desc->len = dlen;
|
||||
|
||||
@@ -780,17 +779,93 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_dma_filter);
|
||||
|
||||
static int dwc_verify_p_buswidth(struct dma_chan *chan)
|
||||
{
|
||||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct dw_dma *dw = to_dw_dma(chan->device);
|
||||
u32 reg_width, max_width;
|
||||
|
||||
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
|
||||
reg_width = dwc->dma_sconfig.dst_addr_width;
|
||||
else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM)
|
||||
reg_width = dwc->dma_sconfig.src_addr_width;
|
||||
else /* DMA_MEM_TO_MEM */
|
||||
return 0;
|
||||
|
||||
max_width = dw->pdata->data_width[dwc->dws.p_master];
|
||||
|
||||
/* Fall-back to 1-byte transfer width if undefined */
|
||||
if (reg_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
|
||||
reg_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||
else if (!is_power_of_2(reg_width) || reg_width > max_width)
|
||||
return -EINVAL;
|
||||
else /* bus width is valid */
|
||||
return 0;
|
||||
|
||||
/* Update undefined addr width value */
|
||||
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
|
||||
dwc->dma_sconfig.dst_addr_width = reg_width;
|
||||
else /* DMA_DEV_TO_MEM */
|
||||
dwc->dma_sconfig.src_addr_width = reg_width;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dwc_verify_m_buswidth(struct dma_chan *chan)
|
||||
{
|
||||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct dw_dma *dw = to_dw_dma(chan->device);
|
||||
u32 reg_width, reg_burst, mem_width;
|
||||
|
||||
mem_width = dw->pdata->data_width[dwc->dws.m_master];
|
||||
|
||||
/*
|
||||
* It's possible to have a data portion locked in the DMA FIFO in case
|
||||
* of the channel suspension. Subsequent channel disabling will cause
|
||||
* that data silent loss. In order to prevent that maintain the src and
|
||||
* dst transfer widths coherency by means of the relation:
|
||||
* (CTLx.SRC_TR_WIDTH * CTLx.SRC_MSIZE >= CTLx.DST_TR_WIDTH)
|
||||
* Look for the details in the commit message that brings this change.
|
||||
*
|
||||
* Note the DMA configs utilized in the calculations below must have
|
||||
* been verified to have correct values by this method call.
|
||||
*/
|
||||
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) {
|
||||
reg_width = dwc->dma_sconfig.dst_addr_width;
|
||||
if (mem_width < reg_width)
|
||||
return -EINVAL;
|
||||
|
||||
dwc->dma_sconfig.src_addr_width = mem_width;
|
||||
} else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) {
|
||||
reg_width = dwc->dma_sconfig.src_addr_width;
|
||||
reg_burst = rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst);
|
||||
|
||||
dwc->dma_sconfig.dst_addr_width = min(mem_width, reg_width * reg_burst);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
|
||||
{
|
||||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct dw_dma *dw = to_dw_dma(chan->device);
|
||||
int ret;
|
||||
|
||||
memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
|
||||
|
||||
dwc->dma_sconfig.src_maxburst =
|
||||
clamp(dwc->dma_sconfig.src_maxburst, 0U, dwc->max_burst);
|
||||
clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst);
|
||||
dwc->dma_sconfig.dst_maxburst =
|
||||
clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst);
|
||||
clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst);
|
||||
|
||||
ret = dwc_verify_p_buswidth(chan);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = dwc_verify_m_buswidth(chan);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst);
|
||||
dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst);
|
||||
|
||||
@@ -743,7 +743,8 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p,
|
||||
uint32_t created = 0;
|
||||
uint32_t allocated = 0;
|
||||
uint32_t tmp, handle = 0;
|
||||
uint32_t *size = &tmp;
|
||||
uint32_t dummy = 0xffffffff;
|
||||
uint32_t *size = &dummy;
|
||||
unsigned idx;
|
||||
int i, r = 0;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
@@ -848,10 +849,14 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
||||
}
|
||||
|
||||
afb = to_amdgpu_framebuffer(new_state->fb);
|
||||
obj = new_state->fb->obj[0];
|
||||
obj = drm_gem_fb_get_obj(new_state->fb, 0);
|
||||
if (!obj) {
|
||||
DRM_ERROR("Failed to get obj from framebuffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rbo = gem_to_amdgpu_bo(obj);
|
||||
adev = amdgpu_ttm_adev(rbo->tbo.bdev);
|
||||
|
||||
r = amdgpu_bo_reserve(rbo, true);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
|
||||
|
||||
@@ -1829,8 +1829,9 @@ static int smu_bump_power_profile_mode(struct smu_context *smu,
|
||||
}
|
||||
|
||||
static int smu_adjust_power_state_dynamic(struct smu_context *smu,
|
||||
enum amd_dpm_forced_level level,
|
||||
bool skip_display_settings)
|
||||
enum amd_dpm_forced_level level,
|
||||
bool skip_display_settings,
|
||||
bool force_update)
|
||||
{
|
||||
int ret = 0;
|
||||
int index = 0;
|
||||
@@ -1859,7 +1860,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
|
||||
}
|
||||
}
|
||||
|
||||
if (smu_dpm_ctx->dpm_level != level) {
|
||||
if (force_update || smu_dpm_ctx->dpm_level != level) {
|
||||
ret = smu_asic_set_performance_level(smu, level);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "Failed to set performance level!");
|
||||
@@ -1870,13 +1871,12 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
|
||||
smu_dpm_ctx->dpm_level = level;
|
||||
}
|
||||
|
||||
if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
|
||||
smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
|
||||
if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
|
||||
index = fls(smu->workload_mask);
|
||||
index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
|
||||
workload[0] = smu->workload_setting[index];
|
||||
|
||||
if (smu->power_profile_mode != workload[0])
|
||||
if (force_update || smu->power_profile_mode != workload[0])
|
||||
smu_bump_power_profile_mode(smu, workload, 0);
|
||||
}
|
||||
|
||||
@@ -1897,11 +1897,13 @@ static int smu_handle_task(struct smu_context *smu,
|
||||
ret = smu_pre_display_config_changed(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, false);
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, false, false);
|
||||
break;
|
||||
case AMD_PP_TASK_COMPLETE_INIT:
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, true, true);
|
||||
break;
|
||||
case AMD_PP_TASK_READJUST_POWER_STATE:
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, true);
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1948,8 +1950,7 @@ static int smu_switch_power_profile(void *handle,
|
||||
workload[0] = smu->workload_setting[index];
|
||||
}
|
||||
|
||||
if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
|
||||
smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
|
||||
if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
|
||||
smu_bump_power_profile_mode(smu, workload, 0);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -552,9 +552,8 @@ static int arm_v7s_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
|
||||
paddr >= (1ULL << data->iop.cfg.oas)))
|
||||
return -ERANGE;
|
||||
|
||||
/* If no access, then nothing to do */
|
||||
if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
|
||||
while (pgcount--) {
|
||||
ret = __arm_v7s_map(data, iova, paddr, pgsize, prot, 1, data->pgd,
|
||||
|
||||
@@ -494,9 +494,8 @@ static int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
|
||||
if (WARN_ON(iaext || paddr >> cfg->oas))
|
||||
return -ERANGE;
|
||||
|
||||
/* If no access, then nothing to do */
|
||||
if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
|
||||
prot = arm_lpae_prot_to_pte(data, iommu_prot);
|
||||
ret = __arm_lpae_map(data, iova, paddr, pgsize, pgcount, prot, lvl,
|
||||
|
||||
@@ -250,9 +250,8 @@ static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
|
||||
if (WARN_ON(paddr >> cfg->oas))
|
||||
return -ERANGE;
|
||||
|
||||
/* If no access, then nothing to do */
|
||||
if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
|
||||
tbl = dart_get_table(data, iova);
|
||||
|
||||
|
||||
@@ -142,8 +142,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
|
||||
int err = cmd->error;
|
||||
|
||||
/* Flag re-tuning needed on CRC errors */
|
||||
if (cmd->opcode != MMC_SEND_TUNING_BLOCK &&
|
||||
cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
|
||||
if (!mmc_op_tuning(cmd->opcode) &&
|
||||
!host->retune_crc_disable &&
|
||||
(err == -EILSEQ || (mrq->sbc && mrq->sbc->error == -EILSEQ) ||
|
||||
(mrq->data && mrq->data->error == -EILSEQ) ||
|
||||
|
||||
@@ -334,8 +334,7 @@ static u32 dw_mci_prep_stop_abort(struct dw_mci *host, struct mmc_command *cmd)
|
||||
cmdr == MMC_READ_MULTIPLE_BLOCK ||
|
||||
cmdr == MMC_WRITE_BLOCK ||
|
||||
cmdr == MMC_WRITE_MULTIPLE_BLOCK ||
|
||||
cmdr == MMC_SEND_TUNING_BLOCK ||
|
||||
cmdr == MMC_SEND_TUNING_BLOCK_HS200 ||
|
||||
mmc_op_tuning(cmdr) ||
|
||||
cmdr == MMC_GEN_CMD) {
|
||||
stop->opcode = MMC_STOP_TRANSMISSION;
|
||||
stop->arg = 0;
|
||||
|
||||
@@ -1206,10 +1206,8 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
|
||||
}
|
||||
|
||||
if (!sbc_error && !(events & MSDC_INT_CMDRDY)) {
|
||||
if (events & MSDC_INT_CMDTMO ||
|
||||
(cmd->opcode != MMC_SEND_TUNING_BLOCK &&
|
||||
cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
|
||||
!host->hs400_tuning))
|
||||
if ((events & MSDC_INT_CMDTMO && !host->hs400_tuning) ||
|
||||
(!mmc_op_tuning(cmd->opcode) && !host->hs400_tuning))
|
||||
/*
|
||||
* should not clear fifo/interrupt as the tune data
|
||||
* may have alreay come when cmd19/cmd21 gets response
|
||||
@@ -1301,11 +1299,9 @@ static void msdc_start_command(struct msdc_host *host,
|
||||
static void msdc_cmd_next(struct msdc_host *host,
|
||||
struct mmc_request *mrq, struct mmc_command *cmd)
|
||||
{
|
||||
if ((cmd->error &&
|
||||
!(cmd->error == -EILSEQ &&
|
||||
(cmd->opcode == MMC_SEND_TUNING_BLOCK ||
|
||||
cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200 ||
|
||||
host->hs400_tuning))) ||
|
||||
if ((cmd->error && !host->hs400_tuning &&
|
||||
!(cmd->error == -EILSEQ &&
|
||||
mmc_op_tuning(cmd->opcode))) ||
|
||||
(mrq->sbc && mrq->sbc->error))
|
||||
msdc_request_done(host, mrq);
|
||||
else if (cmd == mrq->sbc)
|
||||
|
||||
@@ -2218,8 +2218,7 @@ static int __sdhci_msm_check_write(struct sdhci_host *host, u16 val, int reg)
|
||||
if (!msm_host->use_cdr)
|
||||
break;
|
||||
if ((msm_host->transfer_mode & SDHCI_TRNS_READ) &&
|
||||
SDHCI_GET_CMD(val) != MMC_SEND_TUNING_BLOCK_HS200 &&
|
||||
SDHCI_GET_CMD(val) != MMC_SEND_TUNING_BLOCK)
|
||||
!mmc_op_tuning(SDHCI_GET_CMD(val)))
|
||||
sdhci_msm_set_cdr(host, true);
|
||||
else
|
||||
sdhci_msm_set_cdr(host, false);
|
||||
|
||||
@@ -326,8 +326,7 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
(host->timing != MMC_TIMING_UHS_SDR50))
|
||||
return sdhci_execute_tuning(mmc, opcode);
|
||||
|
||||
if (WARN_ON((opcode != MMC_SEND_TUNING_BLOCK_HS200) &&
|
||||
(opcode != MMC_SEND_TUNING_BLOCK)))
|
||||
if (WARN_ON(!mmc_op_tuning(opcode)))
|
||||
return -EINVAL;
|
||||
|
||||
/* Force power mode enter L0 */
|
||||
|
||||
@@ -268,13 +268,9 @@ static void tegra210_sdhci_writew(struct sdhci_host *host, u16 val, int reg)
|
||||
{
|
||||
bool is_tuning_cmd = 0;
|
||||
bool clk_enabled;
|
||||
u8 cmd;
|
||||
|
||||
if (reg == SDHCI_COMMAND) {
|
||||
cmd = SDHCI_GET_CMD(val);
|
||||
is_tuning_cmd = cmd == MMC_SEND_TUNING_BLOCK ||
|
||||
cmd == MMC_SEND_TUNING_BLOCK_HS200;
|
||||
}
|
||||
if (reg == SDHCI_COMMAND)
|
||||
is_tuning_cmd = mmc_op_tuning(SDHCI_GET_CMD(val));
|
||||
|
||||
if (is_tuning_cmd)
|
||||
clk_enabled = tegra_sdhci_configure_card_clk(host, 0);
|
||||
|
||||
@@ -1712,8 +1712,7 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
|
||||
flags |= SDHCI_CMD_INDEX;
|
||||
|
||||
/* CMD19 is special in that the Data Present Select should be set */
|
||||
if (cmd->data || cmd->opcode == MMC_SEND_TUNING_BLOCK ||
|
||||
cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200)
|
||||
if (cmd->data || mmc_op_tuning(cmd->opcode))
|
||||
flags |= SDHCI_CMD_DATA;
|
||||
|
||||
timeout = jiffies;
|
||||
@@ -3396,8 +3395,6 @@ static void sdhci_adma_show_error(struct sdhci_host *host)
|
||||
|
||||
static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
|
||||
{
|
||||
u32 command;
|
||||
|
||||
/*
|
||||
* CMD19 generates _only_ Buffer Read Ready interrupt if
|
||||
* use sdhci_send_tuning.
|
||||
@@ -3406,9 +3403,7 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
|
||||
* SDHCI_INT_DATA_AVAIL always there, stuck in irq storm.
|
||||
*/
|
||||
if (intmask & SDHCI_INT_DATA_AVAIL && !host->data) {
|
||||
command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND));
|
||||
if (command == MMC_SEND_TUNING_BLOCK ||
|
||||
command == MMC_SEND_TUNING_BLOCK_HS200) {
|
||||
if (mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)))) {
|
||||
host->tuning_done = 1;
|
||||
wake_up(&host->buf_ready_int);
|
||||
return;
|
||||
|
||||
@@ -577,12 +577,47 @@ static void bond_ipsec_del_sa_all(struct bonding *bond)
|
||||
__func__);
|
||||
} else {
|
||||
slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
|
||||
if (slave->dev->xfrmdev_ops->xdo_dev_state_free)
|
||||
slave->dev->xfrmdev_ops->xdo_dev_state_free(ipsec->xs);
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&bond->ipsec_lock);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void bond_ipsec_free_sa(struct xfrm_state *xs)
|
||||
{
|
||||
struct net_device *bond_dev = xs->xso.dev;
|
||||
struct net_device *real_dev;
|
||||
netdevice_tracker tracker;
|
||||
struct bonding *bond;
|
||||
struct slave *slave;
|
||||
|
||||
if (!bond_dev)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
bond = netdev_priv(bond_dev);
|
||||
slave = rcu_dereference(bond->curr_active_slave);
|
||||
real_dev = slave ? slave->dev : NULL;
|
||||
netdev_hold(real_dev, &tracker, GFP_ATOMIC);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!slave)
|
||||
goto out;
|
||||
|
||||
if (!xs->xso.real_dev)
|
||||
goto out;
|
||||
|
||||
WARN_ON(xs->xso.real_dev != real_dev);
|
||||
|
||||
if (real_dev && real_dev->xfrmdev_ops &&
|
||||
real_dev->xfrmdev_ops->xdo_dev_state_free)
|
||||
real_dev->xfrmdev_ops->xdo_dev_state_free(xs);
|
||||
out:
|
||||
netdev_put(real_dev, &tracker);
|
||||
}
|
||||
|
||||
/**
|
||||
* bond_ipsec_offload_ok - can this packet use the xfrm hw offload
|
||||
* @skb: current data packet
|
||||
@@ -623,6 +658,7 @@ out:
|
||||
static const struct xfrmdev_ops bond_xfrmdev_ops = {
|
||||
.xdo_dev_state_add = bond_ipsec_add_sa,
|
||||
.xdo_dev_state_delete = bond_ipsec_del_sa,
|
||||
.xdo_dev_state_free = bond_ipsec_free_sa,
|
||||
.xdo_dev_offload_ok = bond_ipsec_offload_ok,
|
||||
};
|
||||
#endif /* CONFIG_XFRM_OFFLOAD */
|
||||
|
||||
@@ -49,12 +49,19 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
|
||||
return new_flags;
|
||||
}
|
||||
|
||||
static bool igc_tsn_is_tx_mode_in_tsn(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
|
||||
return !!(rd32(IGC_TQAVCTRL) & IGC_TQAVCTRL_TRANSMIT_MODE_TSN);
|
||||
}
|
||||
|
||||
void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u16 txoffset;
|
||||
|
||||
if (!is_any_launchtime(adapter))
|
||||
if (!igc_tsn_is_tx_mode_in_tsn(adapter))
|
||||
return;
|
||||
|
||||
switch (adapter->link_speed) {
|
||||
|
||||
@@ -51,32 +51,6 @@ static int mana_hwc_verify_resp_msg(const struct hwc_caller_ctx *caller_ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,
|
||||
const struct gdma_resp_hdr *resp_msg)
|
||||
{
|
||||
struct hwc_caller_ctx *ctx;
|
||||
int err;
|
||||
|
||||
if (!test_bit(resp_msg->response.hwc_msg_id,
|
||||
hwc->inflight_msg_res.map)) {
|
||||
dev_err(hwc->dev, "hwc_rx: invalid msg_id = %u\n",
|
||||
resp_msg->response.hwc_msg_id);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = hwc->caller_ctx + resp_msg->response.hwc_msg_id;
|
||||
err = mana_hwc_verify_resp_msg(ctx, resp_msg, resp_len);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
ctx->status_code = resp_msg->status;
|
||||
|
||||
memcpy(ctx->output_buf, resp_msg, resp_len);
|
||||
out:
|
||||
ctx->error = err;
|
||||
complete(&ctx->comp_event);
|
||||
}
|
||||
|
||||
static int mana_hwc_post_rx_wqe(const struct hwc_wq *hwc_rxq,
|
||||
struct hwc_work_request *req)
|
||||
{
|
||||
@@ -100,6 +74,40 @@ static int mana_hwc_post_rx_wqe(const struct hwc_wq *hwc_rxq,
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,
|
||||
struct hwc_work_request *rx_req)
|
||||
{
|
||||
const struct gdma_resp_hdr *resp_msg = rx_req->buf_va;
|
||||
struct hwc_caller_ctx *ctx;
|
||||
int err;
|
||||
|
||||
if (!test_bit(resp_msg->response.hwc_msg_id,
|
||||
hwc->inflight_msg_res.map)) {
|
||||
dev_err(hwc->dev, "hwc_rx: invalid msg_id = %u\n",
|
||||
resp_msg->response.hwc_msg_id);
|
||||
mana_hwc_post_rx_wqe(hwc->rxq, rx_req);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = hwc->caller_ctx + resp_msg->response.hwc_msg_id;
|
||||
err = mana_hwc_verify_resp_msg(ctx, resp_msg, resp_len);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
ctx->status_code = resp_msg->status;
|
||||
|
||||
memcpy(ctx->output_buf, resp_msg, resp_len);
|
||||
out:
|
||||
ctx->error = err;
|
||||
|
||||
/* Must post rx wqe before complete(), otherwise the next rx may
|
||||
* hit no_wqe error.
|
||||
*/
|
||||
mana_hwc_post_rx_wqe(hwc->rxq, rx_req);
|
||||
|
||||
complete(&ctx->comp_event);
|
||||
}
|
||||
|
||||
static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
|
||||
struct gdma_event *event)
|
||||
{
|
||||
@@ -216,14 +224,12 @@ static void mana_hwc_rx_event_handler(void *ctx, u32 gdma_rxq_id,
|
||||
return;
|
||||
}
|
||||
|
||||
mana_hwc_handle_resp(hwc, rx_oob->tx_oob_data_size, resp);
|
||||
mana_hwc_handle_resp(hwc, rx_oob->tx_oob_data_size, rx_req);
|
||||
|
||||
/* Do no longer use 'resp', because the buffer is posted to the HW
|
||||
* in the below mana_hwc_post_rx_wqe().
|
||||
/* Can no longer use 'resp', because the buffer is posted to the HW
|
||||
* in mana_hwc_handle_resp() above.
|
||||
*/
|
||||
resp = NULL;
|
||||
|
||||
mana_hwc_post_rx_wqe(hwc_rxq, rx_req);
|
||||
}
|
||||
|
||||
static void mana_hwc_tx_event_handler(void *ctx, u32 gdma_txq_id,
|
||||
|
||||
@@ -1219,7 +1219,7 @@ static struct sock *gtp_encap_enable_socket(int fd, int type,
|
||||
sock = sockfd_lookup(fd, &err);
|
||||
if (!sock) {
|
||||
pr_debug("gtp socket fd=%d not found\n", fd);
|
||||
return NULL;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
sk = sock->sk;
|
||||
|
||||
@@ -825,22 +825,25 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
|
||||
entry = &wifi_pkg->package.elements[entry_idx];
|
||||
entry_idx++;
|
||||
if (entry->type != ACPI_TYPE_INTEGER ||
|
||||
entry->integer.value > num_profiles) {
|
||||
entry->integer.value > num_profiles ||
|
||||
entry->integer.value <
|
||||
rev_data[idx].min_profiles) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
num_profiles = entry->integer.value;
|
||||
|
||||
/*
|
||||
* this also validates >= min_profiles since we
|
||||
* otherwise wouldn't have gotten the data when
|
||||
* looking up in ACPI
|
||||
* Check to see if we received package count
|
||||
* same as max # of profiles
|
||||
*/
|
||||
if (wifi_pkg->package.count !=
|
||||
hdr_size + profile_size * num_profiles) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* Number of valid profiles */
|
||||
num_profiles = entry->integer.value;
|
||||
}
|
||||
goto read_table;
|
||||
}
|
||||
|
||||
@@ -4362,11 +4362,27 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info))
|
||||
wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
|
||||
|
||||
wiphy->bands[NL80211_BAND_2GHZ] = &mwifiex_band_2ghz;
|
||||
if (adapter->config_bands & BAND_A)
|
||||
wiphy->bands[NL80211_BAND_5GHZ] = &mwifiex_band_5ghz;
|
||||
else
|
||||
wiphy->bands[NL80211_BAND_2GHZ] = devm_kmemdup(adapter->dev,
|
||||
&mwifiex_band_2ghz,
|
||||
sizeof(mwifiex_band_2ghz),
|
||||
GFP_KERNEL);
|
||||
if (!wiphy->bands[NL80211_BAND_2GHZ]) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (adapter->config_bands & BAND_A) {
|
||||
wiphy->bands[NL80211_BAND_5GHZ] = devm_kmemdup(adapter->dev,
|
||||
&mwifiex_band_5ghz,
|
||||
sizeof(mwifiex_band_5ghz),
|
||||
GFP_KERNEL);
|
||||
if (!wiphy->bands[NL80211_BAND_5GHZ]) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
wiphy->bands[NL80211_BAND_5GHZ] = NULL;
|
||||
}
|
||||
|
||||
if (adapter->drcs_enabled && ISSUPP_DRCS_ENABLED(adapter->fw_cap_info))
|
||||
wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_drcs;
|
||||
@@ -4459,8 +4475,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
if (ret < 0) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"%s: wiphy_register failed: %d\n", __func__, ret);
|
||||
wiphy_free(wiphy);
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!adapter->regd) {
|
||||
@@ -4502,4 +4517,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
|
||||
adapter->wiphy = wiphy;
|
||||
return ret;
|
||||
|
||||
err:
|
||||
wiphy_free(wiphy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -370,8 +370,11 @@ static int wfx_set_mfp_ap(struct wfx_vif *wvif)
|
||||
|
||||
ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset,
|
||||
skb->len - ieoffset);
|
||||
if (unlikely(!ptr))
|
||||
if (!ptr) {
|
||||
/* No RSN IE is fine in open networks */
|
||||
ret = 0;
|
||||
goto free_skb;
|
||||
}
|
||||
|
||||
ptr += pairwise_cipher_suite_count_offset;
|
||||
if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
|
||||
|
||||
@@ -1723,6 +1723,11 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev,
|
||||
}
|
||||
|
||||
pn533_poll_create_mod_list(dev, im_protocols, tm_protocols);
|
||||
if (!dev->poll_mod_count) {
|
||||
nfc_err(dev->dev,
|
||||
"Poll mod list is empty\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Do not always start polling from the same modulation */
|
||||
get_random_bytes(&rand_mod, sizeof(rand_mod));
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
@@ -80,7 +81,8 @@
|
||||
|
||||
/* Reference clock selection parameters */
|
||||
#define L0_Ln_REF_CLK_SEL(n) (0x2860 + (n) * 4)
|
||||
#define L0_REF_CLK_SEL_MASK 0x8f
|
||||
#define L0_REF_CLK_LCL_SEL BIT(7)
|
||||
#define L0_REF_CLK_SEL_MASK 0x9f
|
||||
|
||||
/* Calibration digital logic parameters */
|
||||
#define L3_TM_CALIB_DIG19 0xec4c
|
||||
@@ -165,6 +167,24 @@
|
||||
/* Timeout values */
|
||||
#define TIMEOUT_US 1000
|
||||
|
||||
/* Lane 0/1/2/3 offset */
|
||||
#define DIG_8(n) ((0x4000 * (n)) + 0x1074)
|
||||
#define ILL13(n) ((0x4000 * (n)) + 0x1994)
|
||||
#define DIG_10(n) ((0x4000 * (n)) + 0x107c)
|
||||
#define RST_DLY(n) ((0x4000 * (n)) + 0x19a4)
|
||||
#define BYP_15(n) ((0x4000 * (n)) + 0x1038)
|
||||
#define BYP_12(n) ((0x4000 * (n)) + 0x102c)
|
||||
#define MISC3(n) ((0x4000 * (n)) + 0x19ac)
|
||||
#define EQ11(n) ((0x4000 * (n)) + 0x1978)
|
||||
|
||||
static u32 save_reg_address[] = {
|
||||
/* Lane 0/1/2/3 Register */
|
||||
DIG_8(0), ILL13(0), DIG_10(0), RST_DLY(0), BYP_15(0), BYP_12(0), MISC3(0), EQ11(0),
|
||||
DIG_8(1), ILL13(1), DIG_10(1), RST_DLY(1), BYP_15(1), BYP_12(1), MISC3(1), EQ11(1),
|
||||
DIG_8(2), ILL13(2), DIG_10(2), RST_DLY(2), BYP_15(2), BYP_12(2), MISC3(2), EQ11(2),
|
||||
DIG_8(3), ILL13(3), DIG_10(3), RST_DLY(3), BYP_15(3), BYP_12(3), MISC3(3), EQ11(3),
|
||||
};
|
||||
|
||||
struct xpsgtr_dev;
|
||||
|
||||
/**
|
||||
@@ -213,6 +233,7 @@ struct xpsgtr_phy {
|
||||
* @tx_term_fix: fix for GT issue
|
||||
* @saved_icm_cfg0: stored value of ICM CFG0 register
|
||||
* @saved_icm_cfg1: stored value of ICM CFG1 register
|
||||
* @saved_regs: registers to be saved/restored during suspend/resume
|
||||
*/
|
||||
struct xpsgtr_dev {
|
||||
struct device *dev;
|
||||
@@ -225,6 +246,7 @@ struct xpsgtr_dev {
|
||||
bool tx_term_fix;
|
||||
unsigned int saved_icm_cfg0;
|
||||
unsigned int saved_icm_cfg1;
|
||||
u32 *saved_regs;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -298,6 +320,32 @@ static inline void xpsgtr_clr_set_phy(struct xpsgtr_phy *gtr_phy,
|
||||
writel((readl(addr) & ~clr) | set, addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* xpsgtr_save_lane_regs - Saves registers on suspend
|
||||
* @gtr_dev: pointer to phy controller context structure
|
||||
*/
|
||||
static void xpsgtr_save_lane_regs(struct xpsgtr_dev *gtr_dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(save_reg_address); i++)
|
||||
gtr_dev->saved_regs[i] = xpsgtr_read(gtr_dev,
|
||||
save_reg_address[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* xpsgtr_restore_lane_regs - Restores registers on resume
|
||||
* @gtr_dev: pointer to phy controller context structure
|
||||
*/
|
||||
static void xpsgtr_restore_lane_regs(struct xpsgtr_dev *gtr_dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(save_reg_address); i++)
|
||||
xpsgtr_write(gtr_dev, save_reg_address[i],
|
||||
gtr_dev->saved_regs[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardware Configuration
|
||||
*/
|
||||
@@ -349,11 +397,12 @@ static void xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy)
|
||||
PLL_FREQ_MASK, ssc->pll_ref_clk);
|
||||
|
||||
/* Enable lane clock sharing, if required */
|
||||
if (gtr_phy->refclk != gtr_phy->lane) {
|
||||
/* Lane3 Ref Clock Selection Register */
|
||||
if (gtr_phy->refclk == gtr_phy->lane)
|
||||
xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
|
||||
L0_REF_CLK_SEL_MASK, L0_REF_CLK_LCL_SEL);
|
||||
else
|
||||
xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
|
||||
L0_REF_CLK_SEL_MASK, 1 << gtr_phy->refclk);
|
||||
}
|
||||
|
||||
/* SSC step size [7:0] */
|
||||
xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_0_LSB,
|
||||
@@ -572,6 +621,10 @@ static int xpsgtr_phy_init(struct phy *phy)
|
||||
|
||||
mutex_lock(>r_dev->gtr_mutex);
|
||||
|
||||
/* Configure and enable the clock when peripheral phy_init call */
|
||||
if (clk_prepare_enable(gtr_dev->clk[gtr_phy->refclk]))
|
||||
goto out;
|
||||
|
||||
/* Skip initialization if not required. */
|
||||
if (!xpsgtr_phy_init_required(gtr_phy))
|
||||
goto out;
|
||||
@@ -616,9 +669,13 @@ out:
|
||||
static int xpsgtr_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct xpsgtr_phy *gtr_phy = phy_get_drvdata(phy);
|
||||
struct xpsgtr_dev *gtr_dev = gtr_phy->dev;
|
||||
|
||||
gtr_phy->skip_phy_init = false;
|
||||
|
||||
/* Ensure that disable clock only, which configure for lane */
|
||||
clk_disable_unprepare(gtr_dev->clk[gtr_phy->refclk]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -821,34 +878,27 @@ static struct phy *xpsgtr_xlate(struct device *dev,
|
||||
* Power Management
|
||||
*/
|
||||
|
||||
static int __maybe_unused xpsgtr_suspend(struct device *dev)
|
||||
static int xpsgtr_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev);
|
||||
unsigned int i;
|
||||
|
||||
/* Save the snapshot ICM_CFG registers. */
|
||||
gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0);
|
||||
gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++)
|
||||
clk_disable_unprepare(gtr_dev->clk[i]);
|
||||
xpsgtr_save_lane_regs(gtr_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused xpsgtr_resume(struct device *dev)
|
||||
static int xpsgtr_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev);
|
||||
unsigned int icm_cfg0, icm_cfg1;
|
||||
unsigned int i;
|
||||
bool skip_phy_init;
|
||||
int err;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) {
|
||||
err = clk_prepare_enable(gtr_dev->clk[i]);
|
||||
if (err)
|
||||
goto err_clk_put;
|
||||
}
|
||||
xpsgtr_restore_lane_regs(gtr_dev);
|
||||
|
||||
icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0);
|
||||
icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1);
|
||||
@@ -869,18 +919,10 @@ static int __maybe_unused xpsgtr_resume(struct device *dev)
|
||||
gtr_dev->phys[i].skip_phy_init = skip_phy_init;
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_put:
|
||||
while (i--)
|
||||
clk_disable_unprepare(gtr_dev->clk[i]);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops xpsgtr_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(xpsgtr_suspend, xpsgtr_resume)
|
||||
};
|
||||
|
||||
static DEFINE_RUNTIME_DEV_PM_OPS(xpsgtr_pm_ops, xpsgtr_runtime_suspend,
|
||||
xpsgtr_runtime_resume, NULL);
|
||||
/*
|
||||
* Probe & Platform Driver
|
||||
*/
|
||||
@@ -888,7 +930,6 @@ static const struct dev_pm_ops xpsgtr_pm_ops = {
|
||||
static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev)
|
||||
{
|
||||
unsigned int refclk;
|
||||
int ret;
|
||||
|
||||
for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) {
|
||||
unsigned long rate;
|
||||
@@ -899,19 +940,14 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev)
|
||||
snprintf(name, sizeof(name), "ref%u", refclk);
|
||||
clk = devm_clk_get_optional(gtr_dev->dev, name);
|
||||
if (IS_ERR(clk)) {
|
||||
ret = dev_err_probe(gtr_dev->dev, PTR_ERR(clk),
|
||||
"Failed to get reference clock %u\n",
|
||||
refclk);
|
||||
goto err_clk_put;
|
||||
return dev_err_probe(gtr_dev->dev, PTR_ERR(clk),
|
||||
"Failed to get ref clock %u\n",
|
||||
refclk);
|
||||
}
|
||||
|
||||
if (!clk)
|
||||
continue;
|
||||
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret)
|
||||
goto err_clk_put;
|
||||
|
||||
gtr_dev->clk[refclk] = clk;
|
||||
|
||||
/*
|
||||
@@ -931,18 +967,11 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev)
|
||||
dev_err(gtr_dev->dev,
|
||||
"Invalid rate %lu for reference clock %u\n",
|
||||
rate, refclk);
|
||||
ret = -EINVAL;
|
||||
goto err_clk_put;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_put:
|
||||
while (refclk--)
|
||||
clk_disable_unprepare(gtr_dev->clk[refclk]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xpsgtr_probe(struct platform_device *pdev)
|
||||
@@ -951,7 +980,6 @@ static int xpsgtr_probe(struct platform_device *pdev)
|
||||
struct xpsgtr_dev *gtr_dev;
|
||||
struct phy_provider *provider;
|
||||
unsigned int port;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
gtr_dev = devm_kzalloc(&pdev->dev, sizeof(*gtr_dev), GFP_KERNEL);
|
||||
@@ -991,8 +1019,7 @@ static int xpsgtr_probe(struct platform_device *pdev)
|
||||
phy = devm_phy_create(&pdev->dev, np, &xpsgtr_phyops);
|
||||
if (IS_ERR(phy)) {
|
||||
dev_err(&pdev->dev, "failed to create PHY\n");
|
||||
ret = PTR_ERR(phy);
|
||||
goto err_clk_put;
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
gtr_phy->phy = phy;
|
||||
@@ -1003,16 +1030,36 @@ static int xpsgtr_probe(struct platform_device *pdev)
|
||||
provider = devm_of_phy_provider_register(&pdev->dev, xpsgtr_xlate);
|
||||
if (IS_ERR(provider)) {
|
||||
dev_err(&pdev->dev, "registering provider failed\n");
|
||||
ret = PTR_ERR(provider);
|
||||
goto err_clk_put;
|
||||
return PTR_ERR(provider);
|
||||
}
|
||||
|
||||
pm_runtime_set_active(gtr_dev->dev);
|
||||
pm_runtime_enable(gtr_dev->dev);
|
||||
|
||||
ret = pm_runtime_resume_and_get(gtr_dev->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_disable(gtr_dev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gtr_dev->saved_regs = devm_kmalloc(gtr_dev->dev,
|
||||
sizeof(save_reg_address),
|
||||
GFP_KERNEL);
|
||||
if (!gtr_dev->saved_regs)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
err_clk_put:
|
||||
for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++)
|
||||
clk_disable_unprepare(gtr_dev->clk[i]);
|
||||
static int xpsgtr_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct xpsgtr_dev *gtr_dev = platform_get_drvdata(pdev);
|
||||
|
||||
return ret;
|
||||
pm_runtime_disable(gtr_dev->dev);
|
||||
pm_runtime_put_noidle(gtr_dev->dev);
|
||||
pm_runtime_set_suspended(gtr_dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id xpsgtr_of_match[] = {
|
||||
@@ -1024,10 +1071,11 @@ MODULE_DEVICE_TABLE(of, xpsgtr_of_match);
|
||||
|
||||
static struct platform_driver xpsgtr_driver = {
|
||||
.probe = xpsgtr_probe,
|
||||
.remove = xpsgtr_remove,
|
||||
.driver = {
|
||||
.name = "xilinx-psgtr",
|
||||
.of_match_table = xpsgtr_of_match,
|
||||
.pm = &xpsgtr_pm_ops,
|
||||
.pm = pm_ptr(&xpsgtr_pm_ops),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -709,32 +709,35 @@ static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw,
|
||||
{
|
||||
int err, rsel_val;
|
||||
|
||||
if (!pullup && arg == MTK_DISABLE)
|
||||
return 0;
|
||||
|
||||
if (hw->rsel_si_unit) {
|
||||
/* find pin rsel_index from pin_rsel array*/
|
||||
err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val);
|
||||
if (err)
|
||||
goto out;
|
||||
return err;
|
||||
} else {
|
||||
if (arg < MTK_PULL_SET_RSEL_000 ||
|
||||
arg > MTK_PULL_SET_RSEL_111) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (arg < MTK_PULL_SET_RSEL_000 || arg > MTK_PULL_SET_RSEL_111)
|
||||
return -EINVAL;
|
||||
|
||||
rsel_val = arg - MTK_PULL_SET_RSEL_000;
|
||||
}
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
|
||||
if (err)
|
||||
goto out;
|
||||
return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
|
||||
}
|
||||
|
||||
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, MTK_ENABLE);
|
||||
static int mtk_pinconf_bias_set_pu_pd_rsel(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 pullup, u32 arg)
|
||||
{
|
||||
u32 enable = arg == MTK_DISABLE ? MTK_DISABLE : MTK_ENABLE;
|
||||
int err;
|
||||
|
||||
out:
|
||||
return err;
|
||||
if (arg != MTK_DISABLE) {
|
||||
err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable);
|
||||
}
|
||||
|
||||
int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
|
||||
@@ -750,22 +753,22 @@ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
|
||||
try_all_type = MTK_PULL_TYPE_MASK;
|
||||
|
||||
if (try_all_type & MTK_PULL_RSEL_TYPE) {
|
||||
err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
|
||||
err = mtk_pinconf_bias_set_pu_pd_rsel(hw, desc, pullup, arg);
|
||||
if (!err)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
|
||||
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
|
||||
if (!err)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
|
||||
err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc,
|
||||
pullup, arg);
|
||||
if (!err)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
|
||||
@@ -803,9 +806,9 @@ static int mtk_rsel_get_si_unit(struct mtk_pinctrl *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_bias_get_rsel(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 *pullup, u32 *enable)
|
||||
static int mtk_pinconf_bias_get_pu_pd_rsel(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 *pullup, u32 *enable)
|
||||
{
|
||||
int pu, pd, rsel, err;
|
||||
|
||||
@@ -939,22 +942,22 @@ int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
|
||||
try_all_type = MTK_PULL_TYPE_MASK;
|
||||
|
||||
if (try_all_type & MTK_PULL_RSEL_TYPE) {
|
||||
err = mtk_pinconf_bias_get_rsel(hw, desc, pullup, enable);
|
||||
err = mtk_pinconf_bias_get_pu_pd_rsel(hw, desc, pullup, enable);
|
||||
if (!err)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
|
||||
err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
|
||||
if (!err)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
|
||||
err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc,
|
||||
pullup, enable);
|
||||
if (!err)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
|
||||
|
||||
@@ -3803,7 +3803,7 @@ static struct rockchip_pin_bank rk3328_pin_banks[] = {
|
||||
PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0),
|
||||
PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
|
||||
PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0,
|
||||
0,
|
||||
IOMUX_WIDTH_2BIT,
|
||||
IOMUX_WIDTH_3BIT,
|
||||
0),
|
||||
PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
|
||||
|
||||
@@ -350,6 +350,8 @@ static int pcs_get_function(struct pinctrl_dev *pctldev, unsigned pin,
|
||||
return -ENOTSUPP;
|
||||
fselector = setting->func;
|
||||
function = pinmux_generic_get_function(pctldev, fselector);
|
||||
if (!function)
|
||||
return -EINVAL;
|
||||
*func = function->data;
|
||||
if (!(*func)) {
|
||||
dev_err(pcs->dev, "%s could not find function%i\n",
|
||||
|
||||
@@ -642,6 +642,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
|
||||
|
||||
if (aac_comm_init(dev)<0){
|
||||
kfree(dev->queues);
|
||||
dev->queues = NULL;
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
@@ -649,6 +650,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
|
||||
*/
|
||||
if (aac_fib_setup(dev) < 0) {
|
||||
kfree(dev->queues);
|
||||
dev->queues = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ static int cmd_db_dev_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cmd_db_header = memremap(rmem->base, rmem->size, MEMREMAP_WB);
|
||||
cmd_db_header = memremap(rmem->base, rmem->size, MEMREMAP_WC);
|
||||
if (!cmd_db_header) {
|
||||
ret = -ENOMEM;
|
||||
cmd_db_header = NULL;
|
||||
|
||||
@@ -1272,18 +1272,18 @@ struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave,
|
||||
unsigned int port_num)
|
||||
{
|
||||
struct sdw_dpn_prop *dpn_prop;
|
||||
u8 num_ports;
|
||||
unsigned long mask;
|
||||
int i;
|
||||
|
||||
if (direction == SDW_DATA_DIR_TX) {
|
||||
num_ports = hweight32(slave->prop.source_ports);
|
||||
mask = slave->prop.source_ports;
|
||||
dpn_prop = slave->prop.src_dpn_prop;
|
||||
} else {
|
||||
num_ports = hweight32(slave->prop.sink_ports);
|
||||
mask = slave->prop.sink_ports;
|
||||
dpn_prop = slave->prop.sink_dpn_prop;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_ports; i++) {
|
||||
for_each_set_bit(i, &mask, 32) {
|
||||
if (dpn_prop[i].num == port_num)
|
||||
return &dpn_prop[i];
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ static int thermal_of_populate_trip(struct device_node *np,
|
||||
static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *ntrips)
|
||||
{
|
||||
struct thermal_trip *tt;
|
||||
struct device_node *trips, *trip;
|
||||
struct device_node *trips;
|
||||
int ret, count;
|
||||
|
||||
trips = of_get_child_by_name(np, "trips");
|
||||
@@ -260,7 +260,7 @@ static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *n
|
||||
*ntrips = count;
|
||||
|
||||
count = 0;
|
||||
for_each_child_of_node(trips, trip) {
|
||||
for_each_child_of_node_scoped(trips, trip) {
|
||||
ret = thermal_of_populate_trip(trip, &tt[count++]);
|
||||
if (ret)
|
||||
goto out_kfree;
|
||||
@@ -294,14 +294,14 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int
|
||||
* Search for each thermal zone, a defined sensor
|
||||
* corresponding to the one passed as parameter
|
||||
*/
|
||||
for_each_available_child_of_node(np, tz) {
|
||||
for_each_available_child_of_node_scoped(np, child) {
|
||||
|
||||
int count, i;
|
||||
|
||||
count = of_count_phandle_with_args(tz, "thermal-sensors",
|
||||
count = of_count_phandle_with_args(child, "thermal-sensors",
|
||||
"#thermal-sensor-cells");
|
||||
if (count <= 0) {
|
||||
pr_err("%pOFn: missing thermal sensor\n", tz);
|
||||
pr_err("%pOFn: missing thermal sensor\n", child);
|
||||
tz = ERR_PTR(-EINVAL);
|
||||
goto out;
|
||||
}
|
||||
@@ -310,18 +310,19 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int
|
||||
|
||||
int ret;
|
||||
|
||||
ret = of_parse_phandle_with_args(tz, "thermal-sensors",
|
||||
ret = of_parse_phandle_with_args(child, "thermal-sensors",
|
||||
"#thermal-sensor-cells",
|
||||
i, &sensor_specs);
|
||||
if (ret < 0) {
|
||||
pr_err("%pOFn: Failed to read thermal-sensors cells: %d\n", tz, ret);
|
||||
pr_err("%pOFn: Failed to read thermal-sensors cells: %d\n", child, ret);
|
||||
tz = ERR_PTR(ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((sensor == sensor_specs.np) && id == (sensor_specs.args_count ?
|
||||
sensor_specs.args[0] : 0)) {
|
||||
pr_debug("sensor %pOFn id=%d belongs to %pOFn\n", sensor, id, tz);
|
||||
pr_debug("sensor %pOFn id=%d belongs to %pOFn\n", sensor, id, child);
|
||||
tz = no_free_ptr(child);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -811,6 +811,7 @@ struct cdnsp_stream_info {
|
||||
* generate Missed Service Error Event.
|
||||
* Set skip flag when receive a Missed Service Error Event and
|
||||
* process the missed tds on the endpoint ring.
|
||||
* @wa1_nop_trb: hold pointer to NOP trb.
|
||||
*/
|
||||
struct cdnsp_ep {
|
||||
struct usb_ep endpoint;
|
||||
@@ -838,6 +839,8 @@ struct cdnsp_ep {
|
||||
#define EP_UNCONFIGURED BIT(7)
|
||||
|
||||
bool skip;
|
||||
union cdnsp_trb *wa1_nop_trb;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -402,7 +402,7 @@ static u64 cdnsp_get_hw_deq(struct cdnsp_device *pdev,
|
||||
struct cdnsp_stream_ctx *st_ctx;
|
||||
struct cdnsp_ep *pep;
|
||||
|
||||
pep = &pdev->eps[stream_id];
|
||||
pep = &pdev->eps[ep_index];
|
||||
|
||||
if (pep->ep_state & EP_HAS_STREAMS) {
|
||||
st_ctx = &pep->stream_info.stream_ctx_array[stream_id];
|
||||
@@ -1902,6 +1902,23 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* workaround 1: STOP EP command on LINK TRB with TC bit set to 1
|
||||
* causes that internal cycle bit can have incorrect state after
|
||||
* command complete. In consequence empty transfer ring can be
|
||||
* incorrectly detected when EP is resumed.
|
||||
* NOP TRB before LINK TRB avoid such scenario. STOP EP command is
|
||||
* then on NOP TRB and internal cycle bit is not changed and have
|
||||
* correct value.
|
||||
*/
|
||||
if (pep->wa1_nop_trb) {
|
||||
field = le32_to_cpu(pep->wa1_nop_trb->trans_event.flags);
|
||||
field ^= TRB_CYCLE;
|
||||
|
||||
pep->wa1_nop_trb->trans_event.flags = cpu_to_le32(field);
|
||||
pep->wa1_nop_trb = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't give the first TRB to the hardware (by toggling the cycle bit)
|
||||
* until we've finished creating all the other TRBs. The ring's cycle
|
||||
@@ -1997,6 +2014,17 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
|
||||
send_addr = addr;
|
||||
}
|
||||
|
||||
if (cdnsp_trb_is_link(ring->enqueue + 1)) {
|
||||
field = TRB_TYPE(TRB_TR_NOOP) | TRB_IOC;
|
||||
if (!ring->cycle_state)
|
||||
field |= TRB_CYCLE;
|
||||
|
||||
pep->wa1_nop_trb = ring->enqueue;
|
||||
|
||||
cdnsp_queue_trb(pdev, ring, 0, 0x0, 0x0,
|
||||
TRB_INTR_TARGET(0), field);
|
||||
}
|
||||
|
||||
cdnsp_check_trb_math(preq, enqd_len);
|
||||
ret = cdnsp_giveback_first_trb(pdev, pep, preq->request.stream_id,
|
||||
start_cycle, start_trb);
|
||||
|
||||
@@ -1737,6 +1737,9 @@ static const struct usb_device_id acm_ids[] = {
|
||||
{ USB_DEVICE(0x11ca, 0x0201), /* VeriFone Mx870 Gadget Serial */
|
||||
.driver_info = SINGLE_RX_URB,
|
||||
},
|
||||
{ USB_DEVICE(0x1901, 0x0006), /* GE Healthcare Patient Monitor UI Controller */
|
||||
.driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */
|
||||
},
|
||||
{ USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */
|
||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||
},
|
||||
|
||||
@@ -670,6 +670,7 @@ static int add_power_attributes(struct device *dev)
|
||||
|
||||
static void remove_power_attributes(struct device *dev)
|
||||
{
|
||||
sysfs_unmerge_group(&dev->kobj, &usb3_hardware_lpm_attr_group);
|
||||
sysfs_unmerge_group(&dev->kobj, &usb2_hardware_lpm_attr_group);
|
||||
sysfs_unmerge_group(&dev->kobj, &power_attr_group);
|
||||
}
|
||||
|
||||
@@ -553,9 +553,17 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
|
||||
void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
|
||||
{
|
||||
struct dwc3_event_buffer *evt;
|
||||
u32 reg;
|
||||
|
||||
if (!dwc->ev_buf)
|
||||
return;
|
||||
/*
|
||||
* Exynos platforms may not be able to access event buffer if the
|
||||
* controller failed to halt on dwc3_core_exit().
|
||||
*/
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DSTS);
|
||||
if (!(reg & DWC3_DSTS_DEVCTRLHLT))
|
||||
return;
|
||||
|
||||
evt = dwc->ev_buf;
|
||||
|
||||
|
||||
@@ -522,11 +522,13 @@ static int dwc3_omap_probe(struct platform_device *pdev)
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to request IRQ #%d --> %d\n",
|
||||
omap->irq, ret);
|
||||
goto err1;
|
||||
goto err2;
|
||||
}
|
||||
dwc3_omap_enable_irqs(omap);
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
of_platform_depopulate(dev);
|
||||
err1:
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
@@ -219,10 +219,8 @@ static int st_dwc3_probe(struct platform_device *pdev)
|
||||
dwc3_data->regmap = regmap;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "syscfg-reg");
|
||||
if (!res) {
|
||||
ret = -ENXIO;
|
||||
goto undo_platform_dev_alloc;
|
||||
}
|
||||
if (!res)
|
||||
return -ENXIO;
|
||||
|
||||
dwc3_data->syscfg_reg_off = res->start;
|
||||
|
||||
@@ -233,8 +231,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
|
||||
devm_reset_control_get_exclusive(dev, "powerdown");
|
||||
if (IS_ERR(dwc3_data->rstc_pwrdn)) {
|
||||
dev_err(&pdev->dev, "could not get power controller\n");
|
||||
ret = PTR_ERR(dwc3_data->rstc_pwrdn);
|
||||
goto undo_platform_dev_alloc;
|
||||
return PTR_ERR(dwc3_data->rstc_pwrdn);
|
||||
}
|
||||
|
||||
/* Manage PowerDown */
|
||||
@@ -269,7 +266,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
|
||||
if (!child_pdev) {
|
||||
dev_err(dev, "failed to find dwc3 core device\n");
|
||||
ret = -ENODEV;
|
||||
goto err_node_put;
|
||||
goto depopulate;
|
||||
}
|
||||
|
||||
dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev);
|
||||
@@ -285,6 +282,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
|
||||
ret = st_dwc3_drd_init(dwc3_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "drd initialisation failed\n");
|
||||
of_platform_depopulate(dev);
|
||||
goto undo_softreset;
|
||||
}
|
||||
|
||||
@@ -294,14 +292,14 @@ static int st_dwc3_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, dwc3_data);
|
||||
return 0;
|
||||
|
||||
depopulate:
|
||||
of_platform_depopulate(dev);
|
||||
err_node_put:
|
||||
of_node_put(child);
|
||||
undo_softreset:
|
||||
reset_control_assert(dwc3_data->rstc_rst);
|
||||
undo_powerdown:
|
||||
reset_control_assert(dwc3_data->rstc_pwrdn);
|
||||
undo_platform_dev_alloc:
|
||||
platform_device_put(pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -619,6 +619,8 @@ static void option_instat_callback(struct urb *urb);
|
||||
|
||||
/* MeiG Smart Technology products */
|
||||
#define MEIGSMART_VENDOR_ID 0x2dee
|
||||
/* MeiG Smart SRM825L based on Qualcomm 315 */
|
||||
#define MEIGSMART_PRODUCT_SRM825L 0x4d22
|
||||
/* MeiG Smart SLM320 based on UNISOC UIS8910 */
|
||||
#define MEIGSMART_PRODUCT_SLM320 0x4d41
|
||||
|
||||
@@ -2366,6 +2368,9 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
|
||||
@@ -613,6 +613,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
|
||||
put_page(page);
|
||||
break;
|
||||
}
|
||||
add_size = min(em->start + em->len, page_end + 1) - cur;
|
||||
free_extent_map(em);
|
||||
|
||||
if (page->index == end_index) {
|
||||
@@ -625,7 +626,6 @@ static noinline int add_ra_bio_pages(struct inode *inode,
|
||||
}
|
||||
}
|
||||
|
||||
add_size = min(em->start + em->len, page_end + 1) - cur;
|
||||
ret = bio_add_page(cb->orig_bio, page, add_size, offset_in_page(cur));
|
||||
if (ret != add_size) {
|
||||
unlock_extent(tree, cur, page_end, NULL);
|
||||
|
||||
@@ -3745,6 +3745,8 @@ static int try_flush_qgroup(struct btrfs_root *root)
|
||||
return 0;
|
||||
}
|
||||
|
||||
btrfs_run_delayed_iputs(root->fs_info);
|
||||
btrfs_wait_on_delayed_iputs(root->fs_info);
|
||||
ret = btrfs_start_delalloc_snapshot(root, true);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
@@ -4184,7 +4184,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
|
||||
* If we want to do a RDMA write, fill in and append
|
||||
* smbd_buffer_descriptor_v1 to the end of read request
|
||||
*/
|
||||
if (smb3_use_rdma_offload(io_parms)) {
|
||||
if (rdata && smb3_use_rdma_offload(io_parms)) {
|
||||
struct smbd_buffer_descriptor_v1 *v1;
|
||||
bool need_invalidate = server->dialect == SMB30_PROT_ID;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
@@ -128,6 +129,7 @@ static inline struct device_node *of_node_get(struct device_node *node)
|
||||
}
|
||||
static inline void of_node_put(struct device_node *node) { }
|
||||
#endif /* !CONFIG_OF_DYNAMIC */
|
||||
DEFINE_FREE(device_node, struct device_node *, if (_T) of_node_put(_T))
|
||||
|
||||
/* Pointer for first entry in chain of all nodes. */
|
||||
extern struct device_node *of_root;
|
||||
@@ -1371,10 +1373,23 @@ static inline int of_property_read_s32(const struct device_node *np,
|
||||
#define for_each_child_of_node(parent, child) \
|
||||
for (child = of_get_next_child(parent, NULL); child != NULL; \
|
||||
child = of_get_next_child(parent, child))
|
||||
|
||||
#define for_each_child_of_node_scoped(parent, child) \
|
||||
for (struct device_node *child __free(device_node) = \
|
||||
of_get_next_child(parent, NULL); \
|
||||
child != NULL; \
|
||||
child = of_get_next_child(parent, child))
|
||||
|
||||
#define for_each_available_child_of_node(parent, child) \
|
||||
for (child = of_get_next_available_child(parent, NULL); child != NULL; \
|
||||
child = of_get_next_available_child(parent, child))
|
||||
|
||||
#define for_each_available_child_of_node_scoped(parent, child) \
|
||||
for (struct device_node *child __free(device_node) = \
|
||||
of_get_next_available_child(parent, NULL); \
|
||||
child != NULL; \
|
||||
child = of_get_next_available_child(parent, child))
|
||||
|
||||
#define for_each_of_cpu_node(cpu) \
|
||||
for (cpu = of_get_next_cpu_node(NULL); cpu != NULL; \
|
||||
cpu = of_get_next_cpu_node(cpu))
|
||||
|
||||
@@ -63,7 +63,7 @@ static inline bool sk_can_busy_loop(struct sock *sk)
|
||||
static inline unsigned long busy_loop_current_time(void)
|
||||
{
|
||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||
return (unsigned long)(local_clock() >> 10);
|
||||
return (unsigned long)(ktime_get_ns() >> 10);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,7 @@ static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt)
|
||||
static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
|
||||
{
|
||||
struct iphdr *iph, _iph;
|
||||
u32 len, thoff;
|
||||
u32 len, thoff, skb_len;
|
||||
|
||||
iph = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb),
|
||||
sizeof(*iph), &_iph);
|
||||
@@ -30,15 +30,17 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
|
||||
return -1;
|
||||
|
||||
len = iph_totlen(pkt->skb, iph);
|
||||
thoff = skb_network_offset(pkt->skb) + (iph->ihl * 4);
|
||||
if (pkt->skb->len < len)
|
||||
thoff = iph->ihl * 4;
|
||||
skb_len = pkt->skb->len - skb_network_offset(pkt->skb);
|
||||
|
||||
if (skb_len < len)
|
||||
return -1;
|
||||
else if (len < thoff)
|
||||
return -1;
|
||||
|
||||
pkt->flags = NFT_PKTINFO_L4PROTO;
|
||||
pkt->tprot = iph->protocol;
|
||||
pkt->thoff = thoff;
|
||||
pkt->thoff = skb_network_offset(pkt->skb) + thoff;
|
||||
pkt->fragoff = ntohs(iph->frag_off) & IP_OFFSET;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -31,8 +31,8 @@ static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt)
|
||||
struct ipv6hdr *ip6h, _ip6h;
|
||||
unsigned int thoff = 0;
|
||||
unsigned short frag_off;
|
||||
u32 pkt_len, skb_len;
|
||||
int protohdr;
|
||||
u32 pkt_len;
|
||||
|
||||
ip6h = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb),
|
||||
sizeof(*ip6h), &_ip6h);
|
||||
@@ -43,7 +43,8 @@ static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt)
|
||||
return -1;
|
||||
|
||||
pkt_len = ntohs(ip6h->payload_len);
|
||||
if (pkt_len + sizeof(*ip6h) > pkt->skb->len)
|
||||
skb_len = pkt->skb->len - skb_network_offset(pkt->skb);
|
||||
if (pkt_len + sizeof(*ip6h) > skb_len)
|
||||
return -1;
|
||||
|
||||
protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);
|
||||
|
||||
@@ -175,7 +175,7 @@ static void truncate_cleanup_folio(struct folio *folio)
|
||||
if (folio_mapped(folio))
|
||||
unmap_mapping_folio(folio);
|
||||
|
||||
if (folio_has_private(folio))
|
||||
if (folio_needs_release(folio))
|
||||
folio_invalidate(folio, 0, folio_size(folio));
|
||||
|
||||
/*
|
||||
@@ -237,7 +237,7 @@ bool truncate_inode_partial_folio(struct folio *folio, loff_t start, loff_t end)
|
||||
folio_zero_range(folio, offset, length);
|
||||
|
||||
cleancache_invalidate_page(folio->mapping, &folio->page);
|
||||
if (folio_has_private(folio))
|
||||
if (folio_needs_release(folio))
|
||||
folio_invalidate(folio, offset, length);
|
||||
if (!folio_test_large(folio))
|
||||
return true;
|
||||
|
||||
@@ -2404,10 +2404,16 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
|
||||
/* To avoid a potential race with hci_unregister_dev. */
|
||||
hci_dev_hold(hdev);
|
||||
|
||||
if (action == PM_SUSPEND_PREPARE)
|
||||
switch (action) {
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
case PM_SUSPEND_PREPARE:
|
||||
ret = hci_suspend_dev(hdev);
|
||||
else if (action == PM_POST_SUSPEND)
|
||||
break;
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_SUSPEND:
|
||||
ret = hci_resume_dev(hdev);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
|
||||
|
||||
@@ -215,7 +215,7 @@ static ssize_t speed_show(struct device *dev,
|
||||
if (!rtnl_trylock())
|
||||
return restart_syscall();
|
||||
|
||||
if (netif_running(netdev) && netif_device_present(netdev)) {
|
||||
if (netif_running(netdev)) {
|
||||
struct ethtool_link_ksettings cmd;
|
||||
|
||||
if (!__ethtool_get_link_ksettings(netdev, &cmd))
|
||||
|
||||
@@ -447,6 +447,9 @@ int __ethtool_get_link_ksettings(struct net_device *dev,
|
||||
if (!dev->ethtool_ops->get_link_ksettings)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!netif_device_present(dev))
|
||||
return -ENODEV;
|
||||
|
||||
memset(link_ksettings, 0, sizeof(*link_ksettings));
|
||||
return dev->ethtool_ops->get_link_ksettings(dev, link_ksettings);
|
||||
}
|
||||
|
||||
@@ -59,16 +59,6 @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list)
|
||||
{
|
||||
pr_debug("msk=%p, rm_list_nr=%d", msk, rm_list->nr);
|
||||
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
mptcp_pm_nl_rm_subflow_received(msk, rm_list);
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* path manager event handlers */
|
||||
|
||||
void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side)
|
||||
@@ -235,7 +225,9 @@ void mptcp_pm_add_addr_received(const struct sock *ssk,
|
||||
} else {
|
||||
__MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP);
|
||||
}
|
||||
} else if (!READ_ONCE(pm->accept_addr)) {
|
||||
/* id0 should not have a different address */
|
||||
} else if ((addr->id == 0 && !mptcp_pm_nl_is_init_remote_addr(msk, addr)) ||
|
||||
(addr->id > 0 && !READ_ONCE(pm->accept_addr))) {
|
||||
mptcp_pm_announce_addr(msk, addr, true);
|
||||
mptcp_pm_add_addr_send_ack(msk);
|
||||
} else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) {
|
||||
@@ -413,7 +405,23 @@ out_unlock:
|
||||
|
||||
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
|
||||
{
|
||||
return mptcp_pm_nl_get_local_id(msk, skc);
|
||||
struct mptcp_addr_info skc_local;
|
||||
struct mptcp_addr_info msk_local;
|
||||
|
||||
if (WARN_ON_ONCE(!msk))
|
||||
return -1;
|
||||
|
||||
/* The 0 ID mapping is defined by the first subflow, copied into the msk
|
||||
* addr
|
||||
*/
|
||||
mptcp_local_address((struct sock_common *)msk, &msk_local);
|
||||
mptcp_local_address((struct sock_common *)skc, &skc_local);
|
||||
if (mptcp_addresses_equal(&msk_local, &skc_local, false))
|
||||
return 0;
|
||||
|
||||
if (mptcp_pm_is_userspace(msk))
|
||||
return mptcp_userspace_pm_get_local_id(msk, &skc_local);
|
||||
return mptcp_pm_nl_get_local_id(msk, &skc_local);
|
||||
}
|
||||
|
||||
bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
|
||||
|
||||
@@ -134,12 +134,15 @@ static bool lookup_subflow_by_daddr(const struct list_head *list,
|
||||
{
|
||||
struct mptcp_subflow_context *subflow;
|
||||
struct mptcp_addr_info cur;
|
||||
struct sock_common *skc;
|
||||
|
||||
list_for_each_entry(subflow, list, node) {
|
||||
skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);
|
||||
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
|
||||
|
||||
remote_address(skc, &cur);
|
||||
if (!((1 << inet_sk_state_load(ssk)) &
|
||||
(TCPF_ESTABLISHED | TCPF_SYN_SENT | TCPF_SYN_RECV)))
|
||||
continue;
|
||||
|
||||
remote_address((struct sock_common *)ssk, &cur);
|
||||
if (mptcp_addresses_equal(&cur, daddr, daddr->port))
|
||||
return true;
|
||||
}
|
||||
@@ -736,6 +739,15 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
|
||||
}
|
||||
}
|
||||
|
||||
bool mptcp_pm_nl_is_init_remote_addr(struct mptcp_sock *msk,
|
||||
const struct mptcp_addr_info *remote)
|
||||
{
|
||||
struct mptcp_addr_info mpc_remote;
|
||||
|
||||
remote_address((struct sock_common *)msk, &mpc_remote);
|
||||
return mptcp_addresses_equal(&mpc_remote, remote, remote->port);
|
||||
}
|
||||
|
||||
void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
|
||||
{
|
||||
struct mptcp_subflow_context *subflow;
|
||||
@@ -747,9 +759,12 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
|
||||
!mptcp_pm_should_rm_signal(msk))
|
||||
return;
|
||||
|
||||
subflow = list_first_entry_or_null(&msk->conn_list, typeof(*subflow), node);
|
||||
if (subflow)
|
||||
mptcp_pm_send_ack(msk, subflow, false, false);
|
||||
mptcp_for_each_subflow(msk, subflow) {
|
||||
if (__mptcp_subflow_active(subflow)) {
|
||||
mptcp_pm_send_ack(msk, subflow, false, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
|
||||
@@ -819,6 +834,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
|
||||
int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
|
||||
u8 id = subflow_get_local_id(subflow);
|
||||
|
||||
if (inet_sk_state_load(ssk) == TCP_CLOSE)
|
||||
continue;
|
||||
if (rm_type == MPTCP_MIB_RMADDR && remote_id != rm_id)
|
||||
continue;
|
||||
if (rm_type == MPTCP_MIB_RMSUBFLOW && !mptcp_local_id_match(msk, id, rm_id))
|
||||
@@ -838,10 +855,10 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
|
||||
if (rm_type == MPTCP_MIB_RMSUBFLOW)
|
||||
__MPTCP_INC_STATS(sock_net(sk), rm_type);
|
||||
}
|
||||
if (rm_type == MPTCP_MIB_RMSUBFLOW)
|
||||
__set_bit(rm_id ? rm_id : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap);
|
||||
else if (rm_type == MPTCP_MIB_RMADDR)
|
||||
|
||||
if (rm_type == MPTCP_MIB_RMADDR)
|
||||
__MPTCP_INC_STATS(sock_net(sk), rm_type);
|
||||
|
||||
if (!removed)
|
||||
continue;
|
||||
|
||||
@@ -853,10 +870,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
|
||||
/* Note: if the subflow has been closed before, this
|
||||
* add_addr_accepted counter will not be decremented.
|
||||
*/
|
||||
msk->pm.add_addr_accepted--;
|
||||
WRITE_ONCE(msk->pm.accept_addr, true);
|
||||
} else if (rm_type == MPTCP_MIB_RMSUBFLOW) {
|
||||
msk->pm.local_addr_used--;
|
||||
if (--msk->pm.add_addr_accepted < mptcp_pm_get_add_addr_accept_max(msk))
|
||||
WRITE_ONCE(msk->pm.accept_addr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -866,8 +881,8 @@ static void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
|
||||
mptcp_pm_nl_rm_addr_or_subflow(msk, &msk->pm.rm_list_rx, MPTCP_MIB_RMADDR);
|
||||
}
|
||||
|
||||
void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
|
||||
const struct mptcp_rm_list *rm_list)
|
||||
static void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
|
||||
const struct mptcp_rm_list *rm_list)
|
||||
{
|
||||
mptcp_pm_nl_rm_addr_or_subflow(msk, rm_list, MPTCP_MIB_RMSUBFLOW);
|
||||
}
|
||||
@@ -1074,33 +1089,17 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
|
||||
int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
|
||||
{
|
||||
struct mptcp_pm_addr_entry *entry;
|
||||
struct mptcp_addr_info skc_local;
|
||||
struct mptcp_addr_info msk_local;
|
||||
struct pm_nl_pernet *pernet;
|
||||
int ret = -1;
|
||||
|
||||
if (WARN_ON_ONCE(!msk))
|
||||
return -1;
|
||||
|
||||
/* The 0 ID mapping is defined by the first subflow, copied into the msk
|
||||
* addr
|
||||
*/
|
||||
mptcp_local_address((struct sock_common *)msk, &msk_local);
|
||||
mptcp_local_address((struct sock_common *)skc, &skc_local);
|
||||
if (mptcp_addresses_equal(&msk_local, &skc_local, false))
|
||||
return 0;
|
||||
|
||||
if (mptcp_pm_is_userspace(msk))
|
||||
return mptcp_userspace_pm_get_local_id(msk, &skc_local);
|
||||
|
||||
pernet = pm_nl_get_pernet_from_msk(msk);
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
|
||||
if (mptcp_addresses_equal(&entry->addr, &skc_local, entry->addr.port)) {
|
||||
if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) {
|
||||
ret = entry->addr.id;
|
||||
break;
|
||||
}
|
||||
@@ -1114,7 +1113,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
entry->addr = skc_local;
|
||||
entry->addr = *skc;
|
||||
entry->addr.id = 0;
|
||||
entry->addr.port = 0;
|
||||
entry->ifindex = 0;
|
||||
@@ -1328,20 +1327,27 @@ static struct pm_nl_pernet *genl_info_pm_nl(struct genl_info *info)
|
||||
return pm_nl_get_pernet(genl_info_net(info));
|
||||
}
|
||||
|
||||
static int mptcp_nl_add_subflow_or_signal_addr(struct net *net)
|
||||
static int mptcp_nl_add_subflow_or_signal_addr(struct net *net,
|
||||
struct mptcp_addr_info *addr)
|
||||
{
|
||||
struct mptcp_sock *msk;
|
||||
long s_slot = 0, s_num = 0;
|
||||
|
||||
while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
|
||||
struct sock *sk = (struct sock *)msk;
|
||||
struct mptcp_addr_info mpc_addr;
|
||||
|
||||
if (!READ_ONCE(msk->fully_established) ||
|
||||
mptcp_pm_is_userspace(msk))
|
||||
goto next;
|
||||
|
||||
/* if the endp linked to the init sf is re-added with a != ID */
|
||||
mptcp_local_address((struct sock_common *)msk, &mpc_addr);
|
||||
|
||||
lock_sock(sk);
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
if (mptcp_addresses_equal(addr, &mpc_addr, addr->port))
|
||||
msk->mpc_endpoint_id = addr->id;
|
||||
mptcp_pm_create_subflow_or_signal_addr(msk);
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
release_sock(sk);
|
||||
@@ -1414,7 +1420,7 @@ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk));
|
||||
mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk), &entry->addr);
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
@@ -1488,6 +1494,14 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id)
|
||||
{
|
||||
/* If it was marked as used, and not ID 0, decrement local_addr_used */
|
||||
if (!__test_and_set_bit(id ? : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap) &&
|
||||
id && !WARN_ON_ONCE(msk->pm.local_addr_used == 0))
|
||||
msk->pm.local_addr_used--;
|
||||
}
|
||||
|
||||
static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
|
||||
const struct mptcp_pm_addr_entry *entry)
|
||||
{
|
||||
@@ -1518,15 +1532,19 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
|
||||
!(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
|
||||
|
||||
if (remove_subflow) {
|
||||
mptcp_pm_remove_subflow(msk, &list);
|
||||
} else if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
|
||||
/* If the subflow has been used, but now closed */
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
if (!__test_and_set_bit(entry->addr.id, msk->pm.id_avail_bitmap))
|
||||
msk->pm.local_addr_used--;
|
||||
mptcp_pm_nl_rm_subflow_received(msk, &list);
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
}
|
||||
|
||||
if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
__mark_subflow_endp_available(msk, list.ids[0]);
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
}
|
||||
|
||||
if (msk->mpc_endpoint_id == entry->addr.id)
|
||||
msk->mpc_endpoint_id = 0;
|
||||
release_sock(sk);
|
||||
|
||||
next:
|
||||
@@ -1561,6 +1579,7 @@ static int mptcp_nl_remove_id_zero_address(struct net *net,
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
mptcp_pm_remove_addr(msk, &list);
|
||||
mptcp_pm_nl_rm_subflow_received(msk, &list);
|
||||
__mark_subflow_endp_available(msk, 0);
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
release_sock(sk);
|
||||
|
||||
@@ -1664,18 +1683,14 @@ void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
|
||||
alist.ids[alist.nr++] = entry->addr.id;
|
||||
}
|
||||
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
if (alist.nr) {
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
msk->pm.add_addr_signaled -= alist.nr;
|
||||
mptcp_pm_remove_addr(msk, &alist);
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
}
|
||||
|
||||
if (slist.nr)
|
||||
mptcp_pm_remove_subflow(msk, &slist);
|
||||
|
||||
mptcp_pm_nl_rm_subflow_received(msk, &slist);
|
||||
/* Reset counters: maybe some subflows have been removed before */
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
|
||||
msk->pm.local_addr_used = 0;
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
@@ -1957,6 +1972,7 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
|
||||
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
mptcp_pm_nl_rm_subflow_received(msk, &list);
|
||||
__mark_subflow_endp_available(msk, list.ids[0]);
|
||||
mptcp_pm_create_subflow_or_signal_addr(msk);
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
}
|
||||
|
||||
@@ -2309,7 +2309,7 @@ static struct sock *mptcp_subflow_get_retrans(struct mptcp_sock *msk)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (subflow->backup) {
|
||||
if (subflow->backup || subflow->request_bkup) {
|
||||
if (!backup)
|
||||
backup = ssk;
|
||||
continue;
|
||||
@@ -2528,8 +2528,11 @@ static void __mptcp_close_subflow(struct sock *sk)
|
||||
|
||||
mptcp_for_each_subflow_safe(msk, subflow, tmp) {
|
||||
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
|
||||
int ssk_state = inet_sk_state_load(ssk);
|
||||
|
||||
if (inet_sk_state_load(ssk) != TCP_CLOSE)
|
||||
if (ssk_state != TCP_CLOSE &&
|
||||
(ssk_state != TCP_CLOSE_WAIT ||
|
||||
inet_sk_state_load(sk) != TCP_ESTABLISHED))
|
||||
continue;
|
||||
|
||||
/* 'subflow_data_ready' will re-sched once rx queue is empty */
|
||||
|
||||
@@ -802,6 +802,8 @@ void mptcp_pm_add_addr_received(const struct sock *ssk,
|
||||
void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk,
|
||||
const struct mptcp_addr_info *addr);
|
||||
void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk);
|
||||
bool mptcp_pm_nl_is_init_remote_addr(struct mptcp_sock *msk,
|
||||
const struct mptcp_addr_info *remote);
|
||||
void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk);
|
||||
void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
|
||||
const struct mptcp_rm_list *rm_list);
|
||||
@@ -834,7 +836,6 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
|
||||
const struct mptcp_addr_info *addr,
|
||||
bool echo);
|
||||
int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
|
||||
int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
|
||||
void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list);
|
||||
void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
|
||||
struct list_head *rm_list);
|
||||
@@ -912,6 +913,7 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
|
||||
bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
|
||||
struct mptcp_rm_list *rm_list);
|
||||
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
|
||||
int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
|
||||
int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
|
||||
bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
|
||||
bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
|
||||
@@ -928,9 +930,6 @@ static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflo
|
||||
|
||||
void __init mptcp_pm_nl_init(void);
|
||||
void mptcp_pm_nl_work(struct mptcp_sock *msk);
|
||||
void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
|
||||
const struct mptcp_rm_list *rm_list);
|
||||
int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
|
||||
unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk);
|
||||
unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk);
|
||||
unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk);
|
||||
|
||||
@@ -1137,12 +1137,16 @@ out:
|
||||
/* sched mptcp worker to remove the subflow if no more data is pending */
|
||||
static void subflow_sched_work_if_closed(struct mptcp_sock *msk, struct sock *ssk)
|
||||
{
|
||||
if (likely(ssk->sk_state != TCP_CLOSE))
|
||||
struct sock *sk = (struct sock *)msk;
|
||||
|
||||
if (likely(ssk->sk_state != TCP_CLOSE &&
|
||||
(ssk->sk_state != TCP_CLOSE_WAIT ||
|
||||
inet_sk_state_load(sk) != TCP_ESTABLISHED)))
|
||||
return;
|
||||
|
||||
if (skb_queue_empty(&ssk->sk_receive_queue) &&
|
||||
!test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
|
||||
mptcp_schedule_work((struct sock *)msk);
|
||||
mptcp_schedule_work(sk);
|
||||
}
|
||||
|
||||
static bool subflow_can_fallback(struct mptcp_subflow_context *subflow)
|
||||
|
||||
@@ -2261,12 +2261,6 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
|
||||
}
|
||||
}
|
||||
|
||||
/* Update socket peer label if first association. */
|
||||
if (security_sctp_assoc_request(new_asoc, chunk->head_skb ?: chunk->skb)) {
|
||||
sctp_association_free(new_asoc);
|
||||
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
|
||||
}
|
||||
|
||||
/* Set temp so that it won't be added into hashtable */
|
||||
new_asoc->temp = 1;
|
||||
|
||||
@@ -2275,6 +2269,22 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
|
||||
*/
|
||||
action = sctp_tietags_compare(new_asoc, asoc);
|
||||
|
||||
/* In cases C and E the association doesn't enter the ESTABLISHED
|
||||
* state, so there is no need to call security_sctp_assoc_request().
|
||||
*/
|
||||
switch (action) {
|
||||
case 'A': /* Association restart. */
|
||||
case 'B': /* Collision case B. */
|
||||
case 'D': /* Collision case D. */
|
||||
/* Update socket peer label if first association. */
|
||||
if (security_sctp_assoc_request((struct sctp_association *)asoc,
|
||||
chunk->head_skb ?: chunk->skb)) {
|
||||
sctp_association_free(new_asoc);
|
||||
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case 'A': /* Association restart. */
|
||||
retval = sctp_sf_do_dupcook_a(net, ep, asoc, chunk, commands,
|
||||
|
||||
@@ -81,14 +81,14 @@ static struct aa_ext *build_aa_ext_struct(struct policy_unpack_fixture *puf,
|
||||
*(buf + 1) = strlen(TEST_U32_NAME) + 1;
|
||||
strcpy(buf + 3, TEST_U32_NAME);
|
||||
*(buf + 3 + strlen(TEST_U32_NAME) + 1) = AA_U32;
|
||||
*((u32 *)(buf + 3 + strlen(TEST_U32_NAME) + 2)) = TEST_U32_DATA;
|
||||
*((__le32 *)(buf + 3 + strlen(TEST_U32_NAME) + 2)) = cpu_to_le32(TEST_U32_DATA);
|
||||
|
||||
buf = e->start + TEST_NAMED_U64_BUF_OFFSET;
|
||||
*buf = AA_NAME;
|
||||
*(buf + 1) = strlen(TEST_U64_NAME) + 1;
|
||||
strcpy(buf + 3, TEST_U64_NAME);
|
||||
*(buf + 3 + strlen(TEST_U64_NAME) + 1) = AA_U64;
|
||||
*((u64 *)(buf + 3 + strlen(TEST_U64_NAME) + 2)) = TEST_U64_DATA;
|
||||
*((__le64 *)(buf + 3 + strlen(TEST_U64_NAME) + 2)) = cpu_to_le64(TEST_U64_DATA);
|
||||
|
||||
buf = e->start + TEST_NAMED_BLOB_BUF_OFFSET;
|
||||
*buf = AA_NAME;
|
||||
@@ -104,7 +104,7 @@ static struct aa_ext *build_aa_ext_struct(struct policy_unpack_fixture *puf,
|
||||
*(buf + 1) = strlen(TEST_ARRAY_NAME) + 1;
|
||||
strcpy(buf + 3, TEST_ARRAY_NAME);
|
||||
*(buf + 3 + strlen(TEST_ARRAY_NAME) + 1) = AA_ARRAY;
|
||||
*((u16 *)(buf + 3 + strlen(TEST_ARRAY_NAME) + 2)) = TEST_ARRAY_SIZE;
|
||||
*((__le16 *)(buf + 3 + strlen(TEST_ARRAY_NAME) + 2)) = cpu_to_le16(TEST_ARRAY_SIZE);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -144,6 +144,8 @@ static const struct platform_device_id board_ids[] = {
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, board_ids);
|
||||
|
||||
static struct platform_driver acp_asoc_audio = {
|
||||
.driver = {
|
||||
.pm = &snd_soc_pm_ops,
|
||||
|
||||
@@ -363,6 +363,7 @@ static int acp_power_on(struct snd_sof_dev *sdev)
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
unsigned int base = desc->pgfsm_base;
|
||||
unsigned int val;
|
||||
unsigned int acp_pgfsm_status_mask, acp_pgfsm_cntl_mask;
|
||||
int ret;
|
||||
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + PGFSM_STATUS_OFFSET);
|
||||
@@ -370,9 +371,23 @@ static int acp_power_on(struct snd_sof_dev *sdev)
|
||||
if (val == ACP_POWERED_ON)
|
||||
return 0;
|
||||
|
||||
if (val & ACP_PGFSM_STATUS_MASK)
|
||||
switch (desc->rev) {
|
||||
case 3:
|
||||
case 5:
|
||||
acp_pgfsm_status_mask = ACP3X_PGFSM_STATUS_MASK;
|
||||
acp_pgfsm_cntl_mask = ACP3X_PGFSM_CNTL_POWER_ON_MASK;
|
||||
break;
|
||||
case 6:
|
||||
acp_pgfsm_status_mask = ACP6X_PGFSM_STATUS_MASK;
|
||||
acp_pgfsm_cntl_mask = ACP6X_PGFSM_CNTL_POWER_ON_MASK;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (val & acp_pgfsm_status_mask)
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + PGFSM_CONTROL_OFFSET,
|
||||
ACP_PGFSM_CNTL_POWER_ON_MASK);
|
||||
acp_pgfsm_cntl_mask);
|
||||
|
||||
ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, base + PGFSM_STATUS_OFFSET, val,
|
||||
!val, ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
|
||||
|
||||
@@ -22,8 +22,11 @@
|
||||
#define ACP_REG_POLL_TIMEOUT_US 2000
|
||||
#define ACP_DMA_COMPLETE_TIMEOUT_US 5000
|
||||
|
||||
#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
|
||||
#define ACP_PGFSM_STATUS_MASK 0x03
|
||||
#define ACP3X_PGFSM_CNTL_POWER_ON_MASK 0x01
|
||||
#define ACP3X_PGFSM_STATUS_MASK 0x03
|
||||
#define ACP6X_PGFSM_CNTL_POWER_ON_MASK 0x07
|
||||
#define ACP6X_PGFSM_STATUS_MASK 0x0F
|
||||
|
||||
#define ACP_POWERED_ON 0x00
|
||||
#define ACP_ASSERT_RESET 0x01
|
||||
#define ACP_RELEASE_RESET 0x00
|
||||
|
||||
@@ -278,6 +278,10 @@ bridge()
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
||||
ip link set $h2 down
|
||||
ip link set $h1 down
|
||||
|
||||
vrf_cleanup
|
||||
}
|
||||
|
||||
|
||||
@@ -233,6 +233,9 @@ cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
||||
ip link set dev $swp2 down
|
||||
ip link set dev $swp1 down
|
||||
|
||||
h2_destroy
|
||||
h1_destroy
|
||||
|
||||
|
||||
Reference in New Issue
Block a user