mirror of
https://github.com/armbian/build.git
synced 2025-08-15 23:56:57 +02:00
951 lines
33 KiB
Diff
951 lines
33 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index bb3bd3c9072059..2b22872d3cea59 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,7 +1,7 @@
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
VERSION = 6
|
|
PATCHLEVEL = 6
|
|
-SUBLEVEL = 85
|
|
+SUBLEVEL = 86
|
|
EXTRAVERSION =
|
|
NAME = Pinguïn Aangedreven
|
|
|
|
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
|
|
index fef62e4a9edde6..ed1a25f457e48e 100644
|
|
--- a/arch/arm/mm/fault.c
|
|
+++ b/arch/arm/mm/fault.c
|
|
@@ -27,6 +27,13 @@
|
|
|
|
#ifdef CONFIG_MMU
|
|
|
|
+bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
|
|
+{
|
|
+ unsigned long addr = (unsigned long)unsafe_src;
|
|
+
|
|
+ return addr >= TASK_SIZE && ULONG_MAX - addr >= size;
|
|
+}
|
|
+
|
|
/*
|
|
* This is useful to dump out the page tables associated with
|
|
* 'addr' in mm 'mm'.
|
|
@@ -556,6 +563,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
|
|
if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
|
|
return;
|
|
|
|
+ pr_alert("8<--- cut here ---\n");
|
|
pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
|
|
inf->name, ifsr, addr);
|
|
|
|
diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
|
|
index b3e615cbd2caa6..461f57f66631c3 100644
|
|
--- a/drivers/counter/microchip-tcb-capture.c
|
|
+++ b/drivers/counter/microchip-tcb-capture.c
|
|
@@ -368,6 +368,25 @@ static int mchp_tc_probe(struct platform_device *pdev)
|
|
channel);
|
|
}
|
|
|
|
+ /* Disable Quadrature Decoder and position measure */
|
|
+ ret = regmap_update_bits(regmap, ATMEL_TC_BMR, ATMEL_TC_QDEN | ATMEL_TC_POSEN, 0);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ /* Setup the period capture mode */
|
|
+ ret = regmap_update_bits(regmap, ATMEL_TC_REG(priv->channel[0], CMR),
|
|
+ ATMEL_TC_WAVE | ATMEL_TC_ABETRG | ATMEL_TC_CMR_MASK |
|
|
+ ATMEL_TC_TCCLKS,
|
|
+ ATMEL_TC_CMR_MASK);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ /* Enable clock and trigger counter */
|
|
+ ret = regmap_write(regmap, ATMEL_TC_REG(priv->channel[0], CCR),
|
|
+ ATMEL_TC_CLKEN | ATMEL_TC_SWTRG);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
priv->tc_cfg = tcb_config;
|
|
priv->regmap = regmap;
|
|
counter->name = dev_name(&pdev->dev);
|
|
diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
|
|
index 8439755559b219..537fe9b669f352 100644
|
|
--- a/drivers/counter/stm32-lptimer-cnt.c
|
|
+++ b/drivers/counter/stm32-lptimer-cnt.c
|
|
@@ -58,37 +58,43 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
|
|
return 0;
|
|
}
|
|
|
|
+ ret = clk_enable(priv->clk);
|
|
+ if (ret)
|
|
+ goto disable_cnt;
|
|
+
|
|
/* LP timer must be enabled before writing CMP & ARR */
|
|
ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->ceiling);
|
|
if (ret)
|
|
- return ret;
|
|
+ goto disable_clk;
|
|
|
|
ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, 0);
|
|
if (ret)
|
|
- return ret;
|
|
+ goto disable_clk;
|
|
|
|
/* ensure CMP & ARR registers are properly written */
|
|
ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
|
|
(val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
|
|
100, 1000);
|
|
if (ret)
|
|
- return ret;
|
|
+ goto disable_clk;
|
|
|
|
ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
|
|
STM32_LPTIM_CMPOKCF_ARROKCF);
|
|
if (ret)
|
|
- return ret;
|
|
+ goto disable_clk;
|
|
|
|
- ret = clk_enable(priv->clk);
|
|
- if (ret) {
|
|
- regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
|
|
- return ret;
|
|
- }
|
|
priv->enabled = true;
|
|
|
|
/* Start LP timer in continuous mode */
|
|
return regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
|
|
STM32_LPTIM_CNTSTRT, STM32_LPTIM_CNTSTRT);
|
|
+
|
|
+disable_clk:
|
|
+ clk_disable(priv->clk);
|
|
+disable_cnt:
|
|
+ regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
|
|
+
|
|
+ return ret;
|
|
}
|
|
|
|
static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
|
|
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
|
|
index 986ee37688c16c..2b7f98a2e36f55 100644
|
|
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
|
|
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
|
|
@@ -2825,8 +2825,7 @@ static int dm_resume(void *handle)
|
|
struct dm_atomic_state *dm_state = to_dm_atomic_state(dm->atomic_obj.state);
|
|
enum dc_connection_type new_connection_type = dc_connection_none;
|
|
struct dc_state *dc_state;
|
|
- int i, r, j, ret;
|
|
- bool need_hotplug = false;
|
|
+ int i, r, j;
|
|
|
|
if (amdgpu_in_reset(adev)) {
|
|
dc_state = dm->cached_dc_state;
|
|
@@ -3003,23 +3002,16 @@ static int dm_resume(void *handle)
|
|
aconnector->mst_root)
|
|
continue;
|
|
|
|
- ret = drm_dp_mst_topology_mgr_resume(&aconnector->mst_mgr, true);
|
|
-
|
|
- if (ret < 0) {
|
|
- dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx,
|
|
- aconnector->dc_link);
|
|
- need_hotplug = true;
|
|
- }
|
|
+ drm_dp_mst_topology_queue_probe(&aconnector->mst_mgr);
|
|
}
|
|
drm_connector_list_iter_end(&iter);
|
|
|
|
- if (need_hotplug)
|
|
- drm_kms_helper_hotplug_event(ddev);
|
|
-
|
|
amdgpu_dm_irq_resume_late(adev);
|
|
|
|
amdgpu_dm_smu_write_watermarks_table(adev);
|
|
|
|
+ drm_kms_helper_hotplug_event(ddev);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
|
|
index 3f3b555b4523a2..597fa0364a3a9b 100644
|
|
--- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
|
|
+++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
|
|
@@ -1753,7 +1753,7 @@ static int dcn315_populate_dml_pipes_from_context(
|
|
bool split_required = pipe->stream->timing.pix_clk_100hz >= dcn_get_max_non_odm_pix_rate_100hz(&dc->dml.soc)
|
|
|| (pipe->plane_state && pipe->plane_state->src_rect.width > 5120);
|
|
|
|
- if (remaining_det_segs > MIN_RESERVED_DET_SEGS)
|
|
+ if (remaining_det_segs > MIN_RESERVED_DET_SEGS && crb_pipes != 0)
|
|
pipes[pipe_cnt].pipe.src.det_size_override += (remaining_det_segs - MIN_RESERVED_DET_SEGS) / crb_pipes +
|
|
(crb_idx < (remaining_det_segs - MIN_RESERVED_DET_SEGS) % crb_pipes ? 1 : 0);
|
|
if (pipes[pipe_cnt].pipe.src.det_size_override > 2 * DCN3_15_MAX_DET_SEGS) {
|
|
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
|
|
index 08f8a22431fe1f..71a30387ca125b 100644
|
|
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
|
|
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
|
|
@@ -2692,6 +2692,11 @@ static void drm_dp_mst_link_probe_work(struct work_struct *work)
|
|
drm_kms_helper_hotplug_event(dev);
|
|
}
|
|
|
|
+static void drm_dp_mst_queue_probe_work(struct drm_dp_mst_topology_mgr *mgr)
|
|
+{
|
|
+ queue_work(system_long_wq, &mgr->work);
|
|
+}
|
|
+
|
|
static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
|
|
u8 *guid)
|
|
{
|
|
@@ -3643,7 +3648,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
|
|
/* Write reset payload */
|
|
drm_dp_dpcd_write_payload(mgr, 0, 0, 0x3f);
|
|
|
|
- queue_work(system_long_wq, &mgr->work);
|
|
+ drm_dp_mst_queue_probe_work(mgr);
|
|
|
|
ret = 0;
|
|
} else {
|
|
@@ -3680,6 +3685,33 @@ drm_dp_mst_topology_mgr_invalidate_mstb(struct drm_dp_mst_branch *mstb)
|
|
drm_dp_mst_topology_mgr_invalidate_mstb(port->mstb);
|
|
}
|
|
|
|
+/**
|
|
+ * drm_dp_mst_topology_queue_probe - Queue a topology probe
|
|
+ * @mgr: manager to probe
|
|
+ *
|
|
+ * Queue a work to probe the MST topology. Driver's should call this only to
|
|
+ * sync the topology's HW->SW state after the MST link's parameters have
|
|
+ * changed in a way the state could've become out-of-sync. This is the case
|
|
+ * for instance when the link rate between the source and first downstream
|
|
+ * branch device has switched between UHBR and non-UHBR rates. Except of those
|
|
+ * cases - for instance when a sink gets plugged/unplugged to a port - the SW
|
|
+ * state will get updated automatically via MST UP message notifications.
|
|
+ */
|
|
+void drm_dp_mst_topology_queue_probe(struct drm_dp_mst_topology_mgr *mgr)
|
|
+{
|
|
+ mutex_lock(&mgr->lock);
|
|
+
|
|
+ if (drm_WARN_ON(mgr->dev, !mgr->mst_state || !mgr->mst_primary))
|
|
+ goto out_unlock;
|
|
+
|
|
+ drm_dp_mst_topology_mgr_invalidate_mstb(mgr->mst_primary);
|
|
+ drm_dp_mst_queue_probe_work(mgr);
|
|
+
|
|
+out_unlock:
|
|
+ mutex_unlock(&mgr->lock);
|
|
+}
|
|
+EXPORT_SYMBOL(drm_dp_mst_topology_queue_probe);
|
|
+
|
|
/**
|
|
* drm_dp_mst_topology_mgr_suspend() - suspend the MST manager
|
|
* @mgr: manager to suspend
|
|
@@ -3766,7 +3798,7 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,
|
|
* state of our in-memory topology back into sync with reality. So,
|
|
* restart the probing process as if we're probing a new hub
|
|
*/
|
|
- queue_work(system_long_wq, &mgr->work);
|
|
+ drm_dp_mst_queue_probe_work(mgr);
|
|
mutex_unlock(&mgr->lock);
|
|
|
|
if (sync) {
|
|
diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c
|
|
index 25cfd964dc25d9..acb9eb18f7ccfe 100644
|
|
--- a/drivers/hid/hid-plantronics.c
|
|
+++ b/drivers/hid/hid-plantronics.c
|
|
@@ -6,9 +6,6 @@
|
|
* Copyright (c) 2015-2018 Terry Junge <terry.junge@plantronics.com>
|
|
*/
|
|
|
|
-/*
|
|
- */
|
|
-
|
|
#include "hid-ids.h"
|
|
|
|
#include <linux/hid.h>
|
|
@@ -23,30 +20,28 @@
|
|
|
|
#define PLT_VOL_UP 0x00b1
|
|
#define PLT_VOL_DOWN 0x00b2
|
|
+#define PLT_MIC_MUTE 0x00b5
|
|
|
|
#define PLT1_VOL_UP (PLT_HID_1_0_PAGE | PLT_VOL_UP)
|
|
#define PLT1_VOL_DOWN (PLT_HID_1_0_PAGE | PLT_VOL_DOWN)
|
|
+#define PLT1_MIC_MUTE (PLT_HID_1_0_PAGE | PLT_MIC_MUTE)
|
|
#define PLT2_VOL_UP (PLT_HID_2_0_PAGE | PLT_VOL_UP)
|
|
#define PLT2_VOL_DOWN (PLT_HID_2_0_PAGE | PLT_VOL_DOWN)
|
|
+#define PLT2_MIC_MUTE (PLT_HID_2_0_PAGE | PLT_MIC_MUTE)
|
|
+#define HID_TELEPHONY_MUTE (HID_UP_TELEPHONY | 0x2f)
|
|
+#define HID_CONSUMER_MUTE (HID_UP_CONSUMER | 0xe2)
|
|
|
|
#define PLT_DA60 0xda60
|
|
#define PLT_BT300_MIN 0x0413
|
|
#define PLT_BT300_MAX 0x0418
|
|
|
|
-
|
|
-#define PLT_ALLOW_CONSUMER (field->application == HID_CP_CONSUMERCONTROL && \
|
|
- (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
|
|
-
|
|
-#define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0)
|
|
-#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1)
|
|
-
|
|
#define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
|
|
-#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */
|
|
|
|
struct plt_drv_data {
|
|
unsigned long device_type;
|
|
- unsigned long last_volume_key_ts;
|
|
- u32 quirks;
|
|
+ unsigned long last_key_ts;
|
|
+ unsigned long double_key_to;
|
|
+ __u16 last_key;
|
|
};
|
|
|
|
static int plantronics_input_mapping(struct hid_device *hdev,
|
|
@@ -58,34 +53,43 @@ static int plantronics_input_mapping(struct hid_device *hdev,
|
|
unsigned short mapped_key;
|
|
struct plt_drv_data *drv_data = hid_get_drvdata(hdev);
|
|
unsigned long plt_type = drv_data->device_type;
|
|
+ int allow_mute = usage->hid == HID_TELEPHONY_MUTE;
|
|
+ int allow_consumer = field->application == HID_CP_CONSUMERCONTROL &&
|
|
+ (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER &&
|
|
+ usage->hid != HID_CONSUMER_MUTE;
|
|
|
|
/* special case for PTT products */
|
|
if (field->application == HID_GD_JOYSTICK)
|
|
goto defaulted;
|
|
|
|
- /* handle volume up/down mapping */
|
|
/* non-standard types or multi-HID interfaces - plt_type is PID */
|
|
if (!(plt_type & HID_USAGE_PAGE)) {
|
|
switch (plt_type) {
|
|
case PLT_DA60:
|
|
- if (PLT_ALLOW_CONSUMER)
|
|
+ if (allow_consumer)
|
|
goto defaulted;
|
|
- goto ignored;
|
|
+ if (usage->hid == HID_CONSUMER_MUTE) {
|
|
+ mapped_key = KEY_MICMUTE;
|
|
+ goto mapped;
|
|
+ }
|
|
+ break;
|
|
default:
|
|
- if (PLT_ALLOW_CONSUMER)
|
|
+ if (allow_consumer || allow_mute)
|
|
goto defaulted;
|
|
}
|
|
+ goto ignored;
|
|
}
|
|
- /* handle standard types - plt_type is 0xffa0uuuu or 0xffa2uuuu */
|
|
- /* 'basic telephony compliant' - allow default consumer page map */
|
|
- else if ((plt_type & HID_USAGE) >= PLT_BASIC_TELEPHONY &&
|
|
- (plt_type & HID_USAGE) != PLT_BASIC_EXCEPTION) {
|
|
- if (PLT_ALLOW_CONSUMER)
|
|
- goto defaulted;
|
|
- }
|
|
- /* not 'basic telephony' - apply legacy mapping */
|
|
- /* only map if the field is in the device's primary vendor page */
|
|
- else if (!((field->application ^ plt_type) & HID_USAGE_PAGE)) {
|
|
+
|
|
+ /* handle standard consumer control mapping */
|
|
+ /* and standard telephony mic mute mapping */
|
|
+ if (allow_consumer || allow_mute)
|
|
+ goto defaulted;
|
|
+
|
|
+ /* handle vendor unique types - plt_type is 0xffa0uuuu or 0xffa2uuuu */
|
|
+ /* if not 'basic telephony compliant' - map vendor unique controls */
|
|
+ if (!((plt_type & HID_USAGE) >= PLT_BASIC_TELEPHONY &&
|
|
+ (plt_type & HID_USAGE) != PLT_BASIC_EXCEPTION) &&
|
|
+ !((field->application ^ plt_type) & HID_USAGE_PAGE))
|
|
switch (usage->hid) {
|
|
case PLT1_VOL_UP:
|
|
case PLT2_VOL_UP:
|
|
@@ -95,8 +99,11 @@ static int plantronics_input_mapping(struct hid_device *hdev,
|
|
case PLT2_VOL_DOWN:
|
|
mapped_key = KEY_VOLUMEDOWN;
|
|
goto mapped;
|
|
+ case PLT1_MIC_MUTE:
|
|
+ case PLT2_MIC_MUTE:
|
|
+ mapped_key = KEY_MICMUTE;
|
|
+ goto mapped;
|
|
}
|
|
- }
|
|
|
|
/*
|
|
* Future mapping of call control or other usages,
|
|
@@ -105,6 +112,8 @@ static int plantronics_input_mapping(struct hid_device *hdev,
|
|
*/
|
|
|
|
ignored:
|
|
+ hid_dbg(hdev, "usage: %08x (appl: %08x) - ignored\n",
|
|
+ usage->hid, field->application);
|
|
return -1;
|
|
|
|
defaulted:
|
|
@@ -123,38 +132,26 @@ static int plantronics_event(struct hid_device *hdev, struct hid_field *field,
|
|
struct hid_usage *usage, __s32 value)
|
|
{
|
|
struct plt_drv_data *drv_data = hid_get_drvdata(hdev);
|
|
+ unsigned long prev_tsto, cur_ts;
|
|
+ __u16 prev_key, cur_key;
|
|
|
|
- if (drv_data->quirks & PLT_QUIRK_DOUBLE_VOLUME_KEYS) {
|
|
- unsigned long prev_ts, cur_ts;
|
|
+ /* Usages are filtered in plantronics_usages. */
|
|
|
|
- /* Usages are filtered in plantronics_usages. */
|
|
+ /* HZ too low for ms resolution - double key detection disabled */
|
|
+ /* or it is a key release - handle key presses only. */
|
|
+ if (!drv_data->double_key_to || !value)
|
|
+ return 0;
|
|
|
|
- if (!value) /* Handle key presses only. */
|
|
- return 0;
|
|
+ prev_tsto = drv_data->last_key_ts + drv_data->double_key_to;
|
|
+ cur_ts = drv_data->last_key_ts = jiffies;
|
|
+ prev_key = drv_data->last_key;
|
|
+ cur_key = drv_data->last_key = usage->code;
|
|
|
|
- prev_ts = drv_data->last_volume_key_ts;
|
|
- cur_ts = jiffies;
|
|
- if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_DOUBLE_KEY_TIMEOUT)
|
|
- return 1; /* Ignore the repeated key. */
|
|
-
|
|
- drv_data->last_volume_key_ts = cur_ts;
|
|
+ /* If the same key occurs in <= double_key_to -- ignore it */
|
|
+ if (prev_key == cur_key && time_before_eq(cur_ts, prev_tsto)) {
|
|
+ hid_dbg(hdev, "double key %d ignored\n", cur_key);
|
|
+ return 1; /* Ignore the repeated key. */
|
|
}
|
|
- if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) {
|
|
- unsigned long prev_ts, cur_ts;
|
|
-
|
|
- /* Usages are filtered in plantronics_usages. */
|
|
-
|
|
- if (!value) /* Handle key presses only. */
|
|
- return 0;
|
|
-
|
|
- prev_ts = drv_data->last_volume_key_ts;
|
|
- cur_ts = jiffies;
|
|
- if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT)
|
|
- return 1; /* Ignore the followed opposite volume key. */
|
|
-
|
|
- drv_data->last_volume_key_ts = cur_ts;
|
|
- }
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -196,12 +193,16 @@ static int plantronics_probe(struct hid_device *hdev,
|
|
ret = hid_parse(hdev);
|
|
if (ret) {
|
|
hid_err(hdev, "parse failed\n");
|
|
- goto err;
|
|
+ return ret;
|
|
}
|
|
|
|
drv_data->device_type = plantronics_device_type(hdev);
|
|
- drv_data->quirks = id->driver_data;
|
|
- drv_data->last_volume_key_ts = jiffies - msecs_to_jiffies(PLT_DOUBLE_KEY_TIMEOUT);
|
|
+ drv_data->double_key_to = msecs_to_jiffies(PLT_DOUBLE_KEY_TIMEOUT);
|
|
+ drv_data->last_key_ts = jiffies - drv_data->double_key_to;
|
|
+
|
|
+ /* if HZ does not allow ms resolution - disable double key detection */
|
|
+ if (drv_data->double_key_to < PLT_DOUBLE_KEY_TIMEOUT)
|
|
+ drv_data->double_key_to = 0;
|
|
|
|
hid_set_drvdata(hdev, drv_data);
|
|
|
|
@@ -210,29 +211,10 @@ static int plantronics_probe(struct hid_device *hdev,
|
|
if (ret)
|
|
hid_err(hdev, "hw start failed\n");
|
|
|
|
-err:
|
|
return ret;
|
|
}
|
|
|
|
static const struct hid_device_id plantronics_devices[] = {
|
|
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
|
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
|
|
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
|
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
|
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
|
|
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
|
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
|
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
|
|
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
|
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
|
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
|
|
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
|
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
|
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES),
|
|
- .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
|
|
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
|
- USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES),
|
|
- .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
|
|
{ }
|
|
};
|
|
@@ -241,6 +223,14 @@ MODULE_DEVICE_TABLE(hid, plantronics_devices);
|
|
static const struct hid_usage_id plantronics_usages[] = {
|
|
{ HID_CP_VOLUMEUP, EV_KEY, HID_ANY_ID },
|
|
{ HID_CP_VOLUMEDOWN, EV_KEY, HID_ANY_ID },
|
|
+ { HID_TELEPHONY_MUTE, EV_KEY, HID_ANY_ID },
|
|
+ { HID_CONSUMER_MUTE, EV_KEY, HID_ANY_ID },
|
|
+ { PLT2_VOL_UP, EV_KEY, HID_ANY_ID },
|
|
+ { PLT2_VOL_DOWN, EV_KEY, HID_ANY_ID },
|
|
+ { PLT2_MIC_MUTE, EV_KEY, HID_ANY_ID },
|
|
+ { PLT1_VOL_UP, EV_KEY, HID_ANY_ID },
|
|
+ { PLT1_VOL_DOWN, EV_KEY, HID_ANY_ID },
|
|
+ { PLT1_MIC_MUTE, EV_KEY, HID_ANY_ID },
|
|
{ HID_TERMINATOR, HID_TERMINATOR, HID_TERMINATOR }
|
|
};
|
|
|
|
diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c
|
|
index 29271ad4728a2f..dec279845a752d 100644
|
|
--- a/drivers/memstick/host/rtsx_usb_ms.c
|
|
+++ b/drivers/memstick/host/rtsx_usb_ms.c
|
|
@@ -813,6 +813,7 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
|
|
|
|
host->eject = true;
|
|
cancel_work_sync(&host->handle_req);
|
|
+ cancel_delayed_work_sync(&host->poll_card);
|
|
|
|
mutex_lock(&host->host_mutex);
|
|
if (host->req) {
|
|
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
|
|
index 8e30df676ededb..dc84d9029c2c79 100644
|
|
--- a/drivers/net/usb/qmi_wwan.c
|
|
+++ b/drivers/net/usb/qmi_wwan.c
|
|
@@ -1373,9 +1373,11 @@ static const struct usb_device_id products[] = {
|
|
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a0, 0)}, /* Telit FN920C04 */
|
|
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a4, 0)}, /* Telit FN920C04 */
|
|
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a9, 0)}, /* Telit FN920C04 */
|
|
+ {QMI_QUIRK_SET_DTR(0x1bc7, 0x10b0, 0)}, /* Telit FE990B */
|
|
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c0, 0)}, /* Telit FE910C04 */
|
|
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c4, 0)}, /* Telit FE910C04 */
|
|
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c8, 0)}, /* Telit FE910C04 */
|
|
+ {QMI_QUIRK_SET_DTR(0x1bc7, 0x10d0, 0)}, /* Telit FN990B */
|
|
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
|
|
{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */
|
|
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
|
|
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
|
|
index 9f66c47dc58bc7..08cbc8e4b361df 100644
|
|
--- a/drivers/net/usb/usbnet.c
|
|
+++ b/drivers/net/usb/usbnet.c
|
|
@@ -178,6 +178,17 @@ int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress)
|
|
}
|
|
EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
|
|
|
|
+static bool usbnet_needs_usb_name_format(struct usbnet *dev, struct net_device *net)
|
|
+{
|
|
+ /* Point to point devices which don't have a real MAC address
|
|
+ * (or report a fake local one) have historically used the usb%d
|
|
+ * naming. Preserve this..
|
|
+ */
|
|
+ return (dev->driver_info->flags & FLAG_POINTTOPOINT) != 0 &&
|
|
+ (is_zero_ether_addr(net->dev_addr) ||
|
|
+ is_local_ether_addr(net->dev_addr));
|
|
+}
|
|
+
|
|
static void intr_complete (struct urb *urb)
|
|
{
|
|
struct usbnet *dev = urb->context;
|
|
@@ -1766,13 +1777,11 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
|
|
if (status < 0)
|
|
goto out1;
|
|
|
|
- // heuristic: "usb%d" for links we know are two-host,
|
|
- // else "eth%d" when there's reasonable doubt. userspace
|
|
- // can rename the link if it knows better.
|
|
+ /* heuristic: rename to "eth%d" if we are not sure this link
|
|
+ * is two-host (these links keep "usb%d")
|
|
+ */
|
|
if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
|
|
- ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
|
|
- /* somebody touched it*/
|
|
- !is_zero_ether_addr(net->dev_addr)))
|
|
+ !usbnet_needs_usb_name_format(dev, net))
|
|
strscpy(net->name, "eth%d", sizeof(net->name));
|
|
/* WLAN devices should always be named "wlan%d" */
|
|
if ((dev->driver_info->flags & FLAG_WLAN) != 0)
|
|
diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.c b/drivers/reset/starfive/reset-starfive-jh71x0.c
|
|
index 55bbbd2de52cf9..29ce3486752f38 100644
|
|
--- a/drivers/reset/starfive/reset-starfive-jh71x0.c
|
|
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
|
|
@@ -94,6 +94,9 @@ static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
|
|
void __iomem *reg_status = data->status + offset * sizeof(u32);
|
|
u32 value = readl(reg_status);
|
|
|
|
+ if (!data->asserted)
|
|
+ return !(value & mask);
|
|
+
|
|
return !((value ^ data->asserted[offset]) & mask);
|
|
}
|
|
|
|
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c
|
|
index 7f23037813bc85..62492cf10bc9d4 100644
|
|
--- a/drivers/tty/serial/8250/8250_dma.c
|
|
+++ b/drivers/tty/serial/8250/8250_dma.c
|
|
@@ -152,7 +152,7 @@ void serial8250_tx_dma_flush(struct uart_8250_port *p)
|
|
*/
|
|
dma->tx_size = 0;
|
|
|
|
- dmaengine_terminate_async(dma->rxchan);
|
|
+ dmaengine_terminate_async(dma->txchan);
|
|
}
|
|
|
|
int serial8250_rx_dma(struct uart_8250_port *p)
|
|
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
|
|
index bbd7914ddc9adc..0b38fada414472 100644
|
|
--- a/drivers/tty/serial/8250/8250_pci.c
|
|
+++ b/drivers/tty/serial/8250/8250_pci.c
|
|
@@ -2576,6 +2576,22 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
|
|
.init = pci_oxsemi_tornado_init,
|
|
.setup = pci_oxsemi_tornado_setup,
|
|
},
|
|
+ {
|
|
+ .vendor = PCI_VENDOR_ID_INTASHIELD,
|
|
+ .device = 0x4026,
|
|
+ .subvendor = PCI_ANY_ID,
|
|
+ .subdevice = PCI_ANY_ID,
|
|
+ .init = pci_oxsemi_tornado_init,
|
|
+ .setup = pci_oxsemi_tornado_setup,
|
|
+ },
|
|
+ {
|
|
+ .vendor = PCI_VENDOR_ID_INTASHIELD,
|
|
+ .device = 0x4021,
|
|
+ .subvendor = PCI_ANY_ID,
|
|
+ .subdevice = PCI_ANY_ID,
|
|
+ .init = pci_oxsemi_tornado_init,
|
|
+ .setup = pci_oxsemi_tornado_setup,
|
|
+ },
|
|
{
|
|
.vendor = PCI_VENDOR_ID_INTEL,
|
|
.device = 0x8811,
|
|
@@ -5107,6 +5123,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
|
|
PCI_ANY_ID, PCI_ANY_ID,
|
|
0, 0,
|
|
pbn_b2_2_115200 },
|
|
+ { PCI_VENDOR_ID_INTASHIELD, 0x0BA2,
|
|
+ PCI_ANY_ID, PCI_ANY_ID,
|
|
+ 0, 0,
|
|
+ pbn_b2_2_115200 },
|
|
+ { PCI_VENDOR_ID_INTASHIELD, 0x0BA3,
|
|
+ PCI_ANY_ID, PCI_ANY_ID,
|
|
+ 0, 0,
|
|
+ pbn_b2_2_115200 },
|
|
/*
|
|
* Brainboxes UC-235/246
|
|
*/
|
|
@@ -5227,6 +5251,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
|
|
PCI_ANY_ID, PCI_ANY_ID,
|
|
0, 0,
|
|
pbn_b2_4_115200 },
|
|
+ { PCI_VENDOR_ID_INTASHIELD, 0x0C42,
|
|
+ PCI_ANY_ID, PCI_ANY_ID,
|
|
+ 0, 0,
|
|
+ pbn_b2_4_115200 },
|
|
+ { PCI_VENDOR_ID_INTASHIELD, 0x0C43,
|
|
+ PCI_ANY_ID, PCI_ANY_ID,
|
|
+ 0, 0,
|
|
+ pbn_b2_4_115200 },
|
|
/*
|
|
* Brainboxes UC-420
|
|
*/
|
|
@@ -5453,6 +5485,20 @@ static const struct pci_device_id serial_pci_tbl[] = {
|
|
PCI_ANY_ID, PCI_ANY_ID,
|
|
0, 0,
|
|
pbn_oxsemi_1_15625000 },
|
|
+ /*
|
|
+ * Brainboxes XC-235
|
|
+ */
|
|
+ { PCI_VENDOR_ID_INTASHIELD, 0x4026,
|
|
+ PCI_ANY_ID, PCI_ANY_ID,
|
|
+ 0, 0,
|
|
+ pbn_oxsemi_1_15625000 },
|
|
+ /*
|
|
+ * Brainboxes XC-475
|
|
+ */
|
|
+ { PCI_VENDOR_ID_INTASHIELD, 0x4021,
|
|
+ PCI_ANY_ID, PCI_ANY_ID,
|
|
+ 0, 0,
|
|
+ pbn_oxsemi_1_15625000 },
|
|
|
|
/*
|
|
* Perle PCI-RAS cards
|
|
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
|
|
index 8bd0f8e45b146f..70fa1e6aebe136 100644
|
|
--- a/drivers/tty/serial/fsl_lpuart.c
|
|
+++ b/drivers/tty/serial/fsl_lpuart.c
|
|
@@ -1488,6 +1488,19 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio
|
|
|
|
unsigned long modem = lpuart32_read(&sport->port, UARTMODIR)
|
|
& ~(UARTMODIR_TXRTSPOL | UARTMODIR_TXRTSE);
|
|
+ u32 ctrl;
|
|
+
|
|
+ /* TXRTSE and TXRTSPOL only can be changed when transmitter is disabled. */
|
|
+ ctrl = lpuart32_read(&sport->port, UARTCTRL);
|
|
+ if (ctrl & UARTCTRL_TE) {
|
|
+ /* wait for the transmit engine to complete */
|
|
+ lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
|
|
+ lpuart32_write(&sport->port, ctrl & ~UARTCTRL_TE, UARTCTRL);
|
|
+
|
|
+ while (lpuart32_read(&sport->port, UARTCTRL) & UARTCTRL_TE)
|
|
+ cpu_relax();
|
|
+ }
|
|
+
|
|
lpuart32_write(&sport->port, modem, UARTMODIR);
|
|
|
|
if (rs485->flags & SER_RS485_ENABLED) {
|
|
@@ -1507,6 +1520,10 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio
|
|
}
|
|
|
|
lpuart32_write(&sport->port, modem, UARTMODIR);
|
|
+
|
|
+ if (ctrl & UARTCTRL_TE)
|
|
+ lpuart32_write(&sport->port, ctrl, UARTCTRL);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
|
|
index c5a6b133d3643f..51ed40529f9a7b 100644
|
|
--- a/drivers/ufs/host/ufs-qcom.c
|
|
+++ b/drivers/ufs/host/ufs-qcom.c
|
|
@@ -1918,10 +1918,12 @@ static int ufs_qcom_probe(struct platform_device *pdev)
|
|
static int ufs_qcom_remove(struct platform_device *pdev)
|
|
{
|
|
struct ufs_hba *hba = platform_get_drvdata(pdev);
|
|
+ struct ufs_qcom_host *host = ufshcd_get_variant(hba);
|
|
|
|
pm_runtime_get_sync(&(pdev)->dev);
|
|
ufshcd_remove(hba);
|
|
- platform_msi_domain_free_irqs(hba->dev);
|
|
+ if (host->esi_enabled)
|
|
+ platform_msi_domain_free_irqs(hba->dev);
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c
|
|
index 3f0a9795c0d45d..0195625bef53ab 100644
|
|
--- a/drivers/usb/gadget/function/uvc_v4l2.c
|
|
+++ b/drivers/usb/gadget/function/uvc_v4l2.c
|
|
@@ -121,6 +121,9 @@ static struct uvcg_format *find_format_by_pix(struct uvc_device *uvc,
|
|
list_for_each_entry(format, &uvc->header->formats, entry) {
|
|
const struct uvc_format_desc *fmtdesc = to_uvc_format(format->fmt);
|
|
|
|
+ if (IS_ERR(fmtdesc))
|
|
+ continue;
|
|
+
|
|
if (fmtdesc->fcc == pixelformat) {
|
|
uformat = format->fmt;
|
|
break;
|
|
@@ -240,6 +243,7 @@ uvc_v4l2_try_format(struct file *file, void *fh, struct v4l2_format *fmt)
|
|
struct uvc_video *video = &uvc->video;
|
|
struct uvcg_format *uformat;
|
|
struct uvcg_frame *uframe;
|
|
+ const struct uvc_format_desc *fmtdesc;
|
|
u8 *fcc;
|
|
|
|
if (fmt->type != video->queue.queue.type)
|
|
@@ -265,7 +269,10 @@ uvc_v4l2_try_format(struct file *file, void *fh, struct v4l2_format *fmt)
|
|
fmt->fmt.pix.field = V4L2_FIELD_NONE;
|
|
fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(uformat, uframe);
|
|
fmt->fmt.pix.sizeimage = uvc_get_frame_size(uformat, uframe);
|
|
- fmt->fmt.pix.pixelformat = to_uvc_format(uformat)->fcc;
|
|
+ fmtdesc = to_uvc_format(uformat);
|
|
+ if (IS_ERR(fmtdesc))
|
|
+ return PTR_ERR(fmtdesc);
|
|
+ fmt->fmt.pix.pixelformat = fmtdesc->fcc;
|
|
fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
|
|
fmt->fmt.pix.priv = 0;
|
|
|
|
@@ -375,6 +382,9 @@ uvc_v4l2_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
|
|
return -EINVAL;
|
|
|
|
fmtdesc = to_uvc_format(uformat);
|
|
+ if (IS_ERR(fmtdesc))
|
|
+ return PTR_ERR(fmtdesc);
|
|
+
|
|
f->pixelformat = fmtdesc->fcc;
|
|
|
|
return 0;
|
|
diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
|
|
index ab1d73f93408e7..46705dacdd0816 100644
|
|
--- a/include/drm/display/drm_dp_mst_helper.h
|
|
+++ b/include/drm/display/drm_dp_mst_helper.h
|
|
@@ -859,6 +859,8 @@ int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
|
|
void drm_dp_mst_dump_topology(struct seq_file *m,
|
|
struct drm_dp_mst_topology_mgr *mgr);
|
|
|
|
+void drm_dp_mst_topology_queue_probe(struct drm_dp_mst_topology_mgr *mgr);
|
|
+
|
|
void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr);
|
|
int __must_check
|
|
drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,
|
|
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
|
|
index 191f0f95d3edf6..bc62bb2a3b132e 100644
|
|
--- a/mm/page_alloc.c
|
|
+++ b/mm/page_alloc.c
|
|
@@ -6653,7 +6653,7 @@ static bool try_to_accept_memory_one(struct zone *zone)
|
|
|
|
static bool cond_accept_memory(struct zone *zone, unsigned int order)
|
|
{
|
|
- long to_accept;
|
|
+ long to_accept, wmark;
|
|
bool ret = false;
|
|
|
|
if (!has_unaccepted_memory())
|
|
@@ -6662,8 +6662,18 @@ static bool cond_accept_memory(struct zone *zone, unsigned int order)
|
|
if (list_empty(&zone->unaccepted_pages))
|
|
return false;
|
|
|
|
+ wmark = high_wmark_pages(zone);
|
|
+
|
|
+ /*
|
|
+ * Watermarks have not been initialized yet.
|
|
+ *
|
|
+ * Accepting one MAX_ORDER page to ensure progress.
|
|
+ */
|
|
+ if (!wmark)
|
|
+ return try_to_accept_memory_one(zone);
|
|
+
|
|
/* How much to accept to get to high watermark? */
|
|
- to_accept = high_wmark_pages(zone) -
|
|
+ to_accept = wmark -
|
|
(zone_page_state(zone, NR_FREE_PAGES) -
|
|
__zone_watermark_unusable_free(zone, order, 0) -
|
|
zone_page_state(zone, NR_UNACCEPTED));
|
|
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
|
|
index 033871e718a34f..583c27131b7d64 100644
|
|
--- a/net/atm/mpc.c
|
|
+++ b/net/atm/mpc.c
|
|
@@ -1314,6 +1314,8 @@ static void MPOA_cache_impos_rcvd(struct k_message *msg,
|
|
holding_time = msg->content.eg_info.holding_time;
|
|
dprintk("(%s) entry = %p, holding_time = %u\n",
|
|
mpc->dev->name, entry, holding_time);
|
|
+ if (entry == NULL && !holding_time)
|
|
+ return;
|
|
if (entry == NULL && holding_time) {
|
|
entry = mpc->eg_ops->add_entry(msg, mpc);
|
|
mpc->eg_ops->put(entry);
|
|
diff --git a/net/ipv6/netfilter/nf_socket_ipv6.c b/net/ipv6/netfilter/nf_socket_ipv6.c
|
|
index a7690ec6232596..9ea5ef56cb2704 100644
|
|
--- a/net/ipv6/netfilter/nf_socket_ipv6.c
|
|
+++ b/net/ipv6/netfilter/nf_socket_ipv6.c
|
|
@@ -103,6 +103,10 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
|
|
struct sk_buff *data_skb = NULL;
|
|
int doff = 0;
|
|
int thoff = 0, tproto;
|
|
+#if IS_ENABLED(CONFIG_NF_CONNTRACK)
|
|
+ enum ip_conntrack_info ctinfo;
|
|
+ struct nf_conn const *ct;
|
|
+#endif
|
|
|
|
tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
|
|
if (tproto < 0) {
|
|
@@ -136,6 +140,25 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
|
|
return NULL;
|
|
}
|
|
|
|
+#if IS_ENABLED(CONFIG_NF_CONNTRACK)
|
|
+ /* Do the lookup with the original socket address in
|
|
+ * case this is a reply packet of an established
|
|
+ * SNAT-ted connection.
|
|
+ */
|
|
+ ct = nf_ct_get(skb, &ctinfo);
|
|
+ if (ct &&
|
|
+ ((tproto != IPPROTO_ICMPV6 &&
|
|
+ ctinfo == IP_CT_ESTABLISHED_REPLY) ||
|
|
+ (tproto == IPPROTO_ICMPV6 &&
|
|
+ ctinfo == IP_CT_RELATED_REPLY)) &&
|
|
+ (ct->status & IPS_SRC_NAT_DONE)) {
|
|
+ daddr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.in6;
|
|
+ dport = (tproto == IPPROTO_TCP) ?
|
|
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port :
|
|
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
|
|
+ }
|
|
+#endif
|
|
+
|
|
return nf_socket_get_sock_v6(net, data_skb, doff, tproto, saddr, daddr,
|
|
sport, dport, indev);
|
|
}
|
|
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
|
index 1fd6e84b0e3718..b3cd6090f46aad 100644
|
|
--- a/sound/pci/hda/patch_realtek.c
|
|
+++ b/sound/pci/hda/patch_realtek.c
|
|
@@ -10023,6 +10023,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
|
SND_PCI_QUIRK(0x103c, 0x8811, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
|
|
SND_PCI_QUIRK(0x103c, 0x8812, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
|
|
SND_PCI_QUIRK(0x103c, 0x881d, "HP 250 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
|
|
+ SND_PCI_QUIRK(0x103c, 0x881e, "HP Laptop 15s-du3xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
|
|
SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
|
|
SND_PCI_QUIRK(0x103c, 0x8847, "HP EliteBook x360 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
|
|
SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
|
|
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
|
|
index 06965da51dd083..be0b3c8ac7055b 100644
|
|
--- a/sound/usb/mixer_quirks.c
|
|
+++ b/sound/usb/mixer_quirks.c
|
|
@@ -3575,6 +3575,52 @@ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
|
|
}
|
|
}
|
|
|
|
+/*
|
|
+ * Some Plantronics headsets have control names that don't meet ALSA naming
|
|
+ * standards. This function fixes nonstandard source names. By the time
|
|
+ * this function is called the control name should look like one of these:
|
|
+ * "source names Playback Volume"
|
|
+ * "source names Playback Switch"
|
|
+ * "source names Capture Volume"
|
|
+ * "source names Capture Switch"
|
|
+ * If any of the trigger words are found in the name then the name will
|
|
+ * be changed to:
|
|
+ * "Headset Playback Volume"
|
|
+ * "Headset Playback Switch"
|
|
+ * "Headset Capture Volume"
|
|
+ * "Headset Capture Switch"
|
|
+ * depending on the current suffix.
|
|
+ */
|
|
+static void snd_fix_plt_name(struct snd_usb_audio *chip,
|
|
+ struct snd_ctl_elem_id *id)
|
|
+{
|
|
+ /* no variant of "Sidetone" should be added to this list */
|
|
+ static const char * const trigger[] = {
|
|
+ "Earphone", "Microphone", "Receive", "Transmit"
|
|
+ };
|
|
+ static const char * const suffix[] = {
|
|
+ " Playback Volume", " Playback Switch",
|
|
+ " Capture Volume", " Capture Switch"
|
|
+ };
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(trigger); i++)
|
|
+ if (strstr(id->name, trigger[i]))
|
|
+ goto triggered;
|
|
+ usb_audio_dbg(chip, "no change in %s\n", id->name);
|
|
+ return;
|
|
+
|
|
+triggered:
|
|
+ for (i = 0; i < ARRAY_SIZE(suffix); i++)
|
|
+ if (strstr(id->name, suffix[i])) {
|
|
+ usb_audio_dbg(chip, "fixing kctl name %s\n", id->name);
|
|
+ snprintf(id->name, sizeof(id->name), "Headset%s",
|
|
+ suffix[i]);
|
|
+ return;
|
|
+ }
|
|
+ usb_audio_dbg(chip, "something wrong in kctl name %s\n", id->name);
|
|
+}
|
|
+
|
|
void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
|
|
struct usb_mixer_elem_info *cval, int unitid,
|
|
struct snd_kcontrol *kctl)
|
|
@@ -3592,5 +3638,10 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
|
|
cval->min_mute = 1;
|
|
break;
|
|
}
|
|
+
|
|
+ /* ALSA-ify some Plantronics headset control names */
|
|
+ if (USB_ID_VENDOR(mixer->chip->usb_id) == 0x047f &&
|
|
+ (cval->control == UAC_FU_MUTE || cval->control == UAC_FU_VOLUME))
|
|
+ snd_fix_plt_name(mixer->chip, &kctl->id);
|
|
}
|
|
|