mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
1982 lines
62 KiB
Diff
1982 lines
62 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index 8750309fc42ac..a94b5ea499e13 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,7 +1,7 @@
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
VERSION = 5
|
|
PATCHLEVEL = 4
|
|
-SUBLEVEL = 182
|
|
+SUBLEVEL = 183
|
|
EXTRAVERSION =
|
|
NAME = Kleptomaniac Octopus
|
|
|
|
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
|
|
index 6a95b92966406..183a6f2f165ad 100644
|
|
--- a/arch/arm/kernel/kgdb.c
|
|
+++ b/arch/arm/kernel/kgdb.c
|
|
@@ -154,22 +154,38 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
|
|
return 0;
|
|
}
|
|
|
|
-static struct undef_hook kgdb_brkpt_hook = {
|
|
+static struct undef_hook kgdb_brkpt_arm_hook = {
|
|
.instr_mask = 0xffffffff,
|
|
.instr_val = KGDB_BREAKINST,
|
|
- .cpsr_mask = MODE_MASK,
|
|
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
|
|
.cpsr_val = SVC_MODE,
|
|
.fn = kgdb_brk_fn
|
|
};
|
|
|
|
-static struct undef_hook kgdb_compiled_brkpt_hook = {
|
|
+static struct undef_hook kgdb_brkpt_thumb_hook = {
|
|
+ .instr_mask = 0xffff,
|
|
+ .instr_val = KGDB_BREAKINST & 0xffff,
|
|
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
|
|
+ .cpsr_val = PSR_T_BIT | SVC_MODE,
|
|
+ .fn = kgdb_brk_fn
|
|
+};
|
|
+
|
|
+static struct undef_hook kgdb_compiled_brkpt_arm_hook = {
|
|
.instr_mask = 0xffffffff,
|
|
.instr_val = KGDB_COMPILED_BREAK,
|
|
- .cpsr_mask = MODE_MASK,
|
|
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
|
|
.cpsr_val = SVC_MODE,
|
|
.fn = kgdb_compiled_brk_fn
|
|
};
|
|
|
|
+static struct undef_hook kgdb_compiled_brkpt_thumb_hook = {
|
|
+ .instr_mask = 0xffff,
|
|
+ .instr_val = KGDB_COMPILED_BREAK & 0xffff,
|
|
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
|
|
+ .cpsr_val = PSR_T_BIT | SVC_MODE,
|
|
+ .fn = kgdb_compiled_brk_fn
|
|
+};
|
|
+
|
|
static int __kgdb_notify(struct die_args *args, unsigned long cmd)
|
|
{
|
|
struct pt_regs *regs = args->regs;
|
|
@@ -210,8 +226,10 @@ int kgdb_arch_init(void)
|
|
if (ret != 0)
|
|
return ret;
|
|
|
|
- register_undef_hook(&kgdb_brkpt_hook);
|
|
- register_undef_hook(&kgdb_compiled_brkpt_hook);
|
|
+ register_undef_hook(&kgdb_brkpt_arm_hook);
|
|
+ register_undef_hook(&kgdb_brkpt_thumb_hook);
|
|
+ register_undef_hook(&kgdb_compiled_brkpt_arm_hook);
|
|
+ register_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
|
|
|
|
return 0;
|
|
}
|
|
@@ -224,8 +242,10 @@ int kgdb_arch_init(void)
|
|
*/
|
|
void kgdb_arch_exit(void)
|
|
{
|
|
- unregister_undef_hook(&kgdb_brkpt_hook);
|
|
- unregister_undef_hook(&kgdb_compiled_brkpt_hook);
|
|
+ unregister_undef_hook(&kgdb_brkpt_arm_hook);
|
|
+ unregister_undef_hook(&kgdb_brkpt_thumb_hook);
|
|
+ unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook);
|
|
+ unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
|
|
unregister_die_notifier(&kgdb_notifier);
|
|
}
|
|
|
|
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
|
|
index 538d5da741b09..6e7f841f67ff1 100644
|
|
--- a/arch/arm/mm/mmu.c
|
|
+++ b/arch/arm/mm/mmu.c
|
|
@@ -229,12 +229,14 @@ early_param("ecc", early_ecc);
|
|
static int __init early_cachepolicy(char *p)
|
|
{
|
|
pr_warn("cachepolicy kernel parameter not supported without cp15\n");
|
|
+ return 0;
|
|
}
|
|
early_param("cachepolicy", early_cachepolicy);
|
|
|
|
static int __init noalign_setup(char *__unused)
|
|
{
|
|
pr_warn("noalign kernel parameter not supported without cp15\n");
|
|
+ return 1;
|
|
}
|
|
__setup("noalign", noalign_setup);
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
|
|
index dd5624975c9b4..b7e7bb3517c03 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
|
|
@@ -281,7 +281,7 @@
|
|
|
|
sound: sound {
|
|
compatible = "rockchip,rk3399-gru-sound";
|
|
- rockchip,cpu = <&i2s0 &i2s2>;
|
|
+ rockchip,cpu = <&i2s0 &spdif>;
|
|
};
|
|
};
|
|
|
|
@@ -432,10 +432,6 @@ ap_i2c_audio: &i2c8 {
|
|
status = "okay";
|
|
};
|
|
|
|
-&i2s2 {
|
|
- status = "okay";
|
|
-};
|
|
-
|
|
&io_domains {
|
|
status = "okay";
|
|
|
|
@@ -532,6 +528,17 @@ ap_i2c_audio: &i2c8 {
|
|
vqmmc-supply = <&ppvar_sd_card_io>;
|
|
};
|
|
|
|
+&spdif {
|
|
+ status = "okay";
|
|
+
|
|
+ /*
|
|
+ * SPDIF is routed internally to DP; we either don't use these pins, or
|
|
+ * mux them to something else.
|
|
+ */
|
|
+ /delete-property/ pinctrl-0;
|
|
+ /delete-property/ pinctrl-names;
|
|
+};
|
|
+
|
|
&spi1 {
|
|
status = "okay";
|
|
|
|
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
|
|
index 70d1587ddcd46..361b109933725 100644
|
|
--- a/arch/ia64/kernel/acpi.c
|
|
+++ b/arch/ia64/kernel/acpi.c
|
|
@@ -448,7 +448,8 @@ void __init acpi_numa_fixup(void)
|
|
if (srat_num_cpus == 0) {
|
|
node_set_online(0);
|
|
node_cpuid[0].phys_id = hard_smp_processor_id();
|
|
- return;
|
|
+ slit_distance(0, 0) = LOCAL_DISTANCE;
|
|
+ goto out;
|
|
}
|
|
|
|
/*
|
|
@@ -491,7 +492,7 @@ void __init acpi_numa_fixup(void)
|
|
for (j = 0; j < MAX_NUMNODES; j++)
|
|
slit_distance(i, j) = i == j ?
|
|
LOCAL_DISTANCE : REMOTE_DISTANCE;
|
|
- return;
|
|
+ goto out;
|
|
}
|
|
|
|
memset(numa_slit, -1, sizeof(numa_slit));
|
|
@@ -516,6 +517,8 @@ void __init acpi_numa_fixup(void)
|
|
printk("\n");
|
|
}
|
|
#endif
|
|
+out:
|
|
+ node_possible_map = node_online_map;
|
|
}
|
|
#endif /* CONFIG_ACPI_NUMA */
|
|
|
|
diff --git a/block/blk-flush.c b/block/blk-flush.c
|
|
index 5aa6fada22598..f66ff16855310 100644
|
|
--- a/block/blk-flush.c
|
|
+++ b/block/blk-flush.c
|
|
@@ -222,8 +222,10 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error)
|
|
return;
|
|
}
|
|
|
|
- if (fq->rq_status != BLK_STS_OK)
|
|
+ if (fq->rq_status != BLK_STS_OK) {
|
|
error = fq->rq_status;
|
|
+ fq->rq_status = BLK_STS_OK;
|
|
+ }
|
|
|
|
hctx = flush_rq->mq_hctx;
|
|
if (!q->elevator) {
|
|
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
|
|
index 499a947d56ddb..fef46de2f6b23 100644
|
|
--- a/drivers/ata/pata_hpt37x.c
|
|
+++ b/drivers/ata/pata_hpt37x.c
|
|
@@ -962,14 +962,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
|
if ((freq >> 12) != 0xABCDE) {
|
|
int i;
|
|
- u8 sr;
|
|
+ u16 sr;
|
|
u32 total = 0;
|
|
|
|
pr_warn("BIOS has not set timing clocks\n");
|
|
|
|
/* This is the process the HPT371 BIOS is reported to use */
|
|
for (i = 0; i < 128; i++) {
|
|
- pci_read_config_byte(dev, 0x78, &sr);
|
|
+ pci_read_config_word(dev, 0x78, &sr);
|
|
total += sr & 0x1FF;
|
|
udelay(15);
|
|
}
|
|
diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
|
|
index c51de498b5b4b..19eee3d0900b0 100644
|
|
--- a/drivers/dma/sh/shdma-base.c
|
|
+++ b/drivers/dma/sh/shdma-base.c
|
|
@@ -115,8 +115,10 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx)
|
|
ret = pm_runtime_get(schan->dev);
|
|
|
|
spin_unlock_irq(&schan->chan_lock);
|
|
- if (ret < 0)
|
|
+ if (ret < 0) {
|
|
dev_err(schan->dev, "%s(): GET = %d\n", __func__, ret);
|
|
+ pm_runtime_put(schan->dev);
|
|
+ }
|
|
|
|
pm_runtime_barrier(schan->dev);
|
|
|
|
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
|
|
index 4e43bdfa041f5..f0b055bc027c4 100644
|
|
--- a/drivers/firmware/arm_scmi/driver.c
|
|
+++ b/drivers/firmware/arm_scmi/driver.c
|
|
@@ -983,7 +983,7 @@ static struct platform_driver scmi_driver = {
|
|
|
|
module_platform_driver(scmi_driver);
|
|
|
|
-MODULE_ALIAS("platform: arm-scmi");
|
|
+MODULE_ALIAS("platform:arm-scmi");
|
|
MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
|
|
MODULE_DESCRIPTION("ARM SCMI protocol driver");
|
|
MODULE_LICENSE("GPL v2");
|
|
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
|
|
index 436d1776bc7be..a32d15b2928f7 100644
|
|
--- a/drivers/firmware/efi/vars.c
|
|
+++ b/drivers/firmware/efi/vars.c
|
|
@@ -750,6 +750,7 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
|
|
{
|
|
const struct efivar_operations *ops;
|
|
efi_status_t status;
|
|
+ unsigned long varsize;
|
|
|
|
if (!__efivars)
|
|
return -EINVAL;
|
|
@@ -772,15 +773,17 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
|
|
return efivar_entry_set_nonblocking(name, vendor, attributes,
|
|
size, data);
|
|
|
|
+ varsize = size + ucs2_strsize(name, 1024);
|
|
if (!block) {
|
|
if (down_trylock(&efivars_lock))
|
|
return -EBUSY;
|
|
+ status = check_var_size_nonblocking(attributes, varsize);
|
|
} else {
|
|
if (down_interruptible(&efivars_lock))
|
|
return -EINTR;
|
|
+ status = check_var_size(attributes, varsize);
|
|
}
|
|
|
|
- status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
|
|
if (status != EFI_SUCCESS) {
|
|
up(&efivars_lock);
|
|
return -ENOSPC;
|
|
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
|
|
index 01135713e8f9b..419d8dec7e498 100644
|
|
--- a/drivers/hid/hid-debug.c
|
|
+++ b/drivers/hid/hid-debug.c
|
|
@@ -823,7 +823,9 @@ static const char *keys[KEY_MAX + 1] = {
|
|
[KEY_F22] = "F22", [KEY_F23] = "F23",
|
|
[KEY_F24] = "F24", [KEY_PLAYCD] = "PlayCD",
|
|
[KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3",
|
|
- [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend",
|
|
+ [KEY_PROG4] = "Prog4",
|
|
+ [KEY_ALL_APPLICATIONS] = "AllApplications",
|
|
+ [KEY_SUSPEND] = "Suspend",
|
|
[KEY_CLOSE] = "Close", [KEY_PLAY] = "Play",
|
|
[KEY_FASTFORWARD] = "FastForward", [KEY_BASSBOOST] = "BassBoost",
|
|
[KEY_PRINT] = "Print", [KEY_HP] = "HP",
|
|
@@ -930,6 +932,7 @@ static const char *keys[KEY_MAX + 1] = {
|
|
[KEY_SCREENSAVER] = "ScreenSaver",
|
|
[KEY_VOICECOMMAND] = "VoiceCommand",
|
|
[KEY_EMOJI_PICKER] = "EmojiPicker",
|
|
+ [KEY_DICTATE] = "Dictate",
|
|
[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
|
|
[KEY_BRIGHTNESS_MAX] = "BrightnessMax",
|
|
[KEY_BRIGHTNESS_AUTO] = "BrightnessAuto",
|
|
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
|
|
index 749558aa27e78..d1ba6fafe960f 100644
|
|
--- a/drivers/hid/hid-input.c
|
|
+++ b/drivers/hid/hid-input.c
|
|
@@ -956,6 +956,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|
case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
|
|
case 0x0cf: map_key_clear(KEY_VOICECOMMAND); break;
|
|
|
|
+ case 0x0d8: map_key_clear(KEY_DICTATE); break;
|
|
case 0x0d9: map_key_clear(KEY_EMOJI_PICKER); break;
|
|
|
|
case 0x0e0: map_abs_clear(ABS_VOLUME); break;
|
|
@@ -1047,6 +1048,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|
|
|
case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT); break;
|
|
|
|
+ case 0x2a2: map_key_clear(KEY_ALL_APPLICATIONS); break;
|
|
+
|
|
case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV); break;
|
|
case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT); break;
|
|
case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP); break;
|
|
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
|
|
index 2d08a8719506c..854f1b2658b82 100644
|
|
--- a/drivers/i2c/busses/Kconfig
|
|
+++ b/drivers/i2c/busses/Kconfig
|
|
@@ -483,7 +483,7 @@ config I2C_BRCMSTB
|
|
|
|
config I2C_CADENCE
|
|
tristate "Cadence I2C Controller"
|
|
- depends on ARCH_ZYNQ || ARM64 || XTENSA
|
|
+ depends on ARCH_ZYNQ || ARM64 || XTENSA || COMPILE_TEST
|
|
help
|
|
Say yes here to select Cadence I2C Host Controller. This controller is
|
|
e.g. used by Xilinx Zynq.
|
|
@@ -894,7 +894,7 @@ config I2C_QCOM_GENI
|
|
|
|
config I2C_QUP
|
|
tristate "Qualcomm QUP based I2C controller"
|
|
- depends on ARCH_QCOM
|
|
+ depends on ARCH_QCOM || COMPILE_TEST
|
|
help
|
|
If you say yes to this option, support will be included for the
|
|
built-in I2C interface on the Qualcomm SoCs.
|
|
diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
|
|
index 5ab901ad615dd..c265fe4621621 100644
|
|
--- a/drivers/i2c/busses/i2c-bcm2835.c
|
|
+++ b/drivers/i2c/busses/i2c-bcm2835.c
|
|
@@ -23,6 +23,11 @@
|
|
#define BCM2835_I2C_FIFO 0x10
|
|
#define BCM2835_I2C_DIV 0x14
|
|
#define BCM2835_I2C_DEL 0x18
|
|
+/*
|
|
+ * 16-bit field for the number of SCL cycles to wait after rising SCL
|
|
+ * before deciding the slave is not responding. 0 disables the
|
|
+ * timeout detection.
|
|
+ */
|
|
#define BCM2835_I2C_CLKT 0x1c
|
|
|
|
#define BCM2835_I2C_C_READ BIT(0)
|
|
@@ -479,6 +484,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
|
|
adap->dev.of_node = pdev->dev.of_node;
|
|
adap->quirks = of_device_get_match_data(&pdev->dev);
|
|
|
|
+ /*
|
|
+ * Disable the hardware clock stretching timeout. SMBUS
|
|
+ * specifies a limit for how long the device can stretch the
|
|
+ * clock, but core I2C doesn't.
|
|
+ */
|
|
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_CLKT, 0);
|
|
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0);
|
|
|
|
ret = i2c_add_adapter(adap);
|
|
diff --git a/drivers/input/input.c b/drivers/input/input.c
|
|
index e2eb9b9b8363d..f7398b996bacf 100644
|
|
--- a/drivers/input/input.c
|
|
+++ b/drivers/input/input.c
|
|
@@ -2181,6 +2181,12 @@ int input_register_device(struct input_dev *dev)
|
|
/* KEY_RESERVED is not supposed to be transmitted to userspace. */
|
|
__clear_bit(KEY_RESERVED, dev->keybit);
|
|
|
|
+ /* Buttonpads should not map BTN_RIGHT and/or BTN_MIDDLE. */
|
|
+ if (test_bit(INPUT_PROP_BUTTONPAD, dev->propbit)) {
|
|
+ __clear_bit(BTN_RIGHT, dev->keybit);
|
|
+ __clear_bit(BTN_MIDDLE, dev->keybit);
|
|
+ }
|
|
+
|
|
/* Make sure that bitmasks not mentioned in dev->evbit are clean. */
|
|
input_cleanse_bitmasks(dev);
|
|
|
|
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
|
|
index 196e8505dd8d7..aaef8847f8862 100644
|
|
--- a/drivers/input/mouse/elan_i2c_core.c
|
|
+++ b/drivers/input/mouse/elan_i2c_core.c
|
|
@@ -139,55 +139,21 @@ static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count,
|
|
return 0;
|
|
}
|
|
|
|
-static int elan_enable_power(struct elan_tp_data *data)
|
|
+static int elan_set_power(struct elan_tp_data *data, bool on)
|
|
{
|
|
int repeat = ETP_RETRY_COUNT;
|
|
int error;
|
|
|
|
- error = regulator_enable(data->vcc);
|
|
- if (error) {
|
|
- dev_err(&data->client->dev,
|
|
- "failed to enable regulator: %d\n", error);
|
|
- return error;
|
|
- }
|
|
-
|
|
do {
|
|
- error = data->ops->power_control(data->client, true);
|
|
+ error = data->ops->power_control(data->client, on);
|
|
if (error >= 0)
|
|
return 0;
|
|
|
|
msleep(30);
|
|
} while (--repeat > 0);
|
|
|
|
- dev_err(&data->client->dev, "failed to enable power: %d\n", error);
|
|
- return error;
|
|
-}
|
|
-
|
|
-static int elan_disable_power(struct elan_tp_data *data)
|
|
-{
|
|
- int repeat = ETP_RETRY_COUNT;
|
|
- int error;
|
|
-
|
|
- do {
|
|
- error = data->ops->power_control(data->client, false);
|
|
- if (!error) {
|
|
- error = regulator_disable(data->vcc);
|
|
- if (error) {
|
|
- dev_err(&data->client->dev,
|
|
- "failed to disable regulator: %d\n",
|
|
- error);
|
|
- /* Attempt to power the chip back up */
|
|
- data->ops->power_control(data->client, true);
|
|
- break;
|
|
- }
|
|
-
|
|
- return 0;
|
|
- }
|
|
-
|
|
- msleep(30);
|
|
- } while (--repeat > 0);
|
|
-
|
|
- dev_err(&data->client->dev, "failed to disable power: %d\n", error);
|
|
+ dev_err(&data->client->dev, "failed to set power %s: %d\n",
|
|
+ on ? "on" : "off", error);
|
|
return error;
|
|
}
|
|
|
|
@@ -1316,9 +1282,19 @@ static int __maybe_unused elan_suspend(struct device *dev)
|
|
/* Enable wake from IRQ */
|
|
data->irq_wake = (enable_irq_wake(client->irq) == 0);
|
|
} else {
|
|
- ret = elan_disable_power(data);
|
|
+ ret = elan_set_power(data, false);
|
|
+ if (ret)
|
|
+ goto err;
|
|
+
|
|
+ ret = regulator_disable(data->vcc);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "error %d disabling regulator\n", ret);
|
|
+ /* Attempt to power the chip back up */
|
|
+ elan_set_power(data, true);
|
|
+ }
|
|
}
|
|
|
|
+err:
|
|
mutex_unlock(&data->sysfs_mutex);
|
|
return ret;
|
|
}
|
|
@@ -1329,12 +1305,18 @@ static int __maybe_unused elan_resume(struct device *dev)
|
|
struct elan_tp_data *data = i2c_get_clientdata(client);
|
|
int error;
|
|
|
|
- if (device_may_wakeup(dev) && data->irq_wake) {
|
|
+ if (!device_may_wakeup(dev)) {
|
|
+ error = regulator_enable(data->vcc);
|
|
+ if (error) {
|
|
+ dev_err(dev, "error %d enabling regulator\n", error);
|
|
+ goto err;
|
|
+ }
|
|
+ } else if (data->irq_wake) {
|
|
disable_irq_wake(client->irq);
|
|
data->irq_wake = false;
|
|
}
|
|
|
|
- error = elan_enable_power(data);
|
|
+ error = elan_set_power(data, true);
|
|
if (error) {
|
|
dev_err(dev, "power up when resuming failed: %d\n", error);
|
|
goto err;
|
|
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
|
|
index eb7f76753c9c0..9f44e2e458df1 100644
|
|
--- a/drivers/net/arcnet/com20020-pci.c
|
|
+++ b/drivers/net/arcnet/com20020-pci.c
|
|
@@ -136,6 +136,9 @@ static int com20020pci_probe(struct pci_dev *pdev,
|
|
return -ENOMEM;
|
|
|
|
ci = (struct com20020_pci_card_info *)id->driver_data;
|
|
+ if (!ci)
|
|
+ return -EINVAL;
|
|
+
|
|
priv->ci = ci;
|
|
mm = &ci->misc_map;
|
|
|
|
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
|
|
index 8b4c1bb77c334..76747d94c7602 100644
|
|
--- a/drivers/net/can/usb/gs_usb.c
|
|
+++ b/drivers/net/can/usb/gs_usb.c
|
|
@@ -190,8 +190,8 @@ struct gs_can {
|
|
struct gs_usb {
|
|
struct gs_can *canch[GS_MAX_INTF];
|
|
struct usb_anchor rx_submitted;
|
|
- atomic_t active_channels;
|
|
struct usb_device *udev;
|
|
+ u8 active_channels;
|
|
};
|
|
|
|
/* 'allocate' a tx context.
|
|
@@ -588,7 +588,7 @@ static int gs_can_open(struct net_device *netdev)
|
|
if (rc)
|
|
return rc;
|
|
|
|
- if (atomic_add_return(1, &parent->active_channels) == 1) {
|
|
+ if (!parent->active_channels) {
|
|
for (i = 0; i < GS_MAX_RX_URBS; i++) {
|
|
struct urb *urb;
|
|
u8 *buf;
|
|
@@ -689,6 +689,7 @@ static int gs_can_open(struct net_device *netdev)
|
|
|
|
dev->can.state = CAN_STATE_ERROR_ACTIVE;
|
|
|
|
+ parent->active_channels++;
|
|
if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
|
|
netif_start_queue(netdev);
|
|
|
|
@@ -704,7 +705,8 @@ static int gs_can_close(struct net_device *netdev)
|
|
netif_stop_queue(netdev);
|
|
|
|
/* Stop polling */
|
|
- if (atomic_dec_and_test(&parent->active_channels))
|
|
+ parent->active_channels--;
|
|
+ if (!parent->active_channels)
|
|
usb_kill_anchored_urbs(&parent->rx_submitted);
|
|
|
|
/* Stop sending URBs */
|
|
@@ -983,8 +985,6 @@ static int gs_usb_probe(struct usb_interface *intf,
|
|
|
|
init_usb_anchor(&dev->rx_submitted);
|
|
|
|
- atomic_set(&dev->active_channels, 0);
|
|
-
|
|
usb_set_intfdata(intf, dev);
|
|
dev->udev = interface_to_usbdev(intf);
|
|
|
|
diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
|
|
index 0a9f2c5966242..d3e11fe1eabcc 100644
|
|
--- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
|
|
+++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
|
|
@@ -3677,6 +3677,8 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
|
|
MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
|
|
adapter->params.pci.vpd_cap_addr =
|
|
pci_find_capability(adapter->pdev, PCI_CAP_ID_VPD);
|
|
+ if (!adapter->params.pci.vpd_cap_addr)
|
|
+ return -ENODEV;
|
|
ret = get_vpd_params(adapter, &adapter->params.vpd);
|
|
if (ret < 0)
|
|
return ret;
|
|
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
|
|
index 26d49dcdbeb3e..34bf6f4eef4ab 100644
|
|
--- a/drivers/net/ethernet/ibm/ibmvnic.c
|
|
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
|
|
@@ -2248,8 +2248,10 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
|
|
* flush reset queue and process this reset
|
|
*/
|
|
if (adapter->force_reset_recovery && !list_empty(&adapter->rwi_list)) {
|
|
- list_for_each_safe(entry, tmp_entry, &adapter->rwi_list)
|
|
+ list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) {
|
|
list_del(entry);
|
|
+ kfree(list_entry(entry, struct ibmvnic_rwi, list));
|
|
+ }
|
|
}
|
|
rwi->reset_reason = reason;
|
|
list_add_tail(&rwi->list, &adapter->rwi_list);
|
|
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
|
|
index 309e953ed1e44..e8850ba5604c4 100644
|
|
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
|
|
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
|
|
@@ -3323,8 +3323,11 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu)
|
|
iavf_notify_client_l2_params(&adapter->vsi);
|
|
adapter->flags |= IAVF_FLAG_SERVICE_CLIENT_REQUESTED;
|
|
}
|
|
- adapter->flags |= IAVF_FLAG_RESET_NEEDED;
|
|
- queue_work(iavf_wq, &adapter->reset_task);
|
|
+
|
|
+ if (netif_running(netdev)) {
|
|
+ adapter->flags |= IAVF_FLAG_RESET_NEEDED;
|
|
+ queue_work(iavf_wq, &adapter->reset_task);
|
|
+ }
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/net/ethernet/intel/igc/igc_phy.c b/drivers/net/ethernet/intel/igc/igc_phy.c
|
|
index f4b05af0dd2f6..1a4947e6933c3 100644
|
|
--- a/drivers/net/ethernet/intel/igc/igc_phy.c
|
|
+++ b/drivers/net/ethernet/intel/igc/igc_phy.c
|
|
@@ -734,8 +734,6 @@ s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data)
|
|
if (ret_val)
|
|
return ret_val;
|
|
ret_val = igc_write_phy_reg_mdic(hw, offset, data);
|
|
- if (ret_val)
|
|
- return ret_val;
|
|
hw->phy.ops.release(hw);
|
|
} else {
|
|
ret_val = igc_write_xmdio_reg(hw, (u16)offset, dev_addr,
|
|
@@ -767,8 +765,6 @@ s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data)
|
|
if (ret_val)
|
|
return ret_val;
|
|
ret_val = igc_read_phy_reg_mdic(hw, offset, data);
|
|
- if (ret_val)
|
|
- return ret_val;
|
|
hw->phy.ops.release(hw);
|
|
} else {
|
|
ret_val = igc_read_xmdio_reg(hw, (u16)offset, dev_addr,
|
|
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
|
|
index b43be9f141053..921a2ddb497e1 100644
|
|
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
|
|
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
|
|
@@ -583,12 +583,14 @@ static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget)
|
|
u32 cmd_type;
|
|
|
|
while (budget-- > 0) {
|
|
- if (unlikely(!ixgbe_desc_unused(xdp_ring)) ||
|
|
- !netif_carrier_ok(xdp_ring->netdev)) {
|
|
+ if (unlikely(!ixgbe_desc_unused(xdp_ring))) {
|
|
work_done = false;
|
|
break;
|
|
}
|
|
|
|
+ if (!netif_carrier_ok(xdp_ring->netdev))
|
|
+ break;
|
|
+
|
|
if (!xsk_umem_consume_tx(xdp_ring->xsk_umem, &desc))
|
|
break;
|
|
|
|
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
|
|
index 38767d7979147..431146b391d0c 100644
|
|
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
|
|
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
|
|
@@ -2277,18 +2277,18 @@ static int __init sxgbe_cmdline_opt(char *str)
|
|
char *opt;
|
|
|
|
if (!str || !*str)
|
|
- return -EINVAL;
|
|
+ return 1;
|
|
while ((opt = strsep(&str, ",")) != NULL) {
|
|
if (!strncmp(opt, "eee_timer:", 10)) {
|
|
if (kstrtoint(opt + 10, 0, &eee_timer))
|
|
goto err;
|
|
}
|
|
}
|
|
- return 0;
|
|
+ return 1;
|
|
|
|
err:
|
|
pr_err("%s: ERROR broken module parameter conversion\n", __func__);
|
|
- return -EINVAL;
|
|
+ return 1;
|
|
}
|
|
|
|
__setup("sxgbeeth=", sxgbe_cmdline_opt);
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
index 94c652b9a0a8b..9cbc0179d24ec 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
@@ -4890,7 +4890,7 @@ static int __init stmmac_cmdline_opt(char *str)
|
|
char *opt;
|
|
|
|
if (!str || !*str)
|
|
- return -EINVAL;
|
|
+ return 1;
|
|
while ((opt = strsep(&str, ",")) != NULL) {
|
|
if (!strncmp(opt, "debug:", 6)) {
|
|
if (kstrtoint(opt + 6, 0, &debug))
|
|
@@ -4921,11 +4921,11 @@ static int __init stmmac_cmdline_opt(char *str)
|
|
goto err;
|
|
}
|
|
}
|
|
- return 0;
|
|
+ return 1;
|
|
|
|
err:
|
|
pr_err("%s: ERROR broken module parameter conversion", __func__);
|
|
- return -EINVAL;
|
|
+ return 1;
|
|
}
|
|
|
|
__setup("stmmaceth=", stmmac_cmdline_opt);
|
|
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
|
|
index d2eb33f53993b..43aab2835f8ff 100644
|
|
--- a/drivers/net/hamradio/mkiss.c
|
|
+++ b/drivers/net/hamradio/mkiss.c
|
|
@@ -31,6 +31,8 @@
|
|
|
|
#define AX_MTU 236
|
|
|
|
+/* some arch define END as assembly function ending, just undef it */
|
|
+#undef END
|
|
/* SLIP/KISS protocol characters. */
|
|
#define END 0300 /* indicates end of frame */
|
|
#define ESC 0333 /* indicates byte stuffing */
|
|
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
|
|
index 77ac5a721e7b6..414341c9cf5ae 100644
|
|
--- a/drivers/net/usb/cdc_mbim.c
|
|
+++ b/drivers/net/usb/cdc_mbim.c
|
|
@@ -658,6 +658,11 @@ static const struct usb_device_id mbim_devs[] = {
|
|
.driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
|
|
},
|
|
|
|
+ /* Telit FN990 */
|
|
+ { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1071, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
|
|
+ .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
|
|
+ },
|
|
+
|
|
/* default entry */
|
|
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
|
|
.driver_info = (unsigned long)&cdc_mbim_info_zlp,
|
|
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
|
|
index 07b070b14d75d..6e1721d533846 100644
|
|
--- a/drivers/net/wireless/mac80211_hwsim.c
|
|
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
|
@@ -2062,6 +2062,15 @@ static void hw_scan_work(struct work_struct *work)
|
|
if (req->ie_len)
|
|
skb_put_data(probe, req->ie, req->ie_len);
|
|
|
|
+ if (!ieee80211_tx_prepare_skb(hwsim->hw,
|
|
+ hwsim->hw_scan_vif,
|
|
+ probe,
|
|
+ hwsim->tmp_chan->band,
|
|
+ NULL)) {
|
|
+ kfree_skb(probe);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
local_bh_disable();
|
|
mac80211_hwsim_tx_frame(hwsim->hw, probe,
|
|
hwsim->tmp_chan);
|
|
@@ -3316,6 +3325,10 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
|
|
}
|
|
txi->flags |= IEEE80211_TX_STAT_ACK;
|
|
}
|
|
+
|
|
+ if (hwsim_flags & HWSIM_TX_CTL_NO_ACK)
|
|
+ txi->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
|
+
|
|
ieee80211_tx_status_irqsafe(data2->hw, skb);
|
|
return 0;
|
|
out:
|
|
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
|
|
index d2b3381f71825..d45d83968e769 100644
|
|
--- a/drivers/net/xen-netfront.c
|
|
+++ b/drivers/net/xen-netfront.c
|
|
@@ -761,6 +761,28 @@ static int xennet_close(struct net_device *dev)
|
|
return 0;
|
|
}
|
|
|
|
+static void xennet_destroy_queues(struct netfront_info *info)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < info->netdev->real_num_tx_queues; i++) {
|
|
+ struct netfront_queue *queue = &info->queues[i];
|
|
+
|
|
+ if (netif_running(info->netdev))
|
|
+ napi_disable(&queue->napi);
|
|
+ netif_napi_del(&queue->napi);
|
|
+ }
|
|
+
|
|
+ kfree(info->queues);
|
|
+ info->queues = NULL;
|
|
+}
|
|
+
|
|
+static void xennet_uninit(struct net_device *dev)
|
|
+{
|
|
+ struct netfront_info *np = netdev_priv(dev);
|
|
+ xennet_destroy_queues(np);
|
|
+}
|
|
+
|
|
static void xennet_set_rx_rsp_cons(struct netfront_queue *queue, RING_IDX val)
|
|
{
|
|
unsigned long flags;
|
|
@@ -1373,6 +1395,7 @@ static void xennet_poll_controller(struct net_device *dev)
|
|
#endif
|
|
|
|
static const struct net_device_ops xennet_netdev_ops = {
|
|
+ .ndo_uninit = xennet_uninit,
|
|
.ndo_open = xennet_open,
|
|
.ndo_stop = xennet_close,
|
|
.ndo_start_xmit = xennet_start_xmit,
|
|
@@ -1860,22 +1883,6 @@ error:
|
|
return err;
|
|
}
|
|
|
|
-static void xennet_destroy_queues(struct netfront_info *info)
|
|
-{
|
|
- unsigned int i;
|
|
-
|
|
- for (i = 0; i < info->netdev->real_num_tx_queues; i++) {
|
|
- struct netfront_queue *queue = &info->queues[i];
|
|
-
|
|
- if (netif_running(info->netdev))
|
|
- napi_disable(&queue->napi);
|
|
- netif_napi_del(&queue->napi);
|
|
- }
|
|
-
|
|
- kfree(info->queues);
|
|
- info->queues = NULL;
|
|
-}
|
|
-
|
|
static int xennet_create_queues(struct netfront_info *info,
|
|
unsigned int *num_queues)
|
|
{
|
|
diff --git a/drivers/soc/fsl/qe/qe_io.c b/drivers/soc/fsl/qe/qe_io.c
|
|
index 3657e296a8a27..058c2fec9a4b4 100644
|
|
--- a/drivers/soc/fsl/qe/qe_io.c
|
|
+++ b/drivers/soc/fsl/qe/qe_io.c
|
|
@@ -37,6 +37,8 @@ int par_io_init(struct device_node *np)
|
|
if (ret)
|
|
return ret;
|
|
par_io = ioremap(res.start, resource_size(&res));
|
|
+ if (!par_io)
|
|
+ return -ENOMEM;
|
|
|
|
num_ports = of_get_property(np, "num-ports", NULL);
|
|
if (num_ports)
|
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
|
index 5f1e15172403e..9cd80ad075bd2 100644
|
|
--- a/drivers/usb/gadget/legacy/inode.c
|
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
|
@@ -1829,8 +1829,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
|
spin_lock_irq (&dev->lock);
|
|
value = -EINVAL;
|
|
if (dev->buf) {
|
|
+ spin_unlock_irq(&dev->lock);
|
|
kfree(kbuf);
|
|
- goto fail;
|
|
+ return value;
|
|
}
|
|
dev->buf = kbuf;
|
|
|
|
@@ -1877,8 +1878,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
|
|
|
value = usb_gadget_probe_driver(&gadgetfs_driver);
|
|
if (value != 0) {
|
|
- kfree (dev->buf);
|
|
- dev->buf = NULL;
|
|
+ spin_lock_irq(&dev->lock);
|
|
+ goto fail;
|
|
} else {
|
|
/* at this point "good" hardware has for the first time
|
|
* let the USB the host see us. alternatively, if users
|
|
@@ -1895,6 +1896,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
|
return value;
|
|
|
|
fail:
|
|
+ dev->config = NULL;
|
|
+ dev->hs_config = NULL;
|
|
+ dev->dev = NULL;
|
|
spin_unlock_irq (&dev->lock);
|
|
pr_debug ("%s: %s fail %zd, %p\n", shortname, __func__, value, dev);
|
|
kfree (dev->buf);
|
|
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
|
|
index a5041bf0d5db1..5a3006c75d63f 100644
|
|
--- a/fs/btrfs/qgroup.c
|
|
+++ b/fs/btrfs/qgroup.c
|
|
@@ -1116,6 +1116,14 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
|
|
if (!fs_info->quota_root)
|
|
goto out;
|
|
|
|
+ /*
|
|
+ * Unlock the qgroup_ioctl_lock mutex before waiting for the rescan worker to
|
|
+ * complete. Otherwise we can deadlock because btrfs_remove_qgroup() needs
|
|
+ * to lock that mutex while holding a transaction handle and the rescan
|
|
+ * worker needs to commit a transaction.
|
|
+ */
|
|
+ mutex_unlock(&fs_info->qgroup_ioctl_lock);
|
|
+
|
|
/*
|
|
* Request qgroup rescan worker to complete and wait for it. This wait
|
|
* must be done before transaction start for quota disable since it may
|
|
@@ -1123,7 +1131,6 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
|
|
*/
|
|
clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
|
|
btrfs_qgroup_wait_for_completion(fs_info, false);
|
|
- mutex_unlock(&fs_info->qgroup_ioctl_lock);
|
|
|
|
/*
|
|
* 1 For the root item
|
|
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
|
|
index 7bc4477d7ee7d..9b703c0db9796 100644
|
|
--- a/fs/btrfs/tree-log.c
|
|
+++ b/fs/btrfs/tree-log.c
|
|
@@ -1308,6 +1308,15 @@ again:
|
|
inode, name, namelen);
|
|
kfree(name);
|
|
iput(dir);
|
|
+ /*
|
|
+ * Whenever we need to check if a name exists or not, we
|
|
+ * check the subvolume tree. So after an unlink we must
|
|
+ * run delayed items, so that future checks for a name
|
|
+ * during log replay see that the name does not exists
|
|
+ * anymore.
|
|
+ */
|
|
+ if (!ret)
|
|
+ ret = btrfs_run_delayed_items(trans);
|
|
if (ret)
|
|
goto out;
|
|
goto again;
|
|
@@ -1559,6 +1568,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
|
|
*/
|
|
if (!ret && inode->i_nlink == 0)
|
|
inc_nlink(inode);
|
|
+ /*
|
|
+ * Whenever we need to check if a name exists or
|
|
+ * not, we check the subvolume tree. So after an
|
|
+ * unlink we must run delayed items, so that future
|
|
+ * checks for a name during log replay see that the
|
|
+ * name does not exists anymore.
|
|
+ */
|
|
+ if (!ret)
|
|
+ ret = btrfs_run_delayed_items(trans);
|
|
}
|
|
if (ret < 0)
|
|
goto out;
|
|
@@ -4249,7 +4267,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
|
|
|
|
/*
|
|
* Log all prealloc extents beyond the inode's i_size to make sure we do not
|
|
- * lose them after doing a fast fsync and replaying the log. We scan the
|
|
+ * lose them after doing a full/fast fsync and replaying the log. We scan the
|
|
* subvolume's root instead of iterating the inode's extent map tree because
|
|
* otherwise we can log incorrect extent items based on extent map conversion.
|
|
* That can happen due to the fact that extent maps are merged when they
|
|
@@ -5042,6 +5060,7 @@ static int copy_inode_items_to_log(struct btrfs_trans_handle *trans,
|
|
struct btrfs_log_ctx *ctx,
|
|
bool *need_log_inode_item)
|
|
{
|
|
+ const u64 i_size = i_size_read(&inode->vfs_inode);
|
|
struct btrfs_root *root = inode->root;
|
|
int ins_start_slot = 0;
|
|
int ins_nr = 0;
|
|
@@ -5062,13 +5081,21 @@ again:
|
|
if (min_key->type > max_key->type)
|
|
break;
|
|
|
|
- if (min_key->type == BTRFS_INODE_ITEM_KEY)
|
|
+ if (min_key->type == BTRFS_INODE_ITEM_KEY) {
|
|
*need_log_inode_item = false;
|
|
-
|
|
- if ((min_key->type == BTRFS_INODE_REF_KEY ||
|
|
- min_key->type == BTRFS_INODE_EXTREF_KEY) &&
|
|
- inode->generation == trans->transid &&
|
|
- !recursive_logging) {
|
|
+ } else if (min_key->type == BTRFS_EXTENT_DATA_KEY &&
|
|
+ min_key->offset >= i_size) {
|
|
+ /*
|
|
+ * Extents at and beyond eof are logged with
|
|
+ * btrfs_log_prealloc_extents().
|
|
+ * Only regular files have BTRFS_EXTENT_DATA_KEY keys,
|
|
+ * and no keys greater than that, so bail out.
|
|
+ */
|
|
+ break;
|
|
+ } else if ((min_key->type == BTRFS_INODE_REF_KEY ||
|
|
+ min_key->type == BTRFS_INODE_EXTREF_KEY) &&
|
|
+ inode->generation == trans->transid &&
|
|
+ !recursive_logging) {
|
|
u64 other_ino = 0;
|
|
u64 other_parent = 0;
|
|
|
|
@@ -5099,10 +5126,8 @@ again:
|
|
btrfs_release_path(path);
|
|
goto next_key;
|
|
}
|
|
- }
|
|
-
|
|
- /* Skip xattrs, we log them later with btrfs_log_all_xattrs() */
|
|
- if (min_key->type == BTRFS_XATTR_ITEM_KEY) {
|
|
+ } else if (min_key->type == BTRFS_XATTR_ITEM_KEY) {
|
|
+ /* Skip xattrs, logged later with btrfs_log_all_xattrs() */
|
|
if (ins_nr == 0)
|
|
goto next_slot;
|
|
ret = copy_items(trans, inode, dst_path, path,
|
|
@@ -5155,9 +5180,21 @@ next_key:
|
|
break;
|
|
}
|
|
}
|
|
- if (ins_nr)
|
|
+ if (ins_nr) {
|
|
ret = copy_items(trans, inode, dst_path, path, ins_start_slot,
|
|
ins_nr, inode_only, logged_isize);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ if (inode_only == LOG_INODE_ALL && S_ISREG(inode->vfs_inode.i_mode)) {
|
|
+ /*
|
|
+ * Release the path because otherwise we might attempt to double
|
|
+ * lock the same leaf with btrfs_log_prealloc_extents() below.
|
|
+ */
|
|
+ btrfs_release_path(path);
|
|
+ ret = btrfs_log_prealloc_extents(trans, inode, dst_path);
|
|
+ }
|
|
|
|
return ret;
|
|
}
|
|
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
|
|
index 41b3c5fc958c7..f44b6f9d07776 100644
|
|
--- a/fs/cifs/cifsfs.c
|
|
+++ b/fs/cifs/cifsfs.c
|
|
@@ -855,6 +855,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
|
|
|
|
out_super:
|
|
deactivate_locked_super(sb);
|
|
+ return root;
|
|
out:
|
|
cifs_cleanup_volume_info(volume_info);
|
|
return root;
|
|
diff --git a/include/linux/topology.h b/include/linux/topology.h
|
|
index eb2fe6edd73c8..64e7ee0abe71c 100644
|
|
--- a/include/linux/topology.h
|
|
+++ b/include/linux/topology.h
|
|
@@ -48,6 +48,7 @@ int arch_update_cpu_topology(void);
|
|
/* Conform to ACPI 2.0 SLIT distance definitions */
|
|
#define LOCAL_DISTANCE 10
|
|
#define REMOTE_DISTANCE 20
|
|
+#define DISTANCE_BITS 8
|
|
#ifndef node_distance
|
|
#define node_distance(from,to) ((from) == (to) ? LOCAL_DISTANCE : REMOTE_DISTANCE)
|
|
#endif
|
|
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
|
|
index 47088083667b2..c204af20c27e4 100644
|
|
--- a/include/net/netfilter/nf_queue.h
|
|
+++ b/include/net/netfilter/nf_queue.h
|
|
@@ -34,7 +34,7 @@ void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *q
|
|
void nf_unregister_queue_handler(struct net *net);
|
|
void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
|
|
|
|
-void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
|
|
+bool nf_queue_entry_get_refs(struct nf_queue_entry *entry);
|
|
void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
|
|
|
|
static inline void init_hashrandom(u32 *jhash_initval)
|
|
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
|
|
index 8ce63850d6d01..614f19bbad74f 100644
|
|
--- a/include/net/xfrm.h
|
|
+++ b/include/net/xfrm.h
|
|
@@ -1543,7 +1543,6 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
|
|
void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
|
|
u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
|
|
int xfrm_init_replay(struct xfrm_state *x);
|
|
-u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu);
|
|
u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
|
|
int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
|
|
int xfrm_init_state(struct xfrm_state *x);
|
|
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
|
|
index 311a57f3e01a2..7f0ae1f411e3a 100644
|
|
--- a/include/uapi/linux/input-event-codes.h
|
|
+++ b/include/uapi/linux/input-event-codes.h
|
|
@@ -278,7 +278,8 @@
|
|
#define KEY_PAUSECD 201
|
|
#define KEY_PROG3 202
|
|
#define KEY_PROG4 203
|
|
-#define KEY_DASHBOARD 204 /* AL Dashboard */
|
|
+#define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
|
|
+#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
|
|
#define KEY_SUSPEND 205
|
|
#define KEY_CLOSE 206 /* AC Close */
|
|
#define KEY_PLAY 207
|
|
@@ -608,6 +609,7 @@
|
|
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
|
|
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
|
|
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
|
|
+#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
|
|
|
|
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
|
|
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
|
|
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
|
|
index ff7cfdc6cb44d..90a8f968af2f9 100644
|
|
--- a/include/uapi/linux/xfrm.h
|
|
+++ b/include/uapi/linux/xfrm.h
|
|
@@ -504,6 +504,12 @@ struct xfrm_user_offload {
|
|
int ifindex;
|
|
__u8 flags;
|
|
};
|
|
+/* This flag was exposed without any kernel code that supporting it.
|
|
+ * Unfortunately, strongswan has the code that uses sets this flag,
|
|
+ * which makes impossible to reuse this bit.
|
|
+ *
|
|
+ * So leave it here to make sure that it won't be reused by mistake.
|
|
+ */
|
|
#define XFRM_OFFLOAD_IPV6 1
|
|
#define XFRM_OFFLOAD_INBOUND 2
|
|
|
|
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
|
|
index ffaa97a8d4051..e5ebaffc4fef5 100644
|
|
--- a/kernel/sched/topology.c
|
|
+++ b/kernel/sched/topology.c
|
|
@@ -1552,66 +1552,58 @@ static void init_numa_topology_type(void)
|
|
}
|
|
}
|
|
|
|
+
|
|
+#define NR_DISTANCE_VALUES (1 << DISTANCE_BITS)
|
|
+
|
|
void sched_init_numa(void)
|
|
{
|
|
- int next_distance, curr_distance = node_distance(0, 0);
|
|
struct sched_domain_topology_level *tl;
|
|
- int level = 0;
|
|
- int i, j, k;
|
|
-
|
|
- sched_domains_numa_distance = kzalloc(sizeof(int) * (nr_node_ids + 1), GFP_KERNEL);
|
|
- if (!sched_domains_numa_distance)
|
|
- return;
|
|
-
|
|
- /* Includes NUMA identity node at level 0. */
|
|
- sched_domains_numa_distance[level++] = curr_distance;
|
|
- sched_domains_numa_levels = level;
|
|
+ unsigned long *distance_map;
|
|
+ int nr_levels = 0;
|
|
+ int i, j;
|
|
|
|
/*
|
|
* O(nr_nodes^2) deduplicating selection sort -- in order to find the
|
|
* unique distances in the node_distance() table.
|
|
- *
|
|
- * Assumes node_distance(0,j) includes all distances in
|
|
- * node_distance(i,j) in order to avoid cubic time.
|
|
*/
|
|
- next_distance = curr_distance;
|
|
+ distance_map = bitmap_alloc(NR_DISTANCE_VALUES, GFP_KERNEL);
|
|
+ if (!distance_map)
|
|
+ return;
|
|
+
|
|
+ bitmap_zero(distance_map, NR_DISTANCE_VALUES);
|
|
for (i = 0; i < nr_node_ids; i++) {
|
|
for (j = 0; j < nr_node_ids; j++) {
|
|
- for (k = 0; k < nr_node_ids; k++) {
|
|
- int distance = node_distance(i, k);
|
|
-
|
|
- if (distance > curr_distance &&
|
|
- (distance < next_distance ||
|
|
- next_distance == curr_distance))
|
|
- next_distance = distance;
|
|
-
|
|
- /*
|
|
- * While not a strong assumption it would be nice to know
|
|
- * about cases where if node A is connected to B, B is not
|
|
- * equally connected to A.
|
|
- */
|
|
- if (sched_debug() && node_distance(k, i) != distance)
|
|
- sched_numa_warn("Node-distance not symmetric");
|
|
+ int distance = node_distance(i, j);
|
|
|
|
- if (sched_debug() && i && !find_numa_distance(distance))
|
|
- sched_numa_warn("Node-0 not representative");
|
|
+ if (distance < LOCAL_DISTANCE || distance >= NR_DISTANCE_VALUES) {
|
|
+ sched_numa_warn("Invalid distance value range");
|
|
+ return;
|
|
}
|
|
- if (next_distance != curr_distance) {
|
|
- sched_domains_numa_distance[level++] = next_distance;
|
|
- sched_domains_numa_levels = level;
|
|
- curr_distance = next_distance;
|
|
- } else break;
|
|
+
|
|
+ bitmap_set(distance_map, distance, 1);
|
|
}
|
|
+ }
|
|
+ /*
|
|
+ * We can now figure out how many unique distance values there are and
|
|
+ * allocate memory accordingly.
|
|
+ */
|
|
+ nr_levels = bitmap_weight(distance_map, NR_DISTANCE_VALUES);
|
|
|
|
- /*
|
|
- * In case of sched_debug() we verify the above assumption.
|
|
- */
|
|
- if (!sched_debug())
|
|
- break;
|
|
+ sched_domains_numa_distance = kcalloc(nr_levels, sizeof(int), GFP_KERNEL);
|
|
+ if (!sched_domains_numa_distance) {
|
|
+ bitmap_free(distance_map);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ for (i = 0, j = 0; i < nr_levels; i++, j++) {
|
|
+ j = find_next_bit(distance_map, NR_DISTANCE_VALUES, j);
|
|
+ sched_domains_numa_distance[i] = j;
|
|
}
|
|
|
|
+ bitmap_free(distance_map);
|
|
+
|
|
/*
|
|
- * 'level' contains the number of unique distances
|
|
+ * 'nr_levels' contains the number of unique distances
|
|
*
|
|
* The sched_domains_numa_distance[] array includes the actual distance
|
|
* numbers.
|
|
@@ -1620,15 +1612,15 @@ void sched_init_numa(void)
|
|
/*
|
|
* Here, we should temporarily reset sched_domains_numa_levels to 0.
|
|
* If it fails to allocate memory for array sched_domains_numa_masks[][],
|
|
- * the array will contain less then 'level' members. This could be
|
|
+ * the array will contain less then 'nr_levels' members. This could be
|
|
* dangerous when we use it to iterate array sched_domains_numa_masks[][]
|
|
* in other functions.
|
|
*
|
|
- * We reset it to 'level' at the end of this function.
|
|
+ * We reset it to 'nr_levels' at the end of this function.
|
|
*/
|
|
sched_domains_numa_levels = 0;
|
|
|
|
- sched_domains_numa_masks = kzalloc(sizeof(void *) * level, GFP_KERNEL);
|
|
+ sched_domains_numa_masks = kzalloc(sizeof(void *) * nr_levels, GFP_KERNEL);
|
|
if (!sched_domains_numa_masks)
|
|
return;
|
|
|
|
@@ -1636,7 +1628,7 @@ void sched_init_numa(void)
|
|
* Now for each level, construct a mask per node which contains all
|
|
* CPUs of nodes that are that many hops away from us.
|
|
*/
|
|
- for (i = 0; i < level; i++) {
|
|
+ for (i = 0; i < nr_levels; i++) {
|
|
sched_domains_numa_masks[i] =
|
|
kzalloc(nr_node_ids * sizeof(void *), GFP_KERNEL);
|
|
if (!sched_domains_numa_masks[i])
|
|
@@ -1644,12 +1636,17 @@ void sched_init_numa(void)
|
|
|
|
for (j = 0; j < nr_node_ids; j++) {
|
|
struct cpumask *mask = kzalloc(cpumask_size(), GFP_KERNEL);
|
|
+ int k;
|
|
+
|
|
if (!mask)
|
|
return;
|
|
|
|
sched_domains_numa_masks[i][j] = mask;
|
|
|
|
for_each_node(k) {
|
|
+ if (sched_debug() && (node_distance(j, k) != node_distance(k, j)))
|
|
+ sched_numa_warn("Node-distance not symmetric");
|
|
+
|
|
if (node_distance(j, k) > sched_domains_numa_distance[i])
|
|
continue;
|
|
|
|
@@ -1661,7 +1658,7 @@ void sched_init_numa(void)
|
|
/* Compute default topology size */
|
|
for (i = 0; sched_domain_topology[i].mask; i++);
|
|
|
|
- tl = kzalloc((i + level + 1) *
|
|
+ tl = kzalloc((i + nr_levels + 1) *
|
|
sizeof(struct sched_domain_topology_level), GFP_KERNEL);
|
|
if (!tl)
|
|
return;
|
|
@@ -1684,7 +1681,7 @@ void sched_init_numa(void)
|
|
/*
|
|
* .. and append 'j' levels of NUMA goodness.
|
|
*/
|
|
- for (j = 1; j < level; i++, j++) {
|
|
+ for (j = 1; j < nr_levels; i++, j++) {
|
|
tl[i] = (struct sched_domain_topology_level){
|
|
.mask = sd_numa_mask,
|
|
.sd_flags = cpu_numa_flags,
|
|
@@ -1696,8 +1693,8 @@ void sched_init_numa(void)
|
|
|
|
sched_domain_topology = tl;
|
|
|
|
- sched_domains_numa_levels = level;
|
|
- sched_max_numa_distance = sched_domains_numa_distance[level - 1];
|
|
+ sched_domains_numa_levels = nr_levels;
|
|
+ sched_max_numa_distance = sched_domains_numa_distance[nr_levels - 1];
|
|
|
|
init_numa_topology_type();
|
|
}
|
|
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
|
|
index 615259d8fa9ad..1a89b2bf626a5 100644
|
|
--- a/kernel/trace/trace.c
|
|
+++ b/kernel/trace/trace.c
|
|
@@ -219,7 +219,7 @@ static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata;
|
|
static int __init set_trace_boot_options(char *str)
|
|
{
|
|
strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE);
|
|
- return 0;
|
|
+ return 1;
|
|
}
|
|
__setup("trace_options=", set_trace_boot_options);
|
|
|
|
@@ -230,7 +230,7 @@ static int __init set_trace_boot_clock(char *str)
|
|
{
|
|
strlcpy(trace_boot_clock_buf, str, MAX_TRACER_SIZE);
|
|
trace_boot_clock = trace_boot_clock_buf;
|
|
- return 0;
|
|
+ return 1;
|
|
}
|
|
__setup("trace_clock=", set_trace_boot_clock);
|
|
|
|
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
|
|
index 3cef24c6391a5..413da11260f89 100644
|
|
--- a/kernel/trace/trace_events_hist.c
|
|
+++ b/kernel/trace/trace_events_hist.c
|
|
@@ -2891,9 +2891,9 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
|
|
/*
|
|
* For backward compatibility, if field_name
|
|
* was "cpu", then we treat this the same as
|
|
- * common_cpu.
|
|
+ * common_cpu. This also works for "CPU".
|
|
*/
|
|
- if (strcmp(field_name, "cpu") == 0) {
|
|
+ if (field && field->filter_type == FILTER_CPU) {
|
|
*flags |= HIST_FIELD_FL_CPU;
|
|
} else {
|
|
hist_err(tr, HIST_ERR_FIELD_NOT_FOUND,
|
|
@@ -5247,7 +5247,7 @@ static int create_tracing_map_fields(struct hist_trigger_data *hist_data)
|
|
|
|
if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
|
|
cmp_fn = tracing_map_cmp_none;
|
|
- else if (!field)
|
|
+ else if (!field || hist_field->flags & HIST_FIELD_FL_CPU)
|
|
cmp_fn = tracing_map_cmp_num(hist_field->size,
|
|
hist_field->is_signed);
|
|
else if (is_string_field(field))
|
|
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
|
|
index 13ccf2f28987e..a422cf6a0358b 100644
|
|
--- a/kernel/trace/trace_kprobe.c
|
|
+++ b/kernel/trace/trace_kprobe.c
|
|
@@ -430,7 +430,7 @@ static int disable_trace_kprobe(struct trace_event_call *call,
|
|
*/
|
|
trace_probe_remove_file(tp, file);
|
|
|
|
- return 0;
|
|
+ return 1;
|
|
}
|
|
|
|
#if defined(CONFIG_DYNAMIC_FTRACE) && \
|
|
diff --git a/mm/memfd.c b/mm/memfd.c
|
|
index 2647c898990c8..fae4142f7d254 100644
|
|
--- a/mm/memfd.c
|
|
+++ b/mm/memfd.c
|
|
@@ -31,20 +31,28 @@
|
|
static void memfd_tag_pins(struct xa_state *xas)
|
|
{
|
|
struct page *page;
|
|
- unsigned int tagged = 0;
|
|
+ int latency = 0;
|
|
+ int cache_count;
|
|
|
|
lru_add_drain();
|
|
|
|
xas_lock_irq(xas);
|
|
xas_for_each(xas, page, ULONG_MAX) {
|
|
- if (xa_is_value(page))
|
|
- continue;
|
|
- page = find_subpage(page, xas->xa_index);
|
|
- if (page_count(page) - page_mapcount(page) > 1)
|
|
+ cache_count = 1;
|
|
+ if (!xa_is_value(page) &&
|
|
+ PageTransHuge(page) && !PageHuge(page))
|
|
+ cache_count = HPAGE_PMD_NR;
|
|
+
|
|
+ if (!xa_is_value(page) &&
|
|
+ page_count(page) - total_mapcount(page) != cache_count)
|
|
xas_set_mark(xas, MEMFD_TAG_PINNED);
|
|
+ if (cache_count != 1)
|
|
+ xas_set(xas, page->index + cache_count);
|
|
|
|
- if (++tagged % XA_CHECK_SCHED)
|
|
+ latency += cache_count;
|
|
+ if (latency < XA_CHECK_SCHED)
|
|
continue;
|
|
+ latency = 0;
|
|
|
|
xas_pause(xas);
|
|
xas_unlock_irq(xas);
|
|
@@ -73,7 +81,8 @@ static int memfd_wait_for_pins(struct address_space *mapping)
|
|
|
|
error = 0;
|
|
for (scan = 0; scan <= LAST_SCAN; scan++) {
|
|
- unsigned int tagged = 0;
|
|
+ int latency = 0;
|
|
+ int cache_count;
|
|
|
|
if (!xas_marked(&xas, MEMFD_TAG_PINNED))
|
|
break;
|
|
@@ -87,10 +96,14 @@ static int memfd_wait_for_pins(struct address_space *mapping)
|
|
xas_lock_irq(&xas);
|
|
xas_for_each_marked(&xas, page, ULONG_MAX, MEMFD_TAG_PINNED) {
|
|
bool clear = true;
|
|
- if (xa_is_value(page))
|
|
- continue;
|
|
- page = find_subpage(page, xas.xa_index);
|
|
- if (page_count(page) - page_mapcount(page) != 1) {
|
|
+
|
|
+ cache_count = 1;
|
|
+ if (!xa_is_value(page) &&
|
|
+ PageTransHuge(page) && !PageHuge(page))
|
|
+ cache_count = HPAGE_PMD_NR;
|
|
+
|
|
+ if (!xa_is_value(page) && cache_count !=
|
|
+ page_count(page) - total_mapcount(page)) {
|
|
/*
|
|
* On the last scan, we clean up all those tags
|
|
* we inserted; but make a note that we still
|
|
@@ -103,8 +116,11 @@ static int memfd_wait_for_pins(struct address_space *mapping)
|
|
}
|
|
if (clear)
|
|
xas_clear_mark(&xas, MEMFD_TAG_PINNED);
|
|
- if (++tagged % XA_CHECK_SCHED)
|
|
+
|
|
+ latency += cache_count;
|
|
+ if (latency < XA_CHECK_SCHED)
|
|
continue;
|
|
+ latency = 0;
|
|
|
|
xas_pause(&xas);
|
|
xas_unlock_irq(&xas);
|
|
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
|
|
index 18e644f3cb309..5f44c94ad707b 100644
|
|
--- a/net/batman-adv/hard-interface.c
|
|
+++ b/net/batman-adv/hard-interface.c
|
|
@@ -151,22 +151,25 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
|
|
struct net *net = dev_net(net_dev);
|
|
struct net_device *parent_dev;
|
|
struct net *parent_net;
|
|
+ int iflink;
|
|
bool ret;
|
|
|
|
/* check if this is a batman-adv mesh interface */
|
|
if (batadv_softif_is_valid(net_dev))
|
|
return true;
|
|
|
|
- /* no more parents..stop recursion */
|
|
- if (dev_get_iflink(net_dev) == 0 ||
|
|
- dev_get_iflink(net_dev) == net_dev->ifindex)
|
|
+ iflink = dev_get_iflink(net_dev);
|
|
+ if (iflink == 0)
|
|
return false;
|
|
|
|
parent_net = batadv_getlink_net(net_dev, net);
|
|
|
|
+ /* iflink to itself, most likely physical device */
|
|
+ if (net == parent_net && iflink == net_dev->ifindex)
|
|
+ return false;
|
|
+
|
|
/* recurse over the parent device */
|
|
- parent_dev = __dev_get_by_index((struct net *)parent_net,
|
|
- dev_get_iflink(net_dev));
|
|
+ parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
|
|
/* if we got a NULL parent_dev there is something broken.. */
|
|
if (!parent_dev) {
|
|
pr_err("Cannot find parent device\n");
|
|
@@ -216,14 +219,15 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
|
|
struct net_device *real_netdev = NULL;
|
|
struct net *real_net;
|
|
struct net *net;
|
|
- int ifindex;
|
|
+ int iflink;
|
|
|
|
ASSERT_RTNL();
|
|
|
|
if (!netdev)
|
|
return NULL;
|
|
|
|
- if (netdev->ifindex == dev_get_iflink(netdev)) {
|
|
+ iflink = dev_get_iflink(netdev);
|
|
+ if (iflink == 0) {
|
|
dev_hold(netdev);
|
|
return netdev;
|
|
}
|
|
@@ -233,9 +237,16 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
|
|
goto out;
|
|
|
|
net = dev_net(hard_iface->soft_iface);
|
|
- ifindex = dev_get_iflink(netdev);
|
|
real_net = batadv_getlink_net(netdev, net);
|
|
- real_netdev = dev_get_by_index(real_net, ifindex);
|
|
+
|
|
+ /* iflink to itself, most likely physical device */
|
|
+ if (net == real_net && netdev->ifindex == iflink) {
|
|
+ real_netdev = netdev;
|
|
+ dev_hold(real_netdev);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ real_netdev = dev_get_by_index(real_net, iflink);
|
|
|
|
out:
|
|
if (hard_iface)
|
|
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
|
|
index e9ecbb57df455..b53d5e1d026fe 100644
|
|
--- a/net/dcb/dcbnl.c
|
|
+++ b/net/dcb/dcbnl.c
|
|
@@ -2063,10 +2063,54 @@ u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev)
|
|
}
|
|
EXPORT_SYMBOL(dcb_ieee_getapp_default_prio_mask);
|
|
|
|
+static void dcbnl_flush_dev(struct net_device *dev)
|
|
+{
|
|
+ struct dcb_app_type *itr, *tmp;
|
|
+
|
|
+ spin_lock_bh(&dcb_lock);
|
|
+
|
|
+ list_for_each_entry_safe(itr, tmp, &dcb_app_list, list) {
|
|
+ if (itr->ifindex == dev->ifindex) {
|
|
+ list_del(&itr->list);
|
|
+ kfree(itr);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ spin_unlock_bh(&dcb_lock);
|
|
+}
|
|
+
|
|
+static int dcbnl_netdevice_event(struct notifier_block *nb,
|
|
+ unsigned long event, void *ptr)
|
|
+{
|
|
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
|
+
|
|
+ switch (event) {
|
|
+ case NETDEV_UNREGISTER:
|
|
+ if (!dev->dcbnl_ops)
|
|
+ return NOTIFY_DONE;
|
|
+
|
|
+ dcbnl_flush_dev(dev);
|
|
+
|
|
+ return NOTIFY_OK;
|
|
+ default:
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+}
|
|
+
|
|
+static struct notifier_block dcbnl_nb __read_mostly = {
|
|
+ .notifier_call = dcbnl_netdevice_event,
|
|
+};
|
|
+
|
|
static int __init dcbnl_init(void)
|
|
{
|
|
+ int err;
|
|
+
|
|
INIT_LIST_HEAD(&dcb_app_list);
|
|
|
|
+ err = register_netdevice_notifier(&dcbnl_nb);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, 0);
|
|
rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, 0);
|
|
|
|
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
|
|
index 86c836fa21459..00210e55b4cd1 100644
|
|
--- a/net/ipv4/esp4.c
|
|
+++ b/net/ipv4/esp4.c
|
|
@@ -499,7 +499,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
|
struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
|
|
u32 padto;
|
|
|
|
- padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached));
|
|
+ padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached));
|
|
if (skb->len < padto)
|
|
esp.tfclen = padto - skb->len;
|
|
}
|
|
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
|
|
index 12570a73def80..7a739f16d82b2 100644
|
|
--- a/net/ipv6/esp6.c
|
|
+++ b/net/ipv6/esp6.c
|
|
@@ -440,7 +440,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
|
|
struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
|
|
u32 padto;
|
|
|
|
- padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached));
|
|
+ padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached));
|
|
if (skb->len < padto)
|
|
esp.tfclen = padto - skb->len;
|
|
}
|
|
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
|
|
index d847aa32628da..918a9520d1f17 100644
|
|
--- a/net/ipv6/ip6_output.c
|
|
+++ b/net/ipv6/ip6_output.c
|
|
@@ -1361,8 +1361,6 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
|
|
if (np->frag_size)
|
|
mtu = np->frag_size;
|
|
}
|
|
- if (mtu < IPV6_MIN_MTU)
|
|
- return -EINVAL;
|
|
cork->base.fragsize = mtu;
|
|
cork->base.gso_size = ipc6->gso_size;
|
|
cork->base.tx_flags = 0;
|
|
@@ -1424,8 +1422,6 @@ static int __ip6_append_data(struct sock *sk,
|
|
|
|
fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
|
|
(opt ? opt->opt_nflen : 0);
|
|
- maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
|
|
- sizeof(struct frag_hdr);
|
|
|
|
headersize = sizeof(struct ipv6hdr) +
|
|
(opt ? opt->opt_flen + opt->opt_nflen : 0) +
|
|
@@ -1433,6 +1429,13 @@ static int __ip6_append_data(struct sock *sk,
|
|
sizeof(struct frag_hdr) : 0) +
|
|
rt->rt6i_nfheader_len;
|
|
|
|
+ if (mtu < fragheaderlen ||
|
|
+ ((mtu - fragheaderlen) & ~7) + fragheaderlen < sizeof(struct frag_hdr))
|
|
+ goto emsgsize;
|
|
+
|
|
+ maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
|
|
+ sizeof(struct frag_hdr);
|
|
+
|
|
/* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
|
|
* the first fragment
|
|
*/
|
|
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
|
|
index 464029892478f..ab91683d94596 100644
|
|
--- a/net/mac80211/rx.c
|
|
+++ b/net/mac80211/rx.c
|
|
@@ -2852,13 +2852,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
|
ether_addr_equal(sdata->vif.addr, hdr->addr3))
|
|
return RX_CONTINUE;
|
|
|
|
- ac = ieee80211_select_queue_80211(sdata, skb, hdr);
|
|
+ ac = ieee802_1d_to_ac[skb->priority];
|
|
q = sdata->vif.hw_queue[ac];
|
|
if (ieee80211_queue_stopped(&local->hw, q)) {
|
|
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
|
|
return RX_DROP_MONITOR;
|
|
}
|
|
- skb_set_queue_mapping(skb, q);
|
|
+ skb_set_queue_mapping(skb, ac);
|
|
|
|
if (!--mesh_hdr->ttl) {
|
|
if (!is_multicast_ether_addr(hdr->addr1))
|
|
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
|
|
index 5d5bdf4500916..451b2df998ea7 100644
|
|
--- a/net/netfilter/core.c
|
|
+++ b/net/netfilter/core.c
|
|
@@ -336,14 +336,15 @@ static int __nf_register_net_hook(struct net *net, int pf,
|
|
p = nf_entry_dereference(*pp);
|
|
new_hooks = nf_hook_entries_grow(p, reg);
|
|
|
|
- if (!IS_ERR(new_hooks))
|
|
+ if (!IS_ERR(new_hooks)) {
|
|
+ hooks_validate(new_hooks);
|
|
rcu_assign_pointer(*pp, new_hooks);
|
|
+ }
|
|
|
|
mutex_unlock(&nf_hook_mutex);
|
|
if (IS_ERR(new_hooks))
|
|
return PTR_ERR(new_hooks);
|
|
|
|
- hooks_validate(new_hooks);
|
|
#ifdef CONFIG_NETFILTER_INGRESS
|
|
if (pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS)
|
|
net_inc_ingress_queue();
|
|
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
|
|
index f8f52ff99cfb0..643dbfe7c5815 100644
|
|
--- a/net/netfilter/nf_queue.c
|
|
+++ b/net/netfilter/nf_queue.c
|
|
@@ -64,6 +64,15 @@ static void nf_queue_entry_release_br_nf_refs(struct sk_buff *skb)
|
|
#endif
|
|
}
|
|
|
|
+static void nf_queue_sock_put(struct sock *sk)
|
|
+{
|
|
+#ifdef CONFIG_INET
|
|
+ sock_gen_put(sk);
|
|
+#else
|
|
+ sock_put(sk);
|
|
+#endif
|
|
+}
|
|
+
|
|
void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
|
|
{
|
|
struct nf_hook_state *state = &entry->state;
|
|
@@ -74,7 +83,7 @@ void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
|
|
if (state->out)
|
|
dev_put(state->out);
|
|
if (state->sk)
|
|
- sock_put(state->sk);
|
|
+ nf_queue_sock_put(state->sk);
|
|
|
|
nf_queue_entry_release_br_nf_refs(entry->skb);
|
|
}
|
|
@@ -99,18 +108,20 @@ static void nf_queue_entry_get_br_nf_refs(struct sk_buff *skb)
|
|
}
|
|
|
|
/* Bump dev refs so they don't vanish while packet is out */
|
|
-void nf_queue_entry_get_refs(struct nf_queue_entry *entry)
|
|
+bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
|
|
{
|
|
struct nf_hook_state *state = &entry->state;
|
|
|
|
+ if (state->sk && !refcount_inc_not_zero(&state->sk->sk_refcnt))
|
|
+ return false;
|
|
+
|
|
if (state->in)
|
|
dev_hold(state->in);
|
|
if (state->out)
|
|
dev_hold(state->out);
|
|
- if (state->sk)
|
|
- sock_hold(state->sk);
|
|
|
|
nf_queue_entry_get_br_nf_refs(entry->skb);
|
|
+ return true;
|
|
}
|
|
EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
|
|
|
|
@@ -201,7 +212,10 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state,
|
|
.size = sizeof(*entry) + route_key_size,
|
|
};
|
|
|
|
- nf_queue_entry_get_refs(entry);
|
|
+ if (!nf_queue_entry_get_refs(entry)) {
|
|
+ kfree(entry);
|
|
+ return -ENOTCONN;
|
|
+ }
|
|
|
|
switch (entry->state.pf) {
|
|
case AF_INET:
|
|
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
|
|
index ca21f8f4a47c1..7d3ab08a5a2d0 100644
|
|
--- a/net/netfilter/nfnetlink_queue.c
|
|
+++ b/net/netfilter/nfnetlink_queue.c
|
|
@@ -712,9 +712,15 @@ static struct nf_queue_entry *
|
|
nf_queue_entry_dup(struct nf_queue_entry *e)
|
|
{
|
|
struct nf_queue_entry *entry = kmemdup(e, e->size, GFP_ATOMIC);
|
|
- if (entry)
|
|
- nf_queue_entry_get_refs(entry);
|
|
- return entry;
|
|
+
|
|
+ if (!entry)
|
|
+ return NULL;
|
|
+
|
|
+ if (nf_queue_entry_get_refs(entry))
|
|
+ return entry;
|
|
+
|
|
+ kfree(entry);
|
|
+ return NULL;
|
|
}
|
|
|
|
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
|
|
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
|
|
index aeea67f908415..12672019f76c5 100644
|
|
--- a/net/smc/smc_core.c
|
|
+++ b/net/smc/smc_core.c
|
|
@@ -342,8 +342,8 @@ void smc_conn_free(struct smc_connection *conn)
|
|
} else {
|
|
smc_cdc_tx_dismiss_slots(conn);
|
|
}
|
|
- smc_lgr_unregister_conn(conn);
|
|
smc_buf_unuse(conn, lgr); /* allow buffer reuse */
|
|
+ smc_lgr_unregister_conn(conn);
|
|
conn->lgr = NULL;
|
|
|
|
if (!lgr->conns_num)
|
|
@@ -632,7 +632,8 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
|
|
!lgr->sync_err &&
|
|
lgr->vlan_id == ini->vlan_id &&
|
|
(role == SMC_CLNT ||
|
|
- lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) {
|
|
+ (lgr->conns_num < SMC_RMBS_PER_LGR_MAX &&
|
|
+ !bitmap_full(lgr->rtokens_used_mask, SMC_RMBS_PER_LGR_MAX)))) {
|
|
/* link group found */
|
|
ini->cln_first_contact = SMC_REUSE_CONTACT;
|
|
conn->lgr = lgr;
|
|
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
|
|
index 7633d6a74bc2b..f2bc465de2845 100644
|
|
--- a/net/wireless/nl80211.c
|
|
+++ b/net/wireless/nl80211.c
|
|
@@ -12320,6 +12320,9 @@ static int handle_nan_filter(struct nlattr *attr_filter,
|
|
i = 0;
|
|
nla_for_each_nested(attr, attr_filter, rem) {
|
|
filter[i].filter = nla_memdup(attr, GFP_KERNEL);
|
|
+ if (!filter[i].filter)
|
|
+ goto err;
|
|
+
|
|
filter[i].len = nla_len(attr);
|
|
i++;
|
|
}
|
|
@@ -12332,6 +12335,15 @@ static int handle_nan_filter(struct nlattr *attr_filter,
|
|
}
|
|
|
|
return 0;
|
|
+
|
|
+err:
|
|
+ i = 0;
|
|
+ nla_for_each_nested(attr, attr_filter, rem) {
|
|
+ kfree(filter[i].filter);
|
|
+ i++;
|
|
+ }
|
|
+ kfree(filter);
|
|
+ return -ENOMEM;
|
|
}
|
|
|
|
static int nl80211_nan_add_func(struct sk_buff *skb,
|
|
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
|
|
index bb2292b5260c2..d758e9ec3d008 100644
|
|
--- a/net/xfrm/xfrm_device.c
|
|
+++ b/net/xfrm/xfrm_device.c
|
|
@@ -206,6 +206,9 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
|
|
if (x->encap || x->tfcpad)
|
|
return -EINVAL;
|
|
|
|
+ if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND))
|
|
+ return -EINVAL;
|
|
+
|
|
dev = dev_get_by_index(net, xuo->ifindex);
|
|
if (!dev) {
|
|
if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) {
|
|
@@ -243,7 +246,8 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
|
|
|
|
xso->dev = dev;
|
|
xso->num_exthdrs = 1;
|
|
- xso->flags = xuo->flags;
|
|
+ /* Don't forward bit that is not implemented */
|
|
+ xso->flags = xuo->flags & ~XFRM_OFFLOAD_IPV6;
|
|
|
|
err = dev->xfrmdev_ops->xdo_dev_state_add(x);
|
|
if (err) {
|
|
diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c
|
|
index 08343201513a9..3932d3aaff270 100644
|
|
--- a/net/xfrm/xfrm_interface.c
|
|
+++ b/net/xfrm/xfrm_interface.c
|
|
@@ -695,12 +695,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
|
|
struct net *net = xi->net;
|
|
struct xfrm_if_parms p = {};
|
|
|
|
+ xfrmi_netlink_parms(data, &p);
|
|
if (!p.if_id) {
|
|
NL_SET_ERR_MSG(extack, "if_id must be non zero");
|
|
return -EINVAL;
|
|
}
|
|
|
|
- xfrmi_netlink_parms(data, &p);
|
|
xi = xfrmi_locate(net, &p);
|
|
if (!xi) {
|
|
xi = netdev_priv(dev);
|
|
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
|
|
index c6b2c99b501b9..1423e2b7cb42a 100644
|
|
--- a/net/xfrm/xfrm_state.c
|
|
+++ b/net/xfrm/xfrm_state.c
|
|
@@ -2440,7 +2440,7 @@ void xfrm_state_delete_tunnel(struct xfrm_state *x)
|
|
}
|
|
EXPORT_SYMBOL(xfrm_state_delete_tunnel);
|
|
|
|
-u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu)
|
|
+u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
|
|
{
|
|
const struct xfrm_type *type = READ_ONCE(x->type);
|
|
struct crypto_aead *aead;
|
|
@@ -2471,17 +2471,7 @@ u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu)
|
|
return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
|
|
net_adj) & ~(blksize - 1)) + net_adj - 2;
|
|
}
|
|
-EXPORT_SYMBOL_GPL(__xfrm_state_mtu);
|
|
-
|
|
-u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
|
|
-{
|
|
- mtu = __xfrm_state_mtu(x, mtu);
|
|
-
|
|
- if (x->props.family == AF_INET6 && mtu < IPV6_MIN_MTU)
|
|
- return IPV6_MIN_MTU;
|
|
-
|
|
- return mtu;
|
|
-}
|
|
+EXPORT_SYMBOL_GPL(xfrm_state_mtu);
|
|
|
|
int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
|
|
{
|
|
diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c
|
|
index 2fb65f246b0cf..77af5b67b9bb4 100644
|
|
--- a/sound/soc/codecs/cs4265.c
|
|
+++ b/sound/soc/codecs/cs4265.c
|
|
@@ -150,7 +150,6 @@ static const struct snd_kcontrol_new cs4265_snd_controls[] = {
|
|
SOC_SINGLE("E to F Buffer Disable Switch", CS4265_SPDIF_CTL1,
|
|
6, 1, 0),
|
|
SOC_ENUM("C Data Access", cam_mode_enum),
|
|
- SOC_SINGLE("SPDIF Switch", CS4265_SPDIF_CTL2, 5, 1, 1),
|
|
SOC_SINGLE("Validity Bit Control Switch", CS4265_SPDIF_CTL2,
|
|
3, 1, 0),
|
|
SOC_ENUM("SPDIF Mono/Stereo", spdif_mono_stereo_enum),
|
|
@@ -186,7 +185,7 @@ static const struct snd_soc_dapm_widget cs4265_dapm_widgets[] = {
|
|
|
|
SND_SOC_DAPM_SWITCH("Loopback", SND_SOC_NOPM, 0, 0,
|
|
&loopback_ctl),
|
|
- SND_SOC_DAPM_SWITCH("SPDIF", SND_SOC_NOPM, 0, 0,
|
|
+ SND_SOC_DAPM_SWITCH("SPDIF", CS4265_SPDIF_CTL2, 5, 1,
|
|
&spdif_switch),
|
|
SND_SOC_DAPM_SWITCH("DAC", CS4265_PWRCTL, 1, 1,
|
|
&dac_switch),
|
|
diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c
|
|
index 5716cede99cb4..acc2b34ca334a 100644
|
|
--- a/sound/soc/codecs/rt5668.c
|
|
+++ b/sound/soc/codecs/rt5668.c
|
|
@@ -1022,11 +1022,13 @@ static void rt5668_jack_detect_handler(struct work_struct *work)
|
|
container_of(work, struct rt5668_priv, jack_detect_work.work);
|
|
int val, btn_type;
|
|
|
|
- while (!rt5668->component)
|
|
- usleep_range(10000, 15000);
|
|
-
|
|
- while (!rt5668->component->card->instantiated)
|
|
- usleep_range(10000, 15000);
|
|
+ if (!rt5668->component || !rt5668->component->card ||
|
|
+ !rt5668->component->card->instantiated) {
|
|
+ /* card not yet ready, try later */
|
|
+ mod_delayed_work(system_power_efficient_wq,
|
|
+ &rt5668->jack_detect_work, msecs_to_jiffies(15));
|
|
+ return;
|
|
+ }
|
|
|
|
mutex_lock(&rt5668->calibrate_mutex);
|
|
|
|
diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c
|
|
index 05e883a65d7a7..a8cf4c7451304 100644
|
|
--- a/sound/soc/codecs/rt5682.c
|
|
+++ b/sound/soc/codecs/rt5682.c
|
|
@@ -1052,11 +1052,13 @@ static void rt5682_jack_detect_handler(struct work_struct *work)
|
|
container_of(work, struct rt5682_priv, jack_detect_work.work);
|
|
int val, btn_type;
|
|
|
|
- while (!rt5682->component)
|
|
- usleep_range(10000, 15000);
|
|
-
|
|
- while (!rt5682->component->card->instantiated)
|
|
- usleep_range(10000, 15000);
|
|
+ if (!rt5682->component || !rt5682->component->card ||
|
|
+ !rt5682->component->card->instantiated) {
|
|
+ /* card not yet ready, try later */
|
|
+ mod_delayed_work(system_power_efficient_wq,
|
|
+ &rt5682->jack_detect_work, msecs_to_jiffies(15));
|
|
+ return;
|
|
+ }
|
|
|
|
mutex_lock(&rt5682->calibrate_mutex);
|
|
|
|
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
|
|
index f5dcd625e4355..c88bc6bb41cfe 100644
|
|
--- a/sound/soc/soc-ops.c
|
|
+++ b/sound/soc/soc-ops.c
|
|
@@ -323,7 +323,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
|
|
mask = BIT(sign_bit + 1) - 1;
|
|
|
|
val = ucontrol->value.integer.value[0];
|
|
- if (mc->platform_max && val > mc->platform_max)
|
|
+ if (mc->platform_max && ((int)val + min) > mc->platform_max)
|
|
return -EINVAL;
|
|
if (val > max - min)
|
|
return -EINVAL;
|
|
@@ -336,7 +336,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
|
|
val = val << shift;
|
|
if (snd_soc_volsw_is_stereo(mc)) {
|
|
val2 = ucontrol->value.integer.value[1];
|
|
- if (mc->platform_max && val2 > mc->platform_max)
|
|
+ if (mc->platform_max && ((int)val2 + min) > mc->platform_max)
|
|
return -EINVAL;
|
|
if (val2 > max - min)
|
|
return -EINVAL;
|
|
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
|
|
index 5fd4e32247a6d..a314f13e3292e 100644
|
|
--- a/sound/x86/intel_hdmi_audio.c
|
|
+++ b/sound/x86/intel_hdmi_audio.c
|
|
@@ -1279,7 +1279,7 @@ static int had_pcm_mmap(struct snd_pcm_substream *substream,
|
|
{
|
|
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
|
return remap_pfn_range(vma, vma->vm_start,
|
|
- substream->dma_buffer.addr >> PAGE_SHIFT,
|
|
+ substream->runtime->dma_addr >> PAGE_SHIFT,
|
|
vma->vm_end - vma->vm_start, vma->vm_page_prot);
|
|
}
|
|
|