From 07af7810e0a5bc4e51682c90f9fa19fc4cb93f18 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Sat, 12 Dec 2020 10:55:25 +0100 Subject: [PATCH 0001/1084] DTS: ARM: gta04: remove legacy spi-cs-high to make display work again This reverts commit f1f028ff89cb ("DTS: ARM: gta04: introduce legacy spi-cs-high to make display work again") which had to be intruduced after commit 6953c57ab172 ("gpio: of: Handle SPI chipselect legacy bindings") broke the GTA04 display. This contradicted the data sheet but was the only way to get it as an spi client operational again. The panel data sheet defines the chip-select to be active low. Now, with the arrival of commit 766c6b63aa04 ("spi: fix client driver breakages when using GPIO descriptors") the logic of interaction between spi-cs-high and the gpio descriptor flags has been changed a second time, making the display broken again. So we have to remove the original fix which in retrospect was a workaround of a bug in the spi subsystem and not a feature of the panel or bug in the device tree. With this fix the device tree is back in sync with the data sheet and spi subsystem code. Fixes: 766c6b63aa04 ("spi: fix client driver breakages when using GPIO descriptors") CC: stable@vger.kernel.org Signed-off-by: H. Nikolaus Schaller Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi index c8745bc800f71..003202d129907 100644 --- a/arch/arm/boot/dts/omap3-gta04.dtsi +++ b/arch/arm/boot/dts/omap3-gta04.dtsi @@ -124,7 +124,6 @@ spi-max-frequency = <100000>; spi-cpol; spi-cpha; - spi-cs-high; backlight= <&backlight>; label = "lcd"; -- GitLab From 6efac0173cd15460b48c91e1b0a000379f341f00 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 14 Dec 2020 23:01:21 +0200 Subject: [PATCH 0002/1084] ARM: OMAP1: OSK: fix ohci-omap breakage Commit 45c5775460f3 ("usb: ohci-omap: Fix descriptor conversion") tried to fix all issues related to ohci-omap descriptor conversion, but a wrong patch was applied, and one needed change to the OSK board file is still missing. Fix that. Fixes: 45c5775460f3 ("usb: ohci-omap: Fix descriptor conversion") Signed-off-by: Linus Walleij [aaro.koskinen@iki.fi: rebased and updated the changelog] Signed-off-by: Aaro Koskinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-osk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index a720259099edf..0a4c9b0b13b0c 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -203,6 +203,8 @@ static int osk_tps_setup(struct i2c_client *client, void *context) */ gpio_request(OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en"); gpio_direction_output(OSK_TPS_GPIO_USB_PWR_EN, 1); + /* Free the GPIO again as the driver will request it */ + gpio_free(OSK_TPS_GPIO_USB_PWR_EN); /* Set GPIO 2 high so LED D3 is off by default */ tps65010_set_gpio_out_value(GPIO2, HIGH); -- GitLab From 06fde695ee76429634c1e8c8c1154035aa61191e Mon Sep 17 00:00:00 2001 From: Zenghui Yu Date: Fri, 18 Dec 2020 14:00:39 +0800 Subject: [PATCH 0003/1084] genirq/msi: Initialize msi_alloc_info before calling msi_domain_prepare_irqs() Since commit 5fe71d271df8 ("irqchip/gic-v3-its: Tag ITS device as shared if allocating for a proxy device"), some of the devices are wrongly marked as "shared" by the ITS driver on systems equipped with the ITS(es). The problem is that the @info->flags may not be initialized anywhere and we end up looking at random bits on the stack. That's obviously not good. We can perform the initialization in the IRQ core layer before calling msi_domain_prepare_irqs(), which is neat enough. Fixes: 5fe71d271df8 ("irqchip/gic-v3-its: Tag ITS device as shared if allocating for a proxy device") Signed-off-by: Zenghui Yu Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20201218060039.1770-1-yuzenghui@huawei.com --- kernel/irq/msi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 2c0c4d6d0f83a..dc0e2d7fbdfd9 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -402,7 +402,7 @@ int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, struct msi_domain_ops *ops = info->ops; struct irq_data *irq_data; struct msi_desc *desc; - msi_alloc_info_t arg; + msi_alloc_info_t arg = { }; int i, ret, virq; bool can_reserve; -- GitLab From e90f55e0196a66f8e9e445f7f33f876dd889be9a Mon Sep 17 00:00:00 2001 From: Zheng Yongjun Date: Mon, 14 Dec 2020 21:35:30 +0800 Subject: [PATCH 0004/1084] irqchip/irq-sl28cpld: Convert comma to semicolon Replace a comma between expression statements by a semicolon. Signed-off-by: Zheng Yongjun Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20201214133530.3783-1-zhengyongjun3@huawei.com --- drivers/irqchip/irq-sl28cpld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-sl28cpld.c b/drivers/irqchip/irq-sl28cpld.c index 0aa50d025ef6c..fbb354413ffa1 100644 --- a/drivers/irqchip/irq-sl28cpld.c +++ b/drivers/irqchip/irq-sl28cpld.c @@ -66,7 +66,7 @@ static int sl28cpld_intc_probe(struct platform_device *pdev) irqchip->chip.num_regs = 1; irqchip->chip.status_base = base + INTC_IP; irqchip->chip.mask_base = base + INTC_IE; - irqchip->chip.mask_invert = true, + irqchip->chip.mask_invert = true; irqchip->chip.ack_base = base + INTC_IP; return devm_regmap_add_irq_chip_fwnode(dev, dev_fwnode(dev), -- GitLab From d7f39c40ebb6986e7371510d1c20a4efee4a7f0d Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 18 Dec 2020 18:03:46 +0000 Subject: [PATCH 0005/1084] irqchip/bcm2836: Fix IPI acknowledgement after conversion to handle_percpu_devid_irq It appears that despite its name, the bcm2836_arm_irqchip_ipi_eoi() callback is an acknowledgement, and not an EOI. This means that we lose IPIs that are made pending between the handling of the IPI and the write to LOCAL_MAILBOX0_CLR0. With the right timing, things fail nicely. This used to work with handle_percpu_devid_fasteoi_ipi(), which started by eoi-ing the interrupt. With the standard fasteoi flow, this doesn't work anymore. So let's use this callback for what it is, an ack. Your favourite RPi-2/3 is back up and running. Fixes: ffdad793d579 ("irqchip/bcm2836: Make IPIs use handle_percpu_devid_irq()") Cc: Valentin Schneider Reported-by: Guenter Roeck Tested-by: Guenter Roeck Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/c9fb4ab3-a5cb-648c-6de3-c6a871e60870@roeck-us.net --- drivers/irqchip/irq-bcm2836.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c index 5f5eb8877c413..25c9a9c06e410 100644 --- a/drivers/irqchip/irq-bcm2836.c +++ b/drivers/irqchip/irq-bcm2836.c @@ -167,7 +167,7 @@ static void bcm2836_arm_irqchip_handle_ipi(struct irq_desc *desc) chained_irq_exit(chip, desc); } -static void bcm2836_arm_irqchip_ipi_eoi(struct irq_data *d) +static void bcm2836_arm_irqchip_ipi_ack(struct irq_data *d) { int cpu = smp_processor_id(); @@ -195,7 +195,7 @@ static struct irq_chip bcm2836_arm_irqchip_ipi = { .name = "IPI", .irq_mask = bcm2836_arm_irqchip_dummy_op, .irq_unmask = bcm2836_arm_irqchip_dummy_op, - .irq_eoi = bcm2836_arm_irqchip_ipi_eoi, + .irq_ack = bcm2836_arm_irqchip_ipi_ack, .ipi_send_mask = bcm2836_arm_irqchip_ipi_send_mask, }; -- GitLab From 56ce7c25ae1525d83cf80a880cf506ead1914250 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Mon, 14 Dec 2020 15:38:32 +0200 Subject: [PATCH 0006/1084] xfrm: Fix oops in xfrm_replay_advance_bmp When setting xfrm replay_window to values higher than 32, a rare page-fault occurs in xfrm_replay_advance_bmp: BUG: unable to handle page fault for address: ffff8af350ad7920 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD ad001067 P4D ad001067 PUD 0 Oops: 0002 [#1] SMP PTI CPU: 3 PID: 30 Comm: ksoftirqd/3 Kdump: loaded Not tainted 5.4.52-050452-generic #202007160732 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2.el7 04/01/2014 RIP: 0010:xfrm_replay_advance_bmp+0xbb/0x130 RSP: 0018:ffffa1304013ba40 EFLAGS: 00010206 RAX: 000000000000010d RBX: 0000000000000002 RCX: 00000000ffffff4b RDX: 0000000000000018 RSI: 00000000004c234c RDI: 00000000ffb3dbff RBP: ffffa1304013ba50 R08: ffff8af330ad7920 R09: 0000000007fffffa R10: 0000000000000800 R11: 0000000000000010 R12: ffff8af29d6258c0 R13: ffff8af28b95c700 R14: 0000000000000000 R15: ffff8af29d6258fc FS: 0000000000000000(0000) GS:ffff8af339ac0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff8af350ad7920 CR3: 0000000015ee4000 CR4: 00000000001406e0 Call Trace: xfrm_input+0x4e5/0xa10 xfrm4_rcv_encap+0xb5/0xe0 xfrm4_udp_encap_rcv+0x140/0x1c0 Analysis revealed offending code is when accessing: replay_esn->bmp[nr] |= (1U << bitnr); with 'nr' being 0x07fffffa. This happened in an SMP system when reordering of packets was present; A packet arrived with a "too old" sequence number (outside the window, i.e 'diff > replay_window'), and therefore the following calculation: bitnr = replay_esn->replay_window - (diff - pos); yields a negative result, but since bitnr is u32 we get a large unsigned quantity (in crash dump above: 0xffffff4b seen in ecx). This was supposed to be protected by xfrm_input()'s former call to: if (x->repl->check(x, skb, seq)) { However, the state's spinlock x->lock is *released* after '->check()' is performed, and gets re-acquired before '->advance()' - which gives a chance for a different core to update the xfrm state, e.g. by advancing 'replay_esn->seq' when it encounters more packets - leading to a 'diff > replay_window' situation when original core continues to xfrm_replay_advance_bmp(). An attempt to fix this issue was suggested in commit bcf66bf54aab ("xfrm: Perform a replay check after return from async codepaths"), by calling 'x->repl->recheck()' after lock is re-acquired, but fix applied only to asyncronous crypto algorithms. Augment the fix, by *always* calling 'recheck()' - irrespective if we're using async crypto. Fixes: 0ebea8ef3559 ("[IPSEC]: Move state lock into x->type->input") Signed-off-by: Shmulik Ladkani Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 37456d022cfa3..61e6220ddd5ae 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -660,7 +660,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) /* only the first xfrm gets the encap type */ encap_type = 0; - if (async && x->repl->recheck(x, skb, seq)) { + if (x->repl->recheck(x, skb, seq)) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR); goto drop_unlock; } -- GitLab From e1dc20995cb9fa04b46e8f37113a7203c906d2bf Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 21 Dec 2020 22:30:55 +0800 Subject: [PATCH 0007/1084] driver core: platform: Add extra error check in devm_platform_get_irqs_affinity() The current check of nvec < minvec for nvec returned from platform_irq_count() will not detect a negative error code in nvec. This is because minvec is unsigned, and, as such, nvec is promoted to unsigned in that check, which will make it a huge number (if it contained -EPROBE_DEFER). In practice, an error should not occur in nvec for the only in-tree user, but add a check anyway. Fixes: e15f2fa959f2 ("driver core: platform: Add devm_platform_get_irqs_affinity()") Reported-by: Dan Carpenter Signed-off-by: John Garry Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/1608561055-231244-1-git-send-email-john.garry@huawei.com --- drivers/base/platform.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index ea8add164b896..74c97b65048c9 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -351,6 +351,8 @@ int devm_platform_get_irqs_affinity(struct platform_device *dev, return -ERANGE; nvec = platform_irq_count(dev); + if (nvec < 0) + return nvec; if (nvec < minvec) return -ENOSPC; -- GitLab From a9830fc388817c90282925694474fae005fec990 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 14 Dec 2020 19:21:38 +0200 Subject: [PATCH 0008/1084] catpt: Switch to use list_entry_is_head() helper Since we got list_entry_is_head() helper in the generic header, we may switch catpt to use it. It removes the need in additional variable. Signed-off-by: Andy Shevchenko Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20201214172138.44267-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/catpt/pcm.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c index e5d54bb1c42ac..9d304b3a817fa 100644 --- a/sound/soc/intel/catpt/pcm.c +++ b/sound/soc/intel/catpt/pcm.c @@ -331,7 +331,7 @@ static int catpt_dai_apply_usettings(struct snd_soc_dai *dai, { struct catpt_dev *cdev = dev_get_drvdata(dai->dev); struct snd_soc_component *component = dai->component; - struct snd_kcontrol *pos, *kctl = NULL; + struct snd_kcontrol *pos; const char *name; int ret; u32 id = stream->info.stream_hw_id; @@ -356,17 +356,15 @@ static int catpt_dai_apply_usettings(struct snd_soc_dai *dai, list_for_each_entry(pos, &component->card->snd_card->controls, list) { if (pos->private_data == component && - !strncmp(name, pos->id.name, sizeof(pos->id.name))) { - kctl = pos; + !strncmp(name, pos->id.name, sizeof(pos->id.name))) break; - } } - if (!kctl) + if (list_entry_is_head(pos, &component->card->snd_card->controls, list)) return -ENOENT; if (stream->template->type != CATPT_STRM_TYPE_LOOPBACK) - return catpt_set_dspvol(cdev, id, (long *)kctl->private_value); - ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)kctl->private_value); + return catpt_set_dspvol(cdev, id, (long *)pos->private_value); + ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)pos->private_value); if (ret) return CATPT_IPC_ERROR(ret); return 0; -- GitLab From 7726e49837af634accaec317c8d246d1d90d8fc5 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Wed, 16 Dec 2020 11:25:12 +0000 Subject: [PATCH 0009/1084] ASoC: wm_adsp: Improve handling of raw byte streams As the register map is 16-bit or 32-bit big-endian, the 24-bit DSP words appear padded and with the bytes swapped. When reading a raw stream of bytes, the pad bytes must be removed and the data bytes swapped back to their original order. The previous implementation of this assumed that the be32_to_cpu() in wm_adsp_read_data_block() would swap back to little-endian. But this is obviously only true on a little-endian CPU. It also made two walks through the data, once to endian-swap and again to strip the pad bytes. This patch re-works the code so that the endian-swap and unpad are done together in a single walk, and it is not dependent on the endianness of the CPU. The data_word_size argument to wm_adsp_remove_padding() has been dropped because currently this is always 3. Signed-off-by: Richard Fitzgerald Link: https://lore.kernel.org/r/20201216112512.26503-1-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 55 +++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index dec8716aa8ef5..5b7d81a91df3a 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3664,12 +3664,12 @@ int wm_adsp_compr_get_caps(struct snd_soc_component *component, } EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); -static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type, - unsigned int mem_addr, - unsigned int num_words, u32 *data) +static int wm_adsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, + unsigned int num_words, __be32 *data) { struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); - unsigned int i, reg; + unsigned int reg; int ret; if (!mem) @@ -3682,16 +3682,22 @@ static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type, if (ret < 0) return ret; - for (i = 0; i < num_words; ++i) - data[i] = be32_to_cpu(data[i]) & 0x00ffffffu; - return 0; } static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, unsigned int mem_addr, u32 *data) { - return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data); + __be32 raw; + int ret; + + ret = wm_adsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); + if (ret) + return ret; + + *data = be32_to_cpu(raw) & 0x00ffffffu; + + return 0; } static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, @@ -3724,18 +3730,22 @@ static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, buf->host_buf_ptr + field_offset, data); } -static void wm_adsp_remove_padding(u32 *buf, int nwords, int data_word_size) +static void wm_adsp_remove_padding(u32 *buf, int nwords) { - u8 *pack_in = (u8 *)buf; + const __be32 *pack_in = (__be32 *)buf; u8 *pack_out = (u8 *)buf; - int i, j; + int i; - /* Remove the padding bytes from the data read from the DSP */ + /* + * DSP words from the register map have pad bytes and the data bytes + * are in swapped order. This swaps back to the original little-endian + * order and strips the pad bytes. + */ for (i = 0; i < nwords; i++) { - for (j = 0; j < data_word_size; j++) - *pack_out++ = *pack_in++; - - pack_in += sizeof(*buf) - data_word_size; + u32 word = be32_to_cpu(*pack_in++); + *pack_out++ = (u8)word; + *pack_out++ = (u8)(word >> 8); + *pack_out++ = (u8)(word >> 16); } } @@ -3919,12 +3929,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) return -EINVAL; } - for (i = 0; i < ARRAY_SIZE(coeff_v1.name); i++) - coeff_v1.name[i] = be32_to_cpu(coeff_v1.name[i]); - - wm_adsp_remove_padding((u32 *)&coeff_v1.name, - ARRAY_SIZE(coeff_v1.name), - WM_ADSP_DATA_WORD_SIZE); + wm_adsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name)); buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, (char *)&coeff_v1.name); @@ -4263,12 +4268,12 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) return 0; /* Read data from DSP */ - ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr, - nwords, compr->raw_buf); + ret = wm_adsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, + nwords, compr->raw_buf); if (ret < 0) return ret; - wm_adsp_remove_padding(compr->raw_buf, nwords, WM_ADSP_DATA_WORD_SIZE); + wm_adsp_remove_padding(compr->raw_buf, nwords); /* update read index to account for words read */ buf->read_index += nwords; -- GitLab From 6bdd75a1f6f552ecfb0afd6f544b022b2d34c56a Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Tue, 22 Dec 2020 03:15:24 +0000 Subject: [PATCH 0010/1084] ASoC: rt1015: modify calibration sequence for better performance New calibration sequence to fix power issue in idle state. Signed-off-by: Jack Yu Link: https://lore.kernel.org/r/ec66399502514edbb1de3cf9bff08b1d@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1015.c | 40 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 32e6bcf763d1d..5fdf7bbfd375f 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -497,40 +497,20 @@ static void rt1015_calibrate(struct rt1015_priv *rt1015) snd_soc_dapm_mutex_lock(&component->dapm); regcache_cache_bypass(regmap, true); - regmap_write(regmap, RT1015_PWR9, 0xAA60); - regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0089); - regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008A); - regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008C); - regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008D); - regmap_write(regmap, RT1015_PWR4, 0x80B2); - regmap_write(regmap, RT1015_CLASSD_SEQ, 0x5797); - regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2100); - regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0100); - regmap_write(regmap, RT1015_PWR5, 0x2175); - regmap_write(regmap, RT1015_MIXER1, 0x005D); - regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x00A1); - regmap_write(regmap, RT1015_CLSD_INTERNAL2, 0x12F7); - regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x1205); - msleep(200); - regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2000); - regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0180); - regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x00A1); - regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x0A05); - msleep(200); + regmap_write(regmap, RT1015_CLK_DET, 0x0000); regmap_write(regmap, RT1015_PWR4, 0x00B2); + regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0009); + msleep(100); + regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000A); + msleep(100); + regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000C); + msleep(100); regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2028); regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0140); - regmap_write(regmap, RT1015_PWR5, 0x0175); - regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x1721); - regmap_write(regmap, RT1015_CLASSD_SEQ, 0x570E); - regmap_write(regmap, RT1015_MIXER1, 0x203D); - regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5A01); - regmap_write(regmap, RT1015_CLSD_INTERNAL2, 0x12FF); - regmap_write(regmap, RT1015_GAT_BOOST, 0x0eFE); - regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008E); - regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0088); + regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000D); + msleep(300); + regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0008); regmap_write(regmap, RT1015_SYS_RST1, 0x05F5); - regmap_write(regmap, RT1015_SYS_RST2, 0x0b9a); regcache_cache_bypass(regmap, false); regcache_mark_dirty(regmap); -- GitLab From 57fc2bbc62ef9d505e8732acbae0d6b5c59836cd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 8 Dec 2020 13:18:05 +0200 Subject: [PATCH 0011/1084] ASoC: sprd: Switch to use list_entry_is_head() helper Since we got list_entry_is_head() helper in the generic header, we may switch driver to use it. This eliminates the need in additional variable. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20201208111805.6989-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sprd/sprd-mcdt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/sprd/sprd-mcdt.c b/sound/soc/sprd/sprd-mcdt.c index f439e5503a3c0..34b2ce733b542 100644 --- a/sound/soc/sprd/sprd-mcdt.c +++ b/sound/soc/sprd/sprd-mcdt.c @@ -866,23 +866,23 @@ EXPORT_SYMBOL_GPL(sprd_mcdt_chan_dma_disable); struct sprd_mcdt_chan *sprd_mcdt_request_chan(u8 channel, enum sprd_mcdt_channel_type type) { - struct sprd_mcdt_chan *temp, *chan = NULL; + struct sprd_mcdt_chan *temp; mutex_lock(&sprd_mcdt_list_mutex); list_for_each_entry(temp, &sprd_mcdt_chan_list, list) { if (temp->type == type && temp->id == channel) { - chan = temp; + list_del_init(&temp->list); break; } } - if (chan) - list_del(&chan->list); + if (list_entry_is_head(temp, &sprd_mcdt_chan_list, list)) + temp = NULL; mutex_unlock(&sprd_mcdt_list_mutex); - return chan; + return temp; } EXPORT_SYMBOL_GPL(sprd_mcdt_request_chan); -- GitLab From e05cde84eabccc0441f837f0661cd4c6f4820513 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 18 Dec 2020 16:45:44 +0100 Subject: [PATCH 0012/1084] ASoC: meson: Use managed DMA buffer allocation Using a managed buffer will pre-allocate the buffer using snd_pcm_lib_preallocate_pages() and automatically free it when the PCM is destroyed. In addition it will call snd_pcm_lib_malloc_pages() before the driver's hw_params() callback and snd_pcm_lib_free_pages() after the driver's hw_free() callback. This slightly reduces the boilerplate code of the driver. Signed-off-by: Lars-Peter Clausen Reviewed-by: Jerome Brunet Tested-by: Jerome Brunet Link: https://lore.kernel.org/r/20201218154544.25513-1-lars@metafoo.de Signed-off-by: Mark Brown --- sound/soc/meson/aiu-fifo-i2s.c | 1 - sound/soc/meson/aiu-fifo-spdif.c | 1 - sound/soc/meson/aiu-fifo.c | 18 ++---------------- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/sound/soc/meson/aiu-fifo-i2s.c b/sound/soc/meson/aiu-fifo-i2s.c index d91b0d874342f..2388a2d0b3a6c 100644 --- a/sound/soc/meson/aiu-fifo-i2s.c +++ b/sound/soc/meson/aiu-fifo-i2s.c @@ -124,7 +124,6 @@ const struct snd_soc_dai_ops aiu_fifo_i2s_dai_ops = { .trigger = aiu_fifo_i2s_trigger, .prepare = aiu_fifo_i2s_prepare, .hw_params = aiu_fifo_i2s_hw_params, - .hw_free = aiu_fifo_hw_free, .startup = aiu_fifo_startup, .shutdown = aiu_fifo_shutdown, }; diff --git a/sound/soc/meson/aiu-fifo-spdif.c b/sound/soc/meson/aiu-fifo-spdif.c index 44eb6faacf44d..2fb30f89bf7a2 100644 --- a/sound/soc/meson/aiu-fifo-spdif.c +++ b/sound/soc/meson/aiu-fifo-spdif.c @@ -158,7 +158,6 @@ const struct snd_soc_dai_ops aiu_fifo_spdif_dai_ops = { .trigger = fifo_spdif_trigger, .prepare = fifo_spdif_prepare, .hw_params = fifo_spdif_hw_params, - .hw_free = aiu_fifo_hw_free, .startup = aiu_fifo_startup, .shutdown = aiu_fifo_shutdown, }; diff --git a/sound/soc/meson/aiu-fifo.c b/sound/soc/meson/aiu-fifo.c index aa88aae8e517d..4ad23267cace5 100644 --- a/sound/soc/meson/aiu-fifo.c +++ b/sound/soc/meson/aiu-fifo.c @@ -99,11 +99,6 @@ int aiu_fifo_hw_params(struct snd_pcm_substream *substream, struct snd_soc_component *component = dai->component; struct aiu_fifo *fifo = dai->playback_dma_data; dma_addr_t end; - int ret; - - ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); - if (ret < 0) - return ret; /* Setup the fifo boundaries */ end = runtime->dma_addr + runtime->dma_bytes - fifo->fifo_block; @@ -124,12 +119,6 @@ int aiu_fifo_hw_params(struct snd_pcm_substream *substream, return 0; } -int aiu_fifo_hw_free(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - return snd_pcm_lib_free_pages(substream); -} - static irqreturn_t aiu_fifo_isr(int irq, void *dev_id) { struct snd_pcm_substream *playback = dev_id; @@ -187,15 +176,12 @@ void aiu_fifo_shutdown(struct snd_pcm_substream *substream, int aiu_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { - struct snd_pcm_substream *substream = - rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; struct snd_card *card = rtd->card->snd_card; struct aiu_fifo *fifo = dai->playback_dma_data; size_t size = fifo->pcm->buffer_bytes_max; - snd_pcm_lib_preallocate_pages(substream, - SNDRV_DMA_TYPE_DEV, - card->dev, size, size); + snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, + card->dev, size, size); return 0; } -- GitLab From 54ca955b5a4024e2ce0f206b03adb7109bc4da26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 23 Dec 2020 20:19:31 +0100 Subject: [PATCH 0013/1084] serial: mvebu-uart: fix tx lost characters at power off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit c685af1108d7 ("serial: mvebu-uart: fix tx lost characters") fixed tx lost characters at low baud rates but started causing tx lost characters when kernel is going to power off or reboot. TX_EMP tells us when transmit queue is empty therefore all characters were transmitted. TX_RDY tells us when CPU can send a new character. Therefore we need to use different check prior transmitting new character and different check after all characters were sent. This patch splits polling code into two functions: wait_for_xmitr() which waits for TX_RDY and wait_for_xmite() which waits for TX_EMP. When rebooting A3720 platform without this patch on UART is print only: [ 42.699� And with this patch on UART is full output: [ 39.530216] reboot: Restarting system Fixes: c685af1108d7 ("serial: mvebu-uart: fix tx lost characters") Signed-off-by: Pali Rohár Cc: stable Link: https://lore.kernel.org/r/20201223191931.18343-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 118b299122898..e0c00a1b07639 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -648,6 +648,14 @@ static void wait_for_xmitr(struct uart_port *port) (val & STAT_TX_RDY(port)), 1, 10000); } +static void wait_for_xmite(struct uart_port *port) +{ + u32 val; + + readl_poll_timeout_atomic(port->membase + UART_STAT, val, + (val & STAT_TX_EMP), 1, 10000); +} + static void mvebu_uart_console_putchar(struct uart_port *port, int ch) { wait_for_xmitr(port); @@ -675,7 +683,7 @@ static void mvebu_uart_console_write(struct console *co, const char *s, uart_console_write(port, s, count, mvebu_uart_console_putchar); - wait_for_xmitr(port); + wait_for_xmite(port); if (ier) writel(ier, port->membase + UART_CTRL(port)); -- GitLab From ef019c5daf032dce0b95ed4d45bfec93c4fbcb9f Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Tue, 22 Dec 2020 13:10:46 +0000 Subject: [PATCH 0014/1084] PHY: Ingenic: fix unconditional build of phy-ingenic-usb Currently drivers/phy/ingenic/Makefile adds phy-ingenic-usb to targets not depending on actual Kconfig symbol CONFIG_PHY_INGENIC_USB, so this driver always gets built[-in] on every system. Add missing dependency. Fixes: 31de313dfdcf ("PHY: Ingenic: Add USB PHY driver using generic PHY framework.") Signed-off-by: Alexander Lobakin Link: https://lore.kernel.org/r/20201222131021.4751-1-alobakin@pm.me Signed-off-by: Vinod Koul --- drivers/phy/ingenic/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/ingenic/Makefile b/drivers/phy/ingenic/Makefile index 65d5ea00fc9d4..1cb158d7233f4 100644 --- a/drivers/phy/ingenic/Makefile +++ b/drivers/phy/ingenic/Makefile @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 -obj-y += phy-ingenic-usb.o +obj-$(CONFIG_PHY_INGENIC_USB) += phy-ingenic-usb.o -- GitLab From 92cbdb923c17544684c2dd3be9f8636617898a44 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 10 Dec 2020 21:31:36 +0800 Subject: [PATCH 0015/1084] usb: cdns3: imx: fix writing read-only memory issue The memory for struct clk_bulk_data should not be static which will be written during the clk_bulk_get. It fixed below oops when loading cdns3-imx as module. [ 17.272605] Unable to handle kernel write to read-only memory at virtual address ffff8000092a5398 [ 17.299730] Mem abort info: [ 17.313542] unregister ISI channel: mxc_isi.4 [ 17.324076] ESR = 0x9600004f [ 17.344658] EC = 0x25: DABT (current EL), IL = 32 bits [ 17.402055] SET = 0, FnV = 0 [ 17.404321] mxs_phy 5b100000.usbphy: supply phy-3p0 not found, using dummy regulator [ 17.405121] EA = 0, S1PTW = 0 [ 17.405133] Data abort info: [ 17.496231] ISV = 0, ISS = 0x0000004f [ 17.510871] CM = 0, WnR = 1 [ 17.533542] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000081ea5000 [ 17.545709] [ffff8000092a5398] pgd=00000008bffff003, p4d=00000008bffff003, pud=00000008bfffe003, pmd=0000000885041003, pte=006000088513b783 [ 17.573521] Internal error: Oops: 9600004f [#1] PREEMPT SMP [ 17.579113] Modules linked in: usbmisc_imx phy_mxs_usb phy_cadence_salvo cdns3_imx(+) tcpci imx8_media_dev(C) caam error [ 17.590044] CPU: 2 PID: 253 Comm: systemd-udevd Tainted: G C 5.10.0-rc4-04445-g11f3c3a29d0-dirty #19 [ 17.600488] Hardware name: Freescale i.MX8QXP MEK (DT) [ 17.605633] pstate: 20000005 (nzCv daif -PAN -UAO -TCO BTYPE=--) [ 17.611662] pc : __clk_bulk_get+0x48/0x130 [ 17.615786] lr : clk_bulk_get+0x18/0x20 [ 17.619634] sp : ffff80001369b880 [ 17.622953] x29: ffff80001369b880 x28: 0000000000000013 [ 17.628277] x27: 0000000000000100 x26: ffff00080553b100 [ 17.633602] x25: ffff80001229b4d8 x24: 0000000000000000 [ 17.638928] x23: ffff000800665410 x22: 0000000000000005 [ 17.644275] x21: ffff8000092a5390 x20: ffff000800665400 [ 17.649605] x19: ffff000804e6f980 x18: 000000005b110000 [ 17.654946] x17: 0000000000000000 x16: 0000000000000000 [ 17.660274] x15: ffff800011989100 x14: 0000000000000000 [ 17.665599] x13: ffff800013ce1000 x12: ffff800013ca1000 [ 17.670924] x11: 000000005b110000 x10: 0000000000000000 [ 17.676249] x9 : ffff8000106c5a30 x8 : ffff000804e6fa00 [ 17.681575] x7 : 0000000000000000 x6 : 000000000000003f [ 17.686901] x5 : 0000000000000040 x4 : ffff80001369b8b0 [ 17.692228] x3 : ffff8000092a5398 x2 : ffff8000092a5390 [ 17.697574] x1 : ffff8000092a53e8 x0 : 0000000000000004 [ 17.702905] Call trace: [ 17.705366] __clk_bulk_get+0x48/0x130 [ 17.709125] clk_bulk_get+0x18/0x20 [ 17.712620] devm_clk_bulk_get+0x58/0xb8 [ 17.716563] cdns_imx_probe+0x84/0x1f0 [cdns3_imx] [ 17.721363] platform_drv_probe+0x58/0xa8 [ 17.725381] really_probe+0xec/0x4c8 [ 17.728967] driver_probe_device+0xf4/0x160 [ 17.733160] device_driver_attach+0x74/0x80 [ 17.737355] __driver_attach+0xa4/0x170 [ 17.741202] bus_for_each_dev+0x74/0xc8 [ 17.745043] driver_attach+0x28/0x30 [ 17.748620] bus_add_driver+0x144/0x228 [ 17.752462] driver_register+0x68/0x118 [ 17.756308] __platform_driver_register+0x4c/0x58 [ 17.761022] cdns_imx_driver_init+0x24/0x1000 [cdns3_imx] [ 17.766434] do_one_initcall+0x48/0x2c0 [ 17.770280] do_init_module+0x5c/0x220 [ 17.774029] load_module+0x210c/0x2858 [ 17.777784] __do_sys_finit_module+0xb8/0x120 [ 17.782148] __arm64_sys_finit_module+0x24/0x30 [ 17.786691] el0_svc_common.constprop.0+0x70/0x168 [ 17.791497] do_el0_svc+0x28/0x88 [ 17.794822] el0_sync_handler+0x158/0x160 [ 17.798833] el0_sync+0x140/0x180 [ 17.802158] Code: aa0203f5 91002043 8b205021 a90153f3 (f801047f) Cc: Fixes: 1e056efab993 ("usb: cdns3: add NXP imx8qm glue layer") Signed-off-by: Peter Chen --- drivers/usb/cdns3/cdns3-imx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/cdns3/cdns3-imx.c b/drivers/usb/cdns3/cdns3-imx.c index 22a56c4dce678..4d3fedc867530 100644 --- a/drivers/usb/cdns3/cdns3-imx.c +++ b/drivers/usb/cdns3/cdns3-imx.c @@ -185,7 +185,11 @@ static int cdns_imx_probe(struct platform_device *pdev) } data->num_clks = ARRAY_SIZE(imx_cdns3_core_clks); - data->clks = (struct clk_bulk_data *)imx_cdns3_core_clks; + data->clks = devm_kmemdup(dev, imx_cdns3_core_clks, + sizeof(imx_cdns3_core_clks), GFP_KERNEL); + if (!data->clks) + return -ENOMEM; + ret = devm_clk_bulk_get(dev, data->num_clks, data->clks); if (ret) return ret; -- GitLab From 2ef02b846ee2526249a562a66d6dcb25fcbca9d8 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 10 Dec 2020 21:31:37 +0800 Subject: [PATCH 0016/1084] usb: cdns3: imx: fix can't create core device the second time issue The cdns3 core device is populated by calling of_platform_populate, the flag OF_POPULATED is set for core device node, if this flag is not cleared, when calling of_platform_populate the second time after loading parent module again, the OF code will not try to create platform device for core device. To fix it, it uses of_platform_depopulate to depopulate the core device which the parent created, and the flag OF_POPULATED for core device node will be cleared accordingly. Cc: Fixes: 1e056efab993 ("usb: cdns3: add NXP imx8qm glue layer") Signed-off-by: Peter Chen --- drivers/usb/cdns3/cdns3-imx.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/usb/cdns3/cdns3-imx.c b/drivers/usb/cdns3/cdns3-imx.c index 4d3fedc867530..6b358e8be5799 100644 --- a/drivers/usb/cdns3/cdns3-imx.c +++ b/drivers/usb/cdns3/cdns3-imx.c @@ -218,20 +218,11 @@ static int cdns_imx_probe(struct platform_device *pdev) return ret; } -static int cdns_imx_remove_core(struct device *dev, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - - platform_device_unregister(pdev); - - return 0; -} - static int cdns_imx_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - device_for_each_child(dev, NULL, cdns_imx_remove_core); + of_platform_depopulate(dev); platform_set_drvdata(pdev, NULL); return 0; -- GitLab From d1357119157c4662d43143885f3691f9a766369a Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 10 Dec 2020 21:33:21 +0800 Subject: [PATCH 0017/1084] usb: cdns3: imx: improve driver .remove API Keep the runtime active during the remove operation, and disable related clocks. Signed-off-by: Peter Chen --- drivers/usb/cdns3/cdns3-imx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/cdns3/cdns3-imx.c b/drivers/usb/cdns3/cdns3-imx.c index 6b358e8be5799..7990fee03fe4b 100644 --- a/drivers/usb/cdns3/cdns3-imx.c +++ b/drivers/usb/cdns3/cdns3-imx.c @@ -221,8 +221,13 @@ static int cdns_imx_probe(struct platform_device *pdev) static int cdns_imx_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct cdns_imx *data = dev_get_drvdata(dev); + pm_runtime_get_sync(dev); of_platform_depopulate(dev); + clk_bulk_disable_unprepare(data->num_clks, data->clks); + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); platform_set_drvdata(pdev, NULL); return 0; -- GitLab From 65403ff98ebb86caf498e020d572819bb61860ad Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Fri, 18 Dec 2020 12:57:36 +0200 Subject: [PATCH 0018/1084] MAINTAINERS: Update address for Cadence USB3 driver Updates my email address for Cadence USB3 driver. Signed-off-by: Roger Quadros Signed-off-by: Peter Chen --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 546aa66428c9f..afe3a5c66bc90 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3883,7 +3883,7 @@ F: drivers/mtd/nand/raw/cadence-nand-controller.c CADENCE USB3 DRD IP DRIVER M: Peter Chen M: Pawel Laszczak -M: Roger Quadros +R: Roger Quadros R: Aswath Govindraju L: linux-usb@vger.kernel.org S: Maintained -- GitLab From 49d411f2c93aae48dd379c77db887aa282e9fb51 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 29 Dec 2020 09:51:03 +0100 Subject: [PATCH 0019/1084] ASoC: Intel: common: Fix some typos s/apci/acpi/ Turn an ICL into a TGL because it is likely a cut'n'paste error Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/20201229085103.192715-1-christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-ehl-match.c | 2 +- sound/soc/intel/common/soc-acpi-intel-tgl-match.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c index badafc1d54d20..5c7a1214403d3 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * soc-apci-intel-ehl-match.c - tables and support for EHL ACPI enumeration. + * soc-acpi-intel-ehl-match.c - tables and support for EHL ACPI enumeration. * * Copyright (c) 2019, Intel Corporation. * diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c index 98196e9fad62f..4933184df5f50 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * soc-apci-intel-tgl-match.c - tables and support for ICL ACPI enumeration. + * soc-acpi-intel-tgl-match.c - tables and support for TGL ACPI enumeration. * * Copyright (c) 2019, Intel Corporation. * -- GitLab From 4ac275eda0d7bf6f222ad0093ffbdfd2f4228eaa Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Thu, 24 Dec 2020 18:06:03 +0800 Subject: [PATCH 0020/1084] ASoC: rt1015: sort header inclusions Sorts header inclusions. ASCII value of 'r' is less than 's'. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20201224100607.3006171-2-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1015.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 5fdf7bbfd375f..e78364f54451e 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -24,10 +24,10 @@ #include #include #include +#include #include #include #include -#include #include "rl6231.h" #include "rt1015.h" -- GitLab From bf1eb056ac15a058fb5e254307f14f45efbe79d8 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Thu, 24 Dec 2020 18:06:04 +0800 Subject: [PATCH 0021/1084] ASoC: rt1015: save boost_mode only if valid Saves boost_mode only if valid. Also returns -EINVAL if it is invalid. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20201224100607.3006171-3-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1015.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index e78364f54451e..3b9db3a1a3bc7 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -444,10 +444,9 @@ static int rt1015_boost_mode_put(struct snd_kcontrol *kcontrol, snd_soc_kcontrol_component(kcontrol); struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component); + int boost_mode = ucontrol->value.integer.value[0]; - rt1015->boost_mode = ucontrol->value.integer.value[0]; - - switch (rt1015->boost_mode) { + switch (boost_mode) { case BYPASS: snd_soc_component_update_bits(component, RT1015_SMART_BST_CTRL1, RT1015_ABST_AUTO_EN_MASK | @@ -471,8 +470,11 @@ static int rt1015_boost_mode_put(struct snd_kcontrol *kcontrol, break; default: dev_err(component->dev, "Unknown boost control.\n"); + return -EINVAL; } + rt1015->boost_mode = boost_mode; + return 0; } -- GitLab From e48b41e903a102744827661080acd500b7bbef26 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Thu, 24 Dec 2020 18:06:05 +0800 Subject: [PATCH 0022/1084] ASoC: rt1015: return error if any when setting bypass_boost Returns -EBUSY if DAC is using when setting bypass_boost. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20201224100607.3006171-4-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1015.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 3b9db3a1a3bc7..aab5c1b0ece55 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -528,17 +528,19 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component); - if (!rt1015->dac_is_used) { - rt1015->bypass_boost = ucontrol->value.integer.value[0]; - if (rt1015->bypass_boost == RT1015_Bypass_Boost && + if (rt1015->dac_is_used) { + dev_err(component->dev, "DAC is being used!\n"); + return -EBUSY; + } + + rt1015->bypass_boost = ucontrol->value.integer.value[0]; + if (rt1015->bypass_boost == RT1015_Bypass_Boost && !rt1015->cali_done) { - rt1015_calibrate(rt1015); - rt1015->cali_done = 1; + rt1015_calibrate(rt1015); + rt1015->cali_done = 1; - regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010); - } - } else - dev_err(component->dev, "DAC is being used!\n"); + regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010); + } return 0; } -- GitLab From 3128f1c3b53d73e35e1069663736284358fcdd01 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Thu, 24 Dec 2020 18:06:06 +0800 Subject: [PATCH 0023/1084] ASoC: rt1015: refactor retry loop and rt1015_priv allocation Refactors retry loop in flush DAC work. It is more clear to use a for-loop here. Uses !rt1015 to check if NULL. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20201224100607.3006171-5-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1015.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index aab5c1b0ece55..cc57529ea877e 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -550,15 +550,14 @@ static void rt1015_flush_work(struct work_struct *work) struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv, flush_work.work); struct snd_soc_component *component = rt1015->component; - unsigned int val, i = 0, count = 200; + unsigned int val, i; - while (i < count) { + for (i = 0; i < 200; ++i) { usleep_range(1000, 1500); dev_dbg(component->dev, "Flush DAC (retry:%u)\n", i); regmap_read(rt1015->regmap, RT1015_CLK_DET, &val); if (val & 0x800) break; - i++; } regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597); @@ -1167,9 +1166,8 @@ static int rt1015_i2c_probe(struct i2c_client *i2c, int ret; unsigned int val; - rt1015 = devm_kzalloc(&i2c->dev, sizeof(struct rt1015_priv), - GFP_KERNEL); - if (rt1015 == NULL) + rt1015 = devm_kzalloc(&i2c->dev, sizeof(*rt1015), GFP_KERNEL); + if (!rt1015) return -ENOMEM; i2c_set_clientdata(i2c, rt1015); -- GitLab From a5db2ca51367eeafb0c4013d3a6fc58932612c03 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Thu, 24 Dec 2020 18:06:07 +0800 Subject: [PATCH 0024/1084] ASoC: rt1015: remove unneeded variables in rt1015_priv - `lrck' is only used in .hw_params callback so that it can be local. - `bclk' is unused. - `id' is unused. - `amp_ver' is unused. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20201224100607.3006171-6-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1015.c | 9 ++++----- sound/soc/codecs/rt1015.h | 4 ---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index cc57529ea877e..bf452cc0096f4 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -704,11 +704,11 @@ static int rt1015_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component); - int pre_div, bclk_ms, frame_size; + int pre_div, bclk_ms, frame_size, lrck; unsigned int val_len = 0; - rt1015->lrck = params_rate(params); - pre_div = rl6231_get_clk_info(rt1015->sysclk, rt1015->lrck); + lrck = params_rate(params); + pre_div = rl6231_get_clk_info(rt1015->sysclk, lrck); if (pre_div < 0) { dev_err(component->dev, "Unsupported clock rate\n"); return -EINVAL; @@ -722,13 +722,12 @@ static int rt1015_hw_params(struct snd_pcm_substream *substream, } bclk_ms = frame_size > 32; - rt1015->bclk = rt1015->lrck * (32 << bclk_ms); dev_dbg(component->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", bclk_ms, pre_div, dai->id); dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d\n", - rt1015->lrck, pre_div, dai->id); + lrck, pre_div, dai->id); switch (params_width(params)) { case 16: diff --git a/sound/soc/codecs/rt1015.h b/sound/soc/codecs/rt1015.h index b6ea753014e1f..e9b498a754e0b 100644 --- a/sound/soc/codecs/rt1015.h +++ b/sound/soc/codecs/rt1015.h @@ -427,16 +427,12 @@ struct rt1015_priv { struct regmap *regmap; int sysclk; int sysclk_src; - int lrck; - int bclk; int bclk_ratio; - int id; int pll_src; int pll_in; int pll_out; int boost_mode; int bypass_boost; - int amp_ver; int dac_is_used; int cali_done; int hw_config; -- GitLab From 7078a5ba7a58e5db07583b176f8a03e0b8714731 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 8 Dec 2020 16:08:02 +0200 Subject: [PATCH 0025/1084] soc: ti: omap-prm: Fix boot time errors for rst_map_012 bits 0 and 1 We have rst_map_012 used for various accelerators like dsp, ipu and iva. For these use cases, we have rstctrl bit 2 control the subsystem module reset, and have and bits 0 and 1 control the accelerator specific features. If the bootloader, or kexec boot, has left any accelerator specific reset bits deasserted, deasserting bit 2 reset will potentially enable an accelerator with unconfigured MMU and no firmware. And we may get spammed with a lot by warnings on boot with "Data Access in User mode during Functional access", or depending on the accelerator, the system can also just hang. This issue can be quite easily reproduced by setting a rst_map_012 type rstctrl register to 0 or 4 in the bootloader, and booting the system. Let's just assert all reset bits for rst_map_012 type resets. So far it looks like the other rstctrl types don't need this. If it turns out that the other type rstctrl bits also need reset on init, we need to add an instance specific reset mask for the bits to avoid resetting unwanted bits. Reported-by: Carl Philipp Klemm Cc: Philipp Zabel Cc: Santosh Shilimkar Cc: Suman Anna Cc: Tero Kristo Tested-by: Carl Philipp Klemm Signed-off-by: Tony Lindgren --- drivers/soc/ti/omap_prm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c index 980b04c38fd94..3dc3f34afbab3 100644 --- a/drivers/soc/ti/omap_prm.c +++ b/drivers/soc/ti/omap_prm.c @@ -548,6 +548,7 @@ static int omap_prm_reset_init(struct platform_device *pdev, const struct omap_rst_map *map; struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev); char buf[32]; + u32 v; /* * Check if we have controllable resets. If either rstctrl is non-zero @@ -595,6 +596,16 @@ static int omap_prm_reset_init(struct platform_device *pdev, map++; } + /* Quirk handling to assert rst_map_012 bits on reset and avoid errors */ + if (prm->data->rstmap == rst_map_012) { + v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); + if ((v & reset->mask) != reset->mask) { + dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v); + writel_relaxed(reset->mask, reset->prm->base + + reset->prm->data->rstctrl); + } + } + return devm_reset_controller_register(&pdev->dev, &reset->rcdev); } -- GitLab From 181739822cf6f8f4e12b173913af2967a28906c0 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Wed, 23 Dec 2020 11:30:21 +0100 Subject: [PATCH 0026/1084] ARM: dts; gta04: SPI panel chip select is active low With the arrival of commit 2fee9583198eb9 ("spi: dt-bindings: clarify CS behavior for spi-cs-high and gpio descriptors") it was clarified what the proper state for cs-gpios should be, even if the flag is ignored. The driver code is doing the right thing since 766c6b63aa04 ("spi: fix client driver breakages when using GPIO descriptors") The chip-select of the td028ttec1 panel is active-low, so we must omit spi-cs-high; attribute (already removed by separate patch) and should now use GPIO_ACTIVE_LOW for the client device description to be fully consistent. Fixes: 766c6b63aa04 ("spi: fix client driver breakages when using GPIO descriptors") CC: stable@vger.kernel.org Signed-off-by: H. Nikolaus Schaller Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi index 003202d129907..7b8c18e6605e4 100644 --- a/arch/arm/boot/dts/omap3-gta04.dtsi +++ b/arch/arm/boot/dts/omap3-gta04.dtsi @@ -114,7 +114,7 @@ gpio-sck = <&gpio1 12 GPIO_ACTIVE_HIGH>; gpio-miso = <&gpio1 18 GPIO_ACTIVE_HIGH>; gpio-mosi = <&gpio1 20 GPIO_ACTIVE_HIGH>; - cs-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>; num-chipselects = <1>; /* lcd panel */ -- GitLab From e9141c1aaa72782b9de7b224cd184a809aa4a87f Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Wed, 30 Dec 2020 16:02:35 +0800 Subject: [PATCH 0027/1084] ASoC: rt5645: Remove the redundant delay time This patch removes the redundant delay time to speed up from the cold start of headphone playback. Signed-off-by: Oder Chiou Link: https://lore.kernel.org/r/20201230080235.12698-1-oder_chiou@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 420003d062c7f..1c9e61abda307 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -435,7 +435,6 @@ struct rt5645_priv { int jack_type; bool en_button_func; - bool hp_on; int v_id; }; @@ -1645,6 +1644,7 @@ static void hp_amp_power(struct snd_soc_component *component, int on) { static int hp_amp_power_count; struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); + int i, val; if (on) { if (hp_amp_power_count <= 0) { @@ -1655,7 +1655,13 @@ static void hp_amp_power(struct snd_soc_component *component, int on) snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d); regmap_write(rt5645->regmap, RT5645_PR_BASE + RT5645_HP_DCC_INT1, 0x9f01); - msleep(20); + for (i = 0; i < 20; i++) { + usleep_range(1000, 1500); + regmap_read(rt5645->regmap, RT5645_PR_BASE + + RT5645_HP_DCC_INT1, &val); + if (!(val & 0x8000)) + break; + } snd_soc_component_update_bits(component, RT5645_DEPOP_M1, RT5645_HP_CO_MASK, RT5645_HP_CO_EN); regmap_write(rt5645->regmap, RT5645_PR_BASE + @@ -1665,7 +1671,6 @@ static void hp_amp_power(struct snd_soc_component *component, int on) RT5645_MAMP_INT_REG2, 0xfc00); snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140); msleep(90); - rt5645->hp_on = true; } else { /* depop parameters */ snd_soc_component_update_bits(component, RT5645_DEPOP_M2, @@ -1885,27 +1890,6 @@ static int rt5645_bst2_event(struct snd_soc_dapm_widget *w, return 0; } -static int rt5650_hp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - if (rt5645->hp_on) { - msleep(100); - rt5645->hp_on = false; - } - break; - - default: - return 0; - } - - return 0; -} - static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { @@ -2242,7 +2226,6 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("PDM1R"), SND_SOC_DAPM_OUTPUT("SPOL"), SND_SOC_DAPM_OUTPUT("SPOR"), - SND_SOC_DAPM_POST("DAPM_POST", rt5650_hp_event), }; static const struct snd_soc_dapm_widget rt5645_specific_dapm_widgets[] = { -- GitLab From 5b5465dd947cb655550332d3fa509f91a768482b Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 21 Dec 2020 20:37:45 -0800 Subject: [PATCH 0028/1084] arm64: defconfig: Make INTERCONNECT_QCOM_SDM845 builtin As of v5.11-rc1 the QUP nodes of SDM845 has got their interconnect properties specified, this means that the relevant interconnect provider needs to be builtin for the UART device to probe and the console to be registered before userspace needs to access it. Reviewed-by: Georgi Djakov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20201222043745.3420447-1-bjorn.andersson@linaro.org Signed-off-by: Bjorn Andersson --- arch/arm64/configs/defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 838301650a794..3848ae99501c5 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1078,7 +1078,7 @@ CONFIG_INTERCONNECT=y CONFIG_INTERCONNECT_QCOM=y CONFIG_INTERCONNECT_QCOM_MSM8916=m CONFIG_INTERCONNECT_QCOM_OSM_L3=m -CONFIG_INTERCONNECT_QCOM_SDM845=m +CONFIG_INTERCONNECT_QCOM_SDM845=y CONFIG_INTERCONNECT_QCOM_SM8150=m CONFIG_INTERCONNECT_QCOM_SM8250=m CONFIG_EXT2_FS=y -- GitLab From 355845b738e76445c8522802552146d96cb4afa7 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Thu, 31 Dec 2020 06:10:32 +0100 Subject: [PATCH 0029/1084] efi/apple-properties: Reinstate support for boolean properties Since commit 4466bf82821b ("efi/apple-properties: use PROPERTY_ENTRY_U8_ARRAY_LEN"), my MacBook Pro issues a -ENODATA error when trying to assign EFI properties to the discrete GPU: pci 0000:01:00.0: assigning 56 device properties pci 0000:01:00.0: error -61 assigning properties That's because some of the properties have no value. They're booleans whose presence can be checked by drivers, e.g. "use-backlight-blanking". Commit 6e98503dba64 ("efi/apple-properties: Remove redundant attribute initialization from unmarshal_key_value_pairs()") employed a trick to store such booleans as u8 arrays (which is the data type used for all other EFI properties on Macs): It cleared the property_entry's "is_array" flag, thereby denoting that the value is stored inline in the property_entry. Commit 4466bf82821b erroneously removed that trick. It was probably a little fragile to begin with. Reinstate support for boolean properties by explicitly invoking the PROPERTY_ENTRY_BOOL() initializer for properties with zero-length value. Fixes: 4466bf82821b ("efi/apple-properties: use PROPERTY_ENTRY_U8_ARRAY_LEN") Cc: Reviewed-by: Andy Shevchenko Signed-off-by: Lukas Wunner Link: https://lore.kernel.org/r/be958bda75331a011d53c696d1deec8dccd06fd2.1609388549.git.lukas@wunner.de Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/apple-properties.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/efi/apple-properties.c b/drivers/firmware/efi/apple-properties.c index 34f53d898acb0..e1926483ae2fd 100644 --- a/drivers/firmware/efi/apple-properties.c +++ b/drivers/firmware/efi/apple-properties.c @@ -3,8 +3,9 @@ * apple-properties.c - EFI device properties on Macs * Copyright (C) 2016 Lukas Wunner * - * Note, all properties are considered as u8 arrays. - * To get a value of any of them the caller must use device_property_read_u8_array(). + * Properties are stored either as: + * u8 arrays which can be retrieved with device_property_read_u8_array() or + * booleans which can be queried with device_property_present(). */ #define pr_fmt(fmt) "apple-properties: " fmt @@ -88,8 +89,12 @@ static void __init unmarshal_key_value_pairs(struct dev_header *dev_header, entry_data = ptr + key_len + sizeof(val_len); entry_len = val_len - sizeof(val_len); - entry[i] = PROPERTY_ENTRY_U8_ARRAY_LEN(key, entry_data, - entry_len); + if (entry_len) + entry[i] = PROPERTY_ENTRY_U8_ARRAY_LEN(key, entry_data, + entry_len); + else + entry[i] = PROPERTY_ENTRY_BOOL(key); + if (dump_properties) { dev_info(dev, "property: %s\n", key); print_hex_dump(KERN_INFO, pr_fmt(), DUMP_PREFIX_OFFSET, -- GitLab From a0b653e89a3afd2a833f23589a83488fac842ddb Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Wed, 30 Dec 2020 17:24:26 +0000 Subject: [PATCH 0030/1084] ASoC: wm_adsp: Only use __be32 for big-endian data This fixes some minor cases where u32 or unsigned int types were used to store big-endian data, and __be32 types used to store both big-endian and cpu-endian data. This was producing sparse warnings. Most cases resulted from using the same variable to hold the big-endian value and its converted cpu-endian value. These can be simply fixed by introducing another local variable, or avoiding storing the intermediate value back into the original variable. One special case is the raw_buf used in the compressed streams to transfer data from DSP to user-side. The endian conversion happens in-place (as there's no point introducing another buffer) so a cast to (__be32 *) is added when passing it to wm_adsp_read_raw_data_block(). Signed-off-by: Richard Fitzgerald Link: https://lore.kernel.org/r/20201230172427.13865-1-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 5b7d81a91df3a..8cfa8ac1b8c4d 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -980,7 +980,7 @@ static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, unsigned int event_id) { struct wm_adsp *dsp = ctl->dsp; - u32 val = cpu_to_be32(event_id); + __be32 val = cpu_to_be32(event_id); unsigned int reg; int i, ret; @@ -3704,6 +3704,7 @@ static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, unsigned int mem_addr, u32 data) { struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); + __be32 val = cpu_to_be32(data & 0x00ffffffu); unsigned int reg; if (!mem) @@ -3711,9 +3712,7 @@ static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, reg = dsp->ops->region_to_reg(mem, mem_addr); - data = cpu_to_be32(data & 0x00ffffffu); - - return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data)); + return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); } static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, @@ -3870,7 +3869,8 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) { struct wm_adsp_host_buf_coeff_v1 coeff_v1; struct wm_adsp_compr_buf *buf; - unsigned int val, reg; + unsigned int reg, version; + __be32 bufp; int ret, i; ret = wm_coeff_base_reg(ctl, ®); @@ -3878,17 +3878,17 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) return ret; for (i = 0; i < 5; ++i) { - ret = regmap_raw_read(ctl->dsp->regmap, reg, &val, sizeof(val)); + ret = regmap_raw_read(ctl->dsp->regmap, reg, &bufp, sizeof(bufp)); if (ret < 0) return ret; - if (val) + if (bufp) break; usleep_range(1000, 2000); } - if (!val) { + if (!bufp) { adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); return -EIO; } @@ -3898,7 +3898,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) return -ENOMEM; buf->host_buf_mem_type = ctl->alg_region.type; - buf->host_buf_ptr = be32_to_cpu(val); + buf->host_buf_ptr = be32_to_cpu(bufp); ret = wm_adsp_buffer_populate(buf); if (ret < 0) @@ -3918,14 +3918,13 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) if (ret < 0) return ret; - coeff_v1.versions = be32_to_cpu(coeff_v1.versions); - val = coeff_v1.versions & HOST_BUF_COEFF_COMPAT_VER_MASK; - val >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; + version = be32_to_cpu(coeff_v1.versions) & HOST_BUF_COEFF_COMPAT_VER_MASK; + version >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; - if (val > HOST_BUF_COEFF_SUPPORTED_COMPAT_VER) { + if (version > HOST_BUF_COEFF_SUPPORTED_COMPAT_VER) { adsp_err(ctl->dsp, "Host buffer coeff ver %u > supported version %u\n", - val, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); + version, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); return -EINVAL; } @@ -3935,9 +3934,9 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) (char *)&coeff_v1.name); compr_dbg(buf, "host_buf_ptr=%x coeff version %u\n", - buf->host_buf_ptr, val); + buf->host_buf_ptr, version); - return val; + return version; } static int wm_adsp_buffer_init(struct wm_adsp *dsp) @@ -4269,7 +4268,7 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) /* Read data from DSP */ ret = wm_adsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, - nwords, compr->raw_buf); + nwords, (__be32 *)compr->raw_buf); if (ret < 0) return ret; -- GitLab From f6212e0ab3ff28d4e2e53a520496a052c241df39 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Wed, 30 Dec 2020 17:24:27 +0000 Subject: [PATCH 0031/1084] ASoC: wm_adsp: Use snd_ctl_elem_type_t for control types Sparse will complain about trying to convert between values declared as snd_ctl_elem_type_t and other types. This patch converts to consistently use snd_ctl_elem_type_t for control type values. A __force cast is needed in a couple of cases where the control type value is parsed out of a DSP data block. Signed-off-by: Richard Fitzgerald Link: https://lore.kernel.org/r/20201230172427.13865-2-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 12 +++++++----- sound/soc/codecs/wmfw.h | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 8cfa8ac1b8c4d..f8ad768364c23 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -619,7 +619,7 @@ struct wm_coeff_ctl { unsigned int set:1; struct soc_bytes_ext bytes_ext; unsigned int flags; - unsigned int type; + snd_ctl_elem_type_t type; }; static const char *wm_adsp_mem_region_name(unsigned int type) @@ -1420,7 +1420,7 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, const struct wm_adsp_alg_region *alg_region, unsigned int offset, unsigned int len, const char *subname, unsigned int subname_len, - unsigned int flags, unsigned int type) + unsigned int flags, snd_ctl_elem_type_t type) { struct wm_coeff_ctl *ctl; struct wmfw_ctl_work *ctl_work; @@ -1554,7 +1554,7 @@ struct wm_coeff_parsed_coeff { int mem_type; const u8 *name; int name_len; - int ctl_type; + snd_ctl_elem_type_t ctl_type; int flags; int len; }; @@ -1649,7 +1649,7 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, blk->mem_type = le16_to_cpu(raw->hdr.type); blk->name = raw->name; blk->name_len = strlen(raw->name); - blk->ctl_type = le16_to_cpu(raw->ctl_type); + blk->ctl_type = (__force snd_ctl_elem_type_t)le16_to_cpu(raw->ctl_type); blk->flags = le16_to_cpu(raw->flags); blk->len = le32_to_cpu(raw->len); break; @@ -1662,7 +1662,9 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, &blk->name); wm_coeff_parse_string(sizeof(u8), &tmp, NULL); wm_coeff_parse_string(sizeof(u16), &tmp, NULL); - blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); + blk->ctl_type = + (__force snd_ctl_elem_type_t)wm_coeff_parse_int(sizeof(raw->ctl_type), + &tmp); blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h index 7423272c30e94..f3d51602f85c7 100644 --- a/sound/soc/codecs/wmfw.h +++ b/sound/soc/codecs/wmfw.h @@ -24,9 +24,9 @@ #define WMFW_CTL_FLAG_READABLE 0x0001 /* Non-ALSA coefficient types start at 0x1000 */ -#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ -#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ -#define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */ +#define WMFW_CTL_TYPE_ACKED ((__force snd_ctl_elem_type_t)0x1000) /* acked control */ +#define WMFW_CTL_TYPE_HOSTEVENT ((__force snd_ctl_elem_type_t)0x1001) /* event control */ +#define WMFW_CTL_TYPE_HOST_BUFFER ((__force snd_ctl_elem_type_t)0x1002) /* host buffer pointer */ struct wmfw_header { char magic[4]; -- GitLab From c1cbbea9c4db41eb69a831d8b07da52e05b1d1e8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 30 Dec 2020 16:43:34 +0100 Subject: [PATCH 0032/1084] ASoC: mediatek: add MTK_PMIC_WRAP dependency Randconfig builds often show harmless warnings like WARNING: unmet direct dependencies detected for SND_SOC_MT6359 Depends on [n]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && MTK_PMIC_WRAP [=n] Selected by [y]: - SND_SOC_MT8192_MT6359_RT1015_RT5682 [=y] && SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && I2C [=y] && SND_SOC_MT8192 [=y] Add a dependency to avoid that. Signed-off-by: Arnd Bergmann Acked-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20201230154345.639122-1-arnd@kernel.org Signed-off-by: Mark Brown --- sound/soc/mediatek/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 8d3dcfb6a5802..effdb76369e42 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -172,7 +172,7 @@ config SND_SOC_MT8192 config SND_SOC_MT8192_MT6359_RT1015_RT5682 tristate "ASoC Audio driver for MT8192 with MT6359 RT1015 RT5682 codec" depends on I2C - depends on SND_SOC_MT8192 + depends on SND_SOC_MT8192 && MTK_PMIC_WRAP select SND_SOC_MT6359 select SND_SOC_RT1015 select SND_SOC_RT1015P -- GitLab From 928eedf013b25fcaeb6aef2ad721ed92c2e8bc66 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 1 Jan 2021 22:12:27 -0800 Subject: [PATCH 0033/1084] Input: st1232 - fix off-by-one error in resolution handling Before, the maximum coordinates were fixed to (799, 479) or (319, 479), depending on touchscreen controller type. The driver was changed to read the actual values from the touchscreen controller, but did not take into account the returned values are not the maximum coordinates, but the touchscreen resolution (e.g. 800 and 480). Fix this by subtracting 1. Fixes: 3a54a215410b1650 ("Input: st1232 - add support resolution reading") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20201229162601.2154566-2-geert+renesas@glider.be Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index bda96762744e6..f18d4c7e03da1 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -85,8 +85,8 @@ static int st1232_ts_read_resolution(struct st1232_ts_data *ts, u16 *max_x, buf = ts->read_buf; - *max_x = ((buf[0] & 0x0070) << 4) | buf[1]; - *max_y = ((buf[0] & 0x0007) << 8) | buf[2]; + *max_x = (((buf[0] & 0x0070) << 4) | buf[1]) - 1; + *max_y = (((buf[0] & 0x0007) << 8) | buf[2]) - 1; return 0; } -- GitLab From b999dbea06b9874c7724a410f47a6bac1e219e37 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 1 Jan 2021 22:13:13 -0800 Subject: [PATCH 0034/1084] Input: st1232 - do not read more bytes than needed st1232_ts_read_data() already reads ts->read_buf_len bytes (8 or 20 bytes) from the touchscreen controller. This was fine when it was used to read touch point coordinates only, but is overkill for reading the touchscreen resolution, which just needs 3 bytes. Optimize transfers by passing the wanted number of bytes. Fixes: 3a54a215410b1650 ("Input: st1232 - add support resolution reading") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20201229162601.2154566-3-geert+renesas@glider.be Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index f18d4c7e03da1..459701056f2bd 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -47,7 +47,8 @@ struct st1232_ts_data { u8 *read_buf; }; -static int st1232_ts_read_data(struct st1232_ts_data *ts, u8 reg) +static int st1232_ts_read_data(struct st1232_ts_data *ts, u8 reg, + unsigned int n) { struct i2c_client *client = ts->client; struct i2c_msg msg[] = { @@ -59,7 +60,7 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts, u8 reg) { .addr = client->addr, .flags = I2C_M_RD | I2C_M_DMA_SAFE, - .len = ts->read_buf_len, + .len = n, .buf = ts->read_buf, } }; @@ -79,7 +80,7 @@ static int st1232_ts_read_resolution(struct st1232_ts_data *ts, u16 *max_x, int error; /* select resolution register */ - error = st1232_ts_read_data(ts, REG_XY_RESOLUTION); + error = st1232_ts_read_data(ts, REG_XY_RESOLUTION, 3); if (error) return error; @@ -140,7 +141,7 @@ static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) int count; int error; - error = st1232_ts_read_data(ts, REG_XY_COORDINATES); + error = st1232_ts_read_data(ts, REG_XY_COORDINATES, ts->read_buf_len); if (error) goto out; -- GitLab From f605be6a57b439df7568a865c187b81863018c95 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 1 Jan 2021 22:15:15 -0800 Subject: [PATCH 0035/1084] Input: st1232 - wait until device is ready before reading resolution According to the st1232 datasheet, the host has to wait for the device to change into Normal state before accessing registers other than the Status Register. If the reset GPIO is wired, the device is powered on during driver probe, just before reading the resolution. However, the latter may happen before the device is ready, leading to a probe failure: st1232-ts 1-0055: Failed to read resolution: -6 Fix this by waiting until the device is ready, by trying to read the Status Register until it indicates so, or until timeout. On Armadillo 800 EVA, typically the first read fails with an I2C transfer error, while the second read indicates the device is ready. Fixes: 3a54a215410b1650 ("Input: st1232 - add support resolution reading") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20201229162601.2154566-4-geert+renesas@glider.be Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 459701056f2bd..b4e7bcbe9b91d 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -26,6 +26,20 @@ #define ST1232_TS_NAME "st1232-ts" #define ST1633_TS_NAME "st1633-ts" +#define REG_STATUS 0x01 /* Device Status | Error Code */ + +#define STATUS_NORMAL 0x00 +#define STATUS_INIT 0x01 +#define STATUS_ERROR 0x02 +#define STATUS_AUTO_TUNING 0x03 +#define STATUS_IDLE 0x04 +#define STATUS_POWER_DOWN 0x05 + +#define ERROR_NONE 0x00 +#define ERROR_INVALID_ADDRESS 0x10 +#define ERROR_INVALID_VALUE 0x20 +#define ERROR_INVALID_PLATFORM 0x30 + #define REG_XY_RESOLUTION 0x04 #define REG_XY_COORDINATES 0x12 #define ST_TS_MAX_FINGERS 10 @@ -73,6 +87,22 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts, u8 reg, return 0; } +static int st1232_ts_wait_ready(struct st1232_ts_data *ts) +{ + unsigned int retries; + int error; + + for (retries = 10; retries; retries--) { + error = st1232_ts_read_data(ts, REG_STATUS, 1); + if (!error && ts->read_buf[0] == (STATUS_NORMAL | ERROR_NONE)) + return 0; + + usleep_range(1000, 2000); + } + + return -ENXIO; +} + static int st1232_ts_read_resolution(struct st1232_ts_data *ts, u16 *max_x, u16 *max_y) { @@ -252,6 +282,11 @@ static int st1232_ts_probe(struct i2c_client *client, input_dev->name = "st1232-touchscreen"; input_dev->id.bustype = BUS_I2C; + /* Wait until device is ready */ + error = st1232_ts_wait_ready(ts); + if (error) + return error; + /* Read resolution from the chip */ error = st1232_ts_read_resolution(ts, &max_x, &max_y); if (error) { -- GitLab From 2e202ad873365513c6ad72e29a531071dffa498a Mon Sep 17 00:00:00 2001 From: Kent Gibson Date: Mon, 28 Dec 2020 00:10:40 +0800 Subject: [PATCH 0036/1084] gpiolib: cdev: fix frame size warning in gpio_ioctl() The kernel test robot reports the following warning in [1]: drivers/gpio/gpiolib-cdev.c: In function 'gpio_ioctl': >>drivers/gpio/gpiolib-cdev.c:1437:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=] Refactor gpio_ioctl() to handle each ioctl in its own helper function and so reduce the variables stored on the stack to those explicitly required to service the ioctl at hand. The lineinfo_get_v1() helper handles both the GPIO_GET_LINEINFO_IOCTL and GPIO_GET_LINEINFO_WATCH_IOCTL, as per the corresponding v2 implementation - lineinfo_get(). [1] https://lore.kernel.org/lkml/202012270910.VW3qc1ER-lkp@intel.com/ Fixes: aad955842d1c ("gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and GPIO_V2_GET_LINEINFO_WATCH_IOCTL") Reported-by: kernel test robot Signed-off-by: Kent Gibson Reviewed-by: Linus Walleij Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-cdev.c | 145 ++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 12b679ca552cc..1a7b51163528b 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -1979,6 +1979,21 @@ struct gpio_chardev_data { #endif }; +static int chipinfo_get(struct gpio_chardev_data *cdev, void __user *ip) +{ + struct gpio_device *gdev = cdev->gdev; + struct gpiochip_info chipinfo; + + memset(&chipinfo, 0, sizeof(chipinfo)); + + strscpy(chipinfo.name, dev_name(&gdev->dev), sizeof(chipinfo.name)); + strscpy(chipinfo.label, gdev->label, sizeof(chipinfo.label)); + chipinfo.lines = gdev->ngpio; + if (copy_to_user(ip, &chipinfo, sizeof(chipinfo))) + return -EFAULT; + return 0; +} + #ifdef CONFIG_GPIO_CDEV_V1 /* * returns 0 if the versions match, else the previously selected ABI version @@ -1993,6 +2008,41 @@ static int lineinfo_ensure_abi_version(struct gpio_chardev_data *cdata, return abiv; } + +static int lineinfo_get_v1(struct gpio_chardev_data *cdev, void __user *ip, + bool watch) +{ + struct gpio_desc *desc; + struct gpioline_info lineinfo; + struct gpio_v2_line_info lineinfo_v2; + + if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) + return -EFAULT; + + /* this doubles as a range check on line_offset */ + desc = gpiochip_get_desc(cdev->gdev->chip, lineinfo.line_offset); + if (IS_ERR(desc)) + return PTR_ERR(desc); + + if (watch) { + if (lineinfo_ensure_abi_version(cdev, 1)) + return -EPERM; + + if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines)) + return -EBUSY; + } + + gpio_desc_to_lineinfo(desc, &lineinfo_v2); + gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); + + if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { + if (watch) + clear_bit(lineinfo.line_offset, cdev->watched_lines); + return -EFAULT; + } + + return 0; +} #endif static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip, @@ -2030,6 +2080,22 @@ static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip, return 0; } +static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip) +{ + __u32 offset; + + if (copy_from_user(&offset, ip, sizeof(offset))) + return -EFAULT; + + if (offset >= cdev->gdev->ngpio) + return -EINVAL; + + if (!test_and_clear_bit(offset, cdev->watched_lines)) + return -EBUSY; + + return 0; +} + /* * gpio_ioctl() - ioctl handler for the GPIO chardev */ @@ -2037,80 +2103,24 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct gpio_chardev_data *cdev = file->private_data; struct gpio_device *gdev = cdev->gdev; - struct gpio_chip *gc = gdev->chip; void __user *ip = (void __user *)arg; - __u32 offset; /* We fail any subsequent ioctl():s when the chip is gone */ - if (!gc) + if (!gdev->chip) return -ENODEV; /* Fill in the struct and pass to userspace */ if (cmd == GPIO_GET_CHIPINFO_IOCTL) { - struct gpiochip_info chipinfo; - - memset(&chipinfo, 0, sizeof(chipinfo)); - - strscpy(chipinfo.name, dev_name(&gdev->dev), - sizeof(chipinfo.name)); - strscpy(chipinfo.label, gdev->label, - sizeof(chipinfo.label)); - chipinfo.lines = gdev->ngpio; - if (copy_to_user(ip, &chipinfo, sizeof(chipinfo))) - return -EFAULT; - return 0; + return chipinfo_get(cdev, ip); #ifdef CONFIG_GPIO_CDEV_V1 - } else if (cmd == GPIO_GET_LINEINFO_IOCTL) { - struct gpio_desc *desc; - struct gpioline_info lineinfo; - struct gpio_v2_line_info lineinfo_v2; - - if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) - return -EFAULT; - - /* this doubles as a range check on line_offset */ - desc = gpiochip_get_desc(gc, lineinfo.line_offset); - if (IS_ERR(desc)) - return PTR_ERR(desc); - - gpio_desc_to_lineinfo(desc, &lineinfo_v2); - gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); - - if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) - return -EFAULT; - return 0; } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) { return linehandle_create(gdev, ip); } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) { return lineevent_create(gdev, ip); - } else if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) { - struct gpio_desc *desc; - struct gpioline_info lineinfo; - struct gpio_v2_line_info lineinfo_v2; - - if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) - return -EFAULT; - - /* this doubles as a range check on line_offset */ - desc = gpiochip_get_desc(gc, lineinfo.line_offset); - if (IS_ERR(desc)) - return PTR_ERR(desc); - - if (lineinfo_ensure_abi_version(cdev, 1)) - return -EPERM; - - if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines)) - return -EBUSY; - - gpio_desc_to_lineinfo(desc, &lineinfo_v2); - gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo); - - if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) { - clear_bit(lineinfo.line_offset, cdev->watched_lines); - return -EFAULT; - } - - return 0; + } else if (cmd == GPIO_GET_LINEINFO_IOCTL || + cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) { + return lineinfo_get_v1(cdev, ip, + cmd == GPIO_GET_LINEINFO_WATCH_IOCTL); #endif /* CONFIG_GPIO_CDEV_V1 */ } else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL || cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) { @@ -2119,16 +2129,7 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } else if (cmd == GPIO_V2_GET_LINE_IOCTL) { return linereq_create(gdev, ip); } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) { - if (copy_from_user(&offset, ip, sizeof(offset))) - return -EFAULT; - - if (offset >= cdev->gdev->ngpio) - return -EINVAL; - - if (!test_and_clear_bit(offset, cdev->watched_lines)) - return -EBUSY; - - return 0; + return lineinfo_unwatch(cdev, ip); } return -EINVAL; } -- GitLab From a9164910c5ceed63551280a4a0b85d37ac2b19a5 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 2 Jan 2021 12:59:40 +0800 Subject: [PATCH 0037/1084] arm64: dts: qcom: c630: keep both touchpad devices enabled Indicated by AML code in ACPI table, the touchpad in-use could be found on two possible slave addresses on &i2c3, i.e. hid@15 and hid@2c. And which one is in-use can be determined by reading another address on the I2C bus. Unfortunately, for DT boot, there is currently no support in firmware to make this check and patch DT accordingly. This results in a non-functional touchpad on those C630 devices with hid@2c. As i2c-hid driver will stop probing the device if there is nothing on the slave address, we can actually keep both devices enabled in DT, and i2c-hid driver will only probe the existing one. The only problem is that we cannot set up pinctrl in both device nodes, as two devices with the same pinctrl will cause pin conflict that makes the second device fail to probe. Let's move the pinctrl state up to parent node to solve this problem. As the pinctrl state of parent node is already defined in sdm845.dtsi, it ends up with overwriting pinctrl-0 with i2c3_hid_active state added in there. Fixes: 11d0e4f28156 ("arm64: dts: qcom: c630: Polish i2c-hid devices") Signed-off-by: Shawn Guo Link: https://lore.kernel.org/r/20210102045940.26874-1-shawn.guo@linaro.org Signed-off-by: Bjorn Andersson --- arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts index 13fdd02cffe63..3be85161a54e3 100644 --- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts @@ -320,6 +320,8 @@ &i2c3 { status = "okay"; clock-frequency = <400000>; + /* Overwrite pinctrl-0 from sdm845.dtsi */ + pinctrl-0 = <&qup_i2c3_default &i2c3_hid_active>; tsel: hid@15 { compatible = "hid-over-i2c"; @@ -327,9 +329,6 @@ hid-descr-addr = <0x1>; interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>; - - pinctrl-names = "default"; - pinctrl-0 = <&i2c3_hid_active>; }; tsc2: hid@2c { @@ -338,11 +337,6 @@ hid-descr-addr = <0x20>; interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>; - - pinctrl-names = "default"; - pinctrl-0 = <&i2c3_hid_active>; - - status = "disabled"; }; }; -- GitLab From a3a9060ecad030e2c7903b2b258383d2c716b56c Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 3 Jan 2021 17:59:51 -0800 Subject: [PATCH 0038/1084] Input: i8042 - unbreak Pegatron C15B MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit g++ reports drivers/input/serio/i8042-x86ia64io.h:225:3: error: ‘.matches’ designator used multiple times in the same initializer list C99 semantics is that last duplicated initialiser wins, so DMI entry gets overwritten. Fixes: a48491c65b51 ("Input: i8042 - add ByteSpeed touchpad to noloop table") Signed-off-by: Alexey Dobriyan Acked-by: Po-Hsu Lin Link: https://lore.kernel.org/r/20201228072335.GA27766@localhost.localdomain Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 3a2dcf0805f12..c74b020796a94 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -219,6 +219,8 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"), DMI_MATCH(DMI_PRODUCT_NAME, "C15B"), }, + }, + { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"), DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"), -- GitLab From 60159e9e7bc7e528c103b6b6d47dfd83af29669c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 3 Jan 2021 17:43:04 -0800 Subject: [PATCH 0039/1084] Input: ili210x - implement pressure reporting for ILI251x The ILI251x seems to report pressure information in the 5th byte of each per-finger touch data element. On the available hardware, this information has the values ranging from 0x0 to 0xa, which is also matching the downstream example code. Report pressure information on the ILI251x. Signed-off-by: Marek Vasut Link: https://lore.kernel.org/r/20201224071238.160098-1-marex@denx.de Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 199cf3daec106..d8fccf048bf44 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -29,11 +29,13 @@ struct ili2xxx_chip { void *buf, size_t len); int (*get_touch_data)(struct i2c_client *client, u8 *data); bool (*parse_touch_data)(const u8 *data, unsigned int finger, - unsigned int *x, unsigned int *y); + unsigned int *x, unsigned int *y, + unsigned int *z); bool (*continue_polling)(const u8 *data, bool touch); unsigned int max_touches; unsigned int resolution; bool has_calibrate_reg; + bool has_pressure_reg; }; struct ili210x { @@ -82,7 +84,8 @@ static int ili210x_read_touch_data(struct i2c_client *client, u8 *data) static bool ili210x_touchdata_to_coords(const u8 *touchdata, unsigned int finger, - unsigned int *x, unsigned int *y) + unsigned int *x, unsigned int *y, + unsigned int *z) { if (touchdata[0] & BIT(finger)) return false; @@ -137,7 +140,8 @@ static int ili211x_read_touch_data(struct i2c_client *client, u8 *data) static bool ili211x_touchdata_to_coords(const u8 *touchdata, unsigned int finger, - unsigned int *x, unsigned int *y) + unsigned int *x, unsigned int *y, + unsigned int *z) { u32 data; @@ -169,7 +173,8 @@ static const struct ili2xxx_chip ili211x_chip = { static bool ili212x_touchdata_to_coords(const u8 *touchdata, unsigned int finger, - unsigned int *x, unsigned int *y) + unsigned int *x, unsigned int *y, + unsigned int *z) { u16 val; @@ -235,7 +240,8 @@ static int ili251x_read_touch_data(struct i2c_client *client, u8 *data) static bool ili251x_touchdata_to_coords(const u8 *touchdata, unsigned int finger, - unsigned int *x, unsigned int *y) + unsigned int *x, unsigned int *y, + unsigned int *z) { u16 val; @@ -245,6 +251,7 @@ static bool ili251x_touchdata_to_coords(const u8 *touchdata, *x = val & 0x3fff; *y = get_unaligned_be16(touchdata + 1 + (finger * 5) + 2); + *z = touchdata[1 + (finger * 5) + 4]; return true; } @@ -261,6 +268,7 @@ static const struct ili2xxx_chip ili251x_chip = { .continue_polling = ili251x_check_continue_polling, .max_touches = 10, .has_calibrate_reg = true, + .has_pressure_reg = true, }; static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) @@ -268,14 +276,16 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) struct input_dev *input = priv->input; int i; bool contact = false, touch; - unsigned int x = 0, y = 0; + unsigned int x = 0, y = 0, z = 0; for (i = 0; i < priv->chip->max_touches; i++) { - touch = priv->chip->parse_touch_data(touchdata, i, &x, &y); + touch = priv->chip->parse_touch_data(touchdata, i, &x, &y, &z); input_mt_slot(input, i); if (input_mt_report_slot_state(input, MT_TOOL_FINGER, touch)) { touchscreen_report_pos(input, &priv->prop, x, y, true); + if (priv->chip->has_pressure_reg) + input_report_abs(input, ABS_MT_PRESSURE, z); contact = true; } } @@ -437,6 +447,8 @@ static int ili210x_i2c_probe(struct i2c_client *client, max_xy = (chip->resolution ?: SZ_64K) - 1; input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0); + if (priv->chip->has_pressure_reg) + input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xa, 0, 0); touchscreen_parse_properties(input, true, &priv->prop); error = input_mt_init_slots(input, priv->chip->max_touches, -- GitLab From 764257d9069a9c19758b626cc1ba4ae079335d9e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 30 Dec 2020 12:21:05 +0200 Subject: [PATCH 0040/1084] phy: cpcap-usb: Fix warning for missing regulator_disable On deferred probe, we will get the following splat: cpcap-usb-phy cpcap-usb-phy.0: could not initialize VBUS or ID IIO: -517 WARNING: CPU: 0 PID: 21 at drivers/regulator/core.c:2123 regulator_put+0x68/0x78 ... (regulator_put) from [] (release_nodes+0x1b4/0x1fc) (release_nodes) from [] (really_probe+0x104/0x4a0) (really_probe) from [] (driver_probe_device+0x58/0xb4) Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20201230102105.11826-1-tony@atomide.com Signed-off-by: Vinod Koul --- drivers/phy/motorola/phy-cpcap-usb.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c index 442522ba487f0..4728e2bff6620 100644 --- a/drivers/phy/motorola/phy-cpcap-usb.c +++ b/drivers/phy/motorola/phy-cpcap-usb.c @@ -662,35 +662,42 @@ static int cpcap_usb_phy_probe(struct platform_device *pdev) generic_phy = devm_phy_create(ddata->dev, NULL, &ops); if (IS_ERR(generic_phy)) { error = PTR_ERR(generic_phy); - return PTR_ERR(generic_phy); + goto out_reg_disable; } phy_set_drvdata(generic_phy, ddata); phy_provider = devm_of_phy_provider_register(ddata->dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); + if (IS_ERR(phy_provider)) { + error = PTR_ERR(phy_provider); + goto out_reg_disable; + } error = cpcap_usb_init_optional_pins(ddata); if (error) - return error; + goto out_reg_disable; cpcap_usb_init_optional_gpios(ddata); error = cpcap_usb_init_iio(ddata); if (error) - return error; + goto out_reg_disable; error = cpcap_usb_init_interrupts(pdev, ddata); if (error) - return error; + goto out_reg_disable; usb_add_phy_dev(&ddata->phy); atomic_set(&ddata->active, 1); schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1)); return 0; + +out_reg_disable: + regulator_disable(ddata->vusb); + + return error; } static int cpcap_usb_phy_remove(struct platform_device *pdev) -- GitLab From d092bd9110494de3372722b317510b3692f1b2fe Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 3 Jan 2021 14:55:17 +0100 Subject: [PATCH 0041/1084] phy: mediatek: allow compile-testing the dsi phy Randconfig builds show another broken dependency: WARNING: unmet direct dependencies detected for PHY_MTK_MIPI_DSI Depends on [n]: ARCH_MEDIATEK [=n] && OF [=y] Selected by [m]: - DRM_MEDIATEK [=m] && HAS_IOMEM [=y] && DRM [=m] && (ARCH_MEDIATEK [=n] || ARM [=y] && COMPILE_TEST [=y]) && COMMON_CLK [=y] && HAVE_ARM_SMCCC [=y] && OF [=y] && MTK_MMSYS [=y] This is similar to the hdmi driver I fixed earlier, and I guess the common-clk bug would sooner or later also manifest here, so just use the exact same solution I chose for the other driver, and hope that any future drivers just copy it from here. Fixes: 90f80d95992f ("phy: mediatek: Move mtk_mipi_dsi_phy driver into drivers/phy/mediatek folder") Fixes: f5f6e01f9164 ("phy: mediatek: allow compile-testing the hdmi phy") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20210103135524.3678664-1-arnd@kernel.org Signed-off-by: Vinod Koul --- drivers/phy/mediatek/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig index d38def43b1bf6..55f8e6c048ab3 100644 --- a/drivers/phy/mediatek/Kconfig +++ b/drivers/phy/mediatek/Kconfig @@ -49,7 +49,9 @@ config PHY_MTK_HDMI config PHY_MTK_MIPI_DSI tristate "MediaTek MIPI-DSI Driver" - depends on ARCH_MEDIATEK && OF + depends on ARCH_MEDIATEK || COMPILE_TEST + depends on COMMON_CLK + depends on OF select GENERIC_PHY help Support MIPI DSI for Mediatek SoCs. -- GitLab From 9f8550e4bd9d78a8436c2061ad2530215f875376 Mon Sep 17 00:00:00 2001 From: Eyal Birger Date: Wed, 23 Dec 2020 17:00:46 +0200 Subject: [PATCH 0042/1084] xfrm: fix disable_xfrm sysctl when used on xfrm interfaces The disable_xfrm flag signals that xfrm should not be performed during routing towards a device before reaching device xmit. For xfrm interfaces this is usually desired as they perform the outbound policy lookup as part of their xmit using their if_id. Before this change enabling this flag on xfrm interfaces prevented them from xmitting as xfrm_lookup_with_ifid() would not perform a policy lookup in case the original dst had the DST_NOXFRM flag. This optimization is incorrect when the lookup is done by the xfrm interface xmit logic. Fix by performing policy lookup when invoked by xfrmi as if_id != 0. Similarly it's unlikely for the 'no policy exists on net' check to yield any performance benefits when invoked from xfrmi. Fixes: f203b76d7809 ("xfrm: Add virtual xfrm interfaces") Signed-off-by: Eyal Birger Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index d622c2548d229..2f84136af48ab 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -3078,8 +3078,8 @@ struct dst_entry *xfrm_lookup_with_ifid(struct net *net, xflo.flags = flags; /* To accelerate a bit... */ - if ((dst_orig->flags & DST_NOXFRM) || - !net->xfrm.policy_count[XFRM_POLICY_OUT]) + if (!if_id && ((dst_orig->flags & DST_NOXFRM) || + !net->xfrm.policy_count[XFRM_POLICY_OUT])) goto nopol; xdst = xfrm_bundle_lookup(net, fl, family, dir, &xflo, if_id); -- GitLab From afbc293add6466f8f3f0c3d944d85f53709c170f Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Sat, 26 Dec 2020 16:50:20 -0800 Subject: [PATCH 0043/1084] af_key: relax availability checks for skb size calculation xfrm_probe_algs() probes kernel crypto modules and changes the availability of struct xfrm_algo_desc. But there is a small window where ealg->available and aalg->available get changed between count_ah_combs()/count_esp_combs() and dump_ah_combs()/dump_esp_combs(), in this case we may allocate a smaller skb but later put a larger amount of data and trigger the panic in skb_put(). Fix this by relaxing the checks when counting the size, that is, skipping the test of ->available. We may waste some memory for a few of sizeof(struct sadb_comb), but it is still much better than a panic. Reported-by: syzbot+b2bf2652983d23734c5c@syzkaller.appspotmail.com Cc: Steffen Klassert Cc: Herbert Xu Signed-off-by: Cong Wang Signed-off-by: Steffen Klassert --- net/key/af_key.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/key/af_key.c b/net/key/af_key.c index c12dbc51ef5fe..ef9b4ac03e7b7 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2902,7 +2902,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t) break; if (!aalg->pfkey_supported) continue; - if (aalg_tmpl_set(t, aalg) && aalg->available) + if (aalg_tmpl_set(t, aalg)) sz += sizeof(struct sadb_comb); } return sz + sizeof(struct sadb_prop); @@ -2920,7 +2920,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t) if (!ealg->pfkey_supported) continue; - if (!(ealg_tmpl_set(t, ealg) && ealg->available)) + if (!(ealg_tmpl_set(t, ealg))) continue; for (k = 1; ; k++) { @@ -2931,7 +2931,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t) if (!aalg->pfkey_supported) continue; - if (aalg_tmpl_set(t, aalg) && aalg->available) + if (aalg_tmpl_set(t, aalg)) sz += sizeof(struct sadb_comb); } } -- GitLab From f6e9ceb7a7fc321a31a9dde93a99b7b4b016a3b3 Mon Sep 17 00:00:00 2001 From: Po-Hsu Lin Date: Wed, 30 Dec 2020 17:52:04 +0800 Subject: [PATCH 0044/1084] selftests: xfrm: fix test return value override issue in xfrm_policy.sh When running this xfrm_policy.sh test script, even with some cases marked as FAIL, the overall test result will still be PASS: $ sudo ./xfrm_policy.sh PASS: policy before exception matches FAIL: expected ping to .254 to fail (exceptions) PASS: direct policy matches (exceptions) PASS: policy matches (exceptions) FAIL: expected ping to .254 to fail (exceptions and block policies) PASS: direct policy matches (exceptions and block policies) PASS: policy matches (exceptions and block policies) FAIL: expected ping to .254 to fail (exceptions and block policies after hresh changes) PASS: direct policy matches (exceptions and block policies after hresh changes) PASS: policy matches (exceptions and block policies after hresh changes) FAIL: expected ping to .254 to fail (exceptions and block policies after hthresh change in ns3) PASS: direct policy matches (exceptions and block policies after hthresh change in ns3) PASS: policy matches (exceptions and block policies after hthresh change in ns3) FAIL: expected ping to .254 to fail (exceptions and block policies after htresh change to normal) PASS: direct policy matches (exceptions and block policies after htresh change to normal) PASS: policy matches (exceptions and block policies after htresh change to normal) PASS: policies with repeated htresh change $ echo $? 0 This is because the $lret in check_xfrm() is not a local variable. Therefore when a test failed in check_exceptions(), the non-zero $lret will later get reset to 0 when the next test calls check_xfrm(). With this fix, the final return value will be 1. Make it easier for testers to spot this failure. Fixes: 39aa6928d462d0 ("xfrm: policy: fix netlink/pf_key policy lookups") Signed-off-by: Po-Hsu Lin Acked-by: Florian Westphal Signed-off-by: Steffen Klassert --- tools/testing/selftests/net/xfrm_policy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/xfrm_policy.sh b/tools/testing/selftests/net/xfrm_policy.sh index 7a1bf94c5bd38..5922941e70c6c 100755 --- a/tools/testing/selftests/net/xfrm_policy.sh +++ b/tools/testing/selftests/net/xfrm_policy.sh @@ -202,7 +202,7 @@ check_xfrm() { # 1: iptables -m policy rule count != 0 rval=$1 ip=$2 - lret=0 + local lret=0 ip netns exec ns1 ping -q -c 1 10.0.2.$ip > /dev/null -- GitLab From da64ae2d35d3673233f0403b035d4c6acbf71965 Mon Sep 17 00:00:00 2001 From: Visa Hankala Date: Wed, 30 Dec 2020 16:15:53 +0000 Subject: [PATCH 0045/1084] xfrm: Fix wraparound in xfrm_policy_addr_delta() Use three-way comparison for address components to avoid integer wraparound in the result of xfrm_policy_addr_delta(). This ensures that the search trees are built and traversed correctly. Treat IPv4 and IPv6 similarly by returning 0 when prefixlen == 0. Prefix /0 has only one equivalence class. Fixes: 9cf545ebd591d ("xfrm: policy: store inexact policies in a tree ordered by destination address") Signed-off-by: Visa Hankala Acked-by: Florian Westphal Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_policy.c | 26 +++++++++---- tools/testing/selftests/net/xfrm_policy.sh | 43 ++++++++++++++++++++++ 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2f84136af48ab..b74f28cabe24f 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -793,15 +793,22 @@ static int xfrm_policy_addr_delta(const xfrm_address_t *a, const xfrm_address_t *b, u8 prefixlen, u16 family) { + u32 ma, mb, mask; unsigned int pdw, pbi; int delta = 0; switch (family) { case AF_INET: - if (sizeof(long) == 4 && prefixlen == 0) - return ntohl(a->a4) - ntohl(b->a4); - return (ntohl(a->a4) & ((~0UL << (32 - prefixlen)))) - - (ntohl(b->a4) & ((~0UL << (32 - prefixlen)))); + if (prefixlen == 0) + return 0; + mask = ~0U << (32 - prefixlen); + ma = ntohl(a->a4) & mask; + mb = ntohl(b->a4) & mask; + if (ma < mb) + delta = -1; + else if (ma > mb) + delta = 1; + break; case AF_INET6: pdw = prefixlen >> 5; pbi = prefixlen & 0x1f; @@ -812,10 +819,13 @@ static int xfrm_policy_addr_delta(const xfrm_address_t *a, return delta; } if (pbi) { - u32 mask = ~0u << (32 - pbi); - - delta = (ntohl(a->a6[pdw]) & mask) - - (ntohl(b->a6[pdw]) & mask); + mask = ~0U << (32 - pbi); + ma = ntohl(a->a6[pdw]) & mask; + mb = ntohl(b->a6[pdw]) & mask; + if (ma < mb) + delta = -1; + else if (ma > mb) + delta = 1; } break; default: diff --git a/tools/testing/selftests/net/xfrm_policy.sh b/tools/testing/selftests/net/xfrm_policy.sh index 5922941e70c6c..bdf450eaf60cf 100755 --- a/tools/testing/selftests/net/xfrm_policy.sh +++ b/tools/testing/selftests/net/xfrm_policy.sh @@ -287,6 +287,47 @@ check_hthresh_repeat() return 0 } +# insert non-overlapping policies in a random order and check that +# all of them can be fetched using the traffic selectors. +check_random_order() +{ + local ns=$1 + local log=$2 + + for i in $(seq 100); do + ip -net $ns xfrm policy flush + for j in $(seq 0 16 255 | sort -R); do + ip -net $ns xfrm policy add dst $j.0.0.0/24 dir out priority 10 action allow + done + for j in $(seq 0 16 255); do + if ! ip -net $ns xfrm policy get dst $j.0.0.0/24 dir out > /dev/null; then + echo "FAIL: $log" 1>&2 + return 1 + fi + done + done + + for i in $(seq 100); do + ip -net $ns xfrm policy flush + for j in $(seq 0 16 255 | sort -R); do + local addr=$(printf "e000:0000:%02x00::/56" $j) + ip -net $ns xfrm policy add dst $addr dir out priority 10 action allow + done + for j in $(seq 0 16 255); do + local addr=$(printf "e000:0000:%02x00::/56" $j) + if ! ip -net $ns xfrm policy get dst $addr dir out > /dev/null; then + echo "FAIL: $log" 1>&2 + return 1 + fi + done + done + + ip -net $ns xfrm policy flush + + echo "PASS: $log" + return 0 +} + #check for needed privileges if [ "$(id -u)" -ne 0 ];then echo "SKIP: Need root privileges" @@ -438,6 +479,8 @@ check_exceptions "exceptions and block policies after htresh change to normal" check_hthresh_repeat "policies with repeated htresh change" +check_random_order ns3 "policies inserted in random order" + for i in 1 2 3 4;do ip netns del ns$i;done exit $ret -- GitLab From 896111dc4bcf887b835b3ef54f48b450d4692a1d Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sun, 20 Dec 2020 13:29:54 +0100 Subject: [PATCH 0046/1084] media: rc: ensure that uevent can be read directly after rc device register There is a race condition where if the /sys/class/rc0/uevent file is read before rc_dev->registered is set to true, -ENODEV will be returned. Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1901089 Cc: stable@vger.kernel.org Fixes: a2e2d73fa281 ("media: rc: do not access device via sysfs after rc_unregister_device()") Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 1d811e5ffb557..29d4d01896ff6 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1928,6 +1928,8 @@ int rc_register_device(struct rc_dev *dev) goto out_raw; } + dev->registered = true; + rc = device_add(&dev->dev); if (rc) goto out_rx_free; @@ -1937,8 +1939,6 @@ int rc_register_device(struct rc_dev *dev) dev->device_name ?: "Unspecified device", path ?: "N/A"); kfree(path); - dev->registered = true; - /* * once the the input device is registered in rc_setup_rx_device, * userspace can open the input device and rc_open() will be called -- GitLab From 4883a60c17eda6bf52d1c817ee7ead65b4a02da2 Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Mon, 21 Dec 2020 11:00:13 +0100 Subject: [PATCH 0047/1084] mtd: rawnand: gpmi: fix dst bit offset when extracting raw payload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-add the multiply by 8 to "step * eccsize" to correct the destination bit offset when extracting the data payload in gpmi_ecc_read_page_raw(). Fixes: e5e5631cc889 ("mtd: rawnand: gpmi: Use nand_extract_bits()") Cc: stable@vger.kernel.org Reported-by: Martin Hundebøll Signed-off-by: Sean Nyekjaer Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20201221100013.2715675-1-sean@geanix.com --- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index 5cdf05bcbf8fa..3fa8c22d3f36a 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -1615,7 +1615,7 @@ static int gpmi_ecc_read_page_raw(struct nand_chip *chip, uint8_t *buf, /* Extract interleaved payload data and ECC bits */ for (step = 0; step < nfc_geo->ecc_chunk_count; step++) { if (buf) - nand_extract_bits(buf, step * eccsize, tmp_buf, + nand_extract_bits(buf, step * eccsize * 8, tmp_buf, src_bit_off, eccsize * 8); src_bit_off += eccsize * 8; -- GitLab From e33c93b2206fedee35df756940e07af7b1f29768 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Thu, 17 Dec 2020 10:27:40 -0600 Subject: [PATCH 0048/1084] ASoC: wm8962: Add optional mclk device tree binding The driver can request an optional clock for mclk. Update the txt file to reflect this. Suggested-by: Geert Uytterhoeven Signed-off-by: Adam Ford Acked-by: Charles Keepax Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201217162740.1452000-1-aford173@gmail.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/wm8962.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/wm8962.txt b/Documentation/devicetree/bindings/sound/wm8962.txt index dcfa9a3369fde..c36c649ddfd04 100644 --- a/Documentation/devicetree/bindings/sound/wm8962.txt +++ b/Documentation/devicetree/bindings/sound/wm8962.txt @@ -9,6 +9,9 @@ Required properties: - reg : the I2C address of the device. Optional properties: + + - clocks : The clock source of the mclk + - spk-mono: This is a boolean property. If present, the SPK_MONO bit of R51 (Class D Control 2) gets set, indicating that the speaker is in mono mode. @@ -27,6 +30,7 @@ Example: wm8962: codec@1a { compatible = "wlf,wm8962"; reg = <0x1a>; + clocks = <&clks IMX6QDL_CLK_CKO>; gpio-cfg = < 0x0000 /* 0:Default */ -- GitLab From a1f31cc4e98e1833f53fd2c6e9a218d6b86f5388 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 3 Jan 2021 14:53:17 +0100 Subject: [PATCH 0049/1084] ASoC: fsl_aud2htx: select SND_SOC_IMX_PCM_DMA The newly added driver requires DMA support and fails to build when that is disabled: aarch64-linux-ld: sound/soc/fsl/fsl_aud2htx.o: in function `fsl_aud2htx_probe': fsl_aud2htx.c:(.text+0x3e0): undefined reference to `imx_pcm_dma_init' Fixes: 8a24c834c053 ("ASoC: fsl_aud2htx: Add aud2htx module driver") Signed-off-by: Arnd Bergmann Acked-by: Nicolin Chen Link: https://lore.kernel.org/r/20210103135327.3630973-1-arnd@kernel.org Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 84db0b7b9d593..d7f30036d4343 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -108,6 +108,7 @@ config SND_SOC_FSL_XCVR config SND_SOC_FSL_AUD2HTX tristate "AUDIO TO HDMI TX module support" depends on ARCH_MXC || COMPILE_TEST + select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n help Say Y if you want to add AUDIO TO HDMI TX support for NXP. -- GitLab From 9a85c09a3f507b925d75cb0c7c8f364467038052 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Fri, 11 Dec 2020 23:28:09 +0000 Subject: [PATCH 0050/1084] pinctrl: ingenic: Fix JZ4760 support - JZ4760 and JZ4760B have a similar register layout as the JZ4740, and don't use the new register layout, which was introduced with the JZ4770 SoC and not the JZ4760 or JZ4760B SoCs. - The JZ4740 code path only expected two function modes to be configurable for each pin, and wouldn't work with more than two. Fix it for the JZ4760, which has four configurable function modes. Fixes: 0257595a5cf4 ("pinctrl: Ingenic: Add pinctrl driver for JZ4760 and JZ4760B.") Cc: # 5.3 Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20201211232810.261565-1-paul@crapouillou.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 53a6a24bd0527..8ac3091c44691 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -1688,7 +1688,7 @@ static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip *jzgc, static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc, u8 offset, int value) { - if (jzgc->jzpc->info->version >= ID_JZ4760) + if (jzgc->jzpc->info->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_PAT0, offset, !!value); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value); @@ -1718,7 +1718,7 @@ static void irq_set_type(struct ingenic_gpio_chip *jzgc, break; } - if (jzgc->jzpc->info->version >= ID_JZ4760) { + if (jzgc->jzpc->info->version >= ID_JZ4770) { reg1 = JZ4760_GPIO_PAT1; reg2 = JZ4760_GPIO_PAT0; } else { @@ -1758,7 +1758,7 @@ static void ingenic_gpio_irq_enable(struct irq_data *irqd) struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc); int irq = irqd->hwirq; - if (jzgc->jzpc->info->version >= ID_JZ4760) + if (jzgc->jzpc->info->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, true); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true); @@ -1774,7 +1774,7 @@ static void ingenic_gpio_irq_disable(struct irq_data *irqd) ingenic_gpio_irq_mask(irqd); - if (jzgc->jzpc->info->version >= ID_JZ4760) + if (jzgc->jzpc->info->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, false); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false); @@ -1799,7 +1799,7 @@ static void ingenic_gpio_irq_ack(struct irq_data *irqd) irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_HIGH); } - if (jzgc->jzpc->info->version >= ID_JZ4760) + if (jzgc->jzpc->info->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_FLAG, irq, false); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true); @@ -1856,7 +1856,7 @@ static void ingenic_gpio_irq_handler(struct irq_desc *desc) chained_irq_enter(irq_chip, desc); - if (jzgc->jzpc->info->version >= ID_JZ4760) + if (jzgc->jzpc->info->version >= ID_JZ4770) flag = ingenic_gpio_read_reg(jzgc, JZ4760_GPIO_FLAG); else flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG); @@ -1938,7 +1938,7 @@ static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) struct ingenic_pinctrl *jzpc = jzgc->jzpc; unsigned int pin = gc->base + offset; - if (jzpc->info->version >= ID_JZ4760) { + if (jzpc->info->version >= ID_JZ4770) { if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_INT) || ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1)) return GPIO_LINE_DIRECTION_IN; @@ -1996,7 +1996,7 @@ static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc, ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2); ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1); ingenic_shadow_config_pin_load(jzpc, pin); - } else if (jzpc->info->version >= ID_JZ4760) { + } else if (jzpc->info->version >= ID_JZ4770) { ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false); ingenic_config_pin(jzpc, pin, GPIO_MSK, false); ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2); @@ -2004,7 +2004,7 @@ static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc, } else { ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true); ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2); - ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0); + ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func & 0x1); } return 0; @@ -2061,7 +2061,7 @@ static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, true); ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input); ingenic_shadow_config_pin_load(jzpc, pin); - } else if (jzpc->info->version >= ID_JZ4760) { + } else if (jzpc->info->version >= ID_JZ4770) { ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false); ingenic_config_pin(jzpc, pin, GPIO_MSK, true); ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input); @@ -2091,7 +2091,7 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev, unsigned int offt = pin / PINS_PER_GPIO_CHIP; bool pull; - if (jzpc->info->version >= ID_JZ4760) + if (jzpc->info->version >= ID_JZ4770) pull = !ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PEN); else pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS); @@ -2141,7 +2141,7 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc, REG_SET(X1830_GPIO_PEH), bias << idxh); } - } else if (jzpc->info->version >= ID_JZ4760) { + } else if (jzpc->info->version >= ID_JZ4770) { ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PEN, !bias); } else { ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !bias); @@ -2151,7 +2151,7 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc, static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc, unsigned int pin, bool high) { - if (jzpc->info->version >= ID_JZ4760) + if (jzpc->info->version >= ID_JZ4770) ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, high); else ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DATA, high); -- GitLab From b4aa4876e58d12fb3ace425969dcbf4df37aa254 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Fri, 11 Dec 2020 23:28:10 +0000 Subject: [PATCH 0051/1084] pinctrl: ingenic: Rename registers from JZ4760_GPIO_* to JZ4770_GPIO_* Now that JZ4760 support has been fixed, it looks wrong to have JZ4760_GPIO_* registers being written if the SoC is a JZ4770 or later. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20201211232810.261565-2-paul@crapouillou.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 54 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 8ac3091c44691..3ea163498647f 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -37,11 +37,11 @@ #define JZ4740_GPIO_TRIG 0x70 #define JZ4740_GPIO_FLAG 0x80 -#define JZ4760_GPIO_INT 0x10 -#define JZ4760_GPIO_PAT1 0x30 -#define JZ4760_GPIO_PAT0 0x40 -#define JZ4760_GPIO_FLAG 0x50 -#define JZ4760_GPIO_PEN 0x70 +#define JZ4770_GPIO_INT 0x10 +#define JZ4770_GPIO_PAT1 0x30 +#define JZ4770_GPIO_PAT0 0x40 +#define JZ4770_GPIO_FLAG 0x50 +#define JZ4770_GPIO_PEN 0x70 #define X1830_GPIO_PEL 0x110 #define X1830_GPIO_PEH 0x120 @@ -1689,7 +1689,7 @@ static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc, u8 offset, int value) { if (jzgc->jzpc->info->version >= ID_JZ4770) - ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_PAT0, offset, !!value); + ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value); } @@ -1719,8 +1719,8 @@ static void irq_set_type(struct ingenic_gpio_chip *jzgc, } if (jzgc->jzpc->info->version >= ID_JZ4770) { - reg1 = JZ4760_GPIO_PAT1; - reg2 = JZ4760_GPIO_PAT0; + reg1 = JZ4770_GPIO_PAT1; + reg2 = JZ4770_GPIO_PAT0; } else { reg1 = JZ4740_GPIO_TRIG; reg2 = JZ4740_GPIO_DIR; @@ -1759,7 +1759,7 @@ static void ingenic_gpio_irq_enable(struct irq_data *irqd) int irq = irqd->hwirq; if (jzgc->jzpc->info->version >= ID_JZ4770) - ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, true); + ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, true); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true); @@ -1775,7 +1775,7 @@ static void ingenic_gpio_irq_disable(struct irq_data *irqd) ingenic_gpio_irq_mask(irqd); if (jzgc->jzpc->info->version >= ID_JZ4770) - ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, false); + ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, false); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false); } @@ -1800,7 +1800,7 @@ static void ingenic_gpio_irq_ack(struct irq_data *irqd) } if (jzgc->jzpc->info->version >= ID_JZ4770) - ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_FLAG, irq, false); + ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true); } @@ -1857,7 +1857,7 @@ static void ingenic_gpio_irq_handler(struct irq_desc *desc) chained_irq_enter(irq_chip, desc); if (jzgc->jzpc->info->version >= ID_JZ4770) - flag = ingenic_gpio_read_reg(jzgc, JZ4760_GPIO_FLAG); + flag = ingenic_gpio_read_reg(jzgc, JZ4770_GPIO_FLAG); else flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG); @@ -1939,8 +1939,8 @@ static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) unsigned int pin = gc->base + offset; if (jzpc->info->version >= ID_JZ4770) { - if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_INT) || - ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1)) + if (ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_INT) || + ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PAT1)) return GPIO_LINE_DIRECTION_IN; return GPIO_LINE_DIRECTION_OUT; } @@ -1991,16 +1991,16 @@ static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc, 'A' + offt, idx, func); if (jzpc->info->version >= ID_X1000) { - ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_INT, false); + ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_INT, false); ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, false); - ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2); - ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1); + ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2); + ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1); ingenic_shadow_config_pin_load(jzpc, pin); } else if (jzpc->info->version >= ID_JZ4770) { - ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false); + ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false); ingenic_config_pin(jzpc, pin, GPIO_MSK, false); - ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2); - ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1); + ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2); + ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1); } else { ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true); ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2); @@ -2057,14 +2057,14 @@ static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, 'A' + offt, idx, input ? "in" : "out"); if (jzpc->info->version >= ID_X1000) { - ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_INT, false); + ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_INT, false); ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, true); - ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input); + ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input); ingenic_shadow_config_pin_load(jzpc, pin); } else if (jzpc->info->version >= ID_JZ4770) { - ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false); + ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false); ingenic_config_pin(jzpc, pin, GPIO_MSK, true); - ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input); + ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input); } else { ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false); ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, !input); @@ -2092,7 +2092,7 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev, bool pull; if (jzpc->info->version >= ID_JZ4770) - pull = !ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PEN); + pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN); else pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS); @@ -2142,7 +2142,7 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc, } } else if (jzpc->info->version >= ID_JZ4770) { - ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PEN, !bias); + ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !bias); } else { ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !bias); } @@ -2152,7 +2152,7 @@ static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc, unsigned int pin, bool high) { if (jzpc->info->version >= ID_JZ4770) - ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, high); + ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, high); else ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DATA, high); } -- GitLab From f981dc171c04c6cf5a35c712543b231ebf805832 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Sun, 20 Dec 2020 23:18:58 -0800 Subject: [PATCH 0052/1084] tools/power/x86/intel-speed-select: Set scaling_max_freq to base_frequency When BIOS disables turbo, The scaling_max_freq in cpufreq sysfs will be limited to config level 0 base frequency. But when user selects a higher config levels, this will result in higher base frequency. But since scaling_max_freq is still old base frequency, the performance will still be limited. So when the turbo is disabled and cpufreq base_frequency is higher than scaling_max_freq, update the scaling_max_freq to the base_frequency. Signed-off-by: Srinivas Pandruvada Link: https://lore.kernel.org/r/20201221071859.2783957-2-srinivas.pandruvada@linux.intel.com Signed-off-by: Hans de Goede --- .../x86/intel-speed-select/isst-config.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 5390158cdb401..9b6f0e6f150db 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1249,6 +1249,8 @@ static void dump_isst_config(int arg) isst_ctdp_display_information_end(outf); } +static void adjust_scaling_max_from_base_freq(int cpu); + static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, void *arg4) { @@ -1267,6 +1269,9 @@ static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, int pkg_id = get_physical_package_id(cpu); int die_id = get_physical_die_id(cpu); + /* Wait for updated base frequencies */ + usleep(2000); + fprintf(stderr, "Option is set to online/offline\n"); ctdp_level.core_cpumask_size = alloc_cpu_set(&ctdp_level.core_cpumask); @@ -1283,6 +1288,7 @@ static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) { fprintf(stderr, "online cpu %d\n", i); set_cpu_online_offline(i, 1); + adjust_scaling_max_from_base_freq(i); } else { fprintf(stderr, "offline cpu %d\n", i); set_cpu_online_offline(i, 0); @@ -1440,6 +1446,21 @@ static int set_cpufreq_scaling_min_max(int cpu, int max, int freq) return 0; } +static int no_turbo(void) +{ + return parse_int_file(0, "/sys/devices/system/cpu/intel_pstate/no_turbo"); +} + +static void adjust_scaling_max_from_base_freq(int cpu) +{ + int base_freq, scaling_max_freq; + + scaling_max_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); + base_freq = get_cpufreq_base_freq(cpu); + if (scaling_max_freq < base_freq || no_turbo()) + set_cpufreq_scaling_min_max(cpu, 1, base_freq); +} + static int set_clx_pbf_cpufreq_scaling_min_max(int cpu) { struct isst_pkg_ctdp_level_info *ctdp_level; -- GitLab From bbaa2e95e23e74791dd75b90d5ad9aad535acc6e Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Sun, 20 Dec 2020 23:18:59 -0800 Subject: [PATCH 0053/1084] tools/power/x86/intel-speed-select: Set higher of cpuinfo_max_freq or base_frequency In some case when BIOS disabled turbo, cpufreq cpuinfo_max_freq can be lower than base_frequency at higher config level. So, in that case set scaling_min_freq to base_frequency. Signed-off-by: Srinivas Pandruvada Link: https://lore.kernel.org/r/20201221071859.2783957-3-srinivas.pandruvada@linux.intel.com Signed-off-by: Hans de Goede --- tools/power/x86/intel-speed-select/isst-config.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 9b6f0e6f150db..09cb3a6672f3e 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1461,6 +1461,16 @@ static void adjust_scaling_max_from_base_freq(int cpu) set_cpufreq_scaling_min_max(cpu, 1, base_freq); } +static void adjust_scaling_min_from_base_freq(int cpu) +{ + int base_freq, scaling_min_freq; + + scaling_min_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); + base_freq = get_cpufreq_base_freq(cpu); + if (scaling_min_freq < base_freq) + set_cpufreq_scaling_min_max(cpu, 0, base_freq); +} + static int set_clx_pbf_cpufreq_scaling_min_max(int cpu) { struct isst_pkg_ctdp_level_info *ctdp_level; @@ -1558,6 +1568,7 @@ static void set_scaling_min_to_cpuinfo_max(int cpu) continue; set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 0); + adjust_scaling_min_from_base_freq(i); } } -- GitLab From 6a4b1f2dff558d75ee4f2ce88595a933b6918183 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Dec 2020 15:33:36 -0800 Subject: [PATCH 0054/1084] platform/surface: surface_gpe: Fix non-PM_SLEEP build warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix build warnings when CONFIG_PM_SLEEP is not enabled and these functions are not used: ../drivers/platform/surface/surface_gpe.c:189:12: warning: ‘surface_gpe_resume’ defined but not used [-Wunused-function] static int surface_gpe_resume(struct device *dev) ^~~~~~~~~~~~~~~~~~ ../drivers/platform/surface/surface_gpe.c:184:12: warning: ‘surface_gpe_suspend’ defined but not used [-Wunused-function] static int surface_gpe_suspend(struct device *dev) ^~~~~~~~~~~~~~~~~~~ Fixes: 274335f1c557 ("platform/surface: Add Driver to set up lid GPEs on MS Surface device") Signed-off-by: Randy Dunlap Cc: Maximilian Luz Cc: Hans de Goede Cc: platform-driver-x86@vger.kernel.org Reviewed-by: Maximilian Luz Link: https://lore.kernel.org/r/20201214233336.19782-1-rdunlap@infradead.org Signed-off-by: Hans de Goede --- drivers/platform/surface/surface_gpe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/surface/surface_gpe.c b/drivers/platform/surface/surface_gpe.c index e49e5d6d5d4e1..86f6991b12157 100644 --- a/drivers/platform/surface/surface_gpe.c +++ b/drivers/platform/surface/surface_gpe.c @@ -181,12 +181,12 @@ static int surface_lid_enable_wakeup(struct device *dev, bool enable) return 0; } -static int surface_gpe_suspend(struct device *dev) +static int __maybe_unused surface_gpe_suspend(struct device *dev) { return surface_lid_enable_wakeup(dev, true); } -static int surface_gpe_resume(struct device *dev) +static int __maybe_unused surface_gpe_resume(struct device *dev) { return surface_lid_enable_wakeup(dev, false); } -- GitLab From e4a02c7a0e3aeb966e4fdc4a43dce978c467fe83 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 16 Dec 2020 14:37:52 +0100 Subject: [PATCH 0055/1084] platform/surface: SURFACE_PLATFORMS should depend on ACPI All Microsoft Surface platform-specific device drivers depend on ACPI, but the gatekeeper symbol SURFACE_PLATFORMS does not. Hence when the user is configuring a kernel without ACPI support, he is still asked about Microsoft Surface drivers, even though this question is irrelevant. Fix this by moving the dependency on ACPI from the individual driver symbols to SURFACE_PLATFORMS. Signed-off-by: Geert Uytterhoeven Reviewed-by: Maximilian Luz Link: https://lore.kernel.org/r/20201216133752.1321978-1-geert@linux-m68k.org Signed-off-by: Hans de Goede --- drivers/platform/surface/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/platform/surface/Kconfig b/drivers/platform/surface/Kconfig index 33040b0b3b799..2c941cdac9eed 100644 --- a/drivers/platform/surface/Kconfig +++ b/drivers/platform/surface/Kconfig @@ -5,6 +5,7 @@ menuconfig SURFACE_PLATFORMS bool "Microsoft Surface Platform-Specific Device Drivers" + depends on ACPI default y help Say Y here to get to see options for platform-specific device drivers @@ -29,20 +30,19 @@ config SURFACE3_WMI config SURFACE_3_BUTTON tristate "Power/home/volume buttons driver for Microsoft Surface 3 tablet" - depends on ACPI && KEYBOARD_GPIO && I2C + depends on KEYBOARD_GPIO && I2C help This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet. config SURFACE_3_POWER_OPREGION tristate "Surface 3 battery platform operation region support" - depends on ACPI && I2C + depends on I2C help This driver provides support for ACPI operation region of the Surface 3 battery platform driver. config SURFACE_GPE tristate "Surface GPE/Lid Support Driver" - depends on ACPI depends on DMI help This driver marks the GPEs related to the ACPI lid device found on @@ -52,7 +52,7 @@ config SURFACE_GPE config SURFACE_PRO3_BUTTON tristate "Power/home/volume buttons driver for Microsoft Surface Pro 3/4 tablet" - depends on ACPI && INPUT + depends on INPUT help This driver handles the power/home/volume buttons on the Microsoft Surface Pro 3/4 tablet. -- GitLab From 9bba96275576da0cf78ede62aeb2fc975ed8a32d Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 23 Dec 2020 17:36:44 +0300 Subject: [PATCH 0056/1084] platform/x86: i2c-multi-instantiate: Don't create platform device for INT3515 ACPI nodes There are several reports about the tps6598x causing interrupt flood on boards with the INT3515 ACPI node, which then causes instability. There appears to be several problems with the interrupt. One problem is that the I2CSerialBus resources do not always map to the Interrupt resource with the same index, but that is not the only problem. We have not been able to come up with a solution for all the issues, and because of that disabling the device for now. The PD controller on these platforms is autonomous, and the purpose for the driver is primarily to supply status to the userspace, so this will not affect any functionality. Reported-by: Moody Salem Fixes: a3dd034a1707 ("ACPI / scan: Create platform device for INT3515 ACPI nodes") Cc: stable@vger.kernel.org BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1883511 Signed-off-by: Heikki Krogerus Link: https://lore.kernel.org/r/20201223143644.33341-1-heikki.krogerus@linux.intel.com Signed-off-by: Hans de Goede --- drivers/platform/x86/i2c-multi-instantiate.c | 31 +++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/i2c-multi-instantiate.c b/drivers/platform/x86/i2c-multi-instantiate.c index b457b0babde39..2cce82579d091 100644 --- a/drivers/platform/x86/i2c-multi-instantiate.c +++ b/drivers/platform/x86/i2c-multi-instantiate.c @@ -164,13 +164,29 @@ static const struct i2c_inst_data bsg2150_data[] = { {} }; -static const struct i2c_inst_data int3515_data[] = { - { "tps6598x", IRQ_RESOURCE_APIC, 0 }, - { "tps6598x", IRQ_RESOURCE_APIC, 1 }, - { "tps6598x", IRQ_RESOURCE_APIC, 2 }, - { "tps6598x", IRQ_RESOURCE_APIC, 3 }, - {} -}; +/* + * Device with _HID INT3515 (TI PD controllers) has some unresolved interrupt + * issues. The most common problem seen is interrupt flood. + * + * There are at least two known causes. Firstly, on some boards, the + * I2CSerialBus resource index does not match the Interrupt resource, i.e. they + * are not one-to-one mapped like in the array below. Secondly, on some boards + * the IRQ line from the PD controller is not actually connected at all. But the + * interrupt flood is also seen on some boards where those are not a problem, so + * there are some other problems as well. + * + * Because of the issues with the interrupt, the device is disabled for now. If + * you wish to debug the issues, uncomment the below, and add an entry for the + * INT3515 device to the i2c_multi_instance_ids table. + * + * static const struct i2c_inst_data int3515_data[] = { + * { "tps6598x", IRQ_RESOURCE_APIC, 0 }, + * { "tps6598x", IRQ_RESOURCE_APIC, 1 }, + * { "tps6598x", IRQ_RESOURCE_APIC, 2 }, + * { "tps6598x", IRQ_RESOURCE_APIC, 3 }, + * { } + * }; + */ /* * Note new device-ids must also be added to i2c_multi_instantiate_ids in @@ -179,7 +195,6 @@ static const struct i2c_inst_data int3515_data[] = { static const struct acpi_device_id i2c_multi_inst_acpi_ids[] = { { "BSG1160", (unsigned long)bsg1160_data }, { "BSG2150", (unsigned long)bsg2150_data }, - { "INT3515", (unsigned long)int3515_data }, { } }; MODULE_DEVICE_TABLE(acpi, i2c_multi_inst_acpi_ids); -- GitLab From 46c54cf2706122c37497896d56d67b0c0aca2ede Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 24 Dec 2020 14:51:58 +0100 Subject: [PATCH 0057/1084] platform/x86: touchscreen_dmi: Add swap-x-y quirk for Goodix touchscreen on Estar Beauty HD tablet The Estar Beauty HD (MID 7316R) tablet uses a Goodix touchscreen, with the X and Y coordinates swapped compared to the LCD panel. Add a touchscreen_dmi entry for this adding a "touchscreen-swapped-x-y" device-property to the i2c-client instantiated for this device before the driver binds. This is the first entry of a Goodix touchscreen to touchscreen_dmi.c, so far DMI quirks for Goodix touchscreen's have been added directly to drivers/input/touchscreen/goodix.c. Currently there are 3 DMI tables in goodix.c: 1. rotated_screen[] for devices where the touchscreen is rotated 180 degrees vs the LCD panel 2. inverted_x_screen[] for devices where the X axis is inverted 3. nine_bytes_report[] for devices which use a non standard touch report size Arguably only 3. really needs to be inside the driver and the other 2 cases are better handled through the generic touchscreen DMI quirk mechanism from touchscreen_dmi.c, which allows adding device-props to any i2c-client. Esp. now that goodix.c is using the generic touchscreen_properties code. Alternative to the approach from this patch we could add a 4th dmi_system_id table for devices with swapped-x-y axis to goodix.c, but that seems undesirable. Cc: Bastien Nocera Cc: Dmitry Torokhov Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20201224135158.10976-1-hdegoede@redhat.com --- drivers/platform/x86/touchscreen_dmi.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c index 5783139d0a119..c4de932302d6b 100644 --- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -263,6 +263,16 @@ static const struct ts_dmi_data digma_citi_e200_data = { .properties = digma_citi_e200_props, }; +static const struct property_entry estar_beauty_hd_props[] = { + PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), + { } +}; + +static const struct ts_dmi_data estar_beauty_hd_data = { + .acpi_name = "GDIX1001:00", + .properties = estar_beauty_hd_props, +}; + static const struct property_entry gp_electronic_t701_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 960), PROPERTY_ENTRY_U32("touchscreen-size-y", 640), @@ -942,6 +952,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), }, }, + { + /* Estar Beauty HD (MID 7316R) */ + .driver_data = (void *)&estar_beauty_hd_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Estar"), + DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"), + }, + }, { /* GP-electronic T701 */ .driver_data = (void *)&gp_electronic_t701_data, -- GitLab From fcd38f178b785623c0325958225744f0d8a075c0 Mon Sep 17 00:00:00 2001 From: Arnold Gozum Date: Sat, 26 Dec 2020 15:53:06 -0500 Subject: [PATCH 0058/1084] platform/x86: intel-vbtn: Support for tablet mode on Dell Inspiron 7352 The Dell Inspiron 7352 is a 2-in-1 model that has chassis-type "Notebook". Add this model to the dmi_switches_allow_list. Signed-off-by: Arnold Gozum Link: https://lore.kernel.org/r/20201226205307.249659-1-arngozum@gmail.com Signed-off-by: Hans de Goede --- drivers/platform/x86/intel-vbtn.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c index 3b49a1f4061bc..9bbdb26d43054 100644 --- a/drivers/platform/x86/intel-vbtn.c +++ b/drivers/platform/x86/intel-vbtn.c @@ -222,6 +222,12 @@ static const struct dmi_system_id dmi_switches_allow_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7352"), + }, + }, {} /* Array terminator */ }; -- GitLab From aa44afab87af079e0cf2ead9621d0447798a305e Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Tue, 29 Dec 2020 21:47:26 -0500 Subject: [PATCH 0059/1084] platform/x86: thinkpad_acpi: correct palmsensor error checking The previous commit adding functionality for the palm sensor had a mistake which meant the error conditions on initialisation was not checked correctly. On some older platforms this meant that if the sensor wasn't available an error would be returned and the driver would fail to load. This commit corrects the error condition. Many thanks to Mario Oenning for reporting and determining the issue Signed-off-by: Mark Pearson Link: https://lore.kernel.org/r/20201230024726.7861-1-markpearson@lenovo.com Signed-off-by: Hans de Goede --- drivers/platform/x86/thinkpad_acpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e03df2881dc6d..c102657b3eb32 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -9951,9 +9951,9 @@ static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm) if ((palm_err == -ENODEV) && (lap_err == -ENODEV)) return 0; /* Otherwise, if there was an error return it */ - if (palm_err && (palm_err != ENODEV)) + if (palm_err && (palm_err != -ENODEV)) return palm_err; - if (lap_err && (lap_err != ENODEV)) + if (lap_err && (lap_err != -ENODEV)) return lap_err; if (has_palmsensor) { -- GitLab From 5b569302520ac8cef03e7a841e45cb37234f8b5f Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Wed, 30 Dec 2020 13:40:28 +0530 Subject: [PATCH 0060/1084] platform/x86: amd-pmc: Fix CONFIG_DEBUG_FS check lkp reported that CONFIG_DEBUG_FS was not defined because of wrong usage if macro, correcting it now. Fixes: 156ec4731cb2 ("platform/x86: amd-pmc: Add AMD platform support for S2Idle") Reported-by: kernel test robot Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20201230081028.2615217-1-Shyam-sundar.S-k@amd.com Signed-off-by: Hans de Goede --- drivers/platform/x86/amd-pmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c index 0102bf1c79160..ef83425724634 100644 --- a/drivers/platform/x86/amd-pmc.c +++ b/drivers/platform/x86/amd-pmc.c @@ -85,7 +85,7 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3 iowrite32(val, dev->regbase + reg_offset); } -#if CONFIG_DEBUG_FS +#ifdef CONFIG_DEBUG_FS static int smu_fw_info_show(struct seq_file *s, void *unused) { struct amd_pmc_dev *dev = s->private; -- GitLab From 92ff62a7bcc17d47c0ce8dddfb7a6e1a2e55ebf4 Mon Sep 17 00:00:00 2001 From: Billy Tsai Date: Thu, 17 Dec 2020 10:49:12 +0800 Subject: [PATCH 0061/1084] pinctrl: aspeed: g6: Fix PWMG0 pinctrl setting The SCU offset for signal PWM8 in group PWM8G0 is wrong, fix it from SCU414 to SCU4B4. Signed-off-by: Billy Tsai Fixes: 2eda1cdec49f ("pinctrl: aspeed: Add AST2600 pinmux support") Reviewed-by: Joel Stanley Reviewed-by: Andrew Jeffery Link: https://lore.kernel.org/r/20201217024912.3198-1-billy_tsai@aspeedtech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c index 34803a6c76643..5c1a109842a76 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c @@ -347,7 +347,7 @@ FUNC_GROUP_DECL(RMII4, F24, E23, E24, E25, C25, C24, B26, B25, B24); #define D22 40 SIG_EXPR_LIST_DECL_SESG(D22, SD1CLK, SD1, SIG_DESC_SET(SCU414, 8)); -SIG_EXPR_LIST_DECL_SEMG(D22, PWM8, PWM8G0, PWM8, SIG_DESC_SET(SCU414, 8)); +SIG_EXPR_LIST_DECL_SEMG(D22, PWM8, PWM8G0, PWM8, SIG_DESC_SET(SCU4B4, 8)); PIN_DECL_2(D22, GPIOF0, SD1CLK, PWM8); GROUP_DECL(PWM8G0, D22); -- GitLab From 7386a559caa6414e74578172c2bc4e636d6bd0a0 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 10 Dec 2020 12:17:47 +0300 Subject: [PATCH 0062/1084] arm64: dts: amlogic: meson-g12: Set FL-adj property value In accordance with the DWC USB3 bindings the property is supposed to have uint32 type. It's erroneous from the DT schema and driver points of view to declare it as boolean. As Neil suggested set it to 0x20 so not break the platform and to make the dtbs checker happy. Link: https://lore.kernel.org/linux-usb/20201010224121.12672-16-Sergey.Semin@baikalelectronics.ru/ Signed-off-by: Serge Semin Reviewed-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Reviewed-by: Krzysztof Kozlowski Fixes: 9baf7d6be730 ("arm64: dts: meson: g12a: Add G12A USB nodes") Signed-off-by: Kevin Hilman Link: https://lore.kernel.org/r/20201210091756.18057-3-Sergey.Semin@baikalelectronics.ru --- arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi index 9c90d562ada1a..221fcca3b0b93 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi @@ -2390,7 +2390,7 @@ interrupts = ; dr_mode = "host"; snps,dis_u2_susphy_quirk; - snps,quirk-frame-length-adjustment; + snps,quirk-frame-length-adjustment = <0x20>; snps,parkmode-disable-ss-quirk; }; }; -- GitLab From 10f42b3e648377b2f2f323a5530354710616c6cc Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Tue, 22 Dec 2020 19:00:48 +0100 Subject: [PATCH 0063/1084] libceph: zero out session key and connection secret Try and avoid leaving bits and pieces of session key and connection secret (gets split into GCM key and a pair of GCM IVs) around. Signed-off-by: Ilya Dryomov Reviewed-by: Jeff Layton --- net/ceph/auth_x.c | 57 ++++++++++++++++++++++++----------------- net/ceph/crypto.c | 3 ++- net/ceph/messenger_v2.c | 45 ++++++++++++++++++-------------- 3 files changed, 62 insertions(+), 43 deletions(-) diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 9815cfe42af09..ca44c327baced 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c @@ -569,6 +569,34 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, return -ERANGE; } +static int decode_con_secret(void **p, void *end, u8 *con_secret, + int *con_secret_len) +{ + int len; + + ceph_decode_32_safe(p, end, len, bad); + ceph_decode_need(p, end, len, bad); + + dout("%s len %d\n", __func__, len); + if (con_secret) { + if (len > CEPH_MAX_CON_SECRET_LEN) { + pr_err("connection secret too big %d\n", len); + goto bad_memzero; + } + memcpy(con_secret, *p, len); + *con_secret_len = len; + } + memzero_explicit(*p, len); + *p += len; + return 0; + +bad_memzero: + memzero_explicit(*p, len); +bad: + pr_err("failed to decode connection secret\n"); + return -EINVAL; +} + static int handle_auth_session_key(struct ceph_auth_client *ac, void **p, void *end, u8 *session_key, int *session_key_len, @@ -612,17 +640,9 @@ static int handle_auth_session_key(struct ceph_auth_client *ac, dout("%s decrypted %d bytes\n", __func__, ret); dend = dp + ret; - ceph_decode_32_safe(&dp, dend, len, e_inval); - if (len > CEPH_MAX_CON_SECRET_LEN) { - pr_err("connection secret too big %d\n", len); - return -EINVAL; - } - - dout("%s connection secret len %d\n", __func__, len); - if (con_secret) { - memcpy(con_secret, dp, len); - *con_secret_len = len; - } + ret = decode_con_secret(&dp, dend, con_secret, con_secret_len); + if (ret) + return ret; } /* service tickets */ @@ -828,7 +848,6 @@ static int decrypt_authorizer_reply(struct ceph_crypto_key *secret, { void *dp, *dend; u8 struct_v; - int len; int ret; dp = *p + ceph_x_encrypt_offset(); @@ -843,17 +862,9 @@ static int decrypt_authorizer_reply(struct ceph_crypto_key *secret, ceph_decode_64_safe(&dp, dend, *nonce_plus_one, e_inval); dout("%s nonce_plus_one %llu\n", __func__, *nonce_plus_one); if (struct_v >= 2) { - ceph_decode_32_safe(&dp, dend, len, e_inval); - if (len > CEPH_MAX_CON_SECRET_LEN) { - pr_err("connection secret too big %d\n", len); - return -EINVAL; - } - - dout("%s connection secret len %d\n", __func__, len); - if (con_secret) { - memcpy(con_secret, dp, len); - *con_secret_len = len; - } + ret = decode_con_secret(&dp, dend, con_secret, con_secret_len); + if (ret) + return ret; } return 0; diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 4f75df40fb121..92d89b3316459 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -96,6 +96,7 @@ int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end) key->len = ceph_decode_16(p); ceph_decode_need(p, end, key->len, bad); ret = set_secret(key, *p); + memzero_explicit(*p, key->len); *p += key->len; return ret; @@ -134,7 +135,7 @@ int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey) void ceph_crypto_key_destroy(struct ceph_crypto_key *key) { if (key) { - kfree(key->key); + kfree_sensitive(key->key); key->key = NULL; if (key->tfm) { crypto_free_sync_skcipher(key->tfm); diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c index c38d8de938363..cc40ce4e02fbc 100644 --- a/net/ceph/messenger_v2.c +++ b/net/ceph/messenger_v2.c @@ -689,11 +689,10 @@ static int verify_epilogue_crcs(struct ceph_connection *con, u32 front_crc, } static int setup_crypto(struct ceph_connection *con, - u8 *session_key, int session_key_len, - u8 *con_secret, int con_secret_len) + const u8 *session_key, int session_key_len, + const u8 *con_secret, int con_secret_len) { unsigned int noio_flag; - void *p; int ret; dout("%s con %p con_mode %d session_key_len %d con_secret_len %d\n", @@ -751,15 +750,14 @@ static int setup_crypto(struct ceph_connection *con, return ret; } - p = con_secret; - WARN_ON((unsigned long)p & crypto_aead_alignmask(con->v2.gcm_tfm)); - ret = crypto_aead_setkey(con->v2.gcm_tfm, p, CEPH_GCM_KEY_LEN); + WARN_ON((unsigned long)con_secret & + crypto_aead_alignmask(con->v2.gcm_tfm)); + ret = crypto_aead_setkey(con->v2.gcm_tfm, con_secret, CEPH_GCM_KEY_LEN); if (ret) { pr_err("failed to set gcm key: %d\n", ret); return ret; } - p += CEPH_GCM_KEY_LEN; WARN_ON(crypto_aead_ivsize(con->v2.gcm_tfm) != CEPH_GCM_IV_LEN); ret = crypto_aead_setauthsize(con->v2.gcm_tfm, CEPH_GCM_TAG_LEN); if (ret) { @@ -777,8 +775,11 @@ static int setup_crypto(struct ceph_connection *con, aead_request_set_callback(con->v2.gcm_req, CRYPTO_TFM_REQ_MAY_BACKLOG, crypto_req_done, &con->v2.gcm_wait); - memcpy(&con->v2.in_gcm_nonce, p, CEPH_GCM_IV_LEN); - memcpy(&con->v2.out_gcm_nonce, p + CEPH_GCM_IV_LEN, CEPH_GCM_IV_LEN); + memcpy(&con->v2.in_gcm_nonce, con_secret + CEPH_GCM_KEY_LEN, + CEPH_GCM_IV_LEN); + memcpy(&con->v2.out_gcm_nonce, + con_secret + CEPH_GCM_KEY_LEN + CEPH_GCM_IV_LEN, + CEPH_GCM_IV_LEN); return 0; /* auth_x, secure mode */ } @@ -800,7 +801,7 @@ static int hmac_sha256(struct ceph_connection *con, const struct kvec *kvecs, desc->tfm = con->v2.hmac_tfm; ret = crypto_shash_init(desc); if (ret) - return ret; + goto out; for (i = 0; i < kvec_cnt; i++) { WARN_ON((unsigned long)kvecs[i].iov_base & @@ -808,15 +809,14 @@ static int hmac_sha256(struct ceph_connection *con, const struct kvec *kvecs, ret = crypto_shash_update(desc, kvecs[i].iov_base, kvecs[i].iov_len); if (ret) - return ret; + goto out; } ret = crypto_shash_final(desc, hmac); - if (ret) - return ret; +out: shash_desc_zero(desc); - return 0; /* auth_x, both plain and secure modes */ + return ret; /* auth_x, both plain and secure modes */ } static void gcm_inc_nonce(struct ceph_gcm_nonce *nonce) @@ -2072,27 +2072,32 @@ static int process_auth_done(struct ceph_connection *con, void *p, void *end) if (con->state != CEPH_CON_S_V2_AUTH) { dout("%s con %p state changed to %d\n", __func__, con, con->state); - return -EAGAIN; + ret = -EAGAIN; + goto out; } dout("%s con %p handle_auth_done ret %d\n", __func__, con, ret); if (ret) - return ret; + goto out; ret = setup_crypto(con, session_key, session_key_len, con_secret, con_secret_len); if (ret) - return ret; + goto out; reset_out_kvecs(con); ret = prepare_auth_signature(con); if (ret) { pr_err("prepare_auth_signature failed: %d\n", ret); - return ret; + goto out; } con->state = CEPH_CON_S_V2_AUTH_SIGNATURE; - return 0; + +out: + memzero_explicit(session_key_buf, sizeof(session_key_buf)); + memzero_explicit(con_secret_buf, sizeof(con_secret_buf)); + return ret; bad: pr_err("failed to decode auth_done\n"); @@ -3436,6 +3441,8 @@ void ceph_con_v2_reset_protocol(struct ceph_connection *con) } con->v2.con_mode = CEPH_CON_MODE_UNKNOWN; + memzero_explicit(&con->v2.in_gcm_nonce, CEPH_GCM_IV_LEN); + memzero_explicit(&con->v2.out_gcm_nonce, CEPH_GCM_IV_LEN); if (con->v2.hmac_tfm) { crypto_free_shash(con->v2.hmac_tfm); -- GitLab From 4972cf605f8a10784bb9ec9bdf3465892fb547c8 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Wed, 23 Dec 2020 16:32:05 +0100 Subject: [PATCH 0064/1084] libceph, ceph: disambiguate ceph_connection_operations handlers Since a few years, kernel addresses are no longer included in oops dumps, at least on x86. All we get is a symbol name with offset and size. This is a problem for ceph_connection_operations handlers, especially con->ops->dispatch(). All three handlers have the same name and there is little context to disambiguate between e.g. monitor and OSD clients because almost everything is inlined. gdb sneakily stops at the first matching symbol, so one has to resort to nm and addr2line. Some of these are already prefixed with mon_, osd_ or mds_. Let's do the same for all others. Signed-off-by: Ilya Dryomov Acked-by: Jeff Layton --- fs/ceph/mds_client.c | 34 +++++++++++++++++----------------- net/ceph/mon_client.c | 14 +++++++------- net/ceph/osd_client.c | 40 ++++++++++++++++++++-------------------- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 840587037b59b..d87bd852ed961 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -5038,7 +5038,7 @@ void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg) return; } -static struct ceph_connection *con_get(struct ceph_connection *con) +static struct ceph_connection *mds_get_con(struct ceph_connection *con) { struct ceph_mds_session *s = con->private; @@ -5047,7 +5047,7 @@ static struct ceph_connection *con_get(struct ceph_connection *con) return NULL; } -static void con_put(struct ceph_connection *con) +static void mds_put_con(struct ceph_connection *con) { struct ceph_mds_session *s = con->private; @@ -5058,7 +5058,7 @@ static void con_put(struct ceph_connection *con) * if the client is unresponsive for long enough, the mds will kill * the session entirely. */ -static void peer_reset(struct ceph_connection *con) +static void mds_peer_reset(struct ceph_connection *con) { struct ceph_mds_session *s = con->private; struct ceph_mds_client *mdsc = s->s_mdsc; @@ -5067,7 +5067,7 @@ static void peer_reset(struct ceph_connection *con) send_mds_reconnect(mdsc, s); } -static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) +static void mds_dispatch(struct ceph_connection *con, struct ceph_msg *msg) { struct ceph_mds_session *s = con->private; struct ceph_mds_client *mdsc = s->s_mdsc; @@ -5125,8 +5125,8 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) * Note: returned pointer is the address of a structure that's * managed separately. Caller must *not* attempt to free it. */ -static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, - int *proto, int force_new) +static struct ceph_auth_handshake * +mds_get_authorizer(struct ceph_connection *con, int *proto, int force_new) { struct ceph_mds_session *s = con->private; struct ceph_mds_client *mdsc = s->s_mdsc; @@ -5142,7 +5142,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, return auth; } -static int add_authorizer_challenge(struct ceph_connection *con, +static int mds_add_authorizer_challenge(struct ceph_connection *con, void *challenge_buf, int challenge_buf_len) { struct ceph_mds_session *s = con->private; @@ -5153,7 +5153,7 @@ static int add_authorizer_challenge(struct ceph_connection *con, challenge_buf, challenge_buf_len); } -static int verify_authorizer_reply(struct ceph_connection *con) +static int mds_verify_authorizer_reply(struct ceph_connection *con) { struct ceph_mds_session *s = con->private; struct ceph_mds_client *mdsc = s->s_mdsc; @@ -5165,7 +5165,7 @@ static int verify_authorizer_reply(struct ceph_connection *con) NULL, NULL, NULL, NULL); } -static int invalidate_authorizer(struct ceph_connection *con) +static int mds_invalidate_authorizer(struct ceph_connection *con) { struct ceph_mds_session *s = con->private; struct ceph_mds_client *mdsc = s->s_mdsc; @@ -5288,15 +5288,15 @@ static int mds_check_message_signature(struct ceph_msg *msg) } static const struct ceph_connection_operations mds_con_ops = { - .get = con_get, - .put = con_put, - .dispatch = dispatch, - .get_authorizer = get_authorizer, - .add_authorizer_challenge = add_authorizer_challenge, - .verify_authorizer_reply = verify_authorizer_reply, - .invalidate_authorizer = invalidate_authorizer, - .peer_reset = peer_reset, + .get = mds_get_con, + .put = mds_put_con, .alloc_msg = mds_alloc_msg, + .dispatch = mds_dispatch, + .peer_reset = mds_peer_reset, + .get_authorizer = mds_get_authorizer, + .add_authorizer_challenge = mds_add_authorizer_challenge, + .verify_authorizer_reply = mds_verify_authorizer_reply, + .invalidate_authorizer = mds_invalidate_authorizer, .sign_message = mds_sign_message, .check_message_signature = mds_check_message_signature, .get_auth_request = mds_get_auth_request, diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index b9d54ed9f3384..195ceb8afb061 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c @@ -1433,7 +1433,7 @@ static int mon_handle_auth_bad_method(struct ceph_connection *con, /* * handle incoming message */ -static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) +static void mon_dispatch(struct ceph_connection *con, struct ceph_msg *msg) { struct ceph_mon_client *monc = con->private; int type = le16_to_cpu(msg->hdr.type); @@ -1565,21 +1565,21 @@ static void mon_fault(struct ceph_connection *con) * will come from the messenger workqueue, which is drained prior to * mon_client destruction. */ -static struct ceph_connection *con_get(struct ceph_connection *con) +static struct ceph_connection *mon_get_con(struct ceph_connection *con) { return con; } -static void con_put(struct ceph_connection *con) +static void mon_put_con(struct ceph_connection *con) { } static const struct ceph_connection_operations mon_con_ops = { - .get = con_get, - .put = con_put, - .dispatch = dispatch, - .fault = mon_fault, + .get = mon_get_con, + .put = mon_put_con, .alloc_msg = mon_alloc_msg, + .dispatch = mon_dispatch, + .fault = mon_fault, .get_auth_request = mon_get_auth_request, .handle_auth_reply_more = mon_handle_auth_reply_more, .handle_auth_done = mon_handle_auth_done, diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 61229c5e22cb8..ff8624a7c9643 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -5412,7 +5412,7 @@ void ceph_osdc_cleanup(void) /* * handle incoming message */ -static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) +static void osd_dispatch(struct ceph_connection *con, struct ceph_msg *msg) { struct ceph_osd *osd = con->private; struct ceph_osd_client *osdc = osd->o_osdc; @@ -5534,9 +5534,9 @@ static struct ceph_msg *alloc_msg_with_page_vector(struct ceph_msg_header *hdr) return m; } -static struct ceph_msg *alloc_msg(struct ceph_connection *con, - struct ceph_msg_header *hdr, - int *skip) +static struct ceph_msg *osd_alloc_msg(struct ceph_connection *con, + struct ceph_msg_header *hdr, + int *skip) { struct ceph_osd *osd = con->private; int type = le16_to_cpu(hdr->type); @@ -5560,7 +5560,7 @@ static struct ceph_msg *alloc_msg(struct ceph_connection *con, /* * Wrappers to refcount containing ceph_osd struct */ -static struct ceph_connection *get_osd_con(struct ceph_connection *con) +static struct ceph_connection *osd_get_con(struct ceph_connection *con) { struct ceph_osd *osd = con->private; if (get_osd(osd)) @@ -5568,7 +5568,7 @@ static struct ceph_connection *get_osd_con(struct ceph_connection *con) return NULL; } -static void put_osd_con(struct ceph_connection *con) +static void osd_put_con(struct ceph_connection *con) { struct ceph_osd *osd = con->private; put_osd(osd); @@ -5582,8 +5582,8 @@ static void put_osd_con(struct ceph_connection *con) * Note: returned pointer is the address of a structure that's * managed separately. Caller must *not* attempt to free it. */ -static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, - int *proto, int force_new) +static struct ceph_auth_handshake * +osd_get_authorizer(struct ceph_connection *con, int *proto, int force_new) { struct ceph_osd *o = con->private; struct ceph_osd_client *osdc = o->o_osdc; @@ -5599,7 +5599,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, return auth; } -static int add_authorizer_challenge(struct ceph_connection *con, +static int osd_add_authorizer_challenge(struct ceph_connection *con, void *challenge_buf, int challenge_buf_len) { struct ceph_osd *o = con->private; @@ -5610,7 +5610,7 @@ static int add_authorizer_challenge(struct ceph_connection *con, challenge_buf, challenge_buf_len); } -static int verify_authorizer_reply(struct ceph_connection *con) +static int osd_verify_authorizer_reply(struct ceph_connection *con) { struct ceph_osd *o = con->private; struct ceph_osd_client *osdc = o->o_osdc; @@ -5622,7 +5622,7 @@ static int verify_authorizer_reply(struct ceph_connection *con) NULL, NULL, NULL, NULL); } -static int invalidate_authorizer(struct ceph_connection *con) +static int osd_invalidate_authorizer(struct ceph_connection *con) { struct ceph_osd *o = con->private; struct ceph_osd_client *osdc = o->o_osdc; @@ -5731,18 +5731,18 @@ static int osd_check_message_signature(struct ceph_msg *msg) } static const struct ceph_connection_operations osd_con_ops = { - .get = get_osd_con, - .put = put_osd_con, - .dispatch = dispatch, - .get_authorizer = get_authorizer, - .add_authorizer_challenge = add_authorizer_challenge, - .verify_authorizer_reply = verify_authorizer_reply, - .invalidate_authorizer = invalidate_authorizer, - .alloc_msg = alloc_msg, + .get = osd_get_con, + .put = osd_put_con, + .alloc_msg = osd_alloc_msg, + .dispatch = osd_dispatch, + .fault = osd_fault, .reencode_message = osd_reencode_message, + .get_authorizer = osd_get_authorizer, + .add_authorizer_challenge = osd_add_authorizer_challenge, + .verify_authorizer_reply = osd_verify_authorizer_reply, + .invalidate_authorizer = osd_invalidate_authorizer, .sign_message = osd_sign_message, .check_message_signature = osd_check_message_signature, - .fault = osd_fault, .get_auth_request = osd_get_auth_request, .handle_auth_reply_more = osd_handle_auth_reply_more, .handle_auth_done = osd_handle_auth_done, -- GitLab From 6337c2353a069b6f1276dc35421e421ef6c1ead9 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Wed, 2 Dec 2020 19:05:58 +0100 Subject: [PATCH 0065/1084] ARM: dts: imx6qdl-kontron-samx6i: fix pwms for lcd-backlight MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pwms property have to specify the no-/inverted flag since commit fa28d8212ede ("ARM: dts: imx: default to #pwm-cells = <3> in the SoC dtsi files"). Fixes: fa28d8212ede ("ARM: dts: imx: default to #pwm-cells = <3> in the SoC dtsi files") Signed-off-by: Marco Felsch Reviewed-by: Uwe Kleine-König Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi index d6df598bd1c29..36c2f0d9ce164 100644 --- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi @@ -137,7 +137,7 @@ lcd_backlight: lcd-backlight { compatible = "pwm-backlight"; - pwms = <&pwm4 0 5000000>; + pwms = <&pwm4 0 5000000 0>; pwm-names = "LCD_BKLT_PWM"; brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>; -- GitLab From 4cc99d03757df10a4064ba28bf6021406b04d6a9 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 5 Jan 2021 10:56:51 +0800 Subject: [PATCH 0066/1084] irqchip/loongson-liointc: Fix build warnings Fix build warnings as below: >> drivers/irqchip/irq-loongson-liointc.c:134:12: warning: no previous prototype for 'liointc_of_init' [-Wmissing-prototypes] 134 | int __init liointc_of_init(struct device_node *node, | ^~~~~~~~~~~~~~~ Fixes: dbb152267908c4b2c3639492a94 ("irqchip: Add driver for Loongson I/O Local Interrupt Controller") Reported-by: kernel test robot Signed-off-by: Huacai Chen Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210105025651.772024-1-chenhuacai@loongson.cn --- drivers/irqchip/irq-loongson-liointc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-loongson-liointc.c b/drivers/irqchip/irq-loongson-liointc.c index 9ed1bc4736634..09b91b81851cc 100644 --- a/drivers/irqchip/irq-loongson-liointc.c +++ b/drivers/irqchip/irq-loongson-liointc.c @@ -142,8 +142,8 @@ static void liointc_resume(struct irq_chip_generic *gc) static const char * const parent_names[] = {"int0", "int1", "int2", "int3"}; -int __init liointc_of_init(struct device_node *node, - struct device_node *parent) +static int __init liointc_of_init(struct device_node *node, + struct device_node *parent) { struct irq_chip_generic *gc; struct irq_domain *domain; -- GitLab From d750570e048165c54a99703729438b2a4ccf379b Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Fri, 25 Dec 2020 11:08:45 +0800 Subject: [PATCH 0067/1084] ASoC: rt1015: re-calibrate again when resuming Assuming the calibration state gets lost after system suspend. Re-calibrates again when resuming. The rt1015_priv is alloced by kzalloc. No need to initialize cali_done to 0 in component probe callback. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20201225030845.4138497-1-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1015.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index bf452cc0096f4..145724a5f389a 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -1035,7 +1035,6 @@ static int rt1015_probe(struct snd_soc_component *component) rt1015->component = component; rt1015->bclk_ratio = 0; - rt1015->cali_done = 0; INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work); @@ -1093,6 +1092,10 @@ static int rt1015_resume(struct snd_soc_component *component) regcache_cache_only(rt1015->regmap, false); regcache_sync(rt1015->regmap); + + if (rt1015->cali_done) + rt1015_calibrate(rt1015); + return 0; } #else -- GitLab From 81a6320da73ca23f44155715ec3d9e92bea4e35a Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Thu, 24 Dec 2020 18:18:54 +0800 Subject: [PATCH 0068/1084] ASoC: rt1015: remove bclk_ratio bclk_ratio is unused. Removes bclk_ratio and .set_bclk_ratio callback. Removes snd_soc_dai_set_bclk_ratio() in a few machine drivers which are obviously using rt1015. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20201224101854.3024823-1-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/amd/acp3x-rt5682-max9836.c | 4 +-- sound/soc/codecs/rt1015.c | 28 ------------------- sound/soc/codecs/rt1015.h | 1 - sound/soc/intel/boards/sof_rt5682.c | 7 ----- .../mediatek/mt8183/mt8183-da7219-max98357.c | 6 ---- .../mt8183/mt8183-mt6358-ts3a227-max98357.c | 6 ---- .../mt8192/mt8192-mt6359-rt1015-rt5682.c | 6 ---- 7 files changed, 1 insertion(+), 57 deletions(-) diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c index 1a4e8ca0f99c2..cea320ad0e1c2 100644 --- a/sound/soc/amd/acp3x-rt5682-max9836.c +++ b/sound/soc/amd/acp3x-rt5682-max9836.c @@ -140,9 +140,7 @@ static int acp3x_1015_hw_params(struct snd_pcm_substream *substream, for_each_rtd_codec_dais(rtd, i, codec_dai) { if (strcmp(codec_dai->name, "rt1015-aif")) continue; - ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); - if (ret < 0) - return ret; + ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, 64 * srate, 256 * srate); if (ret < 0) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 145724a5f389a..37b5795b00d13 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -864,14 +864,6 @@ static int rt1015_set_component_pll(struct snd_soc_component *component, freq_out == rt1015->pll_out) return 0; - if (source == RT1015_PLL_S_BCLK) { - if (rt1015->bclk_ratio == 0) { - dev_err(component->dev, - "Can not support bclk ratio as 0.\n"); - return -EINVAL; - } - } - switch (source) { case RT1015_PLL_S_MCLK: snd_soc_component_update_bits(component, RT1015_CLK2, @@ -911,23 +903,6 @@ static int rt1015_set_component_pll(struct snd_soc_component *component, return 0; } -static int rt1015_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) -{ - struct snd_soc_component *component = dai->component; - struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component); - - dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio); - - rt1015->bclk_ratio = ratio; - - if (ratio == 50) { - dev_dbg(component->dev, "Unsupport bclk ratio\n"); - return -EINVAL; - } - - return 0; -} - static int rt1015_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) { @@ -1034,8 +1009,6 @@ static int rt1015_probe(struct snd_soc_component *component) snd_soc_component_get_drvdata(component); rt1015->component = component; - rt1015->bclk_ratio = 0; - INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work); return 0; @@ -1056,7 +1029,6 @@ static void rt1015_remove(struct snd_soc_component *component) static struct snd_soc_dai_ops rt1015_aif_dai_ops = { .hw_params = rt1015_hw_params, .set_fmt = rt1015_set_dai_fmt, - .set_bclk_ratio = rt1015_set_bclk_ratio, .set_tdm_slot = rt1015_set_tdm_slot, }; diff --git a/sound/soc/codecs/rt1015.h b/sound/soc/codecs/rt1015.h index e9b498a754e0b..2aeaf65ba7931 100644 --- a/sound/soc/codecs/rt1015.h +++ b/sound/soc/codecs/rt1015.h @@ -427,7 +427,6 @@ struct rt1015_priv { struct regmap *regmap; int sysclk; int sysclk_src; - int bclk_ratio; int pll_src; int pll_in; int pll_out; diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 8b1ca2da9bb9e..55505e207bc00 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -323,13 +323,6 @@ static int sof_rt1015_hw_params(struct snd_pcm_substream *substream, fs = 64; for_each_rtd_codec_dais(rtd, i, codec_dai) { - /* Set tdm/i2s1 master bclk ratio */ - ret = snd_soc_dai_set_bclk_ratio(codec_dai, fs); - if (ret < 0) { - dev_err(card->dev, "failed to set bclk ratio\n"); - return ret; - } - ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, params_rate(params) * fs, params_rate(params) * 256); diff --git a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c index 078e58f1ad0b2..870cdfd17ffff 100644 --- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c +++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c @@ -125,12 +125,6 @@ mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, for_each_rtd_codec_dais(rtd, i, codec_dai) { if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) || !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) { - ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); - if (ret) { - dev_err(rtd->dev, "failed to set bclk ratio\n"); - return ret; - } - ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, rate * 64, rate * 256); diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c index 8c8340854859a..0e4892245035d 100644 --- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c +++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c @@ -68,12 +68,6 @@ mt8183_mt6358_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, int ret, i; for_each_rtd_codec_dais(rtd, i, codec_dai) { - ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); - if (ret < 0) { - dev_err(card->dev, "failed to set bclk ratio\n"); - return ret; - } - ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, rate * 64, rate * 256); if (ret < 0) { diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index 716fbb4126b5f..a988ce1e58de6 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -46,12 +46,6 @@ static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, int ret, i; for_each_rtd_codec_dais(rtd, i, codec_dai) { - ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); - if (ret) { - dev_err(card->dev, "failed to set bclk ratio\n"); - return ret; - } - ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, params_rate(params) * 64, -- GitLab From 698dc0cf944772a79a9aa417e647c0f7587e51df Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 5 Jan 2021 14:20:07 -0800 Subject: [PATCH 0069/1084] dt-bindings: input: adc-keys: clarify description The current description of ADC keys is not precise enough. "when this key is pressed" leaves it open if a key is considered pressed below or above the threshold. This has led to confusion: drivers/input/keyboard/adc-keys.c ignores the meaning of thresholds and sets the key that is closest to press-threshold-microvolt. This patch nails down the definitions and provides an interpretation of the supplied example. Signed-off-by: Heinrich Schuchardt Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201222110815.24121-1-xypron.glpk@gmx.de Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/adc-keys.txt | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/input/adc-keys.txt b/Documentation/devicetree/bindings/input/adc-keys.txt index e551814629b48..6c8be6a9ace28 100644 --- a/Documentation/devicetree/bindings/input/adc-keys.txt +++ b/Documentation/devicetree/bindings/input/adc-keys.txt @@ -5,7 +5,8 @@ Required properties: - compatible: "adc-keys" - io-channels: Phandle to an ADC channel - io-channel-names = "buttons"; - - keyup-threshold-microvolt: Voltage at which all the keys are considered up. + - keyup-threshold-microvolt: Voltage above or equal to which all the keys are + considered up. Optional properties: - poll-interval: Poll interval time in milliseconds @@ -17,7 +18,12 @@ Each button (key) is represented as a sub-node of "adc-keys": Required subnode-properties: - label: Descriptive name of the key. - linux,code: Keycode to emit. - - press-threshold-microvolt: Voltage ADC input when this key is pressed. + - press-threshold-microvolt: voltage above or equal to which this key is + considered pressed. + +No two values of press-threshold-microvolt may be the same. +All values of press-threshold-microvolt must be less than +keyup-threshold-microvolt. Example: @@ -47,3 +53,15 @@ Example: press-threshold-microvolt = <500000>; }; }; + ++--------------------------------+------------------------+ +| 2.000.000 <= value | no key pressed | ++--------------------------------+------------------------+ +| 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed | ++--------------------------------+------------------------+ +| 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed | ++--------------------------------+------------------------+ +| 500.000 <= value < 1.000.000 | KEY_ENTER pressed | ++--------------------------------+------------------------+ +| value < 500.000 | no key pressed | ++--------------------------------+------------------------+ -- GitLab From 2f9d9a852f426cdc56ebd5c05c2333ea2012cc97 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 29 Dec 2020 13:47:10 -0700 Subject: [PATCH 0070/1084] pinctrl: nomadik: Remove unused variable in nmk_gpio_dbg_show_one Clang warns: drivers/pinctrl/nomadik/pinctrl-nomadik.c:952:8: warning: unused variable 'wake' [-Wunused-variable] bool wake; ^ 1 warning generated. There were two wake declarations added to nmk_gpio_dbg_show_one when converting it to use irq_has_action but only one is used within its scope. Remove the unused one so there is no more warning. Fixes: f3925032d7fd ("pinctrl: nomadik: Use irq_has_action()") Reported-by: Arnd Bergmann Tested-by: Andrew Halaney Reviewed-by: Andrew Halaney Reported-by: Hulk Robot Reported-by: Ye Bin Signed-off-by: Nathan Chancellor Link: https://lore.kernel.org/r/20201229204710.1129033-1-natechancellor@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index d4ea10803fd90..abfe11c7b49fb 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -949,7 +949,6 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s, } else { int irq = chip->to_irq(chip, offset); const int pullidx = pull ? 1 : 0; - bool wake; int val; static const char * const pulls[] = { "none ", -- GitLab From 81bd1579b43e0e285cba667399f1b063f1ce7672 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Mon, 28 Dec 2020 17:04:25 +0800 Subject: [PATCH 0071/1084] pinctrl: mediatek: Fix fallback call path Some SoCs, eg. mt8183, are using a pinconfig operation bias_set_combo. The fallback path in mtk_pinconf_adv_pull_set() should also try this operation. Fixes: cafe19db7751 ("pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage") Signed-off-by: Hsin-Yi Wang Acked-by: Sean Wang Link: https://lore.kernel.org/r/20201228090425.2130569-1-hsinyi@chromium.org Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index 7aeb552d16ce9..72f17f26acd80 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -920,6 +920,10 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, err = hw->soc->bias_set(hw, desc, pullup); if (err) return err; + } else if (hw->soc->bias_set_combo) { + err = hw->soc->bias_set_combo(hw, desc, pullup, arg); + if (err) + return err; } else { return -ENOTSUPP; } -- GitLab From a8644292ea46064f990e4a3c4585bdb294c0d89a Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Tue, 5 Jan 2021 15:02:55 +0100 Subject: [PATCH 0072/1084] ASoC: txx9: Remove driver CPU support for TX49xx is getting removed, so remove sound support for it. Signed-off-by: Thomas Bogendoerfer Link: https://lore.kernel.org/r/20210105140305.141401-11-tsbogend@alpha.franken.de Signed-off-by: Mark Brown --- sound/soc/Kconfig | 1 - sound/soc/Makefile | 1 - sound/soc/txx9/Kconfig | 30 --- sound/soc/txx9/Makefile | 12 - sound/soc/txx9/txx9aclc-ac97.c | 230 ---------------- sound/soc/txx9/txx9aclc-generic.c | 88 ------- sound/soc/txx9/txx9aclc.c | 422 ------------------------------ sound/soc/txx9/txx9aclc.h | 71 ----- 8 files changed, 855 deletions(-) delete mode 100644 sound/soc/txx9/Kconfig delete mode 100644 sound/soc/txx9/Makefile delete mode 100644 sound/soc/txx9/txx9aclc-ac97.c delete mode 100644 sound/soc/txx9/txx9aclc-generic.c delete mode 100644 sound/soc/txx9/txx9aclc.c delete mode 100644 sound/soc/txx9/txx9aclc.h diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 71a6fe87d1a19..47da9ce176933 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -71,7 +71,6 @@ source "sound/soc/stm/Kconfig" source "sound/soc/sunxi/Kconfig" source "sound/soc/tegra/Kconfig" source "sound/soc/ti/Kconfig" -source "sound/soc/txx9/Kconfig" source "sound/soc/uniphier/Kconfig" source "sound/soc/ux500/Kconfig" source "sound/soc/xilinx/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index ddbac3a2169f2..508dbaa1814ec 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -54,7 +54,6 @@ obj-$(CONFIG_SND_SOC) += stm/ obj-$(CONFIG_SND_SOC) += sunxi/ obj-$(CONFIG_SND_SOC) += tegra/ obj-$(CONFIG_SND_SOC) += ti/ -obj-$(CONFIG_SND_SOC) += txx9/ obj-$(CONFIG_SND_SOC) += uniphier/ obj-$(CONFIG_SND_SOC) += ux500/ obj-$(CONFIG_SND_SOC) += xilinx/ diff --git a/sound/soc/txx9/Kconfig b/sound/soc/txx9/Kconfig deleted file mode 100644 index d928edf9f5a90..0000000000000 --- a/sound/soc/txx9/Kconfig +++ /dev/null @@ -1,30 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -## -## TXx9 ACLC -## -config SND_SOC_TXX9ACLC - tristate "SoC Audio for TXx9" - depends on HAS_TXX9_ACLC && TXX9_DMAC - help - This option enables support for the AC Link Controllers in TXx9 SoC. - -config HAS_TXX9_ACLC - bool - -config SND_SOC_TXX9ACLC_AC97 - tristate - select AC97_BUS - select SND_AC97_CODEC - select SND_SOC_AC97_BUS - - -## -## Boards -## -config SND_SOC_TXX9ACLC_GENERIC - tristate "Generic TXx9 ACLC sound machine" - depends on SND_SOC_TXX9ACLC - select SND_SOC_TXX9ACLC_AC97 - select SND_SOC_AC97_CODEC - help - This is a generic AC97 sound machine for use in TXx9 based systems. diff --git a/sound/soc/txx9/Makefile b/sound/soc/txx9/Makefile deleted file mode 100644 index 37ad833eb329b..0000000000000 --- a/sound/soc/txx9/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Platform -snd-soc-txx9aclc-objs := txx9aclc.o -snd-soc-txx9aclc-ac97-objs := txx9aclc-ac97.o - -obj-$(CONFIG_SND_SOC_TXX9ACLC) += snd-soc-txx9aclc.o -obj-$(CONFIG_SND_SOC_TXX9ACLC_AC97) += snd-soc-txx9aclc-ac97.o - -# Machine -snd-soc-txx9aclc-generic-objs := txx9aclc-generic.o - -obj-$(CONFIG_SND_SOC_TXX9ACLC_GENERIC) += snd-soc-txx9aclc-generic.o diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c deleted file mode 100644 index d9e348444bd0d..0000000000000 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ /dev/null @@ -1,230 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * TXx9 ACLC AC97 driver - * - * Copyright (C) 2009 Atsushi Nemoto - * - * Based on RBTX49xx patch from CELF patch archive. - * (C) Copyright TOSHIBA CORPORATION 2004-2006 - */ - -#include -#include -#include -#include -#include -#include -#include /* for TXX9_DIRECTMAP_BASE */ -#include -#include -#include -#include "txx9aclc.h" - -#define AC97_DIR \ - (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) - -#define AC97_RATES \ - SNDRV_PCM_RATE_8000_48000 - -#ifdef __BIG_ENDIAN -#define AC97_FMTS SNDRV_PCM_FMTBIT_S16_BE -#else -#define AC97_FMTS SNDRV_PCM_FMTBIT_S16_LE -#endif - -static DECLARE_WAIT_QUEUE_HEAD(ac97_waitq); - -/* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */ -static struct txx9aclc_plat_drvdata *txx9aclc_drvdata; - -static int txx9aclc_regready(struct txx9aclc_plat_drvdata *drvdata) -{ - return __raw_readl(drvdata->base + ACINTSTS) & ACINT_REGACCRDY; -} - -/* AC97 controller reads codec register */ -static unsigned short txx9aclc_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; - void __iomem *base = drvdata->base; - u32 dat; - - if (!(__raw_readl(base + ACINTSTS) & ACINT_CODECRDY(ac97->num))) - return 0xffff; - reg |= ac97->num << 7; - dat = (reg << ACREGACC_REG_SHIFT) | ACREGACC_READ; - __raw_writel(dat, base + ACREGACC); - __raw_writel(ACINT_REGACCRDY, base + ACINTEN); - if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(txx9aclc_drvdata), HZ)) { - __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); - printk(KERN_ERR "ac97 read timeout (reg %#x)\n", reg); - dat = 0xffff; - goto done; - } - dat = __raw_readl(base + ACREGACC); - if (((dat >> ACREGACC_REG_SHIFT) & 0xff) != reg) { - printk(KERN_ERR "reg mismatch %x with %x\n", - dat, reg); - dat = 0xffff; - goto done; - } - dat = (dat >> ACREGACC_DAT_SHIFT) & 0xffff; -done: - __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); - return dat; -} - -/* AC97 controller writes to codec register */ -static void txx9aclc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; - void __iomem *base = drvdata->base; - - __raw_writel(((reg | (ac97->num << 7)) << ACREGACC_REG_SHIFT) | - (val << ACREGACC_DAT_SHIFT), - base + ACREGACC); - __raw_writel(ACINT_REGACCRDY, base + ACINTEN); - if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(txx9aclc_drvdata), HZ)) { - printk(KERN_ERR - "ac97 write timeout (reg %#x)\n", reg); - } - __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); -} - -static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97) -{ - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; - void __iomem *base = drvdata->base; - u32 ready = ACINT_CODECRDY(ac97->num) | ACINT_REGACCRDY; - - __raw_writel(ACCTL_ENLINK, base + ACCTLDIS); - udelay(1); - __raw_writel(ACCTL_ENLINK, base + ACCTLEN); - /* wait for primary codec ready status */ - __raw_writel(ready, base + ACINTEN); - if (!wait_event_timeout(ac97_waitq, - (__raw_readl(base + ACINTSTS) & ready) == ready, - HZ)) { - dev_err(&ac97->dev, "primary codec is not ready " - "(status %#x)\n", - __raw_readl(base + ACINTSTS)); - } - __raw_writel(ACINT_REGACCRDY, base + ACINTSTS); - __raw_writel(ready, base + ACINTDIS); -} - -/* AC97 controller operations */ -static struct snd_ac97_bus_ops txx9aclc_ac97_ops = { - .read = txx9aclc_ac97_read, - .write = txx9aclc_ac97_write, - .reset = txx9aclc_ac97_cold_reset, -}; - -static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id) -{ - struct txx9aclc_plat_drvdata *drvdata = dev_id; - void __iomem *base = drvdata->base; - - __raw_writel(__raw_readl(base + ACINTMSTS), base + ACINTDIS); - wake_up(&ac97_waitq); - return IRQ_HANDLED; -} - -static int txx9aclc_ac97_probe(struct snd_soc_dai *dai) -{ - txx9aclc_drvdata = snd_soc_dai_get_drvdata(dai); - return 0; -} - -static int txx9aclc_ac97_remove(struct snd_soc_dai *dai) -{ - struct txx9aclc_plat_drvdata *drvdata = snd_soc_dai_get_drvdata(dai); - - /* disable AC-link */ - __raw_writel(ACCTL_ENLINK, drvdata->base + ACCTLDIS); - txx9aclc_drvdata = NULL; - return 0; -} - -static struct snd_soc_dai_driver txx9aclc_ac97_dai = { - .probe = txx9aclc_ac97_probe, - .remove = txx9aclc_ac97_remove, - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, -}; - -static const struct snd_soc_component_driver txx9aclc_ac97_component = { - .name = "txx9aclc-ac97", -}; - -static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) -{ - struct txx9aclc_plat_drvdata *drvdata; - struct resource *r; - int err; - int irq; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - drvdata->base = devm_ioremap_resource(&pdev->dev, r); - if (IS_ERR(drvdata->base)) - return PTR_ERR(drvdata->base); - - platform_set_drvdata(pdev, drvdata); - drvdata->physbase = r->start; - if (sizeof(drvdata->physbase) > sizeof(r->start) && - r->start >= TXX9_DIRECTMAP_BASE && - r->start < TXX9_DIRECTMAP_BASE + 0x400000) - drvdata->physbase |= 0xf00000000ull; - err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq, - 0, dev_name(&pdev->dev), drvdata); - if (err < 0) - return err; - - err = snd_soc_set_ac97_ops(&txx9aclc_ac97_ops); - if (err < 0) - return err; - - return devm_snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component, - &txx9aclc_ac97_dai, 1); -} - -static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) -{ - snd_soc_set_ac97_ops(NULL); - return 0; -} - -static struct platform_driver txx9aclc_ac97_driver = { - .probe = txx9aclc_ac97_dev_probe, - .remove = txx9aclc_ac97_dev_remove, - .driver = { - .name = "txx9aclc-ac97", - }, -}; - -module_platform_driver(txx9aclc_ac97_driver); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("TXx9 ACLC AC97 driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:txx9aclc-ac97"); diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c deleted file mode 100644 index d6893721ba1d1..0000000000000 --- a/sound/soc/txx9/txx9aclc-generic.c +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Generic TXx9 ACLC machine driver - * - * Copyright (C) 2009 Atsushi Nemoto - * - * Based on RBTX49xx patch from CELF patch archive. - * (C) Copyright TOSHIBA CORPORATION 2004-2006 - * - * This is a very generic AC97 sound machine driver for boards which - * have (AC97) audio at ACLC (e.g. RBTX49XX boards). - */ - -#include -#include -#include -#include -#include -#include "txx9aclc.h" - -SND_SOC_DAILINK_DEFS(hifi, - DAILINK_COMP_ARRAY(COMP_CPU("txx9aclc-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("txx9aclc-pcm-audio"))); - -static struct snd_soc_dai_link txx9aclc_generic_dai = { - .name = "AC97", - .stream_name = "AC97 HiFi", - SND_SOC_DAILINK_REG(hifi), -}; - -static struct snd_soc_card txx9aclc_generic_card = { - .name = "Generic TXx9 ACLC Audio", - .owner = THIS_MODULE, - .dai_link = &txx9aclc_generic_dai, - .num_links = 1, -}; - -static struct platform_device *soc_pdev; - -static int __init txx9aclc_generic_probe(struct platform_device *pdev) -{ - int ret; - - soc_pdev = platform_device_alloc("soc-audio", -1); - if (!soc_pdev) - return -ENOMEM; - platform_set_drvdata(soc_pdev, &txx9aclc_generic_card); - ret = platform_device_add(soc_pdev); - if (ret) { - platform_device_put(soc_pdev); - return ret; - } - - return 0; -} - -static int __exit txx9aclc_generic_remove(struct platform_device *pdev) -{ - platform_device_unregister(soc_pdev); - return 0; -} - -static struct platform_driver txx9aclc_generic_driver = { - .remove = __exit_p(txx9aclc_generic_remove), - .driver = { - .name = "txx9aclc-generic", - }, -}; - -static int __init txx9aclc_generic_init(void) -{ - return platform_driver_probe(&txx9aclc_generic_driver, - txx9aclc_generic_probe); -} - -static void __exit txx9aclc_generic_exit(void) -{ - platform_driver_unregister(&txx9aclc_generic_driver); -} - -module_init(txx9aclc_generic_init); -module_exit(txx9aclc_generic_exit); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:txx9aclc-generic"); diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c deleted file mode 100644 index 1d2d0d9b57b0e..0000000000000 --- a/sound/soc/txx9/txx9aclc.c +++ /dev/null @@ -1,422 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Generic TXx9 ACLC platform driver - * - * Copyright (C) 2009 Atsushi Nemoto - * - * Based on RBTX49xx patch from CELF patch archive. - * (C) Copyright TOSHIBA CORPORATION 2004-2006 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "txx9aclc.h" - -#define DRV_NAME "txx9aclc" - -static struct txx9aclc_soc_device { - struct txx9aclc_dmadata dmadata[2]; -} txx9aclc_soc_device; - -/* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */ -static struct txx9aclc_plat_drvdata *txx9aclc_drvdata; - -static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, - struct txx9aclc_dmadata *dmadata); - -static const struct snd_pcm_hardware txx9aclc_pcm_hardware = { - /* - * REVISIT: SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID - * needs more works for noncoherent MIPS. - */ - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BATCH | - SNDRV_PCM_INFO_PAUSE, - .period_bytes_min = 1024, - .period_bytes_max = 8 * 1024, - .periods_min = 2, - .periods_max = 4096, - .buffer_bytes_max = 32 * 1024, -}; - -static int txx9aclc_pcm_hw_params(struct snd_soc_component *component, - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct txx9aclc_dmadata *dmadata = runtime->private_data; - - dev_dbg(component->dev, - "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd " - "runtime->min_align %ld\n", - (unsigned long)runtime->dma_area, - (unsigned long)runtime->dma_addr, runtime->dma_bytes, - runtime->min_align); - dev_dbg(component->dev, - "periods %d period_bytes %d stream %d\n", - params_periods(params), params_period_bytes(params), - substream->stream); - - dmadata->substream = substream; - dmadata->pos = 0; - return 0; -} - -static int txx9aclc_pcm_prepare(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct txx9aclc_dmadata *dmadata = runtime->private_data; - - dmadata->dma_addr = runtime->dma_addr; - dmadata->buffer_bytes = snd_pcm_lib_buffer_bytes(substream); - dmadata->period_bytes = snd_pcm_lib_period_bytes(substream); - - if (dmadata->buffer_bytes == dmadata->period_bytes) { - dmadata->frag_bytes = dmadata->period_bytes >> 1; - dmadata->frags = 2; - } else { - dmadata->frag_bytes = dmadata->period_bytes; - dmadata->frags = dmadata->buffer_bytes / dmadata->period_bytes; - } - dmadata->frag_count = 0; - dmadata->pos = 0; - return 0; -} - -static void txx9aclc_dma_complete(void *arg) -{ - struct txx9aclc_dmadata *dmadata = arg; - unsigned long flags; - - /* dma completion handler cannot submit new operations */ - spin_lock_irqsave(&dmadata->dma_lock, flags); - if (dmadata->frag_count >= 0) { - dmadata->dmacount--; - if (!WARN_ON(dmadata->dmacount < 0)) - queue_work(system_highpri_wq, &dmadata->work); - } - spin_unlock_irqrestore(&dmadata->dma_lock, flags); -} - -static struct dma_async_tx_descriptor * -txx9aclc_dma_submit(struct txx9aclc_dmadata *dmadata, dma_addr_t buf_dma_addr) -{ - struct dma_chan *chan = dmadata->dma_chan; - struct dma_async_tx_descriptor *desc; - struct scatterlist sg; - - sg_init_table(&sg, 1); - sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf_dma_addr)), - dmadata->frag_bytes, buf_dma_addr & (PAGE_SIZE - 1)); - sg_dma_address(&sg) = buf_dma_addr; - desc = dmaengine_prep_slave_sg(chan, &sg, 1, - dmadata->substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc) { - dev_err(&chan->dev->device, "cannot prepare slave dma\n"); - return NULL; - } - desc->callback = txx9aclc_dma_complete; - desc->callback_param = dmadata; - dmaengine_submit(desc); - return desc; -} - -#define NR_DMA_CHAIN 2 - -static void txx9aclc_dma_work(struct work_struct *work) -{ - struct txx9aclc_dmadata *dmadata = - container_of(work, struct txx9aclc_dmadata, work); - struct dma_chan *chan = dmadata->dma_chan; - struct dma_async_tx_descriptor *desc; - struct snd_pcm_substream *substream = dmadata->substream; - u32 ctlbit = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - ACCTL_AUDODMA : ACCTL_AUDIDMA; - int i; - unsigned long flags; - - spin_lock_irqsave(&dmadata->dma_lock, flags); - if (dmadata->frag_count < 0) { - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; - void __iomem *base = drvdata->base; - - spin_unlock_irqrestore(&dmadata->dma_lock, flags); - dmaengine_terminate_all(chan); - /* first time */ - for (i = 0; i < NR_DMA_CHAIN; i++) { - desc = txx9aclc_dma_submit(dmadata, - dmadata->dma_addr + i * dmadata->frag_bytes); - if (!desc) - return; - } - dmadata->dmacount = NR_DMA_CHAIN; - dma_async_issue_pending(chan); - spin_lock_irqsave(&dmadata->dma_lock, flags); - __raw_writel(ctlbit, base + ACCTLEN); - dmadata->frag_count = NR_DMA_CHAIN % dmadata->frags; - spin_unlock_irqrestore(&dmadata->dma_lock, flags); - return; - } - if (WARN_ON(dmadata->dmacount >= NR_DMA_CHAIN)) { - spin_unlock_irqrestore(&dmadata->dma_lock, flags); - return; - } - while (dmadata->dmacount < NR_DMA_CHAIN) { - dmadata->dmacount++; - spin_unlock_irqrestore(&dmadata->dma_lock, flags); - desc = txx9aclc_dma_submit(dmadata, - dmadata->dma_addr + - dmadata->frag_count * dmadata->frag_bytes); - if (!desc) - return; - dma_async_issue_pending(chan); - - spin_lock_irqsave(&dmadata->dma_lock, flags); - dmadata->frag_count++; - dmadata->frag_count %= dmadata->frags; - dmadata->pos += dmadata->frag_bytes; - dmadata->pos %= dmadata->buffer_bytes; - if ((dmadata->frag_count * dmadata->frag_bytes) % - dmadata->period_bytes == 0) - snd_pcm_period_elapsed(substream); - } - spin_unlock_irqrestore(&dmadata->dma_lock, flags); -} - -static int txx9aclc_pcm_trigger(struct snd_soc_component *component, - struct snd_pcm_substream *substream, int cmd) -{ - struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; - void __iomem *base = drvdata->base; - unsigned long flags; - int ret = 0; - u32 ctlbit = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - ACCTL_AUDODMA : ACCTL_AUDIDMA; - - spin_lock_irqsave(&dmadata->dma_lock, flags); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - dmadata->frag_count = -1; - queue_work(system_highpri_wq, &dmadata->work); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_SUSPEND: - __raw_writel(ctlbit, base + ACCTLDIS); - break; - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_RESUME: - __raw_writel(ctlbit, base + ACCTLEN); - break; - default: - ret = -EINVAL; - } - spin_unlock_irqrestore(&dmadata->dma_lock, flags); - return ret; -} - -static snd_pcm_uframes_t -txx9aclc_pcm_pointer(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; - - return bytes_to_frames(substream->runtime, dmadata->pos); -} - -static int txx9aclc_pcm_open(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct txx9aclc_soc_device *dev = &txx9aclc_soc_device; - struct txx9aclc_dmadata *dmadata = &dev->dmadata[substream->stream]; - int ret; - - ret = snd_soc_set_runtime_hwparams(substream, &txx9aclc_pcm_hardware); - if (ret) - return ret; - /* ensure that buffer size is a multiple of period size */ - ret = snd_pcm_hw_constraint_integer(substream->runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) - return ret; - substream->runtime->private_data = dmadata; - return 0; -} - -static int txx9aclc_pcm_close(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; - struct dma_chan *chan = dmadata->dma_chan; - - dmadata->frag_count = -1; - dmaengine_terminate_all(chan); - return 0; -} - -static int txx9aclc_pcm_new(struct snd_soc_component *component, - struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); - struct snd_pcm *pcm = rtd->pcm; - struct platform_device *pdev = to_platform_device(component->dev); - struct txx9aclc_soc_device *dev; - struct resource *r; - int i; - int ret; - - /* at this point onwards the AC97 component has probed and this will be valid */ - dev = snd_soc_dai_get_drvdata(dai); - - dev->dmadata[0].stream = SNDRV_PCM_STREAM_PLAYBACK; - dev->dmadata[1].stream = SNDRV_PCM_STREAM_CAPTURE; - for (i = 0; i < 2; i++) { - r = platform_get_resource(pdev, IORESOURCE_DMA, i); - if (!r) { - ret = -EBUSY; - goto exit; - } - dev->dmadata[i].dma_res = r; - ret = txx9aclc_dma_init(dev, &dev->dmadata[i]); - if (ret) - goto exit; - } - - snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, - card->dev, 64 * 1024, 4 * 1024 * 1024); - return 0; - -exit: - for (i = 0; i < 2; i++) { - if (dev->dmadata[i].dma_chan) - dma_release_channel(dev->dmadata[i].dma_chan); - dev->dmadata[i].dma_chan = NULL; - } - return ret; -} - -static bool filter(struct dma_chan *chan, void *param) -{ - struct txx9aclc_dmadata *dmadata = param; - char *devname; - bool found = false; - - devname = kasprintf(GFP_KERNEL, "%s.%d", dmadata->dma_res->name, - (int)dmadata->dma_res->start); - if (strcmp(dev_name(chan->device->dev), devname) == 0) { - chan->private = &dmadata->dma_slave; - found = true; - } - kfree(devname); - return found; -} - -static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, - struct txx9aclc_dmadata *dmadata) -{ - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; - struct txx9dmac_slave *ds = &dmadata->dma_slave; - dma_cap_mask_t mask; - - spin_lock_init(&dmadata->dma_lock); - - ds->reg_width = sizeof(u32); - if (dmadata->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ds->tx_reg = drvdata->physbase + ACAUDODAT; - ds->rx_reg = 0; - } else { - ds->tx_reg = 0; - ds->rx_reg = drvdata->physbase + ACAUDIDAT; - } - - /* Try to grab a DMA channel */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dmadata->dma_chan = dma_request_channel(mask, filter, dmadata); - if (!dmadata->dma_chan) { - printk(KERN_ERR - "DMA channel for %s is not available\n", - dmadata->stream == SNDRV_PCM_STREAM_PLAYBACK ? - "playback" : "capture"); - return -EBUSY; - } - INIT_WORK(&dmadata->work, txx9aclc_dma_work); - return 0; -} - -static int txx9aclc_pcm_probe(struct snd_soc_component *component) -{ - snd_soc_component_set_drvdata(component, &txx9aclc_soc_device); - return 0; -} - -static void txx9aclc_pcm_remove(struct snd_soc_component *component) -{ - struct txx9aclc_soc_device *dev = snd_soc_component_get_drvdata(component); - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; - void __iomem *base = drvdata->base; - int i; - - /* disable all FIFO DMAs */ - __raw_writel(ACCTL_AUDODMA | ACCTL_AUDIDMA, base + ACCTLDIS); - /* dummy R/W to clear pending DMAREQ if any */ - __raw_writel(__raw_readl(base + ACAUDIDAT), base + ACAUDODAT); - - for (i = 0; i < 2; i++) { - struct txx9aclc_dmadata *dmadata = &dev->dmadata[i]; - struct dma_chan *chan = dmadata->dma_chan; - - if (chan) { - dmadata->frag_count = -1; - dmaengine_terminate_all(chan); - dma_release_channel(chan); - } - dev->dmadata[i].dma_chan = NULL; - } -} - -static const struct snd_soc_component_driver txx9aclc_soc_component = { - .name = DRV_NAME, - .probe = txx9aclc_pcm_probe, - .remove = txx9aclc_pcm_remove, - .open = txx9aclc_pcm_open, - .close = txx9aclc_pcm_close, - .hw_params = txx9aclc_pcm_hw_params, - .prepare = txx9aclc_pcm_prepare, - .trigger = txx9aclc_pcm_trigger, - .pointer = txx9aclc_pcm_pointer, - .pcm_construct = txx9aclc_pcm_new, -}; - -static int txx9aclc_soc_platform_probe(struct platform_device *pdev) -{ - return devm_snd_soc_register_component(&pdev->dev, - &txx9aclc_soc_component, NULL, 0); -} - -static struct platform_driver txx9aclc_pcm_driver = { - .driver = { - .name = "txx9aclc-pcm-audio", - }, - - .probe = txx9aclc_soc_platform_probe, -}; - -module_platform_driver(txx9aclc_pcm_driver); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/txx9/txx9aclc.h b/sound/soc/txx9/txx9aclc.h deleted file mode 100644 index 37c691ba56edb..0000000000000 --- a/sound/soc/txx9/txx9aclc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * TXx9 SoC AC Link Controller - */ - -#ifndef __TXX9ACLC_H -#define __TXX9ACLC_H - -#include -#include - -#define ACCTLEN 0x00 /* control enable */ -#define ACCTLDIS 0x04 /* control disable */ -#define ACCTL_ENLINK 0x00000001 /* enable/disable AC-link */ -#define ACCTL_AUDODMA 0x00000100 /* AUDODMA enable/disable */ -#define ACCTL_AUDIDMA 0x00001000 /* AUDIDMA enable/disable */ -#define ACCTL_AUDOEHLT 0x00010000 /* AUDO error halt - enable/disable */ -#define ACCTL_AUDIEHLT 0x00100000 /* AUDI error halt - enable/disable */ -#define ACREGACC 0x08 /* codec register access */ -#define ACREGACC_DAT_SHIFT 0 /* data field */ -#define ACREGACC_REG_SHIFT 16 /* address field */ -#define ACREGACC_CODECID_SHIFT 24 /* CODEC ID field */ -#define ACREGACC_READ 0x80000000 /* CODEC read */ -#define ACREGACC_WRITE 0x00000000 /* CODEC write */ -#define ACINTSTS 0x10 /* interrupt status */ -#define ACINTMSTS 0x14 /* interrupt masked status */ -#define ACINTEN 0x18 /* interrupt enable */ -#define ACINTDIS 0x1c /* interrupt disable */ -#define ACINT_CODECRDY(n) (0x00000001 << (n)) /* CODECn ready */ -#define ACINT_REGACCRDY 0x00000010 /* ACREGACC ready */ -#define ACINT_AUDOERR 0x00000100 /* AUDO underrun error */ -#define ACINT_AUDIERR 0x00001000 /* AUDI overrun error */ -#define ACDMASTS 0x80 /* DMA request status */ -#define ACDMA_AUDO 0x00000001 /* AUDODMA pending */ -#define ACDMA_AUDI 0x00000010 /* AUDIDMA pending */ -#define ACAUDODAT 0xa0 /* audio out data */ -#define ACAUDIDAT 0xb0 /* audio in data */ -#define ACREVID 0xfc /* revision ID */ - -struct txx9aclc_dmadata { - struct resource *dma_res; - struct txx9dmac_slave dma_slave; - struct dma_chan *dma_chan; - struct work_struct work; - spinlock_t dma_lock; - int stream; /* SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE */ - struct snd_pcm_substream *substream; - unsigned long pos; - dma_addr_t dma_addr; - unsigned long buffer_bytes; - unsigned long period_bytes; - unsigned long frag_bytes; - int frags; - int frag_count; - int dmacount; -}; - -struct txx9aclc_plat_drvdata { - void __iomem *base; - u64 physbase; -}; - -static inline struct txx9aclc_plat_drvdata *txx9aclc_get_plat_drvdata( - struct snd_soc_dai *dai) -{ - return dev_get_drvdata(dai->dev); -} - -#endif /* __TXX9ACLC_H */ -- GitLab From f477a538c14d07f8c45e554c8c5208d588514e98 Mon Sep 17 00:00:00 2001 From: Necip Fazil Yildiran Date: Thu, 17 Sep 2020 18:45:48 +0300 Subject: [PATCH 0073/1084] sh: dma: fix kconfig dependency for G2_DMA When G2_DMA is enabled and SH_DMA is disabled, it results in the following Kbuild warning: WARNING: unmet direct dependencies detected for SH_DMA_API Depends on [n]: SH_DMA [=n] Selected by [y]: - G2_DMA [=y] && SH_DREAMCAST [=y] The reason is that G2_DMA selects SH_DMA_API without depending on or selecting SH_DMA while SH_DMA_API depends on SH_DMA. When G2_DMA was first introduced with commit 40f49e7ed77f ("sh: dma: Make G2 DMA configurable."), this wasn't an issue since SH_DMA_API didn't have such dependency, and this way was the only way to enable it since SH_DMA_API was non-visible. However, later SH_DMA_API was made visible and dependent on SH_DMA with commit d8902adcc1a9 ("dmaengine: sh: Add Support SuperH DMA Engine driver"). Let G2_DMA depend on SH_DMA_API instead to avoid Kbuild issues. Fixes: d8902adcc1a9 ("dmaengine: sh: Add Support SuperH DMA Engine driver") Signed-off-by: Necip Fazil Yildiran Signed-off-by: Rich Felker --- arch/sh/drivers/dma/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index d0de378beefe5..7d54f284ce10f 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig @@ -63,8 +63,7 @@ config PVR2_DMA config G2_DMA tristate "G2 Bus DMA support" - depends on SH_DREAMCAST - select SH_DMA_API + depends on SH_DREAMCAST && SH_DMA_API help This enables support for the DMA controller for the Dreamcast's G2 bus. Drivers that want this will generally enable this on -- GitLab From 7fb0a1a5e56779c427b409d6e53889d46519755e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 17 Sep 2020 19:14:04 -0700 Subject: [PATCH 0074/1084] arch/sh: hyphenate Non-Uniform in Kconfig prompt Hyphenate Non-Uniform in the NUMA kconfig prompt. Signed-off-by: Randy Dunlap Cc: Yoshinori Sato Cc: Rich Felker Cc: linux-sh@vger.kernel.org Cc: Jiri Kosina Signed-off-by: Rich Felker --- arch/sh/mm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 703d3069997cb..77aa2f802d8d1 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -105,7 +105,7 @@ config VSYSCALL (the default value) say Y. config NUMA - bool "Non Uniform Memory Access (NUMA) Support" + bool "Non-Uniform Memory Access (NUMA) Support" depends on MMU && SYS_SUPPORTS_NUMA select ARCH_WANT_NUMA_VARIABLE_LOCALITY default n -- GitLab From 5c5dc5f8dccbafaacc8c97bbe7762986bdda6f63 Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Sat, 19 Sep 2020 10:52:06 +0800 Subject: [PATCH 0075/1084] sh: intc: Convert to DEFINE_SHOW_ATTRIBUTE Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code. Signed-off-by: Qinglang Miao Signed-off-by: Rich Felker --- drivers/sh/intc/virq-debugfs.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/sh/intc/virq-debugfs.c b/drivers/sh/intc/virq-debugfs.c index 9e62ba9311f07..939915a07d999 100644 --- a/drivers/sh/intc/virq-debugfs.c +++ b/drivers/sh/intc/virq-debugfs.c @@ -16,7 +16,7 @@ #include #include "internals.h" -static int intc_irq_xlate_debug(struct seq_file *m, void *priv) +static int intc_irq_xlate_show(struct seq_file *m, void *priv) { int i; @@ -37,17 +37,7 @@ static int intc_irq_xlate_debug(struct seq_file *m, void *priv) return 0; } -static int intc_irq_xlate_open(struct inode *inode, struct file *file) -{ - return single_open(file, intc_irq_xlate_debug, inode->i_private); -} - -static const struct file_operations intc_irq_xlate_fops = { - .open = intc_irq_xlate_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(intc_irq_xlate); static int __init intc_irq_xlate_init(void) { -- GitLab From a1153636e904faf2b30fae3fb6ee3f4f4d0175c8 Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Sat, 19 Sep 2020 10:52:05 +0800 Subject: [PATCH 0076/1084] sh: mm: Convert to DEFINE_SHOW_ATTRIBUTE Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code. Signed-off-by: Qinglang Miao Signed-off-by: Rich Felker --- arch/sh/mm/asids-debugfs.c | 15 ++------------- arch/sh/mm/cache-debugfs.c | 15 ++------------- arch/sh/mm/pmb.c | 15 ++------------- 3 files changed, 6 insertions(+), 39 deletions(-) diff --git a/arch/sh/mm/asids-debugfs.c b/arch/sh/mm/asids-debugfs.c index 4c1ca197e9c5f..d16d6f5ec7749 100644 --- a/arch/sh/mm/asids-debugfs.c +++ b/arch/sh/mm/asids-debugfs.c @@ -26,7 +26,7 @@ #include #include -static int asids_seq_show(struct seq_file *file, void *iter) +static int asids_debugfs_show(struct seq_file *file, void *iter) { struct task_struct *p; @@ -48,18 +48,7 @@ static int asids_seq_show(struct seq_file *file, void *iter) return 0; } -static int asids_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, asids_seq_show, inode->i_private); -} - -static const struct file_operations asids_debugfs_fops = { - .owner = THIS_MODULE, - .open = asids_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(asids_debugfs); static int __init asids_debugfs_init(void) { diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c index 17d7807944971..b0f185169dfa0 100644 --- a/arch/sh/mm/cache-debugfs.c +++ b/arch/sh/mm/cache-debugfs.c @@ -22,7 +22,7 @@ enum cache_type { CACHE_TYPE_UNIFIED, }; -static int cache_seq_show(struct seq_file *file, void *iter) +static int cache_debugfs_show(struct seq_file *file, void *iter) { unsigned int cache_type = (unsigned int)file->private; struct cache_info *cache; @@ -94,18 +94,7 @@ static int cache_seq_show(struct seq_file *file, void *iter) return 0; } -static int cache_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, cache_seq_show, inode->i_private); -} - -static const struct file_operations cache_debugfs_fops = { - .owner = THIS_MODULE, - .open = cache_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(cache_debugfs); static int __init cache_debugfs_init(void) { diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index b20aba6e1b37c..68eb7cc6e5643 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -812,7 +812,7 @@ bool __in_29bit_mode(void) return (__raw_readl(PMB_PASCR) & PASCR_SE) == 0; } -static int pmb_seq_show(struct seq_file *file, void *iter) +static int pmb_debugfs_show(struct seq_file *file, void *iter) { int i; @@ -846,18 +846,7 @@ static int pmb_seq_show(struct seq_file *file, void *iter) return 0; } -static int pmb_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, pmb_seq_show, NULL); -} - -static const struct file_operations pmb_debugfs_fops = { - .owner = THIS_MODULE, - .open = pmb_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(pmb_debugfs); static int __init pmb_debugfs_init(void) { -- GitLab From b7aaf16d10bd9f1fbc5beefb9496e029fd1424ba Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 24 Sep 2020 06:31:39 +0200 Subject: [PATCH 0077/1084] sh: remove CONFIG_IDE from most defconfig Remove CONFIG_IDE from defconfigs that did not actually select chipset drivers, and switch ones that have libata drivers to libata. Signed-off-by: Christoph Hellwig Signed-off-by: Rich Felker --- arch/sh/configs/landisk_defconfig | 9 ++++----- arch/sh/configs/microdev_defconfig | 2 -- arch/sh/configs/sdk7780_defconfig | 6 ++---- arch/sh/configs/sdk7786_defconfig | 3 --- arch/sh/configs/se7750_defconfig | 1 - arch/sh/configs/sh03_defconfig | 3 --- 6 files changed, 6 insertions(+), 18 deletions(-) diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index ba6ec042606f5..e6c5ddf070c00 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -27,13 +27,12 @@ CONFIG_NETFILTER=y CONFIG_ATALK=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_OFFBOARD=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_AEC62XX=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_ATP867X=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y CONFIG_SCSI_MULTI_LUN=y CONFIG_MD=y CONFIG_BLK_DEV_MD=m diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig index c65667d00313b..e9825196dd66a 100644 --- a/arch/sh/configs/microdev_defconfig +++ b/arch/sh/configs/microdev_defconfig @@ -20,8 +20,6 @@ CONFIG_IP_PNP=y # CONFIG_IPV6 is not set # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig index d10a0414123a5..d00376eb044f8 100644 --- a/arch/sh/configs/sdk7780_defconfig +++ b/arch/sh/configs/sdk7780_defconfig @@ -44,16 +44,14 @@ CONFIG_NET_SCHED=y CONFIG_PARPORT=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_PLATFORM=y -CONFIG_BLK_DEV_GENERIC=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_PLATFORM=y CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_NETDEVICES=y diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 61bec46ebd66a..4a44cac640bc9 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig @@ -116,9 +116,6 @@ CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_PLATFORM=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y CONFIG_SCSI_MULTI_LUN=y diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig index 3f1c13799d799..4defc7628a498 100644 --- a/arch/sh/configs/se7750_defconfig +++ b/arch/sh/configs/se7750_defconfig @@ -29,7 +29,6 @@ CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_ROM=y -CONFIG_IDE=y CONFIG_SCSI=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig index f0073ed399477..48b457d59e790 100644 --- a/arch/sh/configs/sh03_defconfig +++ b/arch/sh/configs/sh03_defconfig @@ -39,9 +39,6 @@ CONFIG_IP_PNP_RARP=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_IDETAPE=m CONFIG_SCSI=m CONFIG_BLK_DEV_SD=m CONFIG_BLK_DEV_SR=m -- GitLab From 19170492735be935747b0545b7eed8bb40cc1209 Mon Sep 17 00:00:00 2001 From: Jinyang He Date: Mon, 12 Oct 2020 11:50:24 +0800 Subject: [PATCH 0078/1084] sh: Remove unused HAVE_COPY_THREAD_TLS macro Fixes: e1cc9d8d596e ("sh: switch to copy_thread_tls()") Signed-off-by: Jinyang He Signed-off-by: Rich Felker --- arch/sh/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5fa580219a864..52646f52f130f 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -29,7 +29,6 @@ config SUPERH select HAVE_ARCH_KGDB select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK - select HAVE_COPY_THREAD_TLS select HAVE_DEBUG_BUGVERBOSE select HAVE_DEBUG_KMEMLEAK select HAVE_DYNAMIC_FTRACE -- GitLab From 542baf5108e052684c3abdeea57861f12f89a6b9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 12 Oct 2020 18:40:50 +0300 Subject: [PATCH 0079/1084] sh: Drop ARCH_NR_GPIOS definition The default by generic header is the same, hence drop unnecessary definition. Signed-off-by: Andy Shevchenko Signed-off-by: Rich Felker --- arch/sh/include/asm/gpio.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sh/include/asm/gpio.h b/arch/sh/include/asm/gpio.h index 351918894e867..d643250f0a0fa 100644 --- a/arch/sh/include/asm/gpio.h +++ b/arch/sh/include/asm/gpio.h @@ -16,7 +16,6 @@ #include #endif -#define ARCH_NR_GPIOS 512 #include #ifdef CONFIG_GPIOLIB -- GitLab From 7a202ec74c151e30edc1d17e3209fe6d6fe50eee Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Mon, 9 Nov 2020 10:45:51 +0800 Subject: [PATCH 0080/1084] arch: sh: remove duplicate include Remove duplicate header which is included twice. Signed-off-by: Wang Qing Signed-off-by: Rich Felker --- arch/sh/kernel/cpu/sh3/entry.S | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 25eb809054160..e48b3dd996f58 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -14,7 +14,6 @@ #include #include #include -#include ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address -- GitLab From a118584e7e60fa72ee441055b33b41c3354dba7e Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Mon, 9 Nov 2020 10:35:01 +0800 Subject: [PATCH 0081/1084] sh: mach-sh03: remove duplicate include Remove duplicate header which is included twice. Signed-off-by: Wang Qing Signed-off-by: Rich Felker --- arch/sh/boards/mach-sh03/rtc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sh/boards/mach-sh03/rtc.c b/arch/sh/boards/mach-sh03/rtc.c index 8b23ed7c201c6..7fb474844a2d1 100644 --- a/arch/sh/boards/mach-sh03/rtc.c +++ b/arch/sh/boards/mach-sh03/rtc.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include -- GitLab From b89bc060b53e7054e5c8ca11feea4bc884d83611 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Nov 2020 16:49:39 +0100 Subject: [PATCH 0082/1084] sh/intc: Restore devm_ioremap() alignment Restore alignment of the continuation of the devm_ioremap() call in register_intc_controller(). Fixes: 4bdc0d676a643140 ("remove ioremap_nocache and devm_ioremap_nocache") Signed-off-by: Geert Uytterhoeven Signed-off-by: Rich Felker --- drivers/sh/intc/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index f8e070d67fa32..a14684ffe4c1a 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -214,7 +214,7 @@ int __init register_intc_controller(struct intc_desc *desc) d->window[k].phys = res->start; d->window[k].size = resource_size(res); d->window[k].virt = ioremap(res->start, - resource_size(res)); + resource_size(res)); if (!d->window[k].virt) goto err2; } -- GitLab From b33cf814b1eb65ef5c939ced8266bb3df18444ef Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 7 Dec 2020 14:53:24 +0800 Subject: [PATCH 0083/1084] arm64: dts: imx8mn: Fix duplicate node name Error log: sysfs: cannot create duplicate filename '/bus/platform/devices/30000000.bus' The spba bus name is duplicate with aips bus name. Refine spba bus name to fix this issue. Fixes: 970406eaef3a ("arm64: dts: imx8mn: Enable Asynchronous Sample Rate Converter") Signed-off-by: Shengjiu Wang Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mn.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi index ee1790230490d..2a79e89f821ee 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi @@ -253,7 +253,7 @@ #size-cells = <1>; ranges; - spba: bus@30000000 { + spba: spba-bus@30000000 { compatible = "fsl,spba-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; -- GitLab From c14556fc0c7c115ffb4a287560e1ec9f7869aac3 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 17 Dec 2020 12:39:11 +0300 Subject: [PATCH 0084/1084] thunderbolt: Drop duplicated 0x prefix from format string The tb_dbg() call is using %#x that already adds the 0x prefix so don't duplicate it. Fixes: 9039387e166e ("thunderbolt: Add USB4 router operation proxy for firmware connection manager") Signed-off-by: Mika Westerberg Reviewed-by: Yehezkel Bernat --- drivers/thunderbolt/icm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c index 8b7f941a9bb7f..b8c4159bc32d0 100644 --- a/drivers/thunderbolt/icm.c +++ b/drivers/thunderbolt/icm.c @@ -2316,7 +2316,7 @@ static int icm_usb4_switch_nvm_authenticate_status(struct tb_switch *sw, if (auth && auth->reply.route_hi == sw->config.route_hi && auth->reply.route_lo == sw->config.route_lo) { - tb_dbg(tb, "NVM_AUTH found for %llx flags 0x%#x status %#x\n", + tb_dbg(tb, "NVM_AUTH found for %llx flags %#x status %#x\n", tb_route(sw), auth->reply.hdr.flags, auth->reply.status); if (auth->reply.hdr.flags & ICM_FLAGS_ERROR) ret = -EIO; -- GitLab From ff474acc4b1a9a15e29c42a41942e6932fa4f01f Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 11 Dec 2020 23:21:28 +0100 Subject: [PATCH 0085/1084] media: ccs-pll: Fix link frequency for C-PHY The highest fundamental frequency signal for C-PHY is half of the symbol rate which is similar to D-PHY. Take this into account in ccs-pll. Also remove the outdated comment. Fixes: 8030aa4f9c51 ("media: ccs-pll: Add C-PHY support") Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ccs-pll.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index eb7b6f01f6231..58ca47e904a14 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -772,14 +772,8 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim, switch (pll->bus_type) { case CCS_PLL_BUS_TYPE_CSI2_DPHY: - /* CSI transfers 2 bits per clock per lane; thus times 2 */ - op_sys_clk_freq_hz_sdr = pll->link_freq * 2 - * (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ? - 1 : pll->csi2.lanes); - break; case CCS_PLL_BUS_TYPE_CSI2_CPHY: - op_sys_clk_freq_hz_sdr = - pll->link_freq + op_sys_clk_freq_hz_sdr = pll->link_freq * 2 * (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ? 1 : pll->csi2.lanes); break; -- GitLab From 1bc0b1baf26efa23c0fd6fdcc24297e7d94f37ac Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 15 Dec 2020 21:31:12 +0100 Subject: [PATCH 0086/1084] media: ccs: Get static data version minor correctly Fix obtaining CCS static data version minor part correctly. Instead, the upper 8 bits were obtained from the major version number. Fixes: a6b396f410b1 ("media: ccs: Add CCS static data parser library") Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ccs/ccs-data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs/ccs-data.c b/drivers/media/i2c/ccs/ccs-data.c index 9a6097b088bdf..6555bd4b325a6 100644 --- a/drivers/media/i2c/ccs/ccs-data.c +++ b/drivers/media/i2c/ccs/ccs-data.c @@ -152,7 +152,7 @@ static int ccs_data_parse_version(struct bin_container *bin, vv->version_major = ((u16)v->static_data_version_major[0] << 8) + v->static_data_version_major[1]; vv->version_minor = ((u16)v->static_data_version_minor[0] << 8) + - v->static_data_version_major[1]; + v->static_data_version_minor[1]; vv->date_year = ((u16)v->year[0] << 8) + v->year[1]; vv->date_month = v->month; vv->date_day = v->day; -- GitLab From e99a8f0f6344fee25cd30907c30ac0ca2f02804d Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 4 Dec 2020 18:38:33 +0100 Subject: [PATCH 0087/1084] media: rcar-vin: fix return, use ret instead of zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the return error code is in ret is being assigned but not used. It and should be returned by the return statement and currently just 0 is being returned. Fix this. Addresses-Coverity: ("Unused value") Fixes: b9ad52aafe38 ("media: rcar-vin: Rework parallel firmware parsing") Signed-off-by: Colin Ian King Reviewed-by: Niklas Söderlund Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar-vin/rcar-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 98bff765b02e6..e48d666f2c63a 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -654,7 +654,7 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin) out: fwnode_handle_put(fwnode); - return 0; + return ret; } static int rvin_parallel_init(struct rvin_dev *vin) -- GitLab From 2984a99ff1c071c85dc09451c8adc859c22fbb96 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 17 Dec 2020 18:57:05 +0100 Subject: [PATCH 0088/1084] media: v4l: common: Fix naming of v4l2_get_link_rate Rename v4l2_get_link_rate() as v4l2_get_link_freq(). What the function returns is the frequency of the link; rename it to reflect the name of the control where the information is obtained. Fixes: 1b888b3cebef ("media: v4l: Add a helper for obtaining the link frequency") Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 2 +- drivers/media/v4l2-core/v4l2-common.c | 4 ++-- include/media/v4l2-common.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index 36e354ecf71ec..6cada8a6e50cc 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -302,7 +302,7 @@ static int cio2_csi2_calc_timing(struct cio2_device *cio2, struct cio2_queue *q, if (!q->sensor) return -ENODEV; - freq = v4l2_get_link_rate(q->sensor->ctrl_handler, bpp, lanes); + freq = v4l2_get_link_freq(q->sensor->ctrl_handler, bpp, lanes); if (freq < 0) { dev_err(dev, "error %lld, invalid link_freq\n", freq); return freq; diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index 78007dba4677c..133d20e40f82a 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -442,7 +442,7 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, } EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt); -s64 v4l2_get_link_rate(struct v4l2_ctrl_handler *handler, unsigned int mul, +s64 v4l2_get_link_freq(struct v4l2_ctrl_handler *handler, unsigned int mul, unsigned int div) { struct v4l2_ctrl *ctrl; @@ -473,4 +473,4 @@ s64 v4l2_get_link_rate(struct v4l2_ctrl_handler *handler, unsigned int mul, return freq > 0 ? freq : -EINVAL; } -EXPORT_SYMBOL_GPL(v4l2_get_link_rate); +EXPORT_SYMBOL_GPL(v4l2_get_link_freq); diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index be36cbdcc1bd2..3eb202259e8cc 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -520,7 +520,7 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, u32 width, u32 height); /** - * v4l2_get_link_rate - Get link rate from transmitter + * v4l2_get_link_freq - Get link rate from transmitter * * @handler: The transmitter's control handler * @mul: The multiplier between pixel rate and link frequency. Bits per pixel on @@ -537,7 +537,7 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, * -ENOENT: Link frequency or pixel rate control not found * -EINVAL: Invalid link frequency value */ -s64 v4l2_get_link_rate(struct v4l2_ctrl_handler *handler, unsigned int mul, +s64 v4l2_get_link_freq(struct v4l2_ctrl_handler *handler, unsigned int mul, unsigned int div); static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf) -- GitLab From aac568269bd80a510758ec5d5744b1a2eea3f049 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 7 Jan 2021 13:07:57 +0100 Subject: [PATCH 0089/1084] ASoC: Intel: bytcht_es8316: Remove comment about SSP0 being untested Remove a stale comment about SSP0 being untested, the bytcht_es8316 has supported SSP0 for a while now and this has been successfully tested on a GP electrinic T701 tablet. Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20210107120757.12051-1-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcht_es8316.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 892cf684216e3..06df2d46d910b 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -331,9 +331,6 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = { /* back ends */ { - /* Only SSP2 has been tested here, so BYT-CR platforms that - * require SSP0 will not work. - */ .name = "SSP2-Codec", .id = 0, .no_pcm = 1, -- GitLab From 2c1382840c194533399818d0ed39dfc94f906187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=81=BF=E7=81=BF?= Date: Fri, 25 Dec 2020 16:42:46 +0800 Subject: [PATCH 0090/1084] ASoC: soc-pcm: disconnect BEs if the FE is not ready FE is connected to two BEs, BE1 is active, BE2 is deactive. When closing BE1, FE/BE1 is in HW_FREE state, then BE2 is startup by mixer runtime update. For FE is in HW_FREE state, dpcm_run_update_startup() will skip BE2's startup because FE's state is HW_FREE, BE2 stays in FE's be_clients list. During FE's closed, the dpcm_fe_dai_close() will close all related BEs, BE2 will be closed. This will lead to BE2's dpcm[stream].users mismatch. We need disconnet all pending BEs in the corner case. Signed-off-by: zhucancan Link: https://lore.kernel.org/r/AAoArwDfDnoefyxzy2wyiaqm.1.1608885766936.Hmail.zhucancan@vivo.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index ee51dc7fd8937..481a4a25acb04 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2440,8 +2440,11 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) /* Only start the BE if the FE is ready */ if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_FREE || - fe->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE) - return -EINVAL; + fe->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE) { + dev_err(fe->dev, "ASoC: FE %s is not ready %d\n", + fe->dai_link->name, fe->dpcm[stream].state); + goto disconnect; + } /* startup must always be called for new BEs */ ret = dpcm_be_dai_startup(fe, stream); @@ -2502,12 +2505,18 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) close: dpcm_be_dai_shutdown(fe, stream); disconnect: - /* disconnect any closed BEs */ + /* disconnect any pending BEs */ spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_be(fe, stream, dpcm) { struct snd_soc_pcm_runtime *be = dpcm->be; - if (be->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE) - dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; + + /* is this op for this BE ? */ + if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + continue; + + if (be->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE || + be->dpcm[stream].state == SND_SOC_DPCM_STATE_NEW) + dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; } spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); -- GitLab From 491b1bea00040233b791dc8fea1608ac6a7003bc Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 8 Jan 2021 08:35:30 +0800 Subject: [PATCH 0091/1084] MAINTAINERS: update Peter Chen's email address Using kernel.org as my email address. Signed-off-by: Peter Chen --- MAINTAINERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index afe3a5c66bc90..c16a2e83e1764 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3881,7 +3881,7 @@ F: Documentation/devicetree/bindings/mtd/cadence-nand-controller.txt F: drivers/mtd/nand/raw/cadence-nand-controller.c CADENCE USB3 DRD IP DRIVER -M: Peter Chen +M: Peter Chen M: Pawel Laszczak R: Roger Quadros R: Aswath Govindraju @@ -4163,7 +4163,7 @@ S: Maintained F: Documentation/translations/zh_CN/ CHIPIDEA USB HIGH SPEED DUAL ROLE CONTROLLER -M: Peter Chen +M: Peter Chen L: linux-usb@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git @@ -18404,7 +18404,7 @@ F: Documentation/usb/ohci.rst F: drivers/usb/host/ohci* USB OTG FSM (Finite State Machine) -M: Peter Chen +M: Peter Chen L: linux-usb@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git -- GitLab From 0b2894cd0fdf8ccc8a9b4e28563db9ac0ecb62b2 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 4 Jan 2021 17:50:26 +0200 Subject: [PATCH 0092/1084] scsi: docs: ABI: sysfs-driver-ufs: Add DeepSleep power mode Update sysfs documentation for addition of DeepSleep power mode. Link: https://lore.kernel.org/r/20210104155026.16417-1-adrian.hunter@intel.com Fixes: fe1d4c2ebcae ("scsi: ufs: Add DeepSleep feature") Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 34 +++++++++++++--------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index adc0d0e916078..e77fa784d6d81 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -916,21 +916,24 @@ Date: September 2014 Contact: Subhash Jadavani Description: This entry could be used to set or show the UFS device runtime power management level. The current driver - implementation supports 6 levels with next target states: + implementation supports 7 levels with next target states: == ==================================================== - 0 an UFS device will stay active, an UIC link will + 0 UFS device will stay active, UIC link will stay active - 1 an UFS device will stay active, an UIC link will + 1 UFS device will stay active, UIC link will hibernate - 2 an UFS device will moved to sleep, an UIC link will + 2 UFS device will be moved to sleep, UIC link will stay active - 3 an UFS device will moved to sleep, an UIC link will + 3 UFS device will be moved to sleep, UIC link will hibernate - 4 an UFS device will be powered off, an UIC link will + 4 UFS device will be powered off, UIC link will hibernate - 5 an UFS device will be powered off, an UIC link will + 5 UFS device will be powered off, UIC link will be powered off + 6 UFS device will be moved to deep sleep, UIC link + will be powered off. Note, deep sleep might not be + supported in which case this value will not be accepted == ==================================================== What: /sys/bus/platform/drivers/ufshcd/*/rpm_target_dev_state @@ -954,21 +957,24 @@ Date: September 2014 Contact: Subhash Jadavani Description: This entry could be used to set or show the UFS device system power management level. The current driver - implementation supports 6 levels with next target states: + implementation supports 7 levels with next target states: == ==================================================== - 0 an UFS device will stay active, an UIC link will + 0 UFS device will stay active, UIC link will stay active - 1 an UFS device will stay active, an UIC link will + 1 UFS device will stay active, UIC link will hibernate - 2 an UFS device will moved to sleep, an UIC link will + 2 UFS device will be moved to sleep, UIC link will stay active - 3 an UFS device will moved to sleep, an UIC link will + 3 UFS device will be moved to sleep, UIC link will hibernate - 4 an UFS device will be powered off, an UIC link will + 4 UFS device will be powered off, UIC link will hibernate - 5 an UFS device will be powered off, an UIC link will + 5 UFS device will be powered off, UIC link will be powered off + 6 UFS device will be moved to deep sleep, UIC link + will be powered off. Note, deep sleep might not be + supported in which case this value will not be accepted == ==================================================== What: /sys/bus/platform/drivers/ufshcd/*/spm_target_dev_state -- GitLab From b112036535eda34460677ea883eaecc3a45a435d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 5 Jan 2021 00:41:04 +0100 Subject: [PATCH 0093/1084] scsi: megaraid_sas: Fix MEGASAS_IOC_FIRMWARE regression Phil Oester reported that a fix for a possible buffer overrun that I sent caused a regression that manifests in this output: Event Message: A PCI parity error was detected on a component at bus 0 device 5 function 0. Severity: Critical Message ID: PCI1308 The original code tried to handle the sense data pointer differently when using 32-bit 64-bit DMA addressing, which would lead to a 32-bit dma_addr_t value of 0x11223344 to get stored 32-bit kernel: 44 33 22 11 ?? ?? ?? ?? 64-bit LE kernel: 44 33 22 11 00 00 00 00 64-bit BE kernel: 00 00 00 00 44 33 22 11 or a 64-bit dma_addr_t value of 0x1122334455667788 to get stored as 32-bit kernel: 88 77 66 55 ?? ?? ?? ?? 64-bit kernel: 88 77 66 55 44 33 22 11 In my patch, I tried to ensure that the same value is used on both 32-bit and 64-bit kernels, and picked what seemed to be the most sensible combination, storing 32-bit addresses in the first four bytes (as 32-bit kernels already did), and 64-bit addresses in eight consecutive bytes (as 64-bit kernels already did), but evidently this was incorrect. Always storing the dma_addr_t pointer as 64-bit little-endian, i.e. initializing the second four bytes to zero in case of 32-bit addressing, apparently solved the problem for Phil, and is consistent with what all 64-bit little-endian machines did before. I also checked in the history that in previous versions of the code, the pointer was always in the first four bytes without padding, and that previous attempts to fix 64-bit user space, big-endian architectures and 64-bit DMA were clearly flawed and seem to have introduced made this worse. Link: https://lore.kernel.org/r/20210104234137.438275-1-arnd@kernel.org Fixes: 381d34e376e3 ("scsi: megaraid_sas: Check user-provided offsets") Fixes: 107a60dd71b5 ("scsi: megaraid_sas: Add support for 64bit consistent DMA") Fixes: 94cd65ddf4d7 ("[SCSI] megaraid_sas: addded support for big endian architecture") Fixes: 7b2519afa1ab ("[SCSI] megaraid_sas: fix 64 bit sense pointer truncation") Reported-by: Phil Oester Tested-by: Phil Oester Signed-off-by: Arnd Bergmann Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index af192096a82b1..63a4f48bdc755 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -8244,11 +8244,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, goto out; } + /* always store 64 bits regardless of addressing */ sense_ptr = (void *)cmd->frame + ioc->sense_off; - if (instance->consistent_mask_64bit) - put_unaligned_le64(sense_handle, sense_ptr); - else - put_unaligned_le32(sense_handle, sense_ptr); + put_unaligned_le64(sense_handle, sense_ptr); } /* -- GitLab From 5e6ddadf7637d336acaad1df1f3bcbb07f7d104d Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 5 Jan 2021 20:08:22 -0800 Subject: [PATCH 0094/1084] scsi: ufs: ufshcd-pltfrm depends on HAS_IOMEM Building ufshcd-pltfrm.c on arch/s390/ has a linker error since S390 does not support IOMEM, so add a dependency on HAS_IOMEM. s390-linux-ld: drivers/scsi/ufs/ufshcd-pltfrm.o: in function `ufshcd_pltfrm_init': ufshcd-pltfrm.c:(.text+0x38e): undefined reference to `devm_platform_ioremap_resource' where that devm_ function is inside an #ifdef CONFIG_HAS_IOMEM/#endif block. Link: lore.kernel.org/r/202101031125.ZEFCUiKi-lkp@intel.com Link: https://lore.kernel.org/r/20210106040822.933-1-rdunlap@infradead.org Fixes: 03b1781aa978 ("[SCSI] ufs: Add Platform glue driver for ufshcd") Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Alim Akhtar Cc: Avri Altman Cc: linux-scsi@vger.kernel.org Reported-by: kernel test robot Signed-off-by: Randy Dunlap Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 3f6dfed4fe84b..b915b38c2b277 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -72,6 +72,7 @@ config SCSI_UFS_DWC_TC_PCI config SCSI_UFSHCD_PLATFORM tristate "Platform bus based UFS Controller support" depends on SCSI_UFSHCD + depends on HAS_IOMEM help This selects the UFS host controller support. Select this if you have an UFS controller on Platform bus. -- GitLab From 901d01c8e50c35a182073219a38b9c6391e59144 Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Wed, 6 Jan 2021 14:37:21 -0600 Subject: [PATCH 0095/1084] scsi: ibmvfc: Fix missing cast of ibmvfc_event pointer to u64 handle Commit 2aa0102c6688 ("scsi: ibmvfc: Use correlation token to tag commands") sets the vfcFrame correlation token to the pointer handle of the associated ibmvfc_event. However, that commit failed to cast the pointer to an appropriate type which in this case is a u64. As such sparse warnings are generated for both correlation token assignments. ibmvfc.c:2375:36: sparse: incorrect type in argument 1 (different base types) ibmvfc.c:2375:36: sparse: expected unsigned long long [usertype] val ibmvfc.c:2375:36: sparse: got struct ibmvfc_event *[assigned] evt Add the appropriate u64 casts when assigning an ibmvfc_event as a correlation token. Link: https://lore.kernel.org/r/20210106203721.1054693-1-tyreld@linux.ibm.com Fixes: 2aa0102c6688 ("scsi: ibmvfc: Use correlation token to tag commands") Reported-by: kernel test robot Signed-off-by: Tyrel Datwyler Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvfc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 42e4d35e0d355..7312f31df878c 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1744,7 +1744,7 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd, iu->pri_task_attr = IBMVFC_SIMPLE_TASK; } - vfc_cmd->correlation = cpu_to_be64(evt); + vfc_cmd->correlation = cpu_to_be64((u64)evt); if (likely(!(rc = ibmvfc_map_sg_data(cmnd, evt, vfc_cmd, vhost->dev)))) return ibmvfc_send_event(evt, vhost, 0); @@ -2418,7 +2418,7 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF)); evt->sync_iu = &rsp_iu; - tmf->correlation = cpu_to_be64(evt); + tmf->correlation = cpu_to_be64((u64)evt); init_completion(&evt->comp); rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); -- GitLab From 4ee7ee530bc2bae6268247988d86722c65d02a37 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 7 Jan 2021 10:53:15 -0800 Subject: [PATCH 0096/1084] scsi: ufs: Fix livelock of ufshcd_clear_ua_wluns() When gate_work/ungate_work experience an error during hibern8_enter or exit we can livelock: ufshcd_err_handler() ufshcd_scsi_block_requests() ufshcd_reset_and_restore() ufshcd_clear_ua_wluns() -> stuck ufshcd_scsi_unblock_requests() In order to avoid this, ufshcd_clear_ua_wluns() can be called per recovery flows such as suspend/resume, link_recovery, and error_handler. Link: https://lore.kernel.org/r/20210107185316.788815-2-jaegeuk@kernel.org Fixes: 1918651f2d7e ("scsi: ufs: Clear UAC for RPMB after ufshcd resets") Reviewed-by: Can Guo Signed-off-by: Jaegeuk Kim Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index e31d2c5c7b23b..cff4f52a91f0a 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3996,6 +3996,8 @@ int ufshcd_link_recovery(struct ufs_hba *hba) if (ret) dev_err(hba->dev, "%s: link recovery failed, err %d", __func__, ret); + else + ufshcd_clear_ua_wluns(hba); return ret; } @@ -6001,6 +6003,9 @@ static void ufshcd_err_handler(struct work_struct *work) ufshcd_scsi_unblock_requests(hba); ufshcd_err_handling_unprepare(hba); up(&hba->eh_sem); + + if (!err && needs_reset) + ufshcd_clear_ua_wluns(hba); } /** @@ -6938,14 +6943,11 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) ufshcd_set_clk_freq(hba, true); err = ufshcd_hba_enable(hba); - if (err) - goto out; /* Establish the link again and restore the device */ - err = ufshcd_probe_hba(hba, false); if (!err) - ufshcd_clear_ua_wluns(hba); -out: + err = ufshcd_probe_hba(hba, false); + if (err) dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err); ufshcd_update_evt_hist(hba, UFS_EVT_HOST_RESET, (u32)err); @@ -7716,6 +7718,8 @@ static int ufshcd_add_lus(struct ufs_hba *hba) if (ret) goto out; + ufshcd_clear_ua_wluns(hba); + /* Initialize devfreq after UFS device is detected */ if (ufshcd_is_clkscaling_supported(hba)) { memcpy(&hba->clk_scaling.saved_pwr_info.info, @@ -7917,8 +7921,6 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) pm_runtime_put_sync(hba->dev); ufshcd_exit_clk_scaling(hba); ufshcd_hba_exit(hba); - } else { - ufshcd_clear_ua_wluns(hba); } } @@ -8775,6 +8777,7 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) ufshcd_resume_clkscaling(hba); hba->clk_gating.is_suspended = false; hba->dev_info.b_rpm_dev_flush_capable = false; + ufshcd_clear_ua_wluns(hba); ufshcd_release(hba); out: if (hba->dev_info.b_rpm_dev_flush_capable) { @@ -8885,6 +8888,8 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) cancel_delayed_work(&hba->rpm_dev_flush_recheck_work); } + ufshcd_clear_ua_wluns(hba); + /* Schedule clock gating in case of no access to UFS device yet */ ufshcd_release(hba); -- GitLab From eeb1b55b6e25c5f7265ff45cd050f3bc2cc423a4 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 7 Jan 2021 10:53:16 -0800 Subject: [PATCH 0097/1084] scsi: ufs: Fix tm request when non-fatal error happens When non-fatal error like line-reset happens, ufshcd_err_handler() starts to abort tasks by ufshcd_try_to_abort_task(). When it tries to issue a task management request, we hit two warnings: WARNING: CPU: 7 PID: 7 at block/blk-core.c:630 blk_get_request+0x68/0x70 WARNING: CPU: 4 PID: 157 at block/blk-mq-tag.c:82 blk_mq_get_tag+0x438/0x46c After fixing the above warnings we hit another tm_cmd timeout which may be caused by unstable controller state: __ufshcd_issue_tm_cmd: task management cmd 0x80 timed-out Then, ufshcd_err_handler() enters full reset, and kernel gets stuck. It turned out ufshcd_print_trs() printed too many messages on console which requires CPU locks. Likewise hba->silence_err_logs, we need to avoid too verbose messages. This is actually not an error case. Link: https://lore.kernel.org/r/20210107185316.788815-3-jaegeuk@kernel.org Fixes: 69a6c269c097 ("scsi: ufs: Use blk_{get,put}_request() to allocate and free TMFs") Reviewed-by: Can Guo Signed-off-by: Jaegeuk Kim Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index cff4f52a91f0a..fb32d122f2e38 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4994,7 +4994,8 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) break; } /* end of switch */ - if ((host_byte(result) != DID_OK) && !hba->silence_err_logs) + if ((host_byte(result) != DID_OK) && + (host_byte(result) != DID_REQUEUE) && !hba->silence_err_logs) ufshcd_print_trs(hba, 1 << lrbp->task_tag, true); return result; } @@ -6300,9 +6301,13 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); } - if (enabled_intr_status && retval == IRQ_NONE) { - dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x\n", - __func__, intr_status); + if (enabled_intr_status && retval == IRQ_NONE && + !ufshcd_eh_in_progress(hba)) { + dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x (0x%08x, 0x%08x)\n", + __func__, + intr_status, + hba->ufs_stats.last_intr_status, + enabled_intr_status); ufshcd_dump_regs(hba, 0, UFSHCI_REG_SPACE_SIZE, "host_regs: "); } @@ -6346,7 +6351,10 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, * Even though we use wait_event() which sleeps indefinitely, * the maximum wait time is bounded by %TM_CMD_TIMEOUT. */ - req = blk_get_request(q, REQ_OP_DRV_OUT, BLK_MQ_REQ_RESERVED); + req = blk_get_request(q, REQ_OP_DRV_OUT, 0); + if (IS_ERR(req)) + return PTR_ERR(req); + req->end_io_data = &wait; free_slot = req->tag; WARN_ON_ONCE(free_slot < 0 || free_slot >= hba->nutmrs); -- GitLab From 3c02e04fd4f57130e4fa75fab6f528f7a52db9b5 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Thu, 31 Dec 2020 00:33:18 +0300 Subject: [PATCH 0098/1084] crypto: xor - Fix divide error in do_xor_speed() crypto: Fix divide error in do_xor_speed() From: Kirill Tkhai Latest (but not only latest) linux-next panics with divide error on my QEMU setup. The patch at the bottom of this message fixes the problem. xor: measuring software checksum speed divide error: 0000 [#1] PREEMPT SMP KASAN PREEMPT SMP KASAN CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.10.0-next-20201223+ #2177 RIP: 0010:do_xor_speed+0xbb/0xf3 Code: 41 ff cc 75 b5 bf 01 00 00 00 e8 3d 23 8b fe 65 8b 05 f6 49 83 7d 85 c0 75 05 e8 84 70 81 fe b8 00 00 50 c3 31 d2 48 8d 7b 10 f5 41 89 c4 e8 58 07 a2 fe 44 89 63 10 48 8d 7b 08 e8 cb 07 a2 RSP: 0000:ffff888100137dc8 EFLAGS: 00010246 RAX: 00000000c3500000 RBX: ffffffff823f0160 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000808 RDI: ffffffff823f0170 RBP: 0000000000000000 R08: ffffffff8109c50f R09: ffffffff824bb6f7 R10: fffffbfff04976de R11: 0000000000000001 R12: 0000000000000000 R13: ffff888101997000 R14: ffff888101994000 R15: ffffffff823f0178 FS: 0000000000000000(0000) GS:ffff8881f7780000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000000220e000 CR4: 00000000000006a0 Call Trace: calibrate_xor_blocks+0x13c/0x1c4 ? do_xor_speed+0xf3/0xf3 do_one_initcall+0xc1/0x1b7 ? start_kernel+0x373/0x373 ? unpoison_range+0x3a/0x60 kernel_init_freeable+0x1dd/0x238 ? rest_init+0xc6/0xc6 kernel_init+0x8/0x10a ret_from_fork+0x1f/0x30 ---[ end trace 5bd3c1d0b77772da ]--- Fixes: c055e3eae0f1 ("crypto: xor - use ktime for template benchmarking") Cc: Signed-off-by: Kirill Tkhai Acked-by: Ard Biesheuvel Signed-off-by: Herbert Xu --- crypto/xor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto/xor.c b/crypto/xor.c index eacbf4f939900..8f899f898ec9f 100644 --- a/crypto/xor.c +++ b/crypto/xor.c @@ -107,6 +107,8 @@ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2) preempt_enable(); // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s] + if (!min) + min = 1; speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min); tmpl->speed = speed; -- GitLab From 382811940303f7cd01d0f3dcdf432dfd89c5a98e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 3 Jan 2021 15:03:04 +0100 Subject: [PATCH 0099/1084] crypto: omap-sham - Fix link error without crypto-engine The driver was converted to use the crypto engine helper but is missing the corresponding Kconfig statement to ensure it is available: arm-linux-gnueabi-ld: drivers/crypto/omap-sham.o: in function `omap_sham_probe': omap-sham.c:(.text+0x374): undefined reference to `crypto_engine_alloc_init' arm-linux-gnueabi-ld: omap-sham.c:(.text+0x384): undefined reference to `crypto_engine_start' arm-linux-gnueabi-ld: omap-sham.c:(.text+0x510): undefined reference to `crypto_engine_exit' arm-linux-gnueabi-ld: drivers/crypto/omap-sham.o: in function `omap_sham_finish_req': omap-sham.c:(.text+0x98c): undefined reference to `crypto_finalize_hash_request' arm-linux-gnueabi-ld: omap-sham.c:(.text+0x9a0): undefined reference to `crypto_transfer_hash_request_to_engine' arm-linux-gnueabi-ld: drivers/crypto/omap-sham.o: in function `omap_sham_update': omap-sham.c:(.text+0xf24): undefined reference to `crypto_transfer_hash_request_to_engine' arm-linux-gnueabi-ld: drivers/crypto/omap-sham.o: in function `omap_sham_final': omap-sham.c:(.text+0x1020): undefined reference to `crypto_transfer_hash_request_to_engine' Fixes: 133c3d434d91 ("crypto: omap-sham - convert to use crypto engine") Signed-off-by: Arnd Bergmann Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index bbd51703e738b..e535f28a80283 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -366,6 +366,7 @@ if CRYPTO_DEV_OMAP config CRYPTO_DEV_OMAP_SHAM tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator" depends on ARCH_OMAP2PLUS + select CRYPTO_ENGINE select CRYPTO_SHA1 select CRYPTO_MD5 select CRYPTO_SHA256 -- GitLab From 31c51a424f5163ee6f14fcc251f81078457123e1 Mon Sep 17 00:00:00 2001 From: Xu Wang Date: Fri, 8 Jan 2021 08:58:34 +0000 Subject: [PATCH 0100/1084] ASoC: es8328: Remove redundant null check before clk_disable_unprepare Because clk_disable_unprepare() already checked NULL clock parameter, so the additional check is unnecessary, just remove it. Signed-off-by: Xu Wang Link: https://lore.kernel.org/r/20210108085834.7168-1-vulab@iscas.ac.cn Signed-off-by: Mark Brown --- sound/soc/codecs/es8328.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index 7e26231a596a4..b537300d0ce86 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -809,8 +809,7 @@ static void es8328_remove(struct snd_soc_component *component) es8328 = snd_soc_component_get_drvdata(component); - if (es8328->clk) - clk_disable_unprepare(es8328->clk); + clk_disable_unprepare(es8328->clk); regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), es8328->supplies); -- GitLab From d0243bbd5dd3ebbd49dafa8b56bb911d971131d0 Mon Sep 17 00:00:00 2001 From: Meng Li Date: Tue, 5 Jan 2021 15:09:27 +0800 Subject: [PATCH 0101/1084] drivers core: Free dma_range_map when driver probe failed There will be memory leak if driver probe failed. Trace as below: backtrace: [<000000002415258f>] kmemleak_alloc+0x3c/0x50 [<00000000f447ebe4>] __kmalloc+0x208/0x530 [<0000000048bc7b3a>] of_dma_get_range+0xe4/0x1b0 [<0000000041e39065>] of_dma_configure_id+0x58/0x27c [<000000006356866a>] platform_dma_configure+0x2c/0x40 ...... [<000000000afcf9b5>] ret_from_fork+0x10/0x3c This issue is introduced by commit e0d072782c73("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset "). It doesn't free dma_range_map when driver probe failed and cause above memory leak. So, add code to free it in error path. Fixes: e0d072782c73 ("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset ") Cc: stable@vger.kernel.org Signed-off-by: Meng Li Link: https://lore.kernel.org/r/20210105070927.14968-1-Meng.Li@windriver.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 2f32f38a11ed0..0b76b54237781 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -619,6 +619,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) else if (drv->remove) drv->remove(dev); probe_failed: + kfree(dev->dma_range_map); + dev->dma_range_map = NULL; if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DRIVER_NOT_BOUND, dev); -- GitLab From 29f7c54b253fc18bff9bf7e9f303b75deb285c7a Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 21 Dec 2020 22:30:55 +0800 Subject: [PATCH 0102/1084] Driver core: platform: Add extra error check in devm_platform_get_irqs_affinity() The current check of nvec < minvec for nvec returned from platform_irq_count() will not detect a negative error code in nvec. This is because minvec is unsigned, and, as such, nvec is promoted to unsigned in that check, which will make it a huge number (if it contained -EPROBE_DEFER). In practice, an error should not occur in nvec for the only in-tree user, but add a check anyway. Fixes: e15f2fa959f2 ("driver core: platform: Add devm_platform_get_irqs_affinity()") Reported-by: Dan Carpenter Signed-off-by: John Garry Link: https://lore.kernel.org/r/1608561055-231244-1-git-send-email-john.garry@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 95fd1549f87de..8456d8384ac8e 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -366,6 +366,8 @@ int devm_platform_get_irqs_affinity(struct platform_device *dev, return -ERANGE; nvec = platform_irq_count(dev); + if (nvec < 0) + return nvec; if (nvec < minvec) return -ENOSPC; -- GitLab From 35d0b389f3b23439ad15b610d6e43fc72fc75779 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 5 Jan 2021 11:32:43 -0700 Subject: [PATCH 0103/1084] task_work: unconditionally run task_work from get_signal() Song reported a boot regression in a kvm image with 5.11-rc, and bisected it down to the below patch. Debugging this issue, turns out that the boot stalled when a task is waiting on a pipe being released. As we no longer run task_work from get_signal() unless it's queued with TWA_SIGNAL, the task goes idle without running the task_work. This prevents ->release() from being called on the pipe, which another boot task is waiting on. For now, re-instate the unconditional task_work run from get_signal(). For 5.12, we'll collapse TWA_RESUME and TWA_SIGNAL, as it no longer makes sense to have a distinction between the two. This will turn task_work notification into a simple boolean, whether to notify or not. Fixes: 98b89b649fce ("signal: kill JOBCTL_TASK_WORK") Reported-by: Song Liu Tested-by: John Stultz Tested-by: Douglas Anderson Tested-by: Sedat Dilek # LLVM/Clang version 11.0.1 Signed-off-by: Jens Axboe --- kernel/signal.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/signal.c b/kernel/signal.c index 5736c55aaa1af..6b9c431da08fe 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2550,6 +2550,9 @@ bool get_signal(struct ksignal *ksig) struct signal_struct *signal = current->signal; int signr; + if (unlikely(current->task_works)) + task_work_run(); + /* * For non-generic architectures, check for TIF_NOTIFY_SIGNAL so * that the arch handlers don't all have to do it. If we get here -- GitLab From eaa7995c529b54d68d97a30f6344cc6ca2f214a7 Mon Sep 17 00:00:00 2001 From: David Collins Date: Thu, 7 Jan 2021 17:16:02 -0800 Subject: [PATCH 0104/1084] regulator: core: avoid regulator_resolve_supply() race condition The final step in regulator_register() is to call regulator_resolve_supply() for each registered regulator (including the one in the process of being registered). The regulator_resolve_supply() function first checks if rdev->supply is NULL, then it performs various steps to try to find the supply. If successful, rdev->supply is set inside of set_supply(). This procedure can encounter a race condition if two concurrent tasks call regulator_register() near to each other on separate CPUs and one of the regulators has rdev->supply_name specified. There is currently nothing guaranteeing atomicity between the rdev->supply check and set steps. Thus, both tasks can observe rdev->supply==NULL in their regulator_resolve_supply() calls. This then results in both creating a struct regulator for the supply. One ends up actually stored in rdev->supply and the other is lost (though still present in the supply's consumer_list). Here is a kernel log snippet showing the issue: [ 12.421768] gpu_cc_gx_gdsc: supplied by pm8350_s5_level [ 12.425854] gpu_cc_gx_gdsc: supplied by pm8350_s5_level [ 12.429064] debugfs: Directory 'regulator.4-SUPPLY' with parent '17a00000.rsc:rpmh-regulator-gfxlvl-pm8350_s5_level' already present! Avoid this race condition by holding the rdev->mutex lock inside of regulator_resolve_supply() while checking and setting rdev->supply. Signed-off-by: David Collins Link: https://lore.kernel.org/r/1610068562-4410-1-git-send-email-collinsd@codeaurora.org Signed-off-by: Mark Brown --- drivers/regulator/core.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ca03d8e70bd13..cfc3bc9df93a0 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1813,23 +1813,34 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) { struct regulator_dev *r; struct device *dev = rdev->dev.parent; - int ret; + int ret = 0; /* No supply to resolve? */ if (!rdev->supply_name) return 0; - /* Supply already resolved? */ + /* Supply already resolved? (fast-path without locking contention) */ if (rdev->supply) return 0; + /* + * Recheck rdev->supply with rdev->mutex lock held to avoid a race + * between rdev->supply null check and setting rdev->supply in + * set_supply() from concurrent tasks. + */ + regulator_lock(rdev); + + /* Supply just resolved by a concurrent task? */ + if (rdev->supply) + goto out; + r = regulator_dev_lookup(dev, rdev->supply_name); if (IS_ERR(r)) { ret = PTR_ERR(r); /* Did the lookup explicitly defer for us? */ if (ret == -EPROBE_DEFER) - return ret; + goto out; if (have_full_constraints()) { r = dummy_regulator_rdev; @@ -1837,15 +1848,18 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) } else { dev_err(dev, "Failed to resolve %s-supply for %s\n", rdev->supply_name, rdev->desc->name); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto out; } } if (r == rdev) { dev_err(dev, "Supply for %s (%s) resolved to itself\n", rdev->desc->name, rdev->supply_name); - if (!have_full_constraints()) - return -EINVAL; + if (!have_full_constraints()) { + ret = -EINVAL; + goto out; + } r = dummy_regulator_rdev; get_device(&r->dev); } @@ -1859,7 +1873,8 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) if (r->dev.parent && r->dev.parent != rdev->dev.parent) { if (!device_is_bound(r->dev.parent)) { put_device(&r->dev); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto out; } } @@ -1867,13 +1882,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) ret = regulator_resolve_supply(r); if (ret < 0) { put_device(&r->dev); - return ret; + goto out; } ret = set_supply(rdev, r); if (ret < 0) { put_device(&r->dev); - return ret; + goto out; } /* @@ -1886,11 +1901,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) if (ret < 0) { _regulator_put(rdev->supply); rdev->supply = NULL; - return ret; + goto out; } } - return 0; +out: + regulator_unlock(rdev); + return ret; } /* Internal regulator request function */ -- GitLab From 11b943c06a1c1baafb0325896e666d77f5ac78b8 Mon Sep 17 00:00:00 2001 From: Michael Sit Wei Hong Date: Fri, 8 Jan 2021 11:12:48 +0800 Subject: [PATCH 0105/1084] ASoC: Intel: KMB: Enable DMA transfer mode Enable DMA transfer mode for Intel Keem Bay ASoC platform driver. The driver will search the device tree for DMA resources at boot time to enable DMA transfer mode, and will proceed to use DMA transfer if the resource is available, otherwise the default PIO mode will be used. Signed-off-by: Michael Sit Wei Hong Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210108031248.20520-6-michael.wei.hong.sit@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 2 + sound/soc/intel/keembay/kmb_platform.c | 157 ++++++++++++++++++++++--- sound/soc/intel/keembay/kmb_platform.h | 9 ++ 3 files changed, 153 insertions(+), 15 deletions(-) diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 0c6404fc12b34..f3a4a907b29d3 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -203,6 +203,8 @@ config SND_SOC_INTEL_KEEMBAY tristate "Keembay Platforms" depends on ARCH_KEEMBAY || COMPILE_TEST depends on COMMON_CLK + select SND_DMAENGINE_PCM + select SND_SOC_GENERIC_DMAENGINE_PCM help If you have a Intel Keembay platform then enable this option by saying Y or m. diff --git a/sound/soc/intel/keembay/kmb_platform.c b/sound/soc/intel/keembay/kmb_platform.c index 1c3748f33136e..4961ba89c1100 100644 --- a/sound/soc/intel/keembay/kmb_platform.c +++ b/sound/soc/intel/keembay/kmb_platform.c @@ -6,10 +6,12 @@ // #include +#include #include #include #include #include +#include #include #include #include @@ -343,6 +345,53 @@ static const struct snd_soc_component_driver kmb_component = { .pointer = kmb_pcm_pointer, }; +static const struct snd_soc_component_driver kmb_component_dma = { + .name = "kmb", +}; + +static int kmb_probe(struct snd_soc_dai *cpu_dai) +{ + struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai); + + if (kmb_i2s->use_pio) + return 0; + + snd_soc_dai_init_dma_data(cpu_dai, &kmb_i2s->play_dma_data, + &kmb_i2s->capture_dma_data); + + return 0; +} + +static inline void kmb_i2s_enable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream) +{ + u32 dma_reg; + + dma_reg = readl(kmb_i2s->i2s_base + I2S_DMACR); + /* Enable DMA handshake for stream */ + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_reg |= I2S_DMAEN_TXBLOCK; + else + dma_reg |= I2S_DMAEN_RXBLOCK; + + writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR); +} + +static inline void kmb_i2s_disable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream) +{ + u32 dma_reg; + + dma_reg = readl(kmb_i2s->i2s_base + I2S_DMACR); + /* Disable DMA handshake for stream */ + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + dma_reg &= ~I2S_DMAEN_TXBLOCK; + writel(1, kmb_i2s->i2s_base + I2S_RTXDMA); + } else { + dma_reg &= ~I2S_DMAEN_RXBLOCK; + writel(1, kmb_i2s->i2s_base + I2S_RRXDMA); + } + writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR); +} + static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s, struct snd_pcm_substream *substream) { @@ -356,7 +405,11 @@ static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s, else writel(1, kmb_i2s->i2s_base + IRER); - kmb_i2s_irq_trigger(kmb_i2s, substream->stream, config->chan_nr, true); + if (kmb_i2s->use_pio) + kmb_i2s_irq_trigger(kmb_i2s, substream->stream, + config->chan_nr, true); + else + kmb_i2s_enable_dma(kmb_i2s, substream->stream); if (kmb_i2s->clock_provider) writel(1, kmb_i2s->i2s_base + CER); @@ -434,7 +487,8 @@ static int kmb_dai_trigger(struct snd_pcm_substream *substream, break; case SNDRV_PCM_TRIGGER_STOP: kmb_i2s->active--; - kmb_i2s_stop(kmb_i2s, substream); + if (kmb_i2s->use_pio) + kmb_i2s_stop(kmb_i2s, substream); break; default: return -EINVAL; @@ -485,16 +539,22 @@ static int kmb_dai_hw_params(struct snd_pcm_substream *substream, config->data_width = 16; kmb_i2s->ccr = 0x00; kmb_i2s->xfer_resolution = 0x02; + kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; break; case SNDRV_PCM_FORMAT_S24_LE: config->data_width = 32; kmb_i2s->ccr = 0x14; kmb_i2s->xfer_resolution = 0x05; + kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; break; case SNDRV_PCM_FORMAT_S32_LE: config->data_width = 32; kmb_i2s->ccr = 0x10; kmb_i2s->xfer_resolution = 0x05; + kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; break; default: dev_err(kmb_i2s->dev, "kmb: unsupported PCM fmt"); @@ -572,9 +632,56 @@ static int kmb_dai_prepare(struct snd_pcm_substream *substream, return 0; } +static int kmb_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) +{ + struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai); + struct snd_dmaengine_dai_dma_data *dma_data; + + if (kmb_i2s->use_pio) + return 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = &kmb_i2s->play_dma_data; + else + dma_data = &kmb_i2s->capture_dma_data; + + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); + + return 0; +} + +static int kmb_dai_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) +{ + struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai); + /* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */ + if (kmb_i2s->use_pio) + kmb_i2s_clear_irqs(kmb_i2s, substream->stream); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + writel(0, kmb_i2s->i2s_base + ITER); + else + writel(0, kmb_i2s->i2s_base + IRER); + + if (kmb_i2s->use_pio) + kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false); + else + kmb_i2s_disable_dma(kmb_i2s, substream->stream); + + if (!kmb_i2s->active) { + writel(0, kmb_i2s->i2s_base + CER); + writel(0, kmb_i2s->i2s_base + IER); + } + + return 0; +} + static struct snd_soc_dai_ops kmb_dai_ops = { + .startup = kmb_dai_startup, .trigger = kmb_dai_trigger, .hw_params = kmb_dai_hw_params, + .hw_free = kmb_dai_hw_free, .prepare = kmb_dai_prepare, .set_fmt = kmb_set_dai_fmt, }; @@ -607,6 +714,7 @@ static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = { SNDRV_PCM_FMTBIT_S16_LE), }, .ops = &kmb_dai_ops, + .probe = kmb_probe, }, }; @@ -626,6 +734,7 @@ static struct snd_soc_dai_driver intel_kmb_tdm_dai[] = { SNDRV_PCM_FMTBIT_S16_LE), }, .ops = &kmb_dai_ops, + .probe = kmb_probe, }, }; @@ -637,10 +746,12 @@ static const struct of_device_id kmb_plat_of_match[] = { static int kmb_plat_dai_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct snd_soc_dai_driver *kmb_i2s_dai; const struct of_device_id *match; struct device *dev = &pdev->dev; struct kmb_i2s_info *kmb_i2s; + struct resource *res; int ret, irq; u32 comp1_reg; @@ -682,7 +793,7 @@ static int kmb_plat_dai_probe(struct platform_device *pdev) return PTR_ERR(kmb_i2s->clk_i2s); } - kmb_i2s->i2s_base = devm_platform_ioremap_resource(pdev, 0); + kmb_i2s->i2s_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(kmb_i2s->i2s_base)) return PTR_ERR(kmb_i2s->i2s_base); @@ -692,22 +803,38 @@ static int kmb_plat_dai_probe(struct platform_device *pdev) kmb_i2s->dev = &pdev->dev; - irq = platform_get_irq_optional(pdev, 0); - if (irq > 0) { - ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0, - pdev->name, kmb_i2s); - if (ret < 0) { - dev_err(dev, "failed to request irq\n"); - return ret; - } - } - comp1_reg = readl(kmb_i2s->i2s_base + I2S_COMP_PARAM_1); kmb_i2s->fifo_th = (1 << COMP1_FIFO_DEPTH(comp1_reg)) / 2; - ret = devm_snd_soc_register_component(dev, &kmb_component, - kmb_i2s_dai, 1); + kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas")); + + if (kmb_i2s->use_pio) { + irq = platform_get_irq_optional(pdev, 0); + if (irq > 0) { + ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0, + pdev->name, kmb_i2s); + if (ret < 0) { + dev_err(dev, "failed to request irq\n"); + return ret; + } + } + ret = devm_snd_soc_register_component(dev, &kmb_component, + kmb_i2s_dai, 1); + } else { + kmb_i2s->play_dma_data.addr = res->start + I2S_TXDMA; + kmb_i2s->capture_dma_data.addr = res->start + I2S_RXDMA; + ret = snd_dmaengine_pcm_register(&pdev->dev, + NULL, 0); + if (ret) { + dev_err(&pdev->dev, "could not register dmaengine: %d\n", + ret); + return ret; + } + ret = devm_snd_soc_register_component(dev, &kmb_component_dma, + kmb_i2s_dai, 1); + } + if (ret) { dev_err(dev, "not able to register dai\n"); return ret; diff --git a/sound/soc/intel/keembay/kmb_platform.h b/sound/soc/intel/keembay/kmb_platform.h index 0c393e5916b6d..67234caee8142 100644 --- a/sound/soc/intel/keembay/kmb_platform.h +++ b/sound/soc/intel/keembay/kmb_platform.h @@ -12,6 +12,7 @@ #include #include #include +#include /* Register values with reference to KMB databook v1.1 */ /* common register for all channel */ @@ -103,7 +104,12 @@ #define DW_I2S_PROVIDER BIT(3) #define I2S_RXDMA 0x01C0 +#define I2S_RRXDMA 0x01C4 #define I2S_TXDMA 0x01C8 +#define I2S_RTXDMA 0x01CC +#define I2S_DMACR 0x0200 +#define I2S_DMAEN_RXBLOCK (1 << 16) +#define I2S_DMAEN_TXBLOCK (1 << 17) /* * struct i2s_clk_config_data - represent i2s clk configuration data @@ -131,6 +137,9 @@ struct kmb_i2s_info { u32 xfer_resolution; u32 fifo_th; bool clock_provider; + /* data related to DMA transfers b/w i2s and DMAC */ + struct snd_dmaengine_dai_dma_data play_dma_data; + struct snd_dmaengine_dai_dma_data capture_dma_data; struct i2s_clk_config_data config; int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); -- GitLab From 9ddaa1e6181b3d33080f2ed7c27cb0bba819e562 Mon Sep 17 00:00:00 2001 From: Michael Sit Wei Hong Date: Fri, 8 Jan 2021 11:12:47 +0800 Subject: [PATCH 0106/1084] ASoC: intel, keembay-i2s: Add info for device to use DMA Add descriptions for entries needed for audio device to use DMA channels for audio playback and capture. Signed-off-by: Michael Sit Wei Hong Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210108031248.20520-5-michael.wei.hong.sit@intel.com Signed-off-by: Mark Brown --- .../bindings/sound/intel,keembay-i2s.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml index d346e61ab7085..e0658f122cbb7 100644 --- a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml @@ -45,6 +45,18 @@ properties: - const: osc - const: apb_clk + dmas: + items: + - description: DMA controller phandle and DMA channel + for TX and RX + + dma-names: + items: + - description: "tx" for the transmit channel + "rx" for the receive channel + - const: tx + - const: rx + required: - compatible - "#sound-dai-cells" @@ -70,4 +82,6 @@ examples: interrupts = ; clock-names = "osc", "apb_clk"; clocks = <&scmi_clk KEEM_BAY_PSS_AUX_I2S3>, <&scmi_clk KEEM_BAY_PSS_I2S3>; + dmas = <&axi_dma0 29 &axi_dma0 33>; + dma-names = "tx", "rx"; }; -- GitLab From 70b6ff35d62050d1573876cc0e1e078acd3e6008 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 6 Jan 2021 23:47:41 +0100 Subject: [PATCH 0107/1084] cfg80211/mac80211: fix kernel-doc for SAR APIs A stray @ caused the kernel-doc parser to not understand this, fix that. Also add some missing kernel-doc. Reported-by: Stephen Rothwell Fixes: 6bdb68cef7bf ("nl80211: add common API to configure SAR power limitations") Fixes: c534e093d865 ("mac80211: add ieee80211_set_sar_specs") Signed-off-by: Johannes Berg Tested-by: Stephen Rothwell # build only Link: https://lore.kernel.org/r/20210106234740.96827c18f9bd.I8b9f0a9cbfe186931ef9640046f414371f216914@changeid Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 5 ++++- include/net/mac80211.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9a4bbccddc7f7..1b3954afcda42 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1756,7 +1756,7 @@ struct cfg80211_sar_specs { /** - * @struct cfg80211_sar_chan_ranges - sar frequency ranges + * struct cfg80211_sar_chan_ranges - sar frequency ranges * @start_freq: start range edge frequency * @end_freq: end range edge frequency */ @@ -3972,6 +3972,8 @@ struct mgmt_frame_regs { * This callback may sleep. * @reset_tid_config: Reset TID specific configuration for the peer, for the * given TIDs. This callback may sleep. + * + * @set_sar_specs: Update the SAR (TX power) settings. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -4929,6 +4931,7 @@ struct wiphy_iftype_akm_suites { * @max_data_retry_count: maximum supported per TID retry count for * configuration through the %NL80211_TID_CONFIG_ATTR_RETRY_SHORT and * %NL80211_TID_CONFIG_ATTR_RETRY_LONG attributes + * @sar_capa: SAR control capabilities */ struct wiphy { /* assign these fields before you register the wiphy */ diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d315740581f1e..2bdbf62f4ecd7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3880,6 +3880,7 @@ enum ieee80211_reconfig_type { * This callback may sleep. * @sta_set_4addr: Called to notify the driver when a station starts/stops using * 4-address mode + * @set_sar_specs: Update the SAR (TX power) settings. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, -- GitLab From 51d62f2f2c501a93d9a6a46f43731f984e227764 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Tue, 5 Jan 2021 16:56:57 +0200 Subject: [PATCH 0108/1084] cfg80211: Save the regulatory domain with a lock Saving the regulatory domain while setting custom regulatory domain was done while accessing a RCU protected pointer but without any protection. Fix this by using RTNL while accessing the pointer. Signed-off-by: Ilan Peer Reported-by: syzbot+27771d4abcd9b7a1f5d3@syzkaller.appspotmail.com Reported-by: syzbot+db4035751c56c0079282@syzkaller.appspotmail.com Reported-by: Hans de Goede Fixes: beee24695157 ("cfg80211: Save the regulatory domain when setting custom regulatory") Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20210105165657.613e9a876829.Ia38d27dbebea28bf9c56d70691d243186ede70e7@changeid Signed-off-by: Johannes Berg --- net/wireless/reg.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index bb72447ad9602..8114bba8556c7 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -5,7 +5,7 @@ * Copyright 2008-2011 Luis R. Rodriguez * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2017 Intel Deutschland GmbH - * Copyright (C) 2018 - 2019 Intel Corporation + * Copyright (C) 2018 - 2021 Intel Corporation * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -139,6 +139,11 @@ static const struct ieee80211_regdomain *get_cfg80211_regdom(void) return rcu_dereference_rtnl(cfg80211_regdomain); } +/* + * Returns the regulatory domain associated with the wiphy. + * + * Requires either RTNL or RCU protection + */ const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy) { return rcu_dereference_rtnl(wiphy->regd); @@ -2571,9 +2576,13 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy, if (IS_ERR(new_regd)) return; + rtnl_lock(); + tmp = get_wiphy_regdom(wiphy); rcu_assign_pointer(wiphy->regd, new_regd); rcu_free_regdom(tmp); + + rtnl_unlock(); } EXPORT_SYMBOL(wiphy_apply_custom_regulatory); -- GitLab From 656c648354e1561fa4f445b0b3252ec1d24e3951 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 8 Jan 2021 12:06:27 +0100 Subject: [PATCH 0109/1084] arm64: dts: rockchip: fix vopl iommu irq on px30 The vop-mmu shares the irq with its matched vop but not the vpu. Fixes: 7053e06b1422 ("arm64: dts: rockchip: add core dtsi file for PX30 SoCs") Signed-off-by: Sandy Huang Signed-off-by: Heiko Stuebner Reviewed-by: Ezequiel Garcia Reviewed-by: Paul Kocialkowski Tested-by: Paul Kocialkowski Link: https://lore.kernel.org/r/20210108110627.3231226-1-heiko@sntech.de --- arch/arm64/boot/dts/rockchip/px30.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index 2695ea8cda142..64193292d26c3 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -1097,7 +1097,7 @@ vopl_mmu: iommu@ff470f00 { compatible = "rockchip,iommu"; reg = <0x0 0xff470f00 0x0 0x100>; - interrupts = ; + interrupts = ; interrupt-names = "vopl_mmu"; clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>; clock-names = "aclk", "iface"; -- GitLab From 642fb2795290c4abe629ca34fb8ff6d78baa9fd3 Mon Sep 17 00:00:00 2001 From: Simon South Date: Wed, 30 Sep 2020 14:56:27 -0400 Subject: [PATCH 0110/1084] arm64: dts: rockchip: Use only supported PCIe link speed on Pinebook Pro On Pinebook Pro laptops with an NVMe SSD installed, prevent random crashes in the NVMe driver by not attempting to use a PCIe link speed higher than that supported by the RK3399 SoC. See commit 712fa1777207 ("arm64: dts: rockchip: add max-link-speed for rk3399"). Fixes: 5a65505a6988 ("arm64: dts: rockchip: Add initial support for Pinebook Pro") Signed-off-by: Simon South Link: https://lore.kernel.org/r/20200930185627.5918-1-simon@simonsouth.net Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts index 06d48338c8362..219b7507a10fb 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts @@ -790,7 +790,6 @@ &pcie0 { bus-scan-delay-ms = <1000>; ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; - max-link-speed = <2>; num-lanes = <4>; pinctrl-names = "default"; pinctrl-0 = <&pcie_clkreqn_cpm>; -- GitLab From 43f20b1c6140896916f4e91aacc166830a7ba849 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 15 Aug 2020 13:51:12 +0100 Subject: [PATCH 0111/1084] arm64: dts: rockchip: Fix PCIe DT properties on rk3399 It recently became apparent that the lack of a 'device_type = "pci"' in the PCIe root complex node for rk3399 is a violation of the PCI binding, as documented in IEEE Std 1275-1994. Changes to the kernel's parsing of the DT made such violation fatal, as drivers cannot probe the controller anymore. Add the missing property makes the PCIe node compliant. While we are at it, drop the pointless linux,pci-domain property, which only makes sense when there are multiple host bridges. Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20200815125112.462652-3-maz@kernel.org Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index f5dee5f447bba..52bce81cfe77d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -234,6 +234,7 @@ reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>; reg-names = "axi-base", "apb-base"; + device_type = "pci"; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; @@ -252,7 +253,6 @@ <0 0 0 2 &pcie0_intc 1>, <0 0 0 3 &pcie0_intc 2>, <0 0 0 4 &pcie0_intc 3>; - linux,pci-domain = <0>; max-link-speed = <1>; msi-map = <0x0 &its 0x0 0x1000>; phys = <&pcie_phy 0>, <&pcie_phy 1>, -- GitLab From 25669e943e06c56750fb2347cce4f3343379e4b2 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Sat, 9 Jan 2021 22:13:56 -0800 Subject: [PATCH 0112/1084] dt-bindings: input: touchscreen: goodix: Add binding for GT9286 IC Support for this chip is being added to the goodix driver: add the DT binding for it. Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20210109135512.149032-3-angelogioacchino.delregno@somainline.org Reviewed-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- Documentation/devicetree/bindings/input/touchscreen/goodix.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml b/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml index da5b0d87e16d0..93f2ce3130ae7 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml @@ -26,6 +26,7 @@ properties: - goodix,gt927 - goodix,gt9271 - goodix,gt928 + - goodix,gt9286 - goodix,gt967 reg: -- GitLab From 2dce6db70c77bbe639f5cd9cc796fb8f2694a7d0 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Sat, 9 Jan 2021 22:14:39 -0800 Subject: [PATCH 0113/1084] Input: goodix - add support for Goodix GT9286 chip The Goodix GT9286 is a capacitive touch sensor IC based on GT1x. This chip can be found on a number of smartphones, including the F(x)tec Pro 1 and the Elephone U. This has been tested on F(x)Tec Pro1 (MSM8998). Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20210109135512.149032-2-angelogioacchino.delregno@somainline.org Reviewed-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 19765f1c04f7e..c682b028f0a29 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -157,6 +157,7 @@ static const struct goodix_chip_id goodix_chip_ids[] = { { .id = "5663", .data = >1x_chip_data }, { .id = "5688", .data = >1x_chip_data }, { .id = "917S", .data = >1x_chip_data }, + { .id = "9286", .data = >1x_chip_data }, { .id = "911", .data = >911_chip_data }, { .id = "9271", .data = >911_chip_data }, @@ -1448,6 +1449,7 @@ static const struct of_device_id goodix_of_match[] = { { .compatible = "goodix,gt927" }, { .compatible = "goodix,gt9271" }, { .compatible = "goodix,gt928" }, + { .compatible = "goodix,gt9286" }, { .compatible = "goodix,gt967" }, { } }; -- GitLab From b8e594fa20d2e33d40c7a8c7c106549a35c38972 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 8 Jan 2021 10:29:01 -0600 Subject: [PATCH 0114/1084] irqchip/pruss: Simplify the TI_PRUSS_INTC Kconfig The TI PRUSS INTC irqchip driver handles the local interrupt controller which is a child device of it's parent PRUSS/ICSSG device. The driver was upstreamed in parallel with the PRUSS platform driver, and was configurable independently previously. The PRUSS interrupt controller is an integral part of the overall PRUSS software architecture, and is not useful at all by itself. Simplify the TI_PRUSS_INTC Kconfig dependencies by making it silent and selected automatically when the TI_PRUSS platform driver is enabled. Signed-off-by: Suman Anna Reviewed-by: David Lechner Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210108162901.6003-1-s-anna@ti.com --- drivers/irqchip/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 94920a51c6286..b147f22a78f48 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -493,8 +493,9 @@ config TI_SCI_INTA_IRQCHIP TI System Controller, say Y here. Otherwise, say N. config TI_PRUSS_INTC - tristate "TI PRU-ICSS Interrupt Controller" - depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX || ARCH_KEYSTONE || ARCH_K3 + tristate + depends on TI_PRUSS + default TI_PRUSS select IRQ_DOMAIN help This enables support for the PRU-ICSS Local Interrupt Controller -- GitLab From 599b3063adf4bf041a87a69244ee36aded0d878f Mon Sep 17 00:00:00 2001 From: Mathias Kresin Date: Thu, 7 Jan 2021 22:36:03 +0100 Subject: [PATCH 0115/1084] irqchip/mips-cpu: Set IPI domain parent chip Since commit 55567976629e ("genirq/irqdomain: Allow partial trimming of irq_data hierarchy") the irq_data chain is valided. The irq_domain_trim_hierarchy() function doesn't consider the irq + ipi domain hierarchy as valid, since the ipi domain has the irq domain set as parent, but the parent domain has no chip set. Hence the boot ends in a kernel panic. Set the chip for the parent domain as it is done in the mips gic irq driver, to have a valid irq_data chain. Fixes: 3838a547fda2 ("irqchip: mips-cpu: Introduce IPI IRQ domain support") Cc: # v5.10+ Signed-off-by: Mathias Kresin Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210107213603.1637781-1-dev@kresin.me --- drivers/irqchip/irq-mips-cpu.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c index 95d4fd8f7a968..0bbb0b2d0dd5f 100644 --- a/drivers/irqchip/irq-mips-cpu.c +++ b/drivers/irqchip/irq-mips-cpu.c @@ -197,6 +197,13 @@ static int mips_cpu_ipi_alloc(struct irq_domain *domain, unsigned int virq, if (ret) return ret; + ret = irq_domain_set_hwirq_and_chip(domain->parent, virq + i, hwirq, + &mips_mt_cpu_irq_controller, + NULL); + + if (ret) + return ret; + ret = irq_set_irq_type(virq + i, IRQ_TYPE_LEVEL_HIGH); if (ret) return ret; -- GitLab From 1653e3d470629d25c64cd8a2f84adb20a9348b0c Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Tue, 15 Dec 2020 22:26:22 +0100 Subject: [PATCH 0116/1084] arm64: dts: ls1028a: fix the offset of the reset register The offset of the reset request register is 0, the absolute address is 0x1e60000. Boards without PSCI support will fail to perform a reset: [ 26.734700] reboot: Restarting system [ 27.743259] Unable to restart system [ 27.746845] Reboot failed -- System halted Fixes: 8897f3255c9c ("arm64: dts: Add support for NXP LS1028A SoC") Signed-off-by: Michael Walle Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi index 60ff19fa53b40..6c8a61c2cc740 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi @@ -101,7 +101,7 @@ reboot { compatible ="syscon-reboot"; regmap = <&rst>; - offset = <0xb0>; + offset = <0>; mask = <0x02>; }; -- GitLab From fd25c883667b61f845a4188b6be110bb45de0bac Mon Sep 17 00:00:00 2001 From: Soeren Moch Date: Tue, 22 Dec 2020 16:59:08 +0100 Subject: [PATCH 0117/1084] ARM: dts: tbs2910: rename MMC node aliases to be consistent with kernel versions up to v5.9 (mmc aliases not used here). usdhc1 is not wired up on this board and therefore cannot be used. Start mmc aliases with usdhc2. Signed-off-by: Soeren Moch Cc: stable@vger.kernel.org # 5.10.x Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6q-tbs2910.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/imx6q-tbs2910.dts b/arch/arm/boot/dts/imx6q-tbs2910.dts index 861e05d53157e..343364d3e4f7d 100644 --- a/arch/arm/boot/dts/imx6q-tbs2910.dts +++ b/arch/arm/boot/dts/imx6q-tbs2910.dts @@ -16,6 +16,13 @@ stdout-path = &uart1; }; + aliases { + mmc0 = &usdhc2; + mmc1 = &usdhc3; + mmc2 = &usdhc4; + /delete-property/ mmc3; + }; + memory@10000000 { device_type = "memory"; reg = <0x10000000 0x80000000>; -- GitLab From 097530bf8cd469ef7b3d52ef00cafb64b33bacb1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 30 Dec 2020 16:17:51 +0100 Subject: [PATCH 0118/1084] ARM: imx: fix imx8m dependencies Selecting ARM_GIC_V3 on non-CP15 processors leads to build failures like arch/arm/include/asm/arch_gicv3.h: In function 'write_ICC_AP1R3_EL1': arch/arm/include/asm/arch_gicv3.h:36:40: error: 'c12' undeclared (first use in this function) 36 | #define __ICC_AP1Rx(x) __ACCESS_CP15(c12, 0, c9, x) | ^~~ Add a dependency to only enable the gic driver when building for at an ARMv7 target, which is the closes approximation to the ARMv8 processor that is actually in this chip. Fixes: fc40200ebf82 ("soc: imx: increase build coverage for imx8m soc driver") Signed-off-by: Arnd Bergmann Signed-off-by: Shawn Guo --- drivers/soc/imx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig index a9370f4aacca9..05812f8ae7340 100644 --- a/drivers/soc/imx/Kconfig +++ b/drivers/soc/imx/Kconfig @@ -13,7 +13,7 @@ config SOC_IMX8M depends on ARCH_MXC || COMPILE_TEST default ARCH_MXC && ARM64 select SOC_BUS - select ARM_GIC_V3 if ARCH_MXC + select ARM_GIC_V3 if ARCH_MXC && ARCH_MULTI_V7 help If you say yes here you get support for the NXP i.MX8M family support, it will provide the SoC info like SoC family, -- GitLab From 70b6ff4c549a62b59b286445f66cfec6c5327ac8 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Tue, 5 Jan 2021 10:24:07 +0100 Subject: [PATCH 0119/1084] ARM: dts: imx6qdl-kontron-samx6i: fix i2c_lcd/cam default status Fix typo so the gpio i2c busses are really disabled. Fixes: 2125212785c9 ("ARM: dts: imx6qdl-kontron-samx6i: add Kontron SMARC SoM Support") Signed-off-by: Marco Felsch Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi index 36c2f0d9ce164..b167b33bd108d 100644 --- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi @@ -167,7 +167,7 @@ i2c-gpio,delay-us = <2>; /* ~100 kHz */ #address-cells = <1>; #size-cells = <0>; - status = "disabld"; + status = "disabled"; }; i2c_cam: i2c-gpio-cam { @@ -179,7 +179,7 @@ i2c-gpio,delay-us = <2>; /* ~100 kHz */ #address-cells = <1>; #size-cells = <0>; - status = "disabld"; + status = "disabled"; }; }; -- GitLab From 5a22747b76ca2384057d8e783265404439d31d7f Mon Sep 17 00:00:00 2001 From: Koen Vandeputte Date: Thu, 7 Jan 2021 10:19:06 +0100 Subject: [PATCH 0120/1084] ARM: dts: imx6qdl-gw52xx: fix duplicate regulator naming 2 regulator descriptions carry identical naming. This leads to following boot warning: [ 0.173138] debugfs: Directory 'vdd1p8' with parent 'regulator' already present! Fix this by renaming the one used for audio. Fixes: 5051bff33102 ("ARM: dts: imx: ventana: add LTC3676 PMIC support") Signed-off-by: Tim Harvey Signed-off-by: Koen Vandeputte Cc: stable@vger.kernel.org # v4.11 Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl-gw52xx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi index 736074f1c3ef9..959d8ac2e393b 100644 --- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -418,7 +418,7 @@ /* VDD_AUD_1P8: Audio codec */ reg_aud_1p8v: ldo3 { - regulator-name = "vdd1p8"; + regulator-name = "vdd1p8a"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-boot-on; -- GitLab From adc5d8757288a3a5628436d16e78fb696d802e39 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Mon, 7 Dec 2020 01:02:52 +0100 Subject: [PATCH 0121/1084] signal: Add missing __user annotation to copy_siginfo_from_user_any copy_siginfo_from_user_any() takes a userspace pointer as second argument; annotate the parameter type accordingly. Signed-off-by: Jann Horn Link: https://lore.kernel.org/r/20201207000252.138564-1-jannh@google.com Signed-off-by: Christian Brauner --- kernel/signal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/signal.c b/kernel/signal.c index 5736c55aaa1af..546b860c6514d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3701,7 +3701,8 @@ static bool access_pidfd_pidns(struct pid *pid) return true; } -static int copy_siginfo_from_user_any(kernel_siginfo_t *kinfo, siginfo_t *info) +static int copy_siginfo_from_user_any(kernel_siginfo_t *kinfo, + siginfo_t __user *info) { #ifdef CONFIG_COMPAT /* -- GitLab From 96e1e9846c6691f90009ae4d8e486e0ce5c628a7 Mon Sep 17 00:00:00 2001 From: Alexander Guril Date: Sat, 26 Dec 2020 12:40:21 +0100 Subject: [PATCH 0122/1084] Kernel: fork.c: Fix coding style: Do not use {} around single-line statements Fixed two coding style issues in kernel/fork.c Do not use {} around single-line statements. Cc: linux-kernel@vger.kernel.org Acked-by: Christian Brauner Signed-off-by: Alexander Guril Link: https://lore.kernel.org/r/20201226114021.2589-1-alexander.guril02@gmail.com Signed-off-by: Christian Brauner --- kernel/fork.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/fork.c b/kernel/fork.c index 37720a6d04eaa..d66cd1014211b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -819,9 +819,8 @@ void __init fork_init(void) init_task.signal->rlim[RLIMIT_SIGPENDING] = init_task.signal->rlim[RLIMIT_NPROC]; - for (i = 0; i < UCOUNT_COUNTS; i++) { + for (i = 0; i < UCOUNT_COUNTS; i++) init_user_ns.ucount_max[i] = max_threads/2; - } #ifdef CONFIG_VMAP_STACK cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache", @@ -1654,9 +1653,8 @@ static inline void init_task_pid_links(struct task_struct *task) { enum pid_type type; - for (type = PIDTYPE_PID; type < PIDTYPE_MAX; ++type) { + for (type = PIDTYPE_PID; type < PIDTYPE_MAX; ++type) INIT_HLIST_NODE(&task->pid_links[type]); - } } static inline void -- GitLab From 06b831588b639ad9d94e4789b0250562228722c2 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Tue, 5 Jan 2021 10:30:23 +0100 Subject: [PATCH 0123/1084] media: rc: fix timeout handling after switch to microsecond durations Commit 528222d853f92 ("media: rc: harmonize infrared durations to microseconds") missed to switch some timeout calculations from nanoseconds to microseconds. This resulted in spurious key_up+key_down events at the last scancode if the rc device uses a long timeout (eg 100ms on nuvoton-cir) as the device timeout wasn't properly accounted for in the keyup timeout calculation. Fix this by applying the proper conversion functions. Cc: stable@vger.kernel.org Fixes: 528222d853f92 ("media: rc: harmonize infrared durations to microseconds") Signed-off-by: Matthias Reichl Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-mce_kbd-decoder.c | 2 +- drivers/media/rc/rc-main.c | 4 ++-- drivers/media/rc/serial_ir.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index be8f2756a444e..1524dc0fc566e 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -320,7 +320,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev) data->body); spin_lock(&data->keylock); if (scancode) { - delay = nsecs_to_jiffies(dev->timeout) + + delay = usecs_to_jiffies(dev->timeout) + msecs_to_jiffies(100); mod_timer(&data->rx_timeout, jiffies + delay); } else { diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 29d4d01896ff6..1fd62c1dac768 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -737,7 +737,7 @@ static unsigned int repeat_period(int protocol) void rc_repeat(struct rc_dev *dev) { unsigned long flags; - unsigned int timeout = nsecs_to_jiffies(dev->timeout) + + unsigned int timeout = usecs_to_jiffies(dev->timeout) + msecs_to_jiffies(repeat_period(dev->last_protocol)); struct lirc_scancode sc = { .scancode = dev->last_scancode, .rc_proto = dev->last_protocol, @@ -855,7 +855,7 @@ void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode, ir_do_keydown(dev, protocol, scancode, keycode, toggle); if (dev->keypressed) { - dev->keyup_jiffies = jiffies + nsecs_to_jiffies(dev->timeout) + + dev->keyup_jiffies = jiffies + usecs_to_jiffies(dev->timeout) + msecs_to_jiffies(repeat_period(protocol)); mod_timer(&dev->timer_keyup, dev->keyup_jiffies); } diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index 8cc28c92d05d6..96ae0294ac102 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -385,7 +385,7 @@ static irqreturn_t serial_ir_irq_handler(int i, void *blah) } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ mod_timer(&serial_ir.timeout_timer, - jiffies + nsecs_to_jiffies(serial_ir.rcdev->timeout)); + jiffies + usecs_to_jiffies(serial_ir.rcdev->timeout)); ir_raw_event_handle(serial_ir.rcdev); -- GitLab From 9eb09dc2f4650de8c6ce286d3153511e6f6314c0 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Tue, 15 Dec 2020 15:07:44 +0100 Subject: [PATCH 0124/1084] media: venus: core: Fix platform driver shutdown With TZ system reboot cannot finish successfully. To fix that enable core clocks by runtime pm before TZ calls and disable clocks after that. Tested-by: Shawn Guo Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index bdd293faaad0f..7233a73117577 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -349,8 +349,10 @@ static void venus_core_shutdown(struct platform_device *pdev) { struct venus_core *core = platform_get_drvdata(pdev); + pm_runtime_get_sync(core->dev); venus_shutdown(core); venus_firmware_deinit(core); + pm_runtime_put_sync(core->dev); } static __maybe_unused int venus_runtime_suspend(struct device *dev) -- GitLab From 21f603482a6bdc4e7481f5a8e0e4b654d8d6e3a3 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Mon, 11 Jan 2021 13:41:38 +0800 Subject: [PATCH 0125/1084] ASoC: rt5645: Introduce mapping for ACPI-defined GPIO On at least one laptop (ECS EF20EA) the 'hp-detect' GPIO is defined in the DSDT table by the ACPI GpioIo resources in _CRS. The GPIO related information should be mapped to the rt5645 driver to enable the jack detection also on non-DT platforms. Signed-off-by: Chris Chiu Link: https://lore.kernel.org/r/20210111054141.4668-2-chiu@endlessos.org Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 1c9e61abda307..33f277678223c 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -42,6 +42,8 @@ static unsigned int quirk = -1; module_param(quirk, uint, 0444); MODULE_PARM_DESC(quirk, "RT5645 pdata quirk override"); +static const struct acpi_gpio_mapping *cht_rt5645_gpios; + #define RT5645_DEVICE_ID 0x6308 #define RT5650_DEVICE_ID 0x6419 @@ -3831,6 +3833,10 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, rt5645->pdata.dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk); } + if (cht_rt5645_gpios && has_acpi_companion(&i2c->dev)) + if (devm_acpi_dev_add_driver_gpios(&i2c->dev, cht_rt5645_gpios)) + dev_dbg(&i2c->dev, "Failed to add driver gpios\n"); + rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", GPIOD_IN); -- GitLab From a4dae468cfdd90cdb08d96161482c23739dd636a Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Mon, 11 Jan 2021 13:41:39 +0800 Subject: [PATCH 0126/1084] ASoC: rt5645: Add ACPI-defined GPIO for ECS EF20 series Add the hp-detect gpio for ECS EF20 series laptops based on the _CRS defined in DSDT table. Method (_CRS, 0, NotSerialized) { Name (SBUF, ResourceTemplate () { I2cSerialBusV2 (0x001A, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\\_SB.PCI0.I2C2", 0x00, ResourceConsumer, , Exclusive, ) GpioInt (Edge, ActiveBoth, SharedAndWake, PullNone, 0x0000, "\\_SB.GPO3", 0x00, ResourceConsumer, , ) { // Pin list 0x004F } GpioIo (Shared, PullDefault, 0x0000, 0x0000, IoRestrictionInputOnly, "\\_SB.GPO3", 0x00, ResourceConsumer, , ) { // Pin list 0x004F } }) Return (SBUF) /* \_SB_.PCI0.I2C2.RTK2._CRS.SBUF */ } Signed-off-by: Chris Chiu Link: https://lore.kernel.org/r/20210111054141.4668-3-chiu@endlessos.org Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 33f277678223c..f830a463f9b9c 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3636,6 +3636,19 @@ static const struct rt5645_platform_data kahlee_platform_data = { .jd_mode = 3, }; +static const struct acpi_gpio_params ef20_hp_detect = { 1, 0, false }; + +static const struct acpi_gpio_mapping cht_rt5645_ef20_gpios[] = { + { "hp-detect-gpios", &ef20_hp_detect, 1 }, + { }, +}; + +static int cht_rt5645_ef20_quirk_cb(const struct dmi_system_id *id) +{ + cht_rt5645_gpios = cht_rt5645_ef20_gpios; + return 1; +} + static const struct dmi_system_id dmi_platform_data[] = { { .ident = "Chrome Buddy", @@ -3765,6 +3778,20 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&intel_braswell_platform_data, }, + { + .ident = "EF20", + .callback = cht_rt5645_ef20_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "EF20"), + }, + }, + { + .ident = "EF20EA", + .callback = cht_rt5645_ef20_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), + }, + }, { } }; -- GitLab From 28c988492cf65626d06ae32d7f20f1596c080667 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Mon, 11 Jan 2021 13:41:40 +0800 Subject: [PATCH 0127/1084] ASoC: rt5645: add inv_hp_det flag The ECS EF20EA laptop use gpio for jack detection instead of rt5645 rt5645 JD. However, the GPIO polarity is inverse for hp-detect based on the _DSD property of the RTK2 device. Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"hp-detect-gpio", Package() {^RTK2, 0, 0, 1 }}, } }) This flag will invert the hp-detect gpio polarity. Signed-off-by: Chris Chiu Link: https://lore.kernel.org/r/20210111054141.4668-4-chiu@endlessos.org Signed-off-by: Mark Brown --- include/sound/rt5645.h | 2 ++ sound/soc/codecs/rt5645.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/include/sound/rt5645.h b/include/sound/rt5645.h index 39a77c7cea364..710c95be55098 100644 --- a/include/sound/rt5645.h +++ b/include/sound/rt5645.h @@ -22,6 +22,8 @@ struct rt5645_platform_data { bool level_trigger_irq; /* Invert JD1_1 status polarity */ bool inv_jd1_1; + /* Invert HP detect status polarity */ + bool inv_hp_pol; /* Value to asign to snd_soc_card.long_name */ const char *long_name; diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index f830a463f9b9c..aaeb10c593349 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -34,6 +34,7 @@ #define QUIRK_INV_JD1_1(q) ((q) & 1) #define QUIRK_LEVEL_IRQ(q) (((q) >> 1) & 1) #define QUIRK_IN2_DIFF(q) (((q) >> 2) & 1) +#define QUIRK_INV_HP_POL(q) (((q) >> 3) & 1) #define QUIRK_JD_MODE(q) (((q) >> 4) & 7) #define QUIRK_DMIC1_DATA_PIN(q) (((q) >> 8) & 3) #define QUIRK_DMIC2_DATA_PIN(q) (((q) >> 12) & 3) @@ -3246,6 +3247,8 @@ static void rt5645_jack_detect_work(struct work_struct *work) case 0: /* Not using rt5645 JD */ if (rt5645->gpiod_hp_det) { gpio_state = gpiod_get_value(rt5645->gpiod_hp_det); + if (rt5645->pdata.inv_hp_pol) + gpio_state ^= 1; dev_dbg(rt5645->component->dev, "gpio_state = %d\n", gpio_state); report = rt5645_jack_detect(rt5645->component, gpio_state); @@ -3855,6 +3858,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); rt5645->pdata.level_trigger_irq = QUIRK_LEVEL_IRQ(quirk); rt5645->pdata.inv_jd1_1 = QUIRK_INV_JD1_1(quirk); + rt5645->pdata.inv_hp_pol = QUIRK_INV_HP_POL(quirk); rt5645->pdata.jd_mode = QUIRK_JD_MODE(quirk); rt5645->pdata.dmic1_data_pin = QUIRK_DMIC1_DATA_PIN(quirk); rt5645->pdata.dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk); -- GitLab From 3ac2bfd52b7de6206b1e694a4e79a39d6106c961 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Mon, 11 Jan 2021 13:41:41 +0800 Subject: [PATCH 0128/1084] ASoC: rt5645: Enable internal microphone and JD on ECS EF20 On ECS EF20 series laptops, the internal mic is on DMIC2/IN2P. And they need the inv_hp_det to make jack detection to work as exoected. Signed-off-by: Chris Chiu Link: https://lore.kernel.org/r/20210111054141.4668-5-chiu@endlessos.org Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index aaeb10c593349..63a7e052eaa03 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3639,6 +3639,12 @@ static const struct rt5645_platform_data kahlee_platform_data = { .jd_mode = 3, }; +static const struct rt5645_platform_data ecs_ef20_platform_data = { + .dmic1_data_pin = RT5645_DMIC1_DISABLE, + .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, + .inv_hp_pol = 1, +}; + static const struct acpi_gpio_params ef20_hp_detect = { 1, 0, false }; static const struct acpi_gpio_mapping cht_rt5645_ef20_gpios[] = { @@ -3787,6 +3793,7 @@ static const struct dmi_system_id dmi_platform_data[] = { .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "EF20"), }, + .driver_data = (void *)&ecs_ef20_platform_data, }, { .ident = "EF20EA", @@ -3794,6 +3801,7 @@ static const struct dmi_system_id dmi_platform_data[] = { .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), }, + .driver_data = (void *)&ecs_ef20_platform_data, }, { } }; -- GitLab From 867f8d18df4f5ccd6c2daf4441a6adeca0b9725b Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Mon, 11 Jan 2021 17:27:40 +0800 Subject: [PATCH 0129/1084] ASoC: rt5682: fix getting the wrong device id when the suspend_stress_test This patch will be the workaround to fix getting the wrong device ID on the rare chance. It seems like something unstable when the system resumes. e.g. the bus clock This patch tries to read the device ID to check several times. After the test, the driver will get the correct device ID the second time. Signed-off-by: Shuming Fan Link: https://lore.kernel.org/r/20210111092740.9128-1-shumingf@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682-sdw.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index 4d707e854875b..69f046bba67ae 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -375,18 +375,12 @@ static int rt5682_sdw_init(struct device *dev, struct regmap *regmap, static int rt5682_io_init(struct device *dev, struct sdw_slave *slave) { struct rt5682_priv *rt5682 = dev_get_drvdata(dev); - int ret = 0; + int ret = 0, loop = 10; unsigned int val; if (rt5682->hw_init) return 0; - regmap_read(rt5682->regmap, RT5682_DEVICE_ID, &val); - if (val != DEVICE_ID) { - dev_err(dev, "Device with ID register %x is not rt5682\n", val); - return -ENODEV; - } - /* * PM runtime is only enabled when a Slave reports as Attached */ @@ -406,6 +400,19 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave) pm_runtime_get_noresume(&slave->dev); + while (loop > 0) { + regmap_read(rt5682->regmap, RT5682_DEVICE_ID, &val); + if (val == DEVICE_ID) + break; + dev_warn(dev, "Device with ID register %x is not rt5682\n", val); + usleep_range(30000, 30005); + loop--; + } + if (val != DEVICE_ID) { + dev_err(dev, "Device with ID register %x is not rt5682\n", val); + return -ENODEV; + } + if (rt5682->first_hw_init) { regcache_cache_only(rt5682->regmap, false); regcache_cache_bypass(rt5682->regmap, true); -- GitLab From 5a15cd7fce20b1fd4aece6a0240e2b58cd6a225d Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Mon, 11 Jan 2021 17:25:44 +0800 Subject: [PATCH 0130/1084] ASoC: rt5682: enable fast discharge for headset unplugging To avoid the pop noise, this patch enables the feature of fast discharge. Signed-off-by: Shuming Fan Link: https://lore.kernel.org/r/20210111092544.9064-1-shumingf@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 4d865edadd7eb..42ad5bea86b50 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -953,6 +953,8 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) case 0x1: case 0x2: rt5682->jack_type = SND_JACK_HEADSET; + snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, + RT5682_FAST_OFF_MASK, RT5682_FAST_OFF_EN); rt5682_enable_push_button_irq(component, true); break; default: @@ -982,6 +984,8 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) snd_soc_component_update_bits(component, RT5682_MICBIAS_2, RT5682_PWR_CLK25M_MASK | RT5682_PWR_CLK1M_MASK, RT5682_PWR_CLK25M_PD | RT5682_PWR_CLK1M_PD); + snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, + RT5682_FAST_OFF_MASK, RT5682_FAST_OFF_DIS); rt5682->jack_type = 0; } @@ -1011,11 +1015,13 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, if (!rt5682->is_sdw) { switch (rt5682->pdata.jd_src) { case RT5682_JD1: + snd_soc_component_update_bits(component, + RT5682_CBJ_CTRL_5, 0x0700, 0x0600); snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_2, RT5682_EXT_JD_SRC, RT5682_EXT_JD_SRC_MANUAL); snd_soc_component_write(component, RT5682_CBJ_CTRL_1, - 0xd042); + 0xd142); snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_3, RT5682_CBJ_IN_BUF_EN, RT5682_CBJ_IN_BUF_EN); -- GitLab From 4eeed5f40354735c4e68e71904db528ed19c9cbb Mon Sep 17 00:00:00 2001 From: Souptick Joarder Date: Sat, 9 Jan 2021 09:15:01 +0530 Subject: [PATCH 0131/1084] ASoC: soc-pcm: return correct -ERRNO in failure path Kernel test robot throws below error -> sound/soc/soc-pcm.c:2523 dpcm_run_update_startup() error: uninitialized symbol 'ret'. Initializing ret = 0 and returning correct -ERRNO in failure path. Reported-by: kernel test robot Signed-off-by: Souptick Joarder Link: https://lore.kernel.org/r/1610163901-5523-1-git-send-email-jrdr.linux@gmail.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 481a4a25acb04..29328ce39904a 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2432,7 +2432,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) snd_soc_dpcm_get_substream(fe, stream); struct snd_soc_dpcm *dpcm; enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; - int ret; + int ret = 0; unsigned long flags; dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", @@ -2441,6 +2441,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) /* Only start the BE if the FE is ready */ if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_FREE || fe->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE) { + ret = -EINVAL; dev_err(fe->dev, "ASoC: FE %s is not ready %d\n", fe->dai_link->name, fe->dpcm[stream].state); goto disconnect; -- GitLab From fe9989fb25b0cea6414e72e0514c70ed8b158c28 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 11 Jan 2021 13:38:25 +0000 Subject: [PATCH 0132/1084] ASoC: wm_adsp: Fix uninitialized variable warnings wm_adsp_read_data_word() used if (ret) to check for an error from wm_adsp_read_raw_data_block(). While this is perfectly valid, wm_adsp_read_raw_data_block() itself uses if (ret < 0) and three calls to wm_adsp_read_data_word() also use if (ret < 0). This creates an error check chain like this: 1st) if (ret < 0) return ret; 2nd) if (ret) return ret; 3rd) if (ret < 0) ... This can confuse the compiler into thinking that there are possible returns > 0 from the middle if() that are not handled by the final if(). If this was true it would lead to using uninitialized variables later in the outer function. Fix this by changing the test in wm_adsp_read_data_word() to be if (ret < 0). Signed-off-by: Richard Fitzgerald Link: https://lore.kernel.org/r/20210111133825.8758-1-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f8ad768364c23..1fc7bc1970eaa 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3694,7 +3694,7 @@ static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, int ret; ret = wm_adsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); - if (ret) + if (ret < 0) return ret; *data = be32_to_cpu(raw) & 0x00ffffffu; -- GitLab From e91b65b36fde0690f1c694f17dd1b549295464a7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 11 Jan 2021 12:50:21 +0300 Subject: [PATCH 0133/1084] ASoC: soc-pcm: Fix an uninitialized error code The error path here doesn't set "ret" so it returns uninitialized data instead of a negative error code. Fixes: 2c1382840c19 ("ASoC: soc-pcm: disconnect BEs if the FE is not ready") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/X/wfXQFxeMLvpO+1@mwanda Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 29328ce39904a..a253c9f918e1e 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2444,6 +2444,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) ret = -EINVAL; dev_err(fe->dev, "ASoC: FE %s is not ready %d\n", fe->dai_link->name, fe->dpcm[stream].state); + ret = -EINVAL; goto disconnect; } -- GitLab From cb5021ca622fe83923e0789f99fe7227cbcd3f68 Mon Sep 17 00:00:00 2001 From: Yanfei Xu Date: Mon, 11 Jan 2021 18:48:07 +0800 Subject: [PATCH 0134/1084] kthread: remove comments about old _do_fork() helper The old _do_fork() helper has been removed in favor of kernel_clone(). Here correct some comments which still contain _do_fork() Link: https://lore.kernel.org/r/20210111104807.18022-1-yanfei.xu@windriver.com Cc: christian@brauner.io Cc: linux-kernel@vger.kernel.org Acked-by: Christian Brauner Signed-off-by: Yanfei Xu Signed-off-by: Christian Brauner --- include/trace/events/sched.h | 2 +- kernel/kthread.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h index 5039af667645d..cbe3e152d24c0 100644 --- a/include/trace/events/sched.h +++ b/include/trace/events/sched.h @@ -366,7 +366,7 @@ TRACE_EVENT(sched_process_wait, ); /* - * Tracepoint for do_fork: + * Tracepoint for kernel_clone: */ TRACE_EVENT(sched_process_fork, diff --git a/kernel/kthread.c b/kernel/kthread.c index a5eceecd4513c..fb9c3dcbb68db 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -294,7 +294,7 @@ static int kthread(void *_create) do_exit(ret); } -/* called from do_fork() to get node information for about to be created task */ +/* called from kernel_clone() to get node information for about to be created task */ int tsk_fork_get_node(struct task_struct *tsk) { #ifdef CONFIG_NUMA -- GitLab From ca1219c0a7432272324660fc9f61a9940f90c50b Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Tue, 29 Dec 2020 16:16:25 +0800 Subject: [PATCH 0135/1084] mmc: sdhci-of-dwcmshc: fix rpmb access Commit a44f7cb93732 ("mmc: core: use mrq->sbc when sending CMD23 for RPMB") began to use ACMD23 for RPMB if the host supports ACMD23. In RPMB ACM23 case, we need to set bit 31 to CMD23 argument, otherwise RPMB write operation will return general fail. However, no matter V4 is enabled or not, the dwcmshc's ARGUMENT2 register is 32-bit block count register which doesn't support stuff bits of CMD23 argument. So let's handle this specific ACMD23 case. From another side, this patch also prepare for future v4 enabling for dwcmshc, because from the 4.10 spec, the ARGUMENT2 register is redefined as 32bit block count which doesn't support stuff bits of CMD23 argument. Fixes: a44f7cb93732 ("mmc: core: use mrq->sbc when sending CMD23 for RPMB") Signed-off-by: Jisheng Zhang Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/20201229161625.38255233@xhacker.debian Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-dwcmshc.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index 4b673792b5a42..d90020ed36227 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -16,6 +16,8 @@ #include "sdhci-pltfm.h" +#define SDHCI_DWCMSHC_ARG2_STUFF GENMASK(31, 16) + /* DWCMSHC specific Mode Select value */ #define DWCMSHC_CTRL_HS400 0x7 @@ -49,6 +51,29 @@ static void dwcmshc_adma_write_desc(struct sdhci_host *host, void **desc, sdhci_adma_write_desc(host, desc, addr, len, cmd); } +static void dwcmshc_check_auto_cmd23(struct mmc_host *mmc, + struct mmc_request *mrq) +{ + struct sdhci_host *host = mmc_priv(mmc); + + /* + * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit + * block count register which doesn't support stuff bits of + * CMD23 argument on dwcmsch host controller. + */ + if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF)) + host->flags &= ~SDHCI_AUTO_CMD23; + else + host->flags |= SDHCI_AUTO_CMD23; +} + +static void dwcmshc_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + dwcmshc_check_auto_cmd23(mmc, mrq); + + sdhci_request(mmc, mrq); +} + static void dwcmshc_set_uhs_signaling(struct sdhci_host *host, unsigned int timing) { @@ -133,6 +158,8 @@ static int dwcmshc_probe(struct platform_device *pdev) sdhci_get_of_property(pdev); + host->mmc_host_ops.request = dwcmshc_request; + err = sdhci_add_host(host); if (err) goto err_clk; -- GitLab From 1a3ed0dc3594d99ff341ec63865a40519ea24b8d Mon Sep 17 00:00:00 2001 From: Alex Leibovich Date: Fri, 11 Dec 2020 15:16:56 +0100 Subject: [PATCH 0136/1084] mmc: sdhci-xenon: fix 1.8v regulator stabilization Automatic Clock Gating is a feature used for the power consumption optimisation. It turned out that during early init phase it may prevent the stable voltage switch to 1.8V - due to that on some platforms an endless printout in dmesg can be observed: "mmc1: 1.8V regulator output did not became stable" Fix the problem by disabling the ACG at very beginning of the sdhci_init and let that be enabled later. Fixes: 3a3748dba881 ("mmc: sdhci-xenon: Add Marvell Xenon SDHC core functionality") Signed-off-by: Alex Leibovich Signed-off-by: Marcin Wojtas Cc: stable@vger.kernel.org Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/20201211141656.24915-1-mw@semihalf.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-xenon.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c index c67611fdaa8aa..d19eef5f725f8 100644 --- a/drivers/mmc/host/sdhci-xenon.c +++ b/drivers/mmc/host/sdhci-xenon.c @@ -168,7 +168,12 @@ static void xenon_reset_exit(struct sdhci_host *host, /* Disable tuning request and auto-retuning again */ xenon_retune_setup(host); - xenon_set_acg(host, true); + /* + * The ACG should be turned off at the early init time, in order + * to solve a possible issues with the 1.8V regulator stabilization. + * The feature is enabled in later stage. + */ + xenon_set_acg(host, false); xenon_set_sdclk_off_idle(host, sdhc_id, false); -- GitLab From 7024f60d655272bd2ca1d3a4c9e0a63319b1eea1 Mon Sep 17 00:00:00 2001 From: "Hyunwook (Wooky) Baek" Date: Sat, 9 Jan 2021 23:11:02 -0800 Subject: [PATCH 0137/1084] x86/sev-es: Handle string port IO to kernel memory properly Don't assume dest/source buffers are userspace addresses when manually copying data for string I/O or MOVS MMIO, as {get,put}_user() will fail if handed a kernel address and ultimately lead to a kernel panic. When invoking INSB/OUTSB instructions in kernel space in a SEV-ES-enabled VM, the kernel crashes with the following message: "SEV-ES: Unsupported exception in #VC instruction emulation - can't continue" Handle that case properly. [ bp: Massage commit message. ] Fixes: f980f9c31a92 ("x86/sev-es: Compile early handler code into kernel image") Signed-off-by: Hyunwook (Wooky) Baek Signed-off-by: Borislav Petkov Acked-by: David Rientjes Link: https://lkml.kernel.org/r/20210110071102.2576186-1-baekhw@google.com --- arch/x86/kernel/sev-es.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c index 0bd1a0fc587e0..ab31c34ba508c 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -286,6 +286,12 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, u16 d2; u8 d1; + /* If instruction ran in kernel mode and the I/O buffer is in kernel space */ + if (!user_mode(ctxt->regs) && !access_ok(target, size)) { + memcpy(dst, buf, size); + return ES_OK; + } + switch (size) { case 1: memcpy(&d1, buf, 1); @@ -335,6 +341,12 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, u16 d2; u8 d1; + /* If instruction ran in kernel mode and the I/O buffer is in kernel space */ + if (!user_mode(ctxt->regs) && !access_ok(s, size)) { + memcpy(buf, src, size); + return ES_OK; + } + switch (size) { case 1: if (get_user(d1, s)) -- GitLab From 637464c59e0bb13a1da6abf1d7c4b9f9c01646d2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 4 Jan 2021 17:21:25 -0800 Subject: [PATCH 0138/1084] ACPI: NFIT: Fix flexible_array.cocci warnings Julia and 0day report: Zero-length and one-element arrays are deprecated, see Documentation/process/deprecated.rst Flexible-array members should be used instead. However, a straight conversion to flexible arrays yields: drivers/acpi/nfit/core.c:2276:4: error: flexible array member in a struct with no named members drivers/acpi/nfit/core.c:2287:4: error: flexible array member in a struct with no named members Instead, just use plain arrays not embedded flexible arrays. Cc: Denis Efremov Reported-by: kernel test robot Reported-by: Julia Lawall Signed-off-by: Dan Williams --- drivers/acpi/nfit/core.c | 75 +++++++++++++++------------------------- 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index b11b08a606843..8c5dde628405a 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -2269,40 +2269,24 @@ static const struct attribute_group *acpi_nfit_region_attribute_groups[] = { /* enough info to uniquely specify an interleave set */ struct nfit_set_info { - struct nfit_set_info_map { - u64 region_offset; - u32 serial_number; - u32 pad; - } mapping[0]; + u64 region_offset; + u32 serial_number; + u32 pad; }; struct nfit_set_info2 { - struct nfit_set_info_map2 { - u64 region_offset; - u32 serial_number; - u16 vendor_id; - u16 manufacturing_date; - u8 manufacturing_location; - u8 reserved[31]; - } mapping[0]; + u64 region_offset; + u32 serial_number; + u16 vendor_id; + u16 manufacturing_date; + u8 manufacturing_location; + u8 reserved[31]; }; -static size_t sizeof_nfit_set_info(int num_mappings) -{ - return sizeof(struct nfit_set_info) - + num_mappings * sizeof(struct nfit_set_info_map); -} - -static size_t sizeof_nfit_set_info2(int num_mappings) -{ - return sizeof(struct nfit_set_info2) - + num_mappings * sizeof(struct nfit_set_info_map2); -} - static int cmp_map_compat(const void *m0, const void *m1) { - const struct nfit_set_info_map *map0 = m0; - const struct nfit_set_info_map *map1 = m1; + const struct nfit_set_info *map0 = m0; + const struct nfit_set_info *map1 = m1; return memcmp(&map0->region_offset, &map1->region_offset, sizeof(u64)); @@ -2310,8 +2294,8 @@ static int cmp_map_compat(const void *m0, const void *m1) static int cmp_map(const void *m0, const void *m1) { - const struct nfit_set_info_map *map0 = m0; - const struct nfit_set_info_map *map1 = m1; + const struct nfit_set_info *map0 = m0; + const struct nfit_set_info *map1 = m1; if (map0->region_offset < map1->region_offset) return -1; @@ -2322,8 +2306,8 @@ static int cmp_map(const void *m0, const void *m1) static int cmp_map2(const void *m0, const void *m1) { - const struct nfit_set_info_map2 *map0 = m0; - const struct nfit_set_info_map2 *map1 = m1; + const struct nfit_set_info2 *map0 = m0; + const struct nfit_set_info2 *map1 = m1; if (map0->region_offset < map1->region_offset) return -1; @@ -2361,22 +2345,22 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc, return -ENOMEM; import_guid(&nd_set->type_guid, spa->range_guid); - info = devm_kzalloc(dev, sizeof_nfit_set_info(nr), GFP_KERNEL); + info = devm_kcalloc(dev, nr, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - info2 = devm_kzalloc(dev, sizeof_nfit_set_info2(nr), GFP_KERNEL); + info2 = devm_kcalloc(dev, nr, sizeof(*info2), GFP_KERNEL); if (!info2) return -ENOMEM; for (i = 0; i < nr; i++) { struct nd_mapping_desc *mapping = &ndr_desc->mapping[i]; - struct nfit_set_info_map *map = &info->mapping[i]; - struct nfit_set_info_map2 *map2 = &info2->mapping[i]; struct nvdimm *nvdimm = mapping->nvdimm; struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); - struct acpi_nfit_memory_map *memdev = memdev_from_spa(acpi_desc, - spa->range_index, i); + struct nfit_set_info *map = &info[i]; + struct nfit_set_info2 *map2 = &info2[i]; + struct acpi_nfit_memory_map *memdev = + memdev_from_spa(acpi_desc, spa->range_index, i); struct acpi_nfit_control_region *dcr = nfit_mem->dcr; if (!memdev || !nfit_mem->dcr) { @@ -2395,23 +2379,20 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc, } /* v1.1 namespaces */ - sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map), - cmp_map, NULL); - nd_set->cookie1 = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0); + sort(info, nr, sizeof(*info), cmp_map, NULL); + nd_set->cookie1 = nd_fletcher64(info, sizeof(*info) * nr, 0); /* v1.2 namespaces */ - sort(&info2->mapping[0], nr, sizeof(struct nfit_set_info_map2), - cmp_map2, NULL); - nd_set->cookie2 = nd_fletcher64(info2, sizeof_nfit_set_info2(nr), 0); + sort(info2, nr, sizeof(*info2), cmp_map2, NULL); + nd_set->cookie2 = nd_fletcher64(info2, sizeof(*info2) * nr, 0); /* support v1.1 namespaces created with the wrong sort order */ - sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map), - cmp_map_compat, NULL); - nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0); + sort(info, nr, sizeof(*info), cmp_map_compat, NULL); + nd_set->altcookie = nd_fletcher64(info, sizeof(*info) * nr, 0); /* record the result of the sort for the mapping position */ for (i = 0; i < nr; i++) { - struct nfit_set_info_map2 *map2 = &info2->mapping[i]; + struct nfit_set_info2 *map2 = &info2[i]; int j; for (j = 0; j < nr; j++) { -- GitLab From 5b04cb8224ef9bf0d9af8a4c0e6e23806bb2d720 Mon Sep 17 00:00:00 2001 From: Jianpeng Ma Date: Tue, 29 Dec 2020 08:26:35 +0800 Subject: [PATCH 0139/1084] libnvdimm/pmem: Remove unused header 'commit a8b456d01cd6 ("bdi: remove BDI_CAP_SYNCHRONOUS_IO")' forgot remove the related header file. Signed-off-by: Jianpeng Ma Reviewed-by: Ira Weiny Link: https://lore.kernel.org/r/20201229002635.42555-1-jianpeng.ma@intel.com Signed-off-by: Dan Williams --- drivers/nvdimm/pmem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 875076b0ea6c1..f33bdae626baf 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include "pmem.h" -- GitLab From 27b7c6e096264cc7b91bb80a4f65f8c0a66f079f Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Mon, 11 Jan 2021 18:08:32 +0200 Subject: [PATCH 0140/1084] i2c: tegra: Wait for config load atomically while in ISR Upon a communication error, the interrupt handler can call tegra_i2c_disable_packet_mode. This causes a sleeping poll to happen unless the current transaction was marked atomic. Fix this by making the poll happen atomically if we are in an IRQ. This matches the behavior prior to the patch mentioned in the Fixes tag. Fixes: ede2299f7101 ("i2c: tegra: Support atomic transfers") Cc: stable@vger.kernel.org Signed-off-by: Mikko Perttunen Reviewed-by: Dmitry Osipenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-tegra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 6f08c0c3238d5..0727383f49402 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -533,7 +533,7 @@ static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev, void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg); u32 val; - if (!i2c_dev->atomic_mode) + if (!i2c_dev->atomic_mode && !in_irq()) return readl_relaxed_poll_timeout(addr, val, !(val & mask), delay_us, timeout_us); -- GitLab From 5541075a348b6ca6ac668653f7d2c423ae8e00b6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Jan 2021 20:16:50 +0100 Subject: [PATCH 0141/1084] bpf: Prevent double bpf_prog_put call from bpf_tracing_prog_attach MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bpf_tracing_prog_attach error path calls bpf_prog_put on prog, which causes refcount underflow when it's called from link_create function. link_create prog = bpf_prog_get <-- get ... tracing_bpf_link_attach(prog.. bpf_tracing_prog_attach(prog.. out_put_prog: bpf_prog_put(prog); <-- put if (ret < 0) bpf_prog_put(prog); <-- put Removing bpf_prog_put call from bpf_tracing_prog_attach and making sure its callers call it instead. Fixes: 4a1e7c0c63e0 ("bpf: Support attaching freplace programs to multiple attach points") Signed-off-by: Jiri Olsa Signed-off-by: Daniel Borkmann Acked-by: Toke Høiland-Jørgensen Acked-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20210111191650.1241578-1-jolsa@kernel.org --- kernel/bpf/syscall.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index c3bb03c8371fc..e5999d86c76ea 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2712,7 +2712,6 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog, out_put_prog: if (tgt_prog_fd && tgt_prog) bpf_prog_put(tgt_prog); - bpf_prog_put(prog); return err; } @@ -2825,7 +2824,10 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr) tp_name = prog->aux->attach_func_name; break; } - return bpf_tracing_prog_attach(prog, 0, 0); + err = bpf_tracing_prog_attach(prog, 0, 0); + if (err >= 0) + return err; + goto out_put_prog; case BPF_PROG_TYPE_RAW_TRACEPOINT: case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE: if (strncpy_from_user(buf, -- GitLab From 5d06f72dc29c16a4868dd7ea0a6122454267809b Mon Sep 17 00:00:00 2001 From: Souptick Joarder Date: Mon, 11 Jan 2021 19:41:01 -0800 Subject: [PATCH 0142/1084] Input: ariel-pwrbutton - remove unused variable ariel_pwrbutton_id_table Kernel test robot throws below warning -> >> drivers/input/misc/ariel-pwrbutton.c:152:35: warning: unused variable >> 'ariel_pwrbutton_id_table' [-Wunused-const-variable] static const struct spi_device_id ariel_pwrbutton_id_table[] = { ^ 1 warning generated. Remove unused variable ariel_pwrbutton_id_table[] if no plan to use it further. Reported-by: kernel test robot Signed-off-by: Souptick Joarder Reviewed-by: Lubomir Rintel Link: https://lore.kernel.org/r/1608581041-4354-1-git-send-email-jrdr.linux@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ariel-pwrbutton.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/input/misc/ariel-pwrbutton.c b/drivers/input/misc/ariel-pwrbutton.c index eda86ab552b9c..17bbaac8b80c8 100644 --- a/drivers/input/misc/ariel-pwrbutton.c +++ b/drivers/input/misc/ariel-pwrbutton.c @@ -149,12 +149,6 @@ static const struct of_device_id ariel_pwrbutton_of_match[] = { }; MODULE_DEVICE_TABLE(of, ariel_pwrbutton_of_match); -static const struct spi_device_id ariel_pwrbutton_id_table[] = { - { "wyse-ariel-ec-input", 0 }, - {} -}; -MODULE_DEVICE_TABLE(spi, ariel_pwrbutton_id_table); - static struct spi_driver ariel_pwrbutton_driver = { .driver = { .name = "dell-wyse-ariel-ec-input", -- GitLab From 76e2fc63ca40977af893b724b00cc2f8e9ce47a4 Mon Sep 17 00:00:00 2001 From: Yazen Ghannam Date: Mon, 11 Jan 2021 11:04:29 +0100 Subject: [PATCH 0143/1084] x86/cpu/amd: Set __max_die_per_package on AMD Set the maximum DIE per package variable on AMD using the NodesPerProcessor topology value. This will be used by RAPL, among others, to determine the maximum number of DIEs on the system in order to do per-DIE manipulations. [ bp: Productize into a proper patch. ] Fixes: 028c221ed190 ("x86/CPU/AMD: Save AMD NodeId as cpu_die_id") Reported-by: Johnathan Smithinovic Reported-by: Rafael Kitover Signed-off-by: Yazen Ghannam Signed-off-by: Borislav Petkov Tested-by: Johnathan Smithinovic Tested-by: Rafael Kitover Link: https://bugzilla.kernel.org/show_bug.cgi?id=210939 Link: https://lkml.kernel.org/r/20210106112106.GE5729@zn.tnic Link: https://lkml.kernel.org/r/20210111101455.1194-1-bp@alien8.de --- arch/x86/kernel/cpu/amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f8ca66f3d8617..347a956f71ca0 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -542,12 +542,12 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) u32 ecx; ecx = cpuid_ecx(0x8000001e); - nodes_per_socket = ((ecx >> 8) & 7) + 1; + __max_die_per_package = nodes_per_socket = ((ecx >> 8) & 7) + 1; } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) { u64 value; rdmsrl(MSR_FAM10H_NODE_ID, value); - nodes_per_socket = ((value >> 3) & 7) + 1; + __max_die_per_package = nodes_per_socket = ((value >> 3) & 7) + 1; } if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) && -- GitLab From e1def45b5291278590bc3033cc518bf5c964a18d Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 9 Jan 2021 21:10:55 +0100 Subject: [PATCH 0144/1084] media: rc: ite-cir: fix min_timeout calculation Commit 528222d853f92 ("media: rc: harmonize infrared durations to microseconds") missed to switch the min_timeout calculation from ns to us. This resulted in a minimum timeout of 1.2 seconds instead of 1.2ms, leading to large delays and long key repeats. Fix this by applying proper ns->us conversion. Cc: stable@vger.kernel.org Fixes: 528222d853f92 ("media: rc: harmonize infrared durations to microseconds") Signed-off-by: Matthias Reichl Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ite-cir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index a905113fef6ea..0c6229592e132 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1551,7 +1551,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id rdev->s_rx_carrier_range = ite_set_rx_carrier_range; /* FIFO threshold is 17 bytes, so 17 * 8 samples minimum */ rdev->min_timeout = 17 * 8 * ITE_BAUDRATE_DIVISOR * - itdev->params.sample_period; + itdev->params.sample_period / 1000; rdev->timeout = IR_DEFAULT_TIMEOUT; rdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; rdev->rx_resolution = ITE_BAUDRATE_DIVISOR * -- GitLab From a9d4ef643430d638de1910377f50e0d492d85a43 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Mon, 11 Jan 2021 13:49:38 +0200 Subject: [PATCH 0145/1084] habanalabs: fix dma_addr passed to dma_mmap_coherent When doing dma_alloc_coherent in the driver, we add a certain hard-coded offset to the DMA address before returning to the callee function. This offset is needed when our device use this DMA address to perform outbound transactions to the host. However, if we want to map the DMA'able memory to the user via dma_mmap_coherent(), we need to pass the original dma address, without this offset. Otherwise, we will get erronouos mapping. Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/gaudi/gaudi.c | 3 ++- drivers/misc/habanalabs/goya/goya.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 8c09e4466af8c..b328ddaa64ee5 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -4002,7 +4002,8 @@ static int gaudi_cb_mmap(struct hl_device *hdev, struct vm_area_struct *vma, vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_DONTCOPY | VM_NORESERVE; - rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr, dma_addr, size); + rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr, + (dma_addr - HOST_PHYS_BASE), size); if (rc) dev_err(hdev->dev, "dma_mmap_coherent error %d", rc); diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c index b8b4aa636b7cb..63679a747d2cd 100644 --- a/drivers/misc/habanalabs/goya/goya.c +++ b/drivers/misc/habanalabs/goya/goya.c @@ -2719,7 +2719,8 @@ static int goya_cb_mmap(struct hl_device *hdev, struct vm_area_struct *vma, vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_DONTCOPY | VM_NORESERVE; - rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr, dma_addr, size); + rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr, + (dma_addr - HOST_PHYS_BASE), size); if (rc) dev_err(hdev->dev, "dma_mmap_coherent error %d", rc); -- GitLab From aa6df6533b8f9ead98889baa92e2b19793b1c77e Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Mon, 11 Jan 2021 15:00:38 +0200 Subject: [PATCH 0146/1084] habanalabs: fix reset process in case of failures There are some points in the reset process where if the code fails for some reason, and the system admin tries to initiate the reset process again we will get a kernel panic. This is because there aren't any protections in different fini functions that are called during the reset process. The protections that are added in this patch make sure that if the fini functions are called multiple times, without calling init functions between them, there won't be double release of already released resources. Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 2 +- drivers/misc/habanalabs/common/mmu_v1.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 1456eabf96010..1ea57d86caa37 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -1037,7 +1037,7 @@ int hl_device_reset(struct hl_device *hdev, bool hard_reset, if (hard_reset) { /* Release kernel context */ - if (hl_ctx_put(hdev->kernel_ctx) == 1) + if (hdev->kernel_ctx && hl_ctx_put(hdev->kernel_ctx) == 1) hdev->kernel_ctx = NULL; hl_vm_fini(hdev); hl_mmu_fini(hdev); diff --git a/drivers/misc/habanalabs/common/mmu_v1.c b/drivers/misc/habanalabs/common/mmu_v1.c index 2ce6ea89d4fa2..06d8a44dd5d42 100644 --- a/drivers/misc/habanalabs/common/mmu_v1.c +++ b/drivers/misc/habanalabs/common/mmu_v1.c @@ -467,8 +467,16 @@ static void hl_mmu_v1_fini(struct hl_device *hdev) { /* MMU H/W fini was already done in device hw_fini() */ - kvfree(hdev->mmu_priv.dr.mmu_shadow_hop0); - gen_pool_destroy(hdev->mmu_priv.dr.mmu_pgt_pool); + if (!ZERO_OR_NULL_PTR(hdev->mmu_priv.hr.mmu_shadow_hop0)) { + kvfree(hdev->mmu_priv.dr.mmu_shadow_hop0); + gen_pool_destroy(hdev->mmu_priv.dr.mmu_pgt_pool); + } + + /* Make sure that if we arrive here again without init was called we + * won't cause kernel panic. This can happen for example if we fail + * during hard reset code at certain points + */ + hdev->mmu_priv.dr.mmu_shadow_hop0 = NULL; } /** -- GitLab From 9488307a5559255f2fc9a3ab61e1c31e243ca7c6 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Mon, 11 Jan 2021 17:49:30 +0200 Subject: [PATCH 0147/1084] habanalabs: prevent soft lockup during unmap When using Deep learning framework such as tensorflow or pytorch, there are tens of thousands of host memory mappings. When the user frees all those mappings at the same time, the process of unmapping and unpinning them can take a long time, which may cause a soft lockup bug. To prevent this, we need to free the core to do other things during the unmapping process. For now, we chose to do it every 32K unmappings (each unmap is a single 4K page). Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/habanalabs.h | 1 + drivers/misc/habanalabs/common/memory.c | 10 ++++++++-- drivers/misc/habanalabs/common/mmu.c | 6 +++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index e0d7f5fbaa5c3..60e16dc4bcac3 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -2182,6 +2182,7 @@ void hl_mmu_v1_set_funcs(struct hl_device *hdev, struct hl_mmu_funcs *mmu); int hl_mmu_va_to_pa(struct hl_ctx *ctx, u64 virt_addr, u64 *phys_addr); int hl_mmu_get_tlb_info(struct hl_ctx *ctx, u64 virt_addr, struct hl_mmu_hop_info *hops); +bool hl_is_dram_va(struct hl_device *hdev, u64 virt_addr); int hl_fw_load_fw_to_device(struct hl_device *hdev, const char *fw_name, void __iomem *dst, u32 src_offset, u32 size); diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c index cbe9da4e0211b..5d4fbdcaefe3f 100644 --- a/drivers/misc/habanalabs/common/memory.c +++ b/drivers/misc/habanalabs/common/memory.c @@ -886,8 +886,10 @@ static void unmap_phys_pg_pack(struct hl_ctx *ctx, u64 vaddr, { struct hl_device *hdev = ctx->hdev; u64 next_vaddr, i; + bool is_host_addr; u32 page_size; + is_host_addr = !hl_is_dram_va(hdev, vaddr); page_size = phys_pg_pack->page_size; next_vaddr = vaddr; @@ -900,9 +902,13 @@ static void unmap_phys_pg_pack(struct hl_ctx *ctx, u64 vaddr, /* * unmapping on Palladium can be really long, so avoid a CPU * soft lockup bug by sleeping a little between unmapping pages + * + * In addition, when unmapping host memory we pass through + * the Linux kernel to unpin the pages and that takes a long + * time. Therefore, sleep every 32K pages to avoid soft lockup */ - if (hdev->pldm) - usleep_range(500, 1000); + if (hdev->pldm || (is_host_addr && (i & 0x7FFF) == 0)) + usleep_range(50, 200); } } diff --git a/drivers/misc/habanalabs/common/mmu.c b/drivers/misc/habanalabs/common/mmu.c index 33ae953d3a368..28a4638741d88 100644 --- a/drivers/misc/habanalabs/common/mmu.c +++ b/drivers/misc/habanalabs/common/mmu.c @@ -9,7 +9,7 @@ #include "habanalabs.h" -static bool is_dram_va(struct hl_device *hdev, u64 virt_addr) +bool hl_is_dram_va(struct hl_device *hdev, u64 virt_addr) { struct asic_fixed_properties *prop = &hdev->asic_prop; @@ -156,7 +156,7 @@ int hl_mmu_unmap_page(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, if (!hdev->mmu_enable) return 0; - is_dram_addr = is_dram_va(hdev, virt_addr); + is_dram_addr = hl_is_dram_va(hdev, virt_addr); if (is_dram_addr) mmu_prop = &prop->dmmu; @@ -236,7 +236,7 @@ int hl_mmu_map_page(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, if (!hdev->mmu_enable) return 0; - is_dram_addr = is_dram_va(hdev, virt_addr); + is_dram_addr = hl_is_dram_va(hdev, virt_addr); if (is_dram_addr) mmu_prop = &prop->dmmu; -- GitLab From 2672b94d730c4b69a17ce297dc3fa60b980e72dc Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 17 Dec 2020 15:07:21 +0200 Subject: [PATCH 0148/1084] MAINTAINERS: Update my email address and maintainer level status My employment with TI is ending tomorrow, so update the email address entry in the maintainers file. Also, I don't expect to spend that much time with maintaining TI code anymore, so downgrade the status level to odd fixes only on areas where I remain as the main contact point for now, and move myself as secondary contact point where someone else has taken over the maintainership. Signed-off-by: Tero Kristo Signed-off-by: Tero Kristo Signed-off-by: Nishanth Menon Acked-by: Nishanth Menon Cc: Stephen Boyd Cc: Michael Turquette Cc: Nishanth Menon Cc: Santosh Shilimkar Cc: Borislav Petkov Cc: Tony Luck Link: https://lore.kernel.org/r/20201217130721.23555-1-t-kristo@ti.com --- MAINTAINERS | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 546aa66428c9f..ba3e71fde3237 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2617,8 +2617,8 @@ S: Maintained F: drivers/power/reset/keystone-reset.c ARM/TEXAS INSTRUMENTS K3 ARCHITECTURE -M: Tero Kristo M: Nishanth Menon +M: Tero Kristo L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: Documentation/devicetree/bindings/arm/ti/k3.yaml @@ -6474,9 +6474,9 @@ S: Maintained F: drivers/edac/skx_*.[ch] EDAC-TI -M: Tero Kristo +M: Tero Kristo L: linux-edac@vger.kernel.org -S: Maintained +S: Odd Fixes F: drivers/edac/ti_edac.c EDIROL UA-101/UA-1000 DRIVER @@ -17555,7 +17555,7 @@ F: drivers/iio/dac/ti-dac7612.c TEXAS INSTRUMENTS' SYSTEM CONTROL INTERFACE (TISCI) PROTOCOL DRIVER M: Nishanth Menon -M: Tero Kristo +M: Tero Kristo M: Santosh Shilimkar L: linux-arm-kernel@lists.infradead.org S: Maintained @@ -17699,9 +17699,9 @@ S: Maintained F: drivers/clk/clk-cdce706.c TI CLOCK DRIVER -M: Tero Kristo +M: Tero Kristo L: linux-omap@vger.kernel.org -S: Maintained +S: Odd Fixes F: drivers/clk/ti/ F: include/linux/clk/ti.h -- GitLab From 51b2ee7d006a736a9126e8111d1f24e4fd0afaa6 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 11 Jan 2021 16:01:29 -0500 Subject: [PATCH 0149/1084] nfsd4: readdirplus shouldn't return parent of export If you export a subdirectory of a filesystem, a READDIRPLUS on the root of that export will return the filehandle of the parent with the ".." entry. The filehandle is optional, so let's just not return the filehandle for ".." if we're at the root of an export. Note that once the client learns one filehandle outside of the export, they can trivially access the rest of the export using further lookups. However, it is also not very difficult to guess filehandles outside of the export. So exporting a subdirectory of a filesystem should considered equivalent to providing access to the entire filesystem. To avoid confusion, we recommend only exporting entire filesystems. Reported-by: Youjipeng Signed-off-by: J. Bruce Fields Cc: stable@vger.kernel.org Signed-off-by: Chuck Lever --- fs/nfsd/nfs3xdr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 821db21ba072c..34b880211e5ea 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -865,9 +865,14 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, if (isdotent(name, namlen)) { if (namlen == 2) { dchild = dget_parent(dparent); - /* filesystem root - cannot return filehandle for ".." */ + /* + * Don't return filehandle for ".." if we're at + * the filesystem or export root: + */ if (dchild == dparent) goto out; + if (dparent == exp->ex_path.dentry) + goto out; } else dchild = dget(dparent); } else -- GitLab From 1851ccf9e155b2a6f6cca1a7bd49325f5efbd5d2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 9 Jan 2021 22:01:17 +0100 Subject: [PATCH 0150/1084] ASoC: Intel: bytcr_rt5640: Add new BYT_RT5640_NO_SPEAKERS quirk-flag Some devices, like mini PCs/media/top-set boxes do not have any speakers at all, an example of the is the Mele PCG03 Mini PC. Add a new BYT_RT5640_NO_SPEAKERS quirk-flag which when sets does not add speaker routes and modifies the components and the (optional) long_name strings to reflect that there are no speakers. Cc: Rasmus Porsager Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210109210119.159032-2-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_rt5640.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 5520d7c800196..dce2df30d4c5b 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -71,6 +71,7 @@ enum { #define BYT_RT5640_SSP0_AIF2 BIT(21) #define BYT_RT5640_MCLK_EN BIT(22) #define BYT_RT5640_MCLK_25MHZ BIT(23) +#define BYT_RT5640_NO_SPEAKERS BIT(24) #define BYTCR_INPUT_DEFAULTS \ (BYT_RT5640_IN3_MAP | \ @@ -132,6 +133,8 @@ static void log_quirks(struct device *dev) dev_info(dev, "quirk JD_NOT_INV enabled\n"); if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) dev_info(dev, "quirk MONO_SPEAKER enabled\n"); + if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) + dev_info(dev, "quirk NO_SPEAKERS enabled\n"); if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) dev_info(dev, "quirk DIFF_MIC enabled\n"); if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { @@ -946,7 +949,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5640_mono_spk_map, ARRAY_SIZE(byt_rt5640_mono_spk_map)); - } else { + } else if (!(byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)) { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5640_stereo_spk_map, ARRAY_SIZE(byt_rt5640_stereo_spk_map)); @@ -1188,6 +1191,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" }; + __maybe_unused const char *spk_type; const struct dmi_system_id *dmi_id; struct byt_rt5640_private *priv; struct snd_soc_acpi_mach *mach; @@ -1196,7 +1200,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) bool sof_parent; int ret_val = 0; int dai_index = 0; - int i; + int i, cfg_spk; is_bytcr = false; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -1335,16 +1339,24 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) } } + if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) { + cfg_spk = 0; + spk_type = "none"; + } else if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) { + cfg_spk = 1; + spk_type = "mono"; + } else { + cfg_spk = 2; + spk_type = "stereo"; + } + snprintf(byt_rt5640_components, sizeof(byt_rt5640_components), - "cfg-spk:%s cfg-mic:%s", - (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? "1" : "2", + "cfg-spk:%d cfg-mic:%s", cfg_spk, map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); byt_rt5640_card.components = byt_rt5640_components; #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES) snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name), - "bytcr-rt5640-%s-spk-%s-mic", - (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? - "mono" : "stereo", + "bytcr-rt5640-%s-spk-%s-mic", spk_type, map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); byt_rt5640_card.long_name = byt_rt5640_long_name; #endif -- GitLab From 46466ab68e752d054b4b7aece1bfadc9f9bbf272 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 9 Jan 2021 22:01:18 +0100 Subject: [PATCH 0151/1084] ASoC: Intel: bytcr_rt5640: Add new BYT_RT5640_NO_INTERNAL_MIC_MAP input-mapping Some devices, like mini PCs/media/top-set boxes do not have an internal microphone at all, an example of the is the Mele PCG03 Mini PC. Add a new BYT_RT5640_NO_INTERNAL_MIC_MAP input-mapping for this, which does not add any internal-mic routes and modifies the components and the (optional) long_name strings to reflect this. Cc: Rasmus Porsager Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210109210119.159032-3-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_rt5640.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index dce2df30d4c5b..48d781faded11 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -35,6 +35,7 @@ enum { BYT_RT5640_DMIC2_MAP, BYT_RT5640_IN1_MAP, BYT_RT5640_IN3_MAP, + BYT_RT5640_NO_INTERNAL_MIC_MAP, }; enum { @@ -117,6 +118,9 @@ static void log_quirks(struct device *dev) case BYT_RT5640_IN3_MAP: dev_info(dev, "quirk IN3_MAP enabled\n"); break; + case BYT_RT5640_NO_INTERNAL_MIC_MAP: + dev_info(dev, "quirk NO_INTERNAL_MIC_MAP enabled\n"); + break; default: dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map); break; @@ -876,8 +880,8 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_card *card = runtime->card; struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; - const struct snd_soc_dapm_route *custom_map; - int num_routes; + const struct snd_soc_dapm_route *custom_map = NULL; + int num_routes = 0; int ret; card->dapm.idle_bias_off = true; @@ -912,13 +916,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) custom_map = byt_rt5640_intmic_in3_map; num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map); break; + case BYT_RT5640_DMIC1_MAP: + custom_map = byt_rt5640_intmic_dmic1_map; + num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); + break; case BYT_RT5640_DMIC2_MAP: custom_map = byt_rt5640_intmic_dmic2_map; num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); break; - default: - custom_map = byt_rt5640_intmic_dmic1_map; - num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); } ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); @@ -1190,7 +1195,7 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" }; + static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3", "none" }; __maybe_unused const char *spk_type; const struct dmi_system_id *dmi_id; struct byt_rt5640_private *priv; -- GitLab From df33032146baefb29d7e61193738f39e454917e3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 9 Jan 2021 22:01:19 +0100 Subject: [PATCH 0152/1084] ASoC: Intel: bytcr_rt5640: Add quirk for the Mele PCG03 Mini PC Add a quirk for the Mele PCG03 Mini PC, being a Mini PC this device has no speakers and no internal microphone. To make matters worse the speaker output pins are shorted (to gnd or to each other?) and SPKVDD is provided. So trying to output sound on the speakers leads to shorting SPKVDD, this leads to a power dip after which the codec is an unknown state. Sometimes it drops of the i2c bus, sometimes it does still respond to i2c transfers, but is otherwise not functional. TL;DR: trying to use the speaker outputs on this model is BAD. Besides not having speakers / an internal mic, this is a Bay Trail CR device without a CHAN package in ACPI, so we default to SSP0-AIF2 as codec connection. But the device is actually using SSP0-AIF1, so we need to quirk that too. Cc: Rasmus Porsager Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210109210119.159032-4-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 48d781faded11..2dee84578b90a 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -620,6 +620,15 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { /* Mele PCG03 Mini PC */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Mini PC"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Mini PC"), + }, + .driver_data = (void *)(BYT_RT5640_NO_INTERNAL_MIC_MAP | + BYT_RT5640_NO_SPEAKERS | + BYT_RT5640_SSP0_AIF1), + }, { /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"), -- GitLab From 780b1a02c1795b58f217aabfd0688d616408bb89 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 7 Jan 2021 12:53:24 +0100 Subject: [PATCH 0153/1084] ASoC: Intel: cht_bsw_nau8824: Move snd_soc_dai_set_tdm_slot call to cht_codec_fixup Move the snd_soc_dai_set_tdm_slot() call from cht_codec_init() to cht_codec_fixup(). There are 2 reasons for doing this: 1. This aligns the cht_bsw_nau8824 with all the other BYT/CHT machine drivers which also do this from their codec_fixup function. 2. When using the SOF driver, things like the TDM info is set from the topology file. Moving the call to the codec_fixup function, which gets skipped when using the SOF driver avoids the call interfering with the settings when using the SOF driver. Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210107115324.11602-1-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/cht_bsw_nau8824.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c index fd5e25ca05f7f..da5a5cbc87590 100644 --- a/sound/soc/intel/boards/cht_bsw_nau8824.c +++ b/sound/soc/intel/boards/cht_bsw_nau8824.c @@ -100,13 +100,6 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_component *component = codec_dai->component; int ret, jack_type; - /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xf, 0x1, 4, 24); - if (ret < 0) { - dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret); - return ret; - } - /* NAU88L24 supports 4 butons headset detection * KEY_PLAYPAUSE * KEY_VOICECOMMAND @@ -141,6 +134,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + int ret; /* The DSP will covert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; @@ -150,6 +144,13 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, snd_mask_none(fmt); params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xf, 0x1, 4, 24); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); + return ret; + } + return 0; } -- GitLab From 554a1b00957ec1033994a2d03b5b8eac59a24f3c Mon Sep 17 00:00:00 2001 From: Xu Wang Date: Fri, 8 Jan 2021 08:44:56 +0000 Subject: [PATCH 0154/1084] ASoC: adau17x1: Remove redundant null check before clk_disable_unprepare Because clk_disable_unprepare() already checked NULL clock parameter, so the additional check is unnecessary, just remove it. Signed-off-by: Xu Wang Link: https://lore.kernel.org/r/20210108084456.6603-1-vulab@iscas.ac.cn Signed-off-by: Mark Brown --- sound/soc/codecs/adau17x1.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 30e072c80ac17..546ee81780387 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -1095,8 +1095,7 @@ void adau17x1_remove(struct device *dev) { struct adau *adau = dev_get_drvdata(dev); - if (adau->mclk) - clk_disable_unprepare(adau->mclk); + clk_disable_unprepare(adau->mclk); } EXPORT_SYMBOL_GPL(adau17x1_remove); -- GitLab From f2973a1de9d9890b6ac712fb1825d3449ee9cc93 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 12 Jan 2021 11:17:25 +0100 Subject: [PATCH 0155/1084] ASoC: es8316: Fix possible NULL pointer deref in es8316_disable_jack_detect() sound/soc/soc-core.c: soc_remove_component() unconditionally calls snd_soc_component_set_jack(component, NULL, NULL); on any components being removed. This means that on machines where the machine-driver does not provide a jack through snd_soc_component_set_jack() es8316_disable_jack_detect() will still get called and at this time es8316->jack will be NULL and the es8316->jack->status check in es8316_disable_jack_detect() will lead to a NULL pointer deref. Fix this by checking for es8316->jack bein NULL at the start of es8316_disable_jack_detect() and turn the function into a no-op in that case. Cc: russianneuromancer Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20210112101725.44200-1-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/codecs/es8316.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index f9ec5cf825991..1ce84f12a4cfc 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -681,6 +681,9 @@ static void es8316_disable_jack_detect(struct snd_soc_component *component) { struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); + if (!es8316->jack) + return; /* Already disabled (or never enabled) */ + disable_irq(es8316->irq); mutex_lock(&es8316->lock); -- GitLab From 14ff8e1970c03831bf64cf098f56e6ba83349170 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 8 Jan 2021 17:06:10 +0100 Subject: [PATCH 0156/1084] btrfs: no need to run delayed refs after commit_fs_roots during commit The inode number cache has been removed in this dev cycle, there's one more leftover. We don't need to run the delayed refs again after commit_fs_roots as stated in the comment, because btrfs_save_ino_cache is no more since 5297199a8bca ("btrfs: remove inode number cache feature"). Nothing else between commit_fs_roots and btrfs_qgroup_account_extents could create new delayed refs so the qgroup consistency should be safe. Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/transaction.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 8e0f7a1029c6c..6af7f2bf92de7 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -2264,14 +2264,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) */ btrfs_free_log_root_tree(trans, fs_info); - /* - * commit_fs_roots() can call btrfs_save_ino_cache(), which generates - * new delayed refs. Must handle them or qgroup can be wrong. - */ - ret = btrfs_run_delayed_refs(trans, (unsigned long)-1); - if (ret) - goto unlock_tree_log; - /* * Since fs roots are all committed, we can get a quite accurate * new_roots. So let's do quota accounting. -- GitLab From 518837e65068c385dddc0a87b3e577c8be7c13b1 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 11 Jan 2021 11:41:42 +0000 Subject: [PATCH 0157/1084] btrfs: send: fix invalid clone operations when cloning from the same file and root When an incremental send finds an extent that is shared, it checks which file extent items in the range refer to that extent, and for those it emits clone operations, while for others it emits regular write operations to avoid corruption at the destination (as described and fixed by commit d906d49fc5f4 ("Btrfs: send, fix file corruption due to incorrect cloning operations")). However when the root we are cloning from is the send root, we are cloning from the inode currently being processed and the source file range has several extent items that partially point to the desired extent, with an offset smaller than the offset in the file extent item for the range we want to clone into, it can cause the algorithm to issue a clone operation that starts at the current eof of the file being processed in the receiver side, in which case the receiver will fail, with EINVAL, when attempting to execute the clone operation. Example reproducer: $ cat test-send-clone.sh #!/bin/bash DEV=/dev/sdi MNT=/mnt/sdi mkfs.btrfs -f $DEV >/dev/null mount $DEV $MNT # Create our test file with a single and large extent (1M) and with # different content for different file ranges that will be reflinked # later. xfs_io -f \ -c "pwrite -S 0xab 0 128K" \ -c "pwrite -S 0xcd 128K 128K" \ -c "pwrite -S 0xef 256K 256K" \ -c "pwrite -S 0x1a 512K 512K" \ $MNT/foobar btrfs subvolume snapshot -r $MNT $MNT/snap1 btrfs send -f /tmp/snap1.send $MNT/snap1 # Now do a series of changes to our file such that we end up with # different parts of the extent reflinked into different file offsets # and we overwrite a large part of the extent too, so no file extent # items refer to that part that was overwritten. This used to confuse # the algorithm used by the kernel to figure out which file ranges to # clone, making it attempt to clone from a source range starting at # the current eof of the file, resulting in the receiver to fail since # it is an invalid clone operation. # xfs_io -c "reflink $MNT/foobar 64K 1M 960K" \ -c "reflink $MNT/foobar 0K 512K 256K" \ -c "reflink $MNT/foobar 512K 128K 256K" \ -c "pwrite -S 0x73 384K 640K" \ $MNT/foobar btrfs subvolume snapshot -r $MNT $MNT/snap2 btrfs send -f /tmp/snap2.send -p $MNT/snap1 $MNT/snap2 echo -e "\nFile digest in the original filesystem:" md5sum $MNT/snap2/foobar # Now unmount the filesystem, create a new one, mount it and try to # apply both send streams to recreate both snapshots. umount $DEV mkfs.btrfs -f $DEV >/dev/null mount $DEV $MNT btrfs receive -f /tmp/snap1.send $MNT btrfs receive -f /tmp/snap2.send $MNT # Must match what we got in the original filesystem of course. echo -e "\nFile digest in the new filesystem:" md5sum $MNT/snap2/foobar umount $MNT When running the reproducer, the incremental send operation fails due to an invalid clone operation: $ ./test-send-clone.sh wrote 131072/131072 bytes at offset 0 128 KiB, 32 ops; 0.0015 sec (80.906 MiB/sec and 20711.9741 ops/sec) wrote 131072/131072 bytes at offset 131072 128 KiB, 32 ops; 0.0013 sec (90.514 MiB/sec and 23171.6148 ops/sec) wrote 262144/262144 bytes at offset 262144 256 KiB, 64 ops; 0.0025 sec (98.270 MiB/sec and 25157.2327 ops/sec) wrote 524288/524288 bytes at offset 524288 512 KiB, 128 ops; 0.0052 sec (95.730 MiB/sec and 24506.9883 ops/sec) Create a readonly snapshot of '/mnt/sdi' in '/mnt/sdi/snap1' At subvol /mnt/sdi/snap1 linked 983040/983040 bytes at offset 1048576 960 KiB, 1 ops; 0.0006 sec (1.419 GiB/sec and 1550.3876 ops/sec) linked 262144/262144 bytes at offset 524288 256 KiB, 1 ops; 0.0020 sec (120.192 MiB/sec and 480.7692 ops/sec) linked 262144/262144 bytes at offset 131072 256 KiB, 1 ops; 0.0018 sec (133.833 MiB/sec and 535.3319 ops/sec) wrote 655360/655360 bytes at offset 393216 640 KiB, 160 ops; 0.0093 sec (66.781 MiB/sec and 17095.8436 ops/sec) Create a readonly snapshot of '/mnt/sdi' in '/mnt/sdi/snap2' At subvol /mnt/sdi/snap2 File digest in the original filesystem: 9c13c61cb0b9f5abf45344375cb04dfa /mnt/sdi/snap2/foobar At subvol snap1 At snapshot snap2 ERROR: failed to clone extents to foobar: Invalid argument File digest in the new filesystem: 132f0396da8f48d2e667196bff882cfc /mnt/sdi/snap2/foobar The clone operation is invalid because its source range starts at the current eof of the file in the receiver, causing the receiver to get an EINVAL error from the clone operation when attempting it. For the example above, what happens is the following: 1) When processing the extent at file offset 1M, the algorithm checks that the extent is shared and can be (fully or partially) found at file offset 0. At this point the file has a size (and eof) of 1M at the receiver; 2) It finds that our extent item at file offset 1M has a data offset of 64K and, since the file extent item at file offset 0 has a data offset of 0, it issues a clone operation, from the same file and root, that has a source range offset of 64K, destination offset of 1M and a length of 64K, since the extent item at file offset 0 refers only to the first 128K of the shared extent. After this clone operation, the file size (and eof) at the receiver is increased from 1M to 1088K (1M + 64K); 3) Now there's still 896K (960K - 64K) of data left to clone or write, so it checks for the next file extent item, which starts at file offset 128K. This file extent item has a data offset of 0 and a length of 256K, so a clone operation with a source range offset of 256K, a destination offset of 1088K (1M + 64K) and length of 128K is issued. After this operation the file size (and eof) at the receiver increases from 1088K to 1216K (1088K + 128K); 4) Now there's still 768K (896K - 128K) of data left to clone or write, so it checks for the next file extent item, located at file offset 384K. This file extent item points to a different extent, not the one we want to clone, with a length of 640K. So we issue a write operation into the file range 1216K (1088K + 128K, end of the last clone operation), with a length of 640K and with a data matching the one we can find for that range in send root. After this operation, the file size (and eof) at the receiver increases from 1216K to 1856K (1216K + 640K); 5) Now there's still 128K (768K - 640K) of data left to clone or write, so we look into the file extent item, which is for file offset 1M and it points to the extent we want to clone, with a data offset of 64K and a length of 960K. However this matches the file offset we started with, the start of the range to clone into. So we can't for sure find any file extent item from here onwards with the rest of the data we want to clone, yet we proceed and since the file extent item points to the shared extent, with a data offset of 64K, we issue a clone operation with a source range starting at file offset 1856K, which matches the file extent item's offset, 1M, plus the amount of data cloned and written so far, which is 64K (step 2) + 128K (step 3) + 640K (step 4). This clone operation is invalid since the source range offset matches the current eof of the file in the receiver. We should have stopped looking for extents to clone at this point and instead fallback to write, which would simply the contain the data in the file range from 1856K to 1856K + 128K. So fix this by stopping the loop that looks for file ranges to clone at clone_range() when we reach the current eof of the file being processed, if we are cloning from the same file and using the send root as the clone root. This ensures any data not yet cloned will be sent to the receiver through a write operation. A test case for fstests will follow soon. Reported-by: Massimo B. Link: https://lore.kernel.org/linux-btrfs/6ae34776e85912960a253a8327068a892998e685.camel@gmx.net/ Fixes: 11f2069c113e ("Btrfs: send, allow clone operations within the same file") CC: stable@vger.kernel.org # 5.5+ Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/send.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index ae97f4dbaff30..78a35374d4929 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -5512,6 +5512,21 @@ static int clone_range(struct send_ctx *sctx, break; offset += clone_len; clone_root->offset += clone_len; + + /* + * If we are cloning from the file we are currently processing, + * and using the send root as the clone root, we must stop once + * the current clone offset reaches the current eof of the file + * at the receiver, otherwise we would issue an invalid clone + * operation (source range going beyond eof) and cause the + * receiver to fail. So if we reach the current eof, bail out + * and fallback to a regular write. + */ + if (clone_root->root == sctx->send_root && + clone_root->ino == sctx->cur_ino && + clone_root->offset >= sctx->cur_inode_next_write_offset) + break; + data_offset += clone_len; next: path->slots[0]++; -- GitLab From 95e9295daa849095d8be05fb6e26b2ba9be1594f Mon Sep 17 00:00:00 2001 From: Naushir Patuck Date: Wed, 6 Jan 2021 16:16:57 +0100 Subject: [PATCH 0158/1084] media: Revert "media: videobuf2: Fix length check for single plane dmabuf queueing" The updated length check for dmabuf types broke existing usage in v4l2 userland clients. Fixes: 961d3b27 ("media: videobuf2: Fix length check for single plane dmabuf queueing") Cc: stable@vger.kernel.org Signed-off-by: Naushir Patuck Tested-by: Kieran Bingham Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/videobuf2/videobuf2-v4l2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 96d3b2b2aa318..3f61f5863bf77 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -118,8 +118,7 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) return -EINVAL; } } else { - length = (b->memory == VB2_MEMORY_USERPTR || - b->memory == VB2_MEMORY_DMABUF) + length = (b->memory == VB2_MEMORY_USERPTR) ? b->length : vb->planes[0].length; if (b->bytesused > length) -- GitLab From 1a9c72ad4c26821e215a396167c14959cf24a7f1 Mon Sep 17 00:00:00 2001 From: KP Singh Date: Tue, 12 Jan 2021 07:55:24 +0000 Subject: [PATCH 0159/1084] bpf: Local storage helpers should check nullness of owner ptr passed The verifier allows ARG_PTR_TO_BTF_ID helper arguments to be NULL, so helper implementations need to check this before dereferencing them. This was already fixed for the socket storage helpers but not for task and inode. The issue can be reproduced by attaching an LSM program to inode_rename hook (called when moving files) which tries to get the inode of the new file without checking for its nullness and then trying to move an existing file to a new path: mv existing_file new_file_does_not_exist The report including the sample program and the steps for reproducing the bug: https://lore.kernel.org/bpf/CANaYP3HWkH91SN=wTNO9FL_2ztHfqcXKX38SSE-JJ2voh+vssw@mail.gmail.com Fixes: 4cf1bc1f1045 ("bpf: Implement task local storage") Fixes: 8ea636848aca ("bpf: Implement bpf_local_storage for inodes") Reported-by: Gilad Reti Signed-off-by: KP Singh Signed-off-by: Daniel Borkmann Acked-by: Martin KaFai Lau Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20210112075525.256820-3-kpsingh@kernel.org --- kernel/bpf/bpf_inode_storage.c | 5 ++++- kernel/bpf/bpf_task_storage.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/bpf_inode_storage.c b/kernel/bpf/bpf_inode_storage.c index 6edff97ad594b..dbc1dbdd2cbf0 100644 --- a/kernel/bpf/bpf_inode_storage.c +++ b/kernel/bpf/bpf_inode_storage.c @@ -176,7 +176,7 @@ BPF_CALL_4(bpf_inode_storage_get, struct bpf_map *, map, struct inode *, inode, * bpf_local_storage_update expects the owner to have a * valid storage pointer. */ - if (!inode_storage_ptr(inode)) + if (!inode || !inode_storage_ptr(inode)) return (unsigned long)NULL; sdata = inode_storage_lookup(inode, map, true); @@ -200,6 +200,9 @@ BPF_CALL_4(bpf_inode_storage_get, struct bpf_map *, map, struct inode *, inode, BPF_CALL_2(bpf_inode_storage_delete, struct bpf_map *, map, struct inode *, inode) { + if (!inode) + return -EINVAL; + /* This helper must only called from where the inode is gurranteed * to have a refcount and cannot be freed. */ diff --git a/kernel/bpf/bpf_task_storage.c b/kernel/bpf/bpf_task_storage.c index 4ef1959a78f27..e0da0258b732d 100644 --- a/kernel/bpf/bpf_task_storage.c +++ b/kernel/bpf/bpf_task_storage.c @@ -218,7 +218,7 @@ BPF_CALL_4(bpf_task_storage_get, struct bpf_map *, map, struct task_struct *, * bpf_local_storage_update expects the owner to have a * valid storage pointer. */ - if (!task_storage_ptr(task)) + if (!task || !task_storage_ptr(task)) return (unsigned long)NULL; sdata = task_storage_lookup(task, map, true); @@ -243,6 +243,9 @@ BPF_CALL_4(bpf_task_storage_get, struct bpf_map *, map, struct task_struct *, BPF_CALL_2(bpf_task_storage_delete, struct bpf_map *, map, struct task_struct *, task) { + if (!task) + return -EINVAL; + /* This helper must only be called from places where the lifetime of the task * is guaranteed. Either by being refcounted or by being protected * by an RCU read-side critical section. -- GitLab From 84d571d46c7046a957ff3d1c916a1b9dcc7f1ce8 Mon Sep 17 00:00:00 2001 From: KP Singh Date: Tue, 12 Jan 2021 07:55:25 +0000 Subject: [PATCH 0160/1084] bpf: Fix typo in bpf_inode_storage.c Fix "gurranteed" -> "guaranteed" in bpf_inode_storage.c Suggested-by: Andrii Nakryiko Signed-off-by: KP Singh Signed-off-by: Daniel Borkmann Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20210112075525.256820-4-kpsingh@kernel.org --- kernel/bpf/bpf_inode_storage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/bpf_inode_storage.c b/kernel/bpf/bpf_inode_storage.c index dbc1dbdd2cbf0..2f0597320b6d2 100644 --- a/kernel/bpf/bpf_inode_storage.c +++ b/kernel/bpf/bpf_inode_storage.c @@ -183,7 +183,7 @@ BPF_CALL_4(bpf_inode_storage_get, struct bpf_map *, map, struct inode *, inode, if (sdata) return (unsigned long)sdata->data; - /* This helper must only called from where the inode is gurranteed + /* This helper must only called from where the inode is guaranteed * to have a refcount and cannot be freed. */ if (flags & BPF_LOCAL_STORAGE_GET_F_CREATE) { @@ -203,7 +203,7 @@ BPF_CALL_2(bpf_inode_storage_delete, if (!inode) return -EINVAL; - /* This helper must only called from where the inode is gurranteed + /* This helper must only called from where the inode is guaranteed * to have a refcount and cannot be freed. */ return inode_storage_delete(inode, map); -- GitLab From 2f94ac19184665263b7a285ae88abe19dedf9c1b Mon Sep 17 00:00:00 2001 From: KP Singh Date: Tue, 12 Jan 2021 07:55:23 +0000 Subject: [PATCH 0161/1084] bpf: Update local storage test to check handling of null ptrs It was found in [1] that bpf_inode_storage_get helper did not check the nullness of the passed owner ptr which caused an oops when dereferenced. This change incorporates the example suggested in [1] into the local storage selftest. The test is updated to create a temporary directory instead of just using a tempfile. In order to replicate the issue this copied rm binary is renamed tiggering the inode_rename with a null pointer for the new_inode. The logic to verify the setting and deletion of the inode local storage of the old inode is also moved to this LSM hook. The change also removes the copy_rm function and simply shells out to copy files and recursively delete directories and consolidates the logic of setting the initial inode storage to the bprm_committed_creds hook and removes the file_open hook. [1]: https://lore.kernel.org/bpf/CANaYP3HWkH91SN=wTNO9FL_2ztHfqcXKX38SSE-JJ2voh+vssw@mail.gmail.com Suggested-by: Gilad Reti Signed-off-by: KP Singh Signed-off-by: Daniel Borkmann Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20210112075525.256820-2-kpsingh@kernel.org --- .../bpf/prog_tests/test_local_storage.c | 96 +++++-------------- .../selftests/bpf/progs/local_storage.c | 62 ++++++------ 2 files changed, 61 insertions(+), 97 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/test_local_storage.c b/tools/testing/selftests/bpf/prog_tests/test_local_storage.c index c0fe73a17ed12..3bfcf00c0a673 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_local_storage.c +++ b/tools/testing/selftests/bpf/prog_tests/test_local_storage.c @@ -34,61 +34,6 @@ struct storage { struct bpf_spin_lock lock; }; -/* Copies an rm binary to a temp file. dest is a mkstemp template */ -static int copy_rm(char *dest) -{ - int fd_in, fd_out = -1, ret = 0; - struct stat stat; - char *buf = NULL; - - fd_in = open("/bin/rm", O_RDONLY); - if (fd_in < 0) - return -errno; - - fd_out = mkstemp(dest); - if (fd_out < 0) { - ret = -errno; - goto out; - } - - ret = fstat(fd_in, &stat); - if (ret == -1) { - ret = -errno; - goto out; - } - - buf = malloc(stat.st_blksize); - if (!buf) { - ret = -errno; - goto out; - } - - while (ret = read(fd_in, buf, stat.st_blksize), ret > 0) { - ret = write(fd_out, buf, ret); - if (ret < 0) { - ret = -errno; - goto out; - - } - } - if (ret < 0) { - ret = -errno; - goto out; - - } - - /* Set executable permission on the copied file */ - ret = chmod(dest, 0100); - if (ret == -1) - ret = -errno; - -out: - free(buf); - close(fd_in); - close(fd_out); - return ret; -} - /* Fork and exec the provided rm binary and return the exit code of the * forked process and its pid. */ @@ -168,9 +113,11 @@ static bool check_syscall_operations(int map_fd, int obj_fd) void test_test_local_storage(void) { - char tmp_exec_path[PATH_MAX] = "/tmp/copy_of_rmXXXXXX"; + char tmp_dir_path[64] = "/tmp/local_storageXXXXXX"; int err, serv_sk = -1, task_fd = -1, rm_fd = -1; struct local_storage *skel = NULL; + char tmp_exec_path[64]; + char cmd[256]; skel = local_storage__open_and_load(); if (CHECK(!skel, "skel_load", "lsm skeleton failed\n")) @@ -189,18 +136,24 @@ void test_test_local_storage(void) task_fd)) goto close_prog; - err = copy_rm(tmp_exec_path); - if (CHECK(err < 0, "copy_rm", "err %d errno %d\n", err, errno)) + if (CHECK(!mkdtemp(tmp_dir_path), "mkdtemp", + "unable to create tmpdir: %d\n", errno)) goto close_prog; + snprintf(tmp_exec_path, sizeof(tmp_exec_path), "%s/copy_of_rm", + tmp_dir_path); + snprintf(cmd, sizeof(cmd), "cp /bin/rm %s", tmp_exec_path); + if (CHECK_FAIL(system(cmd))) + goto close_prog_rmdir; + rm_fd = open(tmp_exec_path, O_RDONLY); if (CHECK(rm_fd < 0, "open", "failed to open %s err:%d, errno:%d", tmp_exec_path, rm_fd, errno)) - goto close_prog; + goto close_prog_rmdir; if (!check_syscall_operations(bpf_map__fd(skel->maps.inode_storage_map), rm_fd)) - goto close_prog; + goto close_prog_rmdir; /* Sets skel->bss->monitored_pid to the pid of the forked child * forks a child process that executes tmp_exec_path and tries to @@ -209,33 +162,36 @@ void test_test_local_storage(void) */ err = run_self_unlink(&skel->bss->monitored_pid, tmp_exec_path); if (CHECK(err != EPERM, "run_self_unlink", "err %d want EPERM\n", err)) - goto close_prog_unlink; + goto close_prog_rmdir; /* Set the process being monitored to be the current process */ skel->bss->monitored_pid = getpid(); - /* Remove the temporary created executable */ - err = unlink(tmp_exec_path); - if (CHECK(err != 0, "unlink", "unable to unlink %s: %d", tmp_exec_path, - errno)) - goto close_prog_unlink; + /* Move copy_of_rm to a new location so that it triggers the + * inode_rename LSM hook with a new_dentry that has a NULL inode ptr. + */ + snprintf(cmd, sizeof(cmd), "mv %s/copy_of_rm %s/check_null_ptr", + tmp_dir_path, tmp_dir_path); + if (CHECK_FAIL(system(cmd))) + goto close_prog_rmdir; CHECK(skel->data->inode_storage_result != 0, "inode_storage_result", "inode_local_storage not set\n"); serv_sk = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0); if (CHECK(serv_sk < 0, "start_server", "failed to start server\n")) - goto close_prog; + goto close_prog_rmdir; CHECK(skel->data->sk_storage_result != 0, "sk_storage_result", "sk_local_storage not set\n"); if (!check_syscall_operations(bpf_map__fd(skel->maps.sk_storage_map), serv_sk)) - goto close_prog; + goto close_prog_rmdir; -close_prog_unlink: - unlink(tmp_exec_path); +close_prog_rmdir: + snprintf(cmd, sizeof(cmd), "rm -rf %s", tmp_dir_path); + system(cmd); close_prog: close(serv_sk); close(rm_fd); diff --git a/tools/testing/selftests/bpf/progs/local_storage.c b/tools/testing/selftests/bpf/progs/local_storage.c index 3e3de130f28f3..95868bc7ada98 100644 --- a/tools/testing/selftests/bpf/progs/local_storage.c +++ b/tools/testing/selftests/bpf/progs/local_storage.c @@ -50,7 +50,6 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim) __u32 pid = bpf_get_current_pid_tgid() >> 32; struct local_storage *storage; bool is_self_unlink; - int err; if (pid != monitored_pid) return 0; @@ -66,8 +65,27 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim) return -EPERM; } - storage = bpf_inode_storage_get(&inode_storage_map, victim->d_inode, 0, - BPF_LOCAL_STORAGE_GET_F_CREATE); + return 0; +} + +SEC("lsm/inode_rename") +int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) +{ + __u32 pid = bpf_get_current_pid_tgid() >> 32; + struct local_storage *storage; + int err; + + /* new_dentry->d_inode can be NULL when the inode is renamed to a file + * that did not exist before. The helper should be able to handle this + * NULL pointer. + */ + bpf_inode_storage_get(&inode_storage_map, new_dentry->d_inode, 0, + BPF_LOCAL_STORAGE_GET_F_CREATE); + + storage = bpf_inode_storage_get(&inode_storage_map, old_dentry->d_inode, + 0, 0); if (!storage) return 0; @@ -76,7 +94,7 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim) inode_storage_result = -1; bpf_spin_unlock(&storage->lock); - err = bpf_inode_storage_delete(&inode_storage_map, victim->d_inode); + err = bpf_inode_storage_delete(&inode_storage_map, old_dentry->d_inode); if (!err) inode_storage_result = err; @@ -133,37 +151,18 @@ int BPF_PROG(socket_post_create, struct socket *sock, int family, int type, return 0; } -SEC("lsm/file_open") -int BPF_PROG(file_open, struct file *file) -{ - __u32 pid = bpf_get_current_pid_tgid() >> 32; - struct local_storage *storage; - - if (pid != monitored_pid) - return 0; - - if (!file->f_inode) - return 0; - - storage = bpf_inode_storage_get(&inode_storage_map, file->f_inode, 0, - BPF_LOCAL_STORAGE_GET_F_CREATE); - if (!storage) - return 0; - - bpf_spin_lock(&storage->lock); - storage->value = DUMMY_STORAGE_VALUE; - bpf_spin_unlock(&storage->lock); - return 0; -} - /* This uses the local storage to remember the inode of the binary that a * process was originally executing. */ SEC("lsm/bprm_committed_creds") void BPF_PROG(exec, struct linux_binprm *bprm) { + __u32 pid = bpf_get_current_pid_tgid() >> 32; struct local_storage *storage; + if (pid != monitored_pid) + return; + storage = bpf_task_storage_get(&task_storage_map, bpf_get_current_task_btf(), 0, BPF_LOCAL_STORAGE_GET_F_CREATE); @@ -172,4 +171,13 @@ void BPF_PROG(exec, struct linux_binprm *bprm) storage->exec_inode = bprm->file->f_inode; bpf_spin_unlock(&storage->lock); } + + storage = bpf_inode_storage_get(&inode_storage_map, bprm->file->f_inode, + 0, BPF_LOCAL_STORAGE_GET_F_CREATE); + if (!storage) + return; + + bpf_spin_lock(&storage->lock); + storage->value = DUMMY_STORAGE_VALUE; + bpf_spin_unlock(&storage->lock); } -- GitLab From 796130b1de29575e2e3fc3b0da4bda162b750db7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 19 Dec 2020 10:05:45 +0100 Subject: [PATCH 0162/1084] ia64: fix timer cleanup regression A cleanup patch from my legacy timer series broke ia64 and led to RCU stall errors and a fast system clock: [ 909.360108] INFO: task systemd-sysv-ge:200 blocked for more than 127 seconds. [ 909.360108] Not tainted 5.10.0+ #130 [ 909.360108] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 909.360108] task:systemd-sysv-ge state:D stack: 0 pid: 200 ppid: 189 flags:0x00000000 [ 909.364108] [ 909.364108] Call Trace: [ 909.364423] [] __schedule+0x890/0x21e0 [ 909.364423] sp=e0000100487d7b70 bsp=e0000100487d1748 [ 909.368423] [] schedule+0xa0/0x240 [ 909.368423] sp=e0000100487d7b90 bsp=e0000100487d16e0 [ 909.368558] [] io_schedule+0x70/0xa0 [ 909.368558] sp=e0000100487d7b90 bsp=e0000100487d16c0 [ 909.372290] [] bit_wait_io+0x20/0xe0 [ 909.372290] sp=e0000100487d7b90 bsp=e0000100487d1698 [ 909.374168] rcu: INFO: rcu_sched detected stalls on CPUs/tasks: [ 909.376290] [] __wait_on_bit+0xc0/0x1c0 [ 909.376290] sp=e0000100487d7b90 bsp=e0000100487d1648 [ 909.374168] rcu: 3-....: (2 ticks this GP) idle=19e/1/0x4000000000000002 softirq=1581/1581 fqs=2 [ 909.374168] (detected by 0, t=5661 jiffies, g=1089, q=3) [ 909.376290] [] out_of_line_wait_on_bit+0x120/0x140 [ 909.376290] sp=e0000100487d7b90 bsp=e0000100487d1610 [ 909.374168] Task dump for CPU 3: [ 909.374168] task:khungtaskd state:R running task Revert most of my patch to make this work again, including the extra update_process_times()/profile_tick() and the local_irq_enable() in the loop that I expected not to be needed here. I have not found out exactly what goes wrong, and would suggest that someone with hardware access tries to convert this code into a singleshot clockevent driver, which should give better behavior in all cases. Reported-by: John Paul Adrian Glaubitz Fixes: 2b49ddcef297 ("ia64: convert to legacy_timer_tick") Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: Frederic Weisbecker Signed-off-by: Arnd Bergmann --- arch/ia64/kernel/time.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index ed9fc3d057a6d..43e8050145bef 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -171,29 +171,34 @@ void vtime_account_hardirq(struct task_struct *tsk) static irqreturn_t timer_interrupt (int irq, void *dev_id) { - unsigned long cur_itm, new_itm, ticks; + unsigned long new_itm; if (cpu_is_offline(smp_processor_id())) { return IRQ_HANDLED; } new_itm = local_cpu_data->itm_next; - cur_itm = ia64_get_itc(); - if (!time_after(cur_itm, new_itm)) { + if (!time_after(ia64_get_itc(), new_itm)) printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", - cur_itm, new_itm); - ticks = 1; - } else { - ticks = DIV_ROUND_UP(cur_itm - new_itm, - local_cpu_data->itm_delta); - new_itm += ticks * local_cpu_data->itm_delta; - } + ia64_get_itc(), new_itm); + + while (1) { + new_itm += local_cpu_data->itm_delta; + + legacy_timer_tick(smp_processor_id() == time_keeper_id); - if (smp_processor_id() != time_keeper_id) - ticks = 0; + local_cpu_data->itm_next = new_itm; - legacy_timer_tick(ticks); + if (time_after(new_itm, ia64_get_itc())) + break; + + /* + * Allow IPIs to interrupt the timer loop. + */ + local_irq_enable(); + local_irq_disable(); + } do { /* -- GitLab From 968d7764e35b2fa4aad36481690b297e2c497c99 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 4 Jan 2021 09:52:48 +0100 Subject: [PATCH 0163/1084] ia64: fix xchg() warning The definition if xchg() causes a harmless warning in some files, like: In file included from ../arch/ia64/include/uapi/asm/intrinsics.h:22, from ../arch/ia64/include/asm/intrinsics.h:11, from ../arch/ia64/include/asm/bitops.h:19, from ../include/linux/bitops.h:32, from ../include/linux/kernel.h:11, from ../fs/nfs/read.c:12: ../fs/nfs/read.c: In function 'nfs_read_completion': ../arch/ia64/include/uapi/asm/cmpxchg.h:57:2: warning: value computed is not used [-Wunused-value] 57 | ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../fs/nfs/read.c:196:5: note: in expansion of macro 'xchg' 196 | xchg(&nfs_req_openctx(req)->error, error); | ^~~~ Change it to a compound expression like the other architectures have to get a clean defconfig build. Signed-off-by: Arnd Bergmann --- arch/ia64/include/uapi/asm/cmpxchg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/include/uapi/asm/cmpxchg.h b/arch/ia64/include/uapi/asm/cmpxchg.h index d69c979936d41..5d90307fd6e07 100644 --- a/arch/ia64/include/uapi/asm/cmpxchg.h +++ b/arch/ia64/include/uapi/asm/cmpxchg.h @@ -54,7 +54,7 @@ extern void ia64_xchg_called_with_bad_pointer(void); }) #define xchg(ptr, x) \ -((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) +({(__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)));}) /* * Atomic compare and exchange. Compare OLD with MEM, if identical, -- GitLab From 96ec72a3425d1515b69b7f9dc34a4a6ce5862a37 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 5 Jan 2021 14:49:27 +0100 Subject: [PATCH 0164/1084] ia64: Mark architecture as orphaned Tony Luck has maintained arch/ia64 for the past 16 years, but mentioned that he no longer has working ia64 machines, nor time to look at patches, so he is stepping down as the maintainer. Fenghua Yu came in as a temporary co-maintainer when Tony was on sabbatical in 2009, but has not worked on it after that either. This leaves the architecture as Orphaned, meaning that patches will have to get routed through other trees from now on. Acked-by: Tony Luck Cc: Fenghua Yu Cc: linux-ia64@vger.kernel.org Link: https://lore.kernel.org/lkml/20210105153603.GA17644@agluck-desk2.amr.corp.intel.com/ Signed-off-by: Arnd Bergmann --- MAINTAINERS | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 546aa66428c9f..472cfcc7c11a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8435,11 +8435,8 @@ F: drivers/i3c/ F: include/linux/i3c/ IA64 (Itanium) PLATFORM -M: Tony Luck -M: Fenghua Yu L: linux-ia64@vger.kernel.org -S: Odd Fixes -T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git +S: Orphan F: Documentation/ia64/ F: arch/ia64/ -- GitLab From 280a9045bb18833db921b316a5527d2b565e9f2e Mon Sep 17 00:00:00 2001 From: Eugene Korenevsky Date: Sun, 10 Jan 2021 20:36:09 +0300 Subject: [PATCH 0165/1084] ehci: fix EHCI host controller initialization sequence According to EHCI spec, EHCI HC clears USBSTS.HCHalted whenever USBCMD.RS=1. However, it is a good practice to wait some time after setting USBCMD.RS (approximately 100ms) until USBSTS.HCHalted become zero. Without this waiting, VirtualBox's EHCI virtual HC accidentally hangs (see BugLink). BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=211095 Acked-by: Alan Stern Signed-off-by: Eugene Korenevsky Cc: stable Link: https://lore.kernel.org/r/20210110173609.GA17313@himera.home Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index e358ae17d51e7..1926b328b6aa7 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -574,6 +574,7 @@ static int ehci_run (struct usb_hcd *hcd) struct ehci_hcd *ehci = hcd_to_ehci (hcd); u32 temp; u32 hcc_params; + int rc; hcd->uses_new_polling = 1; @@ -629,9 +630,20 @@ static int ehci_run (struct usb_hcd *hcd) down_write(&ehci_cf_port_reset_rwsem); ehci->rh_state = EHCI_RH_RUNNING; ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); + + /* Wait until HC become operational */ ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ msleep(5); + rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000); + up_write(&ehci_cf_port_reset_rwsem); + + if (rc) { + ehci_err(ehci, "USB %x.%x, controller refused to start: %d\n", + ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), rc); + return rc; + } + ehci->last_periodic_enable = ktime_get_real(); temp = HC_VERSION(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); -- GitLab From 643a4df7fe3f6831d14536fd692be85f92670a52 Mon Sep 17 00:00:00 2001 From: Longfang Liu Date: Tue, 12 Jan 2021 09:57:27 +0800 Subject: [PATCH 0166/1084] USB: ehci: fix an interrupt calltrace error The system that use Synopsys USB host controllers goes to suspend when using USB audio player. This causes the USB host controller continuous send interrupt signal to system, When the number of interrupts exceeds 100000, the system will forcibly close the interrupts and output a calltrace error. When the system goes to suspend, the last interrupt is reported to the driver. At this time, the system has set the state to suspend. This causes the last interrupt to not be processed by the system and not clear the interrupt flag. This uncleared interrupt flag constantly triggers new interrupt event. This causing the driver to receive more than 100,000 interrupts, which causes the system to forcibly close the interrupt report and report the calltrace error. so, when the driver goes to sleep and changes the system state to suspend, the interrupt flag needs to be cleared. Signed-off-by: Longfang Liu Acked-by: Alan Stern Link: https://lore.kernel.org/r/1610416647-45774-1-git-send-email-liulongfang@huawei.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hub.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 087402aec5cbe..9f9ab5ccea889 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -345,6 +345,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) unlink_empty_async_suspended(ehci); + /* Some Synopsys controllers mistakenly leave IAA turned on */ + ehci_writel(ehci, STS_IAA, &ehci->regs->status); + /* Any IAA cycle that started before the suspend is now invalid */ end_iaa_cycle(ehci); ehci_handle_start_intr_unlinks(ehci); -- GitLab From 4e0dcf62ab4cf917d0cbe751b8bf229a065248d4 Mon Sep 17 00:00:00 2001 From: Ryan Chen Date: Fri, 8 Jan 2021 16:12:38 +0800 Subject: [PATCH 0167/1084] usb: gadget: aspeed: fix stop dma register setting. The vhub engine has two dma mode, one is descriptor list, another is single stage DMA. Each mode has different stop register setting. Descriptor list operation (bit2) : 0 disable reset, 1: enable reset Single mode operation (bit0) : 0 : disable, 1: enable Fixes: 7ecca2a4080c ("usb/gadget: Add driver for Aspeed SoC virtual hub") Cc: stable Acked-by: Felipe Balbi Acked-by: Joel Stanley Signed-off-by: Ryan Chen Link: https://lore.kernel.org/r/20210108081238.10199-2-ryan_chen@aspeedtech.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/aspeed-vhub/epn.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/aspeed-vhub/epn.c b/drivers/usb/gadget/udc/aspeed-vhub/epn.c index 0bd6b20435b8a..02d8bfae58fb1 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/epn.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/epn.c @@ -420,7 +420,10 @@ static void ast_vhub_stop_active_req(struct ast_vhub_ep *ep, u32 state, reg, loops; /* Stop DMA activity */ - writel(0, ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); + if (ep->epn.desc_mode) + writel(VHUB_EP_DMA_CTRL_RESET, ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); + else + writel(0, ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); /* Wait for it to complete */ for (loops = 0; loops < 1000; loops++) { -- GitLab From 8b66d7c58c11cf3b1a1cea738582367a96cdaaf8 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Tue, 5 Jan 2021 17:56:40 +0200 Subject: [PATCH 0168/1084] ASoC: SOF: add mutex to protect the dsp_power_state access There could be more than one thread read/write the dsp_power_state simultaneously (e.g. hda_dsp_d0i3_work and sof_ipc_tx_message), add a mutex power_state_access to make sure the access to it is mutually exclusive. Signed-off-by: Keyon Jie Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Guennadi Liakhovetski Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210105155640.3725238-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/core.c | 1 + sound/soc/sof/ops.h | 11 ++++++++--- sound/soc/sof/sof-priv.h | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index adc7c37145d64..2b85ef5d6092a 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -316,6 +316,7 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) INIT_LIST_HEAD(&sdev->route_list); spin_lock_init(&sdev->ipc_lock); spin_lock_init(&sdev->hw_lock); + mutex_init(&sdev->power_state_access); if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) INIT_WORK(&sdev->probe_work, sof_probe_work); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 95e748b36903a..4c1f9daaa6e87 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -208,11 +208,16 @@ static inline int snd_sof_dsp_set_power_state(struct snd_sof_dev *sdev, const struct sof_dsp_power_state *target_state) { + int ret = 0; + + mutex_lock(&sdev->power_state_access); + if (sof_ops(sdev)->set_power_state) - return sof_ops(sdev)->set_power_state(sdev, target_state); + ret = sof_ops(sdev)->set_power_state(sdev, target_state); - /* D0 substate is not supported, do nothing here. */ - return 0; + mutex_unlock(&sdev->power_state_access); + + return ret; } /* debug */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 68da8f797403e..28d19fa30614e 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -375,6 +375,8 @@ struct snd_sof_dev { /* current DSP power state */ struct sof_dsp_power_state dsp_power_state; + /* mutex to protect the dsp_power_state access */ + struct mutex power_state_access; /* Intended power target of system suspend */ enum sof_system_suspend_state system_suspend_target; -- GitLab From 895bee270863588fe3d46dca86cd15d461f47a7a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 12 Jan 2021 19:02:29 +0100 Subject: [PATCH 0169/1084] Revert "driver core: Reorder devices on successful probe" This reverts commit 5b6164d3465fcc13b5679c860c452963443172a7. Stephan reports problems with this commit, so revert it for now. Fixes: 5b6164d3465f ("driver core: Reorder devices on successful probe") Link: https://lore.kernel.org/r/X/ycQpu7NIGI969v@gerhold.net Reported-by: Stephan Gerhold Cc: Jonathan Hunter Cc: Rafael. J. Wysocki Cc: Thierry Reding Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 0b76b54237781..9179825ff646f 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -370,13 +370,6 @@ static void driver_bound(struct device *dev) device_pm_check_callbacks(dev); - /* - * Reorder successfully probed devices to the end of the device list. - * This ensures that suspend/resume order matches probe order, which - * is usually what drivers rely on. - */ - device_pm_move_to_tail(dev); - /* * Make sure the device is no longer in one of the deferred lists and * kick off retrying all pending devices -- GitLab From 98829137a6a04785c8812670a7fa16d7dd59f05a Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 21 Dec 2020 23:33:36 +0530 Subject: [PATCH 0170/1084] clk: qcom: gcc-sc7180: Mark the camera abh clock always ON The camera clock controller requires the AHB clock, the driver when moved to use the pm_runtime_get() API, the camera ahb clock failed turn on before access, thus mark it as always ON. Reported-by: Stephen Boyd Fixes: 8d4025943e13 ("clk: qcom: camcc-sc7180: Use runtime PM ops instead of clk ones") Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/1608573816-1465-1-git-send-email-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-sc7180.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index d82d725ac2319..b05901b249172 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -891,21 +891,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = { }, }; -static struct clk_branch gcc_camera_ahb_clk = { - .halt_reg = 0xb008, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb008, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb008, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_ahb_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_camera_hf_axi_clk = { .halt_reg = 0xb020, .halt_check = BRANCH_HALT, @@ -2317,7 +2302,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, - [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr, [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, [GCC_CAMERA_THROTTLE_HF_AXI_CLK] = &gcc_camera_throttle_hf_axi_clk.clkr, [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, @@ -2519,11 +2503,12 @@ static int gcc_sc7180_probe(struct platform_device *pdev) /* * Keep the clocks always-ON - * GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_DISP_AHB_CLK - * GCC_GPU_CFG_AHB_CLK + * GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_CAMERA_AHB_CLK, + * GCC_DISP_AHB_CLK, GCC_GPU_CFG_AHB_CLK */ regmap_update_bits(regmap, 0x48004, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b008, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); -- GitLab From 73f6b7ed9835ad9f953aebd60dd720aabc487b81 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 30 Dec 2020 16:52:25 +0100 Subject: [PATCH 0171/1084] clk: imx: fix Kconfig warning for i.MX SCU clk A previous patch introduced a harmless randconfig warning: WARNING: unmet direct dependencies detected for MXC_CLK_SCU Depends on [n]: COMMON_CLK [=y] && ARCH_MXC [=n] && IMX_SCU [=y] && HAVE_ARM_SMCCC [=y] Selected by [m]: - CLK_IMX8QXP [=m] && COMMON_CLK [=y] && (ARCH_MXC [=n] && ARM64 [=y] || COMPILE_TEST [=y]) && IMX_SCU [=y] && HAVE_ARM_SMCCC [=y] Since the symbol is now hidden and only selected by other symbols, just remove the dependencies and require the other drivers to get it right. Fixes: 6247e31b7530 ("clk: imx: scu: fix MXC_CLK_SCU module build break") Reported-by: Anders Roxell Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20201230155244.981757-1-arnd@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/imx/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index 3061896503f30..47d9ec3abd2f7 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -6,8 +6,6 @@ config MXC_CLK config MXC_CLK_SCU tristate - depends on ARCH_MXC - depends on IMX_SCU && HAVE_ARM_SMCCC config CLK_IMX1 def_bool SOC_IMX1 -- GitLab From 4be34f3d0731b38a1b24566b37fbb39500aaf3a2 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Tue, 12 Jan 2021 08:28:29 -0800 Subject: [PATCH 0172/1084] bpf: Don't leak memory in bpf getsockopt when optlen == 0 optlen == 0 indicates that the kernel should ignore BPF buffer and use the original one from the user. We, however, forget to free the temporary buffer that we've allocated for BPF. Fixes: d8fe449a9c51 ("bpf: Don't return EINVAL from {get,set}sockopt when optlen > PAGE_SIZE") Reported-by: Martin KaFai Lau Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann Acked-by: Martin KaFai Lau Link: https://lore.kernel.org/bpf/20210112162829.775079-1-sdf@google.com --- kernel/bpf/cgroup.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 6ec088a96302f..96555a8a2c545 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1391,12 +1391,13 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level, if (ctx.optlen != 0) { *optlen = ctx.optlen; *kernel_optval = ctx.optval; + /* export and don't free sockopt buf */ + return 0; } } out: - if (ret) - sockopt_free_buf(&ctx); + sockopt_free_buf(&ctx); return ret; } -- GitLab From fd2383093593b23f8814a879093b746e502fe3cf Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 9 Jan 2021 04:33:14 +0300 Subject: [PATCH 0173/1084] clk: qcom: gcc-sm250: Use floor ops for sdcc clks Followup to the commits 5e4b7e82d497 ("clk: qcom: gcc-sdm845: Use floor ops for sdcc clks") and 6d37a8d19283 ("clk: qcom: gcc-sc7180: Use floor ops for sdcc clks"). Use floor ops for sdcc clocks on sm8250. Signed-off-by: Dmitry Baryshkov Fixes: 3e5770921a88 ("clk: qcom: gcc: Add global clock controller driver for SM8250") Link: https://lore.kernel.org/r/20210109013314.3443134-1-dmitry.baryshkov@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-sm8250.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c index 6cb6617b8d88c..ab594a0f0c408 100644 --- a/drivers/clk/qcom/gcc-sm8250.c +++ b/drivers/clk/qcom/gcc-sm8250.c @@ -722,7 +722,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_4, .num_parents = 5, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; @@ -745,7 +745,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .name = "gcc_sdcc4_apps_clk_src", .parent_data = gcc_parent_data_0, .num_parents = 3, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; -- GitLab From c361c5a6c559d1e0a2717abe9162a71aa602954f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 3 Jan 2021 14:54:53 +0100 Subject: [PATCH 0174/1084] clk: mmp2: fix build without CONFIG_PM pm_clk_suspend()/pm_clk_resume() are defined as NULL pointers rather than empty inline stubs without CONFIG_PM: drivers/clk/mmp/clk-audio.c:402:16: error: called object type 'void *' is not a function or function pointer pm_clk_suspend(dev); drivers/clk/mmp/clk-audio.c:411:15: error: called object type 'void *' is not a function or function pointer pm_clk_resume(dev); I tried redefining the helper functions, but that caused additional problems. This is the simple solution of replacing the __maybe_unused trick with an #ifdef. Fixes: 725262d29139 ("clk: mmp2: Add audio clock controller driver") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20210103135503.3668784-1-arnd@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/mmp/clk-audio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mmp/clk-audio.c b/drivers/clk/mmp/clk-audio.c index eea69d498bd27..7aa7f4a9564fd 100644 --- a/drivers/clk/mmp/clk-audio.c +++ b/drivers/clk/mmp/clk-audio.c @@ -392,7 +392,8 @@ static int mmp2_audio_clk_remove(struct platform_device *pdev) return 0; } -static int __maybe_unused mmp2_audio_clk_suspend(struct device *dev) +#ifdef CONFIG_PM +static int mmp2_audio_clk_suspend(struct device *dev) { struct mmp2_audio_clk *priv = dev_get_drvdata(dev); @@ -404,7 +405,7 @@ static int __maybe_unused mmp2_audio_clk_suspend(struct device *dev) return 0; } -static int __maybe_unused mmp2_audio_clk_resume(struct device *dev) +static int mmp2_audio_clk_resume(struct device *dev) { struct mmp2_audio_clk *priv = dev_get_drvdata(dev); @@ -415,6 +416,7 @@ static int __maybe_unused mmp2_audio_clk_resume(struct device *dev) return 0; } +#endif static const struct dev_pm_ops mmp2_audio_clk_pm_ops = { SET_RUNTIME_PM_OPS(mmp2_audio_clk_suspend, mmp2_audio_clk_resume, NULL) -- GitLab From 9caa7ff509add50959a793b811cc7c9339e281cd Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 6 Jan 2021 15:36:20 +0100 Subject: [PATCH 0175/1084] x86/entry: Fix noinstr fail vmlinux.o: warning: objtool: __do_fast_syscall_32()+0x47: call to syscall_enter_from_user_mode_work() leaves .noinstr.text section Fixes: 4facb95b7ada ("x86/entry: Unbreak 32bit fast syscall") Reported-by: Randy Dunlap Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210106144017.472696632@infradead.org --- arch/x86/entry/common.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 18d8f17f755c4..0904f5676e4d8 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -73,10 +73,8 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, unsigned int nr) { if (likely(nr < IA32_NR_syscalls)) { - instrumentation_begin(); nr = array_index_nospec(nr, IA32_NR_syscalls); regs->ax = ia32_sys_call_table[nr](regs); - instrumentation_end(); } } @@ -91,8 +89,11 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) * or may not be necessary, but it matches the old asm behavior. */ nr = (unsigned int)syscall_enter_from_user_mode(regs, nr); + instrumentation_begin(); do_syscall_32_irqs_on(regs, nr); + + instrumentation_end(); syscall_exit_to_user_mode(regs); } @@ -121,11 +122,12 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) res = get_user(*(u32 *)®s->bp, (u32 __user __force *)(unsigned long)(u32)regs->sp); } - instrumentation_end(); if (res) { /* User code screwed up. */ regs->ax = -EFAULT; + + instrumentation_end(); syscall_exit_to_user_mode(regs); return false; } @@ -135,6 +137,8 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) /* Now this is just like a normal syscall. */ do_syscall_32_irqs_on(regs, nr); + + instrumentation_end(); syscall_exit_to_user_mode(regs); return true; } -- GitLab From a1d5c98aac33a5a0004ecf88905dcc261c52f988 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 6 Jan 2021 15:36:21 +0100 Subject: [PATCH 0176/1084] x86/sev: Fix nonistr violation When the compiler fails to inline, it violates nonisntr: vmlinux.o: warning: objtool: __sev_es_nmi_complete()+0xc7: call to sev_es_wr_ghcb_msr() leaves .noinstr.text section Fixes: 4ca68e023b11 ("x86/sev-es: Handle NMI State") Reported-by: Randy Dunlap Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210106144017.532902065@infradead.org --- arch/x86/kernel/sev-es.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c index ab31c34ba508c..84c1821819afb 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -225,7 +225,7 @@ static inline u64 sev_es_rd_ghcb_msr(void) return __rdmsr(MSR_AMD64_SEV_ES_GHCB); } -static inline void sev_es_wr_ghcb_msr(u64 val) +static __always_inline void sev_es_wr_ghcb_msr(u64 val) { u32 low, high; -- GitLab From 0afda3a888dccf12557b41ef42eee942327d122b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 6 Jan 2021 15:36:22 +0100 Subject: [PATCH 0177/1084] locking/lockdep: Cure noinstr fail When the compiler doesn't feel like inlining, it causes a noinstr fail: vmlinux.o: warning: objtool: lock_is_held_type()+0xb: call to lockdep_enabled() leaves .noinstr.text section Fixes: 4d004099a668 ("lockdep: Fix lockdep recursion") Reported-by: Randy Dunlap Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210106144017.592595176@infradead.org --- kernel/locking/lockdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index c1418b47f625a..02bc5b8f1eb27 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -79,7 +79,7 @@ module_param(lock_stat, int, 0644); DEFINE_PER_CPU(unsigned int, lockdep_recursion); EXPORT_PER_CPU_SYMBOL_GPL(lockdep_recursion); -static inline bool lockdep_enabled(void) +static __always_inline bool lockdep_enabled(void) { if (!debug_locks) return false; -- GitLab From 77ca93a6b1223e210e58e1000c09d8d420403c94 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 6 Jan 2021 15:36:23 +0100 Subject: [PATCH 0178/1084] locking/lockdep: Avoid noinstr warning for DEBUG_LOCKDEP vmlinux.o: warning: objtool: lock_is_held_type()+0x60: call to check_flags.part.0() leaves .noinstr.text section Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210106144017.652218215@infradead.org --- kernel/locking/lockdep.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 02bc5b8f1eb27..bdaf4829098c0 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -5271,12 +5271,15 @@ static void __lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie cookie /* * Check whether we follow the irq-flags state precisely: */ -static void check_flags(unsigned long flags) +static noinstr void check_flags(unsigned long flags) { #if defined(CONFIG_PROVE_LOCKING) && defined(CONFIG_DEBUG_LOCKDEP) if (!debug_locks) return; + /* Get the warning out.. */ + instrumentation_begin(); + if (irqs_disabled_flags(flags)) { if (DEBUG_LOCKS_WARN_ON(lockdep_hardirqs_enabled())) { printk("possible reason: unannotated irqs-off.\n"); @@ -5304,6 +5307,8 @@ static void check_flags(unsigned long flags) if (!debug_locks) print_irqtrace_events(current); + + instrumentation_end(); #endif } -- GitLab From 737495361d4469477ffe45d51e6fc56f44f3cc6a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 6 Jan 2021 15:36:24 +0100 Subject: [PATCH 0179/1084] x86/mce: Remove explicit/superfluous tracing There's some explicit tracing left in exc_machine_check_kernel(), remove it, as it's already implied by irqentry_nmi_enter(). Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210106144017.719310466@infradead.org --- arch/x86/kernel/cpu/mce/core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 13d3f1cbda176..e133ce1e562b3 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -1992,10 +1992,9 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) * that out because it's an indirect call. Annotate it. */ instrumentation_begin(); - trace_hardirqs_off_finish(); + machine_check_vector(regs); - if (regs->flags & X86_EFLAGS_IF) - trace_hardirqs_on_prepare(); + instrumentation_end(); irqentry_nmi_exit(regs, irq_state); } @@ -2004,7 +2003,9 @@ static __always_inline void exc_machine_check_user(struct pt_regs *regs) { irqentry_enter_from_user_mode(regs); instrumentation_begin(); + machine_check_vector(regs); + instrumentation_end(); irqentry_exit_to_user_mode(regs); } -- GitLab From 66a425011c61e71560c234492d204e83cfb73d1d Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 7 Jan 2021 11:14:25 +0100 Subject: [PATCH 0180/1084] x86: __always_inline __{rd,wr}msr() When the compiler choses to not inline the trivial MSR helpers: vmlinux.o: warning: objtool: __sev_es_nmi_complete()+0xce: call to __wrmsr.constprop.14() leaves .noinstr.text section Reported-by: Randy Dunlap Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner Acked-by: Randy Dunlap # build-tested Link: https://lore.kernel.org/r/X/bf3gV+BW7kGEsB@hirez.programming.kicks-ass.net --- arch/x86/include/asm/msr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 0b4920a7238e3..e16cccdd04207 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -86,7 +86,7 @@ static inline void do_trace_rdpmc(unsigned int msr, u64 val, int failed) {} * think of extending them - you will be slapped with a stinking trout or a frozen * shark will reach you, wherever you are! You've been warned. */ -static inline unsigned long long notrace __rdmsr(unsigned int msr) +static __always_inline unsigned long long __rdmsr(unsigned int msr) { DECLARE_ARGS(val, low, high); @@ -98,7 +98,7 @@ static inline unsigned long long notrace __rdmsr(unsigned int msr) return EAX_EDX_VAL(val, low, high); } -static inline void notrace __wrmsr(unsigned int msr, u32 low, u32 high) +static __always_inline void __wrmsr(unsigned int msr, u32 low, u32 high) { asm volatile("1: wrmsr\n" "2:\n" -- GitLab From bcc5e6162d66d44f7929f30fce032f95855fc8b4 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 9 Jan 2021 23:03:40 -0800 Subject: [PATCH 0181/1084] bpf: Allow empty module BTFs Some modules don't declare any new types and end up with an empty BTF, containing only valid BTF header and no types or strings sections. This currently causes BTF validation error. There is nothing wrong with such BTF, so fix the issue by allowing module BTFs with no types or strings. Fixes: 36e68442d1af ("bpf: Load and verify kernel module BTFs") Reported-by: Christopher William Snowhill Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20210110070341.1380086-1-andrii@kernel.org --- kernel/bpf/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 8d6bdb4f4d618..84a36ee4a4c20 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -4172,7 +4172,7 @@ static int btf_parse_hdr(struct btf_verifier_env *env) return -ENOTSUPP; } - if (btf_data_size == hdr->hdr_len) { + if (!btf->base_btf && btf_data_size == hdr->hdr_len) { btf_verifier_log(env, "No data"); return -EINVAL; } -- GitLab From b8d52264df85ec12f370c0a8b28d0ac59a05877a Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 9 Jan 2021 23:03:41 -0800 Subject: [PATCH 0182/1084] libbpf: Allow loading empty BTFs Empty BTFs do come up (e.g., simple kernel modules with no new types and strings, compared to the vmlinux BTF) and there is nothing technically wrong with them. So remove unnecessary check preventing loading empty BTFs. Fixes: d8123624506c ("libbpf: Fix BTF data layout checks and allow empty BTF") Reported-by: Christopher William Snowhill Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20210110070341.1380086-2-andrii@kernel.org --- tools/lib/bpf/btf.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 3c3f2bc6c6528..9970a288dda53 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -240,11 +240,6 @@ static int btf_parse_hdr(struct btf *btf) } meta_left = btf->raw_size - sizeof(*hdr); - if (!meta_left) { - pr_debug("BTF has no data\n"); - return -EINVAL; - } - if (meta_left < hdr->str_off + hdr->str_len) { pr_debug("Invalid BTF total size:%u\n", btf->raw_size); return -EINVAL; -- GitLab From aba428a0c612bb259891307da12e22efd0fab14c Mon Sep 17 00:00:00 2001 From: Chunguang Xu Date: Tue, 1 Dec 2020 17:52:31 +0800 Subject: [PATCH 0183/1084] timekeeping: Remove unused get_seconds() The get_seconds() cleanup seems to have been completed, now it is time to delete the legacy interface to avoid misuse later. Signed-off-by: Chunguang Xu Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/1606816351-26900-1-git-send-email-brookxu@tencent.com --- include/linux/ktime.h | 1 - include/linux/timekeeping32.h | 14 -------------- kernel/time/timekeeping.c | 3 +-- 3 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 include/linux/timekeeping32.h diff --git a/include/linux/ktime.h b/include/linux/ktime.h index a12b5523cc18e..73f20deb497d5 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -230,6 +230,5 @@ static inline ktime_t ms_to_ktime(u64 ms) } # include -# include #endif diff --git a/include/linux/timekeeping32.h b/include/linux/timekeeping32.h deleted file mode 100644 index 266017fc9ee9c..0000000000000 --- a/include/linux/timekeeping32.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _LINUX_TIMEKEEPING32_H -#define _LINUX_TIMEKEEPING32_H -/* - * These interfaces are all based on the old timespec type - * and should get replaced with the timespec64 based versions - * over time so we can remove the file here. - */ - -static inline unsigned long get_seconds(void) -{ - return ktime_get_real_seconds(); -} - -#endif diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index a45cedda93a7c..6aee5768c86ff 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -991,8 +991,7 @@ EXPORT_SYMBOL_GPL(ktime_get_seconds); /** * ktime_get_real_seconds - Get the seconds portion of CLOCK_REALTIME * - * Returns the wall clock seconds since 1970. This replaces the - * get_seconds() interface which is not y2038 safe on 32bit systems. + * Returns the wall clock seconds since 1970. * * For 64bit systems the fast access to tk->xtime_sec is preserved. On * 32bit systems the access must be protected with the sequence -- GitLab From e3fab2f3de081e98c50b7b4ace1b040161d95310 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 11 Jan 2021 11:39:56 +0100 Subject: [PATCH 0184/1084] ntp: Fix RTC synchronization on 32-bit platforms Due to an integer overflow, RTC synchronization now happens every 2s instead of the intended 11 minutes. Fix this by forcing 64-bit arithmetic for the sync period calculation. Annotate the other place which multiplies seconds for consistency as well. Fixes: c9e6189fb03123a7 ("ntp: Make the RTC synchronization more reliable") Signed-off-by: Geert Uytterhoeven Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210111103956.290378-1-geert+renesas@glider.be --- kernel/time/ntp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 7404d38315276..87389b9e21aba 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -498,7 +498,7 @@ int second_overflow(time64_t secs) static void sync_hw_clock(struct work_struct *work); static DECLARE_WORK(sync_work, sync_hw_clock); static struct hrtimer sync_hrtimer; -#define SYNC_PERIOD_NS (11UL * 60 * NSEC_PER_SEC) +#define SYNC_PERIOD_NS (11ULL * 60 * NSEC_PER_SEC) static enum hrtimer_restart sync_timer_callback(struct hrtimer *timer) { @@ -512,7 +512,7 @@ static void sched_sync_hw_clock(unsigned long offset_nsec, bool retry) ktime_t exp = ktime_set(ktime_get_real_seconds(), 0); if (retry) - exp = ktime_add_ns(exp, 2 * NSEC_PER_SEC - offset_nsec); + exp = ktime_add_ns(exp, 2ULL * NSEC_PER_SEC - offset_nsec); else exp = ktime_add_ns(exp, SYNC_PERIOD_NS - offset_nsec); -- GitLab From f2cb4b2397ca9e6e972d6551e5461d1f1d81c23f Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Mon, 11 Jan 2021 11:22:12 +0100 Subject: [PATCH 0185/1084] scsi: docs: ABI: sysfs-driver-ufs: Rectify table formatting Commit 0b2894cd0fdf ("scsi: docs: ABI: sysfs-driver-ufs: Add DeepSleep power mode") adds new entries in tables of sysfs-driver-ufs ABI documentation, but formatted the table incorrectly. Hence, make htmldocs warns: ./Documentation/ABI/testing/sysfs-driver-ufs:{915,956}: WARNING: Malformed table. Text in column margin in table line 15. Rectify table formatting for DeepSleep power mode. Link: https://lore.kernel.org/r/20210111102212.19377-1-lukas.bulwahn@gmail.com Acked-by: Adrian Hunter Signed-off-by: Lukas Bulwahn Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index e77fa784d6d81..75ccc5c62b3c4 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -932,8 +932,9 @@ Description: This entry could be used to set or show the UFS device 5 UFS device will be powered off, UIC link will be powered off 6 UFS device will be moved to deep sleep, UIC link - will be powered off. Note, deep sleep might not be - supported in which case this value will not be accepted + will be powered off. Note, deep sleep might not be + supported in which case this value will not be + accepted == ==================================================== What: /sys/bus/platform/drivers/ufshcd/*/rpm_target_dev_state @@ -973,8 +974,9 @@ Description: This entry could be used to set or show the UFS device 5 UFS device will be powered off, UIC link will be powered off 6 UFS device will be moved to deep sleep, UIC link - will be powered off. Note, deep sleep might not be - supported in which case this value will not be accepted + will be powered off. Note, deep sleep might not be + supported in which case this value will not be + accepted == ==================================================== What: /sys/bus/platform/drivers/ufshcd/*/spm_target_dev_state -- GitLab From 72eeb7c7151302ef007f1acd018cbf6f30e50321 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Mon, 11 Jan 2021 15:25:41 +0100 Subject: [PATCH 0186/1084] scsi: scsi_transport_srp: Don't block target in failfast state If the port is in SRP_RPORT_FAIL_FAST state when srp_reconnect_rport() is entered, a transition to SDEV_BLOCK would be illegal, and a kernel WARNING would be triggered. Skip scsi_target_block() in this case. Link: https://lore.kernel.org/r/20210111142541.21534-1-mwilck@suse.com Reviewed-by: Bart Van Assche Signed-off-by: Martin Wilck Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_transport_srp.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index cba1cf6a1c12d..1e939a2a387f3 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -541,7 +541,14 @@ int srp_reconnect_rport(struct srp_rport *rport) res = mutex_lock_interruptible(&rport->mutex); if (res) goto out; - scsi_target_block(&shost->shost_gendev); + if (rport->state != SRP_RPORT_FAIL_FAST) + /* + * sdev state must be SDEV_TRANSPORT_OFFLINE, transition + * to SDEV_BLOCK is illegal. Calling scsi_target_unblock() + * later is ok though, scsi_internal_device_unblock_nowait() + * treats SDEV_TRANSPORT_OFFLINE like SDEV_BLOCK. + */ + scsi_target_block(&shost->shost_gendev); res = rport->state != SRP_RPORT_LOST ? i->f->reconnect(rport) : -ENODEV; pr_debug("%s (state %d): transport.reconnect() returned %d\n", dev_name(&shost->shost_gendev), rport->state, res); -- GitLab From b2b0f16fa65e910a3ec8771206bb49ee87a54ac5 Mon Sep 17 00:00:00 2001 From: Javed Hasan Date: Tue, 15 Dec 2020 11:47:31 -0800 Subject: [PATCH 0187/1084] scsi: libfc: Avoid invoking response handler twice if ep is already completed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A race condition exists between the response handler getting called because of exchange_mgr_reset() (which clears out all the active XIDs) and the response we get via an interrupt. Sequence of events: rport ba0200: Port timeout, state PLOGI rport ba0200: Port entered PLOGI state from PLOGI state xid 1052: Exchange timer armed : 20000 msecs  xid timer armed here rport ba0200: Received LOGO request while in state PLOGI rport ba0200: Delete port rport ba0200: work event 3 rport ba0200: lld callback ev 3 bnx2fc: rport_event_hdlr: event = 3, port_id = 0xba0200 bnx2fc: ba0200 - rport not created Yet!! /* Here we reset any outstanding exchanges before freeing rport using the exch_mgr_reset() */ xid 1052: Exchange timer canceled /* Here we got two responses for one xid */ xid 1052: invoking resp(), esb 20000000 state 3 xid 1052: invoking resp(), esb 20000000 state 3 xid 1052: fc_rport_plogi_resp() : ep->resp_active 2 xid 1052: fc_rport_plogi_resp() : ep->resp_active 2 Skip the response if the exchange is already completed. Link: https://lore.kernel.org/r/20201215194731.2326-1-jhasan@marvell.com Signed-off-by: Javed Hasan Signed-off-by: Martin K. Petersen --- drivers/scsi/libfc/fc_exch.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index d71afae6191cb..841000445b9a1 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -1623,8 +1623,13 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) rc = fc_exch_done_locked(ep); WARN_ON(fc_seq_exch(sp) != ep); spin_unlock_bh(&ep->ex_lock); - if (!rc) + if (!rc) { fc_exch_delete(ep); + } else { + FC_EXCH_DBG(ep, "ep is completed already," + "hence skip calling the resp\n"); + goto skip_resp; + } } /* @@ -1643,6 +1648,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) if (!fc_invoke_resp(ep, sp, fp)) fc_frame_free(fp); +skip_resp: fc_exch_release(ep); return; rel: @@ -1899,10 +1905,16 @@ static void fc_exch_reset(struct fc_exch *ep) fc_exch_hold(ep); - if (!rc) + if (!rc) { fc_exch_delete(ep); + } else { + FC_EXCH_DBG(ep, "ep is completed already," + "hence skip calling the resp\n"); + goto skip_resp; + } fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_CLOSED)); +skip_resp: fc_seq_set_resp(sp, NULL, ep->arg); fc_exch_release(ep); } -- GitLab From d6e3ae76728ccde49271d9f5acfebbea0c5625a3 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Fri, 25 Dec 2020 16:35:20 +0800 Subject: [PATCH 0188/1084] scsi: fnic: Fix memleak in vnic_dev_init_devcmd2 When ioread32() returns 0xFFFFFFFF, we should execute cleanup functions like other error handling paths before returning. Link: https://lore.kernel.org/r/20201225083520.22015-1-dinghao.liu@zju.edu.cn Acked-by: Karan Tilak Kumar Signed-off-by: Dinghao Liu Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/vnic_dev.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/fnic/vnic_dev.c b/drivers/scsi/fnic/vnic_dev.c index a2beee6e09f06..5988c300cc82e 100644 --- a/drivers/scsi/fnic/vnic_dev.c +++ b/drivers/scsi/fnic/vnic_dev.c @@ -444,7 +444,8 @@ static int vnic_dev_init_devcmd2(struct vnic_dev *vdev) fetch_index = ioread32(&vdev->devcmd2->wq.ctrl->fetch_index); if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */ pr_err("error in devcmd2 init"); - return -ENODEV; + err = -ENODEV; + goto err_free_wq; } /* @@ -460,7 +461,7 @@ static int vnic_dev_init_devcmd2(struct vnic_dev *vdev) err = vnic_dev_alloc_desc_ring(vdev, &vdev->devcmd2->results_ring, DEVCMD2_RING_SIZE, DEVCMD2_DESC_SIZE); if (err) - goto err_free_wq; + goto err_disable_wq; vdev->devcmd2->result = (struct devcmd2_result *) vdev->devcmd2->results_ring.descs; @@ -481,8 +482,9 @@ static int vnic_dev_init_devcmd2(struct vnic_dev *vdev) err_free_desc_ring: vnic_dev_free_desc_ring(vdev, &vdev->devcmd2->results_ring); -err_free_wq: +err_disable_wq: vnic_wq_disable(&vdev->devcmd2->wq); +err_free_wq: vnic_wq_free(&vdev->devcmd2->wq); err_free_devcmd2: kfree(vdev->devcmd2); -- GitLab From 93f2a11580a9732c1d90f9e01a7e9facc825658f Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 21 Dec 2020 16:11:03 -0800 Subject: [PATCH 0189/1084] arm64: dts: qcom: sdm845: Reserve LPASS clocks in gcc The GCC_LPASS_Q6_AXI_CLK and GCC_LPASS_SWAY_CLK clocks may not be touched on a typical UEFI based SDM845 device, but when the kernel is built with CONFIG_SDM_LPASSCC_845 this happens, unless they are marked as protected-clocks in the DT. This was done for the MTP and the Pocophone, but not for DB845c and the Lenovo Yoga C630 - causing these to fail to boot if the LPASS clock controller is enabled (which it typically isn't). Tested-by: Vinod Koul #on db845c Reviewed-by: Vinod Koul Link: https://lore.kernel.org/r/20201222001103.3112306-1-bjorn.andersson@linaro.org Signed-off-by: Bjorn Andersson --- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 4 +++- arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index 7cc236575ee20..c0b93813ea9ac 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -415,7 +415,9 @@ &gcc { protected-clocks = , , - ; + , + , + ; }; &gpu { diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts index 3be85161a54e3..8b40f96e97802 100644 --- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts @@ -302,7 +302,9 @@ &gcc { protected-clocks = , , - ; + , + , + ; }; &gpu { -- GitLab From 43377df70480f82919032eb09832e9646a8a5efb Mon Sep 17 00:00:00 2001 From: Chenxin Jin Date: Wed, 13 Jan 2021 16:59:05 +0800 Subject: [PATCH 0190/1084] USB: serial: cp210x: add new VID/PID for supporting Teraoka AD2000 Teraoka AD2000 uses the CP210x driver, but the chip VID/PID is customized with 0988/0578. We need the driver to support the new VID/PID. Signed-off-by: Chenxin Jin Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index fbb10dfc56e31..06f3cfc9f19aa 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -61,6 +61,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ { USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console */ + { USB_DEVICE(0x0988, 0x0578) }, /* Teraoka AD2000 */ { USB_DEVICE(0x0B00, 0x3070) }, /* Ingenico 3070 */ { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */ { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */ -- GitLab From f419e5940f1d9892ea6f45acdaca572b9e73ff39 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Thu, 7 Jan 2021 22:44:38 +0800 Subject: [PATCH 0191/1084] platform/x86: ideapad-laptop: Disable touchpad_switch for ELAN0634 Newer ideapads (e.g.: Yoga 14s, 720S 14) come with ELAN0634 touchpad do not use EC to switch touchpad. Reading VPCCMD_R_TOUCHPAD will return zero thus touchpad may be blocked unexpectedly. Writing VPCCMD_W_TOUCHPAD may cause a spurious key press. Add has_touchpad_switch to workaround these machines. Signed-off-by: Jiaxun Yang Cc: stable@vger.kernel.org # 5.4+ -- v2: Specify touchpad to ELAN0634 v3: Stupid missing ! in v2 v4: Correct acpi_dev_present usage (Hans) Link: https://lore.kernel.org/r/20210107144438.12605-1-jiaxun.yang@flygoat.com Signed-off-by: Hans de Goede --- drivers/platform/x86/ideapad-laptop.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 7598cd46cf606..5b81bafa5c165 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -92,6 +92,7 @@ struct ideapad_private { struct dentry *debug; unsigned long cfg; bool has_hw_rfkill_switch; + bool has_touchpad_switch; const char *fnesc_guid; }; @@ -535,7 +536,9 @@ static umode_t ideapad_is_visible(struct kobject *kobj, } else if (attr == &dev_attr_fn_lock.attr) { supported = acpi_has_method(priv->adev->handle, "HALS") && acpi_has_method(priv->adev->handle, "SALS"); - } else + } else if (attr == &dev_attr_touchpad.attr) + supported = priv->has_touchpad_switch; + else supported = true; return supported ? attr->mode : 0; @@ -867,6 +870,9 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv) { unsigned long value; + if (!priv->has_touchpad_switch) + return; + /* Without reading from EC touchpad LED doesn't switch state */ if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { /* Some IdeaPads don't really turn off touchpad - they only @@ -989,6 +995,9 @@ static int ideapad_acpi_add(struct platform_device *pdev) priv->platform_device = pdev; priv->has_hw_rfkill_switch = dmi_check_system(hw_rfkill_list); + /* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */ + priv->has_touchpad_switch = !acpi_dev_present("ELAN0634", NULL, -1); + ret = ideapad_sysfs_init(priv); if (ret) return ret; @@ -1006,6 +1015,10 @@ static int ideapad_acpi_add(struct platform_device *pdev) if (!priv->has_hw_rfkill_switch) write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1); + /* The same for Touchpad */ + if (!priv->has_touchpad_switch) + write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, 1); + for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) ideapad_register_rfkill(priv, i); -- GitLab From 5b191dcba719319148eeecf6ed409949fac55b39 Mon Sep 17 00:00:00 2001 From: Al Cooper Date: Thu, 7 Jan 2021 17:15:09 -0500 Subject: [PATCH 0192/1084] mmc: sdhci-brcmstb: Fix mmc timeout errors on S5 suspend Commit e7b5d63a82fe ("mmc: sdhci-brcmstb: Add shutdown callback") that added a shutdown callback to the diver, is causing "mmc timeout" errors on S5 suspend. The problem was that the "remove" was queuing additional MMC commands after the "shutdown" and these caused timeouts as the MMC queues were cleaned up for "remove". The shutdown callback will be changed to calling sdhci-pltfm_suspend which should get better power savings because the clocks will be shutdown. Fixes: e7b5d63a82fe ("mmc: sdhci-brcmstb: Add shutdown callback") Signed-off-by: Al Cooper Acked-by: Florian Fainelli Acked-by: Adrian Hunter Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210107221509.6597-1-alcooperx@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-brcmstb.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c index bbf3496f44955..f9780c65ebe98 100644 --- a/drivers/mmc/host/sdhci-brcmstb.c +++ b/drivers/mmc/host/sdhci-brcmstb.c @@ -314,11 +314,7 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) static void sdhci_brcmstb_shutdown(struct platform_device *pdev) { - int ret; - - ret = sdhci_pltfm_unregister(pdev); - if (ret) - dev_err(&pdev->dev, "failed to shutdown\n"); + sdhci_pltfm_suspend(&pdev->dev); } MODULE_DEVICE_TABLE(of, sdhci_brcm_of_match); -- GitLab From 9c6d7f9346b1526136dc142eb82085737112a3fe Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2020 14:55:16 +0900 Subject: [PATCH 0193/1084] ASoC: soc-pcm: move dpcm_set_fe_update_state() This patch moves dpcm_set_fe_update_state() to top side. This is prepare for cleanup soc-pcm.c Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/871rfw99jn.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index a253c9f918e1e..1cc8d0b6ec3d3 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -203,6 +203,28 @@ static inline void dpcm_remove_debugfs_state(struct snd_soc_dpcm *dpcm) } #endif +/* Set FE's runtime_update state; the state is protected via PCM stream lock + * for avoiding the race with trigger callback. + * If the state is unset and a trigger is pending while the previous operation, + * process the pending trigger action here. + */ +static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); +static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe, + int stream, enum snd_soc_dpcm_update state) +{ + struct snd_pcm_substream *substream = + snd_soc_dpcm_get_substream(fe, stream); + + snd_pcm_stream_lock_irq(substream); + if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) { + dpcm_fe_dai_do_trigger(substream, + fe->dpcm[stream].trigger_pending - 1); + fe->dpcm[stream].trigger_pending = 0; + } + fe->dpcm[stream].runtime_update = state; + snd_pcm_stream_unlock_irq(substream); +} + /** * snd_soc_runtime_action() - Increment/Decrement active count for * PCM runtime components @@ -1710,29 +1732,6 @@ static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) &runtime->hw.rate_min, &runtime->hw.rate_max); } -static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); - -/* Set FE's runtime_update state; the state is protected via PCM stream lock - * for avoiding the race with trigger callback. - * If the state is unset and a trigger is pending while the previous operation, - * process the pending trigger action here. - */ -static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe, - int stream, enum snd_soc_dpcm_update state) -{ - struct snd_pcm_substream *substream = - snd_soc_dpcm_get_substream(fe, stream); - - snd_pcm_stream_lock_irq(substream); - if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) { - dpcm_fe_dai_do_trigger(substream, - fe->dpcm[stream].trigger_pending - 1); - fe->dpcm[stream].trigger_pending = 0; - } - fe->dpcm[stream].runtime_update = state; - snd_pcm_stream_unlock_irq(substream); -} - static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream, int stream) { -- GitLab From a7e20444ef5e7ab74aec34f34eb0e53024c349e1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2020 14:55:22 +0900 Subject: [PATCH 0194/1084] ASoC: soc-pcm: add dpcm_set_be_update_state() soc-pcm has dpcm_set_fe_update_state() to update FE's runtime_update (except dpcm_fe_dai_do_trigger() which needs to update it without it). OTOH, it doesn't have BE's update function. O: dpcm_set_fe_update_state() X: dpcm_set_be_update_state() This patch add BE's dpcm_set_fe_update_state() Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87zh2k7uz1.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 1cc8d0b6ec3d3..54b460f083730 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -225,6 +225,12 @@ static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe, snd_pcm_stream_unlock_irq(substream); } +static void dpcm_set_be_update_state(struct snd_soc_pcm_runtime *be, + int stream, enum snd_soc_dpcm_update state) +{ + be->dpcm[stream].runtime_update = state; +} + /** * snd_soc_runtime_action() - Increment/Decrement active count for * PCM runtime components @@ -1357,7 +1363,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, stream ? "capture" : "playback", dpcm->be->dai_link->name, fe->dai_link->name); dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; - dpcm->be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; + dpcm_set_be_update_state(dpcm->be, stream, SND_SOC_DPCM_UPDATE_BE); prune++; } @@ -1412,7 +1418,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, continue; /* new */ - be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; + dpcm_set_be_update_state(be, stream, SND_SOC_DPCM_UPDATE_BE); new++; } @@ -1440,8 +1446,7 @@ void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_be(fe, stream, dpcm) - dpcm->be->dpcm[stream].runtime_update = - SND_SOC_DPCM_UPDATE_NO; + dpcm_set_be_update_state(dpcm->be, stream, SND_SOC_DPCM_UPDATE_NO); spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); } -- GitLab From 2805b8bd3e0bdda15b3458ab9818d80f5d5b157f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2020 14:55:27 +0900 Subject: [PATCH 0195/1084] ASoC: soc-pcm: add soc_pcm_set_dai_params() Getting rate/channels/sample_bits from param needs fixed method. This patch adds new soc_pcm_set_dai_params() and replace existing code. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87y2i47uyw.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 52 +++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 54b460f083730..6e9f14d482abe 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -329,6 +329,20 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, return 0; } +static void soc_pcm_set_dai_params(struct snd_soc_dai *dai, + struct snd_pcm_hw_params *params) +{ + if (params) { + dai->rate = params_rate(params); + dai->channels = params_channels(params); + dai->sample_bits = snd_pcm_format_physical_width(params_format(params)); + } else { + dai->rate = 0; + dai->channels = 0; + dai->sample_bits = 0; + } +} + static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, struct snd_soc_dai *soc_dai) { @@ -390,13 +404,12 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_dai d; struct snd_soc_dai *dai; struct snd_soc_dai *cpu_dai; - unsigned int rate, channels, sample_bits, symmetry, i; + unsigned int symmetry, i; - rate = params_rate(params); - channels = params_channels(params); - sample_bits = snd_pcm_format_physical_width(params_format(params)); + soc_pcm_set_dai_params(&d, params); /* reject unmatched parameters when applying symmetry */ symmetry = rtd->dai_link->symmetric_rates; @@ -406,9 +419,9 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, if (symmetry) { for_each_rtd_cpu_dais(rtd, i, cpu_dai) { - if (cpu_dai->rate && cpu_dai->rate != rate) { + if (cpu_dai->rate && cpu_dai->rate != d.rate) { dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n", - cpu_dai->rate, rate); + cpu_dai->rate, d.rate); return -EINVAL; } } @@ -422,9 +435,9 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, if (symmetry) { for_each_rtd_cpu_dais(rtd, i, cpu_dai) { if (cpu_dai->channels && - cpu_dai->channels != channels) { + cpu_dai->channels != d.channels) { dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n", - cpu_dai->channels, channels); + cpu_dai->channels, d.channels); return -EINVAL; } } @@ -438,9 +451,9 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, if (symmetry) { for_each_rtd_cpu_dais(rtd, i, cpu_dai) { if (cpu_dai->sample_bits && - cpu_dai->sample_bits != sample_bits) { + cpu_dai->sample_bits != d.sample_bits) { dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n", - cpu_dai->sample_bits, sample_bits); + cpu_dai->sample_bits, d.sample_bits); return -EINVAL; } } @@ -898,11 +911,8 @@ static int soc_pcm_hw_clean(struct snd_pcm_substream *substream, int rollback) for_each_rtd_dais(rtd, i, dai) { int active = snd_soc_dai_stream_active(dai, substream->stream); - if (snd_soc_dai_active(dai) == 1) { - dai->rate = 0; - dai->channels = 0; - dai->sample_bits = 0; - } + if (snd_soc_dai_active(dai) == 1) + soc_pcm_set_dai_params(dai, NULL); if (active == 1) snd_soc_dai_digital_mute(dai, 1, substream->stream); @@ -999,11 +1009,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, if(ret < 0) goto out; - codec_dai->rate = params_rate(&codec_params); - codec_dai->channels = params_channels(&codec_params); - codec_dai->sample_bits = snd_pcm_format_physical_width( - params_format(&codec_params)); - + soc_pcm_set_dai_params(codec_dai, &codec_params); snd_soc_dapm_update_dai(substream, &codec_params, codec_dai); } @@ -1020,11 +1026,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, goto out; /* store the parameters for each DAI */ - cpu_dai->rate = params_rate(params); - cpu_dai->channels = params_channels(params); - cpu_dai->sample_bits = - snd_pcm_format_physical_width(params_format(params)); - + soc_pcm_set_dai_params(cpu_dai, params); snd_soc_dapm_update_dai(substream, params, cpu_dai); } -- GitLab From a39748d03cbc7c0a55d217731c7e16a22a2d2bed Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2020 14:55:33 +0900 Subject: [PATCH 0196/1084] ASoC: soc-pcm: cleanup soc_pcm_apply_symmetry() soc_pcm_apply_symmetry() want to call snd_pcm_hw_constraint_single() for rate/channel/sample_bits, but, it needs many condition check. These are very similar but different, thus, it needs to have very verbose code. This patch use macro for it and make code more simple. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87wnxo7uyq.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 67 ++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 47 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 6e9f14d482abe..f62136f16c2f9 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -349,53 +349,26 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); int ret; - if (soc_dai->rate && (soc_dai->driver->symmetric_rates || - rtd->dai_link->symmetric_rates)) { - dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", - soc_dai->rate); - - ret = snd_pcm_hw_constraint_single(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - soc_dai->rate); - if (ret < 0) { - dev_err(soc_dai->dev, - "ASoC: Unable to apply rate constraint: %d\n", - ret); - return ret; - } - } - - if (soc_dai->channels && (soc_dai->driver->symmetric_channels || - rtd->dai_link->symmetric_channels)) { - dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n", - soc_dai->channels); - - ret = snd_pcm_hw_constraint_single(substream->runtime, - SNDRV_PCM_HW_PARAM_CHANNELS, - soc_dai->channels); - if (ret < 0) { - dev_err(soc_dai->dev, - "ASoC: Unable to apply channel symmetry constraint: %d\n", - ret); - return ret; - } - } - - if (soc_dai->sample_bits && (soc_dai->driver->symmetric_samplebits || - rtd->dai_link->symmetric_samplebits)) { - dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n", - soc_dai->sample_bits); - - ret = snd_pcm_hw_constraint_single(substream->runtime, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - soc_dai->sample_bits); - if (ret < 0) { - dev_err(soc_dai->dev, - "ASoC: Unable to apply sample bits symmetry constraint: %d\n", - ret); - return ret; - } - } +#define __soc_pcm_apply_symmetry(name, sname, NAME) \ + if (soc_dai->name && (soc_dai->driver->symmetric_##sname || \ + rtd->dai_link->symmetric_##sname)) { \ + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %s to %d\n",\ + #name, soc_dai->name); \ + \ + ret = snd_pcm_hw_constraint_single(substream->runtime, \ + SNDRV_PCM_HW_PARAM_##NAME,\ + soc_dai->name); \ + if (ret < 0) { \ + dev_err(soc_dai->dev, \ + "ASoC: Unable to apply %s constraint: %d\n",\ + #name, ret); \ + return ret; \ + } \ + } + + __soc_pcm_apply_symmetry(rate, rates, RATE); + __soc_pcm_apply_symmetry(channels, channels, CHANNELS); + __soc_pcm_apply_symmetry(sample_bits, samplebits, SAMPLE_BITS); return 0; } -- GitLab From 856fe64da84c95a1d415564b981ae3908eea2a76 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 11 Dec 2020 13:07:59 +0300 Subject: [PATCH 0197/1084] ASoC: cs42l56: fix up error handling in probe There are two issues with this code. The first error path forgot to set the error code and instead returns success. The second error path doesn't clean up. Fixes: 272b5edd3b8f ("ASoC: Add support for CS42L56 CODEC") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/X9NE/9nK9/TuxuL+@mwanda Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l56.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index bb9599cc832bc..c44a5cdb796ec 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -1250,6 +1250,7 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client, dev_err(&i2c_client->dev, "CS42L56 Device ID (%X). Expected %X\n", devid, CS42L56_DEVID); + ret = -EINVAL; goto err_enable; } alpha_rev = reg & CS42L56_AREV_MASK; @@ -1307,7 +1308,7 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client, ret = devm_snd_soc_register_component(&i2c_client->dev, &soc_component_dev_cs42l56, &cs42l56_dai, 1); if (ret < 0) - return ret; + goto err_enable; return 0; -- GitLab From 6fd8d2d275f74baa7ac17b2656da1235f56dab99 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Fri, 11 Dec 2020 21:32:55 +0100 Subject: [PATCH 0198/1084] ASoC: qcom: qdsp6: Move frontend AIFs to q6asm-dai At the moment it is necessary to set up the DAPM routes between front-end AIF<->DAI explicitly in the device tree, e.g. using audio-routing = "MM_DL1", "MultiMedia1 Playback", "MM_DL3", "MultiMedia3 Playback", "MM_DL4", "MultiMedia4 Playback", "MultiMedia2 Capture", "MM_UL2"; This is prone to mistakes and (sadly) there is no clear error if one of these routes is missing. :( Actually, this should not be necessary because the ASoC core normally automatically links AIF<->DAI within snd_soc_dapm_link_dai_widgets(). This is done using the "stname" parameter of SND_SOC_DAPM_AIF_IN/OUT. For SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), it should create the route from above: MM_DL1 <-> MultiMedia1 Playback. This does not work at the moment because the AIF widget (MM_DL1) and the DAI widget (MultiMedia1 Playback) belong to different DAPM contexts (q6routing / q6asm-dai). Fix this by declaring the AIF widgets in the same driver as the DAIs (q6asm-dai). Now the routes above are created automatically and no longer need to be specified in the device tree. This is also more consistent with the back-end AIFs which are already declared in q6afe-dais instead of q6routing. q6routing should only link the components together using mixers. Cc: Srinivas Kandagatla Fixes: 2a9e92d371db ("ASoC: qdsp6: q6asm: Add q6asm dai driver") Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20201211203255.148246-1-stephan@gerhold.net Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6asm-dai.c | 21 +++++++++++++++++++++ sound/soc/qcom/qdsp6/q6routing.c | 18 ------------------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index c9ac9c1d26c47..9766725c29166 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -1233,6 +1233,25 @@ static void q6asm_dai_pcm_free(struct snd_soc_component *component, } } +static const struct snd_soc_dapm_widget q6asm_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL7", "MultiMedia7 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, SND_SOC_NOPM, 0, 0), +}; + static const struct snd_soc_component_driver q6asm_fe_dai_component = { .name = DRV_NAME, .open = q6asm_dai_open, @@ -1245,6 +1264,8 @@ static const struct snd_soc_component_driver q6asm_fe_dai_component = { .pcm_construct = q6asm_dai_pcm_new, .pcm_destruct = q6asm_dai_pcm_free, .compress_ops = &q6asm_dai_compress_ops, + .dapm_widgets = q6asm_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(q6asm_dapm_widgets), }; static struct snd_soc_dai_driver q6asm_fe_dais_template[] = { diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c index 53185e26fea17..0a6b9433f6acf 100644 --- a/sound/soc/qcom/qdsp6/q6routing.c +++ b/sound/soc/qcom/qdsp6/q6routing.c @@ -713,24 +713,6 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA8) }; static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { - /* Frontend AIF */ - SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL7", "MultiMedia7 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), - /* Mixer definitions */ SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, hdmi_mixer_controls, -- GitLab From 22eee4d3efe370fedf71ee6a9e4dead3f32ad461 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 6 Jan 2021 14:36:48 +0100 Subject: [PATCH 0199/1084] ASoC: atmel-pdc: Use managed DMA buffer allocation Instead of manually managing its DMA buffers using dma_{alloc,free}_coherent() lets the sound core take care of this using managed buffers. On one hand this reduces the amount of boiler plate code, but the main motivation for the change is to use the shared code where possible. This makes it easier to argue about correctness and that the code does not contain subtle bugs like data leakage or similar. Signed-off-by: Lars-Peter Clausen Reviewed-by: Codrin Ciubotariu Link: https://lore.kernel.org/r/20210106133650.13509-1-lars@metafoo.de Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-pcm-pdc.c | 78 ++------------------------------- 1 file changed, 4 insertions(+), 74 deletions(-) diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c index 704f700013d3e..3e7ea2021b46b 100644 --- a/sound/soc/atmel/atmel-pcm-pdc.c +++ b/sound/soc/atmel/atmel-pcm-pdc.c @@ -34,86 +34,21 @@ #include "atmel-pcm.h" -static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, - int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = ATMEL_SSC_DMABUF_SIZE; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_coherent(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n", - (void *)buf->area, (void *)(long)buf->addr, size); - - if (!buf->area) - return -ENOMEM; - - buf->bytes = size; - return 0; -} - -static int atmel_pcm_mmap(struct snd_soc_component *component, - struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - return remap_pfn_range(vma, vma->vm_start, - substream->dma_buffer.addr >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot); -} - static int atmel_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; int ret; ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); if (ret) return ret; - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n"); - ret = atmel_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } + snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, + card->dev, ATMEL_SSC_DMABUF_SIZE, + ATMEL_SSC_DMABUF_SIZE); - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n"); - ret = atmel_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } - out: - return ret; -} - -static void atmel_pcm_free(struct snd_soc_component *component, - struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - dma_free_coherent(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; - } + return 0; } /*--------------------------------------------------------------------------*\ @@ -210,9 +145,6 @@ static int atmel_pcm_hw_params(struct snd_soc_component *component, /* this may get called several times by oss emulation * with different params */ - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - prtd->params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); prtd->params->dma_intr_handler = atmel_pcm_dma_irq; @@ -384,9 +316,7 @@ static const struct snd_soc_component_driver atmel_soc_platform = { .prepare = atmel_pcm_prepare, .trigger = atmel_pcm_trigger, .pointer = atmel_pcm_pointer, - .mmap = atmel_pcm_mmap, .pcm_construct = atmel_pcm_new, - .pcm_destruct = atmel_pcm_free, }; int atmel_pcm_pdc_platform_register(struct device *dev) -- GitLab From 5ac813c83483e97a13b59aab34b89cebf9d5dcb8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 6 Jan 2021 14:36:49 +0100 Subject: [PATCH 0200/1084] ASoC: bcm: cygnus: Use managed DMA buffer allocation Instead of manually managing its DMA buffers using dma_{alloc,free}_coherent() lets the sound core take care of this using managed buffers. On one hand this reduces the amount of boiler plate code, but the main motivation for the change is to use the shared code where possible. This makes it easier to argue about correctness and that the code does not contain subtle bugs like data leakage or similar. Signed-off-by: Lars-Peter Clausen Link: https://lore.kernel.org/r/20210106133650.13509-2-lars@metafoo.de Signed-off-by: Mark Brown --- sound/soc/bcm/cygnus-pcm.c | 107 ++----------------------------------- 1 file changed, 3 insertions(+), 104 deletions(-) diff --git a/sound/soc/bcm/cygnus-pcm.c b/sound/soc/bcm/cygnus-pcm.c index 7ad07239f99c4..56b71b9656249 100644 --- a/sound/soc/bcm/cygnus-pcm.c +++ b/sound/soc/bcm/cygnus-pcm.c @@ -636,36 +636,6 @@ static int cygnus_pcm_close(struct snd_soc_component *component, return 0; } -static int cygnus_pcm_hw_params(struct snd_soc_component *component, - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct cygnus_aio_port *aio; - - aio = cygnus_dai_get_dma_data(substream); - dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum); - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - - return 0; -} - -static int cygnus_pcm_hw_free(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct cygnus_aio_port *aio; - - aio = cygnus_dai_get_dma_data(substream); - dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum); - - snd_pcm_set_runtime_buffer(substream, NULL); - return 0; -} - static int cygnus_pcm_prepare(struct snd_soc_component *component, struct snd_pcm_substream *substream) { @@ -730,87 +700,19 @@ static snd_pcm_uframes_t cygnus_pcm_pointer(struct snd_soc_component *component, return bytes_to_frames(substream->runtime, res); } -static int cygnus_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size; - - size = cygnus_pcm_hw.buffer_bytes_max; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_coherent(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - - dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s: size 0x%zx @ %pK\n", - __func__, size, buf->area); - - if (!buf->area) { - dev_err(asoc_rtd_to_cpu(rtd, 0)->dev, "%s: dma_alloc failed\n", __func__); - return -ENOMEM; - } - buf->bytes = size; - - return 0; -} - -static void cygnus_dma_free_dma_buffers(struct snd_soc_component *component, - struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - - substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; - if (substream) { - buf = &substream->dma_buffer; - if (buf->area) { - dma_free_coherent(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; - } - } - - substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; - if (substream) { - buf = &substream->dma_buffer; - if (buf->area) { - dma_free_coherent(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; - } - } -} - static int cygnus_dma_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) { + size_t size = cygnus_pcm_hw.buffer_bytes_max; struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - int ret; if (!card->dev->dma_mask) card->dev->dma_mask = &cygnus_dma_dmamask; if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = cygnus_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - return ret; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = cygnus_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) { - cygnus_dma_free_dma_buffers(component, pcm); - return ret; - } - } + snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, + card->dev, size, size); return 0; } @@ -818,13 +720,10 @@ static int cygnus_dma_new(struct snd_soc_component *component, static struct snd_soc_component_driver cygnus_soc_platform = { .open = cygnus_pcm_open, .close = cygnus_pcm_close, - .hw_params = cygnus_pcm_hw_params, - .hw_free = cygnus_pcm_hw_free, .prepare = cygnus_pcm_prepare, .trigger = cygnus_pcm_trigger, .pointer = cygnus_pcm_pointer, .pcm_construct = cygnus_dma_new, - .pcm_destruct = cygnus_dma_free_dma_buffers, }; int cygnus_soc_platform_register(struct device *dev, -- GitLab From b3c0ae75f5d3efa40174230b8c9c01848e03d4d0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 6 Jan 2021 14:36:50 +0100 Subject: [PATCH 0201/1084] ASoC: kirkwood: Use managed DMA buffer allocation Instead of manually managing its DMA buffers using dma_{alloc,free}_coherent() lets the sound core take care of this using managed buffers. On one hand this reduces the amount of boiler plate code, but the main motivation for the change is to use the shared code where possible. This makes it easier to argue about correctness and that the code does not contain subtle bugs like data leakage or similar. Signed-off-by: Lars-Peter Clausen Link: https://lore.kernel.org/r/20210106133650.13509-3-lars@metafoo.de Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-dma.c | 79 ++----------------------------- 1 file changed, 3 insertions(+), 76 deletions(-) diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index e037826b24517..c2a5933bfcfc1 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -182,25 +182,6 @@ static int kirkwood_dma_close(struct snd_soc_component *component, return 0; } -static int kirkwood_dma_hw_params(struct snd_soc_component *component, - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - - return 0; -} - -static int kirkwood_dma_hw_free(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - snd_pcm_set_runtime_buffer(substream, NULL); - return 0; -} - static int kirkwood_dma_prepare(struct snd_soc_component *component, struct snd_pcm_substream *substream) { @@ -244,82 +225,28 @@ static snd_pcm_uframes_t kirkwood_dma_pointer( return count; } -static int kirkwood_dma_preallocate_dma_buffer(struct snd_pcm *pcm, - int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = kirkwood_dma_snd_hw.buffer_bytes_max; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->area = dma_alloc_coherent(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - if (!buf->area) - return -ENOMEM; - buf->bytes = size; - buf->private_data = NULL; - - return 0; -} - static int kirkwood_dma_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) { + size_t size = kirkwood_dma_snd_hw.buffer_bytes_max; struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; int ret; ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); if (ret) return ret; - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = kirkwood_dma_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - return ret; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = kirkwood_dma_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - return ret; - } + snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, + card->dev, size, size); return 0; } -static void kirkwood_dma_free_dma_buffers(struct snd_soc_component *component, - struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_coherent(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; - } -} - const struct snd_soc_component_driver kirkwood_soc_component = { .name = DRV_NAME, .open = kirkwood_dma_open, .close = kirkwood_dma_close, - .hw_params = kirkwood_dma_hw_params, - .hw_free = kirkwood_dma_hw_free, .prepare = kirkwood_dma_prepare, .pointer = kirkwood_dma_pointer, .pcm_construct = kirkwood_dma_new, - .pcm_destruct = kirkwood_dma_free_dma_buffers, }; -- GitLab From 5f39d2713bd80e8a3e6d9299930aec8844872c0e Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sun, 3 Jan 2021 14:39:27 -0500 Subject: [PATCH 0202/1084] SUNRPC: Move the svc_xdr_recvfrom tracepoint again Commit 156708adf2d9 ("SUNRPC: Move the svc_xdr_recvfrom() tracepoint") tried to capture the correct XID in the trace record, but this line in svc_recv: rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]); alters the size of rq_arg.head[0].iov_len. The tracepoint records the correct XID but an incorrect value for the length of the xdr_buf's head. To keep the trace callsites simple, I've created two trace classes. One assumes the xdr_buf contains a full RPC message, and the XID can be extracted from it. The other assumes the contents of the xdr_buf are arbitrary, and the xid will be provided by the caller. Currently there is only one user of each class, but I expect we will need a few more tracepoints using each class as time goes on. Signed-off-by: Chuck Lever --- include/trace/events/sunrpc.h | 59 +++++++++++++++++++++++++++++++---- net/sunrpc/svc_xprt.c | 4 +-- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 58994e0130221..6f89c27265f58 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -1424,13 +1424,61 @@ TRACE_EVENT(rpcb_unregister, ) ); +/* Record an xdr_buf containing a fully-formed RPC message */ +DECLARE_EVENT_CLASS(svc_xdr_msg_class, + TP_PROTO( + const struct xdr_buf *xdr + ), + + TP_ARGS(xdr), + + TP_STRUCT__entry( + __field(u32, xid) + __field(const void *, head_base) + __field(size_t, head_len) + __field(const void *, tail_base) + __field(size_t, tail_len) + __field(unsigned int, page_len) + __field(unsigned int, msg_len) + ), + + TP_fast_assign( + __be32 *p = (__be32 *)xdr->head[0].iov_base; + + __entry->xid = be32_to_cpu(*p); + __entry->head_base = p; + __entry->head_len = xdr->head[0].iov_len; + __entry->tail_base = xdr->tail[0].iov_base; + __entry->tail_len = xdr->tail[0].iov_len; + __entry->page_len = xdr->page_len; + __entry->msg_len = xdr->len; + ), + + TP_printk("xid=0x%08x head=[%p,%zu] page=%u tail=[%p,%zu] len=%u", + __entry->xid, + __entry->head_base, __entry->head_len, __entry->page_len, + __entry->tail_base, __entry->tail_len, __entry->msg_len + ) +); + +#define DEFINE_SVCXDRMSG_EVENT(name) \ + DEFINE_EVENT(svc_xdr_msg_class, \ + svc_xdr_##name, \ + TP_PROTO( \ + const struct xdr_buf *xdr \ + ), \ + TP_ARGS(xdr)) + +DEFINE_SVCXDRMSG_EVENT(recvfrom); + +/* Record an xdr_buf containing arbitrary data, tagged with an XID */ DECLARE_EVENT_CLASS(svc_xdr_buf_class, TP_PROTO( - const struct svc_rqst *rqst, + __be32 xid, const struct xdr_buf *xdr ), - TP_ARGS(rqst, xdr), + TP_ARGS(xid, xdr), TP_STRUCT__entry( __field(u32, xid) @@ -1443,7 +1491,7 @@ DECLARE_EVENT_CLASS(svc_xdr_buf_class, ), TP_fast_assign( - __entry->xid = be32_to_cpu(rqst->rq_xid); + __entry->xid = be32_to_cpu(xid); __entry->head_base = xdr->head[0].iov_base; __entry->head_len = xdr->head[0].iov_len; __entry->tail_base = xdr->tail[0].iov_base; @@ -1463,12 +1511,11 @@ DECLARE_EVENT_CLASS(svc_xdr_buf_class, DEFINE_EVENT(svc_xdr_buf_class, \ svc_xdr_##name, \ TP_PROTO( \ - const struct svc_rqst *rqst, \ + __be32 xid, \ const struct xdr_buf *xdr \ ), \ - TP_ARGS(rqst, xdr)) + TP_ARGS(xid, xdr)) -DEFINE_SVCXDRBUF_EVENT(recvfrom); DEFINE_SVCXDRBUF_EVENT(sendto); /* diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 5fb9164aa6905..dcc50ae545506 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -857,6 +857,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) err = -EAGAIN; if (len <= 0) goto out_release; + trace_svc_xdr_recvfrom(&rqstp->rq_arg); clear_bit(XPT_OLD, &xprt->xpt_flags); @@ -866,7 +867,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) if (serv->sv_stats) serv->sv_stats->netcnt++; - trace_svc_xdr_recvfrom(rqstp, &rqstp->rq_arg); return len; out_release: rqstp->rq_res.len = 0; @@ -904,7 +904,7 @@ int svc_send(struct svc_rqst *rqstp) xb->len = xb->head[0].iov_len + xb->page_len + xb->tail[0].iov_len; - trace_svc_xdr_sendto(rqstp, xb); + trace_svc_xdr_sendto(rqstp->rq_xid, xb); trace_svc_stats_latency(rqstp); len = xprt->xpt_ops->xpo_sendto(rqstp); -- GitLab From ce09ccc50208c04a1b03abfd530b5d6314258fd0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 13 Jan 2021 15:43:18 +0100 Subject: [PATCH 0203/1084] genirq: Export irq_check_status_bit() One of the users can be built modular: ERROR: modpost: "irq_check_status_bit" [drivers/perf/arm_spe_pmu.ko] undefined! Fixes: fdd029630434 ("genirq: Move status flag checks to core") Reported-by: Guenter Roeck Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20201227192049.GA195845@roeck-us.net --- kernel/irq/manage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index ab8567f32501f..dec3f73e8db92 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -2859,3 +2859,4 @@ bool irq_check_status_bit(unsigned int irq, unsigned int bitmask) rcu_read_unlock(); return res; } +EXPORT_SYMBOL_GPL(irq_check_status_bit); -- GitLab From 1e249cb5b7fc09ff216aa5a12f6c302e434e88f9 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 12 Jan 2021 11:02:43 -0800 Subject: [PATCH 0204/1084] fs: fix lazytime expiration handling in __writeback_single_inode() When lazytime is enabled and an inode is being written due to its in-memory updated timestamps having expired, either due to a sync() or syncfs() system call or due to dirtytime_expire_interval having elapsed, the VFS needs to inform the filesystem so that the filesystem can copy the inode's timestamps out to the on-disk data structures. This is done by __writeback_single_inode() calling mark_inode_dirty_sync(), which then calls ->dirty_inode(I_DIRTY_SYNC). However, this occurs after __writeback_single_inode() has already cleared the dirty flags from ->i_state. This causes two bugs: - mark_inode_dirty_sync() redirties the inode, causing it to remain dirty. This wastefully causes the inode to be written twice. But more importantly, it breaks cases where sync_filesystem() is expected to clean dirty inodes. This includes the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl (as reported at https://lore.kernel.org/r/20200306004555.GB225345@gmail.com), as well as possibly filesystem freezing (freeze_super()). - Since ->i_state doesn't contain I_DIRTY_TIME when ->dirty_inode() is called from __writeback_single_inode() for lazytime expiration, xfs_fs_dirty_inode() ignores the notification. (XFS only cares about lazytime expirations, and it assumes that i_state will contain I_DIRTY_TIME during those.) Therefore, lazy timestamps aren't persisted by sync(), syncfs(), or dirtytime_expire_interval on XFS. Fix this by moving the call to mark_inode_dirty_sync() to earlier in __writeback_single_inode(), before the dirty flags are cleared from i_state. This makes filesystems be properly notified of the timestamp expiration, and it avoids incorrectly redirtying the inode. This fixes xfstest generic/580 (which tests FS_IOC_REMOVE_ENCRYPTION_KEY) when run on ext4 or f2fs with lazytime enabled. It also fixes the new lazytime xfstest I've proposed, which reproduces the above-mentioned XFS bug (https://lore.kernel.org/r/20210105005818.92978-1-ebiggers@kernel.org). Alternatively, we could call ->dirty_inode(I_DIRTY_SYNC) directly. But due to the introduction of I_SYNC_QUEUED, mark_inode_dirty_sync() is the right thing to do because mark_inode_dirty_sync() now knows not to move the inode to a writeback list if it is currently queued for sync. Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option") Cc: stable@vger.kernel.org Depends-on: 5afced3bf281 ("writeback: Avoid skipping inode writeback") Link: https://lore.kernel.org/r/20210112190253.64307-2-ebiggers@kernel.org Suggested-by: Jan Kara Reviewed-by: Christoph Hellwig Reviewed-by: Jan Kara Signed-off-by: Eric Biggers Signed-off-by: Jan Kara --- fs/fs-writeback.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index acfb55834af23..c41cb887eb7d3 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1474,21 +1474,25 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) } /* - * Some filesystems may redirty the inode during the writeback - * due to delalloc, clear dirty metadata flags right before - * write_inode() + * If the inode has dirty timestamps and we need to write them, call + * mark_inode_dirty_sync() to notify the filesystem about it and to + * change I_DIRTY_TIME into I_DIRTY_SYNC. */ - spin_lock(&inode->i_lock); - - dirty = inode->i_state & I_DIRTY; if ((inode->i_state & I_DIRTY_TIME) && - ((dirty & I_DIRTY_INODE) || - wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync || + (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync || time_after(jiffies, inode->dirtied_time_when + dirtytime_expire_interval * HZ))) { - dirty |= I_DIRTY_TIME; trace_writeback_lazytime(inode); + mark_inode_dirty_sync(inode); } + + /* + * Some filesystems may redirty the inode during the writeback + * due to delalloc, clear dirty metadata flags right before + * write_inode() + */ + spin_lock(&inode->i_lock); + dirty = inode->i_state & I_DIRTY; inode->i_state &= ~dirty; /* @@ -1509,8 +1513,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) spin_unlock(&inode->i_lock); - if (dirty & I_DIRTY_TIME) - mark_inode_dirty_sync(inode); /* Don't write the inode if only I_DIRTY_PAGES was set */ if (dirty & ~I_DIRTY_PAGES) { int err = write_inode(inode, wbc); -- GitLab From 7edb3051f11683640c38b93e183ef1676090a79b Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 13 Jan 2021 17:26:14 +0200 Subject: [PATCH 0205/1084] ASoC: SOF: add .shutdown() callback to snd_sof_dsp_ops Add .shutdown() callback to the struct snd_sof_dsp_ops, for doing platform specific actions at shutdown. Signed-off-by: Keyon Jie Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210113152617.4048541-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ops.h | 8 ++++++++ sound/soc/sof/sof-priv.h | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 4c1f9daaa6e87..f0c9ca8820d2a 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -37,6 +37,14 @@ static inline int snd_sof_remove(struct snd_sof_dev *sdev) return 0; } +static inline int snd_sof_shutdown(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->shutdown) + return sof_ops(sdev)->shutdown(sdev); + + return 0; +} + /* control */ /* diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 28d19fa30614e..682c4b6d01efb 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -98,9 +98,10 @@ struct snd_sof_pdata; */ struct snd_sof_dsp_ops { - /* probe and remove */ + /* probe/remove/shutdown */ int (*probe)(struct snd_sof_dev *sof_dev); /* mandatory */ int (*remove)(struct snd_sof_dev *sof_dev); /* optional */ + int (*shutdown)(struct snd_sof_dev *sof_dev); /* optional */ /* DSP core boot / reset */ int (*run)(struct snd_sof_dev *sof_dev); /* mandatory */ @@ -462,6 +463,7 @@ struct snd_sof_dev { int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data); int snd_sof_device_remove(struct device *dev); +int snd_sof_device_shutdown(struct device *dev); int snd_sof_runtime_suspend(struct device *dev); int snd_sof_runtime_resume(struct device *dev); -- GitLab From daff7f1478e12cdee3e639c83c571cfd38bc5080 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 13 Jan 2021 17:26:15 +0200 Subject: [PATCH 0206/1084] ASoC: SOF: add snd_sof_device_shutdown() helper for shutdown Add helper snd_sof_device_shutdown() to wrap the platform specific .shutdown callbacks for SOF platforms. Signed-off-by: Keyon Jie Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210113152617.4048541-2-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 2b85ef5d6092a..8d13eb13fe081 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -385,6 +385,14 @@ int snd_sof_device_remove(struct device *dev) } EXPORT_SYMBOL(snd_sof_device_remove); +int snd_sof_device_shutdown(struct device *dev) +{ + struct snd_sof_dev *sdev = dev_get_drvdata(dev); + + return snd_sof_shutdown(sdev); +} +EXPORT_SYMBOL(snd_sof_device_shutdown); + MODULE_AUTHOR("Liam Girdwood"); MODULE_DESCRIPTION("Sound Open Firmware (SOF) Core"); MODULE_LICENSE("Dual BSD/GPL"); -- GitLab From 3475b44c7601d6f2b4d96e731047ef73fd2f1eb2 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 13 Jan 2021 17:26:16 +0200 Subject: [PATCH 0207/1084] ASoC: SOF: sof-pci-dev: add .shutdown() callback Add the .shutdown() callback to the sof-pci-dev driver, to help to handle shutting down specific tasks for SOF PCI platforms. Signed-off-by: Keyon Jie Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210113152617.4048541-3-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-pci-dev.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 63b989e3ec409..5f53c3e76e6fe 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -450,6 +450,11 @@ static void sof_pci_remove(struct pci_dev *pci) pci_release_regions(pci); } +static void sof_pci_shutdown(struct pci_dev *pci) +{ + snd_sof_device_shutdown(&pci->dev); +} + /* PCI IDs */ static const struct pci_device_id sof_pci_ids[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) @@ -523,6 +528,7 @@ static struct pci_driver snd_sof_pci_driver = { .id_table = sof_pci_ids, .probe = sof_pci_probe, .remove = sof_pci_remove, + .shutdown = sof_pci_shutdown, .driver = { .pm = &sof_pci_pm, }, -- GitLab From 44a4cfad8d78efcda9ec0dd97ceea38d8b602f24 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 13 Jan 2021 17:26:17 +0200 Subject: [PATCH 0208/1084] ASoC: SOF: Intel: tgl: do thorough remove at .shutdown() callback Invoke hda_dsp_remove() as the .shutdown() callback. This will help to perform shutdown of the DSP safely on TGL platforms before shutting down or rebooting the system. BugLink: https://github.com/thesofproject/linux/issues/2571 Signed-off-by: Keyon Jie Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210113152617.4048541-4-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/tgl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index 2252ca38ff4bf..419f05ba19208 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -22,9 +22,10 @@ static const struct snd_sof_debugfs_map tgl_dsp_debugfs[] = { /* Tigerlake ops */ const struct snd_sof_dsp_ops sof_tgl_ops = { - /* probe and remove */ + /* probe/remove/shutdown */ .probe = hda_dsp_probe, .remove = hda_dsp_remove, + .shutdown = hda_dsp_remove, /* Register IO */ .write = sof_io_write, -- GitLab From a2e38dffcd93541914aba52b30c6a52acca35201 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Tue, 5 Jan 2021 18:04:20 -0600 Subject: [PATCH 0209/1084] objtool: Don't add empty symbols to the rbtree Building with the Clang assembler shows the following warning: arch/x86/kernel/ftrace_64.o: warning: objtool: missing symbol for insn at offset 0x16 The Clang assembler strips section symbols. That ends up giving objtool's find_func_containing() much more test coverage than normal. Turns out, find_func_containing() doesn't work so well for overlapping symbols: 2: 000000000000000e 0 NOTYPE LOCAL DEFAULT 2 fgraph_trace 3: 000000000000000f 0 NOTYPE LOCAL DEFAULT 2 trace 4: 0000000000000000 165 FUNC GLOBAL DEFAULT 2 __fentry__ 5: 000000000000000e 0 NOTYPE GLOBAL DEFAULT 2 ftrace_stub The zero-length NOTYPE symbols are inside __fentry__(), confusing the rbtree search for any __fentry__() offset coming after a NOTYPE. Try to avoid this problem by not adding zero-length symbols to the rbtree. They're rare and aren't needed in the rbtree anyway. One caveat, this actually might not end up being the right fix. Non-empty overlapping symbols, if they exist, could have the same problem. But that would need bigger changes, let's see if we can get away with the easy fix for now. Reported-by: Arnd Bergmann Acked-by: Peter Zijlstra (Intel) Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index be89c741ba9a0..f9682db33ccab 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -448,6 +448,13 @@ static int read_symbols(struct elf *elf) list_add(&sym->list, entry); elf_hash_add(elf->symbol_hash, &sym->hash, sym->idx); elf_hash_add(elf->symbol_name_hash, &sym->name_hash, str_hash(sym->name)); + + /* + * Don't store empty STT_NOTYPE symbols in the rbtree. They + * can exist within a function, confusing the sorting. + */ + if (!sym->len) + rb_erase(&sym->node, &sym->sec->symbol_tree); } if (stats) -- GitLab From e6dc077b7dffdc01d9c45a5a1f4caf1e51c756a3 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Tue, 12 Jan 2021 21:29:24 +0900 Subject: [PATCH 0210/1084] soc: litex: Fix compile warning when device tree is not configured The test robot reported: drivers/soc/litex/litex_soc_ctrl.c:143:34: warning: unused variable 'litex_soc_ctrl_of_match' [-Wunused-const-variable] static const struct of_device_id litex_soc_ctrl_of_match[] = { ^ 1 warning generated. As per the random config device tree is not configured causing the litex_soc_ctrl_of_match match list to not be used. This would usually mean that we cannot even use this driver as it depends on device tree, but as we also have COMPILE_TEST configured we allow it. Fix the warning by surrounding the unused variable with an ifdef CONFIG_OF. Reported-by: kernel test robot Signed-off-by: Stafford Horne --- drivers/soc/litex/litex_soc_ctrl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/soc/litex/litex_soc_ctrl.c b/drivers/soc/litex/litex_soc_ctrl.c index 1217cafdfd4d1..9b07663845708 100644 --- a/drivers/soc/litex/litex_soc_ctrl.c +++ b/drivers/soc/litex/litex_soc_ctrl.c @@ -140,12 +140,13 @@ struct litex_soc_ctrl_device { void __iomem *base; }; +#ifdef CONFIG_OF static const struct of_device_id litex_soc_ctrl_of_match[] = { {.compatible = "litex,soc-controller"}, {}, }; - MODULE_DEVICE_TABLE(of, litex_soc_ctrl_of_match); +#endif /* CONFIG_OF */ static int litex_soc_ctrl_probe(struct platform_device *pdev) { -- GitLab From 7ac6ad051150592557520b45773201b987ecfce3 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Tue, 12 Jan 2021 15:42:54 -0800 Subject: [PATCH 0211/1084] bpf: Reject too big ctx_size_in for raw_tp test run syzbot reported a WARNING for allocating too big memory: WARNING: CPU: 1 PID: 8484 at mm/page_alloc.c:4976 __alloc_pages_nodemask+0x5f8/0x730 mm/page_alloc.c:5011 Modules linked in: CPU: 1 PID: 8484 Comm: syz-executor862 Not tainted 5.11.0-rc2-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:__alloc_pages_nodemask+0x5f8/0x730 mm/page_alloc.c:4976 Code: 00 00 0c 00 0f 85 a7 00 00 00 8b 3c 24 4c 89 f2 44 89 e6 c6 44 24 70 00 48 89 6c 24 58 e8 d0 d7 ff ff 49 89 c5 e9 ea fc ff ff <0f> 0b e9 b5 fd ff ff 89 74 24 14 4c 89 4c 24 08 4c 89 74 24 18 e8 RSP: 0018:ffffc900012efb10 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 1ffff9200025df66 RCX: 0000000000000000 RDX: 0000000000000000 RSI: dffffc0000000000 RDI: 0000000000140dc0 RBP: 0000000000140dc0 R08: 0000000000000000 R09: 0000000000000000 R10: ffffffff81b1f7e1 R11: 0000000000000000 R12: 0000000000000014 R13: 0000000000000014 R14: 0000000000000000 R15: 0000000000000000 FS: 000000000190c880(0000) GS:ffff8880b9e00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f08b7f316c0 CR3: 0000000012073000 CR4: 00000000001506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: alloc_pages_current+0x18c/0x2a0 mm/mempolicy.c:2267 alloc_pages include/linux/gfp.h:547 [inline] kmalloc_order+0x2e/0xb0 mm/slab_common.c:837 kmalloc_order_trace+0x14/0x120 mm/slab_common.c:853 kmalloc include/linux/slab.h:557 [inline] kzalloc include/linux/slab.h:682 [inline] bpf_prog_test_run_raw_tp+0x4b5/0x670 net/bpf/test_run.c:282 bpf_prog_test_run kernel/bpf/syscall.c:3120 [inline] __do_sys_bpf+0x1ea9/0x4f10 kernel/bpf/syscall.c:4398 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x440499 Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 7b 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007ffe1f3bfb18 EFLAGS: 00000246 ORIG_RAX: 0000000000000141 RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440499 RDX: 0000000000000048 RSI: 0000000020000600 RDI: 000000000000000a RBP: 00000000006ca018 R08: 0000000000000000 R09: 00000000004002c8 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000401ca0 R13: 0000000000401d30 R14: 0000000000000000 R15: 0000000000000000 This is because we didn't filter out too big ctx_size_in. Fix it by rejecting ctx_size_in that are bigger than MAX_BPF_FUNC_ARGS (12) u64 numbers. Fixes: 1b4d60ec162f ("bpf: Enable BPF_PROG_TEST_RUN for raw_tracepoint") Reported-by: syzbot+4f98876664c7337a4ae6@syzkaller.appspotmail.com Signed-off-by: Song Liu Signed-off-by: Alexei Starovoitov Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20210112234254.1906829-1-songliubraving@fb.com --- net/bpf/test_run.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index c1c30a9f76f34..8b796c499cbb2 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -272,7 +272,8 @@ int bpf_prog_test_run_raw_tp(struct bpf_prog *prog, kattr->test.repeat) return -EINVAL; - if (ctx_size_in < prog->aux->max_ctx_offset) + if (ctx_size_in < prog->aux->max_ctx_offset || + ctx_size_in > MAX_BPF_FUNC_ARGS * sizeof(u64)) return -EINVAL; if ((kattr->test.flags & BPF_F_TEST_RUN_ON_CPU) == 0 && cpu != 0) -- GitLab From 744ea4e3885eccb6d332a06fae9eb7420a622c0f Mon Sep 17 00:00:00 2001 From: Gilad Reti Date: Wed, 13 Jan 2021 07:38:07 +0200 Subject: [PATCH 0212/1084] bpf: Support PTR_TO_MEM{,_OR_NULL} register spilling Add support for pointer to mem register spilling, to allow the verifier to track pointers to valid memory addresses. Such pointers are returned for example by a successful call of the bpf_ringbuf_reserve helper. The patch was partially contributed by CyberArk Software, Inc. Fixes: 457f44363a88 ("bpf: Implement BPF ring buffer and verifier support for it") Suggested-by: Yonghong Song Signed-off-by: Gilad Reti Signed-off-by: Alexei Starovoitov Acked-by: KP Singh Link: https://lore.kernel.org/bpf/20210113053810.13518-1-gilad.reti@gmail.com --- kernel/bpf/verifier.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 17270b8404f17..36af69fac5910 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2217,6 +2217,8 @@ static bool is_spillable_regtype(enum bpf_reg_type type) case PTR_TO_RDWR_BUF: case PTR_TO_RDWR_BUF_OR_NULL: case PTR_TO_PERCPU_BTF_ID: + case PTR_TO_MEM: + case PTR_TO_MEM_OR_NULL: return true; default: return false; -- GitLab From 4237e9f4a96228ccc8a7abe5e4b30834323cd353 Mon Sep 17 00:00:00 2001 From: Gilad Reti Date: Wed, 13 Jan 2021 07:38:08 +0200 Subject: [PATCH 0213/1084] selftests/bpf: Add verifier test for PTR_TO_MEM spill Add a test to check that the verifier is able to recognize spilling of PTR_TO_MEM registers, by reserving a ringbuf buffer, forcing the spill of a pointer holding the buffer address to the stack, filling it back in from the stack and writing to the memory area pointed by it. The patch was partially contributed by CyberArk Software, Inc. Signed-off-by: Gilad Reti Signed-off-by: Alexei Starovoitov Acked-by: Yonghong Song Acked-by: KP Singh Link: https://lore.kernel.org/bpf/20210113053810.13518-2-gilad.reti@gmail.com --- tools/testing/selftests/bpf/test_verifier.c | 12 +++++++- .../selftests/bpf/verifier/spill_fill.c | 30 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 777a81404fdbd..f8569f04064b7 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -50,7 +50,7 @@ #define MAX_INSNS BPF_MAXINSNS #define MAX_TEST_INSNS 1000000 #define MAX_FIXUPS 8 -#define MAX_NR_MAPS 20 +#define MAX_NR_MAPS 21 #define MAX_TEST_RUNS 8 #define POINTER_VALUE 0xcafe4all #define TEST_DATA_LEN 64 @@ -87,6 +87,7 @@ struct bpf_test { int fixup_sk_storage_map[MAX_FIXUPS]; int fixup_map_event_output[MAX_FIXUPS]; int fixup_map_reuseport_array[MAX_FIXUPS]; + int fixup_map_ringbuf[MAX_FIXUPS]; const char *errstr; const char *errstr_unpriv; uint32_t insn_processed; @@ -640,6 +641,7 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type, int *fixup_sk_storage_map = test->fixup_sk_storage_map; int *fixup_map_event_output = test->fixup_map_event_output; int *fixup_map_reuseport_array = test->fixup_map_reuseport_array; + int *fixup_map_ringbuf = test->fixup_map_ringbuf; if (test->fill_helper) { test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn)); @@ -817,6 +819,14 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type, fixup_map_reuseport_array++; } while (*fixup_map_reuseport_array); } + if (*fixup_map_ringbuf) { + map_fds[20] = create_map(BPF_MAP_TYPE_RINGBUF, 0, + 0, 4096); + do { + prog[*fixup_map_ringbuf].imm = map_fds[20]; + fixup_map_ringbuf++; + } while (*fixup_map_ringbuf); + } } struct libcap { diff --git a/tools/testing/selftests/bpf/verifier/spill_fill.c b/tools/testing/selftests/bpf/verifier/spill_fill.c index 45d43bf82f269..0b943897aaf6c 100644 --- a/tools/testing/selftests/bpf/verifier/spill_fill.c +++ b/tools/testing/selftests/bpf/verifier/spill_fill.c @@ -28,6 +28,36 @@ .result = ACCEPT, .result_unpriv = ACCEPT, }, +{ + "check valid spill/fill, ptr to mem", + .insns = { + /* reserve 8 byte ringbuf memory */ + BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), + BPF_LD_MAP_FD(BPF_REG_1, 0), + BPF_MOV64_IMM(BPF_REG_2, 8), + BPF_MOV64_IMM(BPF_REG_3, 0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve), + /* store a pointer to the reserved memory in R6 */ + BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), + /* check whether the reservation was successful */ + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), + /* spill R6(mem) into the stack */ + BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8), + /* fill it back in R7 */ + BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_10, -8), + /* should be able to access *(R7) = 0 */ + BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 0), + /* submit the reserved ringbuf memory */ + BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), + BPF_MOV64_IMM(BPF_REG_2, 0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .fixup_map_ringbuf = { 1 }, + .result = ACCEPT, + .result_unpriv = ACCEPT, +}, { "check corrupted spill/fill", .insns = { -- GitLab From 6e6aa61d81194c01283880950df563b1b9abec46 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 13 Jan 2021 14:45:10 -0500 Subject: [PATCH 0214/1084] USB: gadget: dummy-hcd: Fix errors in port-reset handling Commit c318840fb2a4 ("USB: Gadget: dummy-hcd: Fix shift-out-of-bounds bug") messed up the way dummy-hcd handles requests to turn on the RESET port feature (I didn't notice that the original switch case ended with a fallthrough). The call to set_link_state() was inadvertently removed, as was the code to set the USB_PORT_STAT_RESET flag when the speed is USB2. In addition, the original code never checked whether the port was connected before handling the port-reset request. There was a check for the port being powered, but it was removed by that commit! In practice this doesn't matter much because the kernel doesn't try to reset disconnected ports, but it's still bad form. This patch fixes these problems by changing the fallthrough to break, adding back in the missing set_link_state() call, setting the port-reset status flag, adding a port-is-connected test, and removing a redundant assignment statement. Fixes: c318840fb2a4 ("USB: Gadget: dummy-hcd: Fix shift-out-of-bounds bug") CC: Acked-by: Felipe Balbi Signed-off-by: Alan Stern Link: https://lore.kernel.org/r/20210113194510.GA1290698@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/dummy_hcd.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 1a953f44183aa..57067763b1005 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -2270,17 +2270,20 @@ static int dummy_hub_control( } fallthrough; case USB_PORT_FEAT_RESET: + if (!(dum_hcd->port_status & USB_PORT_STAT_CONNECTION)) + break; /* if it's already enabled, disable */ if (hcd->speed == HCD_USB3) { - dum_hcd->port_status = 0; dum_hcd->port_status = (USB_SS_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION | USB_PORT_STAT_RESET); - } else + } else { dum_hcd->port_status &= ~(USB_PORT_STAT_ENABLE | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); + dum_hcd->port_status |= USB_PORT_STAT_RESET; + } /* * We want to reset device status. All but the * Self powered feature @@ -2292,7 +2295,8 @@ static int dummy_hub_control( * interval? Is it still 50msec as for HS? */ dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); - fallthrough; + set_link_state(dum_hcd); + break; case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_ENABLE: -- GitLab From 11663111cd49b4c6dd27479774e420f139e4c447 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 6 Jan 2021 17:22:27 +0000 Subject: [PATCH 0215/1084] KVM: arm64: Hide PMU registers from userspace when not available It appears that while we are now able to properly hide PMU registers from the guest when a PMU isn't available (either because none has been configured, the host doesn't have the PMU support compiled in, or that the HW doesn't have one at all), we are still exposing more than we should to userspace. Introduce a visibility callback gating all the PMU registers, which covers both usrespace and guest. Signed-off-by: Marc Zyngier --- arch/arm64/kvm/sys_regs.c | 68 +++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 42ccc27fb684c..45f4ae71c8dc6 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -590,6 +590,15 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) vcpu_write_sys_reg(vcpu, (1ULL << 31) | mpidr, MPIDR_EL1); } +static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + if (kvm_vcpu_has_pmu(vcpu)) + return 0; + + return REG_HIDDEN; +} + static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { u64 pmcr, val; @@ -936,15 +945,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { SYS_DESC(SYS_DBGWCRn_EL1(n)), \ trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } +#define PMU_SYS_REG(r) \ + SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility + /* Macro to expand the PMEVCNTRn_EL0 register */ #define PMU_PMEVCNTR_EL0(n) \ - { SYS_DESC(SYS_PMEVCNTRn_EL0(n)), \ - access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), } + { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \ + .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), } /* Macro to expand the PMEVTYPERn_EL0 register */ #define PMU_PMEVTYPER_EL0(n) \ - { SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \ - access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), } + { PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \ + .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), } static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) @@ -1486,8 +1498,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 }, { SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 }, - { SYS_DESC(SYS_PMINTENSET_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 }, - { SYS_DESC(SYS_PMINTENCLR_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 }, + { PMU_SYS_REG(SYS_PMINTENSET_EL1), + .access = access_pminten, .reg = PMINTENSET_EL1 }, + { PMU_SYS_REG(SYS_PMINTENCLR_EL1), + .access = access_pminten, .reg = PMINTENSET_EL1 }, { SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 }, { SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 }, @@ -1526,23 +1540,36 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 }, { SYS_DESC(SYS_CTR_EL0), access_ctr }, - { SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, PMCR_EL0 }, - { SYS_DESC(SYS_PMCNTENSET_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 }, - { SYS_DESC(SYS_PMCNTENCLR_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 }, - { SYS_DESC(SYS_PMOVSCLR_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 }, - { SYS_DESC(SYS_PMSWINC_EL0), access_pmswinc, reset_unknown, PMSWINC_EL0 }, - { SYS_DESC(SYS_PMSELR_EL0), access_pmselr, reset_unknown, PMSELR_EL0 }, - { SYS_DESC(SYS_PMCEID0_EL0), access_pmceid }, - { SYS_DESC(SYS_PMCEID1_EL0), access_pmceid }, - { SYS_DESC(SYS_PMCCNTR_EL0), access_pmu_evcntr, reset_unknown, PMCCNTR_EL0 }, - { SYS_DESC(SYS_PMXEVTYPER_EL0), access_pmu_evtyper }, - { SYS_DESC(SYS_PMXEVCNTR_EL0), access_pmu_evcntr }, + { PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr, + .reset = reset_pmcr, .reg = PMCR_EL0 }, + { PMU_SYS_REG(SYS_PMCNTENSET_EL0), + .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, + { PMU_SYS_REG(SYS_PMCNTENCLR_EL0), + .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, + { PMU_SYS_REG(SYS_PMOVSCLR_EL0), + .access = access_pmovs, .reg = PMOVSSET_EL0 }, + { PMU_SYS_REG(SYS_PMSWINC_EL0), + .access = access_pmswinc, .reg = PMSWINC_EL0 }, + { PMU_SYS_REG(SYS_PMSELR_EL0), + .access = access_pmselr, .reg = PMSELR_EL0 }, + { PMU_SYS_REG(SYS_PMCEID0_EL0), + .access = access_pmceid, .reset = NULL }, + { PMU_SYS_REG(SYS_PMCEID1_EL0), + .access = access_pmceid, .reset = NULL }, + { PMU_SYS_REG(SYS_PMCCNTR_EL0), + .access = access_pmu_evcntr, .reg = PMCCNTR_EL0 }, + { PMU_SYS_REG(SYS_PMXEVTYPER_EL0), + .access = access_pmu_evtyper, .reset = NULL }, + { PMU_SYS_REG(SYS_PMXEVCNTR_EL0), + .access = access_pmu_evcntr, .reset = NULL }, /* * PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero * in 32bit mode. Here we choose to reset it as zero for consistency. */ - { SYS_DESC(SYS_PMUSERENR_EL0), access_pmuserenr, reset_val, PMUSERENR_EL0, 0 }, - { SYS_DESC(SYS_PMOVSSET_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 }, + { PMU_SYS_REG(SYS_PMUSERENR_EL0), .access = access_pmuserenr, + .reset = reset_val, .reg = PMUSERENR_EL0, .val = 0 }, + { PMU_SYS_REG(SYS_PMOVSSET_EL0), + .access = access_pmovs, .reg = PMOVSSET_EL0 }, { SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 }, { SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 }, @@ -1694,7 +1721,8 @@ static const struct sys_reg_desc sys_reg_descs[] = { * PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero * in 32bit mode. Here we choose to reset it as zero for consistency. */ - { SYS_DESC(SYS_PMCCFILTR_EL0), access_pmu_evtyper, reset_val, PMCCFILTR_EL0, 0 }, + { PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper, + .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 }, { SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 }, { SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 }, -- GitLab From 7ded92e25cac9758a755b8f524b11b509c49afe1 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 6 Jan 2021 17:22:28 +0000 Subject: [PATCH 0216/1084] KVM: arm64: Simplify handling of absent PMU system registers Now that all PMU registers are gated behind a .visibility callback, remove the other checks against an absent PMU. Signed-off-by: Marc Zyngier --- arch/arm64/kvm/sys_regs.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 45f4ae71c8dc6..93f0a4a0789ab 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -622,9 +622,8 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) static bool check_pmu_access_disabled(struct kvm_vcpu *vcpu, u64 flags) { u64 reg = __vcpu_sys_reg(vcpu, PMUSERENR_EL0); - bool enabled = kvm_vcpu_has_pmu(vcpu); + bool enabled = (reg & flags) || vcpu_mode_priv(vcpu); - enabled &= (reg & flags) || vcpu_mode_priv(vcpu); if (!enabled) kvm_inject_undefined(vcpu); @@ -909,11 +908,6 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p, static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - if (!kvm_vcpu_has_pmu(vcpu)) { - kvm_inject_undefined(vcpu); - return false; - } - if (p->is_write) { if (!vcpu_mode_priv(vcpu)) { kvm_inject_undefined(vcpu); -- GitLab From 2c91ef39216149df6703c3fa6a47dd9a1e6091c1 Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Tue, 29 Dec 2020 16:00:59 +0000 Subject: [PATCH 0217/1084] KVM: arm64: Allow PSCI SYSTEM_OFF/RESET to return The KVM/arm64 PSCI relay assumes that SYSTEM_OFF and SYSTEM_RESET should not return, as dictated by the PSCI spec. However, there is firmware out there which breaks this assumption, leading to a hyp panic. Make KVM more robust to broken firmware by allowing these to return. Signed-off-by: David Brazdil Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20201229160059.64135-1-dbrazdil@google.com --- arch/arm64/kvm/hyp/nvhe/psci-relay.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe/psci-relay.c index e3947846ffcb9..8e7128cb76678 100644 --- a/arch/arm64/kvm/hyp/nvhe/psci-relay.c +++ b/arch/arm64/kvm/hyp/nvhe/psci-relay.c @@ -77,12 +77,6 @@ static unsigned long psci_forward(struct kvm_cpu_context *host_ctxt) cpu_reg(host_ctxt, 2), cpu_reg(host_ctxt, 3)); } -static __noreturn unsigned long psci_forward_noreturn(struct kvm_cpu_context *host_ctxt) -{ - psci_forward(host_ctxt); - hyp_panic(); /* unreachable */ -} - static unsigned int find_cpu_id(u64 mpidr) { unsigned int i; @@ -251,10 +245,13 @@ static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_ case PSCI_0_2_FN_MIGRATE_INFO_TYPE: case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU: return psci_forward(host_ctxt); + /* + * SYSTEM_OFF/RESET should not return according to the spec. + * Allow it so as to stay robust to broken firmware. + */ case PSCI_0_2_FN_SYSTEM_OFF: case PSCI_0_2_FN_SYSTEM_RESET: - psci_forward_noreturn(host_ctxt); - unreachable(); + return psci_forward(host_ctxt); case PSCI_0_2_FN64_CPU_SUSPEND: return psci_cpu_suspend(func_id, host_ctxt); case PSCI_0_2_FN64_CPU_ON: -- GitLab From 7ba8b4380afbdbb29d53c50bee6563cd7457fc34 Mon Sep 17 00:00:00 2001 From: Alexandru Elisei Date: Wed, 6 Jan 2021 14:42:18 +0000 Subject: [PATCH 0218/1084] KVM: arm64: Use the reg_to_encoding() macro instead of sys_reg() The reg_to_encoding() macro is a wrapper over sys_reg() and conveniently takes a sys_reg_desc or a sys_reg_params argument and returns the 32 bit register encoding. Use it instead of calling sys_reg() directly. Signed-off-by: Alexandru Elisei Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210106144218.110665-1-alexandru.elisei@arm.com --- arch/arm64/kvm/sys_regs.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 93f0a4a0789ab..7c4f79532406b 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -43,6 +43,10 @@ * 64bit interface. */ +#define reg_to_encoding(x) \ + sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ + (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2) + static bool read_from_write_only(struct kvm_vcpu *vcpu, struct sys_reg_params *params, const struct sys_reg_desc *r) @@ -273,8 +277,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); - u32 sr = sys_reg((u32)r->Op0, (u32)r->Op1, - (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); + u32 sr = reg_to_encoding(r); if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) { kvm_inject_undefined(vcpu); @@ -924,10 +927,6 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, return true; } -#define reg_to_encoding(x) \ - sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ - (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2) - /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ { SYS_DESC(SYS_DBGBVRn_EL1(n)), \ @@ -1026,8 +1025,7 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu, static u64 read_id_reg(const struct kvm_vcpu *vcpu, struct sys_reg_desc const *r, bool raz) { - u32 id = sys_reg((u32)r->Op0, (u32)r->Op1, - (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); + u32 id = reg_to_encoding(r); u64 val = raz ? 0 : read_sanitised_ftr_reg(id); if (id == SYS_ID_AA64PFR0_EL1) { @@ -1068,8 +1066,7 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, static unsigned int id_visibility(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { - u32 id = sys_reg((u32)r->Op0, (u32)r->Op1, - (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); + u32 id = reg_to_encoding(r); switch (id) { case SYS_ID_AA64ZFR0_EL1: -- GitLab From 1eb8f690bcb565a6600f8b6dcc78f7b239ceba17 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 14 Jan 2021 10:36:59 +0100 Subject: [PATCH 0219/1084] x86/topology: Make __max_die_per_package available unconditionally Move it outside of CONFIG_SMP in order to avoid ifdeffery at the usage sites. Fixes: 76e2fc63ca40 ("x86/cpu/amd: Set __max_die_per_package on AMD") Reported-by: Stephen Rothwell Reported-by: kernel test robot Signed-off-by: Borislav Petkov Link: https://lkml.kernel.org/r/20210114111814.5346-1-bp@alien8.de --- arch/x86/include/asm/topology.h | 4 ++-- arch/x86/kernel/cpu/topology.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 488a8e8487548..9239399e54914 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -110,6 +110,8 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu); #define topology_die_id(cpu) (cpu_data(cpu).cpu_die_id) #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) +extern unsigned int __max_die_per_package; + #ifdef CONFIG_SMP #define topology_die_cpumask(cpu) (per_cpu(cpu_die_map, cpu)) #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) @@ -118,8 +120,6 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu); extern unsigned int __max_logical_packages; #define topology_max_packages() (__max_logical_packages) -extern unsigned int __max_die_per_package; - static inline int topology_max_die_per_package(void) { return __max_die_per_package; diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index 1068002c85323..8678864ce7123 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -25,10 +25,10 @@ #define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f) #define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff) -#ifdef CONFIG_SMP unsigned int __max_die_per_package __read_mostly = 1; EXPORT_SYMBOL(__max_die_per_package); +#ifdef CONFIG_SMP /* * Check if given CPUID extended toplogy "leaf" is implemented */ -- GitLab From 7a2da5d7960a64ee923fe3e31f01a1101052c66f Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 14 Jan 2021 13:09:37 +0000 Subject: [PATCH 0220/1084] spi: fsl: Fix driver breakage when SPI_CS_HIGH is not set in spi->mode Commit 766c6b63aa04 ("spi: fix client driver breakages when using GPIO descriptors") broke fsl spi driver. As now we fully rely on gpiolib for handling the polarity of chip selects, the driver shall not alter the GPIO value anymore when SPI_CS_HIGH is not set in spi->mode. Fixes: 766c6b63aa04 ("spi: fix client driver breakages when using GPIO descriptors") Cc: stable@vger.kernel.org Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/6b51cc2bfbca70d3e9b9da7b7aa4c7a9d793ca0e.1610629002.git.christophe.leroy@csgroup.eu Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-spi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 9494257e1c33f..6d8e0a05a5355 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -115,14 +115,13 @@ static void fsl_spi_chipselect(struct spi_device *spi, int value) { struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); struct fsl_spi_platform_data *pdata; - bool pol = spi->mode & SPI_CS_HIGH; struct spi_mpc8xxx_cs *cs = spi->controller_state; pdata = spi->dev.parent->parent->platform_data; if (value == BITBANG_CS_INACTIVE) { if (pdata->cs_control) - pdata->cs_control(spi, !pol); + pdata->cs_control(spi, false); } if (value == BITBANG_CS_ACTIVE) { @@ -134,7 +133,7 @@ static void fsl_spi_chipselect(struct spi_device *spi, int value) fsl_spi_change_mode(spi); if (pdata->cs_control) - pdata->cs_control(spi, pol); + pdata->cs_control(spi, true); } } -- GitLab From a0572c0734e4926ac51a31f97c12f752e1cdc7c8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 1 Dec 2020 12:13:29 +0100 Subject: [PATCH 0221/1084] ARM: dts: stm32: Fix polarity of the DH DRC02 uSD card detect The uSD card detect signal on the DH DRC02 is active-high, with a default pull down resistor on the board. Invert the polarity. Fixes: fde180f06d7b ("ARM: dts: stm32: Add DHSOM based DRC02 board") Signed-off-by: Marek Vasut Cc: Alexandre Torgue Cc: Maxime Coquelin Cc: Patrice Chotard Cc: Patrick Delaunay Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org -- Note that this could not be tested on prototype SoMs, now that it is tested, this issue surfaced, so it needs to be fixed. Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi index 62ab23824a3e7..3299a42d80633 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi @@ -104,7 +104,7 @@ * are used for on-board microSD slot instead. */ /delete-property/broken-cd; - cd-gpios = <&gpioi 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + cd-gpios = <&gpioi 10 GPIO_ACTIVE_HIGH>; disable-wp; }; -- GitLab From 1a9b001237f85d3cf11a408c2daca6a2245b2add Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 1 Dec 2020 12:13:30 +0100 Subject: [PATCH 0222/1084] ARM: dts: stm32: Connect card-detect signal on DHCOM The DHCOM SoM uSD slot card detect signal is connected to GPIO PG1, describe it in the DT. Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board") Signed-off-by: Marek Vasut Cc: Alexandre Torgue Cc: Maxime Coquelin Cc: Patrice Chotard Cc: Patrick Delaunay Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi index ac46ab363e1b4..c77ab1bfdd3e3 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi @@ -390,7 +390,7 @@ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>; pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>; - broken-cd; + cd-gpios = <&gpiog 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; st,sig-dir; st,neg-edge; st,use-ckin; -- GitLab From 063a60634d48ee89f697371c9850c9370e494f22 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 1 Dec 2020 12:13:31 +0100 Subject: [PATCH 0223/1084] ARM: dts: stm32: Disable WP on DHCOM uSD slot The uSD slot has no WP detection, disable it. Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board") Signed-off-by: Marek Vasut Cc: Alexandre Torgue Cc: Maxime Coquelin Cc: Patrice Chotard Cc: Patrick Delaunay Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi index c77ab1bfdd3e3..daff5318f301e 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi @@ -391,6 +391,7 @@ pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>; pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>; cd-gpios = <&gpiog 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + disable-wp; st,sig-dir; st,neg-edge; st,use-ckin; -- GitLab From 3c97be6982e689d7b2430187a11f8c78e573abdb Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 4 Jan 2021 10:30:57 +0100 Subject: [PATCH 0224/1084] mtd: rawnand: nandsim: Fix the logic when selecting Hamming soft ECC engine I have been fooled by the logic picking the right ECC engine which is spread across two functions: *init_module() and *_attach(). I thought this driver was not impacted by the recent changes around the ECC engines DT parsing logic but in fact it is. Reported-by: kernel test robot Fixes: d7157ff49a5b ("mtd: rawnand: Use the ECC framework user input parsing bits") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210104093057.31178-1-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nandsim.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c index f2b9250c0ea83..0750121ac371c 100644 --- a/drivers/mtd/nand/raw/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c @@ -2210,6 +2210,9 @@ static int ns_attach_chip(struct nand_chip *chip) { unsigned int eccsteps, eccbytes; + chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + chip->ecc.algo = bch ? NAND_ECC_ALGO_BCH : NAND_ECC_ALGO_HAMMING; + if (!bch) return 0; @@ -2233,8 +2236,6 @@ static int ns_attach_chip(struct nand_chip *chip) return -EINVAL; } - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - chip->ecc.algo = NAND_ECC_ALGO_BCH; chip->ecc.size = 512; chip->ecc.strength = bch; chip->ecc.bytes = eccbytes; @@ -2273,8 +2274,6 @@ static int __init ns_init_module(void) nsmtd = nand_to_mtd(chip); nand_set_controller_data(chip, (void *)ns); - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - chip->ecc.algo = NAND_ECC_ALGO_HAMMING; /* The NAND_SKIP_BBTSCAN option is necessary for 'overridesize' */ /* and 'badblocks' parameters to work */ chip->options |= NAND_SKIP_BBTSCAN; -- GitLab From 18f62614308be69a2752afb5f6bbad60096ad774 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Wed, 6 Jan 2021 15:09:43 +0100 Subject: [PATCH 0225/1084] mtd: rawnand: intel: check the mtd name only after setting the variable Move the check for mtd->name after the mtd variable has actually been initialized. While here, also drop the NULL assignment to the mtd variable as it's overwritten later on anyways and the NULL value is never read. Fixes: 0b1039f016e8a3 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") Signed-off-by: Martin Blumenstingl Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210106140943.98072-1-martin.blumenstingl@googlemail.com --- drivers/mtd/nand/raw/intel-nand-controller.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c index fdb112e8a90d2..a304fda5d1fa5 100644 --- a/drivers/mtd/nand/raw/intel-nand-controller.c +++ b/drivers/mtd/nand/raw/intel-nand-controller.c @@ -579,7 +579,7 @@ static int ebu_nand_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct ebu_nand_controller *ebu_host; struct nand_chip *nand; - struct mtd_info *mtd = NULL; + struct mtd_info *mtd; struct resource *res; char *resname; int ret; @@ -647,12 +647,13 @@ static int ebu_nand_probe(struct platform_device *pdev) ebu_host->ebu + EBU_ADDR_SEL(cs)); nand_set_flash_node(&ebu_host->chip, dev->of_node); + + mtd = nand_to_mtd(&ebu_host->chip); if (!mtd->name) { dev_err(ebu_host->dev, "NAND label property is mandatory\n"); return -EINVAL; } - mtd = nand_to_mtd(&ebu_host->chip); mtd->dev.parent = dev; ebu_host->dev = dev; -- GitLab From e708789c4a87989faff1131ccfdc465a1c1eddbc Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 7 Jan 2021 09:38:13 +0100 Subject: [PATCH 0226/1084] mtd: spinand: Fix MTD_OPS_AUTO_OOB requests The initial change breaking the logic is commit 3d1f08b032dc ("mtd: spinand: Use the external ECC engine logic") It inadvertently dropped proper OOB support while doing something else. Shortly later, half of it got re-integrated by commit 868cbe2a6dce ("mtd: spinand: Fix OOB read") (pointing by the way to a more early change which had nothing to do with the issue). Problem is, this commit failed to revert the faulty change entirely and missed the logic handling MTD_OPS_AUTO_OOB requests. Let's fix this mess by re-inserting the missing part now. Fixes: 868cbe2a6dce ("mtd: spinand: Fix OOB read") Reported-by: Felix Fietkau Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210107083813.24283-1-miquel.raynal@bootlin.com --- drivers/mtd/nand/spi/core.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 8ea545bb924d2..61d932c1b7180 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -343,6 +343,7 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand, const struct nand_page_io_req *req) { struct nand_device *nand = spinand_to_nand(spinand); + struct mtd_info *mtd = spinand_to_mtd(spinand); struct spi_mem_dirmap_desc *rdesc; unsigned int nbytes = 0; void *buf = NULL; @@ -382,9 +383,16 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand, memcpy(req->databuf.in, spinand->databuf + req->dataoffs, req->datalen); - if (req->ooblen) - memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs, - req->ooblen); + if (req->ooblen) { + if (req->mode == MTD_OPS_AUTO_OOB) + mtd_ooblayout_get_databytes(mtd, req->oobbuf.in, + spinand->oobbuf, + req->ooboffs, + req->ooblen); + else + memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs, + req->ooblen); + } return 0; } -- GitLab From 087698939f30d489e785d7df3e6aa5dce2487b39 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 7 Jan 2021 16:07:42 +0100 Subject: [PATCH 0227/1084] ARM: dts: stm32: Disable optional TSC2004 on DRC02 board The DRC02 has no use for the on-SoM touchscreen controller, and the on-SoM touchscreen controller may not even be populated, which then results in error messages in kernel log. Disable the touchscreen controller in DT. Fixes: fde180f06d7b ("ARM: dts: stm32: Add DHSOM based DRC02 board") Signed-off-by: Marek Vasut Cc: Alexandre Torgue Cc: Maxime Coquelin Cc: Patrice Chotard Cc: Patrick Delaunay Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi index 3299a42d80633..4cabdade6432b 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi @@ -87,6 +87,12 @@ }; }; +&i2c4 { + touchscreen@49 { + status = "disabled"; + }; +}; + &i2c5 { /* TP7/TP8 */ pinctrl-names = "default"; pinctrl-0 = <&i2c5_pins_a>; -- GitLab From 5e6dca82bcaa49348f9e5fcb48df4881f6d6c4ae Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Tue, 12 Jan 2021 11:46:24 -0800 Subject: [PATCH 0228/1084] x86/entry: Emit a symbol for register restoring thunk Arnd found a randconfig that produces the warning: arch/x86/entry/thunk_64.o: warning: objtool: missing symbol for insn at offset 0x3e when building with LLVM_IAS=1 (Clang's integrated assembler). Josh notes: With the LLVM assembler not generating section symbols, objtool has no way to reference this code when it generates ORC unwinder entries, because this code is outside of any ELF function. The limitation now being imposed by objtool is that all code must be contained in an ELF symbol. And .L symbols don't create such symbols. So basically, you can use an .L symbol *inside* a function or a code segment, you just can't use the .L symbol to contain the code using a SYM_*_START/END annotation pair. Fangrui notes that this optimization is helpful for reducing image size when compiling with -ffunction-sections and -fdata-sections. I have observed on the order of tens of thousands of symbols for the kernel images built with those flags. A patch has been authored against GNU binutils to match this behavior of not generating unused section symbols ([1]), so this will also become a problem for users of GNU binutils once they upgrade to 2.36. Omit the .L prefix on a label so that the assembler will emit an entry into the symbol table for the label, with STB_LOCAL binding. This enables objtool to generate proper unwind info here with LLVM_IAS=1 or GNU binutils 2.36+. [ bp: Massage commit message. ] Reported-by: Arnd Bergmann Suggested-by: Josh Poimboeuf Suggested-by: Borislav Petkov Suggested-by: Mark Brown Signed-off-by: Nick Desaulniers Signed-off-by: Borislav Petkov Acked-by: Peter Zijlstra (Intel) Acked-by: Josh Poimboeuf Link: https://lkml.kernel.org/r/20210112194625.4181814-1-ndesaulniers@google.com Link: https://github.com/ClangBuiltLinux/linux/issues/1209 Link: https://reviews.llvm.org/D93783 Link: https://sourceware.org/binutils/docs/as/Symbol-Names.html Link: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d1bcae833b32f1408485ce69f844dcd7ded093a8 [1] --- Documentation/asm-annotations.rst | 5 +++++ arch/x86/entry/thunk_64.S | 8 ++++---- include/linux/linkage.h | 5 +++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Documentation/asm-annotations.rst b/Documentation/asm-annotations.rst index 32ea57483378d..76424e0431f4b 100644 --- a/Documentation/asm-annotations.rst +++ b/Documentation/asm-annotations.rst @@ -100,6 +100,11 @@ Instruction Macros ~~~~~~~~~~~~~~~~~~ This section covers ``SYM_FUNC_*`` and ``SYM_CODE_*`` enumerated above. +``objtool`` requires that all code must be contained in an ELF symbol. Symbol +names that have a ``.L`` prefix do not emit symbol table entries. ``.L`` +prefixed symbols can be used within a code region, but should be avoided for +denoting a range of code via ``SYM_*_START/END`` annotations. + * ``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the most frequent markings**. They are used for functions with standard calling conventions -- global and local. Like in C, they both align the functions to diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk_64.S index ccd32877a3c41..c9a9fbf1655f3 100644 --- a/arch/x86/entry/thunk_64.S +++ b/arch/x86/entry/thunk_64.S @@ -31,7 +31,7 @@ SYM_FUNC_START_NOALIGN(\name) .endif call \func - jmp .L_restore + jmp __thunk_restore SYM_FUNC_END(\name) _ASM_NOKPROBE(\name) .endm @@ -44,7 +44,7 @@ SYM_FUNC_END(\name) #endif #ifdef CONFIG_PREEMPTION -SYM_CODE_START_LOCAL_NOALIGN(.L_restore) +SYM_CODE_START_LOCAL_NOALIGN(__thunk_restore) popq %r11 popq %r10 popq %r9 @@ -56,6 +56,6 @@ SYM_CODE_START_LOCAL_NOALIGN(.L_restore) popq %rdi popq %rbp ret - _ASM_NOKPROBE(.L_restore) -SYM_CODE_END(.L_restore) + _ASM_NOKPROBE(__thunk_restore) +SYM_CODE_END(__thunk_restore) #endif diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 5bcfbd972e970..dbf8506decca0 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -178,6 +178,11 @@ * Objtool generates debug info for both FUNC & CODE, but needs special * annotations for each CODE's start (to describe the actual stack frame). * + * Objtool requires that all code must be contained in an ELF symbol. Symbol + * names that have a .L prefix do not emit symbol table entries. .L + * prefixed symbols can be used within a code region, but should be avoided for + * denoting a range of code via ``SYM_*_START/END`` annotations. + * * ALIAS -- does not generate debug info -- the aliased function will */ -- GitLab From b7c568752ef3b36afa78e1a1866dc049d175993b Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 29 Dec 2020 14:15:48 -0700 Subject: [PATCH 0229/1084] mt76: Fix queue ID variable types after mcu queue split Clang warns in both mt7615 and mt7915: drivers/net/wireless/mediatek/mt76/mt7915/mcu.c:271:9: warning: implicit conversion from enumeration type 'enum mt76_mcuq_id' to different enumeration type 'enum mt76_txq_id' [-Wenum-conversion] txq = MT_MCUQ_FWDL; ~ ^~~~~~~~~~~~ drivers/net/wireless/mediatek/mt76/mt7915/mcu.c:278:9: warning: implicit conversion from enumeration type 'enum mt76_mcuq_id' to different enumeration type 'enum mt76_txq_id' [-Wenum-conversion] txq = MT_MCUQ_WA; ~ ^~~~~~~~~~ drivers/net/wireless/mediatek/mt76/mt7915/mcu.c:282:9: warning: implicit conversion from enumeration type 'enum mt76_mcuq_id' to different enumeration type 'enum mt76_txq_id' [-Wenum-conversion] txq = MT_MCUQ_WM; ~ ^~~~~~~~~~ 3 warnings generated. drivers/net/wireless/mediatek/mt76/mt7615/mcu.c:238:9: warning: implicit conversion from enumeration type 'enum mt76_mcuq_id' to different enumeration type 'enum mt76_txq_id' [-Wenum-conversion] qid = MT_MCUQ_WM; ~ ^~~~~~~~~~ drivers/net/wireless/mediatek/mt76/mt7615/mcu.c:240:9: warning: implicit conversion from enumeration type 'enum mt76_mcuq_id' to different enumeration type 'enum mt76_txq_id' [-Wenum-conversion] qid = MT_MCUQ_FWDL; ~ ^~~~~~~~~~~~ 2 warnings generated. Use the proper type for the queue ID variables to fix these warnings. Additionally, rename the txq variable in mt7915_mcu_send_message to be more neutral like mt7615_mcu_send_message. Fixes: e637763b606b ("mt76: move mcu queues to mt76_dev q_mcu array") Link: https://github.com/ClangBuiltLinux/linux/issues/1229 Signed-off-by: Nathan Chancellor Acked-by: Lorenzo Bianconi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201229211548.1348077-1-natechancellor@gmail.com --- drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index a44b7766dec64..c13547841a4e9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -231,7 +231,7 @@ mt7615_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, int cmd, int *seq) { struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); - enum mt76_txq_id qid; + enum mt76_mcuq_id qid; mt7615_mcu_fill_msg(dev, skb, cmd, seq); if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 5fdd1a6d32ee1..e211a2bd4d3c0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -256,7 +256,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); struct mt7915_mcu_txd *mcu_txd; u8 seq, pkt_fmt, qidx; - enum mt76_txq_id txq; + enum mt76_mcuq_id qid; __le32 *txd; u32 val; @@ -268,18 +268,18 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, seq = ++dev->mt76.mcu.msg_seq & 0xf; if (cmd == -MCU_CMD_FW_SCATTER) { - txq = MT_MCUQ_FWDL; + qid = MT_MCUQ_FWDL; goto exit; } mcu_txd = (struct mt7915_mcu_txd *)skb_push(skb, sizeof(*mcu_txd)); if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) { - txq = MT_MCUQ_WA; + qid = MT_MCUQ_WA; qidx = MT_TX_MCU_PORT_RX_Q0; pkt_fmt = MT_TX_TYPE_CMD; } else { - txq = MT_MCUQ_WM; + qid = MT_MCUQ_WM; qidx = MT_TX_MCU_PORT_RX_Q0; pkt_fmt = MT_TX_TYPE_CMD; } @@ -326,7 +326,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, if (wait_seq) *wait_seq = seq; - return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0); + return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0); } static void -- GitLab From a6616bc9a0af7c65c0b0856a7508870a4a40c4ac Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 12 Jan 2021 14:24:48 +0100 Subject: [PATCH 0230/1084] iwlwifi: dbg: Don't touch the tlv data The commit ba8f6f4ae254 ("iwlwifi: dbg: add dumping special device memory") added a termination of name string just to be sure, and this seems causing a regression, a GPF triggered at firmware loading. Basically we shouldn't modify the firmware data that may be provided as read-only. This patch drops the code that caused the regression and keep the tlv data as is. Fixes: ba8f6f4ae254 ("iwlwifi: dbg: add dumping special device memory") BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1180344 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=210733 Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai Acked-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210112132449.22243-2-tiwai@suse.de --- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index a654147d3cd61..a80a35a7740f3 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -180,13 +180,6 @@ static int iwl_dbg_tlv_alloc_region(struct iwl_trans *trans, if (le32_to_cpu(tlv->length) < sizeof(*reg)) return -EINVAL; - /* For safe using a string from FW make sure we have a - * null terminator - */ - reg->name[IWL_FW_INI_MAX_NAME - 1] = 0; - - IWL_DEBUG_FW(trans, "WRT: parsing region: %s\n", reg->name); - if (id >= IWL_FW_INI_MAX_REGION_ID) { IWL_ERR(trans, "WRT: Invalid region id %u\n", id); return -EINVAL; -- GitLab From bcbacfb82c7010431182a8aecb860c752e3aed8c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 24 Dec 2020 07:24:38 +0100 Subject: [PATCH 0231/1084] ARM: dts: stm32: Fix GPIO hog names on DHCOM The GPIO hog node name should match regex '^(hog-[0-9]+|.+-hog(-[0-9]+)?)$', make it so and fix the following two make dtbs_check warnings: arch/arm/boot/dts/stm32mp157c-dhcom-picoitx.dt.yaml: hog-usb-port-power: $nodename:0: 'hog-usb-port-power' does not match '^(hog-[0-9]+|.+-hog(-[0-9]+)?)$' arch/arm/boot/dts/stm32mp153c-dhcom-drc02.dt.yaml: hog-usb-hub: $nodename:0: 'hog-usb-hub' does not match '^(hog-[0-9]+|.+-hog(-[0-9]+)?)$' Fixes: ac68793f49de ("ARM: dts: stm32: Add DHCOM based PicoITX board") Signed-off-by: Marek Vasut Cc: Alexandre Torgue Cc: Maxime Coquelin Cc: Patrice Chotard Cc: Patrick Delaunay Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi | 4 ++-- arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi index 4cabdade6432b..28c01cd9ac70e 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi @@ -33,7 +33,7 @@ * during TX anyway and that it only controls drive enable DE * line. Hence, the RX is always enabled here. */ - rs485-rx-en { + rs485-rx-en-hog { gpio-hog; gpios = <8 GPIO_ACTIVE_HIGH>; output-low; @@ -61,7 +61,7 @@ * order to reset the Hub when USB bus is powered down, but * so far there is no such functionality. */ - usb-hub { + usb-hub-hog { gpio-hog; gpios = <2 GPIO_ACTIVE_HIGH>; output-high; diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi index 356150d28c420..b99f2b8916298 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi @@ -43,7 +43,7 @@ * in order to turn on port power when USB bus is powered up, but so * far there is no such functionality. */ - usb-port-power { + usb-port-power-hog { gpio-hog; gpios = <13 GPIO_ACTIVE_LOW>; output-low; -- GitLab From 10793e557acece49fe1c55e8f4563f6b89543c18 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 29 Dec 2020 18:55:20 +0100 Subject: [PATCH 0232/1084] ARM: dts: stm32: Fix GPIO hog flags on DHCOM PicoITX The GPIO hog flags are ignored by gpiolib-of.c now, set the flags to 0. Due to a change in gpiolib-of.c, setting flags to GPIO_ACTIVE_LOW and using output-low DT property leads to the GPIO being set high instead. Fixes: ac68793f49de ("ARM: dts: stm32: Add DHCOM based PicoITX board") Signed-off-by: Marek Vasut Cc: Alexandre Torgue Cc: Maxime Coquelin Cc: Patrice Chotard Cc: Patrick Delaunay Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi index b99f2b8916298..32700cca24c82 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi @@ -45,7 +45,7 @@ */ usb-port-power-hog { gpio-hog; - gpios = <13 GPIO_ACTIVE_LOW>; + gpios = <13 0>; output-low; line-name = "usb-port-power"; }; -- GitLab From 83d411224025ac1baab981e3d2f5d29e7761541d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 29 Dec 2020 18:55:21 +0100 Subject: [PATCH 0233/1084] ARM: dts: stm32: Fix GPIO hog flags on DHCOM DRC02 The GPIO hog flags are ignored by gpiolib-of.c now, set the flags to 0. Since GPIO_ACTIVE_HIGH is defined as 0, this change only increases the correctness of the DT. Fixes: fde180f06d7b ("ARM: dts: stm32: Add DHSOM based DRC02 board") Signed-off-by: Marek Vasut Cc: Alexandre Torgue Cc: Maxime Coquelin Cc: Patrice Chotard Cc: Patrick Delaunay Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi index 28c01cd9ac70e..5088dd3a301b7 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi @@ -35,7 +35,7 @@ */ rs485-rx-en-hog { gpio-hog; - gpios = <8 GPIO_ACTIVE_HIGH>; + gpios = <8 0>; output-low; line-name = "rs485-rx-en"; }; @@ -63,7 +63,7 @@ */ usb-hub-hog { gpio-hog; - gpios = <2 GPIO_ACTIVE_HIGH>; + gpios = <2 0>; output-high; line-name = "usb-hub-reset"; }; -- GitLab From a06b63a1200bd40fd20fa695739e479e2b2ae948 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 1 Dec 2020 10:03:28 +0300 Subject: [PATCH 0234/1084] iio: sx9310: Off by one in sx9310_read_thresh() This > should be >= to prevent reading one element beyond the end of the sx9310_pthresh_codes[] array. Fixes: ad2b473e2ba3 ("iio: sx9310: Support setting proximity thresholds") Signed-off-by: Dan Carpenter Reviewed-by: Stephen Boyd Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/X8XqwK0z//8sSWJR@mwanda Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/sx9310.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c index a2f820997afc2..62eacb22e9bcb 100644 --- a/drivers/iio/proximity/sx9310.c +++ b/drivers/iio/proximity/sx9310.c @@ -601,7 +601,7 @@ static int sx9310_read_thresh(struct sx9310_data *data, return ret; regval = FIELD_GET(SX9310_REG_PROX_CTRL8_9_PTHRESH_MASK, regval); - if (regval > ARRAY_SIZE(sx9310_pthresh_codes)) + if (regval >= ARRAY_SIZE(sx9310_pthresh_codes)) return -EINVAL; *val = sx9310_pthresh_codes[regval]; -- GitLab From b6bc1b4ffad4a55c9461707833dc45de2e4367cc Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 2 Dec 2020 09:35:51 +0100 Subject: [PATCH 0235/1084] dt-bindings: iio: accel: bma255: Fix bmc150/bmi055 compatible The bmc150-accel-i2c.c driver has an "_accel" suffix for the compatibles of BMC150 and BMI055. This is necessary because BMC150 contains both accelerometer (bosch,bmc150_accel) and magnetometer (bosch,bmc150_magn) and therefore "bosch,bmc150" would be ambiguous. However, the binding documentation suggests using "bosch,bmc150". Add the "_accel" suffix for BMC150 and BMI055 so the binding docs match what is expected by the driver. Fixes: 6259551cf19b ("iio: accel: bmc150-accel: Add DT bindings") Signed-off-by: Stephan Gerhold Reviewed-by: Linus Walleij Reviewed-by: Rob Herring Cc: Linus Walleij Link: https://lore.kernel.org/r/20201202083551.7753-1-stephan@gerhold.net Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml b/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml index 6eef3480ea8fc..c2efbb813ca27 100644 --- a/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml +++ b/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml @@ -16,8 +16,8 @@ description: properties: compatible: enum: - - bosch,bmc150 - - bosch,bmi055 + - bosch,bmc150_accel + - bosch,bmi055_accel - bosch,bma255 - bosch,bma250e - bosch,bma222 -- GitLab From 7e6d9788aa02333a4353058816d52b9a90aae0d3 Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Thu, 3 Dec 2020 09:26:50 +0200 Subject: [PATCH 0236/1084] iio: adc: ti_am335x_adc: remove omitted iio_kfifo_free() When the conversion was done to use devm_iio_kfifo_allocate(), a call to iio_kfifo_free() was omitted (to be removed). This change removes it. Fixes: 3c5308058899 ("iio: adc: ti_am335x_adc: alloc kfifo & IRQ via devm_ functions") Signed-off-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20201203072650.24128-1-alexandru.ardelean@analog.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti_am335x_adc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index b11c8c47ba2aa..e946903b09936 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -397,16 +397,12 @@ static int tiadc_iio_buffered_hardware_setup(struct device *dev, ret = devm_request_threaded_irq(dev, irq, pollfunc_th, pollfunc_bh, flags, indio_dev->name, indio_dev); if (ret) - goto error_kfifo_free; + return ret; indio_dev->setup_ops = setup_ops; indio_dev->modes |= INDIO_BUFFER_SOFTWARE; return 0; - -error_kfifo_free: - iio_kfifo_free(indio_dev->buffer); - return ret; } static const char * const chan_name_ain[] = { -- GitLab From cf5b1385d748b2f91b0c05bb301fcaf9bdbad385 Mon Sep 17 00:00:00 2001 From: Slaveyko Slaveykov Date: Wed, 16 Dec 2020 13:57:20 +0200 Subject: [PATCH 0237/1084] drivers: iio: temperature: Add delay after the addressed reset command in mlx90632.c After an I2C reset command, the mlx90632 needs some time before responding to other I2C commands. Without that delay, there is a chance that the I2C command(s) after the reset will not be accepted. Signed-off-by: Slaveyko Slaveykov Reviewed-by: Andy Shevchenko Reviewed-by: Crt Mori Fixes: e02472f74a81 ("iio:temperature:mlx90632: Adding extended calibration option") Link: https://lore.kernel.org/r/20201216115720.12404-2-sis@melexis.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 503fe54a0bb93..608ccb1d8bc82 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -248,6 +248,12 @@ static int mlx90632_set_meas_type(struct regmap *regmap, u8 type) if (ret < 0) return ret; + /* + * Give the mlx90632 some time to reset properly before sending a new I2C command + * if this is not done, the following I2C command(s) will not be accepted. + */ + usleep_range(150, 200); + ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, (MLX90632_CFG_MTYP_MASK | MLX90632_CFG_PWR_MASK), (MLX90632_MTYP_STATUS(type) | MLX90632_PWR_STATUS_HALT)); -- GitLab From 49a9565a7a7ce168e3e6482fb24e62d12f72ab81 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sun, 13 Dec 2020 18:09:27 -0600 Subject: [PATCH 0238/1084] counter:ti-eqep: remove floor The hardware doesn't support this. QPOSINIT is an initialization value that is triggered by other things. When the counter overflows, it always wraps around to zero. Fixes: f213729f6796 "counter: new TI eQEP driver" Signed-off-by: David Lechner Acked-by: William Breathitt Gray Link: https://lore.kernel.org/r/20201214000927.1793062-1-david@lechnology.com Cc: Signed-off-by: Jonathan Cameron --- drivers/counter/ti-eqep.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c index a60aee1a1a291..65df9ef5b5bc0 100644 --- a/drivers/counter/ti-eqep.c +++ b/drivers/counter/ti-eqep.c @@ -235,36 +235,6 @@ static ssize_t ti_eqep_position_ceiling_write(struct counter_device *counter, return len; } -static ssize_t ti_eqep_position_floor_read(struct counter_device *counter, - struct counter_count *count, - void *ext_priv, char *buf) -{ - struct ti_eqep_cnt *priv = counter->priv; - u32 qposinit; - - regmap_read(priv->regmap32, QPOSINIT, &qposinit); - - return sprintf(buf, "%u\n", qposinit); -} - -static ssize_t ti_eqep_position_floor_write(struct counter_device *counter, - struct counter_count *count, - void *ext_priv, const char *buf, - size_t len) -{ - struct ti_eqep_cnt *priv = counter->priv; - int err; - u32 res; - - err = kstrtouint(buf, 0, &res); - if (err < 0) - return err; - - regmap_write(priv->regmap32, QPOSINIT, res); - - return len; -} - static ssize_t ti_eqep_position_enable_read(struct counter_device *counter, struct counter_count *count, void *ext_priv, char *buf) @@ -301,11 +271,6 @@ static struct counter_count_ext ti_eqep_position_ext[] = { .read = ti_eqep_position_ceiling_read, .write = ti_eqep_position_ceiling_write, }, - { - .name = "floor", - .read = ti_eqep_position_floor_read, - .write = ti_eqep_position_floor_write, - }, { .name = "enable", .read = ti_eqep_position_enable_read, -- GitLab From efd597b2839a9895e8a98fcb0b76d2f545802cd4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 9 Dec 2020 11:46:49 +0100 Subject: [PATCH 0239/1084] iio: ad5504: Fix setting power-down state The power-down mask of the ad5504 is actually a power-up mask. Meaning if a bit is set the corresponding channel is powered up and if it is not set the channel is powered down. The driver currently has this the wrong way around, resulting in the channel being powered up when requested to be powered down and vice versa. Fixes: 3bbbf150ffde ("staging:iio:dac:ad5504: Use strtobool for boolean values") Signed-off-by: Lars-Peter Clausen Acked-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20201209104649.5794-1-lars@metafoo.de Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5504.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index 28921b62e6420..e9297c25d4ef6 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -187,9 +187,9 @@ static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev, return ret; if (pwr_down) - st->pwr_down_mask |= (1 << chan->channel); - else st->pwr_down_mask &= ~(1 << chan->channel); + else + st->pwr_down_mask |= (1 << chan->channel); ret = ad5504_spi_write(st, AD5504_ADDR_CTRL, AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) | -- GitLab From 40c48fb79b9798954691f24b8ece1d3a7eb1b353 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 8 Dec 2020 15:36:40 +0100 Subject: [PATCH 0240/1084] iio: common: st_sensors: fix possible infinite loop in st_sensors_irq_thread Return a boolean value in st_sensors_new_samples_available routine in order to avoid an infinite loop in st_sensors_irq_thread if stat_drdy.addr is not defined or stat_drdy read fails Fixes: 90efe05562921 ("iio: st_sensors: harden interrupt handling") Reported-by: Jonathan Cameron Signed-off-by: Lorenzo Bianconi Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/c9ec69ed349e7200c779fd7a5bf04c1aaa2817aa.1607438132.git.lorenzo@kernel.org Cc: Signed-off-by: Jonathan Cameron --- .../common/st_sensors/st_sensors_trigger.c | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c index 0507283bd4c1d..2dbd2646e44e9 100644 --- a/drivers/iio/common/st_sensors/st_sensors_trigger.c +++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c @@ -23,35 +23,31 @@ * @sdata: Sensor data. * * returns: - * 0 - no new samples available - * 1 - new samples available - * negative - error or unknown + * false - no new samples available or read error + * true - new samples available */ -static int st_sensors_new_samples_available(struct iio_dev *indio_dev, - struct st_sensor_data *sdata) +static bool st_sensors_new_samples_available(struct iio_dev *indio_dev, + struct st_sensor_data *sdata) { int ret, status; /* How would I know if I can't check it? */ if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr) - return -EINVAL; + return true; /* No scan mask, no interrupt */ if (!indio_dev->active_scan_mask) - return 0; + return false; ret = regmap_read(sdata->regmap, sdata->sensor_settings->drdy_irq.stat_drdy.addr, &status); if (ret < 0) { dev_err(sdata->dev, "error checking samples available\n"); - return ret; + return false; } - if (status & sdata->sensor_settings->drdy_irq.stat_drdy.mask) - return 1; - - return 0; + return !!(status & sdata->sensor_settings->drdy_irq.stat_drdy.mask); } /** @@ -180,9 +176,15 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev, /* Tell the interrupt handler that we're dealing with edges */ if (irq_trig == IRQF_TRIGGER_FALLING || - irq_trig == IRQF_TRIGGER_RISING) + irq_trig == IRQF_TRIGGER_RISING) { + if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr) { + dev_err(&indio_dev->dev, + "edge IRQ not supported w/o stat register.\n"); + err = -EOPNOTSUPP; + goto iio_trigger_free; + } sdata->edge_irq = true; - else + } else { /* * If we're not using edges (i.e. level interrupts) we * just mask off the IRQ, handle one interrupt, then @@ -190,6 +192,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev, * interrupt handler top half again and start over. */ irq_trig |= IRQF_ONESHOT; + } /* * If the interrupt pin is Open Drain, by definition this -- GitLab From b8653aff1c8876142f965fc69e12ba217da13182 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 2 Dec 2020 12:02:52 -0800 Subject: [PATCH 0241/1084] iio: sx9310: Fix semtech,avg-pos-strength setting when > 16 This DT property can be 0, 16, and then 64, but not 32. The math here doesn't recognize this slight bump in the power of 2 numbers and translates a DT property of 64 into the register value '3' when it really should be '2'. Fix it by subtracting one more if the number being translated is larger than 31. Also use clamp() because we're here. Cc: Daniel Campello Cc: Lars-Peter Clausen Cc: Peter Meerwald-Stadler Cc: Douglas Anderson Cc: Gwendal Grignou Cc: Evan Green Signed-off-by: Stephen Boyd Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20201202200252.986230-1-swboyd@chromium.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/sx9310.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c index 62eacb22e9bcb..37fd0b65a0140 100644 --- a/drivers/iio/proximity/sx9310.c +++ b/drivers/iio/proximity/sx9310.c @@ -1305,7 +1305,8 @@ sx9310_get_default_reg(struct sx9310_data *data, int i, if (ret) break; - pos = min(max(ilog2(pos), 3), 10) - 3; + /* Powers of 2, except for a gap between 16 and 64 */ + pos = clamp(ilog2(pos), 3, 11) - (pos >= 32 ? 4 : 3); reg_def->def &= ~SX9310_REG_PROX_CTRL7_AVGPOSFILT_MASK; reg_def->def |= FIELD_PREP(SX9310_REG_PROX_CTRL7_AVGPOSFILT_MASK, pos); -- GitLab From c2083e280a3d4f71941c9c57992d4e621e4e33c5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 Jan 2021 09:04:49 +0100 Subject: [PATCH 0242/1084] cfg80211: fix a kerneldoc markup A function has a different name between their prototype and its kernel-doc markup: ../include/net/cfg80211.h:1766: warning: expecting prototype for struct cfg80211_sar_chan_ranges. Prototype was for struct cfg80211_sar_freq_ranges instead Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/c7ed4bc4d9e992ead16d3d2df246f3b56dbfb1fb.1610610937.git.mchehab+huawei@kernel.org Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1b3954afcda42..0d6f7ec860615 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1756,7 +1756,7 @@ struct cfg80211_sar_specs { /** - * struct cfg80211_sar_chan_ranges - sar frequency ranges + * struct cfg80211_sar_freq_ranges - sar frequency ranges * @start_freq: start range edge frequency * @end_freq: end range edge frequency */ -- GitLab From 6020d534fa012b80c6d13811dc4d2dfedca2e403 Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Tue, 12 Jan 2021 11:20:28 +0800 Subject: [PATCH 0243/1084] mac80211: fix incorrect strlen of .write in debugfs This fixes strlen mismatch problems happening in some .write callbacks of debugfs. When trying to configure airtime_flags in debugfs, an error appeared: ash: write error: Invalid argument The error is returned from kstrtou16() since a wrong length makes it miss the real end of input string. To fix this, use count as the string length, and set proper end of string for a char buffer. The debug print is shown - airtime_flags_write: count = 2, len = 8, where the actual length is 2, but "len = strlen(buf)" gets 8. Also cleanup the other similar cases for the sake of consistency. Signed-off-by: Sujuan Chen Signed-off-by: Ryder Lee Signed-off-by: Shayne Chen Link: https://lore.kernel.org/r/20210112032028.7482-1-shayne.chen@mediatek.com Signed-off-by: Johannes Berg --- net/mac80211/debugfs.c | 44 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 48f144f107d53..9e723d9434219 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -120,18 +120,17 @@ static ssize_t aqm_write(struct file *file, { struct ieee80211_local *local = file->private_data; char buf[100]; - size_t len; - if (count > sizeof(buf)) + if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; - buf[sizeof(buf) - 1] = '\0'; - len = strlen(buf); - if (len > 0 && buf[len-1] == '\n') - buf[len-1] = 0; + if (count && buf[count - 1] == '\n') + buf[count - 1] = '\0'; + else + buf[count] = '\0'; if (sscanf(buf, "fq_limit %u", &local->fq.limit) == 1) return count; @@ -177,18 +176,17 @@ static ssize_t airtime_flags_write(struct file *file, { struct ieee80211_local *local = file->private_data; char buf[16]; - size_t len; - if (count > sizeof(buf)) + if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; - buf[sizeof(buf) - 1] = 0; - len = strlen(buf); - if (len > 0 && buf[len - 1] == '\n') - buf[len - 1] = 0; + if (count && buf[count - 1] == '\n') + buf[count - 1] = '\0'; + else + buf[count] = '\0'; if (kstrtou16(buf, 0, &local->airtime_flags)) return -EINVAL; @@ -237,20 +235,19 @@ static ssize_t aql_txq_limit_write(struct file *file, { struct ieee80211_local *local = file->private_data; char buf[100]; - size_t len; u32 ac, q_limit_low, q_limit_high, q_limit_low_old, q_limit_high_old; struct sta_info *sta; - if (count > sizeof(buf)) + if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; - buf[sizeof(buf) - 1] = 0; - len = strlen(buf); - if (len > 0 && buf[len - 1] == '\n') - buf[len - 1] = 0; + if (count && buf[count - 1] == '\n') + buf[count - 1] = '\0'; + else + buf[count] = '\0'; if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3) return -EINVAL; @@ -306,18 +303,17 @@ static ssize_t force_tx_status_write(struct file *file, { struct ieee80211_local *local = file->private_data; char buf[3]; - size_t len; - if (count > sizeof(buf)) + if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; - buf[sizeof(buf) - 1] = '\0'; - len = strlen(buf); - if (len > 0 && buf[len - 1] == '\n') - buf[len - 1] = 0; + if (count && buf[count - 1] == '\n') + buf[count - 1] = '\0'; + else + buf[count] = '\0'; if (buf[0] == '0' && buf[1] == '\0') local->force_tx_status = 0; -- GitLab From 622d3b4e39381262da7b18ca1ed1311df227de86 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 18 Dec 2020 19:47:17 +0100 Subject: [PATCH 0244/1084] mac80211: fix fast-rx encryption check When using WEP, the default unicast key needs to be selected, instead of the STA PTK. Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20201218184718.93650-5-nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 13b9bcc4865de..972895e9f22dc 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -4176,6 +4176,8 @@ void ieee80211_check_fast_rx(struct sta_info *sta) rcu_read_lock(); key = rcu_dereference(sta->ptk[sta->ptk_idx]); + if (!key) + key = rcu_dereference(sdata->default_unicast_key); if (key) { switch (key->conf.cipher) { case WLAN_CIPHER_SUITE_TKIP: -- GitLab From b101dd2d22f45d203010b40c739df346a0cbebef Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 18 Dec 2020 19:47:16 +0100 Subject: [PATCH 0245/1084] mac80211: fix encryption key selection for 802.3 xmit When using WEP, the default unicast key needs to be selected, instead of the STA PTK. Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20201218184718.93650-4-nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 6422da6690f79..2d606dbab37c3 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -4251,7 +4251,6 @@ netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct ethhdr *ehdr = (struct ethhdr *)skb->data; struct ieee80211_key *key; struct sta_info *sta; - bool offload = true; if (unlikely(skb->len < ETH_HLEN)) { kfree_skb(skb); @@ -4267,18 +4266,22 @@ netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded || !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || - sdata->control_port_protocol == ehdr->h_proto)) - offload = false; - else if ((key = rcu_dereference(sta->ptk[sta->ptk_idx])) && - (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) || - key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) - offload = false; - - if (offload) - ieee80211_8023_xmit(sdata, dev, sta, key, skb); - else - ieee80211_subif_start_xmit(skb, dev); + sdata->control_port_protocol == ehdr->h_proto)) + goto skip_offload; + + key = rcu_dereference(sta->ptk[sta->ptk_idx]); + if (!key) + key = rcu_dereference(sdata->default_unicast_key); + + if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) || + key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) + goto skip_offload; + + ieee80211_8023_xmit(sdata, dev, sta, key, skb); + goto out; +skip_offload: + ieee80211_subif_start_xmit(skb, dev); out: rcu_read_unlock(); -- GitLab From 2463ec86cd0338a2c2edbfb0b9d50c52ff76ff43 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 18 Dec 2020 20:15:25 +0100 Subject: [PATCH 0246/1084] mac80211: do not drop tx nulldata packets on encrypted links ieee80211_tx_h_select_key drops any non-mgmt packets without a key when encryption is used. This is wrong for nulldata packets that can't be encrypted and are sent out for probing clients and indicating 4-address mode. Reported-by: Sebastian Gottschall Fixes: a0761a301746 ("mac80211: drop data frames without key on encrypted links") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20201218191525.1168-1-nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2d606dbab37c3..de8325c79dd5b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -649,7 +649,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) if (!skip_hw && tx->key && tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) info->control.hw_key = &tx->key->conf; - } else if (!ieee80211_is_mgmt(hdr->frame_control) && tx->sta && + } else if (ieee80211_is_data_present(hdr->frame_control) && tx->sta && test_sta_flag(tx->sta, WLAN_STA_USES_ENCRYPTION)) { return TX_DROP; } -- GitLab From c13cf5c159660451c8fbdc37efb998b198e1d305 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 26 Dec 2020 10:39:08 +0100 Subject: [PATCH 0247/1084] mac80211: check if atf has been disabled in __ieee80211_schedule_txq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check if atf has been disabled in __ieee80211_schedule_txq() in order to avoid a given sta is always put to the beginning of the active_txqs list and never moved to the end since deficit is not decremented in ieee80211_sta_register_airtime() Fixes: b4809e9484da1 ("mac80211: Add airtime accounting and scheduling to TXQs") Signed-off-by: Lorenzo Bianconi Acked-by: Toke Høiland-Jørgensen Link: https://lore.kernel.org/r/93889406c50f1416214c079ca0b8c9faecc5143e.1608975195.git.lorenzo@kernel.org Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index de8325c79dd5b..ebb3228ce9718 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3809,7 +3809,7 @@ void __ieee80211_schedule_txq(struct ieee80211_hw *hw, * get immediately moved to the back of the list on the next * call to ieee80211_next_txq(). */ - if (txqi->txq.sta && + if (txqi->txq.sta && local->airtime_flags && wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) list_add(&txqi->schedule_order, -- GitLab From 780e1384687d6ecdee9ca789a1027610484ac8a2 Mon Sep 17 00:00:00 2001 From: Shin'ichiro Kawasaki Date: Wed, 13 Jan 2021 11:45:08 +0900 Subject: [PATCH 0248/1084] scsi: target: tcmu: Fix use-after-free of se_cmd->priv Commit a35129024e88 ("scsi: target: tcmu: Use priv pointer in se_cmd") modified tcmu_free_cmd() to set NULL to priv pointer in se_cmd. However, se_cmd can be already freed by work queue triggered in target_complete_cmd(). This caused BUG KASAN use-after-free [1]. To fix the bug, do not touch priv pointer in tcmu_free_cmd(). Instead, set NULL to priv pointer before target_complete_cmd() calls. Also, to avoid unnecessary priv pointer change in tcmu_queue_cmd(), modify priv pointer in the function only when tcmu_free_cmd() is not called. [1] BUG: KASAN: use-after-free in tcmu_handle_completions+0x1172/0x1770 [target_core_user] Write of size 8 at addr ffff88814cf79a40 by task cmdproc-uio0/14842 CPU: 2 PID: 14842 Comm: cmdproc-uio0 Not tainted 5.11.0-rc2 #1 Hardware name: Supermicro Super Server/X10SRL-F, BIOS 3.2 11/22/2019 Call Trace: dump_stack+0x9a/0xcc ? tcmu_handle_completions+0x1172/0x1770 [target_core_user] print_address_description.constprop.0+0x18/0x130 ? tcmu_handle_completions+0x1172/0x1770 [target_core_user] ? tcmu_handle_completions+0x1172/0x1770 [target_core_user] kasan_report.cold+0x7f/0x10e ? tcmu_handle_completions+0x1172/0x1770 [target_core_user] tcmu_handle_completions+0x1172/0x1770 [target_core_user] ? queue_tmr_ring+0x5d0/0x5d0 [target_core_user] tcmu_irqcontrol+0x28/0x60 [target_core_user] uio_write+0x155/0x230 ? uio_vma_fault+0x460/0x460 ? security_file_permission+0x4f/0x440 vfs_write+0x1ce/0x860 ksys_write+0xe9/0x1b0 ? __ia32_sys_read+0xb0/0xb0 ? syscall_enter_from_user_mode+0x27/0x70 ? trace_hardirqs_on+0x1c/0x110 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7fcf8b61905f Code: 89 54 24 18 48 89 74 24 10 89 7c 24 08 e8 b9 fc ff ff 48 8b 54 24 18 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 31 44 89 c7 48 89 44 24 08 e8 0c fd ff ff 48 RSP: 002b:00007fcf7b3e6c30 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fcf8b61905f RDX: 0000000000000004 RSI: 00007fcf7b3e6c78 RDI: 000000000000000c RBP: 00007fcf7b3e6c80 R08: 0000000000000000 R09: 00007fcf7b3e6aa8 R10: 000000000b01c000 R11: 0000000000000293 R12: 00007ffe0c32a52e R13: 00007ffe0c32a52f R14: 0000000000000000 R15: 00007fcf7b3e7640 Allocated by task 383: kasan_save_stack+0x1b/0x40 ____kasan_kmalloc.constprop.0+0x84/0xa0 kmem_cache_alloc+0x142/0x330 tcm_loop_queuecommand+0x2a/0x4e0 [tcm_loop] scsi_queue_rq+0x12ec/0x2d20 blk_mq_dispatch_rq_list+0x30a/0x1db0 __blk_mq_do_dispatch_sched+0x326/0x830 __blk_mq_sched_dispatch_requests+0x2c8/0x3f0 blk_mq_sched_dispatch_requests+0xca/0x120 __blk_mq_run_hw_queue+0x93/0xe0 process_one_work+0x7b6/0x1290 worker_thread+0x590/0xf80 kthread+0x362/0x430 ret_from_fork+0x22/0x30 Freed by task 11655: kasan_save_stack+0x1b/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x20/0x30 ____kasan_slab_free+0xec/0x120 slab_free_freelist_hook+0x53/0x160 kmem_cache_free+0xf4/0x5c0 target_release_cmd_kref+0x3ea/0x9e0 [target_core_mod] transport_generic_free_cmd+0x28b/0x2f0 [target_core_mod] target_complete_ok_work+0x250/0xac0 [target_core_mod] process_one_work+0x7b6/0x1290 worker_thread+0x590/0xf80 kthread+0x362/0x430 ret_from_fork+0x22/0x30 Last potentially related work creation: kasan_save_stack+0x1b/0x40 kasan_record_aux_stack+0xa3/0xb0 insert_work+0x48/0x2e0 __queue_work+0x4e8/0xdf0 queue_work_on+0x78/0x80 tcmu_handle_completions+0xad0/0x1770 [target_core_user] tcmu_irqcontrol+0x28/0x60 [target_core_user] uio_write+0x155/0x230 vfs_write+0x1ce/0x860 ksys_write+0xe9/0x1b0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Second to last potentially related work creation: kasan_save_stack+0x1b/0x40 kasan_record_aux_stack+0xa3/0xb0 insert_work+0x48/0x2e0 __queue_work+0x4e8/0xdf0 queue_work_on+0x78/0x80 tcm_loop_queuecommand+0x1c3/0x4e0 [tcm_loop] scsi_queue_rq+0x12ec/0x2d20 blk_mq_dispatch_rq_list+0x30a/0x1db0 __blk_mq_do_dispatch_sched+0x326/0x830 __blk_mq_sched_dispatch_requests+0x2c8/0x3f0 blk_mq_sched_dispatch_requests+0xca/0x120 __blk_mq_run_hw_queue+0x93/0xe0 process_one_work+0x7b6/0x1290 worker_thread+0x590/0xf80 kthread+0x362/0x430 ret_from_fork+0x22/0x30 The buggy address belongs to the object at ffff88814cf79800 which belongs to the cache tcm_loop_cmd_cache of size 896. Link: https://lore.kernel.org/r/20210113024508.1264992-1-shinichiro.kawasaki@wdc.com Fixes: a35129024e88 ("scsi: target: tcmu: Use priv pointer in se_cmd") Cc: stable@vger.kernel.org # v5.9+ Acked-by: Bodo Stroesser Signed-off-by: Shin'ichiro Kawasaki Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 6b171fff007b6..a5991df235811 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -562,8 +562,6 @@ tcmu_get_block_page(struct tcmu_dev *udev, uint32_t dbi) static inline void tcmu_free_cmd(struct tcmu_cmd *tcmu_cmd) { - if (tcmu_cmd->se_cmd) - tcmu_cmd->se_cmd->priv = NULL; kfree(tcmu_cmd->dbi); kmem_cache_free(tcmu_cmd_cache, tcmu_cmd); } @@ -1174,11 +1172,12 @@ tcmu_queue_cmd(struct se_cmd *se_cmd) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; mutex_lock(&udev->cmdr_lock); - se_cmd->priv = tcmu_cmd; if (!(se_cmd->transport_state & CMD_T_ABORTED)) ret = queue_cmd_ring(tcmu_cmd, &scsi_ret); if (ret < 0) tcmu_free_cmd(tcmu_cmd); + else + se_cmd->priv = tcmu_cmd; mutex_unlock(&udev->cmdr_lock); return scsi_ret; } @@ -1241,6 +1240,7 @@ tcmu_tmr_notify(struct se_device *se_dev, enum tcm_tmreq_table tmf, list_del_init(&cmd->queue_entry); tcmu_free_cmd(cmd); + se_cmd->priv = NULL; target_complete_cmd(se_cmd, SAM_STAT_TASK_ABORTED); unqueued = true; } @@ -1332,6 +1332,7 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry * } done: + se_cmd->priv = NULL; if (read_len_valid) { pr_debug("read_len = %d\n", read_len); target_complete_cmd_with_length(cmd->se_cmd, @@ -1478,6 +1479,7 @@ static void tcmu_check_expired_queue_cmd(struct tcmu_cmd *cmd) se_cmd = cmd->se_cmd; tcmu_free_cmd(cmd); + se_cmd->priv = NULL; target_complete_cmd(se_cmd, SAM_STAT_TASK_SET_FULL); } @@ -1592,6 +1594,7 @@ static void run_qfull_queue(struct tcmu_dev *udev, bool fail) * removed then LIO core will do the right thing and * fail the retry. */ + tcmu_cmd->se_cmd->priv = NULL; target_complete_cmd(tcmu_cmd->se_cmd, SAM_STAT_BUSY); tcmu_free_cmd(tcmu_cmd); continue; @@ -1605,6 +1608,7 @@ static void run_qfull_queue(struct tcmu_dev *udev, bool fail) * Ignore scsi_ret for now. target_complete_cmd * drops it. */ + tcmu_cmd->se_cmd->priv = NULL; target_complete_cmd(tcmu_cmd->se_cmd, SAM_STAT_CHECK_CONDITION); tcmu_free_cmd(tcmu_cmd); @@ -2212,6 +2216,7 @@ static void tcmu_reset_ring(struct tcmu_dev *udev, u8 err_level) if (!test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)) { WARN_ON(!cmd->se_cmd); list_del_init(&cmd->queue_entry); + cmd->se_cmd->priv = NULL; if (err_level == 1) { /* * Userspace was not able to start the -- GitLab From 764907293edc1af7ac857389af9dc858944f53dc Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 12 Jan 2021 09:06:38 -0600 Subject: [PATCH 0249/1084] scsi: ibmvfc: Set default timeout to avoid crash during migration While testing live partition mobility, we have observed occasional crashes of the Linux partition. What we've seen is that during the live migration, for specific configurations with large amounts of memory, slow network links, and workloads that are changing memory a lot, the partition can end up being suspended for 30 seconds or longer. This resulted in the following scenario: CPU 0 CPU 1 ------------------------------- ---------------------------------- scsi_queue_rq migration_store -> blk_mq_start_request -> rtas_ibm_suspend_me -> blk_add_timer -> on_each_cpu(rtas_percpu_suspend_me _______________________________________V | V -> IPI from CPU 1 -> rtas_percpu_suspend_me -> __rtas_suspend_last_cpu -- Linux partition suspended for > 30 seconds -- -> for_each_online_cpu(cpu) plpar_hcall_norets(H_PROD -> scsi_dispatch_cmd -> scsi_times_out -> scsi_abort_command -> queue_delayed_work -> ibmvfc_queuecommand_lck -> ibmvfc_send_event -> ibmvfc_send_crq - returns H_CLOSED <- returns SCSI_MLQUEUE_HOST_BUSY -> __blk_mq_requeue_request -> scmd_eh_abort_handler -> scsi_try_to_abort_cmd - returns SUCCESS -> scsi_queue_insert Normally, the SCMD_STATE_COMPLETE bit would protect against the command completion and the timeout, but that doesn't work here, since we don't check that at all in the SCSI_MLQUEUE_HOST_BUSY path. In this case we end up calling scsi_queue_insert on a request that has already been queued, or possibly even freed, and we crash. The patch below simply increases the default I/O timeout to avoid this race condition. This is also the timeout value that nearly all IBM SAN storage recommends setting as the default value. Link: https://lore.kernel.org/r/1610463998-19791-1-git-send-email-brking@linux.vnet.ibm.com Signed-off-by: Brian King Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvfc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 7312f31df878c..65f168c41d233 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -3007,8 +3007,10 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev) unsigned long flags = 0; spin_lock_irqsave(shost->host_lock, flags); - if (sdev->type == TYPE_DISK) + if (sdev->type == TYPE_DISK) { sdev->allow_restart = 1; + blk_queue_rq_timeout(sdev->request_queue, 120 * HZ); + } spin_unlock_irqrestore(shost->host_lock, flags); return 0; } -- GitLab From 668af87f995b6d6d09595c088ad1fb5dd9ff25d2 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Wed, 13 Jan 2021 15:48:34 +0106 Subject: [PATCH 0250/1084] printk: ringbuffer: fix line counting Counting text lines in a record simply involves counting the number of newline characters (+1). However, it is searching the full data block for newline characters, even though the text data can be (and often is) a subset of that area. Since the extra area in the data block was never initialized, the result is that extra newlines may be seen and counted. Restrict newline searching to the text data length. Fixes: b6cf8b3f3312 ("printk: add lockless ringbuffer") Signed-off-by: John Ogness Reviewed-by: Petr Mladek Acked-by: Sergey Senozhatsky Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20210113144234.6545-1-john.ogness@linutronix.de --- kernel/printk/printk_ringbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringbuffer.c index 74e25a1704f2b..617dd63589650 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -1720,7 +1720,7 @@ static bool copy_data(struct prb_data_ring *data_ring, /* Caller interested in the line count? */ if (line_count) - *line_count = count_lines(data, data_size); + *line_count = count_lines(data, len); /* Caller interested in the data content? */ if (!buf || !buf_size) -- GitLab From 89ccf18f032f26946e2ea6258120472eec6aa745 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Wed, 13 Jan 2021 17:50:13 +0106 Subject: [PATCH 0251/1084] printk: fix kmsg_dump_get_buffer length calulations kmsg_dump_get_buffer() uses @syslog to determine if the syslog prefix should be written to the buffer. However, when calculating the maximum number of records that can fit into the buffer, it always counts the bytes from the syslog prefix. Use @syslog when calculating the maximum number of records that can fit into the buffer. Fixes: e2ae715d66bf ("kmsg - kmsg_dump() use iterator to receive log buffer content") Signed-off-by: John Ogness Reviewed-by: Petr Mladek Acked-by: Sergey Senozhatsky Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20210113164413.1599-1-john.ogness@linutronix.de --- kernel/printk/printk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index c8847ee571f0e..96e24074c9626 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3423,7 +3423,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, while (prb_read_valid_info(prb, seq, &info, &line_count)) { if (r.info->seq >= dumper->next_seq) break; - l += get_record_print_text_size(&info, line_count, true, time); + l += get_record_print_text_size(&info, line_count, syslog, time); seq = r.info->seq + 1; } @@ -3433,7 +3433,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, &info, &line_count)) { if (r.info->seq >= dumper->next_seq) break; - l -= get_record_print_text_size(&info, line_count, true, time); + l -= get_record_print_text_size(&info, line_count, syslog, time); seq = r.info->seq + 1; } -- GitLab From 06862d789ddde8a99c1e579e934ca17c15a84755 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Sun, 10 Jan 2021 21:09:11 +0200 Subject: [PATCH 0252/1084] ARM: OMAP2+: Fix suspcious RCU usage splats for omap_enter_idle_coupled We get suspcious RCU usage splats with cpuidle in several places in omap_enter_idle_coupled() with the kernel debug options enabled: RCU used illegally from extended quiescent state! ... (_raw_spin_lock_irqsave) (omap_enter_idle_coupled+0x17c/0x2d8) (omap_enter_idle_coupled) (cpuidle_enter_state) (cpuidle_enter_state_coupled) (cpuidle_enter) Let's use RCU_NONIDLE to suppress these splats. Things got changed around with commit 1098582a0f6c ("sched,idle,rcu: Push rcu_idle deeper into the idle path") that started triggering these warnings. For the tick_broadcast related calls, ideally we'd just switch over to using CPUIDLE_FLAG_TIMER_STOP for omap_enter_idle_coupled() to have the generic cpuidle code handle the tick_broadcast related calls for us and then just drop the tick_broadcast calls here. But we're currently missing the call in the common cpuidle code for tick_broadcast_enable() that CPU1 hotplug needs as described in earlier commit 50d6b3cf9403 ("ARM: OMAP2+: fix lack of timer interrupts on CPU1 after hotplug"). Cc: Daniel Lezcano Cc: Paul E. McKenney Cc: Russell King Acked-by: Paul E. McKenney Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/cpuidle44xx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index c8d317fafe2ea..de37027ad7587 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -151,10 +151,10 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, (cx->mpu_logic_state == PWRDM_POWER_OFF); /* Enter broadcast mode for periodic timers */ - tick_broadcast_enable(); + RCU_NONIDLE(tick_broadcast_enable()); /* Enter broadcast mode for one-shot timers */ - tick_broadcast_enter(); + RCU_NONIDLE(tick_broadcast_enter()); /* * Call idle CPU PM enter notifier chain so that @@ -166,7 +166,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, if (dev->cpu == 0) { pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); - omap_set_pwrdm_state(mpu_pd, cx->mpu_state); + RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state)); /* * Call idle CPU cluster PM enter notifier chain @@ -178,7 +178,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, index = 0; cx = state_ptr + index; pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); - omap_set_pwrdm_state(mpu_pd, cx->mpu_state); + RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state)); mpuss_can_lose_context = 0; } } @@ -194,9 +194,9 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, mpuss_can_lose_context) gic_dist_disable(); - clkdm_deny_idle(cpu_clkdm[1]); - omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON); - clkdm_allow_idle(cpu_clkdm[1]); + RCU_NONIDLE(clkdm_deny_idle(cpu_clkdm[1])); + RCU_NONIDLE(omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON)); + RCU_NONIDLE(clkdm_allow_idle(cpu_clkdm[1])); if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) && mpuss_can_lose_context) { @@ -222,7 +222,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, cpu_pm_exit(); cpu_pm_out: - tick_broadcast_exit(); + RCU_NONIDLE(tick_broadcast_exit()); fail: cpuidle_coupled_parallel_barrier(dev, &abort_barrier); -- GitLab From 2a39af3870e99304df81d2a4058408d68efb02e0 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 15 Jan 2021 10:06:12 +0200 Subject: [PATCH 0253/1084] ARM: OMAP2+: Fix booting for am335x after moving to simple-pm-bus We now depend on SIMPLE_PM_BUS for probing devices. While we have it selected in omap2plus_defconfig, custom configs can fail if it's missing. As SIMPLE_PM_BUS depends on OF and PM, we must now select PM in Kconfig. We have already OF selected by ARCH_MULTIPLATFORM. Let's also drop the earlier PM dependency entries as suggested by Geert Uytterhoeven . Reported-by: Geert Uytterhoeven Reported-by: Matti Vaittinen Fixes: 5a230524f879 ("ARM: dts: Use simple-pm-bus for genpd for am3 l4_wkup") Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 4a59c169a1139..4178c0ee46eba 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -17,11 +17,10 @@ config ARCH_OMAP3 bool "TI OMAP3" depends on ARCH_MULTI_V7 select ARCH_OMAP2PLUS - select ARM_CPU_SUSPEND if PM + select ARM_CPU_SUSPEND select OMAP_HWMOD select OMAP_INTERCONNECT - select PM_OPP if PM - select PM if CPU_IDLE + select PM_OPP select SOC_HAS_OMAP2_SDRC select ARM_ERRATA_430973 @@ -30,7 +29,7 @@ config ARCH_OMAP4 depends on ARCH_MULTI_V7 select ARCH_OMAP2PLUS select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP - select ARM_CPU_SUSPEND if PM + select ARM_CPU_SUSPEND select ARM_ERRATA_720789 select ARM_GIC select HAVE_ARM_SCU if SMP @@ -40,7 +39,7 @@ config ARCH_OMAP4 select OMAP_INTERCONNECT_BARRIER select PL310_ERRATA_588369 if CACHE_L2X0 select PL310_ERRATA_727915 if CACHE_L2X0 - select PM_OPP if PM + select PM_OPP select PM if CPU_IDLE select ARM_ERRATA_754322 select ARM_ERRATA_775420 @@ -50,7 +49,7 @@ config SOC_OMAP5 bool "TI OMAP5" depends on ARCH_MULTI_V7 select ARCH_OMAP2PLUS - select ARM_CPU_SUSPEND if PM + select ARM_CPU_SUSPEND select ARM_GIC select HAVE_ARM_SCU if SMP select HAVE_ARM_ARCH_TIMER @@ -58,14 +57,14 @@ config SOC_OMAP5 select OMAP_HWMOD select OMAP_INTERCONNECT select OMAP_INTERCONNECT_BARRIER - select PM_OPP if PM + select PM_OPP select ZONE_DMA if ARM_LPAE config SOC_AM33XX bool "TI AM33XX" depends on ARCH_MULTI_V7 select ARCH_OMAP2PLUS - select ARM_CPU_SUSPEND if PM + select ARM_CPU_SUSPEND config SOC_AM43XX bool "TI AM43x" @@ -79,13 +78,13 @@ config SOC_AM43XX select ARM_ERRATA_754322 select ARM_ERRATA_775420 select OMAP_INTERCONNECT - select ARM_CPU_SUSPEND if PM + select ARM_CPU_SUSPEND config SOC_DRA7XX bool "TI DRA7XX" depends on ARCH_MULTI_V7 select ARCH_OMAP2PLUS - select ARM_CPU_SUSPEND if PM + select ARM_CPU_SUSPEND select ARM_GIC select HAVE_ARM_SCU if SMP select HAVE_ARM_ARCH_TIMER @@ -94,7 +93,7 @@ config SOC_DRA7XX select OMAP_HWMOD select OMAP_INTERCONNECT select OMAP_INTERCONNECT_BARRIER - select PM_OPP if PM + select PM_OPP select ZONE_DMA if ARM_LPAE select PINCTRL_TI_IODELAY if OF && PINCTRL @@ -112,9 +111,11 @@ config ARCH_OMAP2PLUS select OMAP_DM_TIMER select OMAP_GPMC select PINCTRL - select PM_GENERIC_DOMAINS if PM - select PM_GENERIC_DOMAINS_OF if PM + select PM + select PM_GENERIC_DOMAINS + select PM_GENERIC_DOMAINS_OF select RESET_CONTROLLER + select SIMPLE_PM_BUS select SOC_BUS select TI_SYSC select OMAP_IRQCHIP @@ -140,7 +141,6 @@ config ARCH_OMAP2PLUS_TYPICAL select I2C_OMAP select MENELAUS if ARCH_OMAP2 select NEON if CPU_V7 - select PM select REGULATOR select REGULATOR_FIXED_VOLTAGE select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4 -- GitLab From eda080eabf5b9555e4d574ba035b0cb8aa42f052 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 15 Jan 2021 10:47:17 +0200 Subject: [PATCH 0254/1084] drivers: bus: simple-pm-bus: Fix compatibility with simple-bus for auxdata After converting am335x to probe devices with simple-pm-bus I noticed that we are not passing auxdata for of_platform_populate() like we do with simple-bus. While device tree using SoCs should no longer need platform data, there are still quite a few drivers that still need it as can be seen with git grep OF_DEV_AUXDATA. We want to have simple-pm-bus be usable as a replacement for simple-bus also for cases where OF_DEV_AUXDATA is still needed. Let's fix the issue by passing auxdata as platform data to simple-pm-bus. That way the SoCs needing this can pass the auxdata with OF_DEV_AUXDATA. And let's pass the auxdata for omaps to fix the issue for am335x. As an alternative solution, adding simple-pm-bus handling directly to drivers/of/platform.c was considered, but we would still need simple-pm-bus device driver. So passing auxdata as platform data seems like the simplest solution. Fixes: 5a230524f879 ("ARM: dts: Use simple-pm-bus for genpd for am3 l4_wkup") Acked-by: Arnd Bergmann Reviewed-by: Geert Uytterhoeven Acked-by: Geert Uytterhoeven Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pdata-quirks.c | 1 + drivers/bus/simple-pm-bus.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index cd38bf07c094d..2e3a10914c40a 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -522,6 +522,7 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = { &dra7_ipu1_dsp_iommu_pdata), #endif /* Common auxdata */ + OF_DEV_AUXDATA("simple-pm-bus", 0, NULL, omap_auxdata_lookup), OF_DEV_AUXDATA("ti,sysc", 0, NULL, &ti_sysc_pdata), OF_DEV_AUXDATA("pinctrl-single", 0, NULL, &pcs_pdata), OF_DEV_AUXDATA("ti,omap-prm-inst", 0, NULL, &ti_prm_pdata), diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c index c5eb46cbf388b..01a3d0cd08edc 100644 --- a/drivers/bus/simple-pm-bus.c +++ b/drivers/bus/simple-pm-bus.c @@ -16,6 +16,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev) { + const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev); struct device_node *np = pdev->dev.of_node; dev_dbg(&pdev->dev, "%s\n", __func__); @@ -23,7 +24,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); if (np) - of_platform_populate(np, NULL, NULL, &pdev->dev); + of_platform_populate(np, NULL, lookup, &pdev->dev); return 0; } -- GitLab From b503087445ce7e45fabdee87ca9e460d5b5b5168 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 14 Jan 2021 12:14:05 -0800 Subject: [PATCH 0255/1084] mmc: core: don't initialize block size from ext_csd if not present If extended CSD was not available, the eMMC driver would incorrectly set the block size to 0, as the data_sector_size field of ext_csd was never initialized. This issue was exposed by commit 817046ecddbc ("block: Align max_hw_sectors to logical blocksize") which caused max_sectors and max_hw_sectors to be set to 0 after setting the block size to 0, resulting in a kernel panic in bio_split when attempting to read from the device. Fix it by only reading the block size from ext_csd if it is available. Fixes: a5075eb94837 ("mmc: block: Allow disabling 512B sector size emulation") Signed-off-by: Peter Collingbourne Reviewed-by: Damien Le Moal Link: https://linux-review.googlesource.com/id/If244d178da4d86b52034459438fec295b02d6e60 Acked-by: Adrian Hunter Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210114201405.2934886-1-pcc@google.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/queue.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index de7cb0369c308..002426e3cf76c 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -384,8 +384,10 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card) "merging was advertised but not possible"); blk_queue_max_segments(mq->queue, mmc_get_max_segments(host)); - if (mmc_card_mmc(card)) + if (mmc_card_mmc(card) && card->ext_csd.data_sector_size) { block_size = card->ext_csd.data_sector_size; + WARN_ON(block_size != 512 && block_size != 4096); + } blk_queue_logical_block_size(mq->queue, block_size); /* -- GitLab From 4d163ad79b155c71bf30366dc38f8d2502f78844 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 14 Jan 2021 17:42:17 +0200 Subject: [PATCH 0256/1084] spi: cadence: cache reference clock rate during probe The issue is that using SPI from a callback under the CCF lock will deadlock, since this code uses clk_get_rate(). Fixes: c474b38665463 ("spi: Add driver for Cadence SPI controller") Signed-off-by: Michael Hennerich Signed-off-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20210114154217.51996-1-alexandru.ardelean@analog.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 70467b9d61baa..a3afd1b9ac567 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -115,6 +115,7 @@ struct cdns_spi { void __iomem *regs; struct clk *ref_clk; struct clk *pclk; + unsigned int clk_rate; u32 speed_hz; const u8 *txbuf; u8 *rxbuf; @@ -250,7 +251,7 @@ static void cdns_spi_config_clock_freq(struct spi_device *spi, u32 ctrl_reg, baud_rate_val; unsigned long frequency; - frequency = clk_get_rate(xspi->ref_clk); + frequency = xspi->clk_rate; ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR); @@ -558,8 +559,9 @@ static int cdns_spi_probe(struct platform_device *pdev) master->auto_runtime_pm = true; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + xspi->clk_rate = clk_get_rate(xspi->ref_clk); /* Set to default valid value */ - master->max_speed_hz = clk_get_rate(xspi->ref_clk) / 4; + master->max_speed_hz = xspi->clk_rate / 4; xspi->speed_hz = master->max_speed_hz; master->bits_per_word_mask = SPI_BPW_MASK(8); -- GitLab From 16117beb16f01a470d40339960ffae1e287c03be Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 14 Jan 2021 19:43:24 -0800 Subject: [PATCH 0257/1084] ASoC: qcom: Remove useless debug print This looks like a left over debug print that tells us that HDMI is enabled. Let's remove it as that's definitely not an error to have HDMI enabled. Cc: V Sujith Kumar Reddy Cc: Srinivasa Rao Cc: Srinivas Kandagatla Cc: Cheng-Yi Chiang Fixes: 7cb37b7bd0d3 ("ASoC: qcom: Add support for lpass hdmi driver") Signed-off-by: Stephen Boyd Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210115034327.617223-2-swboyd@chromium.org Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-cpu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index af684fd19ab9e..8437ba31a306d 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -742,7 +742,6 @@ static void of_lpass_cpu_parse_dai_data(struct device *dev, } if (id == LPASS_DP_RX) { data->hdmi_port_enable = 1; - dev_err(dev, "HDMI Port is enabled: %d\n", id); } else { data->mi2s_playback_sd_mode[id] = of_lpass_cpu_parse_sd_lines(dev, node, -- GitLab From 03b49bf9a92b18bbfcc3b5eb206cca8447e9f2cb Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 14 Jan 2021 19:43:25 -0800 Subject: [PATCH 0258/1084] ASoC: qcom: Add some names to regmap configs This device can sometimes have multiple regmaps. Let's add a name so that we can differentiate in debugfs more easily. Cc: V Sujith Kumar Reddy Cc: Srinivasa Rao Cc: Srinivas Kandagatla Cc: Cheng-Yi Chiang Signed-off-by: Stephen Boyd Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210115034327.617223-3-swboyd@chromium.org Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-cpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 8437ba31a306d..40126202a4a31 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -474,6 +474,7 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg) } static struct regmap_config lpass_cpu_regmap_config = { + .name = "lpass_cpu", .reg_bits = 32, .reg_stride = 4, .val_bits = 32, @@ -674,6 +675,7 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg) } static struct regmap_config lpass_hdmi_regmap_config = { + .name = "lpass_hdmi", .reg_bits = 32, .reg_stride = 4, .val_bits = 32, -- GitLab From e697df66876c182927899950971c3b4888df3e6e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 14 Jan 2021 19:43:26 -0800 Subject: [PATCH 0259/1084] ASoC: qcom: Stop casting away __iomem for error pointers We don't need to cast away __iomem when testing with IS_ERR() or converting with PTR_ERR(). Modern sparse can handle this just fine. Drop it. Cc: V Sujith Kumar Reddy Cc: Srinivasa Rao Cc: Srinivas Kandagatla Cc: Cheng-Yi Chiang Signed-off-by: Stephen Boyd Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210115034327.617223-4-swboyd@chromium.org Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-cpu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 40126202a4a31..b267fe8db3fca 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -788,10 +788,10 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif"); drvdata->lpaif = devm_ioremap_resource(dev, res); - if (IS_ERR((void const __force *)drvdata->lpaif)) { + if (IS_ERR(drvdata->lpaif)) { dev_err(dev, "error mapping reg resource: %ld\n", - PTR_ERR((void const __force *)drvdata->lpaif)); - return PTR_ERR((void const __force *)drvdata->lpaif); + PTR_ERR(drvdata->lpaif)); + return PTR_ERR(drvdata->lpaif); } lpass_cpu_regmap_config.max_register = LPAIF_WRDMAPER_REG(variant, @@ -810,10 +810,10 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-hdmiif"); drvdata->hdmiif = devm_ioremap_resource(dev, res); - if (IS_ERR((void const __force *)drvdata->hdmiif)) { + if (IS_ERR(drvdata->hdmiif)) { dev_err(dev, "error mapping reg resource: %ld\n", - PTR_ERR((void const __force *)drvdata->hdmiif)); - return PTR_ERR((void const __force *)drvdata->hdmiif); + PTR_ERR(drvdata->hdmiif)); + return PTR_ERR(drvdata->hdmiif); } lpass_hdmi_regmap_config.max_register = LPAIF_HDMI_RDMAPER_REG(variant, -- GitLab From 4e15f5060d34dd28591cf3af43d3086a4b76c965 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 14 Jan 2021 19:43:27 -0800 Subject: [PATCH 0260/1084] ASoC: qcom: Remove duplicate error messages on ioremap We don't need to print an error message when these ioremap operations fail. The function that returns an error already prints an error message and properly attributes it to the device. Drop them to save some code. Cc: V Sujith Kumar Reddy Cc: Srinivasa Rao Cc: Srinivas Kandagatla Cc: Cheng-Yi Chiang Signed-off-by: Stephen Boyd Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210115034327.617223-5-swboyd@chromium.org Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-cpu.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index b267fe8db3fca..0ca957dcd3fe5 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -788,11 +788,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif"); drvdata->lpaif = devm_ioremap_resource(dev, res); - if (IS_ERR(drvdata->lpaif)) { - dev_err(dev, "error mapping reg resource: %ld\n", - PTR_ERR(drvdata->lpaif)); + if (IS_ERR(drvdata->lpaif)) return PTR_ERR(drvdata->lpaif); - } lpass_cpu_regmap_config.max_register = LPAIF_WRDMAPER_REG(variant, variant->wrdma_channels + @@ -810,11 +807,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-hdmiif"); drvdata->hdmiif = devm_ioremap_resource(dev, res); - if (IS_ERR(drvdata->hdmiif)) { - dev_err(dev, "error mapping reg resource: %ld\n", - PTR_ERR(drvdata->hdmiif)); + if (IS_ERR(drvdata->hdmiif)) return PTR_ERR(drvdata->hdmiif); - } lpass_hdmi_regmap_config.max_register = LPAIF_HDMI_RDMAPER_REG(variant, variant->hdmi_rdma_channels); -- GitLab From 7ef8c9edc86cff0881b2eb9a3274796258fbd872 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 15 Jan 2021 14:16:50 +0800 Subject: [PATCH 0261/1084] ASoC: codecs: soundwire: increase resume timeout The resume operation relies on multiple transactions to synchronize the regmap state, make sure the timeout is one order of magnitude larger than an individual transaction, so that timeouts of failed transactions are detected first. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20210115061651.9740-2-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/max98373-sdw.c | 4 +++- sound/soc/codecs/rt1308-sdw.c | 2 +- sound/soc/codecs/rt5682.h | 2 +- sound/soc/codecs/rt700-sdw.c | 2 +- sound/soc/codecs/rt711-sdw.c | 2 +- sound/soc/codecs/rt715-sdw.c | 2 +- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index b8d471d79e939..d8c47667a9ea2 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -262,6 +262,8 @@ static __maybe_unused int max98373_suspend(struct device *dev) return 0; } +#define MAX98373_PROBE_TIMEOUT 5000 + static __maybe_unused int max98373_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); @@ -275,7 +277,7 @@ static __maybe_unused int max98373_resume(struct device *dev) goto regmap_sync; time = wait_for_completion_timeout(&slave->initialization_complete, - msecs_to_jiffies(2000)); + msecs_to_jiffies(MAX98373_PROBE_TIMEOUT)); if (!time) { dev_err(dev, "Initialization not complete, timed out\n"); return -ETIMEDOUT; diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index ec5564f780e8c..afd2c3b687ccb 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -701,7 +701,7 @@ static int __maybe_unused rt1308_dev_suspend(struct device *dev) return 0; } -#define RT1308_PROBE_TIMEOUT 2000 +#define RT1308_PROBE_TIMEOUT 5000 static int __maybe_unused rt1308_dev_resume(struct device *dev) { diff --git a/sound/soc/codecs/rt5682.h b/sound/soc/codecs/rt5682.h index 99b85cfe6248d..1f9c51a5b9bfc 100644 --- a/sound/soc/codecs/rt5682.h +++ b/sound/soc/codecs/rt5682.h @@ -1356,7 +1356,7 @@ #define RT5682_SAR_SOUR_TYPE (0x0) /* soundwire timeout */ -#define RT5682_PROBE_TIMEOUT 2000 +#define RT5682_PROBE_TIMEOUT 5000 #define RT5682_STEREO_RATES SNDRV_PCM_RATE_8000_192000 diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c index fb77e77a4ebd5..ce9255b881d4a 100644 --- a/sound/soc/codecs/rt700-sdw.c +++ b/sound/soc/codecs/rt700-sdw.c @@ -490,7 +490,7 @@ static int __maybe_unused rt700_dev_suspend(struct device *dev) return 0; } -#define RT700_PROBE_TIMEOUT 2000 +#define RT700_PROBE_TIMEOUT 5000 static int __maybe_unused rt700_dev_resume(struct device *dev) { diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index fc7df79c3b918..756c0ada3b31a 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -493,7 +493,7 @@ static int __maybe_unused rt711_dev_suspend(struct device *dev) return 0; } -#define RT711_PROBE_TIMEOUT 2000 +#define RT711_PROBE_TIMEOUT 5000 static int __maybe_unused rt711_dev_resume(struct device *dev) { diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c index 8f0aa1e8a2737..71dd3b97a4590 100644 --- a/sound/soc/codecs/rt715-sdw.c +++ b/sound/soc/codecs/rt715-sdw.c @@ -533,7 +533,7 @@ static int __maybe_unused rt715_dev_suspend(struct device *dev) return 0; } -#define RT715_PROBE_TIMEOUT 2000 +#define RT715_PROBE_TIMEOUT 5000 static int __maybe_unused rt715_dev_resume(struct device *dev) { -- GitLab From c28095bc99073ddda65e4f31f6ae0d908d4d5cd8 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Thu, 14 Jan 2021 00:09:51 -0800 Subject: [PATCH 0262/1084] usb: udc: core: Use lock when write to soft_connect Use lock to guard against concurrent access for soft-connect/disconnect operations when writing to soft_connect sysfs. Fixes: 2ccea03a8f7e ("usb: gadget: introduce UDC Class") Cc: stable@vger.kernel.org Acked-by: Felipe Balbi Signed-off-by: Thinh Nguyen Link: https://lore.kernel.org/r/338ea01fbd69b1985ef58f0f59af02c805ddf189.1610611437.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/core.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 6a62bbd01324f..ea114f922ccf6 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1529,10 +1529,13 @@ static ssize_t soft_connect_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) { struct usb_udc *udc = container_of(dev, struct usb_udc, dev); + ssize_t ret; + mutex_lock(&udc_lock); if (!udc->driver) { dev_err(dev, "soft-connect without a gadget driver\n"); - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; + goto out; } if (sysfs_streq(buf, "connect")) { @@ -1543,10 +1546,14 @@ static ssize_t soft_connect_store(struct device *dev, usb_gadget_udc_stop(udc); } else { dev_err(dev, "unsupported command '%s'\n", buf); - return -EINVAL; + ret = -EINVAL; + goto out; } - return n; + ret = n; +out: + mutex_unlock(&udc_lock); + return ret; } static DEVICE_ATTR_WO(soft_connect); -- GitLab From 576667bad341516edc4e18eb85acb0a2b4c9c9d9 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 15 Jan 2021 18:19:06 +0200 Subject: [PATCH 0263/1084] xhci: make sure TRB is fully written before giving it to the controller Once the command ring doorbell is rung the xHC controller will parse all command TRBs on the command ring that have the cycle bit set properly. If the driver just started writing the next command TRB to the ring when hardware finished the previous TRB, then HW might fetch an incomplete TRB as long as its cycle bit set correctly. A command TRB is 16 bytes (128 bits) long. Driver writes the command TRB in four 32 bit chunks, with the chunk containing the cycle bit last. This does however not guarantee that chunks actually get written in that order. This was detected in stress testing when canceling URBs with several connected USB devices. Two consecutive "Set TR Dequeue pointer" commands got queued right after each other, and the second one was only partially written when the controller parsed it, causing the dequeue pointer to be set to bogus values. This was seen as error messages: "Mismatch between completed Set TR Deq Ptr command & xHCI internal state" Solution is to add a write memory barrier before writing the cycle bit. Cc: Tested-by: Ross Zwisler Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20210115161907.2875631-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 5677b81c09155..cf0c93a90200f 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2931,6 +2931,8 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, trb->field[0] = cpu_to_le32(field1); trb->field[1] = cpu_to_le32(field2); trb->field[2] = cpu_to_le32(field3); + /* make sure TRB is fully written before giving it to the controller */ + wmb(); trb->field[3] = cpu_to_le32(field4); trace_xhci_queue_trb(ring, trb); -- GitLab From da7e0c3c2909a3d9bf8acfe1db3cb213bd7febfb Mon Sep 17 00:00:00 2001 From: JC Kuo Date: Fri, 15 Jan 2021 18:19:07 +0200 Subject: [PATCH 0264/1084] xhci: tegra: Delay for disabling LFPS detector Occasionally, we are seeing some SuperSpeed devices resumes right after being directed to U3. This commits add 500us delay to ensure LFPS detector is disabled before sending ACK to firmware. [ 16.099363] tegra-xusb 70090000.usb: entering ELPG [ 16.104343] tegra-xusb 70090000.usb: 2-1 isn't suspended: 0x0c001203 [ 16.114576] tegra-xusb 70090000.usb: not all ports suspended: -16 [ 16.120789] tegra-xusb 70090000.usb: entering ELPG failed The register write passes through a few flop stages of 32KHz clock domain. NVIDIA ASIC designer reviewed RTL and suggests 500us delay. Cc: stable@vger.kernel.org Signed-off-by: JC Kuo Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20210115161907.2875631-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-tegra.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 934be16863523..50bb91b6a4b8d 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -623,6 +623,13 @@ static void tegra_xusb_mbox_handle(struct tegra_xusb *tegra, enable); if (err < 0) break; + + /* + * wait 500us for LFPS detector to be disabled before + * sending ACK + */ + if (!enable) + usleep_range(500, 1000); } if (err < 0) { -- GitLab From 1740e6736922cc1a5d061cc4240d08eacfbbaa71 Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Tue, 12 Jan 2021 10:25:49 +0100 Subject: [PATCH 0265/1084] bus: arm-integrator-lm: Add of_node_put() before return statement Every iteration of for_each_available_child_of_node() decrements the reference count of the previous node, however when control is transferred from the middle of the loop, as in the case of a return or break or goto, there is no decrement thus ultimately resulting in a memory leak. Fix a potential memory leak in arm-integrator-lm.c by inserting of_node_put() before a return statement. Issue found with Coccinelle. Signed-off-by: Sumera Priyadarsini Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20200829174154.GA9319@Kaladin Link: https://lore.kernel.org/r/20210112092549.251548-1-linus.walleij@linaro.org' Signed-off-by: Arnd Bergmann --- drivers/bus/arm-integrator-lm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bus/arm-integrator-lm.c b/drivers/bus/arm-integrator-lm.c index 845b6c43fef89..2344d560b1449 100644 --- a/drivers/bus/arm-integrator-lm.c +++ b/drivers/bus/arm-integrator-lm.c @@ -54,6 +54,7 @@ static int integrator_lm_populate(int num, struct device *dev) ret = of_platform_default_populate(child, NULL, dev); if (ret) { dev_err(dev, "failed to populate module\n"); + of_node_put(child); return ret; } } -- GitLab From 2004e62a2a06b9029f7d728a0b5d19a499569184 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 7 Jan 2021 07:22:28 -0600 Subject: [PATCH 0266/1084] arm64: defconfig: Drop unused K3 SoC specific options With [1] integrated and all users of the config symbols removed, we can safely remove the options from defconfig. [1] https://patchwork.kernel.org/project/linux-arm-kernel/patch/20201026170624.24241-1-nm@ti.com/ Signed-off-by: Nishanth Menon Link: https://lore.kernel.org/r/20210107132228.6577-1-nm@ti.com' Signed-off-by: Arnd Bergmann --- arch/arm64/configs/defconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 838301650a794..a0bcf02012614 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -991,8 +991,6 @@ CONFIG_ARCH_TEGRA_210_SOC=y CONFIG_ARCH_TEGRA_186_SOC=y CONFIG_ARCH_TEGRA_194_SOC=y CONFIG_ARCH_TEGRA_234_SOC=y -CONFIG_ARCH_K3_AM6_SOC=y -CONFIG_ARCH_K3_J721E_SOC=y CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_EXTCON_PTN5150=m CONFIG_EXTCON_USB_GPIO=y -- GitLab From 8a996b2d8a03beae3cb6adfc12673778c192085d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 13 Dec 2020 23:55:17 +0100 Subject: [PATCH 0267/1084] ARM: dts: ux500: Reserve memory carveouts The Ux500 platforms have some memory carveouts set aside for communicating with the modem and for the initial secure software (ISSW). These areas are protected by the memory controller and will result in an external abort if accessed like common read/write memory. On the legacy boot loaders, these were set aside by using cmdline arguments such as this: mem=96M@0 mem_mtrace=15M@96M mem_mshared=1M@111M mem_modem=16M@112M mali.mali_mem=32M@128M mem=96M@160M hwmem=127M@256M mem_issw=1M@383M mem_ram_console=1M@384M mem=638M@385M Reserve the relevant areas in the device tree instead. The "mali", "hwmem", "mem_ram_console" and the trailing 1MB at the end of the memory reservations in the list are not relevant for the upstream kernel as these are nowadays replaced with upstream technologies such as CMA. The modem and ISSW reservations are necessary. This was manifested in a bug that surfaced in response to commit 7fef431be9c9 ("mm/page_alloc: place pages to tail in __free_pages_core()") which changes the behaviour of memory allocations in such a way that the platform will sooner run into these dangerous areas, with "Unhandled fault: imprecise external abort (0xc06) at 0xb6fd83dc" or similar: the real reason turns out to be that the PTE is pointing right into one of the reserved memory areas. We were just lucky until now. We need to augment the DB8500 and DB8520 SoCs similarly and also create a new include for the DB9500 used in the Snowball since this does not have a modem and thus does not need the modem memory reservation, albeit it needs the ISSW reservation. Signed-off-by: Linus Walleij Cc: stable@vger.kernel.org Cc: David Hildenbrand Link: https://lore.kernel.org/r/20201213225517.3838501-1-linus.walleij@linaro.org' Signed-off-by: Arnd Bergmann --- arch/arm/boot/dts/ste-db8500.dtsi | 38 ++++++++++++++++++++++++++++++ arch/arm/boot/dts/ste-db8520.dtsi | 38 ++++++++++++++++++++++++++++++ arch/arm/boot/dts/ste-db9500.dtsi | 35 +++++++++++++++++++++++++++ arch/arm/boot/dts/ste-snowball.dts | 2 +- 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/ste-db9500.dtsi diff --git a/arch/arm/boot/dts/ste-db8500.dtsi b/arch/arm/boot/dts/ste-db8500.dtsi index d309fad32229d..344d29853bf76 100644 --- a/arch/arm/boot/dts/ste-db8500.dtsi +++ b/arch/arm/boot/dts/ste-db8500.dtsi @@ -12,4 +12,42 @@ 200000 0>; }; }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* Modem trace memory */ + ram@06000000 { + reg = <0x06000000 0x00f00000>; + no-map; + }; + + /* Modem shared memory */ + ram@06f00000 { + reg = <0x06f00000 0x00100000>; + no-map; + }; + + /* Modem private memory */ + ram@07000000 { + reg = <0x07000000 0x01000000>; + no-map; + }; + + /* + * Initial Secure Software ISSW memory + * + * This is probably only used if the kernel tries + * to actually call into trustzone to run secure + * applications, which the mainline kernel probably + * will not do on this old chipset. But you can never + * be too careful, so reserve this memory anyway. + */ + ram@17f00000 { + reg = <0x17f00000 0x00100000>; + no-map; + }; + }; }; diff --git a/arch/arm/boot/dts/ste-db8520.dtsi b/arch/arm/boot/dts/ste-db8520.dtsi index 48bd8728ae27f..287804e9e1836 100644 --- a/arch/arm/boot/dts/ste-db8520.dtsi +++ b/arch/arm/boot/dts/ste-db8520.dtsi @@ -12,4 +12,42 @@ 200000 0>; }; }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* Modem trace memory */ + ram@06000000 { + reg = <0x06000000 0x00f00000>; + no-map; + }; + + /* Modem shared memory */ + ram@06f00000 { + reg = <0x06f00000 0x00100000>; + no-map; + }; + + /* Modem private memory */ + ram@07000000 { + reg = <0x07000000 0x01000000>; + no-map; + }; + + /* + * Initial Secure Software ISSW memory + * + * This is probably only used if the kernel tries + * to actually call into trustzone to run secure + * applications, which the mainline kernel probably + * will not do on this old chipset. But you can never + * be too careful, so reserve this memory anyway. + */ + ram@17f00000 { + reg = <0x17f00000 0x00100000>; + no-map; + }; + }; }; diff --git a/arch/arm/boot/dts/ste-db9500.dtsi b/arch/arm/boot/dts/ste-db9500.dtsi new file mode 100644 index 0000000000000..0afff703191c6 --- /dev/null +++ b/arch/arm/boot/dts/ste-db9500.dtsi @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "ste-dbx5x0.dtsi" + +/ { + cpus { + cpu@300 { + /* cpufreq controls */ + operating-points = <1152000 0 + 800000 0 + 400000 0 + 200000 0>; + }; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* + * Initial Secure Software ISSW memory + * + * This is probably only used if the kernel tries + * to actually call into trustzone to run secure + * applications, which the mainline kernel probably + * will not do on this old chipset. But you can never + * be too careful, so reserve this memory anyway. + */ + ram@17f00000 { + reg = <0x17f00000 0x00100000>; + no-map; + }; + }; +}; diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts index be90e73c923ec..27d8a07718a00 100644 --- a/arch/arm/boot/dts/ste-snowball.dts +++ b/arch/arm/boot/dts/ste-snowball.dts @@ -4,7 +4,7 @@ */ /dts-v1/; -#include "ste-db8500.dtsi" +#include "ste-db9500.dtsi" #include "ste-href-ab8500.dtsi" #include "ste-href-family-pinctrl.dtsi" -- GitLab From b7ba6cfabc42fc846eb96e33f1edcd3ea6290a27 Mon Sep 17 00:00:00 2001 From: Yingjie Wang Date: Fri, 15 Jan 2021 06:10:04 -0800 Subject: [PATCH 0268/1084] octeontx2-af: Fix missing check bugs in rvu_cgx.c In rvu_mbox_handler_cgx_mac_addr_get() and rvu_mbox_handler_cgx_mac_addr_set(), the msg is expected only from PFs that are mapped to CGX LMACs. It should be checked before mapping, so we add the is_cgx_config_permitted() in the functions. Fixes: 96be2e0da85e ("octeontx2-af: Support for MAC address filters in CGX") Signed-off-by: Yingjie Wang Reviewed-by: Geetha sowjanya Link: https://lore.kernel.org/r/1610719804-35230-1-git-send-email-wangyingjie55@126.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c index d298b93571778..6c6b411e78fd8 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c @@ -469,6 +469,9 @@ int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu, int pf = rvu_get_pf(req->hdr.pcifunc); u8 cgx_id, lmac_id; + if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc)) + return -EPERM; + rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); cgx_lmac_addr_set(cgx_id, lmac_id, req->mac_addr); @@ -485,6 +488,9 @@ int rvu_mbox_handler_cgx_mac_addr_get(struct rvu *rvu, int rc = 0, i; u64 cfg; + if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc)) + return -EPERM; + rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); rsp->hdr.rc = rc; -- GitLab From 235ecd36c7a93e4d6c73ac71137b8f1fa31148dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Date: Fri, 15 Jan 2021 11:43:37 +0100 Subject: [PATCH 0269/1084] MAINTAINERS: Update my email address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit My Intel email will stop working in a not too distant future. Move my MAINTAINERS entries to my kernel.org address. Signed-off-by: Björn Töpel Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20210115104337.7751-1-bjorn.topel@gmail.com --- .mailmap | 2 ++ MAINTAINERS | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.mailmap b/.mailmap index 632700cee55cd..b1ab0129c7d6b 100644 --- a/.mailmap +++ b/.mailmap @@ -55,6 +55,8 @@ Bart Van Assche Ben Gardner Ben M Cahill Björn Steinbrink +Björn Töpel +Björn Töpel Boris Brezillon Boris Brezillon Boris Brezillon diff --git a/MAINTAINERS b/MAINTAINERS index b15514a770e3c..0dfd1a67d430b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3336,7 +3336,7 @@ F: arch/riscv/net/ X: arch/riscv/net/bpf_jit_comp64.c BPF JIT for RISC-V (64-bit) -M: Björn Töpel +M: Björn Töpel L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Maintained @@ -19409,7 +19409,7 @@ F: drivers/net/ethernet/*/*/*xdp* K: (?:\b|_)xdp(?:\b|_) XDP SOCKETS (AF_XDP) -M: Björn Töpel +M: Björn Töpel M: Magnus Karlsson R: Jonathan Lemon L: netdev@vger.kernel.org -- GitLab From c96adff95619178e2118925578343ad54857c80c Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Fri, 15 Jan 2021 10:50:24 -0800 Subject: [PATCH 0270/1084] cls_flower: call nla_ok() before nla_next() fl_set_enc_opt() simply checks if there are still bytes left to parse, but this is not sufficent as syzbot seems to be able to generate malformatted netlink messages. nla_ok() is more strict so should be used to validate the next nlattr here. And nla_validate_nested_deprecated() has less strict check too, it is probably too late to switch to the strict version, but we can just call nla_ok() too after it. Reported-and-tested-by: syzbot+2624e3778b18fc497c92@syzkaller.appspotmail.com Fixes: 0a6e77784f49 ("net/sched: allow flower to match tunnel options") Fixes: 79b1011cb33d ("net: sched: allow flower to match erspan options") Cc: Jamal Hadi Salim Cc: Xin Long Cc: Jiri Pirko Signed-off-by: Cong Wang Link: https://lore.kernel.org/r/20210115185024.72298-1-xiyou.wangcong@gmail.com Signed-off-by: Jakub Kicinski --- net/sched/cls_flower.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 1319986693fc8..84f932532db7d 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -1272,6 +1272,10 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key, nla_opt_msk = nla_data(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]); msk_depth = nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]); + if (!nla_ok(nla_opt_msk, msk_depth)) { + NL_SET_ERR_MSG(extack, "Invalid nested attribute for masks"); + return -EINVAL; + } } nla_for_each_attr(nla_opt_key, nla_enc_key, @@ -1307,9 +1311,6 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key, NL_SET_ERR_MSG(extack, "Key and mask miss aligned"); return -EINVAL; } - - if (msk_depth) - nla_opt_msk = nla_next(nla_opt_msk, &msk_depth); break; case TCA_FLOWER_KEY_ENC_OPTS_VXLAN: if (key->enc_opts.dst_opt_type) { @@ -1340,9 +1341,6 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key, NL_SET_ERR_MSG(extack, "Key and mask miss aligned"); return -EINVAL; } - - if (msk_depth) - nla_opt_msk = nla_next(nla_opt_msk, &msk_depth); break; case TCA_FLOWER_KEY_ENC_OPTS_ERSPAN: if (key->enc_opts.dst_opt_type) { @@ -1373,14 +1371,20 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key, NL_SET_ERR_MSG(extack, "Key and mask miss aligned"); return -EINVAL; } - - if (msk_depth) - nla_opt_msk = nla_next(nla_opt_msk, &msk_depth); break; default: NL_SET_ERR_MSG(extack, "Unknown tunnel option type"); return -EINVAL; } + + if (!msk_depth) + continue; + + if (!nla_ok(nla_opt_msk, msk_depth)) { + NL_SET_ERR_MSG(extack, "A mask attribute is invalid"); + return -EINVAL; + } + nla_opt_msk = nla_next(nla_opt_msk, &msk_depth); } return 0; -- GitLab From ebfd44883ab5dd9a201af2d936e1dfb93962be0b Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 11 Dec 2020 14:32:32 -0800 Subject: [PATCH 0271/1084] kunit: tool: Fix spelling of "diagnostic" in kunit_parser Various helper functions were misspelling "diagnostic" in their names. It finally got annoying, so fix it. Signed-off-by: David Gow Reviewed-by: Brendan Higgins Tested-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit_parser.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py index 6614ec4d08989..1a1e1d13f1d30 100644 --- a/tools/testing/kunit/kunit_parser.py +++ b/tools/testing/kunit/kunit_parser.py @@ -97,11 +97,11 @@ def print_log(log): TAP_ENTRIES = re.compile(r'^(TAP|[\s]*ok|[\s]*not ok|[\s]*[0-9]+\.\.[0-9]+|[\s]*#).*$') -def consume_non_diagnositic(lines: List[str]) -> None: +def consume_non_diagnostic(lines: List[str]) -> None: while lines and not TAP_ENTRIES.match(lines[0]): lines.pop(0) -def save_non_diagnositic(lines: List[str], test_case: TestCase) -> None: +def save_non_diagnostic(lines: List[str], test_case: TestCase) -> None: while lines and not TAP_ENTRIES.match(lines[0]): test_case.log.append(lines[0]) lines.pop(0) @@ -113,7 +113,7 @@ OK_NOT_OK_SUBTEST = re.compile(r'^[\s]+(ok|not ok) [0-9]+ - (.*)$') OK_NOT_OK_MODULE = re.compile(r'^(ok|not ok) ([0-9]+) - (.*)$') def parse_ok_not_ok_test_case(lines: List[str], test_case: TestCase) -> bool: - save_non_diagnositic(lines, test_case) + save_non_diagnostic(lines, test_case) if not lines: test_case.status = TestStatus.TEST_CRASHED return True @@ -139,7 +139,7 @@ SUBTEST_DIAGNOSTIC = re.compile(r'^[\s]+# (.*)$') DIAGNOSTIC_CRASH_MESSAGE = re.compile(r'^[\s]+# .*?: kunit test case crashed!$') def parse_diagnostic(lines: List[str], test_case: TestCase) -> bool: - save_non_diagnositic(lines, test_case) + save_non_diagnostic(lines, test_case) if not lines: return False line = lines[0] @@ -155,7 +155,7 @@ def parse_diagnostic(lines: List[str], test_case: TestCase) -> bool: def parse_test_case(lines: List[str]) -> Optional[TestCase]: test_case = TestCase() - save_non_diagnositic(lines, test_case) + save_non_diagnostic(lines, test_case) while parse_diagnostic(lines, test_case): pass if parse_ok_not_ok_test_case(lines, test_case): @@ -166,7 +166,7 @@ def parse_test_case(lines: List[str]) -> Optional[TestCase]: SUBTEST_HEADER = re.compile(r'^[\s]+# Subtest: (.*)$') def parse_subtest_header(lines: List[str]) -> Optional[str]: - consume_non_diagnositic(lines) + consume_non_diagnostic(lines) if not lines: return None match = SUBTEST_HEADER.match(lines[0]) @@ -179,7 +179,7 @@ def parse_subtest_header(lines: List[str]) -> Optional[str]: SUBTEST_PLAN = re.compile(r'[\s]+[0-9]+\.\.([0-9]+)') def parse_subtest_plan(lines: List[str]) -> Optional[int]: - consume_non_diagnositic(lines) + consume_non_diagnostic(lines) match = SUBTEST_PLAN.match(lines[0]) if match: lines.pop(0) @@ -202,7 +202,7 @@ def max_status(left: TestStatus, right: TestStatus) -> TestStatus: def parse_ok_not_ok_test_suite(lines: List[str], test_suite: TestSuite, expected_suite_index: int) -> bool: - consume_non_diagnositic(lines) + consume_non_diagnostic(lines) if not lines: test_suite.status = TestStatus.TEST_CRASHED return False @@ -235,7 +235,7 @@ def bubble_up_test_case_errors(test_suite: TestSuite) -> TestStatus: def parse_test_suite(lines: List[str], expected_suite_index: int) -> Optional[TestSuite]: if not lines: return None - consume_non_diagnositic(lines) + consume_non_diagnostic(lines) test_suite = TestSuite() test_suite.status = TestStatus.SUCCESS name = parse_subtest_header(lines) @@ -264,7 +264,7 @@ def parse_test_suite(lines: List[str], expected_suite_index: int) -> Optional[Te TAP_HEADER = re.compile(r'^TAP version 14$') def parse_tap_header(lines: List[str]) -> bool: - consume_non_diagnositic(lines) + consume_non_diagnostic(lines) if TAP_HEADER.match(lines[0]): lines.pop(0) return True @@ -274,7 +274,7 @@ def parse_tap_header(lines: List[str]) -> bool: TEST_PLAN = re.compile(r'[0-9]+\.\.([0-9]+)') def parse_test_plan(lines: List[str]) -> Optional[int]: - consume_non_diagnositic(lines) + consume_non_diagnostic(lines) match = TEST_PLAN.match(lines[0]) if match: lines.pop(0) @@ -286,7 +286,7 @@ def bubble_up_suite_errors(test_suite_list: List[TestSuite]) -> TestStatus: return bubble_up_errors(lambda x: x.status, test_suite_list) def parse_test_result(lines: List[str]) -> TestResult: - consume_non_diagnositic(lines) + consume_non_diagnostic(lines) if not lines or not parse_tap_header(lines): return TestResult(TestStatus.NO_TESTS, [], lines) expected_test_suite_num = parse_test_plan(lines) -- GitLab From 8db50be262e9faf59fa0feb74599c29b64eb0af2 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 15 Dec 2020 16:22:46 -0800 Subject: [PATCH 0272/1084] Documentation: kunit: include example of a parameterized test Commit fadb08e7c750 ("kunit: Support for Parameterized Testing") introduced support but lacks documentation for how to use it. This patch builds on commit 1f0e943df68a ("Documentation: kunit: provide guidance for testing many inputs") to show a minimal example of the new feature. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Tested-by: Brendan Higgins Acked-by: Brendan Higgins Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/usage.rst | 57 +++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-tools/kunit/usage.rst index d9fdc14f0677b..650f99590df57 100644 --- a/Documentation/dev-tools/kunit/usage.rst +++ b/Documentation/dev-tools/kunit/usage.rst @@ -522,6 +522,63 @@ There's more boilerplate involved, but it can: * E.g. if we wanted to also test ``sha256sum``, we could add a ``sha256`` field and reuse ``cases``. +* be converted to a "parameterized test", see below. + +Parameterized Testing +~~~~~~~~~~~~~~~~~~~~~ + +The table-driven testing pattern is common enough that KUnit has special +support for it. + +Reusing the same ``cases`` array from above, we can write the test as a +"parameterized test" with the following. + +.. code-block:: c + + // This is copy-pasted from above. + struct sha1_test_case { + const char *str; + const char *sha1; + }; + struct sha1_test_case cases[] = { + { + .str = "hello world", + .sha1 = "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", + }, + { + .str = "hello world!", + .sha1 = "430ce34d020724ed75a196dfc2ad67c77772d169", + }, + }; + + // Need a helper function to generate a name for each test case. + static void case_to_desc(const struct sha1_test_case *t, char *desc) + { + strcpy(desc, t->str); + } + // Creates `sha1_gen_params()` to iterate over `cases`. + KUNIT_ARRAY_PARAM(sha1, cases, case_to_desc); + + // Looks no different from a normal test. + static void sha1_test(struct kunit *test) + { + // This function can just contain the body of the for-loop. + // The former `cases[i]` is accessible under test->param_value. + char out[40]; + struct sha1_test_case *test_param = (struct sha1_test_case *)(test->param_value); + + sha1sum(test_param->str, out); + KUNIT_EXPECT_STREQ_MSG(test, (char *)out, test_param->sha1, + "sha1sum(%s)", test_param->str); + } + + // Instead of KUNIT_CASE, we use KUNIT_CASE_PARAM and pass in the + // function declared by KUNIT_ARRAY_PARAM. + static struct kunit_case sha1_test_cases[] = { + KUNIT_CASE_PARAM(sha1_test, sha1_gen_params), + {} + }; + .. _kunit-on-non-uml: KUnit on non-UML architectures -- GitLab From 09641f7c7d8f1309fe9ad9ce4e6a1697016d73ba Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 14 Jan 2021 16:39:11 -0800 Subject: [PATCH 0273/1084] kunit: tool: surface and address more typing issues The authors of this tool were more familiar with a different type-checker, https://github.com/google/pytype. That's open source, but mypy seems more prevalent (and runs faster). And unlike pytype, mypy doesn't try to infer types so it doesn't check unanotated functions. So annotate ~all functions in kunit tool to increase type-checking coverage. Note: per https://www.python.org/dev/peps/pep-0484/, `__init__()` should be annotated as `-> None`. Doing so makes mypy discover a number of new violations. Exclude main() since we reuse `request` for the different types of requests, which mypy isn't happy about. This commit fixes all but one error, where `TestSuite.status` might be None. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Tested-by: Brendan Higgins Acked-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit.py | 14 ++++----- tools/testing/kunit/kunit_config.py | 7 +++-- tools/testing/kunit/kunit_json.py | 2 +- tools/testing/kunit/kunit_kernel.py | 37 ++++++++++++----------- tools/testing/kunit/kunit_parser.py | 46 ++++++++++++++--------------- 5 files changed, 54 insertions(+), 52 deletions(-) diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py index 21516e293d171..5521e0a8201e3 100755 --- a/tools/testing/kunit/kunit.py +++ b/tools/testing/kunit/kunit.py @@ -43,9 +43,9 @@ class KunitStatus(Enum): BUILD_FAILURE = auto() TEST_FAILURE = auto() -def get_kernel_root_path(): - parts = sys.argv[0] if not __file__ else __file__ - parts = os.path.realpath(parts).split('tools/testing/kunit') +def get_kernel_root_path() -> str: + path = sys.argv[0] if not __file__ else __file__ + parts = os.path.realpath(path).split('tools/testing/kunit') if len(parts) != 2: sys.exit(1) return parts[0] @@ -171,7 +171,7 @@ def run_tests(linux: kunit_kernel.LinuxSourceTree, exec_result.elapsed_time)) return parse_result -def add_common_opts(parser): +def add_common_opts(parser) -> None: parser.add_argument('--build_dir', help='As in the make command, it specifies the build ' 'directory.', @@ -183,13 +183,13 @@ def add_common_opts(parser): help='Run all KUnit tests through allyesconfig', action='store_true') -def add_build_opts(parser): +def add_build_opts(parser) -> None: parser.add_argument('--jobs', help='As in the make command, "Specifies the number of ' 'jobs (commands) to run simultaneously."', type=int, default=8, metavar='jobs') -def add_exec_opts(parser): +def add_exec_opts(parser) -> None: parser.add_argument('--timeout', help='maximum number of seconds to allow for all tests ' 'to run. This does not include time taken to build the ' @@ -198,7 +198,7 @@ def add_exec_opts(parser): default=300, metavar='timeout') -def add_parse_opts(parser): +def add_parse_opts(parser) -> None: parser.add_argument('--raw_output', help='don\'t format output from kernel', action='store_true') parser.add_argument('--json', diff --git a/tools/testing/kunit/kunit_config.py b/tools/testing/kunit/kunit_config.py index 02ffc3a3e5dc7..bdd60230764b0 100644 --- a/tools/testing/kunit/kunit_config.py +++ b/tools/testing/kunit/kunit_config.py @@ -8,6 +8,7 @@ import collections import re +from typing import List, Set CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$' CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$' @@ -30,10 +31,10 @@ class KconfigParseError(Exception): class Kconfig(object): """Represents defconfig or .config specified using the Kconfig language.""" - def __init__(self): - self._entries = [] + def __init__(self) -> None: + self._entries = [] # type: List[KconfigEntry] - def entries(self): + def entries(self) -> Set[KconfigEntry]: return set(self._entries) def add_entry(self, entry: KconfigEntry) -> None: diff --git a/tools/testing/kunit/kunit_json.py b/tools/testing/kunit/kunit_json.py index 624b31b2dbd62..f5cca5c38cacf 100644 --- a/tools/testing/kunit/kunit_json.py +++ b/tools/testing/kunit/kunit_json.py @@ -13,7 +13,7 @@ import kunit_parser from kunit_parser import TestStatus -def get_json_result(test_result, def_config, build_dir, json_path): +def get_json_result(test_result, def_config, build_dir, json_path) -> str: sub_groups = [] # Each test suite is mapped to a KernelCI sub_group diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py index 698358c9c0d60..e77ee06aa4076 100644 --- a/tools/testing/kunit/kunit_kernel.py +++ b/tools/testing/kunit/kunit_kernel.py @@ -11,6 +11,7 @@ import subprocess import os import shutil import signal +from typing import Iterator from contextlib import ExitStack @@ -39,7 +40,7 @@ class BuildError(Exception): class LinuxSourceTreeOperations(object): """An abstraction over command line operations performed on a source tree.""" - def make_mrproper(self): + def make_mrproper(self) -> None: try: subprocess.check_output(['make', 'mrproper'], stderr=subprocess.STDOUT) except OSError as e: @@ -47,7 +48,7 @@ class LinuxSourceTreeOperations(object): except subprocess.CalledProcessError as e: raise ConfigError(e.output.decode()) - def make_olddefconfig(self, build_dir, make_options): + def make_olddefconfig(self, build_dir, make_options) -> None: command = ['make', 'ARCH=um', 'olddefconfig'] if make_options: command.extend(make_options) @@ -60,7 +61,7 @@ class LinuxSourceTreeOperations(object): except subprocess.CalledProcessError as e: raise ConfigError(e.output.decode()) - def make_allyesconfig(self, build_dir, make_options): + def make_allyesconfig(self, build_dir, make_options) -> None: kunit_parser.print_with_timestamp( 'Enabling all CONFIGs for UML...') command = ['make', 'ARCH=um', 'allyesconfig'] @@ -82,7 +83,7 @@ class LinuxSourceTreeOperations(object): kunit_parser.print_with_timestamp( 'Starting Kernel with all configs takes a few minutes...') - def make(self, jobs, build_dir, make_options): + def make(self, jobs, build_dir, make_options) -> None: command = ['make', 'ARCH=um', '--jobs=' + str(jobs)] if make_options: command.extend(make_options) @@ -100,7 +101,7 @@ class LinuxSourceTreeOperations(object): if stderr: # likely only due to build warnings print(stderr.decode()) - def linux_bin(self, params, timeout, build_dir): + def linux_bin(self, params, timeout, build_dir) -> None: """Runs the Linux UML binary. Must be named 'linux'.""" linux_bin = get_file_path(build_dir, 'linux') outfile = get_outfile_path(build_dir) @@ -110,23 +111,23 @@ class LinuxSourceTreeOperations(object): stderr=subprocess.STDOUT) process.wait(timeout) -def get_kconfig_path(build_dir): +def get_kconfig_path(build_dir) -> str: return get_file_path(build_dir, KCONFIG_PATH) -def get_kunitconfig_path(build_dir): +def get_kunitconfig_path(build_dir) -> str: return get_file_path(build_dir, KUNITCONFIG_PATH) -def get_outfile_path(build_dir): +def get_outfile_path(build_dir) -> str: return get_file_path(build_dir, OUTFILE_PATH) class LinuxSourceTree(object): """Represents a Linux kernel source tree with KUnit tests.""" - def __init__(self): + def __init__(self) -> None: self._ops = LinuxSourceTreeOperations() signal.signal(signal.SIGINT, self.signal_handler) - def clean(self): + def clean(self) -> bool: try: self._ops.make_mrproper() except ConfigError as e: @@ -134,17 +135,17 @@ class LinuxSourceTree(object): return False return True - def create_kunitconfig(self, build_dir, defconfig=DEFAULT_KUNITCONFIG_PATH): + def create_kunitconfig(self, build_dir, defconfig=DEFAULT_KUNITCONFIG_PATH) -> None: kunitconfig_path = get_kunitconfig_path(build_dir) if not os.path.exists(kunitconfig_path): shutil.copyfile(defconfig, kunitconfig_path) - def read_kunitconfig(self, build_dir): + def read_kunitconfig(self, build_dir) -> None: kunitconfig_path = get_kunitconfig_path(build_dir) self._kconfig = kunit_config.Kconfig() self._kconfig.read_from_file(kunitconfig_path) - def validate_config(self, build_dir): + def validate_config(self, build_dir) -> bool: kconfig_path = get_kconfig_path(build_dir) validated_kconfig = kunit_config.Kconfig() validated_kconfig.read_from_file(kconfig_path) @@ -158,7 +159,7 @@ class LinuxSourceTree(object): return False return True - def build_config(self, build_dir, make_options): + def build_config(self, build_dir, make_options) -> bool: kconfig_path = get_kconfig_path(build_dir) if build_dir and not os.path.exists(build_dir): os.mkdir(build_dir) @@ -170,7 +171,7 @@ class LinuxSourceTree(object): return False return self.validate_config(build_dir) - def build_reconfig(self, build_dir, make_options): + def build_reconfig(self, build_dir, make_options) -> bool: """Creates a new .config if it is not a subset of the .kunitconfig.""" kconfig_path = get_kconfig_path(build_dir) if os.path.exists(kconfig_path): @@ -186,7 +187,7 @@ class LinuxSourceTree(object): print('Generating .config ...') return self.build_config(build_dir, make_options) - def build_um_kernel(self, alltests, jobs, build_dir, make_options): + def build_um_kernel(self, alltests, jobs, build_dir, make_options) -> bool: try: if alltests: self._ops.make_allyesconfig(build_dir, make_options) @@ -197,7 +198,7 @@ class LinuxSourceTree(object): return False return self.validate_config(build_dir) - def run_kernel(self, args=[], build_dir='', timeout=None): + def run_kernel(self, args=[], build_dir='', timeout=None) -> Iterator[str]: args.extend(['mem=1G', 'console=tty']) self._ops.linux_bin(args, timeout, build_dir) outfile = get_outfile_path(build_dir) @@ -206,6 +207,6 @@ class LinuxSourceTree(object): for line in file: yield line - def signal_handler(self, sig, frame): + def signal_handler(self, sig, frame) -> None: logging.error('Build interruption occurred. Cleaning console.') subprocess.call(['stty', 'sane']) diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py index 1a1e1d13f1d30..bd90d7b86b76c 100644 --- a/tools/testing/kunit/kunit_parser.py +++ b/tools/testing/kunit/kunit_parser.py @@ -12,32 +12,32 @@ from collections import namedtuple from datetime import datetime from enum import Enum, auto from functools import reduce -from typing import List, Optional, Tuple +from typing import Iterator, List, Optional, Tuple TestResult = namedtuple('TestResult', ['status','suites','log']) class TestSuite(object): - def __init__(self): - self.status = None - self.name = None - self.cases = [] + def __init__(self) -> None: + self.status = None # type: Optional[TestStatus] + self.name = '' + self.cases = [] # type: List[TestCase] - def __str__(self): - return 'TestSuite(' + self.status + ',' + self.name + ',' + str(self.cases) + ')' + def __str__(self) -> str: + return 'TestSuite(' + str(self.status) + ',' + self.name + ',' + str(self.cases) + ')' - def __repr__(self): + def __repr__(self) -> str: return str(self) class TestCase(object): - def __init__(self): - self.status = None + def __init__(self) -> None: + self.status = None # type: Optional[TestStatus] self.name = '' - self.log = [] + self.log = [] # type: List[str] - def __str__(self): - return 'TestCase(' + self.status + ',' + self.name + ',' + str(self.log) + ')' + def __str__(self) -> str: + return 'TestCase(' + str(self.status) + ',' + self.name + ',' + str(self.log) + ')' - def __repr__(self): + def __repr__(self) -> str: return str(self) class TestStatus(Enum): @@ -51,7 +51,7 @@ kunit_start_re = re.compile(r'TAP version [0-9]+$') kunit_end_re = re.compile('(List of all partitions:|' 'Kernel panic - not syncing: VFS:)') -def isolate_kunit_output(kernel_output): +def isolate_kunit_output(kernel_output) -> Iterator[str]: started = False for line in kernel_output: line = line.rstrip() # line always has a trailing \n @@ -64,7 +64,7 @@ def isolate_kunit_output(kernel_output): elif started: yield line[prefix_len:] if prefix_len > 0 else line -def raw_output(kernel_output): +def raw_output(kernel_output) -> None: for line in kernel_output: print(line.rstrip()) @@ -72,26 +72,26 @@ DIVIDER = '=' * 60 RESET = '\033[0;0m' -def red(text): +def red(text) -> str: return '\033[1;31m' + text + RESET -def yellow(text): +def yellow(text) -> str: return '\033[1;33m' + text + RESET -def green(text): +def green(text) -> str: return '\033[1;32m' + text + RESET -def print_with_timestamp(message): +def print_with_timestamp(message) -> None: print('[%s] %s' % (datetime.now().strftime('%H:%M:%S'), message)) -def format_suite_divider(message): +def format_suite_divider(message) -> str: return '======== ' + message + ' ========' -def print_suite_divider(message): +def print_suite_divider(message) -> None: print_with_timestamp(DIVIDER) print_with_timestamp(format_suite_divider(message)) -def print_log(log): +def print_log(log) -> None: for m in log: print_with_timestamp(m) -- GitLab From 81c60306dc588e2e6b21391c1f6dd509403e6eec Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 14 Jan 2021 16:39:12 -0800 Subject: [PATCH 0274/1084] kunit: tool: fix minor typing issue with None status The code to handle aggregating statuses didn't check that the status actually got set to some non-None value. Default the value to SUCCESS instead of adding a bunch of `is None` checks. This sorta follows the precedent in commit 3fc48259d525 ("kunit: Don't fail test suites if one of them is empty"). Also slightly simplify the code and add type annotations. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Tested-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit_parser.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py index bd90d7b86b76c..e8bcc139702e2 100644 --- a/tools/testing/kunit/kunit_parser.py +++ b/tools/testing/kunit/kunit_parser.py @@ -12,13 +12,13 @@ from collections import namedtuple from datetime import datetime from enum import Enum, auto from functools import reduce -from typing import Iterator, List, Optional, Tuple +from typing import Iterable, Iterator, List, Optional, Tuple TestResult = namedtuple('TestResult', ['status','suites','log']) class TestSuite(object): def __init__(self) -> None: - self.status = None # type: Optional[TestStatus] + self.status = TestStatus.SUCCESS self.name = '' self.cases = [] # type: List[TestCase] @@ -30,7 +30,7 @@ class TestSuite(object): class TestCase(object): def __init__(self) -> None: - self.status = None # type: Optional[TestStatus] + self.status = TestStatus.SUCCESS self.name = '' self.log = [] # type: List[str] @@ -224,12 +224,11 @@ def parse_ok_not_ok_test_suite(lines: List[str], else: return False -def bubble_up_errors(to_status, status_container_list) -> TestStatus: - status_list = map(to_status, status_container_list) - return reduce(max_status, status_list, TestStatus.SUCCESS) +def bubble_up_errors(statuses: Iterable[TestStatus]) -> TestStatus: + return reduce(max_status, statuses, TestStatus.SUCCESS) def bubble_up_test_case_errors(test_suite: TestSuite) -> TestStatus: - max_test_case_status = bubble_up_errors(lambda x: x.status, test_suite.cases) + max_test_case_status = bubble_up_errors(x.status for x in test_suite.cases) return max_status(max_test_case_status, test_suite.status) def parse_test_suite(lines: List[str], expected_suite_index: int) -> Optional[TestSuite]: @@ -282,8 +281,8 @@ def parse_test_plan(lines: List[str]) -> Optional[int]: else: return None -def bubble_up_suite_errors(test_suite_list: List[TestSuite]) -> TestStatus: - return bubble_up_errors(lambda x: x.status, test_suite_list) +def bubble_up_suite_errors(test_suites: Iterable[TestSuite]) -> TestStatus: + return bubble_up_errors(x.status for x in test_suites) def parse_test_result(lines: List[str]) -> TestResult: consume_non_diagnostic(lines) -- GitLab From 2b8fdbbf1c616300312f71fe5b21fe8f03129950 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 14 Jan 2021 16:39:13 -0800 Subject: [PATCH 0275/1084] kunit: tool: move kunitconfig parsing into __init__, make it optional LinuxSourceTree will unceremoniously crash if the user doesn't call read_kunitconfig() first in a number of functions. And currently every place we create an instance, the caller also calls create_kunitconfig() and read_kunitconfig(). Move these instead into __init__() so they can't be forgotten and to reduce copy-paste. The https://github.com/google/pytype type-checker complained that _config wasn't initialized. With this, kunit_tool now type checks under both pytype and mypy. Add an optional boolean that can be used to disable this for use cases in the future where we might not need/want to load the config. Signed-off-by: Daniel Latypov Reviewed-by: Brendan Higgins Tested-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit.py | 20 ++++---------------- tools/testing/kunit/kunit_kernel.py | 25 +++++++++++++------------ 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py index 5521e0a8201e3..e808a47c839bf 100755 --- a/tools/testing/kunit/kunit.py +++ b/tools/testing/kunit/kunit.py @@ -256,10 +256,7 @@ def main(argv, linux=None): os.mkdir(cli_args.build_dir) if not linux: - linux = kunit_kernel.LinuxSourceTree() - - linux.create_kunitconfig(cli_args.build_dir) - linux.read_kunitconfig(cli_args.build_dir) + linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir) request = KunitRequest(cli_args.raw_output, cli_args.timeout, @@ -277,10 +274,7 @@ def main(argv, linux=None): os.mkdir(cli_args.build_dir) if not linux: - linux = kunit_kernel.LinuxSourceTree() - - linux.create_kunitconfig(cli_args.build_dir) - linux.read_kunitconfig(cli_args.build_dir) + linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir) request = KunitConfigRequest(cli_args.build_dir, cli_args.make_options) @@ -292,10 +286,7 @@ def main(argv, linux=None): sys.exit(1) elif cli_args.subcommand == 'build': if not linux: - linux = kunit_kernel.LinuxSourceTree() - - linux.create_kunitconfig(cli_args.build_dir) - linux.read_kunitconfig(cli_args.build_dir) + linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir) request = KunitBuildRequest(cli_args.jobs, cli_args.build_dir, @@ -309,10 +300,7 @@ def main(argv, linux=None): sys.exit(1) elif cli_args.subcommand == 'exec': if not linux: - linux = kunit_kernel.LinuxSourceTree() - - linux.create_kunitconfig(cli_args.build_dir) - linux.read_kunitconfig(cli_args.build_dir) + linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir) exec_request = KunitExecRequest(cli_args.timeout, cli_args.build_dir, diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py index e77ee06aa4076..2076a5a2d060a 100644 --- a/tools/testing/kunit/kunit_kernel.py +++ b/tools/testing/kunit/kunit_kernel.py @@ -123,28 +123,29 @@ def get_outfile_path(build_dir) -> str: class LinuxSourceTree(object): """Represents a Linux kernel source tree with KUnit tests.""" - def __init__(self) -> None: - self._ops = LinuxSourceTreeOperations() + def __init__(self, build_dir: str, load_config=True, defconfig=DEFAULT_KUNITCONFIG_PATH) -> None: signal.signal(signal.SIGINT, self.signal_handler) - def clean(self) -> bool: - try: - self._ops.make_mrproper() - except ConfigError as e: - logging.error(e) - return False - return True + self._ops = LinuxSourceTreeOperations() + + if not load_config: + return - def create_kunitconfig(self, build_dir, defconfig=DEFAULT_KUNITCONFIG_PATH) -> None: kunitconfig_path = get_kunitconfig_path(build_dir) if not os.path.exists(kunitconfig_path): shutil.copyfile(defconfig, kunitconfig_path) - def read_kunitconfig(self, build_dir) -> None: - kunitconfig_path = get_kunitconfig_path(build_dir) self._kconfig = kunit_config.Kconfig() self._kconfig.read_from_file(kunitconfig_path) + def clean(self) -> bool: + try: + self._ops.make_mrproper() + except ConfigError as e: + logging.error(e) + return False + return True + def validate_config(self, build_dir) -> bool: kconfig_path = get_kconfig_path(build_dir) validated_kconfig = kunit_config.Kconfig() -- GitLab From e4bedf48aaa5552bc1f49703abd17606e7e6e82a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 14 Jan 2021 08:06:37 -0800 Subject: [PATCH 0276/1084] net_sched: reject silly cell_log in qdisc_get_rtab() iproute2 probably never goes beyond 8 for the cell exponent, but stick to the max shift exponent for signed 32bit. UBSAN reported: UBSAN: shift-out-of-bounds in net/sched/sch_api.c:389:22 shift exponent 130 is too large for 32-bit type 'int' CPU: 1 PID: 8450 Comm: syz-executor586 Not tainted 5.11.0-rc3-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x183/0x22e lib/dump_stack.c:120 ubsan_epilogue lib/ubsan.c:148 [inline] __ubsan_handle_shift_out_of_bounds+0x432/0x4d0 lib/ubsan.c:395 __detect_linklayer+0x2a9/0x330 net/sched/sch_api.c:389 qdisc_get_rtab+0x2b5/0x410 net/sched/sch_api.c:435 cbq_init+0x28f/0x12c0 net/sched/sch_cbq.c:1180 qdisc_create+0x801/0x1470 net/sched/sch_api.c:1246 tc_modify_qdisc+0x9e3/0x1fc0 net/sched/sch_api.c:1662 rtnetlink_rcv_msg+0xb1d/0xe60 net/core/rtnetlink.c:5564 netlink_rcv_skb+0x1f0/0x460 net/netlink/af_netlink.c:2494 netlink_unicast_kernel net/netlink/af_netlink.c:1304 [inline] netlink_unicast+0x7de/0x9b0 net/netlink/af_netlink.c:1330 netlink_sendmsg+0xaa6/0xe90 net/netlink/af_netlink.c:1919 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg net/socket.c:672 [inline] ____sys_sendmsg+0x5a2/0x900 net/socket.c:2345 ___sys_sendmsg net/socket.c:2399 [inline] __sys_sendmsg+0x319/0x400 net/socket.c:2432 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet Reported-by: syzbot Acked-by: Cong Wang Link: https://lore.kernel.org/r/20210114160637.1660597-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski --- net/sched/sch_api.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 51cb553e4317a..6fe4e5cc807c9 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -412,7 +412,8 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, { struct qdisc_rate_table *rtab; - if (tab == NULL || r->rate == 0 || r->cell_log == 0 || + if (tab == NULL || r->rate == 0 || + r->cell_log == 0 || r->cell_log >= 32 || nla_len(tab) != TC_RTAB_SIZE) { NL_SET_ERR_MSG(extack, "Invalid rate table parameters for searching"); return NULL; -- GitLab From dd5e073381f2ada3630f36be42833c6e9c78b75e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 14 Jan 2021 10:19:29 -0800 Subject: [PATCH 0277/1084] net_sched: gen_estimator: support large ewma log syzbot report reminded us that very big ewma_log were supported in the past, even if they made litle sense. tc qdisc replace dev xxx root est 1sec 131072sec ... While fixing the bug, also add boundary checks for ewma_log, in line with range supported by iproute2. UBSAN: shift-out-of-bounds in net/core/gen_estimator.c:83:38 shift exponent -1 is negative CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.0-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x107/0x163 lib/dump_stack.c:120 ubsan_epilogue+0xb/0x5a lib/ubsan.c:148 __ubsan_handle_shift_out_of_bounds.cold+0xb1/0x181 lib/ubsan.c:395 est_timer.cold+0xbb/0x12d net/core/gen_estimator.c:83 call_timer_fn+0x1a5/0x710 kernel/time/timer.c:1417 expire_timers kernel/time/timer.c:1462 [inline] __run_timers.part.0+0x692/0xa80 kernel/time/timer.c:1731 __run_timers kernel/time/timer.c:1712 [inline] run_timer_softirq+0xb3/0x1d0 kernel/time/timer.c:1744 __do_softirq+0x2bc/0xa77 kernel/softirq.c:343 asm_call_irq_on_stack+0xf/0x20 __run_on_irqstack arch/x86/include/asm/irq_stack.h:26 [inline] run_on_irqstack_cond arch/x86/include/asm/irq_stack.h:77 [inline] do_softirq_own_stack+0xaa/0xd0 arch/x86/kernel/irq_64.c:77 invoke_softirq kernel/softirq.c:226 [inline] __irq_exit_rcu+0x17f/0x200 kernel/softirq.c:420 irq_exit_rcu+0x5/0x20 kernel/softirq.c:432 sysvec_apic_timer_interrupt+0x4d/0x100 arch/x86/kernel/apic/apic.c:1096 asm_sysvec_apic_timer_interrupt+0x12/0x20 arch/x86/include/asm/idtentry.h:628 RIP: 0010:native_save_fl arch/x86/include/asm/irqflags.h:29 [inline] RIP: 0010:arch_local_save_flags arch/x86/include/asm/irqflags.h:79 [inline] RIP: 0010:arch_irqs_disabled arch/x86/include/asm/irqflags.h:169 [inline] RIP: 0010:acpi_safe_halt drivers/acpi/processor_idle.c:111 [inline] RIP: 0010:acpi_idle_do_entry+0x1c9/0x250 drivers/acpi/processor_idle.c:516 Fixes: 1c0d32fde5bd ("net_sched: gen_estimator: complete rewrite of rate estimators") Signed-off-by: Eric Dumazet Reported-by: syzbot Link: https://lore.kernel.org/r/20210114181929.1717985-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski --- net/core/gen_estimator.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 80dbf2f4016e2..8e582e29a41e3 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -80,11 +80,11 @@ static void est_timer(struct timer_list *t) u64 rate, brate; est_fetch_counters(est, &b); - brate = (b.bytes - est->last_bytes) << (10 - est->ewma_log - est->intvl_log); - brate -= (est->avbps >> est->ewma_log); + brate = (b.bytes - est->last_bytes) << (10 - est->intvl_log); + brate = (brate >> est->ewma_log) - (est->avbps >> est->ewma_log); - rate = (b.packets - est->last_packets) << (10 - est->ewma_log - est->intvl_log); - rate -= (est->avpps >> est->ewma_log); + rate = (b.packets - est->last_packets) << (10 - est->intvl_log); + rate = (rate >> est->ewma_log) - (est->avpps >> est->ewma_log); write_seqcount_begin(&est->seq); est->avbps += brate; @@ -143,6 +143,9 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, if (parm->interval < -2 || parm->interval > 3) return -EINVAL; + if (parm->ewma_log == 0 || parm->ewma_log >= 31) + return -EINVAL; + est = kzalloc(sizeof(*est), GFP_KERNEL); if (!est) return -ENOBUFS; -- GitLab From bcd0cf19ef8258ac31b9a20248b05c15a1f4b4b0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 14 Jan 2021 10:52:29 -0800 Subject: [PATCH 0278/1084] net_sched: avoid shift-out-of-bounds in tcindex_set_parms() tc_index being 16bit wide, we need to check that TCA_TCINDEX_SHIFT attribute is not silly. UBSAN: shift-out-of-bounds in net/sched/cls_tcindex.c:260:29 shift exponent 255 is too large for 32-bit type 'int' CPU: 0 PID: 8516 Comm: syz-executor228 Not tainted 5.10.0-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x107/0x163 lib/dump_stack.c:120 ubsan_epilogue+0xb/0x5a lib/ubsan.c:148 __ubsan_handle_shift_out_of_bounds.cold+0xb1/0x181 lib/ubsan.c:395 valid_perfect_hash net/sched/cls_tcindex.c:260 [inline] tcindex_set_parms.cold+0x1b/0x215 net/sched/cls_tcindex.c:425 tcindex_change+0x232/0x340 net/sched/cls_tcindex.c:546 tc_new_tfilter+0x13fb/0x21b0 net/sched/cls_api.c:2127 rtnetlink_rcv_msg+0x8b6/0xb80 net/core/rtnetlink.c:5555 netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2494 netlink_unicast_kernel net/netlink/af_netlink.c:1304 [inline] netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1330 netlink_sendmsg+0x907/0xe40 net/netlink/af_netlink.c:1919 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:672 ____sys_sendmsg+0x6e8/0x810 net/socket.c:2336 ___sys_sendmsg+0xf3/0x170 net/socket.c:2390 __sys_sendmsg+0xe5/0x1b0 net/socket.c:2423 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet Reported-by: syzbot Link: https://lore.kernel.org/r/20210114185229.1742255-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski --- net/sched/cls_tcindex.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 78bec347b8b66..c4007b9cd16d6 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -366,9 +366,13 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, if (tb[TCA_TCINDEX_MASK]) cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]); - if (tb[TCA_TCINDEX_SHIFT]) + if (tb[TCA_TCINDEX_SHIFT]) { cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]); - + if (cp->shift > 16) { + err = -EINVAL; + goto errout; + } + } if (!cp->hash) { /* Hash not specified, use perfect hash if the upper limit * of the hashing index is below the threshold. -- GitLab From fca05d4d61e65fa573a3768f9019a42143c03349 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 16 Jan 2021 12:26:46 +0100 Subject: [PATCH 0279/1084] netfilter: nft_dynset: honor stateful expressions in set definition If the set definition contains stateful expressions, allocate them for the newly added entries from the packet path. Fixes: 65038428b2c6 ("netfilter: nf_tables: allow to specify stateful expression in set definition") Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables.h | 2 ++ net/netfilter/nf_tables_api.c | 5 ++--- net/netfilter/nft_dynset.c | 6 ++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index f4af8362d2348..4b6ecf5326238 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -721,6 +721,8 @@ void *nft_set_elem_init(const struct nft_set *set, const struct nft_set_ext_tmpl *tmpl, const u32 *key, const u32 *key_end, const u32 *data, u64 timeout, u64 expiration, gfp_t gfp); +int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set, + struct nft_expr *expr_array[]); void nft_set_elem_destroy(const struct nft_set *set, void *elem, bool destroy_expr); diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 15c467f1a9dd9..8d3aa97b52e71 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5235,9 +5235,8 @@ static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx, kfree(elem); } -static int nft_set_elem_expr_clone(const struct nft_ctx *ctx, - struct nft_set *set, - struct nft_expr *expr_array[]) +int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set, + struct nft_expr *expr_array[]) { struct nft_expr *expr; int err, i, k; diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c index 0b053f75cd604..86204740f6c71 100644 --- a/net/netfilter/nft_dynset.c +++ b/net/netfilter/nft_dynset.c @@ -295,6 +295,12 @@ static int nft_dynset_init(const struct nft_ctx *ctx, err = -EOPNOTSUPP; goto err_expr_free; } + } else if (set->num_exprs > 0) { + err = nft_set_elem_expr_clone(ctx, set, priv->expr_array); + if (err < 0) + return err; + + priv->num_exprs = set->num_exprs; } nft_set_ext_prepare(&priv->tmpl); -- GitLab From 0c5b7a501e7400869ee905b4f7af3d6717802bcb Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 16 Jan 2021 19:20:15 +0100 Subject: [PATCH 0280/1084] netfilter: nft_dynset: add timeout extension to template Otherwise, the newly create element shows no timeout when listing the ruleset. If the set definition does not specify a default timeout, then the set element only shows the expiration time, but not the timeout. This is a problem when restoring a stateful ruleset listing since it skips the timeout policy entirely. Fixes: 22fe54d5fefc ("netfilter: nf_tables: add support for dynamic set updates") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_dynset.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c index 86204740f6c71..218c09e4fdddd 100644 --- a/net/netfilter/nft_dynset.c +++ b/net/netfilter/nft_dynset.c @@ -312,8 +312,10 @@ static int nft_dynset_init(const struct nft_ctx *ctx, nft_dynset_ext_add_expr(priv); if (set->flags & NFT_SET_TIMEOUT) { - if (timeout || set->timeout) + if (timeout || set->timeout) { + nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_TIMEOUT); nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION); + } } priv->timeout = timeout; -- GitLab From ce5379963b2884e9d23bea0c5674a7251414c84b Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 16 Jan 2021 19:50:34 +0100 Subject: [PATCH 0281/1084] netfilter: nft_dynset: dump expressions when set definition contains no expressions If the set definition provides no stateful expressions, then include the stateful expression in the ruleset listing. Without this fix, the dynset rule listing shows the stateful expressions provided by the set definition. Fixes: 65038428b2c6 ("netfilter: nf_tables: allow to specify stateful expression in set definition") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_dynset.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c index 218c09e4fdddd..d164ef9e68439 100644 --- a/net/netfilter/nft_dynset.c +++ b/net/netfilter/nft_dynset.c @@ -384,22 +384,25 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr) nf_jiffies64_to_msecs(priv->timeout), NFTA_DYNSET_PAD)) goto nla_put_failure; - if (priv->num_exprs == 1) { - if (nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr_array[0])) - goto nla_put_failure; - } else if (priv->num_exprs > 1) { - struct nlattr *nest; - - nest = nla_nest_start_noflag(skb, NFTA_DYNSET_EXPRESSIONS); - if (!nest) - goto nla_put_failure; - - for (i = 0; i < priv->num_exprs; i++) { - if (nft_expr_dump(skb, NFTA_LIST_ELEM, - priv->expr_array[i])) + if (priv->set->num_exprs == 0) { + if (priv->num_exprs == 1) { + if (nft_expr_dump(skb, NFTA_DYNSET_EXPR, + priv->expr_array[0])) goto nla_put_failure; + } else if (priv->num_exprs > 1) { + struct nlattr *nest; + + nest = nla_nest_start_noflag(skb, NFTA_DYNSET_EXPRESSIONS); + if (!nest) + goto nla_put_failure; + + for (i = 0; i < priv->num_exprs; i++) { + if (nft_expr_dump(skb, NFTA_LIST_ELEM, + priv->expr_array[i])) + goto nla_put_failure; + } + nla_nest_end(skb, nest); } - nla_nest_end(skb, nest); } if (nla_put_be32(skb, NFTA_DYNSET_FLAGS, htonl(flags))) goto nla_put_failure; -- GitLab From c93cc9e16d88e0f5ea95d2d65d58a8a4dab258bc Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 16 Jan 2021 11:52:11 -0700 Subject: [PATCH 0282/1084] io_uring: iopoll requests should also wake task ->in_idle state If we're freeing/finishing iopoll requests, ensure we check if the task is in idling in terms of cancelation. Otherwise we could end up waiting forever in __io_uring_task_cancel() if the task has active iopoll requests that need cancelation. Cc: stable@vger.kernel.org # 5.9+ Signed-off-by: Jens Axboe --- fs/io_uring.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index 985a9e3f976d3..5cda878b69cfd 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2270,6 +2270,8 @@ static void io_req_free_batch_finish(struct io_ring_ctx *ctx, struct io_uring_task *tctx = rb->task->io_uring; percpu_counter_sub(&tctx->inflight, rb->task_refs); + if (atomic_read(&tctx->in_idle)) + wake_up(&tctx->wait); put_task_struct_many(rb->task, rb->task_refs); rb->task = NULL; } @@ -2288,6 +2290,8 @@ static void io_req_free_batch(struct req_batch *rb, struct io_kiocb *req) struct io_uring_task *tctx = rb->task->io_uring; percpu_counter_sub(&tctx->inflight, rb->task_refs); + if (atomic_read(&tctx->in_idle)) + wake_up(&tctx->wait); put_task_struct_many(rb->task, rb->task_refs); } rb->task = req->task; -- GitLab From 6b393a1ff1746a1c91bd95cbb2d79b104d8f15ac Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sat, 16 Jan 2021 05:32:29 +0000 Subject: [PATCH 0283/1084] io_uring: fix false positive sqo warning on flush WARNING: CPU: 1 PID: 9094 at fs/io_uring.c:8884 io_disable_sqo_submit+0x106/0x130 fs/io_uring.c:8884 Call Trace: io_uring_flush+0x28b/0x3a0 fs/io_uring.c:9099 filp_close+0xb4/0x170 fs/open.c:1280 close_fd+0x5c/0x80 fs/file.c:626 __do_sys_close fs/open.c:1299 [inline] __se_sys_close fs/open.c:1297 [inline] __x64_sys_close+0x2f/0xa0 fs/open.c:1297 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xa9 io_uring's final close() may be triggered by any task not only the creator. It's well handled by io_uring_flush() including SQPOLL case, though a warning in io_disable_sqo_submit() will fallaciously fire by moving this warning out to the only call site that matters. Reported-by: syzbot+2f5d1785dc624932da78@syzkaller.appspotmail.com Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 5cda878b69cfd..616c5f732a269 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -8918,8 +8918,6 @@ static void __io_uring_cancel_task_requests(struct io_ring_ctx *ctx, static void io_disable_sqo_submit(struct io_ring_ctx *ctx) { - WARN_ON_ONCE(ctx->sqo_task != current); - mutex_lock(&ctx->uring_lock); ctx->sqo_dead = 1; mutex_unlock(&ctx->uring_lock); @@ -8941,6 +8939,7 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx, if ((ctx->flags & IORING_SETUP_SQPOLL) && ctx->sq_data) { /* for SQPOLL only sqo_task has task notes */ + WARN_ON_ONCE(ctx->sqo_task != current); io_disable_sqo_submit(ctx); task = ctx->sq_data->thread; atomic_inc(&task->io_uring->in_idle); -- GitLab From 4325cb498cb743dacaa3edbec398c5255f476ef6 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sat, 16 Jan 2021 05:32:30 +0000 Subject: [PATCH 0284/1084] io_uring: fix uring_flush in exit_files() warning WARNING: CPU: 1 PID: 11100 at fs/io_uring.c:9096 io_uring_flush+0x326/0x3a0 fs/io_uring.c:9096 RIP: 0010:io_uring_flush+0x326/0x3a0 fs/io_uring.c:9096 Call Trace: filp_close+0xb4/0x170 fs/open.c:1280 close_files fs/file.c:401 [inline] put_files_struct fs/file.c:416 [inline] put_files_struct+0x1cc/0x350 fs/file.c:413 exit_files+0x7e/0xa0 fs/file.c:433 do_exit+0xc22/0x2ae0 kernel/exit.c:820 do_group_exit+0x125/0x310 kernel/exit.c:922 get_signal+0x3e9/0x20a0 kernel/signal.c:2770 arch_do_signal_or_restart+0x2a8/0x1eb0 arch/x86/kernel/signal.c:811 handle_signal_work kernel/entry/common.c:147 [inline] exit_to_user_mode_loop kernel/entry/common.c:171 [inline] exit_to_user_mode_prepare+0x148/0x250 kernel/entry/common.c:201 __syscall_exit_to_user_mode_work kernel/entry/common.c:291 [inline] syscall_exit_to_user_mode+0x19/0x50 kernel/entry/common.c:302 entry_SYSCALL_64_after_hwframe+0x44/0xa9 An SQPOLL ring creator task may have gotten rid of its file note during exit and called io_disable_sqo_submit(), but the io_uring is still left referenced through fdtable, which will be put during close_files() and cause a false positive warning. First split the warning into two for more clarity when is hit, and the add sqo_dead check to handle the described case. Reported-by: syzbot+a32b546d58dde07875a1@syzkaller.appspotmail.com Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 616c5f732a269..d494c4269fc5e 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -9131,7 +9131,10 @@ static int io_uring_flush(struct file *file, void *data) if (ctx->flags & IORING_SETUP_SQPOLL) { /* there is only one file note, which is owned by sqo_task */ - WARN_ON_ONCE((ctx->sqo_task == current) == + WARN_ON_ONCE(ctx->sqo_task != current && + xa_load(&tctx->xa, (unsigned long)file)); + /* sqo_dead check is for when this happens after cancellation */ + WARN_ON_ONCE(ctx->sqo_task == current && !ctx->sqo_dead && !xa_load(&tctx->xa, (unsigned long)file)); io_disable_sqo_submit(ctx); -- GitLab From 66c556025d687dbdd0f748c5e1df89c977b6c02a Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Fri, 15 Jan 2021 15:04:40 +0000 Subject: [PATCH 0285/1084] skbuff: back tiny skbs with kmalloc() in __netdev_alloc_skb() too Commit 3226b158e67c ("net: avoid 32 x truesize under-estimation for tiny skbs") ensured that skbs with data size lower than 1025 bytes will be kmalloc'ed to avoid excessive page cache fragmentation and memory consumption. However, the fix adressed only __napi_alloc_skb() (primarily for virtio_net and napi_get_frags()), but the issue can still be achieved through __netdev_alloc_skb(), which is still used by several drivers. Drivers often allocate a tiny skb for headers and place the rest of the frame to frags (so-called copybreak). Mirror the condition to __netdev_alloc_skb() to handle this case too. Since v1 [0]: - fix "Fixes:" tag; - refine commit message (mention copybreak usecase). [0] https://lore.kernel.org/netdev/20210114235423.232737-1-alobakin@pm.me Fixes: a1c7fff7e18f ("net: netdev_alloc_skb() use build_skb()") Signed-off-by: Alexander Lobakin Link: https://lore.kernel.org/r/20210115150354.85967-1-alobakin@pm.me Signed-off-by: Jakub Kicinski --- net/core/skbuff.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c1a6f262636a1..785daff48030d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -437,7 +437,11 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, len += NET_SKB_PAD; - if ((len > SKB_WITH_OVERHEAD(PAGE_SIZE)) || + /* If requested length is either too small or too big, + * we use kmalloc() for skb->head allocation. + */ + if (len <= SKB_WITH_OVERHEAD(1024) || + len > SKB_WITH_OVERHEAD(PAGE_SIZE) || (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) { skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX, NUMA_NO_NODE); if (!skb) -- GitLab From 0b5cd6c32b14413bf87e10ee62be3162588dcbe6 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sun, 17 Jan 2021 02:29:56 +0000 Subject: [PATCH 0286/1084] io_uring: fix skipping disabling sqo on exec If there are no requests at the time __io_uring_task_cancel() is called, tctx_inflight() returns zero and and it terminates not getting a chance to go through __io_uring_files_cancel() and do io_disable_sqo_submit(). And we absolutely want them disabled by the time cancellation ends. Reported-by: Jens Axboe Signed-off-by: Pavel Begunkov Fixes: d9d05217cb69 ("io_uring: stop SQPOLL submit on creator's death") Signed-off-by: Jens Axboe --- fs/io_uring.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index d494c4269fc5e..383ff6ed37342 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -9085,6 +9085,10 @@ void __io_uring_task_cancel(void) /* make sure overflow events are dropped */ atomic_inc(&tctx->in_idle); + /* trigger io_disable_sqo_submit() */ + if (tctx->sqpoll) + __io_uring_files_cancel(NULL); + do { /* read completions before cancelations */ inflight = tctx_inflight(tctx); -- GitLab From bc1c2048abbe3c3074b4de91d213595c57741a6b Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Tue, 12 Jan 2021 12:22:25 +0200 Subject: [PATCH 0287/1084] i2c: bpmp-tegra: Ignore unknown I2C_M flags In order to not to start returning errors when new I2C_M flags are added, change behavior to just ignore all flags that we don't know about. This includes the I2C_M_DMA_SAFE flag that already exists but causes -EINVAL to be returned for valid transactions. Cc: stable@vger.kernel.org # v4.19+ Signed-off-by: Mikko Perttunen Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-tegra-bpmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-tegra-bpmp.c b/drivers/i2c/busses/i2c-tegra-bpmp.c index ec7a7e917eddb..c0c7d01473f2b 100644 --- a/drivers/i2c/busses/i2c-tegra-bpmp.c +++ b/drivers/i2c/busses/i2c-tegra-bpmp.c @@ -80,7 +80,7 @@ static int tegra_bpmp_xlate_flags(u16 flags, u16 *out) flags &= ~I2C_M_RECV_LEN; } - return (flags != 0) ? -EINVAL : 0; + return 0; } /** -- GitLab From 2f3a0828d46166d4e7df227479ed31766ee67e4a Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Tue, 12 Jan 2021 11:02:41 -0800 Subject: [PATCH 0288/1084] i2c: tegra: Create i2c_writesl_vi() to use with VI I2C for filling TX FIFO VI I2C controller has known hardware bug where immediate multiple writes to TX_FIFO register gets stuck. Recommended software work around is to read I2C register after each write to TX_FIFO register to flush out the data. This patch implements this work around for VI I2C controller. Signed-off-by: Sowjanya Komatineni Reviewed-by: Dmitry Osipenko Acked-by: Thierry Reding Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-tegra.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 0727383f49402..8b113ae32dc71 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -326,6 +326,8 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg) /* read back register to make sure that register writes completed */ if (reg != I2C_TX_FIFO) readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg)); + else if (i2c_dev->is_vi) + readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, I2C_INT_STATUS)); } static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg) @@ -339,6 +341,21 @@ static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data, writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len); } +static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data, + unsigned int reg, unsigned int len) +{ + u32 *data32 = data; + + /* + * VI I2C controller has known hardware bug where writes get stuck + * when immediate multiple writes happen to TX_FIFO register. + * Recommended software work around is to read I2C register after + * each write to TX_FIFO register to flush out the data. + */ + while (len--) + i2c_writel(i2c_dev, *data32++, reg); +} + static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data, unsigned int reg, unsigned int len) { @@ -811,7 +828,10 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev) i2c_dev->msg_buf_remaining = buf_remaining; i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD; - i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer); + if (i2c_dev->is_vi) + i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer); + else + i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer); buf += words_to_transfer * BYTES_PER_FIFO_WORD; } -- GitLab From 1b2cfa2d1dbdcc3b6dba1ecb7026a537a1d7277f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 9 Jan 2021 13:43:08 +0100 Subject: [PATCH 0289/1084] i2c: octeon: check correct size of maximum RECV_LEN packet I2C_SMBUS_BLOCK_MAX defines already the maximum number as defined in the SMBus 2.0 specs. No reason to add one to it. Fixes: 886f6f8337dd ("i2c: octeon: Support I2C_M_RECV_LEN") Signed-off-by: Wolfram Sang Reviewed-by: Robert Richter Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-octeon-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c index d9607905dc2f1..845eda70b8cab 100644 --- a/drivers/i2c/busses/i2c-octeon-core.c +++ b/drivers/i2c/busses/i2c-octeon-core.c @@ -347,7 +347,7 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target, if (result) return result; if (recv_len && i == 0) { - if (data[i] > I2C_SMBUS_BLOCK_MAX + 1) + if (data[i] > I2C_SMBUS_BLOCK_MAX) return -EPROTO; length += data[i]; } -- GitLab From 32c2bc8f2d855d4415c9a05b727e34649397bfbe Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Fri, 18 Dec 2020 18:35:50 +0200 Subject: [PATCH 0290/1084] ia64: fix build failure caused by memory model changes The change of ia64's default memory model to SPARSEMEM causes defconfig build to fail: CC kernel/async.o In file included from include/linux/numa.h:25, from include/linux/async.h:13, from kernel/async.c:47: arch/ia64/include/asm/sparsemem.h:14:40: warning: "PAGE_SHIFT" is not defined, evaluates to 0 [-Wundef] 14 | #if ((CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS) | ^~~~~~~~~~ In file included from include/linux/gfp.h:6, from include/linux/xarray.h:14, from include/linux/radix-tree.h:19, from include/linux/idr.h:15, from include/linux/kernfs.h:13, from include/linux/sysfs.h:16, from include/linux/kobject.h:20, from include/linux/energy_model.h:7, from include/linux/device.h:16, from include/linux/async.h:14, from kernel/async.c:47: include/linux/mmzone.h:1156:2: error: #error Allocator MAX_ORDER exceeds SECTION_SIZE 1156 | #error Allocator MAX_ORDER exceeds SECTION_SIZE | ^~~~~ The error cause is the missing definition of PAGE_SHIFT in the calculation of SECTION_SIZE_BITS. Add include of to arch/ia64/include/asm/sparsemem.h to solve the problem. Fixes: 214496cb1870 ("ia64: make SPARSEMEM default and disable DISCONTIGMEM") Reported-by: Guenter Roeck Tested-by: Guenter Roeck Signed-off-by: Mike Rapoport --- arch/ia64/include/asm/sparsemem.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/ia64/include/asm/sparsemem.h b/arch/ia64/include/asm/sparsemem.h index dd8c166ffd7b5..42ed5248fae98 100644 --- a/arch/ia64/include/asm/sparsemem.h +++ b/arch/ia64/include/asm/sparsemem.h @@ -3,6 +3,7 @@ #define _ASM_IA64_SPARSEMEM_H #ifdef CONFIG_SPARSEMEM +#include /* * SECTION_SIZE_BITS 2^N: how big each section will be * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space -- GitLab From fff7b5e6ee63c5d20406a131b260c619cdd24fd1 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Sat, 16 Jan 2021 14:31:36 -0800 Subject: [PATCH 0291/1084] x86/hyperv: Initialize clockevents after LAPIC is initialized With commit 4df4cb9e99f8, the Hyper-V direct-mode STIMER is actually initialized before LAPIC is initialized: see apic_intr_mode_init() x86_platform.apic_post_init() hyperv_init() hv_stimer_alloc() apic_bsp_setup() setup_local_APIC() setup_local_APIC() temporarily disables LAPIC, initializes it and re-eanble it. The direct-mode STIMER depends on LAPIC, and when it's registered, it can be programmed immediately and the timer can fire very soon: hv_stimer_init clockevents_config_and_register clockevents_register_device tick_check_new_device tick_setup_device tick_setup_periodic(), tick_setup_oneshot() clockevents_program_event When the timer fires in the hypervisor, if the LAPIC is in the disabled state, new versions of Hyper-V ignore the event and don't inject the timer interrupt into the VM, and hence the VM hangs when it boots. Note: when the VM starts/reboots, the LAPIC is pre-enabled by the firmware, so the window of LAPIC being temporarily disabled is pretty small, and the issue can only happen once out of 100~200 reboots for a 40-vCPU VM on one dev host, and on another host the issue doesn't reproduce after 2000 reboots. The issue is more noticeable for kdump/kexec, because the LAPIC is disabled by the first kernel, and stays disabled until the kdump/kexec kernel enables it. This is especially an issue to a Generation-2 VM (for which Hyper-V doesn't emulate the PIT timer) when CONFIG_HZ=1000 (rather than CONFIG_HZ=250) is used. Fix the issue by moving hv_stimer_alloc() to a later place where the LAPIC timer is initialized. Fixes: 4df4cb9e99f8 ("x86/hyperv: Initialize clockevents earlier in CPU onlining") Signed-off-by: Dexuan Cui Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/20210116223136.13892-1-decui@microsoft.com Signed-off-by: Wei Liu --- arch/x86/hyperv/hv_init.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 4638a52d8eaea..6375967a8244d 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -315,6 +315,25 @@ static struct syscore_ops hv_syscore_ops = { .resume = hv_resume, }; +static void (* __initdata old_setup_percpu_clockev)(void); + +static void __init hv_stimer_setup_percpu_clockev(void) +{ + /* + * Ignore any errors in setting up stimer clockevents + * as we can run with the LAPIC timer as a fallback. + */ + (void)hv_stimer_alloc(); + + /* + * Still register the LAPIC timer, because the direct-mode STIMER is + * not supported by old versions of Hyper-V. This also allows users + * to switch to LAPIC timer via /sys, if they want to. + */ + if (old_setup_percpu_clockev) + old_setup_percpu_clockev(); +} + /* * This function is to be invoked early in the boot sequence after the * hypervisor has been detected. @@ -393,10 +412,14 @@ void __init hyperv_init(void) wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); /* - * Ignore any errors in setting up stimer clockevents - * as we can run with the LAPIC timer as a fallback. + * hyperv_init() is called before LAPIC is initialized: see + * apic_intr_mode_init() -> x86_platform.apic_post_init() and + * apic_bsp_setup() -> setup_local_APIC(). The direct-mode STIMER + * depends on LAPIC, so hv_stimer_alloc() should be called from + * x86_init.timers.setup_percpu_clockev. */ - (void)hv_stimer_alloc(); + old_setup_percpu_clockev = x86_init.timers.setup_percpu_clockev; + x86_init.timers.setup_percpu_clockev = hv_stimer_setup_percpu_clockev; hv_apic_init(); -- GitLab From 2be449fcf38ff7e44cf76a2bba1376e923637eb1 Mon Sep 17 00:00:00 2001 From: Jiapeng Zhong Date: Thu, 14 Jan 2021 17:09:20 +0800 Subject: [PATCH 0292/1084] fs/cifs: Assign boolean values to a bool variable Fix the following coccicheck warnings: ./fs/cifs/connect.c:3386:2-21: WARNING: Assignment of 0/1 to bool variable. Reported-by: Abaci Robot Signed-off-by: Jiapeng Zhong Signed-off-by: Steve French --- fs/cifs/connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 5d39129406ea6..7c3325c0fadc8 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2195,7 +2195,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) tcon->nohandlecache = ctx->nohandlecache; else - tcon->nohandlecache = 1; + tcon->nohandlecache = true; tcon->nodelete = ctx->nodelete; tcon->local_lease = ctx->local_lease; INIT_LIST_HEAD(&tcon->pending_opens); -- GitLab From 16a78851e1f52eaed7034b75707d3662b4b13b77 Mon Sep 17 00:00:00 2001 From: Jiapeng Zhong Date: Thu, 14 Jan 2021 18:02:23 +0800 Subject: [PATCH 0293/1084] fs/cifs: Simplify bool comparison. Fix the follow warnings: ./fs/cifs/connect.c: WARNING: Comparison of 0/1 to bool variable Reported-by: Abaci Robot Signed-off-by: Jiapeng Zhong Signed-off-by: Steve French --- fs/cifs/connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 7c3325c0fadc8..c8ef24bac94fc 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2628,7 +2628,7 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, } else if (ctx) tcon->unix_ext = 1; /* Unix Extensions supported */ - if (tcon->unix_ext == 0) { + if (!tcon->unix_ext) { cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n"); return; } -- GitLab From bd9dcef67ffcae2de49e319fba349df76472fd10 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 15 Jan 2021 11:11:23 -0800 Subject: [PATCH 0294/1084] x86/xen: fix 'nopvspin' build error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix build error in x86/xen/ when PARAVIRT_SPINLOCKS is not enabled. Fixes this build error: ../arch/x86/xen/smp_hvm.c: In function ‘xen_hvm_smp_init’: ../arch/x86/xen/smp_hvm.c:77:3: error: ‘nopvspin’ undeclared (first use in this function) nopvspin = true; Fixes: 3d7746bea925 ("x86/xen: Fix xen_hvm_smp_init() when vector callback not available") Signed-off-by: Randy Dunlap Reviewed-by: Juergen Gross Cc: David Woodhouse Cc: Juergen Gross Link: https://lore.kernel.org/r/20210115191123.27572-1-rdunlap@infradead.org Signed-off-by: Juergen Gross --- arch/x86/xen/smp_hvm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/xen/smp_hvm.c b/arch/x86/xen/smp_hvm.c index 056430a1080bb..6ff3c887e0b99 100644 --- a/arch/x86/xen/smp_hvm.c +++ b/arch/x86/xen/smp_hvm.c @@ -74,7 +74,9 @@ void __init xen_hvm_smp_init(void) smp_ops.cpu_die = xen_hvm_cpu_die; if (!xen_have_vector_callback) { +#ifdef CONFIG_PARAVIRT_SPINLOCKS nopvspin = true; +#endif return; } -- GitLab From eb363edace688898956b99e48daa8d7e05cee795 Mon Sep 17 00:00:00 2001 From: Bruno Thomsen Date: Mon, 11 Jan 2021 16:15:37 +0100 Subject: [PATCH 0295/1084] ARM: dts: imx7d-flex-concentrator: fix pcf2127 reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RTC pcf2127 device driver has changed default behaviour of the watchdog feature in v5.11-rc1. Now you need to explicitly enable it with a device tree property, "reset-source", when used in the board design. Fixes: 71ac13457d9d ("rtc: pcf2127: only use watchdog when explicitly available") Signed-off-by: Bruno Thomsen Cc: Bruno Thomsen Cc: Uwe Kleine-König Cc: Rasmus Villemoes Reviewed-by: Alexandre Belloni Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx7d-flex-concentrator.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/imx7d-flex-concentrator.dts b/arch/arm/boot/dts/imx7d-flex-concentrator.dts index 84b095279e656..bd6b5285aa8d2 100644 --- a/arch/arm/boot/dts/imx7d-flex-concentrator.dts +++ b/arch/arm/boot/dts/imx7d-flex-concentrator.dts @@ -115,6 +115,7 @@ compatible = "nxp,pcf2127"; reg = <0>; spi-max-frequency = <2000000>; + reset-source; }; }; -- GitLab From a88afa46b86ff461c89cc33fc3a45267fff053e8 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Mon, 11 Jan 2021 16:17:04 +0100 Subject: [PATCH 0296/1084] ARM: imx: build suspend-imx6.S with arm instruction set When the kernel is configured to use the Thumb-2 instruction set "suspend-to-memory" fails to resume. Observed on a Colibri iMX6ULL (i.MX 6ULL) and Apalis iMX6 (i.MX 6Q). It looks like the CPU resumes unconditionally in ARM instruction mode and then chokes on the presented Thumb-2 code it should execute. Fix this by using the arm instruction set for all code in suspend-imx6.S. Signed-off-by: Max Krummenacher Fixes: df595746fa69 ("ARM: imx: add suspend in ocram support for i.mx6q") Acked-by: Oleksandr Suvorov Signed-off-by: Shawn Guo --- arch/arm/mach-imx/suspend-imx6.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S index 1eabf2d2834be..e06f946b75b96 100644 --- a/arch/arm/mach-imx/suspend-imx6.S +++ b/arch/arm/mach-imx/suspend-imx6.S @@ -67,6 +67,7 @@ #define MX6Q_CCM_CCR 0x0 .align 3 + .arm .macro sync_l2_cache -- GitLab From 2cc0bfc9c12784188482a8f3d751d44af45b0d97 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2021 10:53:06 +0000 Subject: [PATCH 0297/1084] ARM: dts: imx6qdl-sr-som: fix some cubox-i platforms The PHY address bit 2 is configured by the LED pin. Attaching a LED to this pin is not sufficient to guarantee this configuration pin is correctly read. This leads to some platforms having their PHY at address 0 and others at address 4. If there is no phy-handle specified, the FEC driver will scan the PHY bus for a PHY and use that. Consequently, adding the DT configuration of the PHY and the phy properties to the FEC driver broke some boards. Fix this by removing the phy-handle property, and listing two PHY entries for both possible PHY addresses, so that the DT configuration for the PHY can be found by the PHY driver. Fixes: 86b08bd5b994 ("ARM: dts: imx6-sr-som: add ethernet PHY configuration") Reported-by: Christoph Mattheis Signed-off-by: Russell King Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl-sr-som.dtsi | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl-sr-som.dtsi b/arch/arm/boot/dts/imx6qdl-sr-som.dtsi index b06577808ff4e..7e4e5fd0143a1 100644 --- a/arch/arm/boot/dts/imx6qdl-sr-som.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sr-som.dtsi @@ -53,7 +53,6 @@ &fec { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_microsom_enet_ar8035>; - phy-handle = <&phy>; phy-mode = "rgmii-id"; phy-reset-duration = <2>; phy-reset-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; @@ -63,10 +62,19 @@ #address-cells = <1>; #size-cells = <0>; - phy: ethernet-phy@0 { + /* + * The PHY can appear at either address 0 or 4 due to the + * configuration (LED) pin not being pulled sufficiently. + */ + ethernet-phy@0 { reg = <0>; qca,clk-out-frequency = <125000000>; }; + + ethernet-phy@4 { + reg = <4>; + qca,clk-out-frequency = <125000000>; + }; }; }; -- GitLab From b764eb65e1c932f0500b30fcc06417cd9bc3e583 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Fri, 15 Jan 2021 09:18:05 +0800 Subject: [PATCH 0298/1084] arm64: dts: imx8mp: Correct the gpio ranges of gpio3 On i.MX8MP, The GPIO3's secondary gpio-ranges's 'gpio controller offset' cell value should be 26, so correct it. Signed-off-by: Jacky Bai Fixes: 6d9b8d20431f ("arm64: dts: freescale: Add i.MX8MP dtsi support") Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index ecccfbb4f5ad6..23f5a5e37167b 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -266,7 +266,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 56 26>, <&iomuxc 0 144 4>; + gpio-ranges = <&iomuxc 0 56 26>, <&iomuxc 26 144 4>; }; gpio4: gpio@30230000 { -- GitLab From 82c082784e03a9a9c043345f9bc04bc8254cf6da Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 15 Jan 2021 19:32:59 -0800 Subject: [PATCH 0299/1084] firmware: imx: select SOC_BUS to fix firmware build Fix build error in firmware/imx/ selecting SOC_BUS. riscv32-linux-ld: drivers/firmware/imx/imx-scu-soc.o: in function `.L9': imx-scu-soc.c:(.text+0x1b0): undefined reference to `soc_device_register' Fixes: edbee095fafb ("firmware: imx: add SCU firmware driver support") Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Atish Patra Cc: Palmer Dabbelt Cc: Ard Biesheuvel Cc: Anson Huang Cc: Daniel Baluta Reviewed-by: Dong Aisheng Signed-off-by: Shawn Guo --- drivers/firmware/imx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/imx/Kconfig b/drivers/firmware/imx/Kconfig index 1d2e5b85d7ca8..c027d99f2a599 100644 --- a/drivers/firmware/imx/Kconfig +++ b/drivers/firmware/imx/Kconfig @@ -13,6 +13,7 @@ config IMX_DSP config IMX_SCU bool "IMX SCU Protocol driver" depends on IMX_MBOX + select SOC_BUS help The System Controller Firmware (SCFW) is a low-level system function which runs on a dedicated Cortex-M core to provide power, clock, and -- GitLab From b3c95d0bdb0855b1f28370629e9eebec6bceac17 Mon Sep 17 00:00:00 2001 From: Anshuman Gupta Date: Mon, 11 Jan 2021 13:41:02 +0530 Subject: [PATCH 0300/1084] drm/i915/hdcp: Update CP property in update_pipe When crtc state need_modeset is true it is not necessary it is going to be a real modeset, it can turns to be a fastset instead of modeset. This turns content protection property to be DESIRED and hdcp update_pipe left with property to be in DESIRED state but actual hdcp->value was ENABLED. This issue is caught with DP MST setup, where we have multiple connector in same DP_MST topology. When disabling HDCP on one of DP MST connector leads to set the crtc state need_modeset to true for all other crtc driving the other DP-MST topology connectors. This turns up other DP MST connectors CP property to be DESIRED despite the actual hdcp->value is ENABLED. Above scenario fails the DP MST HDCP IGT test, disabling HDCP on one MST stream should not cause to disable HDCP on another MST stream on same DP MST topology. v2: - Fixed connector->base.registration_state == DRM_CONNECTOR_REGISTERED WARN_ON. v3: - Commit log improvement. [Uma] - Added a comment before scheduling prop_work. [Uma] Fixes: 33f9a623bfc6 ("drm/i915/hdcp: Update CP as per the kernel internal state") Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Tested-by: Karthik B S Signed-off-by: Anshuman Gupta Link: https://patchwork.freedesktop.org/patch/msgid/20210111081120.28417-2-anshuman.gupta@intel.com (cherry picked from commit d276e16702e2d634094f75f69df3b493f359fe31) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_hdcp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index b2a4bbcfdcd25..eee8263405b9f 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2221,6 +2221,14 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, desired_and_not_enabled = hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED; mutex_unlock(&hdcp->mutex); + /* + * If HDCP already ENABLED and CP property is DESIRED, schedule + * prop_work to update correct CP property to user space. + */ + if (!desired_and_not_enabled && !content_protection_type_changed) { + drm_connector_get(&connector->base); + schedule_work(&hdcp->prop_work); + } } if (desired_and_not_enabled || content_protection_type_changed) -- GitLab From 8662e1119a7d1baa1b2001689b2923e9050754bd Mon Sep 17 00:00:00 2001 From: Anshuman Gupta Date: Mon, 11 Jan 2021 13:41:03 +0530 Subject: [PATCH 0301/1084] drm/i915/hdcp: Get conn while content_type changed Get DRM connector reference count while scheduling a prop work to avoid any possible destroy of DRM connector when it is in DRM_CONNECTOR_REGISTERED state. Fixes: a6597faa2d59 ("drm/i915: Protect workers against disappearing connectors") Cc: Sean Paul Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Tested-by: Karthik B S Signed-off-by: Anshuman Gupta Link: https://patchwork.freedesktop.org/patch/msgid/20210111081120.28417-3-anshuman.gupta@intel.com (cherry picked from commit b3c6661aad979ec3d4f5675cf3e6a35828607d6a) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_hdcp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index eee8263405b9f..b9d8825e2bb12 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2210,6 +2210,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, if (content_protection_type_changed) { mutex_lock(&hdcp->mutex); hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; + drm_connector_get(&connector->base); schedule_work(&hdcp->prop_work); mutex_unlock(&hdcp->mutex); } -- GitLab From bf9eee249ac2032521677dd74e31ede5429afbc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 13 Jan 2021 14:02:04 +0100 Subject: [PATCH 0302/1084] drm/ttm: stop using GFP_TRANSHUGE_LIGHT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only flag we really need is __GFP_NOMEMALLOC, highmem depends on dma32 and moveable/compound should never be set in the first place. Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/413812/ Link: https://patchwork.freedesktop.org/patch/413964/ Fixes: d099fc8f540a ("drm/ttm: new TT backend allocation pool v3") Reported-by: Hans de Goede Reviewed-by: Daniel Vetter --- drivers/gpu/drm/ttm/ttm_pool.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 8cd776adc592b..11e0313db0ea6 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -79,12 +79,13 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags, struct page *p; void *vaddr; - if (order) { - gfp_flags |= GFP_TRANSHUGE_LIGHT | __GFP_NORETRY | + /* Don't set the __GFP_COMP flag for higher order allocations. + * Mapping pages directly into an userspace process and calling + * put_page() on a TTM allocated page is illegal. + */ + if (order) + gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_KSWAPD_RECLAIM; - gfp_flags &= ~__GFP_MOVABLE; - gfp_flags &= ~__GFP_COMP; - } if (!pool->use_dma_alloc) { p = alloc_pages(gfp_flags, order); -- GitLab From 2fe7c2f99440d52613e1cf845c96e8e463c28111 Mon Sep 17 00:00:00 2001 From: Kent Gibson Date: Thu, 7 Jan 2021 12:00:19 +0800 Subject: [PATCH 0303/1084] tools: gpio: fix %llu warning in gpio-event-mon.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some platforms, such as mips64, don't map __u64 to long long unsigned int so using %llu produces a warning: gpio-event-mon.c:110:37: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 3 has type ‘__u64’ {aka ‘long unsigned int’} [-Wformat=] 110 | fprintf(stdout, "GPIO EVENT at %llu on line %d (%d|%d) ", | ~~~^ | | | long long unsigned int | %lu 111 | event.timestamp_ns, event.offset, event.line_seqno, | ~~~~~~~~~~~~~~~~~~ | | | __u64 {aka long unsigned int} Replace the %llu with PRIu64 and cast the argument to uint64_t. Fixes: 03fd11b03362 ("tools/gpio/gpio-event-mon: fix warning") Signed-off-by: Kent Gibson Signed-off-by: Bartosz Golaszewski --- tools/gpio/gpio-event-mon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c index cacd66ad79261..a2b233fdb572e 100644 --- a/tools/gpio/gpio-event-mon.c +++ b/tools/gpio/gpio-event-mon.c @@ -107,8 +107,8 @@ int monitor_device(const char *device_name, ret = -EIO; break; } - fprintf(stdout, "GPIO EVENT at %llu on line %d (%d|%d) ", - event.timestamp_ns, event.offset, event.line_seqno, + fprintf(stdout, "GPIO EVENT at %" PRIu64 " on line %d (%d|%d) ", + (uint64_t)event.timestamp_ns, event.offset, event.line_seqno, event.seqno); switch (event.id) { case GPIO_V2_LINE_EVENT_RISING_EDGE: -- GitLab From 1fc7c1ef37f86f207b4db40aba57084bb2f6a69a Mon Sep 17 00:00:00 2001 From: Kent Gibson Date: Thu, 7 Jan 2021 12:00:20 +0800 Subject: [PATCH 0304/1084] tools: gpio: fix %llu warning in gpio-watch.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some platforms, such as mips64, don't map __u64 to long long unsigned int so using %llu produces a warning: gpio-watch.c: In function ‘main’: gpio-watch.c:89:30: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 4 has type ‘__u64’ {aka ‘long unsigned int’} [-Wformat=] 89 | printf("line %u: %s at %llu\n", | ~~~^ | | | long long unsigned int | %lu 90 | chg.info.offset, event, chg.timestamp_ns); | ~~~~~~~~~~~~~~~~ | | | __u64 {aka long unsigned int} Replace the %llu with PRIu64 and cast the argument to uint64_t. Fixes: 33f0c47b8fb4 ("tools: gpio: implement gpio-watch") Signed-off-by: Kent Gibson Signed-off-by: Bartosz Golaszewski --- tools/gpio/gpio-watch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/gpio/gpio-watch.c b/tools/gpio/gpio-watch.c index f229ec62301b7..41e76d2441922 100644 --- a/tools/gpio/gpio-watch.c +++ b/tools/gpio/gpio-watch.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -86,8 +87,8 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - printf("line %u: %s at %llu\n", - chg.info.offset, event, chg.timestamp_ns); + printf("line %u: %s at %" PRIu64 "\n", + chg.info.offset, event, (uint64_t)chg.timestamp_ns); } } -- GitLab From 33c74535b03ecf11359de14bc88302595b1de44f Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Fri, 15 Jan 2021 20:12:09 +0100 Subject: [PATCH 0305/1084] drm/vc4: Unify PCM card's driver_name User-space ALSA matches a card's driver name against an internal list of aliases in order to select the correct configuration for the system. When the driver name isn't defined, the match is performed against the card's name. With the introduction of RPi4 we now have two HDMI ports with two distinct audio cards. This is reflected in their names, making them different from previous RPi versions. With this, ALSA ultimately misses the board's configuration on RPi4. In order to avoid this, set "card->driver_name" to "vc4-hdmi" unanimously. Signed-off-by: Nicolas Saenz Julienne Fixes: f437bc1ec731 ("drm/vc4: drv: Support BCM2711") Reviewed-by: Takashi Iwai Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20210115191209.12852-1-nsaenzjulienne@suse.de --- drivers/gpu/drm/vc4/vc4_hdmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 5551062205782..98cab0bbe92d8 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1267,6 +1267,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) card->dai_link = dai_link; card->num_links = 1; card->name = vc4_hdmi->variant->card_name; + card->driver_name = "vc4-hdmi"; card->dev = dev; card->owner = THIS_MODULE; -- GitLab From 488751a0ef9b5ce572c47301ce62d54fc6b5a74d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 18 Jan 2021 09:53:32 +0000 Subject: [PATCH 0306/1084] drm/i915/gt: Prevent use of engine->wa_ctx after error On error we unpin and free the wa_ctx.vma, but do not clear any of the derived flags. During lrc_init, we look at the flags and attempt to dereference the wa_ctx.vma if they are set. To protect the error path where we try to limp along without the wa_ctx, make sure we clear those flags! Reported-by: Matt Roper Fixes: 604a8f6f1e33 ("drm/i915/lrc: Only enable per-context and per-bb buffers if set") Signed-off-by: Chris Wilson Cc: Matt Roper Cc: Tvrtko Ursulin Cc: Mika Kuoppala Cc: # v4.15+ Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20210108204026.20682-1-chris@chris-wilson.co.uk (cherry-picked from 5b4dc95cf7f573e927fbbd406ebe54225d41b9b2) Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210118095332.458813-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 7614a3d24fca5..26c7d0a50585a 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -3988,6 +3988,9 @@ static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) static void lrc_destroy_wa_ctx(struct intel_engine_cs *engine) { i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0); + + /* Called on error unwind, clear all flags to prevent further use */ + memset(&engine->wa_ctx, 0, sizeof(engine->wa_ctx)); } typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch); -- GitLab From 171a8e99828144050015672016dd63494c6d200a Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 18 Jan 2021 10:07:24 +0000 Subject: [PATCH 0307/1084] drm/i915/pmu: Don't grab wakeref when enabling events Chris found a CI report which points out calling intel_runtime_pm_get from inside i915_pmu_enable hook is not allowed since it can be invoked from hard irq context. This is something we knew but forgot, so lets fix it once again. We do this by syncing the internal book keeping with hardware rc6 counter on driver load. v2: * Always sync on parking and fully sync on init. Signed-off-by: Tvrtko Ursulin Fixes: f4e9894b6952 ("drm/i915/pmu: Correct the rc6 offset upon enabling") Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201214094349.3563876-1-tvrtko.ursulin@linux.intel.com (cherry picked from commit dbe13ae1d6abaab417edf3c37601c6a56594a4cd) Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210118100724.465555-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_pmu.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index d76685ce03998..9856479b56d8b 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -184,13 +184,24 @@ static u64 get_rc6(struct intel_gt *gt) return val; } -static void park_rc6(struct drm_i915_private *i915) +static void init_rc6(struct i915_pmu *pmu) { - struct i915_pmu *pmu = &i915->pmu; + struct drm_i915_private *i915 = container_of(pmu, typeof(*i915), pmu); + intel_wakeref_t wakeref; - if (pmu->enable & config_enabled_mask(I915_PMU_RC6_RESIDENCY)) + with_intel_runtime_pm(i915->gt.uncore->rpm, wakeref) { pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); + pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = + pmu->sample[__I915_SAMPLE_RC6].cur; + pmu->sleep_last = ktime_get(); + } +} +static void park_rc6(struct drm_i915_private *i915) +{ + struct i915_pmu *pmu = &i915->pmu; + + pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); pmu->sleep_last = ktime_get(); } @@ -201,6 +212,7 @@ static u64 get_rc6(struct intel_gt *gt) return __get_rc6(gt); } +static void init_rc6(struct i915_pmu *pmu) { } static void park_rc6(struct drm_i915_private *i915) {} #endif @@ -612,10 +624,8 @@ static void i915_pmu_enable(struct perf_event *event) container_of(event->pmu, typeof(*i915), pmu.base); unsigned int bit = event_enabled_bit(event); struct i915_pmu *pmu = &i915->pmu; - intel_wakeref_t wakeref; unsigned long flags; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); spin_lock_irqsave(&pmu->lock, flags); /* @@ -626,13 +636,6 @@ static void i915_pmu_enable(struct perf_event *event) GEM_BUG_ON(bit >= ARRAY_SIZE(pmu->enable_count)); GEM_BUG_ON(pmu->enable_count[bit] == ~0); - if (pmu->enable_count[bit] == 0 && - config_enabled_mask(I915_PMU_RC6_RESIDENCY) & BIT_ULL(bit)) { - pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = 0; - pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); - pmu->sleep_last = ktime_get(); - } - pmu->enable |= BIT_ULL(bit); pmu->enable_count[bit]++; @@ -673,8 +676,6 @@ static void i915_pmu_enable(struct perf_event *event) * an existing non-zero value. */ local64_set(&event->hw.prev_count, __i915_pmu_event_read(event)); - - intel_runtime_pm_put(&i915->runtime_pm, wakeref); } static void i915_pmu_disable(struct perf_event *event) @@ -1130,6 +1131,7 @@ void i915_pmu_register(struct drm_i915_private *i915) hrtimer_init(&pmu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); pmu->timer.function = i915_sample; pmu->cpuhp.cpu = -1; + init_rc6(pmu); if (!is_igp(i915)) { pmu->name = kasprintf(GFP_KERNEL, -- GitLab From 45db630e5f7ec83817c57c8ae387fe219bd42adf Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 18 Jan 2021 10:17:55 +0000 Subject: [PATCH 0308/1084] drm/i915: Check for rq->hwsp validity after acquiring RCU lock Since we allow removing the timeline map at runtime, there is a risk that rq->hwsp points into a stale page. To control that risk, we hold the RCU read lock while reading *rq->hwsp, but we missed a couple of important barriers. First, the unpinning / removal of the timeline map must be after all RCU readers into that map are complete, i.e. after an rcu barrier (in this case courtesy of call_rcu()). Secondly, we must make sure that the rq->hwsp we are about to dereference under the RCU lock is valid. In this case, we make the rq->hwsp pointer safe during i915_request_retire() and so we know that rq->hwsp may become invalid only after the request has been signaled. Therefore is the request is not yet signaled when we acquire rq->hwsp under the RCU, we know that rq->hwsp will remain valid for the duration of the RCU read lock. This is a very small window that may lead to either considering the request not completed (causing a delay until the request is checked again, any wait for the request is not affected) or dereferencing an invalid pointer. Fixes: 3adac4689f58 ("drm/i915: Introduce concept of per-timeline (context) HWSP") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: # v5.1+ Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201218122421.18344-1-chris@chris-wilson.co.uk (cherry picked from commit 9bb36cf66091ddf2d8840e5aa705ad3c93a6279b) Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210118101755.476744-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 9 ++--- drivers/gpu/drm/i915/gt/intel_timeline.c | 10 +++--- drivers/gpu/drm/i915/i915_request.h | 37 ++++++++++++++++++--- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index a24cc1ff08a0c..0625cbb3b4312 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -134,11 +134,6 @@ static bool remove_signaling_context(struct intel_breadcrumbs *b, return true; } -static inline bool __request_completed(const struct i915_request *rq) -{ - return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno); -} - __maybe_unused static bool check_signal_order(struct intel_context *ce, struct i915_request *rq) { @@ -257,7 +252,7 @@ static void signal_irq_work(struct irq_work *work) list_for_each_entry_rcu(rq, &ce->signals, signal_link) { bool release; - if (!__request_completed(rq)) + if (!__i915_request_is_complete(rq)) break; if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, @@ -379,7 +374,7 @@ static void insert_breadcrumb(struct i915_request *rq) * straight onto a signaled list, and queue the irq worker for * its signal completion. */ - if (__request_completed(rq)) { + if (__i915_request_is_complete(rq)) { if (__signal_request(rq) && llist_add(&rq->signal_node, &b->signaled_requests)) irq_work_queue(&b->irq_work); diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c index 7ea94d201fe6f..8015964043eb7 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.c +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c @@ -126,6 +126,10 @@ static void __rcu_cacheline_free(struct rcu_head *rcu) struct intel_timeline_cacheline *cl = container_of(rcu, typeof(*cl), rcu); + /* Must wait until after all *rq->hwsp are complete before removing */ + i915_gem_object_unpin_map(cl->hwsp->vma->obj); + __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS)); + i915_active_fini(&cl->active); kfree(cl); } @@ -133,11 +137,6 @@ static void __rcu_cacheline_free(struct rcu_head *rcu) static void __idle_cacheline_free(struct intel_timeline_cacheline *cl) { GEM_BUG_ON(!i915_active_is_idle(&cl->active)); - - i915_gem_object_unpin_map(cl->hwsp->vma->obj); - i915_vma_put(cl->hwsp->vma); - __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS)); - call_rcu(&cl->rcu, __rcu_cacheline_free); } @@ -179,7 +178,6 @@ cacheline_alloc(struct intel_timeline_hwsp *hwsp, unsigned int cacheline) return ERR_CAST(vaddr); } - i915_vma_get(hwsp->vma); cl->hwsp = hwsp; cl->vaddr = page_pack_bits(vaddr, cacheline); diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 620b6fab2c5cf..92adfee30c7c0 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -434,7 +434,7 @@ static inline u32 hwsp_seqno(const struct i915_request *rq) static inline bool __i915_request_has_started(const struct i915_request *rq) { - return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno - 1); + return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno - 1); } /** @@ -465,11 +465,19 @@ static inline bool __i915_request_has_started(const struct i915_request *rq) */ static inline bool i915_request_started(const struct i915_request *rq) { + bool result; + if (i915_request_signaled(rq)) return true; - /* Remember: started but may have since been preempted! */ - return __i915_request_has_started(rq); + result = true; + rcu_read_lock(); /* the HWSP may be freed at runtime */ + if (likely(!i915_request_signaled(rq))) + /* Remember: started but may have since been preempted! */ + result = __i915_request_has_started(rq); + rcu_read_unlock(); + + return result; } /** @@ -482,10 +490,16 @@ static inline bool i915_request_started(const struct i915_request *rq) */ static inline bool i915_request_is_running(const struct i915_request *rq) { + bool result; + if (!i915_request_is_active(rq)) return false; - return __i915_request_has_started(rq); + rcu_read_lock(); + result = __i915_request_has_started(rq) && i915_request_is_active(rq); + rcu_read_unlock(); + + return result; } /** @@ -509,12 +523,25 @@ static inline bool i915_request_is_ready(const struct i915_request *rq) return !list_empty(&rq->sched.link); } +static inline bool __i915_request_is_complete(const struct i915_request *rq) +{ + return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno); +} + static inline bool i915_request_completed(const struct i915_request *rq) { + bool result; + if (i915_request_signaled(rq)) return true; - return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno); + result = true; + rcu_read_lock(); /* the HWSP may be freed at runtime */ + if (likely(!i915_request_signaled(rq))) + result = __i915_request_is_complete(rq); + rcu_read_unlock(); + + return result; } static inline void i915_request_mark_complete(struct i915_request *rq) -- GitLab From 5cdc4a6950a883594e9640b1decb3fcf6222a594 Mon Sep 17 00:00:00 2001 From: lianzhi chang Date: Thu, 14 Jan 2021 15:57:41 +0800 Subject: [PATCH 0309/1084] udf: fix the problem that the disc content is not displayed When the capacity of the disc is too large (assuming the 4.7G specification), the disc (UDF file system) will be burned multiple times in the windows (Multisession Usage). When the remaining capacity of the CD is less than 300M (estimated value, for reference only), open the CD in the Linux system, the content of the CD is displayed as blank (the kernel will say "No VRS found"). Windows can display the contents of the CD normally. Through analysis, in the "fs/udf/super.c": udf_check_vsd function, the actual value of VSD_MAX_SECTOR_OFFSET may be much larger than 0x800000. According to the current code logic, it is found that the type of sbi->s_session is "__s32", when the remaining capacity of the disc is less than 300M (take a set of test values: sector=3154903040, sbi->s_session=1540464, sb->s_blocksize_bits=11 ), the calculation result of "sbi->s_session << sb->s_blocksize_bits" will overflow. Therefore, it is necessary to convert the type of s_session to "loff_t" (when udf_check_vsd starts, assign a value to _sector, which is also converted in this way), so that the result will not overflow, and then the content of the disc can be displayed normally. Link: https://lore.kernel.org/r/20210114075741.30448-1-changlianzhi@uniontech.com Signed-off-by: lianzhi chang Signed-off-by: Jan Kara --- fs/udf/super.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index 5bef3a68395d8..d0df217f4712a 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -705,6 +705,7 @@ static int udf_check_vsd(struct super_block *sb) struct buffer_head *bh = NULL; int nsr = 0; struct udf_sb_info *sbi; + loff_t session_offset; sbi = UDF_SB(sb); if (sb->s_blocksize < sizeof(struct volStructDesc)) @@ -712,7 +713,8 @@ static int udf_check_vsd(struct super_block *sb) else sectorsize = sb->s_blocksize; - sector += (((loff_t)sbi->s_session) << sb->s_blocksize_bits); + session_offset = (loff_t)sbi->s_session << sb->s_blocksize_bits; + sector += session_offset; udf_debug("Starting at sector %u (%lu byte sectors)\n", (unsigned int)(sector >> sb->s_blocksize_bits), @@ -757,8 +759,7 @@ static int udf_check_vsd(struct super_block *sb) if (nsr > 0) return 1; - else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) == - VSD_FIRST_SECTOR_OFFSET) + else if (!bh && sector - session_offset == VSD_FIRST_SECTOR_OFFSET) return -1; else return 0; -- GitLab From 94a5400f8b966c91c49991bae41c2ef911b935ac Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Sun, 17 Jan 2021 19:16:53 +0100 Subject: [PATCH 0310/1084] arm64: dts: rockchip: remove interrupt-names property from rk3399 vdec node A test with the command below gives this error: /arch/arm64/boot/dts/rockchip/rk3399-evb.dt.yaml: video-codec@ff660000: 'interrupt-names' does not match any of the regexes: 'pinctrl-[0-9]+' The rkvdec driver gets it irq with help of the platform_get_irq() function, so remove the interrupt-names property from the rk3399 vdec node. make ARCH=arm64 dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/ media/rockchip,vdec.yaml Signed-off-by: Johan Jonker Link: https://lore.kernel.org/r/20210117181653.24886-1-jbx6244@gmail.com Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 52bce81cfe77d..2551b238b97c6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -1278,7 +1278,6 @@ compatible = "rockchip,rk3399-vdec"; reg = <0x0 0xff660000 0x0 0x400>; interrupts = ; - interrupt-names = "vdpu"; clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>, <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>; clock-names = "axi", "ahb", "cabac", "core"; -- GitLab From 160e8f96c626ae2bfeef18df467fd9f3814ec89a Mon Sep 17 00:00:00 2001 From: Michael Sit Wei Hong Date: Mon, 18 Jan 2021 18:27:06 +0800 Subject: [PATCH 0311/1084] ASoC: intel, keembay-i2s: Fix dt binding errors Fix devicetree binding errors caused by newly added parameters Signed-off-by: Michael Sit Wei Hong Link: https://lore.kernel.org/r/20210118102706.6125-1-michael.wei.hong.sit@intel.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/intel,keembay-i2s.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml index e0658f122cbb7..dba25c33f0b03 100644 --- a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml @@ -47,13 +47,11 @@ properties: dmas: items: - - description: DMA controller phandle and DMA channel - for TX and RX + - description: DMA TX channel + - description: DMA RX channel dma-names: items: - - description: "tx" for the transmit channel - "rx" for the receive channel - const: tx - const: rx -- GitLab From 57c412d43d71b12df9aa414ec27cd793e9821274 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Mon, 18 Jan 2021 11:13:05 +0530 Subject: [PATCH 0312/1084] ASoC: audio-graph-card: Drop remote-endpoint as required property The remote-endpoint may not be available if it is part of some pluggable module. One such example would be an audio card, the Codec endpoint will not be available until it is plugged in. Hence drop 'remote-endpoint' as a required property. Cc: Rob Herring Cc: Kuninori Morimoto Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1610948585-16286-1-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/audio-graph-port.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml index 2005014161bea..766e9109b2f77 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml +++ b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml @@ -71,9 +71,6 @@ properties: description: CPU to Codec rate channels. $ref: /schemas/types.yaml#/definitions/uint32 - required: - - remote-endpoint - ports: description: multi OF-Graph subnode type: object -- GitLab From 39860fe070c97e62ae9e80addce40ce0b3c2b082 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 14 Jan 2021 13:55:58 +0200 Subject: [PATCH 0313/1084] ASoC: SOF: Intel: initial support to AlderLake-P Add PCI id for the AlderLake-P. Signed-off-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Link: https://lore.kernel.org/r/20210114115558.52699-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-pci-dev.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 5f53c3e76e6fe..7757463bd81ac 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -213,7 +213,7 @@ static const struct sof_dev_desc icl_desc = { }; #endif -#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) || IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) static const struct sof_dev_desc tgl_desc = { .machines = snd_soc_acpi_intel_tgl_machines, .alt_machines = snd_soc_acpi_intel_tgl_sdw_machines, @@ -230,7 +230,9 @@ static const struct sof_dev_desc tgl_desc = { .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", .ops = &sof_tgl_ops, }; +#endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) static const struct sof_dev_desc tglh_desc = { .machines = snd_soc_acpi_intel_tgl_machines, .alt_machines = snd_soc_acpi_intel_tgl_sdw_machines, @@ -517,6 +519,8 @@ static const struct pci_device_id sof_pci_ids[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) { PCI_DEVICE(0x8086, 0x7ad0), .driver_data = (unsigned long)&adls_desc}, + { PCI_DEVICE(0x8086, 0x51c8), + .driver_data = (unsigned long)&tgl_desc}, #endif { 0, } }; -- GitLab From 18d3bff411c8d46d40537483bdc0b61b33ce0371 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 16 Dec 2020 11:22:05 -0500 Subject: [PATCH 0314/1084] btrfs: don't get an EINTR during drop_snapshot for reloc This was partially fixed by f3e3d9cc3525 ("btrfs: avoid possible signal interruption of btrfs_drop_snapshot() on relocation tree"), however it missed a spot when we restart a trans handle because we need to end the transaction. The fix is the same, simply use btrfs_join_transaction() instead of btrfs_start_transaction() when deleting reloc roots. Fixes: f3e3d9cc3525 ("btrfs: avoid possible signal interruption of btrfs_drop_snapshot() on relocation tree") CC: stable@vger.kernel.org # 5.4+ Signed-off-by: Josef Bacik Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/extent-tree.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index d79b8369e6aaf..30b1a630dc2f8 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -5549,7 +5549,15 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc) goto out_free; } - trans = btrfs_start_transaction(tree_root, 0); + /* + * Use join to avoid potential EINTR from transaction + * start. See wait_reserve_ticket and the whole + * reservation callchain. + */ + if (for_reloc) + trans = btrfs_join_transaction(tree_root); + else + trans = btrfs_start_transaction(tree_root, 0); if (IS_ERR(trans)) { err = PTR_ERR(trans); goto out_free; -- GitLab From 49ecc679ab48b40ca799bf94b327d5284eac9e46 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 16 Dec 2020 11:22:11 -0500 Subject: [PATCH 0315/1084] btrfs: do not double free backref nodes on error Zygo reported the following KASAN splat: BUG: KASAN: use-after-free in btrfs_backref_cleanup_node+0x18a/0x420 Read of size 8 at addr ffff888112402950 by task btrfs/28836 CPU: 0 PID: 28836 Comm: btrfs Tainted: G W 5.10.0-e35f27394290-for-next+ #23 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 Call Trace: dump_stack+0xbc/0xf9 ? btrfs_backref_cleanup_node+0x18a/0x420 print_address_description.constprop.8+0x21/0x210 ? record_print_text.cold.34+0x11/0x11 ? btrfs_backref_cleanup_node+0x18a/0x420 ? btrfs_backref_cleanup_node+0x18a/0x420 kasan_report.cold.10+0x20/0x37 ? btrfs_backref_cleanup_node+0x18a/0x420 __asan_load8+0x69/0x90 btrfs_backref_cleanup_node+0x18a/0x420 btrfs_backref_release_cache+0x83/0x1b0 relocate_block_group+0x394/0x780 ? merge_reloc_roots+0x4a0/0x4a0 btrfs_relocate_block_group+0x26e/0x4c0 btrfs_relocate_chunk+0x52/0x120 btrfs_balance+0xe2e/0x1900 ? check_flags.part.50+0x6c/0x1e0 ? btrfs_relocate_chunk+0x120/0x120 ? kmem_cache_alloc_trace+0xa06/0xcb0 ? _copy_from_user+0x83/0xc0 btrfs_ioctl_balance+0x3a7/0x460 btrfs_ioctl+0x24c8/0x4360 ? __kasan_check_read+0x11/0x20 ? check_chain_key+0x1f4/0x2f0 ? __asan_loadN+0xf/0x20 ? btrfs_ioctl_get_supported_features+0x30/0x30 ? kvm_sched_clock_read+0x18/0x30 ? check_chain_key+0x1f4/0x2f0 ? lock_downgrade+0x3f0/0x3f0 ? handle_mm_fault+0xad6/0x2150 ? do_vfs_ioctl+0xfc/0x9d0 ? ioctl_file_clone+0xe0/0xe0 ? check_flags.part.50+0x6c/0x1e0 ? check_flags.part.50+0x6c/0x1e0 ? check_flags+0x26/0x30 ? lock_is_held_type+0xc3/0xf0 ? syscall_enter_from_user_mode+0x1b/0x60 ? do_syscall_64+0x13/0x80 ? rcu_read_lock_sched_held+0xa1/0xd0 ? __kasan_check_read+0x11/0x20 ? __fget_light+0xae/0x110 __x64_sys_ioctl+0xc3/0x100 do_syscall_64+0x37/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f4c4bdfe427 Allocated by task 28836: kasan_save_stack+0x21/0x50 __kasan_kmalloc.constprop.18+0xbe/0xd0 kasan_kmalloc+0x9/0x10 kmem_cache_alloc_trace+0x410/0xcb0 btrfs_backref_alloc_node+0x46/0xf0 btrfs_backref_add_tree_node+0x60d/0x11d0 build_backref_tree+0xc5/0x700 relocate_tree_blocks+0x2be/0xb90 relocate_block_group+0x2eb/0x780 btrfs_relocate_block_group+0x26e/0x4c0 btrfs_relocate_chunk+0x52/0x120 btrfs_balance+0xe2e/0x1900 btrfs_ioctl_balance+0x3a7/0x460 btrfs_ioctl+0x24c8/0x4360 __x64_sys_ioctl+0xc3/0x100 do_syscall_64+0x37/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Freed by task 28836: kasan_save_stack+0x21/0x50 kasan_set_track+0x20/0x30 kasan_set_free_info+0x1f/0x30 __kasan_slab_free+0xf3/0x140 kasan_slab_free+0xe/0x10 kfree+0xde/0x200 btrfs_backref_error_cleanup+0x452/0x530 build_backref_tree+0x1a5/0x700 relocate_tree_blocks+0x2be/0xb90 relocate_block_group+0x2eb/0x780 btrfs_relocate_block_group+0x26e/0x4c0 btrfs_relocate_chunk+0x52/0x120 btrfs_balance+0xe2e/0x1900 btrfs_ioctl_balance+0x3a7/0x460 btrfs_ioctl+0x24c8/0x4360 __x64_sys_ioctl+0xc3/0x100 do_syscall_64+0x37/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xa9 This occurred because we freed our backref node in btrfs_backref_error_cleanup(), but then tried to free it again in btrfs_backref_release_cache(). This is because btrfs_backref_release_cache() will cycle through all of the cache->leaves nodes and free them up. However btrfs_backref_error_cleanup() freed the backref node with btrfs_backref_free_node(), which simply kfree()d the backref node without unlinking it from the cache. Change this to a btrfs_backref_drop_node(), which does the appropriate cleanup and removes the node from the cache->leaves list, so when we go to free the remaining cache we don't trip over items we've already dropped. Fixes: 75bfb9aff45e ("Btrfs: cleanup error handling in build_backref_tree") CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Josef Bacik Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/backref.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 02d7d7b2563b5..9cadacf3ec275 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -3117,7 +3117,7 @@ void btrfs_backref_error_cleanup(struct btrfs_backref_cache *cache, list_del_init(&lower->list); if (lower == node) node = NULL; - btrfs_backref_free_node(cache, lower); + btrfs_backref_drop_node(cache, lower); } btrfs_backref_cleanup_node(cache, node); -- GitLab From fb286100974e7239af243bc2255a52f29442f9c8 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 16 Dec 2020 11:22:14 -0500 Subject: [PATCH 0316/1084] btrfs: fix lockdep splat in btrfs_recover_relocation While testing the error paths of relocation I hit the following lockdep splat: ====================================================== WARNING: possible circular locking dependency detected 5.10.0-rc6+ #217 Not tainted ------------------------------------------------------ mount/779 is trying to acquire lock: ffffa0e676945418 (&fs_info->balance_mutex){+.+.}-{3:3}, at: btrfs_recover_balance+0x2f0/0x340 but task is already holding lock: ffffa0e60ee31da8 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x27/0x100 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (btrfs-root-00){++++}-{3:3}: down_read_nested+0x43/0x130 __btrfs_tree_read_lock+0x27/0x100 btrfs_read_lock_root_node+0x31/0x40 btrfs_search_slot+0x462/0x8f0 btrfs_update_root+0x55/0x2b0 btrfs_drop_snapshot+0x398/0x750 clean_dirty_subvols+0xdf/0x120 btrfs_recover_relocation+0x534/0x5a0 btrfs_start_pre_rw_mount+0xcb/0x170 open_ctree+0x151f/0x1726 btrfs_mount_root.cold+0x12/0xea legacy_get_tree+0x30/0x50 vfs_get_tree+0x28/0xc0 vfs_kern_mount.part.0+0x71/0xb0 btrfs_mount+0x10d/0x380 legacy_get_tree+0x30/0x50 vfs_get_tree+0x28/0xc0 path_mount+0x433/0xc10 __x64_sys_mount+0xe3/0x120 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 -> #1 (sb_internal#2){.+.+}-{0:0}: start_transaction+0x444/0x700 insert_balance_item.isra.0+0x37/0x320 btrfs_balance+0x354/0xf40 btrfs_ioctl_balance+0x2cf/0x380 __x64_sys_ioctl+0x83/0xb0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 -> #0 (&fs_info->balance_mutex){+.+.}-{3:3}: __lock_acquire+0x1120/0x1e10 lock_acquire+0x116/0x370 __mutex_lock+0x7e/0x7b0 btrfs_recover_balance+0x2f0/0x340 open_ctree+0x1095/0x1726 btrfs_mount_root.cold+0x12/0xea legacy_get_tree+0x30/0x50 vfs_get_tree+0x28/0xc0 vfs_kern_mount.part.0+0x71/0xb0 btrfs_mount+0x10d/0x380 legacy_get_tree+0x30/0x50 vfs_get_tree+0x28/0xc0 path_mount+0x433/0xc10 __x64_sys_mount+0xe3/0x120 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 other info that might help us debug this: Chain exists of: &fs_info->balance_mutex --> sb_internal#2 --> btrfs-root-00 Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(btrfs-root-00); lock(sb_internal#2); lock(btrfs-root-00); lock(&fs_info->balance_mutex); *** DEADLOCK *** 2 locks held by mount/779: #0: ffffa0e60dc040e0 (&type->s_umount_key#47/1){+.+.}-{3:3}, at: alloc_super+0xb5/0x380 #1: ffffa0e60ee31da8 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x27/0x100 stack backtrace: CPU: 0 PID: 779 Comm: mount Not tainted 5.10.0-rc6+ #217 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014 Call Trace: dump_stack+0x8b/0xb0 check_noncircular+0xcf/0xf0 ? trace_call_bpf+0x139/0x260 __lock_acquire+0x1120/0x1e10 lock_acquire+0x116/0x370 ? btrfs_recover_balance+0x2f0/0x340 __mutex_lock+0x7e/0x7b0 ? btrfs_recover_balance+0x2f0/0x340 ? btrfs_recover_balance+0x2f0/0x340 ? rcu_read_lock_sched_held+0x3f/0x80 ? kmem_cache_alloc_trace+0x2c4/0x2f0 ? btrfs_get_64+0x5e/0x100 btrfs_recover_balance+0x2f0/0x340 open_ctree+0x1095/0x1726 btrfs_mount_root.cold+0x12/0xea ? rcu_read_lock_sched_held+0x3f/0x80 legacy_get_tree+0x30/0x50 vfs_get_tree+0x28/0xc0 vfs_kern_mount.part.0+0x71/0xb0 btrfs_mount+0x10d/0x380 ? __kmalloc_track_caller+0x2f2/0x320 legacy_get_tree+0x30/0x50 vfs_get_tree+0x28/0xc0 ? capable+0x3a/0x60 path_mount+0x433/0xc10 __x64_sys_mount+0xe3/0x120 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 This is straightforward to fix, simply release the path before we setup the balance_ctl. CC: stable@vger.kernel.org # 4.4+ Reviewed-by: Qu Wenruo Reviewed-by: Johannes Thumshirn Signed-off-by: Josef Bacik Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/volumes.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 2c0aa03b64376..0c7f4f6237e8c 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -4318,6 +4318,8 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info) btrfs_warn(fs_info, "balance: cannot set exclusive op status, resume manually"); + btrfs_release_path(path); + mutex_lock(&fs_info->balance_mutex); BUG_ON(fs_info->balance_ctl); spin_lock(&fs_info->balance_lock); -- GitLab From 34d1eb0e599875064955a74712f08ff14c8e3d5f Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 16 Dec 2020 11:22:17 -0500 Subject: [PATCH 0317/1084] btrfs: don't clear ret in btrfs_start_dirty_block_groups If we fail to update a block group item in the loop we'll break, however we'll do btrfs_run_delayed_refs and lose our error value in ret, and thus not clean up properly. Fix this by only running the delayed refs if there was no failure. CC: stable@vger.kernel.org # 4.4+ Reviewed-by: Qu Wenruo Reviewed-by: Johannes Thumshirn Signed-off-by: Josef Bacik Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/block-group.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 52f2198d44c95..0886e81e55402 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -2669,7 +2669,8 @@ int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans) * Go through delayed refs for all the stuff we've just kicked off * and then loop back (just once) */ - ret = btrfs_run_delayed_refs(trans, 0); + if (!ret) + ret = btrfs_run_delayed_refs(trans, 0); if (!ret && loops == 0) { loops++; spin_lock(&cur_trans->dirty_bgs_lock); -- GitLab From a82e537807d5c85706cd4c16fd2de77a8495dc8d Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 14 Jan 2021 19:16:21 -0800 Subject: [PATCH 0318/1084] pinctrl: qcom: Allow SoCs to specify a GPIO function that's not 0 There's currently a comment in the code saying function 0 is GPIO. Instead of hardcoding it, let's add a member where an SoC can specify it. No known SoCs use a number other than 0, but this just makes the code clearer. NOTE: no SoC code needs to be updated since we can rely on zero-initialization. Signed-off-by: Douglas Anderson Reviewed-by: Stephen Boyd Reviewed-by: Maulik Shah Tested-by: Maulik Shah Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210114191601.v7.1.I3ad184e3423d8e479bc3e86f5b393abb1704a1d1@changeid Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-msm.c | 3 +-- drivers/pinctrl/qcom/pinctrl-msm.h | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index e051aecf95c4e..d1261188fb6ee 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -210,8 +210,7 @@ static int msm_pinmux_request_gpio(struct pinctrl_dev *pctldev, if (!g->nfuncs) return 0; - /* For now assume function 0 is GPIO because it always is */ - return msm_pinmux_set_mux(pctldev, g->funcs[0], offset); + return msm_pinmux_set_mux(pctldev, g->funcs[pctrl->soc->gpio_func], offset); } static const struct pinmux_ops msm_pinmux_ops = { diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h index 333f99243c43a..e31a5167c91ec 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.h +++ b/drivers/pinctrl/qcom/pinctrl-msm.h @@ -118,6 +118,7 @@ struct msm_gpio_wakeirq_map { * @wakeirq_dual_edge_errata: If true then GPIOs using the wakeirq_map need * to be aware that their parent can't handle dual * edge interrupts. + * @gpio_func: Which function number is GPIO (usually 0). */ struct msm_pinctrl_soc_data { const struct pinctrl_pin_desc *pins; @@ -134,6 +135,7 @@ struct msm_pinctrl_soc_data { const struct msm_gpio_wakeirq_map *wakeirq_map; unsigned int nwakeirq_map; bool wakeirq_dual_edge_errata; + unsigned int gpio_func; }; extern const struct dev_pm_ops msm_pinctrl_dev_pm_ops; -- GitLab From 4079d35fa4fca4ee0ffd66968312fc86a5e8c290 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 14 Jan 2021 19:16:22 -0800 Subject: [PATCH 0319/1084] pinctrl: qcom: No need to read-modify-write the interrupt status When the Qualcomm pinctrl driver wants to Ack an interrupt, it does a read-modify-write on the interrupt status register. On some SoCs it makes sure that the status bit is 1 to "Ack" and on others it makes sure that the bit is 0 to "Ack". Presumably the first type of interrupt controller is a "write 1 to clear" type register and the second just let you directly set the interrupt status register. As far as I can tell from scanning structure definitions, the interrupt status bit is always in a register by itself. Thus with both types of interrupt controllers it is safe to "Ack" interrupts without doing a read-modify-write. We can do a simple write. It should be noted that if the interrupt status bit _was_ ever in a register with other things (like maybe status bits for other GPIOs): a) For "write 1 clear" type controllers then read-modify-write would be totally wrong because we'd accidentally end up clearing interrupts we weren't looking at. b) For "direct set" type controllers then read-modify-write would also be wrong because someone setting one of the other bits in the register might accidentally clear (or set) our interrupt. I say this simply to show that the current read-modify-write doesn't provide any sort of "future proofing" of the code. In fact (for "write 1 clear" controllers) the new code is slightly more "future proof" since it would allow more than one interrupt status bits to share a register. NOTE: this code fixes no bugs--it simply avoids an extra register read. Signed-off-by: Douglas Anderson Reviewed-by: Maulik Shah Tested-by: Maulik Shah Reviewed-by: Stephen Boyd Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210114191601.v7.2.I3635de080604e1feda770591c5563bd6e63dd39d@changeid Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-msm.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index d1261188fb6ee..2f363c28d9d98 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -791,16 +791,13 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) raw_spin_lock_irqsave(&pctrl->lock, flags); - if (status_clear) { - /* - * clear the interrupt status bit before unmask to avoid - * any erroneous interrupts that would have got latched - * when the interrupt is not in use. - */ - val = msm_readl_intr_status(pctrl, g); - val &= ~BIT(g->intr_status_bit); - msm_writel_intr_status(val, pctrl, g); - } + /* + * clear the interrupt status bit before unmask to avoid + * any erroneous interrupts that would have got latched + * when the interrupt is not in use. + */ + if (status_clear) + msm_writel_intr_status(0, pctrl, g); val = msm_readl_intr_cfg(pctrl, g); val |= BIT(g->intr_raw_status_bit); @@ -905,11 +902,7 @@ static void msm_gpio_irq_ack(struct irq_data *d) raw_spin_lock_irqsave(&pctrl->lock, flags); - val = msm_readl_intr_status(pctrl, g); - if (g->intr_ack_high) - val |= BIT(g->intr_status_bit); - else - val &= ~BIT(g->intr_status_bit); + val = g->intr_ack_high ? BIT(g->intr_status_bit) : 0; msm_writel_intr_status(val, pctrl, g); if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) -- GitLab From a95881d6aa2c000e3649f27a1a7329cf356e6bb3 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 14 Jan 2021 19:16:23 -0800 Subject: [PATCH 0320/1084] pinctrl: qcom: Properly clear "intr_ack_high" interrupts when unmasking In commit 4b7618fdc7e6 ("pinctrl: qcom: Add irq_enable callback for msm gpio") we tried to Ack interrupts during unmask. However, that patch forgot to check "intr_ack_high" so, presumably, it only worked for a certain subset of SoCs. Let's add a small accessor so we don't need to open-code the logic in both places. This was found by code inspection. I don't have any access to the hardware in question nor software that needs the Ack during unmask. Fixes: 4b7618fdc7e6 ("pinctrl: qcom: Add irq_enable callback for msm gpio") Signed-off-by: Douglas Anderson Reviewed-by: Maulik Shah Tested-by: Maulik Shah Reviewed-by: Stephen Boyd Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210114191601.v7.3.I32d0f4e174d45363b49ab611a13c3da8f1e87d0f@changeid Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-msm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 2f363c28d9d98..192ed31eabf48 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -96,6 +96,14 @@ MSM_ACCESSOR(intr_cfg) MSM_ACCESSOR(intr_status) MSM_ACCESSOR(intr_target) +static void msm_ack_intr_status(struct msm_pinctrl *pctrl, + const struct msm_pingroup *g) +{ + u32 val = g->intr_ack_high ? BIT(g->intr_status_bit) : 0; + + msm_writel_intr_status(val, pctrl, g); +} + static int msm_get_groups_count(struct pinctrl_dev *pctldev) { struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); @@ -797,7 +805,7 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) * when the interrupt is not in use. */ if (status_clear) - msm_writel_intr_status(0, pctrl, g); + msm_ack_intr_status(pctrl, g); val = msm_readl_intr_cfg(pctrl, g); val |= BIT(g->intr_raw_status_bit); @@ -890,7 +898,6 @@ static void msm_gpio_irq_ack(struct irq_data *d) struct msm_pinctrl *pctrl = gpiochip_get_data(gc); const struct msm_pingroup *g; unsigned long flags; - u32 val; if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) { if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) @@ -902,8 +909,7 @@ static void msm_gpio_irq_ack(struct irq_data *d) raw_spin_lock_irqsave(&pctrl->lock, flags); - val = g->intr_ack_high ? BIT(g->intr_status_bit) : 0; - msm_writel_intr_status(val, pctrl, g); + msm_ack_intr_status(pctrl, g); if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) msm_gpio_update_dual_edge_pos(pctrl, g, d); -- GitLab From cf9d052aa6005f1e8dfaf491d83bf37f368af69e Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 14 Jan 2021 19:16:24 -0800 Subject: [PATCH 0321/1084] pinctrl: qcom: Don't clear pending interrupts when enabling In Linux, if a driver does disable_irq() and later does enable_irq() on its interrupt, I believe it's expecting these properties: * If an interrupt was pending when the driver disabled then it will still be pending after the driver re-enables. * If an edge-triggered interrupt comes in while an interrupt is disabled it should assert when the interrupt is re-enabled. If you think that the above sounds a lot like the disable_irq() and enable_irq() are supposed to be masking/unmasking the interrupt instead of disabling/enabling it then you've made an astute observation. Specifically when talking about interrupts, "mask" usually means to stop posting interrupts but keep tracking them and "disable" means to fully shut off interrupt detection. It's unfortunate that this is so confusing, but presumably this is all the way it is for historical reasons. Perhaps more confusing than the above is that, even though clients of IRQs themselves don't have a way to request mask/unmask vs. disable/enable calls, IRQ chips themselves can implement both. ...and yet more confusing is that if an IRQ chip implements disable/enable then they will be called when a client driver calls disable_irq() / enable_irq(). It does feel like some of the above could be cleared up. However, without any other core interrupt changes it should be clear that when an IRQ chip gets a request to "disable" an IRQ that it has to treat it like a mask of that IRQ. In any case, after that long interlude you can see that the "unmask and clear" can break things. Maulik tried to fix it so that we no longer did "unmask and clear" in commit 71266d9d3936 ("pinctrl: qcom: Move clearing pending IRQ to .irq_request_resources callback"), but it only handled the PDC case and it had problems (it caused sc7180-trogdor devices to fail to suspend). Let's fix. >From my understanding the source of the phantom interrupt in the were these two things: 1. One that could have been introduced in msm_gpio_irq_set_type() (only for the non-PDC case). 2. Edges could have been detected when a GPIO was muxed away. Fixing case #1 is easy. We can just add a clear in msm_gpio_irq_set_type(). Fixing case #2 is harder. Let's use a concrete example. In sc7180-trogdor.dtsi we configure the uart3 to have two pinctrl states, sleep and default, and mux between the two during runtime PM and system suspend (see geni_se_resources_{on,off}() for more details). The difference between the sleep and default state is that the RX pin is muxed to a GPIO during sleep and muxed to the UART otherwise. As per Qualcomm, when we mux the pin over to the UART function the PDC (or the non-PDC interrupt detection logic) is still watching it / latching edges. These edges don't cause interrupts because the current code masks the interrupt unless we're entering suspend. However, as soon as we enter suspend we unmask the interrupt and it's counted as a wakeup. Let's deal with the problem like this: * When we mux away, we'll mask our interrupt. This isn't necessary in the above case since the client already masked us, but it's a good idea in general. * When we mux back will clear any interrupts and unmask. Fixes: 4b7618fdc7e6 ("pinctrl: qcom: Add irq_enable callback for msm gpio") Fixes: 71266d9d3936 ("pinctrl: qcom: Move clearing pending IRQ to .irq_request_resources callback") Signed-off-by: Douglas Anderson Reviewed-by: Maulik Shah Tested-by: Maulik Shah Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/20210114191601.v7.4.I7cf3019783720feb57b958c95c2b684940264cd1@changeid Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-msm.c | 74 ++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 192ed31eabf48..d70caecd21d25 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -51,6 +51,7 @@ * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge * detection. * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller + * @disabled_for_mux: These IRQs were disabled because we muxed away. * @soc: Reference to soc_data of platform specific data. * @regs: Base addresses for the TLMM tiles. * @phys_base: Physical base address @@ -72,6 +73,7 @@ struct msm_pinctrl { DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO); DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO); DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO); + DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO); const struct msm_pinctrl_soc_data *soc; void __iomem *regs[MAX_NR_TILES]; @@ -179,6 +181,10 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned group) { struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct gpio_chip *gc = &pctrl->chip; + unsigned int irq = irq_find_mapping(gc->irq.domain, group); + struct irq_data *d = irq_get_irq_data(irq); + unsigned int gpio_func = pctrl->soc->gpio_func; const struct msm_pingroup *g; unsigned long flags; u32 val, mask; @@ -195,6 +201,20 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev, if (WARN_ON(i == g->nfuncs)) return -EINVAL; + /* + * If an GPIO interrupt is setup on this pin then we need special + * handling. Specifically interrupt detection logic will still see + * the pin twiddle even when we're muxed away. + * + * When we see a pin with an interrupt setup on it then we'll disable + * (mask) interrupts on it when we mux away until we mux back. Note + * that disable_irq() refcounts and interrupts are disabled as long as + * at least one disable_irq() has been called. + */ + if (d && i != gpio_func && + !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux)) + disable_irq(irq); + raw_spin_lock_irqsave(&pctrl->lock, flags); val = msm_readl_ctl(pctrl, g); @@ -204,6 +224,20 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev, raw_spin_unlock_irqrestore(&pctrl->lock, flags); + if (d && i == gpio_func && + test_and_clear_bit(d->hwirq, pctrl->disabled_for_mux)) { + /* + * Clear interrupts detected while not GPIO since we only + * masked things. + */ + if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) + irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, false); + else + msm_ack_intr_status(pctrl, g); + + enable_irq(irq); + } + return 0; } @@ -781,7 +815,7 @@ static void msm_gpio_irq_mask(struct irq_data *d) raw_spin_unlock_irqrestore(&pctrl->lock, flags); } -static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) +static void msm_gpio_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct msm_pinctrl *pctrl = gpiochip_get_data(gc); @@ -799,14 +833,6 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) raw_spin_lock_irqsave(&pctrl->lock, flags); - /* - * clear the interrupt status bit before unmask to avoid - * any erroneous interrupts that would have got latched - * when the interrupt is not in use. - */ - if (status_clear) - msm_ack_intr_status(pctrl, g); - val = msm_readl_intr_cfg(pctrl, g); val |= BIT(g->intr_raw_status_bit); val |= BIT(g->intr_enable_bit); @@ -826,7 +852,7 @@ static void msm_gpio_irq_enable(struct irq_data *d) irq_chip_enable_parent(d); if (!test_bit(d->hwirq, pctrl->skip_wake_irqs)) - msm_gpio_irq_clear_unmask(d, true); + msm_gpio_irq_unmask(d); } static void msm_gpio_irq_disable(struct irq_data *d) @@ -841,11 +867,6 @@ static void msm_gpio_irq_disable(struct irq_data *d) msm_gpio_irq_mask(d); } -static void msm_gpio_irq_unmask(struct irq_data *d) -{ - msm_gpio_irq_clear_unmask(d, false); -} - /** * msm_gpio_update_dual_edge_parent() - Prime next edge for IRQs handled by parent. * @d: The irq dta. @@ -934,6 +955,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) struct msm_pinctrl *pctrl = gpiochip_get_data(gc); const struct msm_pingroup *g; unsigned long flags; + bool was_enabled; u32 val; if (msm_gpio_needs_dual_edge_parent_workaround(d, type)) { @@ -995,6 +1017,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) * could cause the INTR_STATUS to be set for EDGE interrupts. */ val = msm_readl_intr_cfg(pctrl, g); + was_enabled = val & BIT(g->intr_raw_status_bit); val |= BIT(g->intr_raw_status_bit); if (g->intr_detection_width == 2) { val &= ~(3 << g->intr_detection_bit); @@ -1044,6 +1067,14 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) } msm_writel_intr_cfg(val, pctrl, g); + /* + * The first time we set RAW_STATUS_EN it could trigger an interrupt. + * Clear the interrupt. This is safe because we have + * IRQCHIP_SET_TYPE_MASKED. + */ + if (!was_enabled) + msm_ack_intr_status(pctrl, g); + if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) msm_gpio_update_dual_edge_pos(pctrl, g, d); @@ -1097,16 +1128,11 @@ static int msm_gpio_irq_reqres(struct irq_data *d) } /* - * Clear the interrupt that may be pending before we enable - * the line. - * This is especially a problem with the GPIOs routed to the - * PDC. These GPIOs are direct-connect interrupts to the GIC. - * Disabling the interrupt line at the PDC does not prevent - * the interrupt from being latched at the GIC. The state at - * GIC needs to be cleared before enabling. + * The disable / clear-enable workaround we do in msm_pinmux_set_mux() + * only works if disable is not lazy since we only clear any bogus + * interrupt in hardware. Explicitly mark the interrupt as UNLAZY. */ - if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) - irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, 0); + irq_set_status_flags(d->irq, IRQ_DISABLE_UNLAZY); return 0; out: -- GitLab From d24c790577ef01bfa01da2b131313a38c843a634 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 14 Jan 2021 18:10:52 +0100 Subject: [PATCH 0322/1084] mt7601u: fix rx buffer refcounting Fix the following crash due to erroneous page refcounting: [ 32.445919] BUG: Bad page state in process swapper/1 pfn:11f65a [ 32.447409] page:00000000938f0632 refcount:0 mapcount:-128 mapping:0000000000000000 index:0x0 pfn:0x11f65a [ 32.449605] flags: 0x8000000000000000() [ 32.450421] raw: 8000000000000000 ffffffff825b0148 ffffea00045ae988 0000000000000000 [ 32.451795] raw: 0000000000000000 0000000000000001 00000000ffffff7f 0000000000000000 [ 32.452999] page dumped because: nonzero mapcount [ 32.453888] Modules linked in: [ 32.454492] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.11.0-rc2+ #1976 [ 32.455695] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-1.fc33 04/01/2014 [ 32.457157] Call Trace: [ 32.457636] [ 32.457993] dump_stack+0x77/0x97 [ 32.458576] bad_page.cold+0x65/0x96 [ 32.459198] get_page_from_freelist+0x46a/0x11f0 [ 32.460008] __alloc_pages_nodemask+0x10a/0x2b0 [ 32.460794] mt7601u_rx_tasklet+0x651/0x720 [ 32.461505] tasklet_action_common.constprop.0+0x6b/0xd0 [ 32.462343] __do_softirq+0x152/0x46c [ 32.462928] asm_call_irq_on_stack+0x12/0x20 [ 32.463610] [ 32.463953] do_softirq_own_stack+0x5b/0x70 [ 32.464582] irq_exit_rcu+0x9f/0xe0 [ 32.465028] common_interrupt+0xae/0x1a0 [ 32.465536] asm_common_interrupt+0x1e/0x40 [ 32.466071] RIP: 0010:default_idle+0x18/0x20 [ 32.468981] RSP: 0018:ffffc90000077f00 EFLAGS: 00000246 [ 32.469648] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000 [ 32.470550] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff81aac3dd [ 32.471463] RBP: ffff88810022ab00 R08: 0000000000000001 R09: 0000000000000001 [ 32.472335] R10: 0000000000000046 R11: 0000000000005aa0 R12: 0000000000000000 [ 32.473235] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 32.474139] ? default_idle_call+0x4d/0x200 [ 32.474681] default_idle_call+0x74/0x200 [ 32.475192] do_idle+0x1d5/0x250 [ 32.475612] cpu_startup_entry+0x19/0x20 [ 32.476114] secondary_startup_64_no_verify+0xb0/0xbb [ 32.476765] Disabling lock debugging due to kernel taint Fixes: c869f77d6abb ("add mt7601u driver") Co-developed-by: Felix Fietkau Signed-off-by: Felix Fietkau Signed-off-by: Lorenzo Bianconi Acked-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/62b2380c8c2091834cfad05e1059b55f945bd114.1610643952.git.lorenzo@kernel.org --- drivers/net/wireless/mediatek/mt7601u/dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c index 5f99054f535b4..47710da5b2a58 100644 --- a/drivers/net/wireless/mediatek/mt7601u/dma.c +++ b/drivers/net/wireless/mediatek/mt7601u/dma.c @@ -152,8 +152,7 @@ mt7601u_rx_process_entry(struct mt7601u_dev *dev, struct mt7601u_dma_buf_rx *e) if (new_p) { /* we have one extra ref from the allocator */ - __free_pages(e->p, MT_RX_ORDER); - + put_page(e->p); e->p = new_p; } } -- GitLab From 952de419b6179ad1424f512d52ec7122662fdf63 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 14 Jan 2021 18:26:47 +0100 Subject: [PATCH 0323/1084] mt76: mt7663s: fix rx buffer refcounting Similar to mt7601u driver, fix erroneous rx page refcounting Fixes: a66cbdd6573d ("mt76: mt7615: introduce mt7663s support") Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/dca19c9d445156201bc41f7cbb6e894bbc9a678c.1610644945.git.lorenzo@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c index 13d77f8fca866..9fb506f2ace6d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c @@ -83,7 +83,7 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid, { struct mt76_queue *q = &dev->q_rx[qid]; struct mt76_sdio *sdio = &dev->sdio; - int len = 0, err, i, order; + int len = 0, err, i; struct page *page; u8 *buf; @@ -96,8 +96,7 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid, if (len > sdio->func->cur_blksize) len = roundup(len, sdio->func->cur_blksize); - order = get_order(len); - page = __dev_alloc_pages(GFP_KERNEL, order); + page = __dev_alloc_pages(GFP_KERNEL, get_order(len)); if (!page) return -ENOMEM; @@ -106,7 +105,7 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid, err = sdio_readsb(sdio->func, buf, MCR_WRDR(qid), len); if (err < 0) { dev_err(dev->dev, "sdio read data failed:%d\n", err); - __free_pages(page, order); + put_page(page); return err; } @@ -123,7 +122,7 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid, if (q->queued + i + 1 == q->ndesc) break; } - __free_pages(page, order); + put_page(page); spin_lock_bh(&q->lock); q->head = (q->head + i) % q->ndesc; -- GitLab From 4d6b1c95b974761c01cbad92321b82232b66d2a2 Mon Sep 17 00:00:00 2001 From: Revanth Rajashekar Date: Thu, 14 Jan 2021 18:55:07 -0700 Subject: [PATCH 0324/1084] nvme: check the PRINFO bit before deciding the host buffer length According to NVMe spec v1.4, section 8.3.1, the PRINFO bit and the metadata size play a vital role in deteriming the host buffer size. If PRIFNO bit is set and MS==8, the host doesn't add the metadata buffer, instead the controller adds it. Signed-off-by: Revanth Rajashekar Signed-off-by: Christoph Hellwig --- drivers/nvme/host/core.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 200bdd672c281..8caf9b34734dc 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1543,8 +1543,21 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) } length = (io.nblocks + 1) << ns->lba_shift; - meta_len = (io.nblocks + 1) * ns->ms; - metadata = nvme_to_user_ptr(io.metadata); + + if ((io.control & NVME_RW_PRINFO_PRACT) && + ns->ms == sizeof(struct t10_pi_tuple)) { + /* + * Protection information is stripped/inserted by the + * controller. + */ + if (nvme_to_user_ptr(io.metadata)) + return -EINVAL; + meta_len = 0; + metadata = NULL; + } else { + meta_len = (io.nblocks + 1) * ns->ms; + metadata = nvme_to_user_ptr(io.metadata); + } if (ns->features & NVME_NS_EXT_LBAS) { length += meta_len; -- GitLab From 7674073b2ed35ac951a49c425dec6b39d5a57140 Mon Sep 17 00:00:00 2001 From: Chao Leng Date: Thu, 14 Jan 2021 17:09:25 +0800 Subject: [PATCH 0325/1084] nvme-rdma: avoid request double completion for concurrent nvme_rdma_timeout A crash happens when inject completing request long time(nearly 30s). Each name space has a request queue, when inject completing request long time, multi request queues may have time out requests at the same time, nvme_rdma_timeout will execute concurrently. Multi requests in different request queues may be queued in the same rdma queue, multi nvme_rdma_timeout may call nvme_rdma_stop_queue at the same time. The first nvme_rdma_timeout will clear NVME_RDMA_Q_LIVE and continue stopping the rdma queue(drain qp), but the others check NVME_RDMA_Q_LIVE is already cleared, and then directly complete the requests, complete request before the qp is fully drained may lead to a use-after-free condition. Add a multex lock to serialize nvme_rdma_stop_queue. Signed-off-by: Chao Leng Tested-by: Israel Rukshin Reviewed-by: Israel Rukshin Signed-off-by: Christoph Hellwig --- drivers/nvme/host/rdma.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index cf6c49d09c820..b7ce4f221d990 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -97,6 +97,7 @@ struct nvme_rdma_queue { struct completion cm_done; bool pi_support; int cq_size; + struct mutex queue_lock; }; struct nvme_rdma_ctrl { @@ -579,6 +580,7 @@ static int nvme_rdma_alloc_queue(struct nvme_rdma_ctrl *ctrl, int ret; queue = &ctrl->queues[idx]; + mutex_init(&queue->queue_lock); queue->ctrl = ctrl; if (idx && ctrl->ctrl.max_integrity_segments) queue->pi_support = true; @@ -598,7 +600,8 @@ static int nvme_rdma_alloc_queue(struct nvme_rdma_ctrl *ctrl, if (IS_ERR(queue->cm_id)) { dev_info(ctrl->ctrl.device, "failed to create CM ID: %ld\n", PTR_ERR(queue->cm_id)); - return PTR_ERR(queue->cm_id); + ret = PTR_ERR(queue->cm_id); + goto out_destroy_mutex; } if (ctrl->ctrl.opts->mask & NVMF_OPT_HOST_TRADDR) @@ -628,6 +631,8 @@ static int nvme_rdma_alloc_queue(struct nvme_rdma_ctrl *ctrl, out_destroy_cm_id: rdma_destroy_id(queue->cm_id); nvme_rdma_destroy_queue_ib(queue); +out_destroy_mutex: + mutex_destroy(&queue->queue_lock); return ret; } @@ -639,9 +644,10 @@ static void __nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) { - if (!test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags)) - return; - __nvme_rdma_stop_queue(queue); + mutex_lock(&queue->queue_lock); + if (test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags)) + __nvme_rdma_stop_queue(queue); + mutex_unlock(&queue->queue_lock); } static void nvme_rdma_free_queue(struct nvme_rdma_queue *queue) @@ -651,6 +657,7 @@ static void nvme_rdma_free_queue(struct nvme_rdma_queue *queue) nvme_rdma_destroy_queue_ib(queue); rdma_destroy_id(queue->cm_id); + mutex_destroy(&queue->queue_lock); } static void nvme_rdma_free_io_queues(struct nvme_rdma_ctrl *ctrl) -- GitLab From 9ebbfe495ecd2e51bc92ac21ed5817c3b9e223ce Mon Sep 17 00:00:00 2001 From: Chao Leng Date: Thu, 14 Jan 2021 17:09:26 +0800 Subject: [PATCH 0326/1084] nvme-tcp: avoid request double completion for concurrent nvme_tcp_timeout Each name space has a request queue, if complete request long time, multi request queues may have time out requests at the same time, nvme_tcp_timeout will execute concurrently. Multi requests in different request queues may be queued in the same tcp queue, multi nvme_tcp_timeout may call nvme_tcp_stop_queue at the same time. The first nvme_tcp_stop_queue will clear NVME_TCP_Q_LIVE and continue stopping the tcp queue(cancel io_work), but the others check NVME_TCP_Q_LIVE is already cleared, and then directly complete the requests, complete request before the io work is completely canceled may lead to a use-after-free condition. Add a multex lock to serialize nvme_tcp_stop_queue. Signed-off-by: Chao Leng Signed-off-by: Christoph Hellwig --- drivers/nvme/host/tcp.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 216619926563e..881d28eb15e9d 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -76,6 +76,7 @@ struct nvme_tcp_queue { struct work_struct io_work; int io_cpu; + struct mutex queue_lock; struct mutex send_mutex; struct llist_head req_list; struct list_head send_list; @@ -1219,6 +1220,7 @@ static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid) sock_release(queue->sock); kfree(queue->pdu); + mutex_destroy(&queue->queue_lock); } static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue) @@ -1380,6 +1382,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, struct nvme_tcp_queue *queue = &ctrl->queues[qid]; int ret, rcv_pdu_size; + mutex_init(&queue->queue_lock); queue->ctrl = ctrl; init_llist_head(&queue->req_list); INIT_LIST_HEAD(&queue->send_list); @@ -1398,7 +1401,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, if (ret) { dev_err(nctrl->device, "failed to create socket: %d\n", ret); - return ret; + goto err_destroy_mutex; } /* Single syn retry */ @@ -1507,6 +1510,8 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, err_sock: sock_release(queue->sock); queue->sock = NULL; +err_destroy_mutex: + mutex_destroy(&queue->queue_lock); return ret; } @@ -1534,9 +1539,10 @@ static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid) struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); struct nvme_tcp_queue *queue = &ctrl->queues[qid]; - if (!test_and_clear_bit(NVME_TCP_Q_LIVE, &queue->flags)) - return; - __nvme_tcp_stop_queue(queue); + mutex_lock(&queue->queue_lock); + if (test_and_clear_bit(NVME_TCP_Q_LIVE, &queue->flags)) + __nvme_tcp_stop_queue(queue); + mutex_unlock(&queue->queue_lock); } static int nvme_tcp_start_queue(struct nvme_ctrl *nctrl, int idx) -- GitLab From 20d3bb92e84d417b0494a3b6867f0c86713db257 Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Fri, 15 Jan 2021 07:30:46 +0100 Subject: [PATCH 0327/1084] nvme-pci: allow use of cmb on v1.4 controllers Since NVMe v1.4 the Controller Memory Buffer must be explicitly enabled by the host. Signed-off-by: Klaus Jensen [hch: avoid a local variable and add a comment] Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 14 ++++++++++++++ include/linux/nvme.h | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 50d9a20568a28..25456d02eddb8 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -1795,6 +1796,9 @@ static void nvme_map_cmb(struct nvme_dev *dev) if (dev->cmb_size) return; + if (NVME_CAP_CMBS(dev->ctrl.cap)) + writel(NVME_CMBMSC_CRE, dev->bar + NVME_REG_CMBMSC); + dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ); if (!dev->cmbsz) return; @@ -1808,6 +1812,16 @@ static void nvme_map_cmb(struct nvme_dev *dev) if (offset > bar_size) return; + /* + * Tell the controller about the host side address mapping the CMB, + * and enable CMB decoding for the NVMe 1.4+ scheme: + */ + if (NVME_CAP_CMBS(dev->ctrl.cap)) { + hi_lo_writeq(NVME_CMBMSC_CRE | NVME_CMBMSC_CMSE | + (pci_bus_address(pdev, bar) + offset), + dev->bar + NVME_REG_CMBMSC); + } + /* * Controllers may support a CMB size larger than their BAR, * for example, due to being behind a bridge. Reduce the CMB to diff --git a/include/linux/nvme.h b/include/linux/nvme.h index d925359976873..bfed36e342ccb 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -116,6 +116,9 @@ enum { NVME_REG_BPMBL = 0x0048, /* Boot Partition Memory Buffer * Location */ + NVME_REG_CMBMSC = 0x0050, /* Controller Memory Buffer Memory + * Space Control + */ NVME_REG_PMRCAP = 0x0e00, /* Persistent Memory Capabilities */ NVME_REG_PMRCTL = 0x0e04, /* Persistent Memory Region Control */ NVME_REG_PMRSTS = 0x0e08, /* Persistent Memory Region Status */ @@ -135,6 +138,7 @@ enum { #define NVME_CAP_CSS(cap) (((cap) >> 37) & 0xff) #define NVME_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf) #define NVME_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf) +#define NVME_CAP_CMBS(cap) (((cap) >> 57) & 0x1) #define NVME_CMB_BIR(cmbloc) ((cmbloc) & 0x7) #define NVME_CMB_OFST(cmbloc) (((cmbloc) >> 12) & 0xfffff) @@ -192,6 +196,8 @@ enum { NVME_CSTS_SHST_OCCUR = 1 << 2, NVME_CSTS_SHST_CMPLT = 2 << 2, NVME_CSTS_SHST_MASK = 3 << 2, + NVME_CMBMSC_CRE = 1 << 0, + NVME_CMBMSC_CMSE = 1 << 1, }; struct nvme_id_power_state { -- GitLab From bffcd507780ea614b5543c66f2e37ce0d55cd449 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Wed, 13 Jan 2021 17:33:51 -0800 Subject: [PATCH 0328/1084] nvmet: set right status on error in id-ns handler The function nvmet_execute_identify_ns() doesn't set the status if call to nvmet_find_namespace() fails. In that case we set the status of the request to the value return by the nvmet_copy_sgl(). Set the status to NVME_SC_INVALID_NS and adjust the code such that request will have the right status on nvmet_find_namespace() failure. Without this patch :- NVME Identify Namespace 3: nsze : 0 ncap : 0 nuse : 0 nsfeat : 0 nlbaf : 0 flbas : 0 mc : 0 dpc : 0 dps : 0 nmic : 0 rescap : 0 fpi : 0 dlfeat : 0 nawun : 0 nawupf : 0 nacwu : 0 nabsn : 0 nabo : 0 nabspf : 0 noiob : 0 nvmcap : 0 mssrl : 0 mcl : 0 msrc : 0 nsattr : 0 nvmsetid: 0 anagrpid: 0 endgid : 0 nguid : 00000000000000000000000000000000 eui64 : 0000000000000000 lbaf 0 : ms:0 lbads:0 rp:0 (in use) With this patch-series :- feb3b88b501e (HEAD -> nvme-5.11) nvmet: remove extra variable in identify ns 6302aa67210a nvmet: remove extra variable in id-desclist ed57951da453 nvmet: remove extra variable in smart log nsid be384b8c24dc nvmet: set right status on error in id-ns handler NVMe status: INVALID_NS: The namespace or the format of that namespace is invalid(0xb) Signed-off-by: Chaitanya Kulkarni Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/nvme/target/admin-cmd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 8d90235e4fcc5..dc1ea468b182b 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -487,8 +487,10 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req) /* return an all zeroed buffer if we can't find an active namespace */ ns = nvmet_find_namespace(ctrl, req->cmd->identify.nsid); - if (!ns) + if (!ns) { + status = NVME_SC_INVALID_NS; goto done; + } nvmet_ns_revalidate(ns); @@ -541,7 +543,9 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req) id->nsattr |= (1 << 0); nvmet_put_namespace(ns); done: - status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id)); + if (!status) + status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id)); + kfree(id); out: nvmet_req_complete(req, status); -- GitLab From 3ed86b9a7140bb9b5ff0669778e56bf9b0e582a5 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Fri, 15 Jan 2021 18:41:53 +0100 Subject: [PATCH 0329/1084] kasan, arm64: fix pointer tags in KASAN reports As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address that is passed to report_tag_fault has pointer tags in the format of 0x0X, while KASAN uses 0xFX format (note the difference in the top 4 bits). Fix up the pointer tag for kernel pointers in do_tag_check_fault by setting them to the same value as bit 55. Explicitly use __untagged_addr() instead of untagged_addr(), as the latter doesn't affect TTBR1 addresses. Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo") Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler") Signed-off-by: Andrey Konovalov Reviewed-by: Catalin Marinas Reviewed-by: Vincenzo Frascino Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649 Link: https://lore.kernel.org/r/ff30b0afe6005fd046f9ac72bfb71822aedccd89.1610731872.git.andreyknvl@google.com Signed-off-by: Catalin Marinas --- arch/arm64/mm/fault.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 3c40da479899d..35d75c60e2b8d 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr, struct pt_regs *regs) { /* - * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN for tag - * check faults. Mask them out now so that userspace doesn't see them. + * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN + * for tag check faults. Set them to corresponding bits in the untagged + * address. */ - far &= (1UL << 60) - 1; + far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK); do_bad_area(far, esr, regs); return 0; } -- GitLab From 070222731be52d741e55d8967b1764482b81e54c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 14 Jan 2021 15:34:32 +0100 Subject: [PATCH 0330/1084] platform/x86: intel-vbtn: Drop HP Stream x360 Convertible PC 11 from allow-list THe HP Stream x360 Convertible PC 11 DSDT has the following VGBS function: Method (VGBS, 0, Serialized) { If ((^^PCI0.LPCB.EC0.ROLS == Zero)) { VBDS = Zero } Else { VBDS = Zero } Return (VBDS) /* \_SB_.VGBI.VBDS */ } Which is obviously wrong, because it always returns 0 independent of the 2-in-1 being in laptop or tablet mode. This causes the intel-vbtn driver to initially report SW_TABLET_MODE = 1 to userspace, which is known to cause problems when the 2-in-1 is actually in laptop mode. During earlier testing this turned out to not be a problem because the 2-in-1 would do a Notify(..., 0xCC) or Notify(..., 0xCD) soon after the intel-vbtn driver loaded, correcting the SW_TABLET_MODE state. Further testing however has shown that this Notify() soon after the intel-vbtn driver loads, does not always happen. When the Notify does not happen, then intel-vbtn reports SW_TABLET_MODE = 1 resulting in a non-working touchpad. IOW the tablet-mode reporting is not reliable on this device, so it should be dropped from the allow-list, fixing the touchpad sometimes not working. Fixes: 8169bd3e6e19 ("platform/x86: intel-vbtn: Switch to an allow-list for SW_TABLET_MODE reporting") Link: https://lore.kernel.org/r/20210114143432.31750-1-hdegoede@redhat.com Signed-off-by: Hans de Goede --- drivers/platform/x86/intel-vbtn.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c index 9bbdb26d43054..30a9062d2b4b8 100644 --- a/drivers/platform/x86/intel-vbtn.c +++ b/drivers/platform/x86/intel-vbtn.c @@ -204,12 +204,6 @@ static const struct dmi_system_id dmi_switches_allow_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), }, }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Stream x360 Convertible PC 11"), - }, - }, { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), -- GitLab From 79267ae22615496655feee2db0848f6786bcf67a Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Mon, 18 Jan 2021 15:52:10 +0200 Subject: [PATCH 0331/1084] net: mscc: ocelot: allow offloading of bridge on top of LAG The blamed commit was too aggressive, and it made ocelot_netdevice_event react only to network interface events emitted for the ocelot switch ports. In fact, only the PRECHANGEUPPER should have had that check. When we ignore all events that are not for us, we miss the fact that the upper of the LAG changes, and the bonding interface gets enslaved to a bridge. This is an operation we could offload under certain conditions. Fixes: 7afb3e575e5a ("net: mscc: ocelot: don't handle netdev events for other netdevs") Signed-off-by: Vladimir Oltean Reviewed-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210118135210.2666246-1-olteanv@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mscc/ocelot_net.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 2bd2840d88bdc..42230f92ca9c8 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -1042,10 +1042,8 @@ static int ocelot_netdevice_event(struct notifier_block *unused, struct net_device *dev = netdev_notifier_info_to_dev(ptr); int ret = 0; - if (!ocelot_netdevice_dev_check(dev)) - return 0; - if (event == NETDEV_PRECHANGEUPPER && + ocelot_netdevice_dev_check(dev) && netif_is_lag_master(info->upper_dev)) { struct netdev_lag_upper_info *lag_upper_info = info->upper_info; struct netlink_ext_ack *extack; -- GitLab From d35c9a029a73e84d84337403d20b060494890570 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 15 Jan 2021 00:27:44 +0100 Subject: [PATCH 0332/1084] platform/x86: hp-wmi: Don't log a warning on HPWMI_RET_UNKNOWN_COMMAND errors The recently added thermal policy support makes a hp_wmi_perform_query(0x4c, ...) call on older devices which do not support thermal policies this causes the following warning to be logged (seen on a HP Stream x360 Convertible PC 11): [ 26.805305] hp_wmi: query 0x4c returned error 0x3 Error 0x3 is HPWMI_RET_UNKNOWN_COMMAND error. This commit silences the warning for unknown-command errors, silencing the new warning. Cc: Elia Devito Fixes: 81c93798ef3e ("platform/x86: hp-wmi: add support for thermal policy") Link: https://lore.kernel.org/r/20210114232744.154886-1-hdegoede@redhat.com Signed-off-by: Hans de Goede --- drivers/platform/x86/hp-wmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index ecd477964d117..18bf8aeb5f870 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -247,7 +247,8 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command, ret = bios_return->return_code; if (ret) { - if (ret != HPWMI_RET_UNKNOWN_CMDTYPE) + if (ret != HPWMI_RET_UNKNOWN_COMMAND && + ret != HPWMI_RET_UNKNOWN_CMDTYPE) pr_warn("query 0x%x returned error 0x%x\n", query, ret); goto out_free; } -- GitLab From 173aac2fef96972e42d33c0e1189e6f756a0d719 Mon Sep 17 00:00:00 2001 From: Jeannie Stevenson Date: Fri, 15 Jan 2021 16:06:30 +0000 Subject: [PATCH 0333/1084] platform/x86: thinkpad_acpi: Add P53/73 firmware to fan_quirk_table for dual fan control This commit enables dual fan control for the new Lenovo P53 and P73 laptop models. Signed-off-by: Jeannie Stevenson Link: https://lore.kernel.org/r/Pn_Xii4XYpQRFtgkf4PbNgieE89BAkHgLI1kWIq-zFudwh2A1DY5J_DJVHK06rMW_hGPHx_mPE33gd8mg9-8BxqJTaSC6hhPqAsfZlcNGH0=@protonmail.com Signed-off-by: Hans de Goede --- drivers/platform/x86/thinkpad_acpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index c102657b3eb32..f3e8eca8d86d6 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -8783,6 +8783,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = { TPACPI_Q_LNV3('N', '1', 'T', TPACPI_FAN_2CTL), /* P71 */ TPACPI_Q_LNV3('N', '1', 'U', TPACPI_FAN_2CTL), /* P51 */ TPACPI_Q_LNV3('N', '2', 'C', TPACPI_FAN_2CTL), /* P52 / P72 */ + TPACPI_Q_LNV3('N', '2', 'N', TPACPI_FAN_2CTL), /* P53 / P73 */ TPACPI_Q_LNV3('N', '2', 'E', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (1st gen) */ TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (2nd gen) */ TPACPI_Q_LNV3('N', '2', 'V', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (3nd gen) */ -- GitLab From 87fe04367d842c4d97a77303242d4dd4ac351e46 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Sat, 16 Jan 2021 03:39:35 +0100 Subject: [PATCH 0334/1084] net: dsa: mv88e6xxx: also read STU state in mv88e6250_g1_vtu_getnext mv88e6xxx_port_vlan_join checks whether the VTU already contains an entry for the given vid (via mv88e6xxx_vtu_getnext), and if so, merely changes the relevant .member[] element and loads the updated entry into the VTU. However, at least for the mv88e6250, the on-stack struct mv88e6xxx_vtu_entry vlan never has its .state[] array explicitly initialized, neither in mv88e6xxx_port_vlan_join() nor inside the getnext implementation. So the new entry has random garbage for the STU bits, breaking VLAN filtering. When the VTU entry is initially created, those bits are all zero, and we should make sure to keep them that way when the entry is updated. Fixes: 92307069a96c (net: dsa: mv88e6xxx: Avoid VTU corruption on 6097) Signed-off-by: Rasmus Villemoes Reviewed-by: Florian Fainelli Reviewed-by: Tobias Waldekranz Tested-by: Tobias Waldekranz Signed-off-by: Jakub Kicinski --- drivers/net/dsa/mv88e6xxx/global1_vtu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx/global1_vtu.c b/drivers/net/dsa/mv88e6xxx/global1_vtu.c index 66ddf67b87371..7b96396be609e 100644 --- a/drivers/net/dsa/mv88e6xxx/global1_vtu.c +++ b/drivers/net/dsa/mv88e6xxx/global1_vtu.c @@ -351,6 +351,10 @@ int mv88e6250_g1_vtu_getnext(struct mv88e6xxx_chip *chip, if (err) return err; + err = mv88e6185_g1_stu_data_read(chip, entry); + if (err) + return err; + /* VTU DBNum[3:0] are located in VTU Operation 3:0 * VTU DBNum[5:4] are located in VTU Operation 9:8 */ -- GitLab From 92a5e1fdb286851d5bd0eb966b8d075be27cf5ee Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Mon, 18 Jan 2021 15:01:45 +0530 Subject: [PATCH 0335/1084] selftests/powerpc: Fix exit status of pkey tests Since main() does not return a value explicitly, the return values from FAIL_IF() conditions are ignored and the tests can still pass irrespective of failures. This makes sure that we always explicitly return the correct test exit status. Fixes: 1addb6444791 ("selftests/powerpc: Add test for execute-disabled pkeys") Fixes: c27f2fd1705a ("selftests/powerpc: Add test for pkey siginfo verification") Reported-by: Eirik Fuller Signed-off-by: Sandipan Das Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210118093145.10134-1-sandipan@linux.ibm.com --- tools/testing/selftests/powerpc/mm/pkey_exec_prot.c | 2 +- tools/testing/selftests/powerpc/mm/pkey_siginfo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c b/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c index 9e5c7f3f498a7..0af4f02669a11 100644 --- a/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c +++ b/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c @@ -290,5 +290,5 @@ static int test(void) int main(void) { - test_harness(test, "pkey_exec_prot"); + return test_harness(test, "pkey_exec_prot"); } diff --git a/tools/testing/selftests/powerpc/mm/pkey_siginfo.c b/tools/testing/selftests/powerpc/mm/pkey_siginfo.c index 4f815d7c12145..2db76e56d4cb9 100644 --- a/tools/testing/selftests/powerpc/mm/pkey_siginfo.c +++ b/tools/testing/selftests/powerpc/mm/pkey_siginfo.c @@ -329,5 +329,5 @@ static int test(void) int main(void) { - test_harness(test, "pkey_siginfo"); + return test_harness(test, "pkey_siginfo"); } -- GitLab From a372173bf314d374da4dd1155549d8ca7fc44709 Mon Sep 17 00:00:00 2001 From: Kamal Heib Date: Thu, 14 Jan 2021 21:14:23 +0200 Subject: [PATCH 0336/1084] RDMA/cxgb4: Fix the reported max_recv_sge value The max_recv_sge value is wrongly reported when calling query_qp, This is happening due to a typo when assigning the max_recv_sge value, the value of sq_max_sges was assigned instead of rq_max_sges. Fixes: 3e5c02c9ef9a ("iw_cxgb4: Support query_qp() verb") Link: https://lore.kernel.org/r/20210114191423.423529-1-kamalheib1@gmail.com Signed-off-by: Kamal Heib Reviewed-by: Potnuri Bharat Teja Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/cxgb4/qp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index a7401398cb344..d109bb3822a5f 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -2474,7 +2474,7 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, init_attr->cap.max_send_wr = qhp->attr.sq_num_entries; init_attr->cap.max_recv_wr = qhp->attr.rq_num_entries; init_attr->cap.max_send_sge = qhp->attr.sq_max_sges; - init_attr->cap.max_recv_sge = qhp->attr.sq_max_sges; + init_attr->cap.max_recv_sge = qhp->attr.rq_max_sges; init_attr->cap.max_inline_data = T4_MAX_SEND_INLINE; init_attr->sq_sig_type = qhp->sq_sig_all ? IB_SIGNAL_ALL_WR : 0; return 0; -- GitLab From a826b04303a40d52439aa141035fca5654ccaccd Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Fri, 15 Jan 2021 19:42:08 +0100 Subject: [PATCH 0337/1084] ipv6: create multicast route with RTPROT_KERNEL The ff00::/8 multicast route is created without specifying the fc_protocol field, so the default RTPROT_BOOT value is used: $ ip -6 -d route unicast ::1 dev lo proto kernel scope global metric 256 pref medium unicast fe80::/64 dev eth0 proto kernel scope global metric 256 pref medium unicast ff00::/8 dev eth0 proto boot scope global metric 256 pref medium As the documentation says, this value identifies routes installed during boot, but the route is created when interface is set up. Change the value to RTPROT_KERNEL which is a better value. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Matteo Croce Signed-off-by: Jakub Kicinski --- net/ipv6/addrconf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index eff2cacd52093..19bf6822911cd 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2469,6 +2469,7 @@ static void addrconf_add_mroute(struct net_device *dev) .fc_flags = RTF_UP, .fc_type = RTN_UNICAST, .fc_nlinfo.nl_net = dev_net(dev), + .fc_protocol = RTPROT_KERNEL, }; ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); -- GitLab From ceed9038b2783d14e0422bdc6fd04f70580efb4c Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Fri, 15 Jan 2021 19:42:09 +0100 Subject: [PATCH 0338/1084] ipv6: set multicast flag on the multicast route The multicast route ff00::/8 is created with type RTN_UNICAST: $ ip -6 -d route unicast ::1 dev lo proto kernel scope global metric 256 pref medium unicast fe80::/64 dev eth0 proto kernel scope global metric 256 pref medium unicast ff00::/8 dev eth0 proto kernel scope global metric 256 pref medium Set the type to RTN_MULTICAST which is more appropriate. Fixes: e8478e80e5a7 ("net/ipv6: Save route type in rt6_info") Signed-off-by: Matteo Croce Signed-off-by: Jakub Kicinski --- net/ipv6/addrconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 19bf6822911cd..9edc5bb2d531a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2467,7 +2467,7 @@ static void addrconf_add_mroute(struct net_device *dev) .fc_ifindex = dev->ifindex, .fc_dst_len = 8, .fc_flags = RTF_UP, - .fc_type = RTN_UNICAST, + .fc_type = RTN_MULTICAST, .fc_nlinfo.nl_net = dev_net(dev), .fc_protocol = RTPROT_KERNEL, }; -- GitLab From 9d9b1ee0b2d1c9e02b2338c4a4b0a062d2d3edac Mon Sep 17 00:00:00 2001 From: Enke Chen Date: Fri, 15 Jan 2021 14:30:58 -0800 Subject: [PATCH 0339/1084] tcp: fix TCP_USER_TIMEOUT with zero window The TCP session does not terminate with TCP_USER_TIMEOUT when data remain untransmitted due to zero window. The number of unanswered zero-window probes (tcp_probes_out) is reset to zero with incoming acks irrespective of the window size, as described in tcp_probe_timer(): RFC 1122 4.2.2.17 requires the sender to stay open indefinitely as long as the receiver continues to respond probes. We support this by default and reset icsk_probes_out with incoming ACKs. This counter, however, is the wrong one to be used in calculating the duration that the window remains closed and data remain untransmitted. Thanks to Jonathan Maxwell for diagnosing the actual issue. In this patch a new timestamp is introduced for the socket in order to track the elapsed time for the zero-window probes that have not been answered with any non-zero window ack. Fixes: 9721e709fa68 ("tcp: simplify window probe aborting on USER_TIMEOUT") Reported-by: William McCall Co-developed-by: Neal Cardwell Signed-off-by: Neal Cardwell Signed-off-by: Enke Chen Reviewed-by: Yuchung Cheng Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/20210115223058.GA39267@localhost.localdomain Signed-off-by: Jakub Kicinski --- include/net/inet_connection_sock.h | 3 +++ net/ipv4/inet_connection_sock.c | 1 + net/ipv4/tcp.c | 1 + net/ipv4/tcp_input.c | 1 + net/ipv4/tcp_output.c | 1 + net/ipv4/tcp_timer.c | 14 +++++++------- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 7338b3865a2a3..111d7771b2081 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -76,6 +76,8 @@ struct inet_connection_sock_af_ops { * @icsk_ext_hdr_len: Network protocol overhead (IP/IPv6 options) * @icsk_ack: Delayed ACK control data * @icsk_mtup; MTU probing control data + * @icsk_probes_tstamp: Probe timestamp (cleared by non-zero window ack) + * @icsk_user_timeout: TCP_USER_TIMEOUT value */ struct inet_connection_sock { /* inet_sock has to be the first member! */ @@ -129,6 +131,7 @@ struct inet_connection_sock { u32 probe_timestamp; } icsk_mtup; + u32 icsk_probes_tstamp; u32 icsk_user_timeout; u64 icsk_ca_priv[104 / sizeof(u64)]; diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index fd8b8800a2c30..6bd7ca09af03d 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -851,6 +851,7 @@ struct sock *inet_csk_clone_lock(const struct sock *sk, newicsk->icsk_retransmits = 0; newicsk->icsk_backoff = 0; newicsk->icsk_probes_out = 0; + newicsk->icsk_probes_tstamp = 0; /* Deinitialize accept_queue to trap illegal accesses. */ memset(&newicsk->icsk_accept_queue, 0, sizeof(newicsk->icsk_accept_queue)); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ed42d2193c5c7..32545ecf2ab10 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2937,6 +2937,7 @@ int tcp_disconnect(struct sock *sk, int flags) icsk->icsk_backoff = 0; icsk->icsk_probes_out = 0; + icsk->icsk_probes_tstamp = 0; icsk->icsk_rto = TCP_TIMEOUT_INIT; icsk->icsk_rto_min = TCP_RTO_MIN; icsk->icsk_delack_max = TCP_DELACK_MAX; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c7e16b0ed791f..bafcab75f4256 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3384,6 +3384,7 @@ static void tcp_ack_probe(struct sock *sk) return; if (!after(TCP_SKB_CB(head)->end_seq, tcp_wnd_end(tp))) { icsk->icsk_backoff = 0; + icsk->icsk_probes_tstamp = 0; inet_csk_clear_xmit_timer(sk, ICSK_TIME_PROBE0); /* Socket must be waked up by subsequent tcp_data_snd_check(). * This function is not for random using! diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f322e798a3519..ab458697881ed 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -4084,6 +4084,7 @@ void tcp_send_probe0(struct sock *sk) /* Cancel probe timer, if it is not required. */ icsk->icsk_probes_out = 0; icsk->icsk_backoff = 0; + icsk->icsk_probes_tstamp = 0; return; } diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 6c62b9ea1320d..454732ecc8f33 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -349,6 +349,7 @@ static void tcp_probe_timer(struct sock *sk) if (tp->packets_out || !skb) { icsk->icsk_probes_out = 0; + icsk->icsk_probes_tstamp = 0; return; } @@ -360,13 +361,12 @@ static void tcp_probe_timer(struct sock *sk) * corresponding system limit. We also implement similar policy when * we use RTO to probe window in tcp_retransmit_timer(). */ - if (icsk->icsk_user_timeout) { - u32 elapsed = tcp_model_timeout(sk, icsk->icsk_probes_out, - tcp_probe0_base(sk)); - - if (elapsed >= icsk->icsk_user_timeout) - goto abort; - } + if (!icsk->icsk_probes_tstamp) + icsk->icsk_probes_tstamp = tcp_jiffies32; + else if (icsk->icsk_user_timeout && + (s32)(tcp_jiffies32 - icsk->icsk_probes_tstamp) >= + msecs_to_jiffies(icsk->icsk_user_timeout)) + goto abort; max_probes = sock_net(sk)->ipv4.sysctl_tcp_retries2; if (sock_flag(sk, SOCK_DEAD)) { -- GitLab From d502297008142645edf5c791af424ed321e5da84 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Jan 2021 15:53:35 +1000 Subject: [PATCH 0340/1084] drm/nouveau/nvif: fix method count when pushing an array Reported-by: Lyude Paul Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/push.h | 216 ++++++++++---------- 1 file changed, 108 insertions(+), 108 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/push.h b/drivers/gpu/drm/nouveau/include/nvif/push.h index 168d7694ede5c..6d3a8a3d2087b 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/push.h +++ b/drivers/gpu/drm/nouveau/include/nvif/push.h @@ -123,131 +123,131 @@ PUSH_KICK(struct nvif_push *push) } while(0) #endif -#define PUSH_1(X,f,ds,n,c,o,p,s,mA,dA) do { \ - PUSH_##o##_HDR((p), s, mA, (c)+(n)); \ - PUSH_##f(X, (p), X##mA, 1, o, (dA), ds, ""); \ +#define PUSH_1(X,f,ds,n,o,p,s,mA,dA) do { \ + PUSH_##o##_HDR((p), s, mA, (ds)+(n)); \ + PUSH_##f(X, (p), X##mA, 1, o, (dA), ds, ""); \ } while(0) -#define PUSH_2(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ - PUSH_ASSERT((mB) - (mA) == (1?PUSH_##o##_INC), "mthd1"); \ - PUSH_1(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ - PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ +#define PUSH_2(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ + PUSH_ASSERT((mB) - (mA) == (1?PUSH_##o##_INC), "mthd1"); \ + PUSH_1(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ } while(0) -#define PUSH_3(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ - PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd2"); \ - PUSH_2(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ - PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ +#define PUSH_3(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd2"); \ + PUSH_2(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ } while(0) -#define PUSH_4(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ - PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd3"); \ - PUSH_3(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ - PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ +#define PUSH_4(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd3"); \ + PUSH_3(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ } while(0) -#define PUSH_5(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ - PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd4"); \ - PUSH_4(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ - PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ +#define PUSH_5(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd4"); \ + PUSH_4(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ } while(0) -#define PUSH_6(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ - PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd5"); \ - PUSH_5(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ - PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ +#define PUSH_6(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd5"); \ + PUSH_5(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ } while(0) -#define PUSH_7(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ - PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd6"); \ - PUSH_6(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ - PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ +#define PUSH_7(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd6"); \ + PUSH_6(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ } while(0) -#define PUSH_8(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ - PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd7"); \ - PUSH_7(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ - PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ +#define PUSH_8(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd7"); \ + PUSH_7(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ } while(0) -#define PUSH_9(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ - PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd8"); \ - PUSH_8(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ - PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ +#define PUSH_9(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd8"); \ + PUSH_8(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ } while(0) -#define PUSH_10(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do { \ - PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd9"); \ - PUSH_9(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \ - PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ +#define PUSH_10(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do { \ + PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd9"); \ + PUSH_9(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \ + PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, ""); \ } while(0) -#define PUSH_1D(X,o,p,s,mA,dA) \ - PUSH_1(X, DATA_, 1, 1, 0, o, (p), s, X##mA, (dA)) -#define PUSH_2D(X,o,p,s,mA,dA,mB,dB) \ - PUSH_2(X, DATA_, 1, 1, 0, o, (p), s, X##mB, (dB), \ - X##mA, (dA)) -#define PUSH_3D(X,o,p,s,mA,dA,mB,dB,mC,dC) \ - PUSH_3(X, DATA_, 1, 1, 0, o, (p), s, X##mC, (dC), \ - X##mB, (dB), \ - X##mA, (dA)) -#define PUSH_4D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD) \ - PUSH_4(X, DATA_, 1, 1, 0, o, (p), s, X##mD, (dD), \ - X##mC, (dC), \ - X##mB, (dB), \ - X##mA, (dA)) -#define PUSH_5D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE) \ - PUSH_5(X, DATA_, 1, 1, 0, o, (p), s, X##mE, (dE), \ - X##mD, (dD), \ - X##mC, (dC), \ - X##mB, (dB), \ - X##mA, (dA)) +#define PUSH_1D(X,o,p,s,mA,dA) \ + PUSH_1(X, DATA_, 1, 0, o, (p), s, X##mA, (dA)) +#define PUSH_2D(X,o,p,s,mA,dA,mB,dB) \ + PUSH_2(X, DATA_, 1, 0, o, (p), s, X##mB, (dB), \ + X##mA, (dA)) +#define PUSH_3D(X,o,p,s,mA,dA,mB,dB,mC,dC) \ + PUSH_3(X, DATA_, 1, 0, o, (p), s, X##mC, (dC), \ + X##mB, (dB), \ + X##mA, (dA)) +#define PUSH_4D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD) \ + PUSH_4(X, DATA_, 1, 0, o, (p), s, X##mD, (dD), \ + X##mC, (dC), \ + X##mB, (dB), \ + X##mA, (dA)) +#define PUSH_5D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE) \ + PUSH_5(X, DATA_, 1, 0, o, (p), s, X##mE, (dE), \ + X##mD, (dD), \ + X##mC, (dC), \ + X##mB, (dB), \ + X##mA, (dA)) #define PUSH_6D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF) \ - PUSH_6(X, DATA_, 1, 1, 0, o, (p), s, X##mF, (dF), \ - X##mE, (dE), \ - X##mD, (dD), \ - X##mC, (dC), \ - X##mB, (dB), \ - X##mA, (dA)) + PUSH_6(X, DATA_, 1, 0, o, (p), s, X##mF, (dF), \ + X##mE, (dE), \ + X##mD, (dD), \ + X##mC, (dC), \ + X##mB, (dB), \ + X##mA, (dA)) #define PUSH_7D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG) \ - PUSH_7(X, DATA_, 1, 1, 0, o, (p), s, X##mG, (dG), \ - X##mF, (dF), \ - X##mE, (dE), \ - X##mD, (dD), \ - X##mC, (dC), \ - X##mB, (dB), \ - X##mA, (dA)) + PUSH_7(X, DATA_, 1, 0, o, (p), s, X##mG, (dG), \ + X##mF, (dF), \ + X##mE, (dE), \ + X##mD, (dD), \ + X##mC, (dC), \ + X##mB, (dB), \ + X##mA, (dA)) #define PUSH_8D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH) \ - PUSH_8(X, DATA_, 1, 1, 0, o, (p), s, X##mH, (dH), \ - X##mG, (dG), \ - X##mF, (dF), \ - X##mE, (dE), \ - X##mD, (dD), \ - X##mC, (dC), \ - X##mB, (dB), \ - X##mA, (dA)) + PUSH_8(X, DATA_, 1, 0, o, (p), s, X##mH, (dH), \ + X##mG, (dG), \ + X##mF, (dF), \ + X##mE, (dE), \ + X##mD, (dD), \ + X##mC, (dC), \ + X##mB, (dB), \ + X##mA, (dA)) #define PUSH_9D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,dI) \ - PUSH_9(X, DATA_, 1, 1, 0, o, (p), s, X##mI, (dI), \ - X##mH, (dH), \ - X##mG, (dG), \ - X##mF, (dF), \ - X##mE, (dE), \ - X##mD, (dD), \ - X##mC, (dC), \ - X##mB, (dB), \ - X##mA, (dA)) + PUSH_9(X, DATA_, 1, 0, o, (p), s, X##mI, (dI), \ + X##mH, (dH), \ + X##mG, (dG), \ + X##mF, (dF), \ + X##mE, (dE), \ + X##mD, (dD), \ + X##mC, (dC), \ + X##mB, (dB), \ + X##mA, (dA)) #define PUSH_10D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,dI,mJ,dJ) \ - PUSH_10(X, DATA_, 1, 1, 0, o, (p), s, X##mJ, (dJ), \ - X##mI, (dI), \ - X##mH, (dH), \ - X##mG, (dG), \ - X##mF, (dF), \ - X##mE, (dE), \ - X##mD, (dD), \ - X##mC, (dC), \ - X##mB, (dB), \ - X##mA, (dA)) + PUSH_10(X, DATA_, 1, 0, o, (p), s, X##mJ, (dJ), \ + X##mI, (dI), \ + X##mH, (dH), \ + X##mG, (dG), \ + X##mF, (dF), \ + X##mE, (dE), \ + X##mD, (dD), \ + X##mC, (dC), \ + X##mB, (dB), \ + X##mA, (dA)) -#define PUSH_1P(X,o,p,s,mA,dp,ds) \ - PUSH_1(X, DATAp, ds, ds, 0, o, (p), s, X##mA, (dp)) -#define PUSH_2P(X,o,p,s,mA,dA,mB,dp,ds) \ - PUSH_2(X, DATAp, ds, ds, 0, o, (p), s, X##mB, (dp), \ - X##mA, (dA)) -#define PUSH_3P(X,o,p,s,mA,dA,mB,dB,mC,dp,ds) \ - PUSH_3(X, DATAp, ds, ds, 0, o, (p), s, X##mC, (dp), \ - X##mB, (dB), \ - X##mA, (dA)) +#define PUSH_1P(X,o,p,s,mA,dp,ds) \ + PUSH_1(X, DATAp, ds, 0, o, (p), s, X##mA, (dp)) +#define PUSH_2P(X,o,p,s,mA,dA,mB,dp,ds) \ + PUSH_2(X, DATAp, ds, 0, o, (p), s, X##mB, (dp), \ + X##mA, (dA)) +#define PUSH_3P(X,o,p,s,mA,dA,mB,dB,mC,dp,ds) \ + PUSH_3(X, DATAp, ds, 0, o, (p), s, X##mC, (dp), \ + X##mB, (dB), \ + X##mA, (dA)) #define PUSH_(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,IMPL,...) IMPL #define PUSH(A...) PUSH_(A, PUSH_10P, PUSH_10D, \ -- GitLab From 1c4995b0a576d24bb7ead991fb037c8b47ab6e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 18 Jan 2021 17:43:55 +0200 Subject: [PATCH 0341/1084] drm/i915: Only enable DFP 4:4:4->4:2:0 conversion when outputting YCbCr 4:4:4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's not enable the 4:4:4->4:2:0 conversion bit in the DFP unless we're actually outputting YCbCr 4:4:4. It would appear some protocol converters blindy consult this bit even when the source is outputting RGB, resulting in a visual mess. Cc: stable@vger.kernel.org Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2914 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210111164111.13302-1-ville.syrjala@linux.intel.com Fixes: 181567aa9f0d ("drm/i915: Do YCbCr 444->420 conversion via DP protocol converters") Reviewed-by: Jani Nikula (cherry picked from commit 3170a21f7059c4660c469f59bf529f372a57da5f) Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210118154355.24453-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 9 +++++---- drivers/gpu/drm/i915/display/intel_dp.h | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 92940a0c5ef8f..d5ace48b1acee 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3725,7 +3725,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_init_dp_buf_reg(encoder, crtc_state); if (!is_mst) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); - intel_dp_configure_protocol_converter(intel_dp); + intel_dp_configure_protocol_converter(intel_dp, crtc_state); intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); intel_dp_sink_set_fec_ready(intel_dp, crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 37f1a10fd0217..09123e8625c49 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4014,7 +4014,8 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp, intel_de_posting_read(dev_priv, intel_dp->output_reg); } -void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp) +void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); u8 tmp; @@ -4033,8 +4034,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp) drm_dbg_kms(&i915->drm, "Failed to set protocol converter HDMI mode to %s\n", enableddisabled(intel_dp->has_hdmi_sink)); - tmp = intel_dp->dfp.ycbcr_444_to_420 ? - DP_CONVERSION_TO_YCBCR420_ENABLE : 0; + tmp = crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 && + intel_dp->dfp.ycbcr_444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0; if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1) @@ -4088,7 +4089,7 @@ static void intel_enable_dp(struct intel_atomic_state *state, } intel_dp_set_power(intel_dp, DP_SET_POWER_D0); - intel_dp_configure_protocol_converter(intel_dp); + intel_dp_configure_protocol_converter(intel_dp, pipe_config); intel_dp_start_link_train(intel_dp, pipe_config); intel_dp_stop_link_train(intel_dp, pipe_config); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index b871a09b69013..05f7ddf7a7952 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -51,7 +51,8 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, int intel_dp_retrain_link(struct intel_encoder *encoder, struct drm_modeset_acquire_ctx *ctx); void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode); -void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp); +void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, bool enable); -- GitLab From 0bab9cb2d980d7c075cffb9216155f7835237f98 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 14 Jan 2021 14:25:35 +0100 Subject: [PATCH 0342/1084] x86/entry: Remove put_ret_addr_in_rdi THUNK macro argument That logic is unused since 320100a5ffe5 ("x86/entry: Remove the TRACE_IRQS cruft") Remove it. Suggested-by: Peter Zijlstra (Intel) Acked-by: Peter Zijlstra (Intel) Signed-off-by: Borislav Petkov Link: https://lkml.kernel.org/r/YAAszZJ2GcIYZmB5@hirez.programming.kicks-ass.net --- arch/x86/entry/thunk_64.S | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk_64.S index c9a9fbf1655f3..496b11ec469de 100644 --- a/arch/x86/entry/thunk_64.S +++ b/arch/x86/entry/thunk_64.S @@ -10,7 +10,7 @@ #include /* rdi: arg1 ... normal C conventions. rax is saved/restored. */ - .macro THUNK name, func, put_ret_addr_in_rdi=0 + .macro THUNK name, func SYM_FUNC_START_NOALIGN(\name) pushq %rbp movq %rsp, %rbp @@ -25,11 +25,6 @@ SYM_FUNC_START_NOALIGN(\name) pushq %r10 pushq %r11 - .if \put_ret_addr_in_rdi - /* 8(%rbp) is return addr on stack */ - movq 8(%rbp), %rdi - .endif - call \func jmp __thunk_restore SYM_FUNC_END(\name) -- GitLab From f0e386ee0c0b71ea6f7238506a4d0965a2dbef11 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Thu, 14 Jan 2021 18:10:12 +0106 Subject: [PATCH 0343/1084] printk: fix buffer overflow potential for print_text() Before the commit 896fbe20b4e2333fb55 ("printk: use the lockless ringbuffer"), msg_print_text() would only write up to size-1 bytes into the provided buffer. Some callers expect this behavior and append a terminator to returned string. In particular: arch/powerpc/xmon/xmon.c:dump_log_buf() arch/um/kernel/kmsg_dump.c:kmsg_dumper_stdout() msg_print_text() has been replaced by record_print_text(), which currently fills the full size of the buffer. This causes a buffer overflow for the above callers. Change record_print_text() so that it will only use size-1 bytes for text data. Also, for paranoia sakes, add a terminator after the text data. And finally, document this behavior so that it is clear that only size-1 bytes are used and a terminator is added. Fixes: 896fbe20b4e2333fb55 ("printk: use the lockless ringbuffer") Cc: stable@vger.kernel.org # 5.10+ Signed-off-by: John Ogness Reviewed-by: Petr Mladek Acked-by: Sergey Senozhatsky Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20210114170412.4819-1-john.ogness@linutronix.de --- kernel/printk/printk.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 96e24074c9626..17fa6dc77053b 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1292,11 +1292,16 @@ static size_t info_print_prefix(const struct printk_info *info, bool syslog, * done: * * - Add prefix for each line. + * - Drop truncated lines that no longer fit into the buffer. * - Add the trailing newline that has been removed in vprintk_store(). - * - Drop truncated lines that do not longer fit into the buffer. + * - Add a string terminator. + * + * Since the produced string is always terminated, the maximum possible + * return value is @r->text_buf_size - 1; * * Return: The length of the updated/prepared text, including the added - * prefixes and the newline. The dropped line(s) are not counted. + * prefixes and the newline. The terminator is not counted. The dropped + * line(s) are not counted. */ static size_t record_print_text(struct printk_record *r, bool syslog, bool time) @@ -1339,26 +1344,31 @@ static size_t record_print_text(struct printk_record *r, bool syslog, /* * Truncate the text if there is not enough space to add the - * prefix and a trailing newline. + * prefix and a trailing newline and a terminator. */ - if (len + prefix_len + text_len + 1 > buf_size) { + if (len + prefix_len + text_len + 1 + 1 > buf_size) { /* Drop even the current line if no space. */ - if (len + prefix_len + line_len + 1 > buf_size) + if (len + prefix_len + line_len + 1 + 1 > buf_size) break; - text_len = buf_size - len - prefix_len - 1; + text_len = buf_size - len - prefix_len - 1 - 1; truncated = true; } memmove(text + prefix_len, text, text_len); memcpy(text, prefix, prefix_len); + /* + * Increment the prepared length to include the text and + * prefix that were just moved+copied. Also increment for the + * newline at the end of this line. If this is the last line, + * there is no newline, but it will be added immediately below. + */ len += prefix_len + line_len + 1; - if (text_len == line_len) { /* - * Add the trailing newline removed in - * vprintk_store(). + * This is the last line. Add the trailing newline + * removed in vprintk_store(). */ text[prefix_len + line_len] = '\n'; break; @@ -1383,6 +1393,14 @@ static size_t record_print_text(struct printk_record *r, bool syslog, text_len -= line_len + 1; } + /* + * If a buffer was provided, it will be terminated. Space for the + * string terminator is guaranteed to be available. The terminator is + * not counted in the return value. + */ + if (buf_size > 0) + text[len] = 0; + return len; } -- GitLab From ef38237444ce952daf041ed2885918f9f7d1e997 Mon Sep 17 00:00:00 2001 From: Nikita Shubin Date: Mon, 18 Jan 2021 12:05:08 +0300 Subject: [PATCH 0344/1084] gpiolib: add a warning on gpiochip->to_irq defined gpiochip->to_irq method is redefined in gpiochip_add_irqchip. A lot of gpiod driver's still define ->to_irq method, let's give a gentle warning that they can no longer rely on it, so they can remove it on ocassion. Fixes: e0d8972898139 ("gpio: Implement tighter IRQ chip integration") Signed-off-by: Nikita Shubin Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index b02cc2abd3b68..b78a634cca240 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1489,6 +1489,9 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc, type = IRQ_TYPE_NONE; } + if (gc->to_irq) + chip_warn(gc, "to_irq is redefined in %s and you shouldn't rely on it\n", __func__); + gc->to_irq = gpiochip_to_irq; gc->irq.default_type = type; gc->irq.lock_key = lock_key; -- GitLab From e73b0101ae5124bf7cd3fb5d250302ad2f16a416 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Sun, 17 Jan 2021 15:17:02 +0200 Subject: [PATCH 0345/1084] gpio: mvebu: fix pwm .get_state period calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The period is the sum of on and off values. That is, calculate period as ($on + $off) / clkrate instead of $off / clkrate - $on / clkrate that makes no sense. Reported-by: Russell King Reviewed-by: Uwe Kleine-König Fixes: 757642f9a584e ("gpio: mvebu: Add limited PWM support") Signed-off-by: Baruch Siach Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mvebu.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 672681a976f50..a912a8fed197a 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -676,20 +676,17 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip, else state->duty_cycle = 1; + val = (unsigned long long) u; /* on duration */ regmap_read(mvpwm->regs, mvebu_pwmreg_blink_off_duration(mvpwm), &u); - val = (unsigned long long) u * NSEC_PER_SEC; + val += (unsigned long long) u; /* period = on + off duration */ + val *= NSEC_PER_SEC; do_div(val, mvpwm->clk_rate); - if (val < state->duty_cycle) { + if (val > UINT_MAX) + state->period = UINT_MAX; + else if (val) + state->period = val; + else state->period = 1; - } else { - val -= state->duty_cycle; - if (val > UINT_MAX) - state->period = UINT_MAX; - else if (val) - state->period = val; - else - state->period = 1; - } regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset, &u); if (u) -- GitLab From 18eedf2b5ec7c8ce2bb23d9148cfd63949207414 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 18 Jan 2021 19:18:13 -0800 Subject: [PATCH 0346/1084] gpio: sifive: select IRQ_DOMAIN_HIERARCHY rather than depend on it This is the only driver in the kernel source tree that depends on IRQ_DOMAIN_HIERARCHY instead of selecting it. Since it is not a visible Kconfig symbol, depending on it (expecting a user to set/enable it) doesn't make much sense, so change it to select instead of "depends on". Fixes: 96868dce644d ("gpio/sifive: Add GPIO driver for SiFive SoCs") Signed-off-by: Randy Dunlap Cc: Linus Walleij Cc: Bartosz Golaszewski Cc: linux-gpio@vger.kernel.org Cc: Thierry Reding Cc: Greentime Hu Cc: Yash Shah Signed-off-by: Bartosz Golaszewski --- drivers/gpio/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c70f46e80a3b7..64291ce454c3f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -521,7 +521,8 @@ config GPIO_SAMA5D2_PIOBU config GPIO_SIFIVE bool "SiFive GPIO support" - depends on OF_GPIO && IRQ_DOMAIN_HIERARCHY + depends on OF_GPIO + select IRQ_DOMAIN_HIERARCHY select GPIO_GENERIC select GPIOLIB_IRQCHIP select REGMAP_MMIO -- GitLab From 298d75c9b18875d2d582dcd5145a45cac8d2bae2 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 18 Jan 2021 20:49:25 +0100 Subject: [PATCH 0347/1084] gpio: tegra: Add missing dependencies Commit efcdca286eef ("gpio: tegra: Convert to gpio_irq_chip") moved the Tegra GPIO driver to the generic GPIO IRQ chip infrastructure and made the IRQ domain hierarchical, so the driver needs to pull in the support infrastructure via the GPIOLIB_IRQCHIP and IRQ_DOMAIN_HIERARCHY Kconfig options. Fixes: efcdca286eef ("gpio: tegra: Convert to gpio_irq_chip") Reported-by: kernel test robot Signed-off-by: Thierry Reding Signed-off-by: Bartosz Golaszewski --- drivers/gpio/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 64291ce454c3f..dea65d85594fc 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -598,6 +598,8 @@ config GPIO_TEGRA default ARCH_TEGRA depends on ARCH_TEGRA || COMPILE_TEST depends on OF_GPIO + select GPIOLIB_IRQCHIP + select IRQ_DOMAIN_HIERARCHY help Say yes here to support GPIO pins on NVIDIA Tegra SoCs. -- GitLab From ef02684c4e67d8c35ac83083564135bc7b1d3445 Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Mon, 18 Jan 2021 21:36:15 +0100 Subject: [PATCH 0348/1084] usb: bdc: Make bdc pci driver depend on BROKEN The bdc pci driver is going to be removed due to it not existing in the wild. This patch turns off compilation of the driver so that stable kernels can also pick up the change. This helps the out-of-tree facetimehd webcam driver as the pci id conflicts with bdc. Cc: Al Cooper Cc: Acked-by: Felipe Balbi Signed-off-by: Patrik Jakobsson Link: https://lore.kernel.org/r/20210118203615.13995-1-patrik.r.jakobsson@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/bdc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig index 3e88c7670b2ed..fb01ff47b64cf 100644 --- a/drivers/usb/gadget/udc/bdc/Kconfig +++ b/drivers/usb/gadget/udc/bdc/Kconfig @@ -17,7 +17,7 @@ if USB_BDC_UDC comment "Platform Support" config USB_BDC_PCI tristate "BDC support for PCIe based platforms" - depends on USB_PCI + depends on USB_PCI && BROKEN default USB_BDC_UDC help Enable support for platforms which have BDC connected through PCIe, such as Lego3 FPGA platform. -- GitLab From 43b67309b6b2a3c08396cc9b3f83f21aa529d273 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Tue, 19 Jan 2021 04:11:27 -0800 Subject: [PATCH 0349/1084] drm/atomic: put state on error path Put the state before returning error code. Fixes: 44596b8c4750 ("drm/atomic: Unify conflicting encoder handling.") Signed-off-by: Pan Bian Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20210119121127.84127-1-bianpan2016@163.com --- drivers/gpu/drm/drm_atomic_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index ba1507036f265..4a8cbec832bc4 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3021,7 +3021,7 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set, ret = handle_conflicting_encoders(state, true); if (ret) - return ret; + goto fail; ret = drm_atomic_commit(state); -- GitLab From d3afb00220becf81bc2d9016f04e05949dfd5bb2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Jan 2021 14:33:35 +0100 Subject: [PATCH 0350/1084] ASoC: intel: skl: Simplify with dma_set_mask_and_coherent() ASoC Intel Skylake driver still has explicit calls of dma_set_mask() and dma_set_coherent_mask(). Let's simplify with dma_set_mask_and_coherent(). Cc: Cezary Rojewski Cc: Pierre-Louis Bossart Signed-off-by: Takashi Iwai Link: https://lore.kernel.org/r/20210114133337.1039-2-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 8b993722f74e7..5b1a15e399123 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -950,12 +950,8 @@ static int skl_first_init(struct hdac_bus *bus) bus->num_streams = cp_streams + pb_streams; /* allow 64bit DMA address if supported by H/W */ - if (!dma_set_mask(bus->dev, DMA_BIT_MASK(64))) { - dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(64)); - } else { - dma_set_mask(bus->dev, DMA_BIT_MASK(32)); - dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(32)); - } + if (dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(64))) + dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(32)); /* initialize streams */ snd_hdac_ext_stream_init_all -- GitLab From ab152afa2427bb3e4eea7c9f21c4393287838774 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Jan 2021 14:33:36 +0100 Subject: [PATCH 0351/1084] ASoC: SOF: intel: Simplify with dma_set_mask_and_coherent() ASoC Intel SOF driver still has explicit calls of dma_set_mask() and dma_set_coherent_mask(). Let's simplify with dma_set_mask_and_coherent(). Cc: Pierre-Louis Bossart Cc: Ranjani Sridharan Cc: Kai Vehmanen Signed-off-by: Takashi Iwai Link: https://lore.kernel.org/r/20210114133337.1039-3-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 509a9b2564230..7e703ce22fcd3 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -809,13 +809,9 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) sdev->mailbox_bar = HDA_DSP_BAR; /* allow 64bit DMA address if supported by H/W */ - if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(64))) { - dev_dbg(sdev->dev, "DMA mask is 64 bit\n"); - dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(64)); - } else { + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(64))) { dev_dbg(sdev->dev, "DMA mask is 32 bit\n"); - dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); - dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); + dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); } /* init streams */ -- GitLab From 7cc206bff69b52be24fa13ee2c9afde3320c6cf6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Jan 2021 14:33:37 +0100 Subject: [PATCH 0352/1084] ASoC: tegra: Simplify with dma_set_mask_and_coherent() ASoC tegra PCM code still has explicit calls of dma_set_mask() and dma_set_coherent_mask(). Let's simplify with dma_set_mask_and_coherent(). Cc: Thierry Reding Cc: Jonathan Hunter Signed-off-by: Takashi Iwai Link: https://lore.kernel.org/r/20210114133337.1039-4-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_pcm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index b3f36515cbc18..573374b89b100 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -255,11 +255,7 @@ static int tegra_pcm_dma_allocate(struct snd_soc_pcm_runtime *rtd, struct snd_pcm *pcm = rtd->pcm; int ret; - ret = dma_set_mask(card->dev, DMA_BIT_MASK(32)); - if (ret < 0) - return ret; - - ret = dma_set_coherent_mask(card->dev, DMA_BIT_MASK(32)); + ret = dma_set_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); if (ret < 0) return ret; -- GitLab From 9e0f86fdcdab6a0e183ad4ec2410453985b4cf3c Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Tue, 19 Jan 2021 14:58:11 +0530 Subject: [PATCH 0353/1084] ASoC: dt-bindings: tegra: Add graph bindings Add device tree binding properties of generic graph to ASoC component devices. This allows to define audio ports out of these components or DAIs and audio graph based sound card can be realised with this. Signed-off-by: Sameer Pujar Reviewed-by: Jon Hunter Link: https://lore.kernel.org/r/1611048496-24650-2-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- .../bindings/sound/nvidia,tegra186-dspk.yaml | 18 +++++++++++++++++- .../bindings/sound/nvidia,tegra210-admaif.yaml | 13 ++++++++++++- .../bindings/sound/nvidia,tegra210-ahub.yaml | 13 +++++++++++-- .../bindings/sound/nvidia,tegra210-dmic.yaml | 18 +++++++++++++++++- .../bindings/sound/nvidia,tegra210-i2s.yaml | 18 +++++++++++++++++- 5 files changed, 74 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml index ed2fb32fcdd44..b8645d9c38ac8 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml @@ -17,6 +17,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^dspk@[0-9a-f]*$" @@ -55,6 +58,19 @@ properties: The name can be "DSPK1" or "DSPKx", where x depends on the maximum available instances on a Tegra SoC. + ports: + type: object + properties: + port@0: + description: | + DSPK ACIF (Audio Client Interface) port connected to the + corresponding AHUB (Audio Hub) ACIF port. + + port@1: + description: | + DSPK DAP (Digital Audio Port) interface which can be connected + to external audio codec for playback. + required: - compatible - reg @@ -64,7 +80,7 @@ required: - assigned-clock-parents - sound-name-prefix -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml index c028b259e822e..7cee7722df413 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml @@ -17,6 +17,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^admaif@[0-9a-f]*$" @@ -37,6 +40,14 @@ properties: dma-names: true + ports: + description: | + Contains list of ACIF (Audio CIF) port nodes for ADMAIF channels. + The number of port nodes depends on the number of ADMAIF channels + that SoC may have. These are interfaced with respective ACIF ports + in AHUB (Audio Hub). Each port is capable of data transfers in + both directions. + if: properties: compatible: @@ -81,7 +92,7 @@ required: - dmas - dma-names -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml index d77219727768e..31f3e51974bb4 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml @@ -17,6 +17,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^ahub@[0-9a-f]*$" @@ -56,6 +59,13 @@ properties: ranges: true + ports: + description: | + Contains list of ACIF (Audio CIF) port nodes for AHUB (Audio Hub). + These are connected to ACIF interfaces of AHUB clients. Thus the + number of port nodes depend on the number of clients that AHUB may + have depending on the SoC revision. + required: - compatible - reg @@ -67,8 +77,7 @@ required: - "#size-cells" - ranges -additionalProperties: - type: object +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml index 2a3207b550e7a..89f4f471be24f 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml @@ -16,6 +16,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^dmic@[0-9a-f]*$" @@ -56,6 +59,19 @@ properties: The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends on the maximum available instances on a Tegra SoC. + ports: + type: object + properties: + port@0: + description: | + DMIC ACIF (Audio Client Interface) port connected to the + corresponding AHUB (Audio Hub) ACIF port. + + port@1: + description: | + DMIC DAP (Digital Audio Port) interface which can be connected + to external audio codec for capture. + required: - compatible - reg @@ -64,7 +80,7 @@ required: - assigned-clocks - assigned-clock-parents -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml index dfc1bf7b77222..556460332ffb8 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml @@ -16,6 +16,9 @@ maintainers: - Jon Hunter - Sameer Pujar +allOf: + - $ref: audio-graph-port.yaml# + properties: $nodename: pattern: "^i2s@[0-9a-f]*$" @@ -74,6 +77,19 @@ properties: The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends on the maximum available instances on a Tegra SoC. + ports: + type: object + properties: + port@0: + description: | + I2S ACIF (Audio Client Interface) port connected to the + corresponding AHUB (Audio Hub) ACIF port. + + port@1: + description: | + I2S DAP (Digital Audio Port) interface which can be connected + to external audio codec for playback or capture. + required: - compatible - reg @@ -82,7 +98,7 @@ required: - assigned-clocks - assigned-clock-parents -additionalProperties: false +unevaluatedProperties: false examples: - | -- GitLab From a9f22c03a8ac5d21ce7a9b9307d9654c963a1f9c Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Tue, 19 Jan 2021 14:58:12 +0530 Subject: [PATCH 0354/1084] ASoC: dt-bindings: tegra: Add json-schema for Tegra audio graph card Add YAML schema for Tegra audio graph sound card DT bindings. It uses the same DT bindings provided by generic audio graph driver. Along with this few standard clock DT bindings are added which are specifically required for Tegra audio. Signed-off-by: Sameer Pujar Reviewed-by: Jon Hunter Link: https://lore.kernel.org/r/1611048496-24650-3-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- .../sound/nvidia,tegra-audio-graph-card.yaml | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml new file mode 100644 index 0000000000000..fc271f644aafb --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml @@ -0,0 +1,187 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-graph-card.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Audio Graph based Tegra sound card driver + +description: | + This is based on generic audio graph card driver along with additional + customizations for Tegra platforms. It uses the same bindings with + additional standard clock DT bindings required for Tegra. + +maintainers: + - Jon Hunter + - Sameer Pujar + +allOf: + - $ref: audio-graph.yaml# + +properties: + compatible: + enum: + - nvidia,tegra210-audio-graph-card + - nvidia,tegra186-audio-graph-card + + clocks: + minItems: 2 + + clock-names: + minItems: 2 + items: + - const: pll_a + - const: plla_out0 + + assigned-clocks: + minItems: 1 + maxItems: 3 + + assigned-clock-parents: + minItems: 1 + maxItems: 3 + + assigned-clock-rates: + minItems: 1 + maxItems: 3 + +required: + - clocks + - clock-names + - assigned-clocks + - assigned-clock-parents + +unevaluatedProperties: false + +examples: + - | + #include + + tegra_sound { + compatible = "nvidia,tegra210-audio-graph-card"; + + clocks = <&tegra_car TEGRA210_CLK_PLL_A>, + <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + clock-names = "pll_a", "plla_out0"; + + assigned-clocks = <&tegra_car TEGRA210_CLK_PLL_A>, + <&tegra_car TEGRA210_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA210_CLK_EXTERN1>; + assigned-clock-parents = <0>, <0>, <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <368640000>, <49152000>, <12288000>; + + dais = /* FE */ + <&admaif1_port>, + /* Router */ + <&xbar_i2s1_port>, + /* I/O DAP Ports */ + <&i2s1_port>; + + label = "jetson-tx1-ape"; + }; + + // The ports are defined for AHUB and its child devices. + ahub@702d0800 { + compatible = "nvidia,tegra210-ahub"; + reg = <0x702d0800 0x800>; + clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; + clock-names = "ahub"; + assigned-clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x702d0000 0x702d0000 0x0000e400>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + xbar_admaif1_ep: endpoint { + remote-endpoint = <&admaif1_ep>; + }; + }; + + // ... + + xbar_i2s1_port: port@a { + reg = <0xa>; + xbar_i2s1_ep: endpoint { + remote-endpoint = <&i2s1_cif_ep>; + }; + }; + }; + + admaif@702d0000 { + compatible = "nvidia,tegra210-admaif"; + reg = <0x702d0000 0x800>; + dmas = <&adma 1>, <&adma 1>, + <&adma 2>, <&adma 2>, + <&adma 3>, <&adma 3>, + <&adma 4>, <&adma 4>, + <&adma 5>, <&adma 5>, + <&adma 6>, <&adma 6>, + <&adma 7>, <&adma 7>, + <&adma 8>, <&adma 8>, + <&adma 9>, <&adma 9>, + <&adma 10>, <&adma 10>; + dma-names = "rx1", "tx1", + "rx2", "tx2", + "rx3", "tx3", + "rx4", "tx4", + "rx5", "tx5", + "rx6", "tx6", + "rx7", "tx7", + "rx8", "tx8", + "rx9", "tx9", + "rx10", "tx10"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + admaif1_port: port@0 { + reg = <0x0>; + admaif1_ep: endpoint { + remote-endpoint = <&xbar_admaif1_ep>; + }; + }; + + // More ADMAIF ports to follow + }; + }; + + i2s@702d1000 { + compatible = "nvidia,tegra210-i2s"; + clocks = <&tegra_car TEGRA210_CLK_I2S0>; + clock-names = "i2s"; + assigned-clocks = <&tegra_car TEGRA210_CLK_I2S0>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + reg = <0x702d1000 0x100>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + + i2s1_cif_ep: endpoint { + remote-endpoint = <&xbar_i2s1_ep>; + }; + }; + + i2s1_port: port@1 { + reg = <0x1>; + + i2s1_dap: endpoint { + dai-format = "i2s"; + }; + }; + }; + }; + }; + +... -- GitLab From 202e2f7745437aa5b694de92cbd30bb43b23fbed Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Tue, 19 Jan 2021 14:58:13 +0530 Subject: [PATCH 0355/1084] ASoC: tegra: Add audio graph based card driver Add Tegra audio machine driver which is based on generic audio graph card driver. It re-uses most of the common stuff from audio graph driver and uses the same DT binding. Required Tegra specific customizations are done in the driver and additional DT bindings are required for clock handling. Details on the customizations done: - Update PLL rates at runtime: Tegra HW supports multiple sample rates (multiples of 8x and 11.025x) and both of these groups require different PLL rates. Hence there is a requirement to update this at runtime. This is achieved by providing a custom 'snd_soc_ops' and in hw_param() callback PLL rate is updated as per the sample rate. - Internal structure 'tegra_audio_graph_data' is used to maintain clock handles of PLL. - The 'force_dpcm' flag is set to use DPCM for all DAI links. - The 'component_chaining' flag is set to use DPCM with component model. Signed-off-by: Sameer Pujar Reviewed-by: Jon Hunter Link: https://lore.kernel.org/r/1611048496-24650-4-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/Kconfig | 9 + sound/soc/tegra/Makefile | 2 + sound/soc/tegra/tegra_audio_graph_card.c | 251 +++++++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100644 sound/soc/tegra/tegra_audio_graph_card.c diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index a62cc87551acf..6dc83ad8607a1 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -117,6 +117,15 @@ config SND_SOC_TEGRA210_ADMAIF channel. Buffer size is configurable for each ADMAIIF channel. Say Y or M if you want to add support for Tegra210 ADMAIF module. +config SND_SOC_TEGRA_AUDIO_GRAPH_CARD + tristate "Audio Graph Card based Tegra driver" + depends on SND_AUDIO_GRAPH_CARD + help + Config to enable Tegra audio machine driver based on generic + audio graph driver. It is a thin driver written to customize + few things for Tegra audio. Most of the code is re-used from + audio graph driver and the same DT bindings are used. + config SND_SOC_TEGRA_RT5640 tristate "SoC Audio support for Tegra boards using an RT5640 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 60040a06b814f..b17dd6eef92ac 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -38,6 +38,7 @@ snd-soc-tegra-trimslice-objs := trimslice.o snd-soc-tegra-alc5632-objs := tegra_alc5632.o snd-soc-tegra-max98090-objs := tegra_max98090.o snd-soc-tegra-sgtl5000-objs := tegra_sgtl5000.o +snd-soc-tegra-audio-graph-card-objs := tegra_audio_graph_card.o obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o @@ -48,3 +49,4 @@ obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o obj-$(CONFIG_SND_SOC_TEGRA_SGTL5000) += snd-soc-tegra-sgtl5000.o +obj-$(CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD) += snd-soc-tegra-audio-graph-card.o diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c new file mode 100644 index 0000000000000..9e43f16f93361 --- /dev/null +++ b/sound/soc/tegra/tegra_audio_graph_card.c @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// tegra_audio_graph_card.c - Audio Graph based Tegra Machine Driver +// +// Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. + +#include +#include +#include +#include +#include +#include + +#define MAX_PLLA_OUT0_DIV 128 + +#define simple_to_tegra_priv(simple) \ + container_of(simple, struct tegra_audio_priv, simple) + +enum srate_type { + /* + * Sample rates multiple of 8000 Hz and below are supported: + * ( 8000, 16000, 32000, 48000, 96000, 192000 Hz ) + */ + x8_RATE, + + /* + * Sample rates multiple of 11025 Hz and below are supported: + * ( 11025, 22050, 44100, 88200, 176400 Hz ) + */ + x11_RATE, + + NUM_RATE_TYPE, +}; + +struct tegra_audio_priv { + struct asoc_simple_priv simple; + struct clk *clk_plla_out0; + struct clk *clk_plla; +}; + +/* Tegra audio chip data */ +struct tegra_audio_cdata { + unsigned int plla_rates[NUM_RATE_TYPE]; + unsigned int plla_out0_rates[NUM_RATE_TYPE]; +}; + +/* Setup PLL clock as per the given sample rate */ +static int tegra_audio_graph_update_pll(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct asoc_simple_priv *simple = snd_soc_card_get_drvdata(rtd->card); + struct tegra_audio_priv *priv = simple_to_tegra_priv(simple); + struct device *dev = rtd->card->dev; + const struct tegra_audio_cdata *data = of_device_get_match_data(dev); + unsigned int plla_rate, plla_out0_rate, bclk; + unsigned int srate = params_rate(params); + int err; + + switch (srate) { + case 11025: + case 22050: + case 44100: + case 88200: + case 176400: + plla_out0_rate = data->plla_out0_rates[x11_RATE]; + plla_rate = data->plla_rates[x11_RATE]; + break; + case 8000: + case 16000: + case 32000: + case 48000: + case 96000: + case 192000: + plla_out0_rate = data->plla_out0_rates[x8_RATE]; + plla_rate = data->plla_rates[x8_RATE]; + break; + default: + dev_err(rtd->card->dev, "Unsupported sample rate %u\n", + srate); + return -EINVAL; + } + + /* + * Below is the clock relation: + * + * PLLA + * | + * |--> PLLA_OUT0 + * | + * |---> I2S modules + * | + * |---> DMIC modules + * | + * |---> DSPK modules + * + * + * Default PLLA_OUT0 rate might be too high when I/O is running + * at minimum PCM configurations. This may result in incorrect + * clock rates and glitchy audio. The maximum divider is 128 + * and any thing higher than that won't work. Thus reduce PLLA_OUT0 + * to work for lower configurations. + * + * This problem is seen for I2S only, as DMIC and DSPK minimum + * clock requirements are under allowed divider limits. + */ + bclk = srate * params_channels(params) * params_width(params); + if (div_u64(plla_out0_rate, bclk) > MAX_PLLA_OUT0_DIV) + plla_out0_rate >>= 1; + + dev_dbg(rtd->card->dev, + "Update clock rates: PLLA(= %u Hz) and PLLA_OUT0(= %u Hz)\n", + plla_rate, plla_out0_rate); + + /* Set PLLA rate */ + err = clk_set_rate(priv->clk_plla, plla_rate); + if (err) { + dev_err(rtd->card->dev, + "Can't set plla rate for %u, err: %d\n", + plla_rate, err); + return err; + } + + /* Set PLLA_OUT0 rate */ + err = clk_set_rate(priv->clk_plla_out0, plla_out0_rate); + if (err) { + dev_err(rtd->card->dev, + "Can't set plla_out0 rate %u, err: %d\n", + plla_out0_rate, err); + return err; + } + + return err; +} + +static int tegra_audio_graph_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + int err; + + /* + * This gets called for each DAI link (FE or BE) when DPCM is used. + * We may not want to update PLLA rate for each call. So PLLA update + * must be restricted to external I/O links (I2S, DMIC or DSPK) since + * they actually depend on it. I/O modules update their clocks in + * hw_param() of their respective component driver and PLLA rate + * update here helps them to derive appropriate rates. + * + * TODO: When more HW accelerators get added (like sample rate + * converter, volume gain controller etc., which don't really + * depend on PLLA) we need a better way to filter here. + */ + if (cpu_dai->driver->ops && rtd->dai_link->no_pcm) { + err = tegra_audio_graph_update_pll(substream, params); + if (err) + return err; + } + + return asoc_simple_hw_params(substream, params); +} + +static const struct snd_soc_ops tegra_audio_graph_ops = { + .startup = asoc_simple_startup, + .shutdown = asoc_simple_shutdown, + .hw_params = tegra_audio_graph_hw_params, +}; + +static int tegra_audio_graph_card_probe(struct snd_soc_card *card) +{ + struct asoc_simple_priv *simple = snd_soc_card_get_drvdata(card); + struct tegra_audio_priv *priv = simple_to_tegra_priv(simple); + + priv->clk_plla = devm_clk_get(card->dev, "pll_a"); + if (IS_ERR(priv->clk_plla)) { + dev_err(card->dev, "Can't retrieve clk pll_a\n"); + return PTR_ERR(priv->clk_plla); + } + + priv->clk_plla_out0 = devm_clk_get(card->dev, "plla_out0"); + if (IS_ERR(priv->clk_plla_out0)) { + dev_err(card->dev, "Can't retrieve clk plla_out0\n"); + return PTR_ERR(priv->clk_plla_out0); + } + + return graph_card_probe(card); +} + +static int tegra_audio_graph_probe(struct platform_device *pdev) +{ + struct tegra_audio_priv *priv; + struct device *dev = &pdev->dev; + struct snd_soc_card *card; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + card = simple_priv_to_card(&priv->simple); + + card->probe = tegra_audio_graph_card_probe; + + /* graph_parse_of() depends on below */ + card->component_chaining = 1; + priv->simple.ops = &tegra_audio_graph_ops; + priv->simple.force_dpcm = 1; + + return graph_parse_of(&priv->simple, dev); +} + +static const struct tegra_audio_cdata tegra210_data = { + /* PLLA */ + .plla_rates[x8_RATE] = 368640000, + .plla_rates[x11_RATE] = 338688000, + /* PLLA_OUT0 */ + .plla_out0_rates[x8_RATE] = 49152000, + .plla_out0_rates[x11_RATE] = 45158400, +}; + +static const struct tegra_audio_cdata tegra186_data = { + /* PLLA */ + .plla_rates[x8_RATE] = 245760000, + .plla_rates[x11_RATE] = 270950400, + /* PLLA_OUT0 */ + .plla_out0_rates[x8_RATE] = 49152000, + .plla_out0_rates[x11_RATE] = 45158400, +}; + +static const struct of_device_id graph_of_tegra_match[] = { + { .compatible = "nvidia,tegra210-audio-graph-card", + .data = &tegra210_data }, + { .compatible = "nvidia,tegra186-audio-graph-card", + .data = &tegra186_data }, + {}, +}; +MODULE_DEVICE_TABLE(of, graph_of_tegra_match); + +static struct platform_driver tegra_audio_graph_card = { + .driver = { + .name = "tegra-audio-graph-card", + .pm = &snd_soc_pm_ops, + .of_match_table = graph_of_tegra_match, + }, + .probe = tegra_audio_graph_probe, +}; +module_platform_driver(tegra_audio_graph_card); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ASoC Tegra Audio Graph Sound Card"); +MODULE_AUTHOR("Sameer Pujar "); -- GitLab From f4d3bd8be4f2bc43e4b13490cbc9969d15c2f058 Mon Sep 17 00:00:00 2001 From: Yu-Hsuan Hsu Date: Fri, 15 Jan 2021 15:53:00 +0800 Subject: [PATCH 0356/1084] cros_ec_commands: Add EC_CODEC_I2S_RX_RESET Add the new command EC_CODEC_I2S_RX_RESET in ec_codec_i2s_rx_subcmd, which is used for resetting the EC codec. Signed-off-by: Yu-Hsuan Hsu Acked-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20210115075301.47995-1-yuhsuan@chromium.org Signed-off-by: Mark Brown --- include/linux/platform_data/cros_ec_commands.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 86376779ab319..95889ada83a31 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -4600,6 +4600,7 @@ enum ec_codec_i2s_rx_subcmd { EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x2, EC_CODEC_I2S_RX_SET_DAIFMT = 0x3, EC_CODEC_I2S_RX_SET_BCLK = 0x4, + EC_CODEC_I2S_RX_RESET = 0x5, EC_CODEC_I2S_RX_SUBCMD_COUNT, }; -- GitLab From 7f1f7ae102ea082745e320b3c8c003f43c063edf Mon Sep 17 00:00:00 2001 From: Yu-Hsuan Hsu Date: Fri, 15 Jan 2021 15:53:01 +0800 Subject: [PATCH 0357/1084] ASoC: cros_ec_codec: Reset I2S RX when probing It is not guaranteed that I2S RX is disabled when the kernel booting. For example, if the kernel crashes while it is enabled, it will keep enabled until the next time EC reboots. Reset I2S RX when probing to fix this issue. Signed-off-by: Yu-Hsuan Hsu Reviewed-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20210115075301.47995-2-yuhsuan@chromium.org Signed-off-by: Mark Brown --- sound/soc/codecs/cros_ec_codec.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index f33a2a9654e76..c4772f82485a3 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -1011,6 +1011,18 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) } priv->ec_capabilities = r.capabilities; + /* Reset EC codec i2s rx. */ + p.cmd = EC_CODEC_I2S_RX_RESET; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + (uint8_t *)&p, sizeof(p), NULL, 0); + if (ret == -ENOPROTOOPT) { + dev_info(dev, + "Missing reset command. Please update EC firmware.\n"); + } else if (ret) { + dev_err(dev, "failed to EC_CODEC_I2S_RESET: %d\n", ret); + return ret; + } + platform_set_drvdata(pdev, priv); ret = devm_snd_soc_register_component(dev, &i2s_rx_component_driver, -- GitLab From 0dedbde5062dbc3cf71ab1ba40792c04a68008e9 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 12 Jan 2021 18:47:04 +0100 Subject: [PATCH 0358/1084] ASoC: cpcap: Implement set_tdm_slot for voice call support ASoC: cpcap: Implement set_tdm_slot for voice call support For using cpcap for voice calls, we need to route audio directly from the modem to cpcap for TDM (Time Division Multiplexing). The voice call is direct data between the modem and cpcap with no CPU involvment. In this mode, the cpcap related audio mixer controls work for the speaker selection and volume though. To do this, we need to implement standard snd_soc_dai_set_tdm_slot() for cpcap. Then the modem codec driver can use snd_soc_dai_set_sysclk(), snd_soc_dai_set_fmt(), and snd_soc_dai_set_tdm_slot() to configure a voice call. Let's add cpcap_voice_set_tdm_slot() for this, and cpcap_voice_call() helper to configure the additional registers needed for voice call. Let's also clear CPCAP_REG_VAUDIOC on init in case we have the bit for CPCAP_BIT_VAUDIO_MODE0 set on init. Signed-off-by: Tony Lindgren Signed-off-by: Pavel Machek Link: https://lore.kernel.org/r/20210112174704.GA13496@duo.ucw.cz Signed-off-by: Mark Brown --- sound/soc/codecs/cpcap.c | 127 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c index f046987ee4cdb..e266d993ab2a5 100644 --- a/sound/soc/codecs/cpcap.c +++ b/sound/soc/codecs/cpcap.c @@ -16,6 +16,14 @@ #include #include +/* Register 512 CPCAP_REG_VAUDIOC --- Audio Regulator and Bias Voltage */ +#define CPCAP_BIT_AUDIO_LOW_PWR 6 +#define CPCAP_BIT_AUD_LOWPWR_SPEED 5 +#define CPCAP_BIT_VAUDIOPRISTBY 4 +#define CPCAP_BIT_VAUDIO_MODE1 2 +#define CPCAP_BIT_VAUDIO_MODE0 1 +#define CPCAP_BIT_V_AUDIO_EN 0 + /* Register 513 CPCAP_REG_CC --- CODEC */ #define CPCAP_BIT_CDC_CLK2 15 #define CPCAP_BIT_CDC_CLK1 14 @@ -221,6 +229,7 @@ struct cpcap_reg_info { }; static const struct cpcap_reg_info cpcap_default_regs[] = { + { CPCAP_REG_VAUDIOC, 0x003F, 0x0000 }, { CPCAP_REG_CC, 0xFFFF, 0x0000 }, { CPCAP_REG_CC, 0xFFFF, 0x0000 }, { CPCAP_REG_CDI, 0xBFFF, 0x0000 }, @@ -1371,8 +1380,121 @@ static int cpcap_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, return 0; } -static int cpcap_voice_set_mute(struct snd_soc_dai *dai, - int mute, int direction) + +/* + * Configure codec for voice call if requested. + * + * We can configure most with snd_soc_dai_set_sysclk(), snd_soc_dai_set_fmt() + * and snd_soc_dai_set_tdm_slot(). This function configures the rest of the + * cpcap related hardware as CPU is not involved in the voice call. + */ +static int cpcap_voice_call(struct cpcap_audio *cpcap, struct snd_soc_dai *dai, + bool voice_call) +{ + int mask, err; + + /* Modem to codec VAUDIO_MODE1 */ + mask = BIT(CPCAP_BIT_VAUDIO_MODE1); + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC, + mask, voice_call ? mask : 0); + if (err) + return err; + + /* Clear MIC1_MUX for call */ + mask = BIT(CPCAP_BIT_MIC1_MUX); + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, + mask, voice_call ? 0 : mask); + if (err) + return err; + + /* Set MIC2_MUX for call */ + mask = BIT(CPCAP_BIT_MB_ON1L) | BIT(CPCAP_BIT_MB_ON1R) | + BIT(CPCAP_BIT_MIC2_MUX) | BIT(CPCAP_BIT_MIC2_PGA_EN); + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, + mask, voice_call ? mask : 0); + if (err) + return err; + + /* Enable LDSP for call */ + mask = BIT(CPCAP_BIT_A2_LDSP_L_EN) | BIT(CPCAP_BIT_A2_LDSP_R_EN); + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA, + mask, voice_call ? mask : 0); + if (err) + return err; + + /* Enable CPCAP_BIT_PGA_CDC_EN for call */ + mask = BIT(CPCAP_BIT_PGA_CDC_EN); + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, + mask, voice_call ? mask : 0); + if (err) + return err; + + /* Unmute voice for call */ + if (dai) { + err = snd_soc_dai_digital_mute(dai, !voice_call, + SNDRV_PCM_STREAM_PLAYBACK); + if (err) + return err; + } + + /* Set modem to codec mic CDC and HPF for call */ + mask = BIT(CPCAP_BIT_MIC2_CDC_EN) | BIT(CPCAP_BIT_CDC_EN_RX) | + BIT(CPCAP_BIT_AUDOHPF_1) | BIT(CPCAP_BIT_AUDOHPF_0) | + BIT(CPCAP_BIT_AUDIHPF_1) | BIT(CPCAP_BIT_AUDIHPF_0); + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, + mask, voice_call ? mask : 0); + if (err) + return err; + + /* Enable modem to codec CDC for call*/ + mask = BIT(CPCAP_BIT_CDC_CLK_EN); + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, + mask, voice_call ? mask : 0); + + return err; +} + +static int cpcap_voice_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, unsigned int rx_mask, + int slots, int slot_width) +{ + struct snd_soc_component *component = dai->component; + struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); + int err, ts_mask, mask; + bool voice_call; + + /* + * Primitive test for voice call, probably needs more checks + * later on for 16-bit calls detected, Bluetooth headset etc. + */ + if (tx_mask == 0 && rx_mask == 1 && slot_width == 8) + voice_call = true; + else + voice_call = false; + + ts_mask = 0x7 << CPCAP_BIT_MIC2_TIMESLOT0; + ts_mask |= 0x7 << CPCAP_BIT_MIC1_RX_TIMESLOT0; + + mask = (tx_mask & 0x7) << CPCAP_BIT_MIC2_TIMESLOT0; + mask |= (rx_mask & 0x7) << CPCAP_BIT_MIC1_RX_TIMESLOT0; + + err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, + ts_mask, mask); + if (err) + return err; + + err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, slot_width * 1000); + if (err) + return err; + + err = cpcap_voice_call(cpcap, dai, voice_call); + if (err) + return err; + + return 0; +} + +static int cpcap_voice_set_mute(struct snd_soc_dai *dai, int mute, int direction) { struct snd_soc_component *component = dai->component; struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); @@ -1393,6 +1515,7 @@ static const struct snd_soc_dai_ops cpcap_dai_voice_ops = { .hw_params = cpcap_voice_hw_params, .set_sysclk = cpcap_voice_set_dai_sysclk, .set_fmt = cpcap_voice_set_dai_fmt, + .set_tdm_slot = cpcap_voice_set_tdm_slot, .mute_stream = cpcap_voice_set_mute, .no_capture_mute = 1, }; -- GitLab From abbc4d6ecd07fa246fd597b5d8fced28f0bcc606 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 18 Jan 2021 15:46:39 +0100 Subject: [PATCH 0359/1084] drm/vram-helper: Reuse existing page mappings in vmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For performance, BO page mappings can stay in place even if the map counter has returned to 0. In these cases, the existing page mapping has to be reused by the next vmap operation. Otherwise a new mapping would be installed and the old mapping's pages leak. Fix the issue by reusing existing page mappings for vmap operations. Signed-off-by: Thomas Zimmermann Fixes: 1086db71a1db ("drm/vram-helper: Remove invariant parameters from internal kmap function") Acked-by: Christian König Tested-by: Eli Cohen Reported-by: Eli Cohen Reported-by: kernel test robot Cc: Daniel Vetter Cc: Christian König Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Link: https://patchwork.freedesktop.org/patch/msgid/20210118144639.27307-1-tzimmermann@suse.de --- drivers/gpu/drm/drm_gem_vram_helper.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 02ca22e90290d..0b232a73c1b74 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -387,9 +387,16 @@ static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo, if (gbo->vmap_use_count > 0) goto out; - ret = ttm_bo_vmap(&gbo->bo, &gbo->map); - if (ret) - return ret; + /* + * VRAM helpers unmap the BO only on demand. So the previous + * page mapping might still be around. Only vmap if the there's + * no mapping present. + */ + if (dma_buf_map_is_null(&gbo->map)) { + ret = ttm_bo_vmap(&gbo->bo, &gbo->map); + if (ret) + return ret; + } out: ++gbo->vmap_use_count; @@ -577,6 +584,7 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo, return; ttm_bo_vunmap(bo, &gbo->map); + dma_buf_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */ } static int drm_gem_vram_bo_driver_move(struct drm_gem_vram_object *gbo, -- GitLab From 9c7d9017a49fb8516c13b7bff59b7da2abed23e1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 8 Jan 2021 19:05:59 +0100 Subject: [PATCH 0360/1084] x86: PM: Register syscore_ops for scale invariance On x86 scale invariace tends to be disabled during resume from suspend-to-RAM, because the MPERF or APERF MSR values are not as expected then due to updates taking place after the platform firmware has been invoked to complete the suspend transition. That, of course, is not desirable, especially if the schedutil scaling governor is in use, because the lack of scale invariance causes it to be less reliable. To counter that effect, modify init_freq_invariance() to register a syscore_ops object for scale invariance with the ->resume callback pointing to init_counter_refs() which will run on the CPU starting the resume transition (the other CPUs will be taken care of the "online" operations taking place later). Fixes: e2b0d619b400 ("x86, sched: check for counters overflow in frequency invariant accounting") Signed-off-by: Rafael J. Wysocki Signed-off-by: Peter Zijlstra (Intel) Acked-by: Giovanni Gherdovich Link: https://lkml.kernel.org/r/1803209.Mvru99baaF@kreacher --- arch/x86/kernel/smpboot.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 8ca66af96a547..117e24fbfd8a0 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -2083,6 +2084,23 @@ static void init_counter_refs(void) this_cpu_write(arch_prev_mperf, mperf); } +#ifdef CONFIG_PM_SLEEP +static struct syscore_ops freq_invariance_syscore_ops = { + .resume = init_counter_refs, +}; + +static void register_freq_invariance_syscore_ops(void) +{ + /* Bail out if registered already. */ + if (freq_invariance_syscore_ops.node.prev) + return; + + register_syscore_ops(&freq_invariance_syscore_ops); +} +#else +static inline void register_freq_invariance_syscore_ops(void) {} +#endif + static void init_freq_invariance(bool secondary, bool cppc_ready) { bool ret = false; @@ -2109,6 +2127,7 @@ static void init_freq_invariance(bool secondary, bool cppc_ready) if (ret) { init_counter_refs(); static_branch_enable(&arch_scale_freq_key); + register_freq_invariance_syscore_ops(); pr_info("Estimated ratio of average max frequency by base frequency (times 1024): %llu\n", arch_max_freq_ratio); } else { pr_debug("Couldn't determine max cpu frequency, necessary for scale-invariant accounting.\n"); -- GitLab From 7e238de8283acd32c26c2bc2a50672d0ea862ff7 Mon Sep 17 00:00:00 2001 From: Oleksandr Mazur Date: Tue, 19 Jan 2021 10:53:33 +0200 Subject: [PATCH 0361/1084] net: core: devlink: use right genl user_ptr when handling port param get/set Fix incorrect user_ptr dereferencing when handling port param get/set: idx [0] stores the 'struct devlink' pointer; idx [1] stores the 'struct devlink_port' pointer; Fixes: 637989b5d77e ("devlink: Always use user_ptr[0] for devlink and simplify post_doit") CC: Parav Pandit Signed-off-by: Oleksandr Mazur Signed-off-by: Vadym Kochan Link: https://lore.kernel.org/r/20210119085333.16833-1-vadym.kochan@plvision.eu Signed-off-by: Jakub Kicinski --- net/core/devlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/devlink.c b/net/core/devlink.c index ee828e4b1007e..738d4344d6799 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -4146,7 +4146,7 @@ static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg, static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb, struct genl_info *info) { - struct devlink_port *devlink_port = info->user_ptr[0]; + struct devlink_port *devlink_port = info->user_ptr[1]; struct devlink_param_item *param_item; struct sk_buff *msg; int err; @@ -4175,7 +4175,7 @@ static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb, static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb, struct genl_info *info) { - struct devlink_port *devlink_port = info->user_ptr[0]; + struct devlink_port *devlink_port = info->user_ptr[1]; return __devlink_nl_cmd_param_set_doit(devlink_port->devlink, devlink_port->index, -- GitLab From 8eed01b5ca9c1deff329ad44f08e2041ca14842c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 18 Jan 2021 16:06:55 +0100 Subject: [PATCH 0362/1084] mdio-bitbang: Export mdiobb_{read,write}() Export mdiobb_read() and mdiobb_write(), so Ethernet controller drivers can call them from their MDIO read/write wrappers. Signed-off-by: Geert Uytterhoeven Tested-by: Wolfram Sang Reviewed-by: Florian Fainelli Signed-off-by: Jakub Kicinski --- drivers/net/mdio/mdio-bitbang.c | 6 ++++-- include/linux/mdio-bitbang.h | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/mdio/mdio-bitbang.c b/drivers/net/mdio/mdio-bitbang.c index 5136275c8e739..d3915f8318543 100644 --- a/drivers/net/mdio/mdio-bitbang.c +++ b/drivers/net/mdio/mdio-bitbang.c @@ -149,7 +149,7 @@ static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr) return dev_addr; } -static int mdiobb_read(struct mii_bus *bus, int phy, int reg) +int mdiobb_read(struct mii_bus *bus, int phy, int reg) { struct mdiobb_ctrl *ctrl = bus->priv; int ret, i; @@ -180,8 +180,9 @@ static int mdiobb_read(struct mii_bus *bus, int phy, int reg) mdiobb_get_bit(ctrl); return ret; } +EXPORT_SYMBOL(mdiobb_read); -static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) +int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) { struct mdiobb_ctrl *ctrl = bus->priv; @@ -201,6 +202,7 @@ static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) mdiobb_get_bit(ctrl); return 0; } +EXPORT_SYMBOL(mdiobb_write); struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl) { diff --git a/include/linux/mdio-bitbang.h b/include/linux/mdio-bitbang.h index 5d71e8a8500f5..aca4dc037b70b 100644 --- a/include/linux/mdio-bitbang.h +++ b/include/linux/mdio-bitbang.h @@ -35,6 +35,9 @@ struct mdiobb_ctrl { const struct mdiobb_ops *ops; }; +int mdiobb_read(struct mii_bus *bus, int phy, int reg); +int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val); + /* The returned bus is not yet registered with the phy layer. */ struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl); -- GitLab From 02cae02a7de1484095e4ba984bfee7a75843ec26 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 18 Jan 2021 16:06:56 +0100 Subject: [PATCH 0363/1084] sh_eth: Make PHY access aware of Runtime PM to fix reboot crash Wolfram reports that his R-Car H2-based Lager board can no longer be rebooted in v5.11-rc1, as it crashes with an imprecise external abort. The issue can be reproduced on other boards (e.g. Koelsch with R-Car M2-W) too, if CONFIG_IP_PNP is disabled, and the Ethernet interface is down at reboot time: Unhandled fault: imprecise external abort (0x1406) at 0x00000000 pgd = (ptrval) [00000000] *pgd=422b6835, *pte=00000000, *ppte=00000000 Internal error: : 1406 [#1] ARM Modules linked in: CPU: 0 PID: 1105 Comm: init Tainted: G W 5.10.0-rc1-00402-ge2f016cf7751 #1048 Hardware name: Generic R-Car Gen2 (Flattened Device Tree) PC is at sh_mdio_ctrl+0x44/0x60 LR is at sh_mmd_ctrl+0x20/0x24 ... Backtrace: [] (sh_mdio_ctrl) from [] (sh_mmd_ctrl+0x20/0x24) r7:0000001f r6:00000020 r5:00000002 r4:c22a1dc4 [] (sh_mmd_ctrl) from [] (mdiobb_cmd+0x38/0xa8) [] (mdiobb_cmd) from [] (mdiobb_read+0x58/0xdc) r9:c229f844 r8:c0c329dc r7:c221e000 r6:00000001 r5:c22a1dc4 r4:00000001 [] (mdiobb_read) from [] (__mdiobus_read+0x74/0xe0) r7:0000001f r6:00000001 r5:c221e000 r4:c221e000 [] (__mdiobus_read) from [] (mdiobus_read+0x40/0x54) r7:0000001f r6:00000001 r5:c221e000 r4:c221e458 [] (mdiobus_read) from [] (phy_read+0x1c/0x20) r7:ffffe000 r6:c221e470 r5:00000200 r4:c229f800 [] (phy_read) from [] (kszphy_config_intr+0x44/0x80) [] (kszphy_config_intr) from [] (phy_disable_interrupts+0x44/0x50) r5:c229f800 r4:c229f800 [] (phy_disable_interrupts) from [] (phy_shutdown+0x18/0x1c) r5:c229f800 r4:c229f804 [] (phy_shutdown) from [] (device_shutdown+0x168/0x1f8) [] (device_shutdown) from [] (kernel_restart_prepare+0x3c/0x48) r9:c22d2000 r8:c0100264 r7:c0b0d034 r6:00000000 r5:4321fedc r4:00000000 [] (kernel_restart_prepare) from [] (kernel_restart+0x1c/0x60) [] (kernel_restart) from [] (__do_sys_reboot+0x168/0x208) r5:4321fedc r4:01234567 [] (__do_sys_reboot) from [] (sys_reboot+0x18/0x1c) r7:00000058 r6:00000000 r5:00000000 r4:00000000 [] (sys_reboot) from [] (ret_fast_syscall+0x0/0x54) As of commit e2f016cf775129c0 ("net: phy: add a shutdown procedure"), system reboot calls phy_disable_interrupts() during shutdown. As this happens unconditionally, the PHY registers may be accessed while the device is suspended, causing undefined behavior, which may crash the system. Fix this by wrapping the PHY bitbang accessors in the sh_eth driver by wrappers that take care of Runtime PM, to resume the device when needed. Reported-by: Wolfram Sang Suggested-by: Andrew Lunn Signed-off-by: Geert Uytterhoeven Tested-by: Wolfram Sang Reviewed-by: Florian Fainelli Reviewed-by: Andrew Lunn Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/renesas/sh_eth.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index c633046329352..9b52d350e21a9 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -3034,6 +3034,28 @@ static int sh_mdio_release(struct sh_eth_private *mdp) return 0; } +static int sh_mdiobb_read(struct mii_bus *bus, int phy, int reg) +{ + int res; + + pm_runtime_get_sync(bus->parent); + res = mdiobb_read(bus, phy, reg); + pm_runtime_put(bus->parent); + + return res; +} + +static int sh_mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) +{ + int res; + + pm_runtime_get_sync(bus->parent); + res = mdiobb_write(bus, phy, reg, val); + pm_runtime_put(bus->parent); + + return res; +} + /* MDIO bus init function */ static int sh_mdio_init(struct sh_eth_private *mdp, struct sh_eth_plat_data *pd) @@ -3058,6 +3080,10 @@ static int sh_mdio_init(struct sh_eth_private *mdp, if (!mdp->mii_bus) return -ENOMEM; + /* Wrap accessors with Runtime PM-aware ops */ + mdp->mii_bus->read = sh_mdiobb_read; + mdp->mii_bus->write = sh_mdiobb_write; + /* Hook up MII support for ethtool */ mdp->mii_bus->name = "sh_mii"; mdp->mii_bus->parent = dev; -- GitLab From 301a33d51880619d0c5a581b5a48d3a5248fa84b Mon Sep 17 00:00:00 2001 From: Mircea Cirjaliu Date: Tue, 19 Jan 2021 21:53:18 +0100 Subject: [PATCH 0364/1084] bpf: Fix helper bpf_map_peek_elem_proto pointing to wrong callback I assume this was obtained by copy/paste. Point it to bpf_map_peek_elem() instead of bpf_map_pop_elem(). In practice it may have been less likely hit when under JIT given shielded via 84430d4232c3 ("bpf, verifier: avoid retpoline for map push/pop/peek operation"). Fixes: f1a2e44a3aec ("bpf: add queue and stack maps") Signed-off-by: Mircea Cirjaliu Signed-off-by: Daniel Borkmann Cc: Mauricio Vasquez Link: https://lore.kernel.org/bpf/AM7PR02MB6082663DFDCCE8DA7A6DD6B1BBA30@AM7PR02MB6082.eurprd02.prod.outlook.com --- kernel/bpf/helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index bd8a3183d0302..41ca280b1dc19 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -108,7 +108,7 @@ BPF_CALL_2(bpf_map_peek_elem, struct bpf_map *, map, void *, value) } const struct bpf_func_proto bpf_map_peek_elem_proto = { - .func = bpf_map_pop_elem, + .func = bpf_map_peek_elem, .gpl_only = false, .ret_type = RET_INTEGER, .arg1_type = ARG_CONST_MAP_PTR, -- GitLab From 031c7a8cd6fc565e90320bf08f22ee6e70f9d969 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 28 Dec 2020 09:33:28 +0100 Subject: [PATCH 0365/1084] openrisc: io: Add missing __iomem annotation to iounmap() With C=1: drivers/soc/renesas/rmobile-sysc.c:330:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *addr @@ got void [noderef] __iomem *[assigned] base @@ drivers/soc/renesas/rmobile-sysc.c:330:33: sparse: expected void *addr drivers/soc/renesas/rmobile-sysc.c:330:33: sparse: got void [noderef] __iomem *[assigned] base Fix this by adding the missing __iomem annotation to iounmap(). Reported-by: kernel test robot Signed-off-by: Geert Uytterhoeven Signed-off-by: Stafford Horne --- arch/openrisc/include/asm/io.h | 2 +- arch/openrisc/mm/ioremap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/openrisc/include/asm/io.h b/arch/openrisc/include/asm/io.h index 7d6b4a77b379d..c298061c70a7e 100644 --- a/arch/openrisc/include/asm/io.h +++ b/arch/openrisc/include/asm/io.h @@ -31,7 +31,7 @@ void __iomem *ioremap(phys_addr_t offset, unsigned long size); #define iounmap iounmap -extern void iounmap(void *addr); +extern void iounmap(void __iomem *addr); #include diff --git a/arch/openrisc/mm/ioremap.c b/arch/openrisc/mm/ioremap.c index 5aed97a18bac9..daae13a76743b 100644 --- a/arch/openrisc/mm/ioremap.c +++ b/arch/openrisc/mm/ioremap.c @@ -77,7 +77,7 @@ void __iomem *__ref ioremap(phys_addr_t addr, unsigned long size) } EXPORT_SYMBOL(ioremap); -void iounmap(void *addr) +void iounmap(void __iomem *addr) { /* If the page is from the fixmap pool then we just clear out * the fixmap mapping. -- GitLab From b425e24a934e21a502d25089c6c7443d799c5594 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Mon, 18 Jan 2021 18:03:33 +0200 Subject: [PATCH 0366/1084] xsk: Clear pool even for inactive queues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The number of queues can change by other means, rather than ethtool. For example, attaching an mqprio qdisc with num_tc > 1 leads to creating multiple sets of TX queues, which may be then destroyed when mqprio is deleted. If an AF_XDP socket is created while mqprio is active, dev->_tx[queue_id].pool will be filled, but then real_num_tx_queues may decrease with deletion of mqprio, which will mean that the pool won't be NULLed, and a further increase of the number of TX queues may expose a dangling pointer. To avoid any potential misbehavior, this commit clears pool for RX and TX queues, regardless of real_num_*_queues, still taking into consideration num_*_queues to avoid overflows. Fixes: 1c1efc2af158 ("xsk: Create and free buffer pool independently from umem") Fixes: a41b4f3c58dd ("xsk: simplify xdp_clear_umem_at_qid implementation") Signed-off-by: Maxim Mikityanskiy Signed-off-by: Daniel Borkmann Acked-by: Björn Töpel Link: https://lore.kernel.org/bpf/20210118160333.333439-1-maximmi@mellanox.com --- net/xdp/xsk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index 8037b04a9edd1..4a83117507f5a 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -108,9 +108,9 @@ EXPORT_SYMBOL(xsk_get_pool_from_qid); void xsk_clear_pool_at_qid(struct net_device *dev, u16 queue_id) { - if (queue_id < dev->real_num_rx_queues) + if (queue_id < dev->num_rx_queues) dev->_rx[queue_id].pool = NULL; - if (queue_id < dev->real_num_tx_queues) + if (queue_id < dev->num_tx_queues) dev->_tx[queue_id].pool = NULL; } -- GitLab From 8d2b51b008c25240914984208b2ced57d1dd25a5 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Sat, 16 Jan 2021 11:44:22 +0100 Subject: [PATCH 0367/1084] udp: mask TOS bits in udp_v4_early_demux() udp_v4_early_demux() is the only function that calls ip_mc_validate_source() with a TOS that hasn't been masked with IPTOS_RT_MASK. This results in different behaviours for incoming multicast UDPv4 packets, depending on if ip_mc_validate_source() is called from the early-demux path (udp_v4_early_demux) or from the regular input path (ip_route_input_noref). ECN would normally not be used with UDP multicast packets, so the practical consequences should be limited on that side. However, IPTOS_RT_MASK is used to also masks the TOS' high order bits, to align with the non-early-demux path behaviour. Reproducer: Setup two netns, connected with veth: $ ip netns add ns0 $ ip netns add ns1 $ ip -netns ns0 link set dev lo up $ ip -netns ns1 link set dev lo up $ ip link add name veth01 netns ns0 type veth peer name veth10 netns ns1 $ ip -netns ns0 link set dev veth01 up $ ip -netns ns1 link set dev veth10 up $ ip -netns ns0 address add 192.0.2.10 peer 192.0.2.11/32 dev veth01 $ ip -netns ns1 address add 192.0.2.11 peer 192.0.2.10/32 dev veth10 In ns0, add route to multicast address 224.0.2.0/24 using source address 198.51.100.10: $ ip -netns ns0 address add 198.51.100.10/32 dev lo $ ip -netns ns0 route add 224.0.2.0/24 dev veth01 src 198.51.100.10 In ns1, define route to 198.51.100.10, only for packets with TOS 4: $ ip -netns ns1 route add 198.51.100.10/32 tos 4 dev veth10 Also activate rp_filter in ns1, so that incoming packets not matching the above route get dropped: $ ip netns exec ns1 sysctl -wq net.ipv4.conf.veth10.rp_filter=1 Now try to receive packets on 224.0.2.11: $ ip netns exec ns1 socat UDP-RECVFROM:1111,ip-add-membership=224.0.2.11:veth10,ignoreeof - In ns0, send packet to 224.0.2.11 with TOS 4 and ECT(0) (that is, tos 6 for socat): $ echo test0 | ip netns exec ns0 socat - UDP-DATAGRAM:224.0.2.11:1111,bind=:1111,tos=6 The "test0" message is properly received by socat in ns1, because early-demux has no cached dst to use, so source address validation is done by ip_route_input_mc(), which receives a TOS that has the ECN bits masked. Now send another packet to 224.0.2.11, still with TOS 4 and ECT(0): $ echo test1 | ip netns exec ns0 socat - UDP-DATAGRAM:224.0.2.11:1111,bind=:1111,tos=6 The "test1" message isn't received by socat in ns1, because, now, early-demux has a cached dst to use and calls ip_mc_validate_source() immediately, without masking the ECN bits. Fixes: bc044e8db796 ("udp: perform source validation for mcast early demux") Signed-off-by: Guillaume Nault Signed-off-by: Jakub Kicinski --- net/ipv4/udp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 7103b0a89756e..69ea76578abb9 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2555,7 +2555,8 @@ int udp_v4_early_demux(struct sk_buff *skb) */ if (!inet_sk(sk)->inet_daddr && in_dev) return ip_mc_validate_source(skb, iph->daddr, - iph->saddr, iph->tos, + iph->saddr, + iph->tos & IPTOS_RT_MASK, skb->dev, in_dev, &itag); } return 0; -- GitLab From 2e5a6266fbb11ae93c468dfecab169aca9c27b43 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Sat, 16 Jan 2021 11:44:26 +0100 Subject: [PATCH 0368/1084] netfilter: rpfilter: mask ecn bits before fib lookup RT_TOS() only masks one of the two ECN bits. Therefore rpfilter_mt() treats Not-ECT or ECT(1) packets in a different way than those with ECT(0) or CE. Reproducer: Create two netns, connected with a veth: $ ip netns add ns0 $ ip netns add ns1 $ ip link add name veth01 netns ns0 type veth peer name veth10 netns ns1 $ ip -netns ns0 link set dev veth01 up $ ip -netns ns1 link set dev veth10 up $ ip -netns ns0 address add 192.0.2.10/32 dev veth01 $ ip -netns ns1 address add 192.0.2.11/32 dev veth10 Add a route to ns1 in ns0: $ ip -netns ns0 route add 192.0.2.11/32 dev veth01 In ns1, only packets with TOS 4 can be routed to ns0: $ ip -netns ns1 route add 192.0.2.10/32 tos 4 dev veth10 Ping from ns0 to ns1 works regardless of the ECN bits, as long as TOS is 4: $ ip netns exec ns0 ping -Q 4 192.0.2.11 # TOS 4, Not-ECT ... 0% packet loss ... $ ip netns exec ns0 ping -Q 5 192.0.2.11 # TOS 4, ECT(1) ... 0% packet loss ... $ ip netns exec ns0 ping -Q 6 192.0.2.11 # TOS 4, ECT(0) ... 0% packet loss ... $ ip netns exec ns0 ping -Q 7 192.0.2.11 # TOS 4, CE ... 0% packet loss ... Now use iptable's rpfilter module in ns1: $ ip netns exec ns1 iptables-legacy -t raw -A PREROUTING -m rpfilter --invert -j DROP Not-ECT and ECT(1) packets still pass: $ ip netns exec ns0 ping -Q 4 192.0.2.11 # TOS 4, Not-ECT ... 0% packet loss ... $ ip netns exec ns0 ping -Q 5 192.0.2.11 # TOS 4, ECT(1) ... 0% packet loss ... But ECT(0) and ECN packets are dropped: $ ip netns exec ns0 ping -Q 6 192.0.2.11 # TOS 4, ECT(0) ... 100% packet loss ... $ ip netns exec ns0 ping -Q 7 192.0.2.11 # TOS 4, CE ... 100% packet loss ... After this patch, rpfilter doesn't drop ECT(0) and CE packets anymore. Fixes: 8f97339d3feb ("netfilter: add ipv4 reverse path filter match") Signed-off-by: Guillaume Nault Signed-off-by: Jakub Kicinski --- net/ipv4/netfilter/ipt_rpfilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c index cc23f1ce239c2..8cd3224d913e0 100644 --- a/net/ipv4/netfilter/ipt_rpfilter.c +++ b/net/ipv4/netfilter/ipt_rpfilter.c @@ -76,7 +76,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) flow.daddr = iph->saddr; flow.saddr = rpfilter_get_saddr(iph->daddr); flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0; - flow.flowi4_tos = RT_TOS(iph->tos); + flow.flowi4_tos = iph->tos & IPTOS_RT_MASK; flow.flowi4_scope = RT_SCOPE_UNIVERSE; flow.flowi4_oif = l3mdev_master_ifindex_rcu(xt_in(par)); -- GitLab From a3eb4e9d4c9218476d05c52dfd2be3d6fdce6b91 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Sun, 17 Jan 2021 17:15:38 +0200 Subject: [PATCH 0369/1084] net: Disable NETIF_F_HW_TLS_RX when RXCSUM is disabled With NETIF_F_HW_TLS_RX packets are decrypted in HW. This cannot be logically done when RXCSUM offload is off. Fixes: 14136564c8ee ("net: Add TLS RX offload feature") Signed-off-by: Tariq Toukan Reviewed-by: Boris Pismenny Link: https://lore.kernel.org/r/20210117151538.9411-1-tariqt@nvidia.com Signed-off-by: Jakub Kicinski --- Documentation/networking/tls-offload.rst | 3 +++ net/core/dev.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/Documentation/networking/tls-offload.rst b/Documentation/networking/tls-offload.rst index 9af3334d9ad08..5f0dea3d571e3 100644 --- a/Documentation/networking/tls-offload.rst +++ b/Documentation/networking/tls-offload.rst @@ -534,3 +534,6 @@ offload. Hence, TLS TX device feature flag requires TX csum offload being set. Disabling the latter implies clearing the former. Disabling TX checksum offload should not affect old connections, and drivers should make sure checksum calculation does not break for them. +Similarly, device-offloaded TLS decryption implies doing RXCSUM. If the user +does not want to enable RX csum offload, TLS RX device feature is disabled +as well. diff --git a/net/core/dev.c b/net/core/dev.c index c360bb5367e24..a979b86dbacda 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -9672,6 +9672,11 @@ static netdev_features_t netdev_fix_features(struct net_device *dev, } } + if ((features & NETIF_F_HW_TLS_RX) && !(features & NETIF_F_RXCSUM)) { + netdev_dbg(dev, "Dropping TLS RX HW offload feature since no RXCSUM feature.\n"); + features &= ~NETIF_F_HW_TLS_RX; + } + return features; } -- GitLab From 9f206f7398f6f6ec7dd0198c045c2459b4f720b6 Mon Sep 17 00:00:00 2001 From: Bryan Tan Date: Mon, 18 Jan 2021 19:16:29 -0800 Subject: [PATCH 0370/1084] RDMA/vmw_pvrdma: Fix network_hdr_type reported in WC The PVRDMA device HW interface defines network_hdr_type according to an old definition of the internal kernel rdma_network_type enum that has since changed, resulting in the wrong rdma_network_type being reported. Fix this by explicitly defining the enum used by the PVRDMA device and adding a function to convert the pvrdma_network_type to rdma_network_type enum. Cc: stable@vger.kernel.org # 5.10+ Fixes: 1c15b4f2a42f ("RDMA/core: Modify enum ib_gid_type and enum rdma_network_type") Link: https://lore.kernel.org/r/1611026189-17943-1-git-send-email-bryantan@vmware.com Reviewed-by: Adit Ranadive Signed-off-by: Bryan Tan Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/vmw_pvrdma/pvrdma.h | 14 ++++++++++++++ drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c | 2 +- include/uapi/rdma/vmw_pvrdma-abi.h | 7 +++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h index c142f5e7f25f8..de57f2fed7437 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h @@ -509,6 +509,20 @@ static inline int ib_send_flags_to_pvrdma(int flags) return flags & PVRDMA_MASK(PVRDMA_SEND_FLAGS_MAX); } +static inline int pvrdma_network_type_to_ib(enum pvrdma_network_type type) +{ + switch (type) { + case PVRDMA_NETWORK_ROCE_V1: + return RDMA_NETWORK_ROCE_V1; + case PVRDMA_NETWORK_IPV4: + return RDMA_NETWORK_IPV4; + case PVRDMA_NETWORK_IPV6: + return RDMA_NETWORK_IPV6; + default: + return RDMA_NETWORK_IPV6; + } +} + void pvrdma_qp_cap_to_ib(struct ib_qp_cap *dst, const struct pvrdma_qp_cap *src); void ib_qp_cap_to_pvrdma(struct pvrdma_qp_cap *dst, diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c index a119ac3e103c8..6aa40bd2fd52d 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c @@ -367,7 +367,7 @@ static int pvrdma_poll_one(struct pvrdma_cq *cq, struct pvrdma_qp **cur_qp, wc->dlid_path_bits = cqe->dlid_path_bits; wc->port_num = cqe->port_num; wc->vendor_err = cqe->vendor_err; - wc->network_hdr_type = cqe->network_hdr_type; + wc->network_hdr_type = pvrdma_network_type_to_ib(cqe->network_hdr_type); /* Update shared ring state */ pvrdma_idx_ring_inc(&cq->ring_state->rx.cons_head, cq->ibcq.cqe); diff --git a/include/uapi/rdma/vmw_pvrdma-abi.h b/include/uapi/rdma/vmw_pvrdma-abi.h index f8b638c73371d..901a4fd72c09f 100644 --- a/include/uapi/rdma/vmw_pvrdma-abi.h +++ b/include/uapi/rdma/vmw_pvrdma-abi.h @@ -133,6 +133,13 @@ enum pvrdma_wc_flags { PVRDMA_WC_FLAGS_MAX = PVRDMA_WC_WITH_NETWORK_HDR_TYPE, }; +enum pvrdma_network_type { + PVRDMA_NETWORK_IB, + PVRDMA_NETWORK_ROCE_V1 = PVRDMA_NETWORK_IB, + PVRDMA_NETWORK_IPV4, + PVRDMA_NETWORK_IPV6 +}; + struct pvrdma_alloc_ucontext_resp { __u32 qp_tab_size; __u32 reserved; -- GitLab From 9293d3fcb70583f2c786f04ca788af026b7c4c5c Mon Sep 17 00:00:00 2001 From: Yangyang Li Date: Tue, 19 Jan 2021 17:28:33 +0800 Subject: [PATCH 0371/1084] RDMA/hns: Use mutex instead of spinlock for ida allocation GFP_KERNEL may cause ida_alloc_range() to sleep, but the spinlock covering this function is not allowed to sleep, so the spinlock needs to be changed to mutex. As there is a certain chance of memory allocation failure, GFP_ATOMIC is not suitable for QP allocation scenarios. Fixes: 71586dd20010 ("RDMA/hns: Create QP with selected QPN for bank load balance") Link: https://lore.kernel.org/r/1611048513-28663-1-git-send-email-liweihang@huawei.com Signed-off-by: Yangyang Li Signed-off-by: Weihang Li Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/hns/hns_roce_device.h | 2 +- drivers/infiniband/hw/hns/hns_roce_qp.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 55d538625e361..ad8253245a85f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -532,7 +532,7 @@ struct hns_roce_qp_table { struct hns_roce_hem_table sccc_table; struct mutex scc_mutex; struct hns_roce_bank bank[HNS_ROCE_QP_BANK_NUM]; - spinlock_t bank_lock; + struct mutex bank_mutex; }; struct hns_roce_cq_table { diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index d8e2fe5558d29..1116371adf74f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -209,7 +209,7 @@ static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) hr_qp->doorbell_qpn = 1; } else { - spin_lock(&qp_table->bank_lock); + mutex_lock(&qp_table->bank_mutex); bankid = get_least_load_bankid_for_qp(qp_table->bank); ret = alloc_qpn_with_bankid(&qp_table->bank[bankid], bankid, @@ -217,12 +217,12 @@ static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) if (ret) { ibdev_err(&hr_dev->ib_dev, "failed to alloc QPN, ret = %d\n", ret); - spin_unlock(&qp_table->bank_lock); + mutex_unlock(&qp_table->bank_mutex); return ret; } qp_table->bank[bankid].inuse++; - spin_unlock(&qp_table->bank_lock); + mutex_unlock(&qp_table->bank_mutex); hr_qp->doorbell_qpn = (u32)num; } @@ -408,9 +408,9 @@ static void free_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) ida_free(&hr_dev->qp_table.bank[bankid].ida, hr_qp->qpn >> 3); - spin_lock(&hr_dev->qp_table.bank_lock); + mutex_lock(&hr_dev->qp_table.bank_mutex); hr_dev->qp_table.bank[bankid].inuse--; - spin_unlock(&hr_dev->qp_table.bank_lock); + mutex_unlock(&hr_dev->qp_table.bank_mutex); } static int set_rq_size(struct hns_roce_dev *hr_dev, struct ib_qp_cap *cap, @@ -1371,6 +1371,7 @@ int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev) unsigned int i; mutex_init(&qp_table->scc_mutex); + mutex_init(&qp_table->bank_mutex); xa_init(&hr_dev->qp_table_xa); reserved_from_bot = hr_dev->caps.reserved_qps; -- GitLab From de641d74fb00f5b32f054ee154e31fb037e0db88 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Sun, 17 Jan 2021 11:26:33 +0200 Subject: [PATCH 0372/1084] Revert "RDMA/mlx5: Fix devlink deadlock on net namespace deletion" This reverts commit fbdd0049d98d44914fc57d4b91f867f4996c787b. Due to commit in fixes tag, netdevice events were received only in one net namespace of mlx5_core_dev. Due to this when netdevice events arrive in net namespace other than net namespace of mlx5_core_dev, they are missed. This results in empty GID table due to RDMA device being detached from its net device. Hence, revert back to receive netdevice events in all net namespaces to restore back RDMA functionality in non init_net net namespace. The deadlock will have to be addressed in another patch. Fixes: fbdd0049d98d ("RDMA/mlx5: Fix devlink deadlock on net namespace deletion") Link: https://lore.kernel.org/r/20210117092633.10690-1-leon@kernel.org Signed-off-by: Parav Pandit Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/mlx5/main.c | 6 ++---- .../net/ethernet/mellanox/mlx5/core/lib/mlx5.h | 5 +++++ include/linux/mlx5/driver.h | 18 ------------------ 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index d26f3f3e0462a..aabdc07e47537 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -3311,8 +3311,7 @@ static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num) int err; dev->port[port_num].roce.nb.notifier_call = mlx5_netdev_event; - err = register_netdevice_notifier_net(mlx5_core_net(dev->mdev), - &dev->port[port_num].roce.nb); + err = register_netdevice_notifier(&dev->port[port_num].roce.nb); if (err) { dev->port[port_num].roce.nb.notifier_call = NULL; return err; @@ -3324,8 +3323,7 @@ static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num) static void mlx5_remove_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num) { if (dev->port[port_num].roce.nb.notifier_call) { - unregister_netdevice_notifier_net(mlx5_core_net(dev->mdev), - &dev->port[port_num].roce.nb); + unregister_netdevice_notifier(&dev->port[port_num].roce.nb); dev->port[port_num].roce.nb.notifier_call = NULL; } } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h index 3a9fa629503f0..d046db7bb047d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h @@ -90,4 +90,9 @@ int mlx5_create_encryption_key(struct mlx5_core_dev *mdev, u32 key_type, u32 *p_key_id); void mlx5_destroy_encryption_key(struct mlx5_core_dev *mdev, u32 key_id); +static inline struct net *mlx5_core_net(struct mlx5_core_dev *dev) +{ + return devlink_net(priv_to_devlink(dev)); +} + #endif diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index f93bfe7473aa7..4672e12f1aa52 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -1209,22 +1209,4 @@ static inline bool mlx5_is_roce_enabled(struct mlx5_core_dev *dev) return val.vbool; } -/** - * mlx5_core_net - Provide net namespace of the mlx5_core_dev - * @dev: mlx5 core device - * - * mlx5_core_net() returns the net namespace of mlx5 core device. - * This can be called only in below described limited context. - * (a) When a devlink instance for mlx5_core is registered and - * when devlink reload operation is disabled. - * or - * (b) during devlink reload reload_down() and reload_up callbacks - * where it is ensured that devlink instance's net namespace is - * stable. - */ -static inline struct net *mlx5_core_net(struct mlx5_core_dev *dev) -{ - return devlink_net(priv_to_devlink(dev)); -} - #endif /* MLX5_DRIVER_H */ -- GitLab From f068cb1db2cb40c9782874df7b08c684106cf609 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 15 Jan 2021 16:36:50 -0800 Subject: [PATCH 0373/1084] RDMA/usnic: Fix misuse of sysfs_emit_at In commit e28bf1f03b01 ("RDMA: Convert various random sprintf sysfs _show uses to sysfs_emit") I mistakenly used len = sysfs_emit_at to overwrite the last trailing space of potentially multiple entry output. Instead use a more common style by removing the trailing space from the output formats and adding a prefixing space to the contination formats and converting the final terminating output newline from the defective len = sysfs_emit_at(buf, len, "\n"); to the now appropriate and typical len += sysfs_emit_at(buf, len, "\n"); Fixes: e28bf1f03b01 ("RDMA: Convert various random sprintf sysfs _show uses to sysfs_emit") Link: https://lore.kernel.org/r/5eb794b9c9bca0494d94b2b209f1627fa4e7b555.camel@perches.com Reported-by: James Bottomley Signed-off-by: Joe Perches Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/usnic/usnic_ib_sysfs.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c b/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c index e59615a4c9d98..586b0e52ba7f8 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c @@ -214,7 +214,7 @@ static ssize_t summary_show(struct usnic_ib_qp_grp *qp_grp, char *buf) struct usnic_vnic_res *vnic_res; int len; - len = sysfs_emit(buf, "QPN: %d State: (%s) PID: %u VF Idx: %hu ", + len = sysfs_emit(buf, "QPN: %d State: (%s) PID: %u VF Idx: %hu", qp_grp->ibqp.qp_num, usnic_ib_qp_grp_state_to_string(qp_grp->state), qp_grp->owner_pid, @@ -224,14 +224,13 @@ static ssize_t summary_show(struct usnic_ib_qp_grp *qp_grp, char *buf) res_chunk = qp_grp->res_chunk_list[i]; for (j = 0; j < res_chunk->cnt; j++) { vnic_res = res_chunk->res[j]; - len += sysfs_emit_at( - buf, len, "%s[%d] ", + len += sysfs_emit_at(buf, len, " %s[%d]", usnic_vnic_res_type_to_str(vnic_res->type), vnic_res->vnic_idx); } } - len = sysfs_emit_at(buf, len, "\n"); + len += sysfs_emit_at(buf, len, "\n"); return len; } -- GitLab From f6a2e94b3f9d89cb40771ff746b16b5687650cbb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 18 Jan 2021 16:08:12 +0100 Subject: [PATCH 0374/1084] sh_eth: Fix power down vs. is_opened flag ordering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sh_eth_close() does a synchronous power down of the device before marking it closed. Revert the order, to make sure the device is never marked opened while suspended. While at it, use pm_runtime_put() instead of pm_runtime_put_sync(), as there is no reason to do a synchronous power down. Fixes: 7fa2955ff70ce453 ("sh_eth: Fix sleeping function called from invalid context") Signed-off-by: Geert Uytterhoeven Reviewed-by: Sergei Shtylyov Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20210118150812.796791-1-geert+renesas@glider.be Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/renesas/sh_eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 9b52d350e21a9..590b088bc4c7f 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2606,10 +2606,10 @@ static int sh_eth_close(struct net_device *ndev) /* Free all the skbuffs in the Rx queue and the DMA buffer. */ sh_eth_ring_free(ndev); - pm_runtime_put_sync(&mdp->pdev->dev); - mdp->is_opened = 0; + pm_runtime_put(&mdp->pdev->dev); + return 0; } -- GitLab From 4964e5a1e080f785f5518b402a9e48c527fe6cbd Mon Sep 17 00:00:00 2001 From: Bongsu Jeon Date: Tue, 19 Jan 2021 05:55:22 +0900 Subject: [PATCH 0375/1084] net: nfc: nci: fix the wrong NCI_CORE_INIT parameters Fix the code because NCI_CORE_INIT_CMD includes two parameters in NCI2.0 but there is no parameters in NCI1.x. Fixes: bcd684aace34 ("net/nfc/nci: Support NCI 2.x initial sequence") Signed-off-by: Bongsu Jeon Link: https://lore.kernel.org/r/20210118205522.317087-1-bongsu.jeon@samsung.com Signed-off-by: Jakub Kicinski --- net/nfc/nci/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index e64727e1a72f9..02a1f13f07980 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -508,7 +508,7 @@ static int nci_open_device(struct nci_dev *ndev) }; unsigned long opt = 0; - if (!(ndev->nci_ver & NCI_VER_2_MASK)) + if (ndev->nci_ver & NCI_VER_2_MASK) opt = (unsigned long)&nci_init_v2_cmd; rc = __nci_request(ndev, nci_init_req, opt, -- GitLab From dd3a44c06f7b4f14e90065bf05d62c255b20005f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 19 Jan 2021 15:18:00 +1100 Subject: [PATCH 0376/1084] selftests/powerpc: Only test lwm/stmw on big endian Newer binutils (>= 2.36) refuse to assemble lmw/stmw when building in little endian mode. That breaks compilation of our alignment handler test: /tmp/cco4l14N.s: Assembler messages: /tmp/cco4l14N.s:1440: Error: `lmw' invalid when little-endian /tmp/cco4l14N.s:1814: Error: `stmw' invalid when little-endian make[2]: *** [../../lib.mk:139: /output/kselftest/powerpc/alignment/alignment_handler] Error 1 These tests do pass on little endian machines, as the kernel will still emulate those instructions even when running little endian (which is arguably a kernel bug). But we don't really need to test that case, so ifdef those instructions out to get the alignment test building again. Reported-by: Libor Pechacek Signed-off-by: Michael Ellerman Tested-by: Libor Pechacek Link: https://lore.kernel.org/r/20210119041800.3093047-1-mpe@ellerman.id.au --- .../testing/selftests/powerpc/alignment/alignment_handler.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c b/tools/testing/selftests/powerpc/alignment/alignment_handler.c index cb53a8b777e68..c25cf7cd45e9f 100644 --- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c +++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c @@ -443,7 +443,6 @@ int test_alignment_handler_integer(void) LOAD_DFORM_TEST(ldu); LOAD_XFORM_TEST(ldx); LOAD_XFORM_TEST(ldux); - LOAD_DFORM_TEST(lmw); STORE_DFORM_TEST(stb); STORE_XFORM_TEST(stbx); STORE_DFORM_TEST(stbu); @@ -462,7 +461,11 @@ int test_alignment_handler_integer(void) STORE_XFORM_TEST(stdx); STORE_DFORM_TEST(stdu); STORE_XFORM_TEST(stdux); + +#ifdef __BIG_ENDIAN__ + LOAD_DFORM_TEST(lmw); STORE_DFORM_TEST(stmw); +#endif return rc; } -- GitLab From fd23d2dc180fccfad4b27a8e52ba1bc415d18509 Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Tue, 19 Jan 2021 10:59:30 +0800 Subject: [PATCH 0377/1084] selftests: net: fib_tests: remove duplicate log test The previous test added an address with a specified metric and check if correspond route was created. I somehow added two logs for the same test. Remove the duplicated one. Reported-by: Antoine Tenart Fixes: 0d29169a708b ("selftests/net/fib_tests: update addr_metric_test for peer route testing") Signed-off-by: Hangbin Liu Reviewed-by: David Ahern Link: https://lore.kernel.org/r/20210119025930.2810532-1-liuhangbin@gmail.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/fib_tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh index 84205c3a55ebe..2b5707738609e 100755 --- a/tools/testing/selftests/net/fib_tests.sh +++ b/tools/testing/selftests/net/fib_tests.sh @@ -1055,7 +1055,6 @@ ipv6_addr_metric_test() check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260" log_test $? 0 "Set metric with peer route on local side" - log_test $? 0 "User specified metric on local address" check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260" log_test $? 0 "Set metric with peer route on peer side" -- GitLab From b160c28548bc0a87cbd16d5af6d3edcfd70b8c9a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 19 Jan 2021 08:49:00 -0800 Subject: [PATCH 0378/1084] tcp: do not mess with cloned skbs in tcp_add_backlog() Heiner Kallweit reported that some skbs were sent with the following invalid GSO properties : - gso_size > 0 - gso_type == 0 This was triggerring a WARN_ON_ONCE() in rtl8169_tso_csum_v2. Juerg Haefliger was able to reproduce a similar issue using a lan78xx NIC and a workload mixing TCP incoming traffic and forwarded packets. The problem is that tcp_add_backlog() is writing over gso_segs and gso_size even if the incoming packet will not be coalesced to the backlog tail packet. While skb_try_coalesce() would bail out if tail packet is cloned, this overwriting would lead to corruptions of other packets cooked by lan78xx, sharing a common super-packet. The strategy used by lan78xx is to use a big skb, and split it into all received packets using skb_clone() to avoid copies. The drawback of this strategy is that all the small skb share a common struct skb_shared_info. This patch rewrites TCP gso_size/gso_segs handling to only happen on the tail skb, since skb_try_coalesce() made sure it was not cloned. Fixes: 4f693b55c3d2 ("tcp: implement coalescing on backlog queue") Signed-off-by: Eric Dumazet Bisected-by: Juerg Haefliger Tested-by: Juerg Haefliger Reported-by: Heiner Kallweit Link: https://bugzilla.kernel.org/show_bug.cgi?id=209423 Link: https://lore.kernel.org/r/20210119164900.766957-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski --- net/ipv4/tcp_ipv4.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 58207c7769d05..4e82745d336fc 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1760,6 +1760,7 @@ int tcp_v4_early_demux(struct sk_buff *skb) bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) { u32 limit = READ_ONCE(sk->sk_rcvbuf) + READ_ONCE(sk->sk_sndbuf); + u32 tail_gso_size, tail_gso_segs; struct skb_shared_info *shinfo; const struct tcphdr *th; struct tcphdr *thtail; @@ -1767,6 +1768,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) unsigned int hdrlen; bool fragstolen; u32 gso_segs; + u32 gso_size; int delta; /* In case all data was pulled from skb frags (in __pskb_pull_tail()), @@ -1792,13 +1794,6 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) */ th = (const struct tcphdr *)skb->data; hdrlen = th->doff * 4; - shinfo = skb_shinfo(skb); - - if (!shinfo->gso_size) - shinfo->gso_size = skb->len - hdrlen; - - if (!shinfo->gso_segs) - shinfo->gso_segs = 1; tail = sk->sk_backlog.tail; if (!tail) @@ -1821,6 +1816,15 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) goto no_coalesce; __skb_pull(skb, hdrlen); + + shinfo = skb_shinfo(skb); + gso_size = shinfo->gso_size ?: skb->len; + gso_segs = shinfo->gso_segs ?: 1; + + shinfo = skb_shinfo(tail); + tail_gso_size = shinfo->gso_size ?: (tail->len - hdrlen); + tail_gso_segs = shinfo->gso_segs ?: 1; + if (skb_try_coalesce(tail, skb, &fragstolen, &delta)) { TCP_SKB_CB(tail)->end_seq = TCP_SKB_CB(skb)->end_seq; @@ -1847,11 +1851,8 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) } /* Not as strict as GRO. We only need to carry mss max value */ - skb_shinfo(tail)->gso_size = max(shinfo->gso_size, - skb_shinfo(tail)->gso_size); - - gso_segs = skb_shinfo(tail)->gso_segs + shinfo->gso_segs; - skb_shinfo(tail)->gso_segs = min_t(u32, gso_segs, 0xFFFF); + shinfo->gso_size = max(gso_size, tail_gso_size); + shinfo->gso_segs = min_t(u32, gso_segs + tail_gso_segs, 0xFFFF); sk->sk_backlog.len += delta; __NET_INC_STATS(sock_net(sk), -- GitLab From 8e4052c32d6b4b39c1e13c652c7e33748d447409 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 19 Jan 2021 17:48:03 +0300 Subject: [PATCH 0379/1084] net: dsa: b53: fix an off by one in checking "vlan->vid" The > comparison should be >= to prevent accessing one element beyond the end of the dev->vlans[] array in the caller function, b53_vlan_add(). The "dev->vlans" array is allocated in the b53_switch_init() function and it has "dev->num_vlans" elements. Fixes: a2482d2ce349 ("net: dsa: b53: Plug in VLAN support") Signed-off-by: Dan Carpenter Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/YAbxI97Dl/pmBy5V@mwanda Signed-off-by: Jakub Kicinski --- drivers/net/dsa/b53/b53_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 288b5a5c3e0db..95c7fa171e35a 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -1404,7 +1404,7 @@ int b53_vlan_prepare(struct dsa_switch *ds, int port, !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)) return -EINVAL; - if (vlan->vid_end > dev->num_vlans) + if (vlan->vid_end >= dev->num_vlans) return -ERANGE; b53_enable_vlan(dev, true, ds->vlan_filtering); -- GitLab From 9c30ae8398b0813e237bde387d67a7f74ab2db2d Mon Sep 17 00:00:00 2001 From: Yuchung Cheng Date: Tue, 19 Jan 2021 11:26:19 -0800 Subject: [PATCH 0380/1084] tcp: fix TCP socket rehash stats mis-accounting The previous commit 32efcc06d2a1 ("tcp: export count for rehash attempts") would mis-account rehashing SNMP and socket stats: a. During handshake of an active open, only counts the first SYN timeout b. After handshake of passive and active open, stop updating after (roughly) TCP_RETRIES1 recurring RTOs c. After the socket aborts, over count timeout_rehash by 1 This patch fixes this by checking the rehash result from sk_rethink_txhash. Fixes: 32efcc06d2a1 ("tcp: export count for rehash attempts") Signed-off-by: Yuchung Cheng Signed-off-by: Eric Dumazet Signed-off-by: Neal Cardwell Link: https://lore.kernel.org/r/20210119192619.1848270-1-ycheng@google.com Signed-off-by: Jakub Kicinski --- include/net/sock.h | 17 ++++++++++++----- net/ipv4/tcp_input.c | 5 ++--- net/ipv4/tcp_timer.c | 22 ++++++++-------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index bdc4323ce53c9..129d200bccb46 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1921,10 +1921,13 @@ static inline void sk_set_txhash(struct sock *sk) sk->sk_txhash = net_tx_rndhash(); } -static inline void sk_rethink_txhash(struct sock *sk) +static inline bool sk_rethink_txhash(struct sock *sk) { - if (sk->sk_txhash) + if (sk->sk_txhash) { sk_set_txhash(sk); + return true; + } + return false; } static inline struct dst_entry * @@ -1947,12 +1950,10 @@ sk_dst_get(struct sock *sk) return dst; } -static inline void dst_negative_advice(struct sock *sk) +static inline void __dst_negative_advice(struct sock *sk) { struct dst_entry *ndst, *dst = __sk_dst_get(sk); - sk_rethink_txhash(sk); - if (dst && dst->ops->negative_advice) { ndst = dst->ops->negative_advice(dst); @@ -1964,6 +1965,12 @@ static inline void dst_negative_advice(struct sock *sk) } } +static inline void dst_negative_advice(struct sock *sk) +{ + sk_rethink_txhash(sk); + __dst_negative_advice(sk); +} + static inline void __sk_dst_set(struct sock *sk, struct dst_entry *dst) { diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index bafcab75f4256..a7dfca0a38cd7 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4397,10 +4397,9 @@ static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb) * The receiver remembers and reflects via DSACKs. Leverage the * DSACK state and change the txhash to re-route speculatively. */ - if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq) { - sk_rethink_txhash(sk); + if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq && + sk_rethink_txhash(sk)) NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPDUPLICATEDATAREHASH); - } } static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb) diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 454732ecc8f33..faa92948441ba 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -219,14 +219,8 @@ static int tcp_write_timeout(struct sock *sk) int retry_until; if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { - if (icsk->icsk_retransmits) { - dst_negative_advice(sk); - } else { - sk_rethink_txhash(sk); - tp->timeout_rehash++; - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPTIMEOUTREHASH); - } + if (icsk->icsk_retransmits) + __dst_negative_advice(sk); retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries; expired = icsk->icsk_retransmits >= retry_until; } else { @@ -234,12 +228,7 @@ static int tcp_write_timeout(struct sock *sk) /* Black hole detection */ tcp_mtu_probing(icsk, sk); - dst_negative_advice(sk); - } else { - sk_rethink_txhash(sk); - tp->timeout_rehash++; - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPTIMEOUTREHASH); + __dst_negative_advice(sk); } retry_until = net->ipv4.sysctl_tcp_retries2; @@ -270,6 +259,11 @@ static int tcp_write_timeout(struct sock *sk) return 1; } + if (sk_rethink_txhash(sk)) { + tp->timeout_rehash++; + __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEOUTREHASH); + } + return 0; } -- GitLab From 08685be7761d69914f08c3d6211c543a385a5b9c Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 11 Jan 2021 16:24:08 +1000 Subject: [PATCH 0381/1084] powerpc/64s: fix scv entry fallback flush vs interrupt The L1D flush fallback functions are not recoverable vs interrupts, yet the scv entry flush runs with MSR[EE]=1. This can result in a timer (soft-NMI) or MCE or SRESET interrupt hitting here and overwriting the EXRFI save area, which ends up corrupting userspace registers for scv return. Fix this by disabling RI and EE for the scv entry fallback flush. Fixes: f79643787e0a0 ("powerpc/64s: flush L1D on kernel entry") Cc: stable@vger.kernel.org # 5.9+ which also have flush L1D patch backport Reported-by: Tulio Magno Quites Machado Filho Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210111062408.287092-1-npiggin@gmail.com --- arch/powerpc/include/asm/exception-64s.h | 13 ++++++++++++ arch/powerpc/include/asm/feature-fixups.h | 10 ++++++++++ arch/powerpc/kernel/entry_64.S | 2 +- arch/powerpc/kernel/exceptions-64s.S | 19 ++++++++++++++++++ arch/powerpc/kernel/vmlinux.lds.S | 7 +++++++ arch/powerpc/lib/feature-fixups.c | 24 ++++++++++++++++++++--- 6 files changed, 71 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 1d32b174ab6ae..c1a8aac01cf91 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -63,6 +63,12 @@ nop; \ nop; +#define SCV_ENTRY_FLUSH_SLOT \ + SCV_ENTRY_FLUSH_FIXUP_SECTION; \ + nop; \ + nop; \ + nop; + /* * r10 must be free to use, r13 must be paca */ @@ -70,6 +76,13 @@ STF_ENTRY_BARRIER_SLOT; \ ENTRY_FLUSH_SLOT +/* + * r10, ctr must be free to use, r13 must be paca + */ +#define SCV_INTERRUPT_TO_KERNEL \ + STF_ENTRY_BARRIER_SLOT; \ + SCV_ENTRY_FLUSH_SLOT + /* * Macros for annotating the expected destination of (h)rfid * diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h index f6d2acb574252..ac605fc369c42 100644 --- a/arch/powerpc/include/asm/feature-fixups.h +++ b/arch/powerpc/include/asm/feature-fixups.h @@ -240,6 +240,14 @@ label##3: \ FTR_ENTRY_OFFSET 957b-958b; \ .popsection; +#define SCV_ENTRY_FLUSH_FIXUP_SECTION \ +957: \ + .pushsection __scv_entry_flush_fixup,"a"; \ + .align 2; \ +958: \ + FTR_ENTRY_OFFSET 957b-958b; \ + .popsection; + #define RFI_FLUSH_FIXUP_SECTION \ 951: \ .pushsection __rfi_flush_fixup,"a"; \ @@ -273,10 +281,12 @@ label##3: \ extern long stf_barrier_fallback; extern long entry_flush_fallback; +extern long scv_entry_flush_fallback; extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup; extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup; extern long __start___uaccess_flush_fixup, __stop___uaccess_flush_fixup; extern long __start___entry_flush_fixup, __stop___entry_flush_fixup; +extern long __start___scv_entry_flush_fixup, __stop___scv_entry_flush_fixup; extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup; extern long __start__btb_flush_fixup, __stop__btb_flush_fixup; diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index aa1af139d9472..33ddfeef4fe9e 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -75,7 +75,7 @@ BEGIN_FTR_SECTION bne .Ltabort_syscall END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif - INTERRUPT_TO_KERNEL + SCV_INTERRUPT_TO_KERNEL mr r10,r1 ld r1,PACAKSAVE(r13) std r10,0(r1) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e02ad6fefa46c..6e53f76387374 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -2993,6 +2993,25 @@ TRAMP_REAL_BEGIN(entry_flush_fallback) ld r11,PACA_EXRFI+EX_R11(r13) blr +/* + * The SCV entry flush happens with interrupts enabled, so it must disable + * to prevent EXRFI being clobbered by NMIs (e.g., soft_nmi_common). r10 + * (containing LR) does not need to be preserved here because scv entry + * puts 0 in the pt_regs, CTR can be clobbered for the same reason. + */ +TRAMP_REAL_BEGIN(scv_entry_flush_fallback) + li r10,0 + mtmsrd r10,1 + lbz r10,PACAIRQHAPPENED(r13) + ori r10,r10,PACA_IRQ_HARD_DIS + stb r10,PACAIRQHAPPENED(r13) + std r11,PACA_EXRFI+EX_R11(r13) + L1D_DISPLACEMENT_FLUSH + ld r11,PACA_EXRFI+EX_R11(r13) + li r10,MSR_RI + mtmsrd r10,1 + blr + TRAMP_REAL_BEGIN(rfi_flush_fallback) SET_SCRATCH0(r13); GET_PACA(r13); diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 4ab426b8b0e02..72fa3c00229a5 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -145,6 +145,13 @@ SECTIONS __stop___entry_flush_fixup = .; } + . = ALIGN(8); + __scv_entry_flush_fixup : AT(ADDR(__scv_entry_flush_fixup) - LOAD_OFFSET) { + __start___scv_entry_flush_fixup = .; + *(__scv_entry_flush_fixup) + __stop___scv_entry_flush_fixup = .; + } + . = ALIGN(8); __stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) { __start___stf_exit_barrier_fixup = .; diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 47821055b94c9..1fd31b4b0e139 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -290,9 +290,6 @@ void do_entry_flush_fixups(enum l1d_flush_type types) long *start, *end; int i; - start = PTRRELOC(&__start___entry_flush_fixup); - end = PTRRELOC(&__stop___entry_flush_fixup); - instrs[0] = 0x60000000; /* nop */ instrs[1] = 0x60000000; /* nop */ instrs[2] = 0x60000000; /* nop */ @@ -312,6 +309,8 @@ void do_entry_flush_fixups(enum l1d_flush_type types) if (types & L1D_FLUSH_MTTRIG) instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */ + start = PTRRELOC(&__start___entry_flush_fixup); + end = PTRRELOC(&__stop___entry_flush_fixup); for (i = 0; start < end; start++, i++) { dest = (void *)start + *start; @@ -328,6 +327,25 @@ void do_entry_flush_fixups(enum l1d_flush_type types) patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2])); } + start = PTRRELOC(&__start___scv_entry_flush_fixup); + end = PTRRELOC(&__stop___scv_entry_flush_fixup); + for (; start < end; start++, i++) { + dest = (void *)start + *start; + + pr_devel("patching dest %lx\n", (unsigned long)dest); + + patch_instruction((struct ppc_inst *)dest, ppc_inst(instrs[0])); + + if (types == L1D_FLUSH_FALLBACK) + patch_branch((struct ppc_inst *)(dest + 1), (unsigned long)&scv_entry_flush_fallback, + BRANCH_SET_LINK); + else + patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instrs[1])); + + patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2])); + } + + printk(KERN_DEBUG "entry-flush: patched %d locations (%s flush)\n", i, (types == L1D_FLUSH_NONE) ? "no" : (types == L1D_FLUSH_FALLBACK) ? "fallback displacement" : -- GitLab From 710eb8e32d04714452759f2b66884bfa7e97d495 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Thu, 7 Jan 2021 09:18:45 +0200 Subject: [PATCH 0382/1084] vdpa/mlx5: Fix memory key MTT population map_direct_mr() assumed that the number of scatter/gather entries returned by dma_map_sg_attrs() was equal to the number of segments in the sgl list. This led to wrong population of the mkey object. Fix this by properly referring to the returned value. The hardware expects each MTT entry to contain the DMA address of a contiguous block of memory of size (1 << mr->log_size) bytes. dma_map_sg_attrs() can coalesce several sg entries into a single scatter/gather entry of contiguous DMA range so we need to scan the list and refer to the size of each s/g entry. In addition, get rid of fill_sg() which effect is overwritten by populate_mtts(). Fixes: 94abbccdf291 ("vdpa/mlx5: Add shared memory registration code") Signed-off-by: Eli Cohen Link: https://lore.kernel.org/r/20210107071845.GA224876@mtl-vdi-166.wap.labs.mlnx Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang --- drivers/vdpa/mlx5/core/mlx5_vdpa.h | 1 + drivers/vdpa/mlx5/core/mr.c | 28 ++++++++++++---------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h b/drivers/vdpa/mlx5/core/mlx5_vdpa.h index 5c92a576edae8..08f742fd24099 100644 --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h @@ -15,6 +15,7 @@ struct mlx5_vdpa_direct_mr { struct sg_table sg_head; int log_size; int nsg; + int nent; struct list_head list; u64 offset; }; diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c index 4b6195666c589..d300f799efcd1 100644 --- a/drivers/vdpa/mlx5/core/mr.c +++ b/drivers/vdpa/mlx5/core/mr.c @@ -25,17 +25,6 @@ static int get_octo_len(u64 len, int page_shift) return (npages + 1) / 2; } -static void fill_sg(struct mlx5_vdpa_direct_mr *mr, void *in) -{ - struct scatterlist *sg; - __be64 *pas; - int i; - - pas = MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt); - for_each_sg(mr->sg_head.sgl, sg, mr->nsg, i) - (*pas) = cpu_to_be64(sg_dma_address(sg)); -} - static void mlx5_set_access_mode(void *mkc, int mode) { MLX5_SET(mkc, mkc, access_mode_1_0, mode & 0x3); @@ -45,10 +34,18 @@ static void mlx5_set_access_mode(void *mkc, int mode) static void populate_mtts(struct mlx5_vdpa_direct_mr *mr, __be64 *mtt) { struct scatterlist *sg; + int nsg = mr->nsg; + u64 dma_addr; + u64 dma_len; + int j = 0; int i; - for_each_sg(mr->sg_head.sgl, sg, mr->nsg, i) - mtt[i] = cpu_to_be64(sg_dma_address(sg)); + for_each_sg(mr->sg_head.sgl, sg, mr->nent, i) { + for (dma_addr = sg_dma_address(sg), dma_len = sg_dma_len(sg); + nsg && dma_len; + nsg--, dma_addr += BIT(mr->log_size), dma_len -= BIT(mr->log_size)) + mtt[j++] = cpu_to_be64(dma_addr); + } } static int create_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr *mr) @@ -64,7 +61,6 @@ static int create_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct return -ENOMEM; MLX5_SET(create_mkey_in, in, uid, mvdev->res.uid); - fill_sg(mr, in); mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); MLX5_SET(mkc, mkc, lw, !!(mr->perm & VHOST_MAP_WO)); MLX5_SET(mkc, mkc, lr, !!(mr->perm & VHOST_MAP_RO)); @@ -276,8 +272,8 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr done: mr->log_size = log_entity_size; mr->nsg = nsg; - err = dma_map_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0); - if (!err) + mr->nent = dma_map_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0); + if (!mr->nent) goto err_map; err = create_direct_mr(mvdev, mr); -- GitLab From a37eef63bc9e16e06361b539e528058146af80ab Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 19 Jan 2021 14:03:18 +0100 Subject: [PATCH 0383/1084] drm/syncobj: Fix use-after-free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While reviewing Christian's annotation patch I noticed that we have a user-after-free for the WAIT_FOR_SUBMIT case: We drop the syncobj reference before we've completed the waiting. Of course usually there's nothing bad happening here since userspace keeps the reference, but we can't rely on userspace to play nice here! Signed-off-by: Daniel Vetter Fixes: bc9c80fe01a2 ("drm/syncobj: use the timeline point in drm_syncobj_find_fence v4") Reviewed-by: Christian König Cc: Christian König Cc: Lionel Landwerlin Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Cc: # v5.2+ Link: https://patchwork.freedesktop.org/patch/msgid/20210119130318.615145-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_syncobj.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 6e74e6745ecae..3491460498491 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -388,19 +388,18 @@ int drm_syncobj_find_fence(struct drm_file *file_private, return -ENOENT; *fence = drm_syncobj_fence_get(syncobj); - drm_syncobj_put(syncobj); if (*fence) { ret = dma_fence_chain_find_seqno(fence, point); if (!ret) - return 0; + goto out; dma_fence_put(*fence); } else { ret = -EINVAL; } if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) - return ret; + goto out; memset(&wait, 0, sizeof(wait)); wait.task = current; @@ -432,6 +431,9 @@ int drm_syncobj_find_fence(struct drm_file *file_private, if (wait.node.next) drm_syncobj_remove_wait(syncobj, &wait); +out: + drm_syncobj_put(syncobj); + return ret; } EXPORT_SYMBOL(drm_syncobj_find_fence); -- GitLab From 03f16c5075b22c8902d2af739969e878b0879c94 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Wed, 20 Jan 2021 20:41:35 +0900 Subject: [PATCH 0384/1084] can: dev: can_restart: fix use after free bug After calling netif_rx_ni(skb), dereferencing skb is unsafe. Especially, the can_frame cf which aliases skb memory is accessed after the netif_rx_ni() in: stats->rx_bytes += cf->len; Reordering the lines solves the issue. Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface") Link: https://lore.kernel.org/r/20210120114137.200019-2-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 3486704c8a957..8b1ae023cb218 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -592,11 +592,11 @@ static void can_restart(struct net_device *dev) cf->can_id |= CAN_ERR_RESTARTED; - netif_rx_ni(skb); - stats->rx_packets++; stats->rx_bytes += cf->len; + netif_rx_ni(skb); + restart: netdev_dbg(dev, "restarted\n"); priv->can_stats.restarts++; -- GitLab From 75854cad5d80976f6ea0f0431f8cedd3bcc475cb Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Wed, 20 Jan 2021 20:41:36 +0900 Subject: [PATCH 0385/1084] can: vxcan: vxcan_xmit: fix use after free bug After calling netif_rx_ni(skb), dereferencing skb is unsafe. Especially, the canfd_frame cfd which aliases skb memory is accessed after the netif_rx_ni(). Fixes: a8f820a380a2 ("can: add Virtual CAN Tunnel driver (vxcan)") Link: https://lore.kernel.org/r/20210120114137.200019-3-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Signed-off-by: Marc Kleine-Budde --- drivers/net/can/vxcan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c index fa47bab510bb9..f9a524c5f6d62 100644 --- a/drivers/net/can/vxcan.c +++ b/drivers/net/can/vxcan.c @@ -39,6 +39,7 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *skb, struct net_device *dev) struct net_device *peer; struct canfd_frame *cfd = (struct canfd_frame *)skb->data; struct net_device_stats *peerstats, *srcstats = &dev->stats; + u8 len; if (can_dropped_invalid_skb(dev, skb)) return NETDEV_TX_OK; @@ -61,12 +62,13 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *skb, struct net_device *dev) skb->dev = peer; skb->ip_summed = CHECKSUM_UNNECESSARY; + len = cfd->len; if (netif_rx_ni(skb) == NET_RX_SUCCESS) { srcstats->tx_packets++; - srcstats->tx_bytes += cfd->len; + srcstats->tx_bytes += len; peerstats = &peer->stats; peerstats->rx_packets++; - peerstats->rx_bytes += cfd->len; + peerstats->rx_bytes += len; } out_unlock: -- GitLab From 50aca891d7a554db0901b245167cd653d73aaa71 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Wed, 20 Jan 2021 20:41:37 +0900 Subject: [PATCH 0386/1084] can: peak_usb: fix use after free bugs After calling peak_usb_netif_rx_ni(skb), dereferencing skb is unsafe. Especially, the can_frame cf which aliases skb memory is accessed after the peak_usb_netif_rx_ni(). Reordering the lines solves the issue. Fixes: 0a25e1f4f185 ("can: peak_usb: add support for PEAK new CANFD USB adapters") Link: https://lore.kernel.org/r/20210120114137.200019-4-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c index 61631f4fd92a1..f347ecc79aef2 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c @@ -514,11 +514,11 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if, else memcpy(cfd->data, rm->d, cfd->len); - peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low)); - netdev->stats.rx_packets++; netdev->stats.rx_bytes += cfd->len; + peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low)); + return 0; } @@ -580,11 +580,11 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if, if (!skb) return -ENOMEM; - peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low)); - netdev->stats.rx_packets++; netdev->stats.rx_bytes += cf->len; + peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low)); + return 0; } -- GitLab From dc5d17a3c39b06aef866afca19245a9cfb533a79 Mon Sep 17 00:00:00 2001 From: Xiao Ni Date: Thu, 10 Dec 2020 14:33:32 +0800 Subject: [PATCH 0387/1084] md: Set prev_flush_start and flush_bio in an atomic way One customer reports a crash problem which causes by flush request. It triggers a warning before crash. /* new request after previous flush is completed */ if (ktime_after(req_start, mddev->prev_flush_start)) { WARN_ON(mddev->flush_bio); mddev->flush_bio = bio; bio = NULL; } The WARN_ON is triggered. We use spin lock to protect prev_flush_start and flush_bio in md_flush_request. But there is no lock protection in md_submit_flush_data. It can set flush_bio to NULL first because of compiler reordering write instructions. For example, flush bio1 sets flush bio to NULL first in md_submit_flush_data. An interrupt or vmware causing an extended stall happen between updating flush_bio and prev_flush_start. Because flush_bio is NULL, flush bio2 can get the lock and submit to underlayer disks. Then flush bio1 updates prev_flush_start after the interrupt or extended stall. Then flush bio3 enters in md_flush_request. The start time req_start is behind prev_flush_start. The flush_bio is not NULL(flush bio2 hasn't finished). So it can trigger the WARN_ON now. Then it calls INIT_WORK again. INIT_WORK() will re-initialize the list pointers in the work_struct, which then can result in a corrupted work list and the work_struct queued a second time. With the work list corrupted, it can lead in invalid work items being used and cause a crash in process_one_work. We need to make sure only one flush bio can be handled at one same time. So add spin lock in md_submit_flush_data to protect prev_flush_start and flush_bio in an atomic way. Reviewed-by: David Jeffery Signed-off-by: Xiao Ni Signed-off-by: Song Liu --- drivers/md/md.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/md/md.c b/drivers/md/md.c index ca409428b4fcb..04384452a7abd 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -639,8 +639,10 @@ static void md_submit_flush_data(struct work_struct *ws) * could wait for this and below md_handle_request could wait for those * bios because of suspend check */ + spin_lock_irq(&mddev->lock); mddev->prev_flush_start = mddev->start_flush; mddev->flush_bio = NULL; + spin_unlock_irq(&mddev->lock); wake_up(&mddev->sb_wait); if (bio->bi_iter.bi_size == 0) { -- GitLab From bc895e8b2a64e502fbba72748d59618272052a8b Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 20 Jan 2021 00:24:24 +0100 Subject: [PATCH 0388/1084] bpf: Fix signed_{sub,add32}_overflows type handling Fix incorrect signed_{sub,add32}_overflows() input types (and a related buggy comment). It looks like this might have slipped in via copy/paste issue, also given prior to 3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking") the signature of signed_sub_overflows() had s64 a and s64 b as its input args whereas now they are truncated to s32. Thus restore proper types. Also, the case of signed_add32_overflows() is not consistent to signed_sub32_overflows(). Both have s32 as inputs, therefore align the former. Fixes: 3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking") Reported-by: De4dCr0w Signed-off-by: Daniel Borkmann Reviewed-by: John Fastabend Acked-by: Alexei Starovoitov --- kernel/bpf/verifier.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 36af69fac5910..e7368c5eacb7b 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5313,7 +5313,7 @@ static bool signed_add_overflows(s64 a, s64 b) return res < a; } -static bool signed_add32_overflows(s64 a, s64 b) +static bool signed_add32_overflows(s32 a, s32 b) { /* Do the add in u32, where overflow is well-defined */ s32 res = (s32)((u32)a + (u32)b); @@ -5323,7 +5323,7 @@ static bool signed_add32_overflows(s64 a, s64 b) return res < a; } -static bool signed_sub_overflows(s32 a, s32 b) +static bool signed_sub_overflows(s64 a, s64 b) { /* Do the sub in u64, where overflow is well-defined */ s64 res = (s64)((u64)a - (u64)b); @@ -5335,7 +5335,7 @@ static bool signed_sub_overflows(s32 a, s32 b) static bool signed_sub32_overflows(s32 a, s32 b) { - /* Do the sub in u64, where overflow is well-defined */ + /* Do the sub in u32, where overflow is well-defined */ s32 res = (s32)((u32)a - (u32)b); if (b < 0) -- GitLab From 55a8b42e8645a6dab88674a30cb6ed328e660680 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Wed, 20 Jan 2021 00:26:35 -0800 Subject: [PATCH 0389/1084] spi: altera: Fix memory leak on error path Release master that have been previously allocated if the number of chipselect is invalid. Fixes: 8e04187c1bc7 ("spi: altera: add SPI core parameters support via platform data.") Signed-off-by: Pan Bian Reviewed-by: Tom Rix Link: https://lore.kernel.org/r/20210120082635.49304-1-bianpan2016@163.com Signed-off-by: Mark Brown --- drivers/spi/spi-altera.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c index cbc4c28c1541c..62ea0c9e321b4 100644 --- a/drivers/spi/spi-altera.c +++ b/drivers/spi/spi-altera.c @@ -254,7 +254,8 @@ static int altera_spi_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Invalid number of chipselect: %hu\n", pdata->num_chipselect); - return -EINVAL; + err = -EINVAL; + goto exit; } master->num_chipselect = pdata->num_chipselect; -- GitLab From c89dffc70b340780e5b933832d8c3e045ef3791e Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 18 Jan 2021 14:59:20 +0900 Subject: [PATCH 0390/1084] tcp: Fix potential use-after-free due to double kfree() Receiving ACK with a valid SYN cookie, cookie_v4_check() allocates struct request_sock and then can allocate inet_rsk(req)->ireq_opt. After that, tcp_v4_syn_recv_sock() allocates struct sock and copies ireq_opt to inet_sk(sk)->inet_opt. Normally, tcp_v4_syn_recv_sock() inserts the full socket into ehash and sets NULL to ireq_opt. Otherwise, tcp_v4_syn_recv_sock() has to reset inet_opt by NULL and free the full socket. The commit 01770a1661657 ("tcp: fix race condition when creating child sockets from syncookies") added a new path, in which more than one cores create full sockets for the same SYN cookie. Currently, the core which loses the race frees the full socket without resetting inet_opt, resulting in that both sock_put() and reqsk_put() call kfree() for the same memory: sock_put sk_free __sk_free sk_destruct __sk_destruct sk->sk_destruct/inet_sock_destruct kfree(rcu_dereference_protected(inet->inet_opt, 1)); reqsk_put reqsk_free __reqsk_free req->rsk_ops->destructor/tcp_v4_reqsk_destructor kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); Calling kmalloc() between the double kfree() can lead to use-after-free, so this patch fixes it by setting NULL to inet_opt before sock_put(). As a side note, this kind of issue does not happen for IPv6. This is because tcp_v6_syn_recv_sock() clones both ipv6_opt and pktopts which correspond to ireq_opt in IPv4. Fixes: 01770a166165 ("tcp: fix race condition when creating child sockets from syncookies") CC: Ricardo Dias Signed-off-by: Kuniyuki Iwashima Reviewed-by: Benjamin Herrenschmidt Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/20210118055920.82516-1-kuniyu@amazon.co.jp Signed-off-by: Jakub Kicinski --- net/ipv4/tcp_ipv4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 4e82745d336fc..777306b5bc224 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1595,6 +1595,8 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, tcp_move_syn(newtp, req); ireq->ireq_opt = NULL; } else { + newinet->inet_opt = NULL; + if (!req_unhash && found_dup_sk) { /* This code path should only be executed in the * syncookie case only @@ -1602,8 +1604,6 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, bh_unlock_sock(newsk); sock_put(newsk); newsk = NULL; - } else { - newinet->inet_opt = NULL; } } return newsk; -- GitLab From 584b7cfcdc7d6d416a9d6fece9516764bd977d2e Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Tue, 19 Jan 2021 15:06:38 +0100 Subject: [PATCH 0391/1084] net: mscc: ocelot: Fix multicast to the CPU port Multicast entries in the MAC table use the high bits of the MAC address to encode the ports that should get the packets. But this port mask does not work for the CPU port, to receive these packets on the CPU port the MAC_CPU_COPY flag must be set. Because of this IPv6 was effectively not working because neighbor solicitations were never received. This was not apparent before commit 9403c158 (net: mscc: ocelot: support IPv4, IPv6 and plain Ethernet mdb entries) as the IPv6 entries were broken so all incoming IPv6 multicast was then treated as unknown and flooded on all ports. To fix this problem rework the ocelot_mact_learn() to set the MAC_CPU_COPY flag when a multicast entry that target the CPU port is added. For this we have to read back the ports endcoded in the pseudo MAC address by the caller. It is not a very nice design but that avoid changing the callers and should make backporting easier. Signed-off-by: Alban Bedel Fixes: 9403c158b872 ("net: mscc: ocelot: support IPv4, IPv6 and plain Ethernet mdb entries") Link: https://lore.kernel.org/r/20210119140638.203374-1-alban.bedel@aerq.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mscc/ocelot.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index 0b9992bd66262..ff87a0bc089cf 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -60,14 +60,27 @@ int ocelot_mact_learn(struct ocelot *ocelot, int port, const unsigned char mac[ETH_ALEN], unsigned int vid, enum macaccess_entry_type type) { + u32 cmd = ANA_TABLES_MACACCESS_VALID | + ANA_TABLES_MACACCESS_DEST_IDX(port) | + ANA_TABLES_MACACCESS_ENTRYTYPE(type) | + ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN); + unsigned int mc_ports; + + /* Set MAC_CPU_COPY if the CPU port is used by a multicast entry */ + if (type == ENTRYTYPE_MACv4) + mc_ports = (mac[1] << 8) | mac[2]; + else if (type == ENTRYTYPE_MACv6) + mc_ports = (mac[0] << 8) | mac[1]; + else + mc_ports = 0; + + if (mc_ports & BIT(ocelot->num_phys_ports)) + cmd |= ANA_TABLES_MACACCESS_MAC_CPU_COPY; + ocelot_mact_select(ocelot, mac, vid); /* Issue a write command */ - ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID | - ANA_TABLES_MACACCESS_DEST_IDX(port) | - ANA_TABLES_MACACCESS_ENTRYTYPE(type) | - ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN), - ANA_TABLES_MACACCESS); + ocelot_write(ocelot, cmd, ANA_TABLES_MACACCESS); return ocelot_mact_wait_for_completion(ocelot); } -- GitLab From de658a195ee23ca6aaffe197d1d2ea040beea0a2 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Tue, 19 Jan 2021 17:12:08 -0800 Subject: [PATCH 0392/1084] net: usb: cdc_ncm: don't spew notifications RTL8156 sends notifications about every 32ms. Only display/log notifications when something changes. This issue has been reported by others: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1832472 https://lkml.org/lkml/2020/8/27/1083 ... [785962.779840] usb 1-1: new high-speed USB device number 5 using xhci_hcd [785962.929944] usb 1-1: New USB device found, idVendor=0bda, idProduct=8156, bcdDevice=30.00 [785962.929949] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=6 [785962.929952] usb 1-1: Product: USB 10/100/1G/2.5G LAN [785962.929954] usb 1-1: Manufacturer: Realtek [785962.929956] usb 1-1: SerialNumber: 000000001 [785962.991755] usbcore: registered new interface driver cdc_ether [785963.017068] cdc_ncm 1-1:2.0: MAC-Address: 00:24:27:88:08:15 [785963.017072] cdc_ncm 1-1:2.0: setting rx_max = 16384 [785963.017169] cdc_ncm 1-1:2.0: setting tx_max = 16384 [785963.017682] cdc_ncm 1-1:2.0 usb0: register 'cdc_ncm' at usb-0000:00:14.0-1, CDC NCM, 00:24:27:88:08:15 [785963.019211] usbcore: registered new interface driver cdc_ncm [785963.023856] usbcore: registered new interface driver cdc_wdm [785963.025461] usbcore: registered new interface driver cdc_mbim [785963.038824] cdc_ncm 1-1:2.0 enx002427880815: renamed from usb0 [785963.089586] cdc_ncm 1-1:2.0 enx002427880815: network connection: disconnected [785963.121673] cdc_ncm 1-1:2.0 enx002427880815: network connection: disconnected [785963.153682] cdc_ncm 1-1:2.0 enx002427880815: network connection: disconnected ... This is about 2KB per second and will overwrite all contents of a 1MB dmesg buffer in under 10 minutes rendering them useless for debugging many kernel problems. This is also an extra 180 MB/day in /var/logs (or 1GB per week) rendering the majority of those logs useless too. When the link is up (expected state), spew amount is >2x higher: ... [786139.600992] cdc_ncm 2-1:2.0 enx002427880815: network connection: connected [786139.632997] cdc_ncm 2-1:2.0 enx002427880815: 2500 mbit/s downlink 2500 mbit/s uplink [786139.665097] cdc_ncm 2-1:2.0 enx002427880815: network connection: connected [786139.697100] cdc_ncm 2-1:2.0 enx002427880815: 2500 mbit/s downlink 2500 mbit/s uplink [786139.729094] cdc_ncm 2-1:2.0 enx002427880815: network connection: connected [786139.761108] cdc_ncm 2-1:2.0 enx002427880815: 2500 mbit/s downlink 2500 mbit/s uplink ... Chrome OS cannot support RTL8156 until this is fixed. Signed-off-by: Grant Grundler Reviewed-by: Hayes Wang Link: https://lore.kernel.org/r/20210120011208.3768105-1-grundler@chromium.org Signed-off-by: Jakub Kicinski --- drivers/net/usb/cdc_ncm.c | 12 +++++++++++- include/linux/usb/usbnet.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 5a78848db93fd..291e76d32abe7 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1827,6 +1827,15 @@ cdc_ncm_speed_change(struct usbnet *dev, uint32_t rx_speed = le32_to_cpu(data->DLBitRRate); uint32_t tx_speed = le32_to_cpu(data->ULBitRate); + /* if the speed hasn't changed, don't report it. + * RTL8156 shipped before 2021 sends notification about every 32ms. + */ + if (dev->rx_speed == rx_speed && dev->tx_speed == tx_speed) + return; + + dev->rx_speed = rx_speed; + dev->tx_speed = tx_speed; + /* * Currently the USB-NET API does not support reporting the actual * device speed. Do print it instead. @@ -1867,7 +1876,8 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. */ - usbnet_link_change(dev, !!event->wValue, 0); + if (netif_carrier_ok(dev->net) != !!event->wValue) + usbnet_link_change(dev, !!event->wValue, 0); break; case USB_CDC_NOTIFY_SPEED_CHANGE: diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 88a7673894d5e..cfbfd6fe01dfa 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -81,6 +81,8 @@ struct usbnet { # define EVENT_LINK_CHANGE 11 # define EVENT_SET_RX_MODE 12 # define EVENT_NO_IP_ALIGN 13 + u32 rx_speed; /* in bps - NOT Mbps */ + u32 tx_speed; /* in bps - NOT Mbps */ }; static inline struct usb_driver *driver_of(struct usb_interface *intf) -- GitLab From 0c630a66bf10991b0ef13d27c93d7545e692ef5b Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Tue, 19 Jan 2021 20:44:23 -0800 Subject: [PATCH 0393/1084] net: systemport: free dev before on error path On the error path, it should goto the error handling label to free allocated memory rather than directly return. Fixes: 31bc72d97656 ("net: systemport: fetch and use clock resources") Signed-off-by: Pan Bian Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/20210120044423.1704-1-bianpan2016@163.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/broadcom/bcmsysport.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index b1ae9eb8f2479..0404aafd5ce56 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -2503,8 +2503,10 @@ static int bcm_sysport_probe(struct platform_device *pdev) priv = netdev_priv(dev); priv->clk = devm_clk_get_optional(&pdev->dev, "sw_sysport"); - if (IS_ERR(priv->clk)) - return PTR_ERR(priv->clk); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto err_free_netdev; + } /* Allocate number of TX rings */ priv->tx_rings = devm_kcalloc(&pdev->dev, txq, -- GitLab From f1b0a8ea9f12b8ade0dbe40dd57e4ffa9a30ed93 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Wed, 20 Jan 2021 17:19:13 +0100 Subject: [PATCH 0394/1084] Revert "RDMA/rxe: Remove VLAN code leftovers from RXE" This reverts commit b2d2440430c0fdd5e0cad3efd6d1c9e3d3d02e5b. It's true that creating rxe on top of 802.1q interfaces doesn't work. Thus, commit fd49ddaf7e26 ("RDMA/rxe: prevent rxe creation on top of vlan interface") was absolutely correct. But b2d2440430c0 was incorrect assuming that with this change, RDMA and VLAN don't work togehter at all. It just has to be set up differently. Rather than creating rxe on top of the VLAN interface, rxe must be created on top of the physical interface. RDMA then works just fine through VLAN interfaces on top of that physical interface, via the "upper device" logic. This is hard to see in the rxe logic because it never talks about vlan, but instead rxe carefully selects upper vlan netdevices when working with packets which in turn imply certain vlan tagging. This is all done correctly and interacts with the gid table with VLAN support the same as real HW does. b2d2440430c0 broke this setup deliberately and should thus be reverted. Also, b2d2440430c0 removed rxe_dma_device(), so adapt the revert to discard that hunk. Fixes: b2d2440430c0 ("RDMA/rxe: Remove VLAN code leftovers from RXE") Link: https://lore.kernel.org/r/20210120161913.7347-1-mwilck@suse.com Signed-off-by: Martin Wilck Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_net.c | 6 ++++++ drivers/infiniband/sw/rxe/rxe_resp.c | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index c4b06ced30a75..943914c2a50c7 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -153,9 +154,14 @@ static int rxe_udp_encap_recv(struct sock *sk, struct sk_buff *skb) { struct udphdr *udph; struct net_device *ndev = skb->dev; + struct net_device *rdev = ndev; struct rxe_dev *rxe = rxe_get_dev_from_net(ndev); struct rxe_pkt_info *pkt = SKB_TO_PKT(skb); + if (!rxe && is_vlan_dev(rdev)) { + rdev = vlan_dev_real_dev(ndev); + rxe = rxe_get_dev_from_net(rdev); + } if (!rxe) goto drop; diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index 5a098083a9d22..c7e3b6a4af38f 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -872,6 +872,11 @@ static enum resp_states do_complete(struct rxe_qp *qp, else wc->network_hdr_type = RDMA_NETWORK_IPV6; + if (is_vlan_dev(skb->dev)) { + wc->wc_flags |= IB_WC_WITH_VLAN; + wc->vlan_id = vlan_dev_vlan_id(skb->dev); + } + if (pkt->mask & RXE_IMMDT_MASK) { wc->wc_flags |= IB_WC_WITH_IMM; wc->ex.imm_data = immdt_imm(pkt); -- GitLab From 9275c206f88e5c49cb3e71932c81c8561083db9e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 20 Jan 2021 09:33:52 +0100 Subject: [PATCH 0395/1084] nvme-pci: refactor nvme_unmap_data Split out three helpers from nvme_unmap_data that will allow finer grained unwinding from nvme_map_data. Signed-off-by: Christoph Hellwig Reviewed-by: Keith Busch Reviewed-by: Marc Orr --- drivers/nvme/host/pci.c | 77 ++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 25456d02eddb8..e29ece9e4d4b8 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -543,50 +543,71 @@ static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req) return true; } -static void nvme_unmap_data(struct nvme_dev *dev, struct request *req) +static void nvme_free_prps(struct nvme_dev *dev, struct request *req) { - struct nvme_iod *iod = blk_mq_rq_to_pdu(req); const int last_prp = NVME_CTRL_PAGE_SIZE / sizeof(__le64) - 1; - dma_addr_t dma_addr = iod->first_dma, next_dma_addr; + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + dma_addr_t dma_addr = iod->first_dma; int i; - if (iod->dma_len) { - dma_unmap_page(dev->dev, dma_addr, iod->dma_len, - rq_dma_dir(req)); - return; + for (i = 0; i < iod->npages; i++) { + __le64 *prp_list = nvme_pci_iod_list(req)[i]; + dma_addr_t next_dma_addr = le64_to_cpu(prp_list[last_prp]); + + dma_pool_free(dev->prp_page_pool, prp_list, dma_addr); + dma_addr = next_dma_addr; } - WARN_ON_ONCE(!iod->nents); +} - if (is_pci_p2pdma_page(sg_page(iod->sg))) - pci_p2pdma_unmap_sg(dev->dev, iod->sg, iod->nents, - rq_dma_dir(req)); - else - dma_unmap_sg(dev->dev, iod->sg, iod->nents, rq_dma_dir(req)); +static void nvme_free_sgls(struct nvme_dev *dev, struct request *req) +{ + const int last_sg = SGES_PER_PAGE - 1; + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + dma_addr_t dma_addr = iod->first_dma; + int i; + for (i = 0; i < iod->npages; i++) { + struct nvme_sgl_desc *sg_list = nvme_pci_iod_list(req)[i]; + dma_addr_t next_dma_addr = le64_to_cpu((sg_list[last_sg]).addr); - if (iod->npages == 0) - dma_pool_free(dev->prp_small_pool, nvme_pci_iod_list(req)[0], - dma_addr); + dma_pool_free(dev->prp_page_pool, sg_list, dma_addr); + dma_addr = next_dma_addr; + } - for (i = 0; i < iod->npages; i++) { - void *addr = nvme_pci_iod_list(req)[i]; +} - if (iod->use_sgl) { - struct nvme_sgl_desc *sg_list = addr; +static void nvme_unmap_sg(struct nvme_dev *dev, struct request *req) +{ + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - next_dma_addr = - le64_to_cpu((sg_list[SGES_PER_PAGE - 1]).addr); - } else { - __le64 *prp_list = addr; + if (is_pci_p2pdma_page(sg_page(iod->sg))) + pci_p2pdma_unmap_sg(dev->dev, iod->sg, iod->nents, + rq_dma_dir(req)); + else + dma_unmap_sg(dev->dev, iod->sg, iod->nents, rq_dma_dir(req)); +} - next_dma_addr = le64_to_cpu(prp_list[last_prp]); - } +static void nvme_unmap_data(struct nvme_dev *dev, struct request *req) +{ + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - dma_pool_free(dev->prp_page_pool, addr, dma_addr); - dma_addr = next_dma_addr; + if (iod->dma_len) { + dma_unmap_page(dev->dev, iod->first_dma, iod->dma_len, + rq_dma_dir(req)); + return; } + WARN_ON_ONCE(!iod->nents); + + nvme_unmap_sg(dev, req); + if (iod->npages == 0) + dma_pool_free(dev->prp_small_pool, nvme_pci_iod_list(req)[0], + iod->first_dma); + else if (iod->use_sgl) + nvme_free_sgls(dev, req); + else + nvme_free_prps(dev, req); mempool_free(iod->sg, dev->iod_mempool); } -- GitLab From fa0732168fa1369dd089e5b06d6158a68229f7b7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 20 Jan 2021 09:35:01 +0100 Subject: [PATCH 0396/1084] nvme-pci: fix error unwind in nvme_map_data Properly unwind step by step using refactored helpers from nvme_unmap_data to avoid a potential double dma_unmap on a mapping failure. Fixes: 7fe07d14f71f ("nvme-pci: merge nvme_free_iod into nvme_unmap_data") Reported-by: Marc Orr Signed-off-by: Christoph Hellwig Reviewed-by: Keith Busch Reviewed-by: Marc Orr --- drivers/nvme/host/pci.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index e29ece9e4d4b8..856aa31931c14 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -683,7 +683,7 @@ static blk_status_t nvme_pci_setup_prps(struct nvme_dev *dev, __le64 *old_prp_list = prp_list; prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma); if (!prp_list) - return BLK_STS_RESOURCE; + goto free_prps; list[iod->npages++] = prp_list; prp_list[0] = old_prp_list[i - 1]; old_prp_list[i - 1] = cpu_to_le64(prp_dma); @@ -703,14 +703,14 @@ static blk_status_t nvme_pci_setup_prps(struct nvme_dev *dev, dma_addr = sg_dma_address(sg); dma_len = sg_dma_len(sg); } - done: cmnd->dptr.prp1 = cpu_to_le64(sg_dma_address(iod->sg)); cmnd->dptr.prp2 = cpu_to_le64(iod->first_dma); - return BLK_STS_OK; - - bad_sgl: +free_prps: + nvme_free_prps(dev, req); + return BLK_STS_RESOURCE; +bad_sgl: WARN(DO_ONCE(nvme_print_sgl, iod->sg, iod->nents), "Invalid SGL for payload:%d nents:%d\n", blk_rq_payload_bytes(req), iod->nents); @@ -782,7 +782,7 @@ static blk_status_t nvme_pci_setup_sgls(struct nvme_dev *dev, sg_list = dma_pool_alloc(pool, GFP_ATOMIC, &sgl_dma); if (!sg_list) - return BLK_STS_RESOURCE; + goto free_sgls; i = 0; nvme_pci_iod_list(req)[iod->npages++] = sg_list; @@ -795,6 +795,9 @@ static blk_status_t nvme_pci_setup_sgls(struct nvme_dev *dev, } while (--entries > 0); return BLK_STS_OK; +free_sgls: + nvme_free_sgls(dev, req); + return BLK_STS_RESOURCE; } static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev, @@ -863,7 +866,7 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, sg_init_table(iod->sg, blk_rq_nr_phys_segments(req)); iod->nents = blk_rq_map_sg(req->q, req, iod->sg); if (!iod->nents) - goto out; + goto out_free_sg; if (is_pci_p2pdma_page(sg_page(iod->sg))) nr_mapped = pci_p2pdma_map_sg_attrs(dev->dev, iod->sg, @@ -872,16 +875,21 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, nr_mapped = dma_map_sg_attrs(dev->dev, iod->sg, iod->nents, rq_dma_dir(req), DMA_ATTR_NO_WARN); if (!nr_mapped) - goto out; + goto out_free_sg; iod->use_sgl = nvme_pci_use_sgls(dev, req); if (iod->use_sgl) ret = nvme_pci_setup_sgls(dev, req, &cmnd->rw, nr_mapped); else ret = nvme_pci_setup_prps(dev, req, &cmnd->rw); -out: if (ret != BLK_STS_OK) - nvme_unmap_data(dev, req); + goto out_unmap_sg; + return BLK_STS_OK; + +out_unmap_sg: + nvme_unmap_sg(dev, req); +out_free_sg: + mempool_free(iod->sg, dev->iod_mempool); return ret; } -- GitLab From 78a18fec5258c8df9435399a1ea022d73d3eceb9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 15 Jan 2021 22:57:52 +0100 Subject: [PATCH 0397/1084] ACPI: scan: Make acpi_bus_get_device() clear return pointer on error Set the acpi_device pointer which acpi_bus_get_device() returns-by- reference to NULL on errors. We've recently had 2 cases where callers of acpi_bus_get_device() did not properly error check the return value, so set the returned- by-reference acpi_device pointer to NULL, because at least some callers of acpi_bus_get_device() expect that to be done on errors. [ rjw: This issue was exposed by commit 71da201f38df ("ACPI: scan: Defer enumeration of devices with _DEP lists") which caused it to be much more likely to occur on some systems, but the real defect had been introduced by an earlier commit. ] Fixes: 40e7fcb19293 ("ACPI: Add _DEP support to fix battery issue on Asus T100TA") Fixes: bcfcd409d4db ("usb: split code locating ACPI companion into port and device") Reported-by: Pierre-Louis Bossart Tested-by: Pierre-Louis Bossart Diagnosed-by: Rafael J. Wysocki Signed-off-by: Hans de Goede Cc: All applicable [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 58ff36340cd7c..1db063b02f63e 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -586,6 +586,8 @@ static int acpi_get_device_data(acpi_handle handle, struct acpi_device **device, if (!device) return -EINVAL; + *device = NULL; + status = acpi_get_data_full(handle, acpi_scan_drop_device, (void **)device, callback); if (ACPI_FAILURE(status) || !*device) { -- GitLab From 4e37528a97bfffb2cd4f645c945759e76d583848 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 20 Jan 2021 16:08:46 +0800 Subject: [PATCH 0398/1084] ASoC: mediatek: mt8192-mt6359: move headset_jack to card specific data Moves headset_jack to card specific data. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210120080850.699354-2-tzungbi@google.com Signed-off-by: Mark Brown --- .../mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index a988ce1e58de6..72d337fc8534b 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -31,7 +31,9 @@ #define RT5682_CODEC_DAI "rt5682-aif1" #define RT5682_DEV0_NAME "rt5682.1-001a" -static struct snd_soc_jack headset_jack; +struct mt8192_mt6359_priv { + struct snd_soc_jack headset_jack; +}; static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -305,7 +307,8 @@ static int mt8192_rt5682_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *cmpnt_codec = asoc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_jack *jack = &headset_jack; + struct mt8192_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &priv->headset_jack; int ret; ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", @@ -1038,6 +1041,7 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) int ret, i; struct snd_soc_dai_link *dai_link; const struct of_device_id *match; + struct mt8192_mt6359_priv *priv; platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); @@ -1083,6 +1087,11 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) dai_link->platforms->of_node = platform_node; } + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + snd_soc_card_set_drvdata(card, priv); + ret = mt8192_afe_gpio_init(&pdev->dev); if (ret) { dev_err(&pdev->dev, "init gpio error %d\n", ret); -- GitLab From 12295ef97078db19683d8c0a23abc6f633ef0e23 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 20 Jan 2021 16:08:47 +0800 Subject: [PATCH 0399/1084] ASoC: mediatek: mt8192-mt6359: simplify mt8192_rt5682_init Returns snd_soc_component_set_jack() directly in mt8192_rt5682_init. No need to have another block to check the return value. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210120080850.699354-3-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index 72d337fc8534b..8ea24b32a535a 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -326,13 +326,7 @@ static int mt8192_rt5682_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); - ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL); - if (ret) { - dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret); - return ret; - } - - return 0; + return snd_soc_component_set_jack(cmpnt_codec, jack, NULL); }; static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, -- GitLab From df369921d726410a093de48d33e605fd4e0ee33c Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 20 Jan 2021 16:08:48 +0800 Subject: [PATCH 0400/1084] ASoC: mediatek: mt8192: change mclk_multiple of TDM from 128 to 512 mclk = rate * mclk_multiple bclk = rate * channel * sample_width If TDM outputs 8 channels and 32 bits, bclk will be greater than mclk. Changes the ratio from 128 to 512. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210120080850.699354-4-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8192/mt8192-dai-tdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-dai-tdm.c b/sound/soc/mediatek/mt8192/mt8192-dai-tdm.c index 8383536b7ae00..f5de1d7696792 100644 --- a/sound/soc/mediatek/mt8192/mt8192-dai-tdm.c +++ b/sound/soc/mediatek/mt8192/mt8192-dai-tdm.c @@ -738,7 +738,7 @@ static struct mtk_afe_tdm_priv *init_tdm_priv_data(struct mtk_base_afe *afe) if (!tdm_priv) return NULL; - tdm_priv->mclk_multiple = 128; + tdm_priv->mclk_multiple = 512; tdm_priv->bck_id = MT8192_I2S4_BCK; tdm_priv->mclk_id = MT8192_I2S4_MCK; tdm_priv->id = MT8192_DAI_TDM; -- GitLab From 9bc20e8076c96a54c9fb20228d12ff35c88447d5 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 20 Jan 2021 16:08:49 +0800 Subject: [PATCH 0401/1084] ASoC: dt-bindings: mt8192-mt6359: add hdmi-codec property Adds optional property "hdmi-codec". If specified, the machine driver should: - Exposes a device that can write audio data to the DP bridge. - Detects jack plug events. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210120080850.699354-5-tzungbi@google.com Signed-off-by: Mark Brown --- .../bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml b/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml index bf8c8ba25009d..a781e7aaaa384 100644 --- a/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml +++ b/Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml @@ -23,6 +23,10 @@ properties: $ref: "/schemas/types.yaml#/definitions/phandle" description: The phandle of MT8192 ASoC platform. + mediatek,hdmi-codec: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of HDMI codec. + additionalProperties: false required: @@ -35,6 +39,7 @@ examples: sound: mt8192-sound { compatible = "mediatek,mt8192_mt6359_rt1015_rt5682"; mediatek,platform = <&afe>; + mediatek,hdmi-codec = <&anx_bridge_dp>; pinctrl-names = "aud_clk_mosi_off", "aud_clk_mosi_on"; pinctrl-0 = <&aud_clk_mosi_off>; -- GitLab From 0d80c48c847842de488e76ae434ccb74397623c3 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 20 Jan 2021 16:08:50 +0800 Subject: [PATCH 0402/1084] ASoC: mediatek: mt8192-mt6359: support audio over DP If the DTS property is specified, the DP bridge should populate a "hdmi-codec" platform device (sound/soc/codecs/hdmi-codec.c). The "hdmi-codec" device is the communication relayer between the ASoC machine driver and the DP bridge. For example: - Notifies DP bridge when setting hw_param. - Notifies ASoC when jack detection events. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210120080850.699354-6-tzungbi@google.com Signed-off-by: Mark Brown --- .../mt8192/mt8192-mt6359-rt1015-rt5682.c | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index 8ea24b32a535a..cc0fc72305d22 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -33,6 +33,7 @@ struct mt8192_mt6359_priv { struct snd_soc_jack headset_jack; + struct snd_soc_jack hdmi_jack; }; static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, @@ -329,6 +330,23 @@ static int mt8192_rt5682_init(struct snd_soc_pcm_runtime *rtd) return snd_soc_component_set_jack(cmpnt_codec, jack, NULL); }; +static int mt8192_mt6359_hdmi_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *cmpnt_codec = + asoc_rtd_to_codec(rtd, 0)->component; + struct mt8192_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); + int ret; + + ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, + &priv->hdmi_jack, NULL, 0); + if (ret) { + dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret); + return ret; + } + + return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); +} + static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -600,7 +618,7 @@ SND_SOC_DAILINK_DEFS(pcm2, SND_SOC_DAILINK_DEFS(tdm, DAILINK_COMP_ARRAY(COMP_CPU("TDM")), - DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")), DAILINK_COMP_ARRAY(COMP_EMPTY())); static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = { @@ -936,8 +954,14 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = { { .name = "TDM", .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_DSP_A | + SND_SOC_DAIFMT_IB_NF | + SND_SOC_DAIFMT_CBM_CFM, .dpcm_playback = 1, .ignore_suspend = 1, + .be_hw_params_fixup = mt8192_i2s_hw_params_fixup, + .ignore = 1, + .init = mt8192_mt6359_hdmi_init, SND_SOC_DAILINK_REG(tdm), }, }; @@ -948,6 +972,7 @@ mt8192_mt6359_rt1015_rt5682_widgets[] = { SND_SOC_DAPM_SPK("Right Spk", NULL), SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_OUTPUT("TDM Out"), }; static const struct snd_soc_dapm_route mt8192_mt6359_rt1015_rt5682_routes[] = { @@ -958,6 +983,8 @@ static const struct snd_soc_dapm_route mt8192_mt6359_rt1015_rt5682_routes[] = { { "Headphone Jack", NULL, "HPOL" }, { "Headphone Jack", NULL, "HPOR" }, { "IN1P", NULL, "Headset Mic" }, + /* TDM */ + { "TDM Out", NULL, "TDM" }, }; static const struct snd_kcontrol_new mt8192_mt6359_rt1015_rt5682_controls[] = { @@ -1031,7 +1058,7 @@ static struct snd_soc_card mt8192_mt6359_rt1015p_rt5682_card = { static int mt8192_mt6359_dev_probe(struct platform_device *pdev) { struct snd_soc_card *card; - struct device_node *platform_node; + struct device_node *platform_node, *hdmi_codec; int ret, i; struct snd_soc_dai_link *dai_link; const struct of_device_id *match; @@ -1051,6 +1078,9 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) card = (struct snd_soc_card *)match->data; card->dev = &pdev->dev; + hdmi_codec = of_parse_phandle(pdev->dev.of_node, + "mediatek,hdmi-codec", 0); + for_each_card_prelinks(card, i, dai_link) { if (strcmp(dai_link->name, "I2S3") == 0) { if (card == &mt8192_mt6359_rt1015_rt5682_card) { @@ -1077,6 +1107,11 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) } } + if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) { + dai_link->codecs->of_node = hdmi_codec; + dai_link->ignore = 0; + } + if (!dai_link->platforms->name) dai_link->platforms->of_node = platform_node; } -- GitLab From 9ce63203eb2071fe0117d2e2454c19d79af4a2f1 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 18 Jan 2021 09:38:10 -0300 Subject: [PATCH 0403/1084] ASoC: fsl_ssi: Use of_device_get_match_data() The retrieval of driver data via of_device_get_match_data() can make the code simpler. Use of_device_get_match_data() to simplify the code. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210118123815.1630882-1-festevam@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 404be27c15fed..db4ba5f22b774 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1397,18 +1397,11 @@ static int fsl_ssi_probe_from_dt(struct fsl_ssi *ssi) { struct device *dev = ssi->dev; struct device_node *np = dev->of_node; - const struct of_device_id *of_id; const char *p, *sprop; const __be32 *iprop; u32 dmas[4]; int ret; - of_id = of_match_device(fsl_ssi_ids, dev); - if (!of_id || !of_id->data) - return -EINVAL; - - ssi->soc = of_id->data; - ret = of_property_match_string(np, "clock-names", "ipg"); /* Get error code if not found */ ssi->has_ipg_clk_name = ret >= 0; @@ -1492,6 +1485,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) return -ENOMEM; ssi->dev = dev; + ssi->soc = of_device_get_match_data(&pdev->dev); /* Probe from DT */ ret = fsl_ssi_probe_from_dt(ssi); -- GitLab From d7388718d491463ed0fb7383a4c678b94fdda785 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 18 Jan 2021 09:38:11 -0300 Subject: [PATCH 0404/1084] ASoC: fsl_micfil: Use of_device_get_match_data() The retrieval of driver data via of_device_get_match_data() can make the code simpler. Use of_device_get_match_data() to simplify the code. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210118123815.1630882-2-festevam@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index efc5daf53bbae..8aedf6590b289 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -637,7 +637,6 @@ static irqreturn_t micfil_err_isr(int irq, void *devid) static int fsl_micfil_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - const struct of_device_id *of_id; struct fsl_micfil *micfil; struct resource *res; void __iomem *regs; @@ -651,11 +650,7 @@ static int fsl_micfil_probe(struct platform_device *pdev) micfil->pdev = pdev; strncpy(micfil->name, np->name, sizeof(micfil->name) - 1); - of_id = of_match_device(fsl_micfil_dt_ids, &pdev->dev); - if (!of_id || !of_id->data) - return -EINVAL; - - micfil->soc = of_id->data; + micfil->soc = of_device_get_match_data(&pdev->dev); /* ipg_clk is used to control the registers * ipg_clk_app is used to operate the filter -- GitLab From 42450175a3d21d0818976114833d23ca5035e713 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 18 Jan 2021 09:38:12 -0300 Subject: [PATCH 0405/1084] ASoC: fsl_xcvr: Remove unused of_id variable The of_id variable is not used, so just remove it. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210118123815.1630882-3-festevam@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_xcvr.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index 3d58c88ea603d..dd228b421e2c5 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -1130,16 +1130,11 @@ MODULE_DEVICE_TABLE(of, fsl_xcvr_dt_ids); static int fsl_xcvr_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - const struct of_device_id *of_id; struct fsl_xcvr *xcvr; struct resource *ram_res, *regs_res, *rx_res, *tx_res; void __iomem *regs; int ret, irq; - of_id = of_match_device(fsl_xcvr_dt_ids, dev); - if (!of_id) - return -EINVAL; - xcvr = devm_kzalloc(dev, sizeof(*xcvr), GFP_KERNEL); if (!xcvr) return -ENOMEM; -- GitLab From 214172a9ca26f77c3d6912f97246dc6ec9b16141 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 18 Jan 2021 09:38:13 -0300 Subject: [PATCH 0406/1084] ASoC: fsl_asrc: Remove of_device_get_match_data() error check The only way this driver can be probed is via devicetree, which always provides driver data. Remove the unneeded of_device_get_match_data() error check, as it can never fail. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210118123815.1630882-4-festevam@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_asrc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 02c81d2e34ad0..c325c984d1659 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -1083,11 +1083,6 @@ static int fsl_asrc_probe(struct platform_device *pdev) } asrc_priv->soc = of_device_get_match_data(&pdev->dev); - if (!asrc_priv->soc) { - dev_err(&pdev->dev, "failed to get soc data\n"); - return -ENODEV; - } - asrc->use_edma = asrc_priv->soc->use_edma; asrc->get_dma_channel = fsl_asrc_get_dma_channel; asrc->request_pair = fsl_asrc_request_pair; -- GitLab From 1ccf6e6ef9261c0c8c0be495070c45c030adcc40 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 18 Jan 2021 09:38:14 -0300 Subject: [PATCH 0407/1084] ASoC: fsl_esai: Remove of_device_get_match_data() error check The only way this driver can be probed is via devicetree, which always provides driver data. Remove the unneeded of_device_get_match_data() error check, as it can never fail. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210118123815.1630882-5-festevam@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 39637ca78cdbb..614e22a95f537 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -967,10 +967,6 @@ static int fsl_esai_probe(struct platform_device *pdev) snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np); esai_priv->soc = of_device_get_match_data(&pdev->dev); - if (!esai_priv->soc) { - dev_err(&pdev->dev, "failed to get soc data\n"); - return -ENODEV; - } /* Get the addresses and IRQ */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- GitLab From 4e63b56593e25937f22c01ae60574a3b0548553c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 18 Jan 2021 09:38:15 -0300 Subject: [PATCH 0408/1084] ASoC: fsl_spdif: Remove of_device_get_match_data() error check The only way this driver can be probed is via devicetree, which always provides driver data. Remove the unneeded of_device_get_match_data() error check, as it can never fail. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210118123815.1630882-6-festevam@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 5fa178f3f4977..b4d3b04694bff 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1305,10 +1305,6 @@ static int fsl_spdif_probe(struct platform_device *pdev) spdif_priv->pdev = pdev; spdif_priv->soc = of_device_get_match_data(&pdev->dev); - if (!spdif_priv->soc) { - dev_err(&pdev->dev, "failed to get soc data\n"); - return -ENODEV; - } /* Initialize this copy of the CPU DAI driver structure */ memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); -- GitLab From db58465f1121086b524be80be39d1fedbe5387f3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 20 Jan 2021 16:11:12 +0000 Subject: [PATCH 0409/1084] cachefiles: Drop superfluous readpages aops NULL check After the recent actions to convert readpages aops to readahead, the NULL checks of readpages aops in cachefiles_read_or_alloc_page() may hit falsely. More badly, it's an ASSERT() call, and this panics. Drop the superfluous NULL checks for fixing this regression. [DH: Note that cachefiles never actually used readpages, so this check was never actually necessary] BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208883 BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1175245 Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem") Signed-off-by: Takashi Iwai Signed-off-by: David Howells Acked-by: Matthew Wilcox (Oracle) Signed-off-by: Linus Torvalds --- fs/cachefiles/rdwr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 8bda092e60c5a..e027c718ca01a 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -413,7 +413,6 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, inode = d_backing_inode(object->backer); ASSERT(S_ISREG(inode->i_mode)); - ASSERT(inode->i_mapping->a_ops->readpages); /* calculate the shift required to use bmap */ shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits; @@ -713,7 +712,6 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op, inode = d_backing_inode(object->backer); ASSERT(S_ISREG(inode->i_mode)); - ASSERT(inode->i_mapping->a_ops->readpages); /* calculate the shift required to use bmap */ shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits; -- GitLab From 7178a107f5ea7bdb1cc23073234f0ded0ef90ec7 Mon Sep 17 00:00:00 2001 From: Tianjia Zhang Date: Tue, 19 Jan 2021 00:13:19 +0000 Subject: [PATCH 0410/1084] X.509: Fix crash caused by NULL pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the following call path, `sig->pkey_algo` is not assigned in asymmetric_key_verify_signature(), which causes runtime crash in public_key_verify_signature(). keyctl_pkey_verify asymmetric_key_verify_signature verify_signature public_key_verify_signature This patch simply check this situation and fixes the crash caused by NULL pointer. Fixes: 215525639631 ("X.509: support OSCCA SM2-with-SM3 certificate verification") Reported-by: Tobias Markus Signed-off-by: Tianjia Zhang Signed-off-by: David Howells Reviewed-and-tested-by: Toke Høiland-Jørgensen Tested-by: João Fonseca Acked-by: Jarkko Sakkinen Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Linus Torvalds --- crypto/asymmetric_keys/public_key.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 8892908ad58ce..788a4ba1e2e74 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -356,7 +356,8 @@ int public_key_verify_signature(const struct public_key *pkey, if (ret) goto error_free_key; - if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) { + if (sig->pkey_algo && strcmp(sig->pkey_algo, "sm2") == 0 && + sig->data_size) { ret = cert_sig_digest_update(sig, tfm); if (ret) goto error_free_key; -- GitLab From 61fbeb5dcb3debb88d9f2eeed7e599b1ed7e3344 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:25:52 +0100 Subject: [PATCH 0411/1084] ASoC: remove sirf prima/atlas drivers The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Signed-off-by: Arnd Bergmann Acked-by: Barry Song Link: https://lore.kernel.org/r/20210120162553.21666-2-arnd@kernel.org Signed-off-by: Mark Brown --- .../bindings/sound/sirf-audio-codec.txt | 17 - .../devicetree/bindings/sound/sirf-usp.txt | 27 - sound/soc/Kconfig | 1 - sound/soc/Makefile | 1 - sound/soc/codecs/Makefile | 2 - sound/soc/codecs/sirf-audio-codec.c | 575 ------------------ sound/soc/sirf/Kconfig | 21 - sound/soc/sirf/Makefile | 8 - sound/soc/sirf/sirf-audio-port.c | 86 --- sound/soc/sirf/sirf-audio.c | 160 ----- sound/soc/sirf/sirf-usp.c | 435 ------------- sound/soc/sirf/sirf-usp.h | 292 --------- 12 files changed, 1625 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/sirf-audio-codec.txt delete mode 100644 Documentation/devicetree/bindings/sound/sirf-usp.txt delete mode 100644 sound/soc/codecs/sirf-audio-codec.c delete mode 100644 sound/soc/sirf/Kconfig delete mode 100644 sound/soc/sirf/Makefile delete mode 100644 sound/soc/sirf/sirf-audio-port.c delete mode 100644 sound/soc/sirf/sirf-audio.c delete mode 100644 sound/soc/sirf/sirf-usp.c delete mode 100644 sound/soc/sirf/sirf-usp.h diff --git a/Documentation/devicetree/bindings/sound/sirf-audio-codec.txt b/Documentation/devicetree/bindings/sound/sirf-audio-codec.txt deleted file mode 100644 index 062f5ec36f9b6..0000000000000 --- a/Documentation/devicetree/bindings/sound/sirf-audio-codec.txt +++ /dev/null @@ -1,17 +0,0 @@ -SiRF internal audio CODEC - -Required properties: - - - compatible : "sirf,atlas6-audio-codec" or "sirf,prima2-audio-codec" - - - reg : the register address of the device. - - - clocks: the clock of SiRF internal audio codec - -Example: - -audiocodec: audiocodec@b0040000 { - compatible = "sirf,atlas6-audio-codec"; - reg = <0xb0040000 0x10000>; - clocks = <&clks 27>; -}; diff --git a/Documentation/devicetree/bindings/sound/sirf-usp.txt b/Documentation/devicetree/bindings/sound/sirf-usp.txt deleted file mode 100644 index 02f85b32d3598..0000000000000 --- a/Documentation/devicetree/bindings/sound/sirf-usp.txt +++ /dev/null @@ -1,27 +0,0 @@ -* SiRF SoC USP module - -Required properties: -- compatible: "sirf,prima2-usp-pcm" -- reg: Base address and size entries: -- dmas: List of DMA controller phandle and DMA request line ordered pairs. -- dma-names: Identifier string for each DMA request line in the dmas property. - These strings correspond 1:1 with the ordered pairs in dmas. - - One of the DMA channels will be responsible for transmission (should be - named "tx") and one for reception (should be named "rx"). - -- clocks: USP controller clock source -- pinctrl-names: Must contain a "default" entry. -- pinctrl-NNN: One property must exist for each entry in pinctrl-names. - -Example: -usp0: usp@b0080000 { - compatible = "sirf,prima2-usp-pcm"; - reg = <0xb0080000 0x10000>; - clocks = <&clks 28>; - dmas = <&dmac1 1>, <&dmac1 2>; - dma-names = "rx", "tx"; - pinctrl-names = "default"; - pinctrl-0 = <&usp0_only_utfs_pins_a>; -}; - diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 47da9ce176933..547b26ca714f5 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -62,7 +62,6 @@ source "sound/soc/qcom/Kconfig" source "sound/soc/rockchip/Kconfig" source "sound/soc/samsung/Kconfig" source "sound/soc/sh/Kconfig" -source "sound/soc/sirf/Kconfig" source "sound/soc/sof/Kconfig" source "sound/soc/spear/Kconfig" source "sound/soc/sprd/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 508dbaa1814ec..74508b0f9c477 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_SND_SOC) += qcom/ obj-$(CONFIG_SND_SOC) += rockchip/ obj-$(CONFIG_SND_SOC) += samsung/ obj-$(CONFIG_SND_SOC) += sh/ -obj-$(CONFIG_SND_SOC) += sirf/ obj-$(CONFIG_SND_SOC) += sof/ obj-$(CONFIG_SND_SOC) += spear/ obj-$(CONFIG_SND_SOC) += sprd/ diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index d277f0366e096..c30762fc9b878 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -201,7 +201,6 @@ snd-soc-sigmadsp-objs := sigmadsp.o snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o snd-soc-si476x-objs := si476x.o -snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o snd-soc-spdif-tx-objs := spdif_transmitter.o snd-soc-spdif-rx-objs := spdif_receiver.o snd-soc-ssm2305-objs := ssm2305.o @@ -516,7 +515,6 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o -obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o obj-$(CONFIG_SND_SOC_SSM2305) += snd-soc-ssm2305.o obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c deleted file mode 100644 index a061d78473ac4..0000000000000 --- a/sound/soc/codecs/sirf-audio-codec.c +++ /dev/null @@ -1,575 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SiRF audio codec driver - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sirf-audio-codec.h" - -struct sirf_audio_codec { - struct clk *clk; - struct regmap *regmap; - u32 reg_ctrl0, reg_ctrl1; -}; - -static const char * const input_mode_mux[] = {"Single-ended", - "Differential"}; - -static const struct soc_enum input_mode_mux_enum = - SOC_ENUM_SINGLE(AUDIO_IC_CODEC_CTRL1, 4, 2, input_mode_mux); - -static const struct snd_kcontrol_new sirf_audio_codec_input_mode_control = - SOC_DAPM_ENUM("Route", input_mode_mux_enum); - -static const DECLARE_TLV_DB_SCALE(playback_vol_tlv, -12400, 100, 0); -static const DECLARE_TLV_DB_SCALE(capture_vol_tlv_prima2, 500, 100, 0); -static const DECLARE_TLV_DB_RANGE(capture_vol_tlv_atlas6, - 0, 7, TLV_DB_SCALE_ITEM(-100, 100, 0), - 0x22, 0x3F, TLV_DB_SCALE_ITEM(700, 100, 0), -); - -static struct snd_kcontrol_new volume_controls_atlas6[] = { - SOC_DOUBLE_TLV("Playback Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, - 0x7F, 0, playback_vol_tlv), - SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 16, 10, - 0x3F, 0, capture_vol_tlv_atlas6), -}; - -static struct snd_kcontrol_new volume_controls_prima2[] = { - SOC_DOUBLE_TLV("Speaker Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, - 0x7F, 0, playback_vol_tlv), - SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 15, 10, - 0x1F, 0, capture_vol_tlv_prima2), -}; - -static struct snd_kcontrol_new left_input_path_controls[] = { - SOC_DAPM_SINGLE("Line Left Switch", AUDIO_IC_CODEC_CTRL1, 6, 1, 0), - SOC_DAPM_SINGLE("Mic Left Switch", AUDIO_IC_CODEC_CTRL1, 3, 1, 0), -}; - -static struct snd_kcontrol_new right_input_path_controls[] = { - SOC_DAPM_SINGLE("Line Right Switch", AUDIO_IC_CODEC_CTRL1, 5, 1, 0), - SOC_DAPM_SINGLE("Mic Right Switch", AUDIO_IC_CODEC_CTRL1, 2, 1, 0), -}; - -static struct snd_kcontrol_new left_dac_to_hp_left_amp_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 9, 1, 0); - -static struct snd_kcontrol_new left_dac_to_hp_right_amp_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 8, 1, 0); - -static struct snd_kcontrol_new right_dac_to_hp_left_amp_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 7, 1, 0); - -static struct snd_kcontrol_new right_dac_to_hp_right_amp_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 6, 1, 0); - -static struct snd_kcontrol_new left_dac_to_speaker_lineout_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 11, 1, 0); - -static struct snd_kcontrol_new right_dac_to_speaker_lineout_switch_control = - SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 10, 1, 0); - -/* After enable adc, Delay 200ms to avoid pop noise */ -static int adc_enable_delay_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - switch (event) { - case SND_SOC_DAPM_POST_PMU: - msleep(200); - break; - default: - break; - } - - return 0; -} - -static void enable_and_reset_codec(struct regmap *regmap, - u32 codec_enable_bits, u32 codec_reset_bits) -{ - regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, - codec_enable_bits | codec_reset_bits, - codec_enable_bits); - msleep(20); - regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, - codec_reset_bits, codec_reset_bits); -} - -static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ -#define ATLAS6_CODEC_ENABLE_BITS (1 << 29) -#define ATLAS6_CODEC_RESET_BITS (1 << 28) - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - enable_and_reset_codec(sirf_audio_codec->regmap, - ATLAS6_CODEC_ENABLE_BITS, ATLAS6_CODEC_RESET_BITS); - break; - case SND_SOC_DAPM_POST_PMD: - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_IC_CODEC_CTRL1, ATLAS6_CODEC_ENABLE_BITS, 0); - break; - default: - break; - } - - return 0; -} - -static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ -#define PRIMA2_CODEC_ENABLE_BITS (1 << 27) -#define PRIMA2_CODEC_RESET_BITS (1 << 26) - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component); - switch (event) { - case SND_SOC_DAPM_POST_PMU: - enable_and_reset_codec(sirf_audio_codec->regmap, - PRIMA2_CODEC_ENABLE_BITS, PRIMA2_CODEC_RESET_BITS); - break; - case SND_SOC_DAPM_POST_PMD: - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_IC_CODEC_CTRL1, PRIMA2_CODEC_ENABLE_BITS, 0); - break; - default: - break; - } - - return 0; -} - -static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets[] = { - SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, - 25, 0, NULL, 0), - SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, - 26, 0, NULL, 0), - SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, - 27, 0, NULL, 0), -}; - -static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets[] = { - SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, - 23, 0, NULL, 0), - SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, - 24, 0, NULL, 0), - SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, - 25, 0, NULL, 0), -}; - -static const struct snd_soc_dapm_widget atlas6_codec_clock_dapm_widget = - SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, - atlas6_codec_enable_and_reset_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); - -static const struct snd_soc_dapm_widget prima2_codec_clock_dapm_widget = - SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, - prima2_codec_enable_and_reset_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); - -static const struct snd_soc_dapm_widget sirf_audio_codec_dapm_widgets[] = { - SND_SOC_DAPM_DAC("DAC left", NULL, AUDIO_IC_CODEC_CTRL0, 1, 0), - SND_SOC_DAPM_DAC("DAC right", NULL, AUDIO_IC_CODEC_CTRL0, 0, 0), - SND_SOC_DAPM_SWITCH("Left dac to hp left amp", SND_SOC_NOPM, 0, 0, - &left_dac_to_hp_left_amp_switch_control), - SND_SOC_DAPM_SWITCH("Left dac to hp right amp", SND_SOC_NOPM, 0, 0, - &left_dac_to_hp_right_amp_switch_control), - SND_SOC_DAPM_SWITCH("Right dac to hp left amp", SND_SOC_NOPM, 0, 0, - &right_dac_to_hp_left_amp_switch_control), - SND_SOC_DAPM_SWITCH("Right dac to hp right amp", SND_SOC_NOPM, 0, 0, - &right_dac_to_hp_right_amp_switch_control), - SND_SOC_DAPM_OUT_DRV("HP amp left driver", AUDIO_IC_CODEC_CTRL0, 3, 0, - NULL, 0), - SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0, 3, 0, - NULL, 0), - - SND_SOC_DAPM_SWITCH("Left dac to speaker lineout", SND_SOC_NOPM, 0, 0, - &left_dac_to_speaker_lineout_switch_control), - SND_SOC_DAPM_SWITCH("Right dac to speaker lineout", SND_SOC_NOPM, 0, 0, - &right_dac_to_speaker_lineout_switch_control), - SND_SOC_DAPM_OUT_DRV("Speaker amp driver", AUDIO_IC_CODEC_CTRL0, 4, 0, - NULL, 0), - - SND_SOC_DAPM_OUTPUT("HPOUTL"), - SND_SOC_DAPM_OUTPUT("HPOUTR"), - SND_SOC_DAPM_OUTPUT("SPKOUT"), - - SND_SOC_DAPM_ADC_E("ADC left", NULL, AUDIO_IC_CODEC_CTRL1, 8, 0, - adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("ADC right", NULL, AUDIO_IC_CODEC_CTRL1, 7, 0, - adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_MIXER("Left PGA mixer", AUDIO_IC_CODEC_CTRL1, 1, 0, - &left_input_path_controls[0], - ARRAY_SIZE(left_input_path_controls)), - SND_SOC_DAPM_MIXER("Right PGA mixer", AUDIO_IC_CODEC_CTRL1, 0, 0, - &right_input_path_controls[0], - ARRAY_SIZE(right_input_path_controls)), - - SND_SOC_DAPM_MUX("Mic input mode mux", SND_SOC_NOPM, 0, 0, - &sirf_audio_codec_input_mode_control), - SND_SOC_DAPM_MICBIAS("Mic Bias", AUDIO_IC_CODEC_PWR, 3, 0), - SND_SOC_DAPM_INPUT("MICIN1"), - SND_SOC_DAPM_INPUT("MICIN2"), - SND_SOC_DAPM_INPUT("LINEIN1"), - SND_SOC_DAPM_INPUT("LINEIN2"), - - SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0, - 30, 0, NULL, 0), -}; - -static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { - {"SPKOUT", NULL, "Speaker Driver"}, - {"Speaker Driver", NULL, "Speaker amp driver"}, - {"Speaker amp driver", NULL, "Left dac to speaker lineout"}, - {"Speaker amp driver", NULL, "Right dac to speaker lineout"}, - {"Left dac to speaker lineout", "Switch", "DAC left"}, - {"Right dac to speaker lineout", "Switch", "DAC right"}, - {"HPOUTL", NULL, "HP Left Driver"}, - {"HPOUTR", NULL, "HP Right Driver"}, - {"HP Left Driver", NULL, "HP amp left driver"}, - {"HP Right Driver", NULL, "HP amp right driver"}, - {"HP amp left driver", NULL, "Right dac to hp left amp"}, - {"HP amp right driver", NULL , "Right dac to hp right amp"}, - {"HP amp left driver", NULL, "Left dac to hp left amp"}, - {"HP amp right driver", NULL , "Right dac to hp right amp"}, - {"Right dac to hp left amp", "Switch", "DAC left"}, - {"Right dac to hp right amp", "Switch", "DAC right"}, - {"Left dac to hp left amp", "Switch", "DAC left"}, - {"Left dac to hp right amp", "Switch", "DAC right"}, - {"DAC left", NULL, "codecclk"}, - {"DAC right", NULL, "codecclk"}, - {"DAC left", NULL, "Playback"}, - {"DAC right", NULL, "Playback"}, - {"DAC left", NULL, "HSL Phase Opposite"}, - {"DAC right", NULL, "HSL Phase Opposite"}, - - {"Capture", NULL, "ADC left"}, - {"Capture", NULL, "ADC right"}, - {"ADC left", NULL, "codecclk"}, - {"ADC right", NULL, "codecclk"}, - {"ADC left", NULL, "Left PGA mixer"}, - {"ADC right", NULL, "Right PGA mixer"}, - {"Left PGA mixer", "Line Left Switch", "LINEIN2"}, - {"Right PGA mixer", "Line Right Switch", "LINEIN1"}, - {"Left PGA mixer", "Mic Left Switch", "MICIN2"}, - {"Right PGA mixer", "Mic Right Switch", "Mic input mode mux"}, - {"Mic input mode mux", "Single-ended", "MICIN1"}, - {"Mic input mode mux", "Differential", "MICIN1"}, -}; - -static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec) -{ - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); - regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); - regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_START, AUDIO_FIFO_START); - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE); -} - -static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec) -{ - regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE); -} - -static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec, - int channels) -{ - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); - regmap_write(sirf_audio_codec->regmap, - AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); - regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_START, AUDIO_FIFO_START); - if (channels == 1) - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); - else - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); -} - -static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec) -{ - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); -} - -static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, - int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_component *component = dai->component; - struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component); - int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - - /* - * This is a workaround, When stop playback, - * need disable HP amp, avoid the current noise. - */ - switch (cmd) { - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (playback) { - snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0, - IC_HSLEN | IC_HSREN, 0); - sirf_audio_codec_tx_disable(sirf_audio_codec); - } else - sirf_audio_codec_rx_disable(sirf_audio_codec); - break; - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (playback) { - sirf_audio_codec_tx_enable(sirf_audio_codec); - snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0, - IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN); - } else - sirf_audio_codec_rx_enable(sirf_audio_codec, - substream->runtime->channels); - break; - default: - return -EINVAL; - } - - return 0; -} - -static const struct snd_soc_dai_ops sirf_audio_codec_dai_ops = { - .trigger = sirf_audio_codec_trigger, -}; - -static struct snd_soc_dai_driver sirf_audio_codec_dai = { - .name = "sirf-audio-codec", - .playback = { - .stream_name = "Playback", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &sirf_audio_codec_dai_ops, -}; - -static int sirf_audio_codec_probe(struct snd_soc_component *component) -{ - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); - - pm_runtime_enable(component->dev); - - if (of_device_is_compatible(component->dev->of_node, "sirf,prima2-audio-codec")) { - snd_soc_dapm_new_controls(dapm, - prima2_output_driver_dapm_widgets, - ARRAY_SIZE(prima2_output_driver_dapm_widgets)); - snd_soc_dapm_new_controls(dapm, - &prima2_codec_clock_dapm_widget, 1); - return snd_soc_add_component_controls(component, - volume_controls_prima2, - ARRAY_SIZE(volume_controls_prima2)); - } - if (of_device_is_compatible(component->dev->of_node, "sirf,atlas6-audio-codec")) { - snd_soc_dapm_new_controls(dapm, - atlas6_output_driver_dapm_widgets, - ARRAY_SIZE(atlas6_output_driver_dapm_widgets)); - snd_soc_dapm_new_controls(dapm, - &atlas6_codec_clock_dapm_widget, 1); - return snd_soc_add_component_controls(component, - volume_controls_atlas6, - ARRAY_SIZE(volume_controls_atlas6)); - } - - return -EINVAL; -} - -static void sirf_audio_codec_remove(struct snd_soc_component *component) -{ - pm_runtime_disable(component->dev); -} - -static const struct snd_soc_component_driver soc_codec_device_sirf_audio_codec = { - .probe = sirf_audio_codec_probe, - .remove = sirf_audio_codec_remove, - .dapm_widgets = sirf_audio_codec_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets), - .dapm_routes = sirf_audio_codec_map, - .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map), - .use_pmdown_time = 1, - .endianness = 1, - .non_legacy_dai_naming = 1, -}; - -static const struct of_device_id sirf_audio_codec_of_match[] = { - { .compatible = "sirf,prima2-audio-codec" }, - { .compatible = "sirf,atlas6-audio-codec" }, - {} -}; -MODULE_DEVICE_TABLE(of, sirf_audio_codec_of_match); - -static const struct regmap_config sirf_audio_codec_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, - .cache_type = REGCACHE_NONE, -}; - -static int sirf_audio_codec_driver_probe(struct platform_device *pdev) -{ - int ret; - struct sirf_audio_codec *sirf_audio_codec; - void __iomem *base; - - sirf_audio_codec = devm_kzalloc(&pdev->dev, - sizeof(struct sirf_audio_codec), GFP_KERNEL); - if (!sirf_audio_codec) - return -ENOMEM; - - platform_set_drvdata(pdev, sirf_audio_codec); - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - - sirf_audio_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, - &sirf_audio_codec_regmap_config); - if (IS_ERR(sirf_audio_codec->regmap)) - return PTR_ERR(sirf_audio_codec->regmap); - - sirf_audio_codec->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(sirf_audio_codec->clk)) { - dev_err(&pdev->dev, "Get clock failed.\n"); - return PTR_ERR(sirf_audio_codec->clk); - } - - ret = clk_prepare_enable(sirf_audio_codec->clk); - if (ret) { - dev_err(&pdev->dev, "Enable clock failed.\n"); - return ret; - } - - ret = devm_snd_soc_register_component(&(pdev->dev), - &soc_codec_device_sirf_audio_codec, - &sirf_audio_codec_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register Audio Codec dai failed.\n"); - goto err_clk_put; - } - - /* - * Always open charge pump, if not, when the charge pump closed the - * adc will not stable - */ - regmap_update_bits(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, - IC_CPFREQ, IC_CPFREQ); - - if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas6-audio-codec")) - regmap_update_bits(sirf_audio_codec->regmap, - AUDIO_IC_CODEC_CTRL0, IC_CPEN, IC_CPEN); - return 0; - -err_clk_put: - clk_disable_unprepare(sirf_audio_codec->clk); - return ret; -} - -static int sirf_audio_codec_driver_remove(struct platform_device *pdev) -{ - struct sirf_audio_codec *sirf_audio_codec = platform_get_drvdata(pdev); - - clk_disable_unprepare(sirf_audio_codec->clk); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int sirf_audio_codec_suspend(struct device *dev) -{ - struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); - - regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, - &sirf_audio_codec->reg_ctrl0); - regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, - &sirf_audio_codec->reg_ctrl1); - clk_disable_unprepare(sirf_audio_codec->clk); - - return 0; -} - -static int sirf_audio_codec_resume(struct device *dev) -{ - struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); - int ret; - - ret = clk_prepare_enable(sirf_audio_codec->clk); - if (ret) - return ret; - - regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, - sirf_audio_codec->reg_ctrl0); - regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, - sirf_audio_codec->reg_ctrl1); - - return 0; -} -#endif - -static const struct dev_pm_ops sirf_audio_codec_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend, sirf_audio_codec_resume) -}; - -static struct platform_driver sirf_audio_codec_driver = { - .driver = { - .name = "sirf-audio-codec", - .of_match_table = sirf_audio_codec_of_match, - .pm = &sirf_audio_codec_pm_ops, - }, - .probe = sirf_audio_codec_driver_probe, - .remove = sirf_audio_codec_driver_remove, -}; - -module_platform_driver(sirf_audio_codec_driver); - -MODULE_DESCRIPTION("SiRF audio codec driver"); -MODULE_AUTHOR("RongJun Ying "); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sirf/Kconfig b/sound/soc/sirf/Kconfig deleted file mode 100644 index 094a1c89c59dc..0000000000000 --- a/sound/soc/sirf/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config SND_SOC_SIRF - tristate "SoC Audio for the SiRF SoC chips" - depends on ARCH_SIRF || COMPILE_TEST - select SND_SOC_GENERIC_DMAENGINE_PCM - -config SND_SOC_SIRF_AUDIO - tristate "SoC Audio support for SiRF internal audio codec" - depends on SND_SOC_SIRF - select SND_SOC_SIRF_AUDIO_CODEC - select SND_SOC_SIRF_AUDIO_PORT - -config SND_SOC_SIRF_AUDIO_PORT - select REGMAP_MMIO - tristate - -config SND_SOC_SIRF_USP - tristate "SoC Audio (I2S protocol) for SiRF SoC USP interface" - depends on SND_SOC_SIRF - select REGMAP_MMIO - tristate diff --git a/sound/soc/sirf/Makefile b/sound/soc/sirf/Makefile deleted file mode 100644 index 16ed11965ff9e..0000000000000 --- a/sound/soc/sirf/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -snd-soc-sirf-audio-objs := sirf-audio.o -snd-soc-sirf-audio-port-objs := sirf-audio-port.o -snd-soc-sirf-usp-objs := sirf-usp.o - -obj-$(CONFIG_SND_SOC_SIRF_AUDIO) += snd-soc-sirf-audio.o -obj-$(CONFIG_SND_SOC_SIRF_AUDIO_PORT) += snd-soc-sirf-audio-port.o -obj-$(CONFIG_SND_SOC_SIRF_USP) += snd-soc-sirf-usp.o diff --git a/sound/soc/sirf/sirf-audio-port.c b/sound/soc/sirf/sirf-audio-port.c deleted file mode 100644 index 8be2f0bc477b1..0000000000000 --- a/sound/soc/sirf/sirf-audio-port.c +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SiRF Audio port driver - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ -#include -#include -#include - -struct sirf_audio_port { - struct regmap *regmap; - struct snd_dmaengine_dai_dma_data playback_dma_data; - struct snd_dmaengine_dai_dma_data capture_dma_data; -}; - - -static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) -{ - struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); - - snd_soc_dai_init_dma_data(dai, &port->playback_dma_data, - &port->capture_dma_data); - return 0; -} - -static struct snd_soc_dai_driver sirf_audio_port_dai = { - .probe = sirf_audio_port_dai_probe, - .name = "sirf-audio-port", - .id = 0, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, -}; - -static const struct snd_soc_component_driver sirf_audio_port_component = { - .name = "sirf-audio-port", -}; - -static int sirf_audio_port_probe(struct platform_device *pdev) -{ - int ret; - struct sirf_audio_port *port; - - port = devm_kzalloc(&pdev->dev, - sizeof(struct sirf_audio_port), GFP_KERNEL); - if (!port) - return -ENOMEM; - - ret = devm_snd_soc_register_component(&pdev->dev, - &sirf_audio_port_component, &sirf_audio_port_dai, 1); - if (ret) - return ret; - - platform_set_drvdata(pdev, port); - return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); -} - -static const struct of_device_id sirf_audio_port_of_match[] = { - { .compatible = "sirf,audio-port", }, - {} -}; -MODULE_DEVICE_TABLE(of, sirf_audio_port_of_match); - -static struct platform_driver sirf_audio_port_driver = { - .driver = { - .name = "sirf-audio-port", - .of_match_table = sirf_audio_port_of_match, - }, - .probe = sirf_audio_port_probe, -}; - -module_platform_driver(sirf_audio_port_driver); - -MODULE_DESCRIPTION("SiRF Audio Port driver"); -MODULE_AUTHOR("RongJun Ying "); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sirf/sirf-audio.c b/sound/soc/sirf/sirf-audio.c deleted file mode 100644 index c923b6772b226..0000000000000 --- a/sound/soc/sirf/sirf-audio.c +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SiRF audio card driver - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct sirf_audio_card { - unsigned int gpio_hp_pa; - unsigned int gpio_spk_pa; -}; - -static int sirf_audio_hp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *ctrl, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); - int on = !SND_SOC_DAPM_EVENT_OFF(event); - - if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) - gpio_set_value(sirf_audio_card->gpio_hp_pa, on); - return 0; -} - -static int sirf_audio_spk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *ctrl, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); - int on = !SND_SOC_DAPM_EVENT_OFF(event); - - if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) - gpio_set_value(sirf_audio_card->gpio_spk_pa, on); - - return 0; -} -static const struct snd_soc_dapm_widget sirf_audio_dapm_widgets[] = { - SND_SOC_DAPM_HP("Hp", sirf_audio_hp_event), - SND_SOC_DAPM_SPK("Ext Spk", sirf_audio_spk_event), - SND_SOC_DAPM_MIC("Ext Mic", NULL), -}; - -static const struct snd_soc_dapm_route intercon[] = { - {"Hp", NULL, "HPOUTL"}, - {"Hp", NULL, "HPOUTR"}, - {"Ext Spk", NULL, "SPKOUT"}, - {"MICIN1", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Ext Mic"}, -}; - -/* Digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(sirf, - DAILINK_COMP_ARRAY(COMP_EMPTY()), - DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "sirf-audio-codec")), - DAILINK_COMP_ARRAY(COMP_EMPTY())); - -static struct snd_soc_dai_link sirf_audio_dai_link[] = { - { - .name = "SiRF audio card", - .stream_name = "SiRF audio HiFi", - SND_SOC_DAILINK_REG(sirf), - }, -}; - -/* Audio machine driver */ -static struct snd_soc_card snd_soc_sirf_audio_card = { - .name = "SiRF audio card", - .owner = THIS_MODULE, - .dai_link = sirf_audio_dai_link, - .num_links = ARRAY_SIZE(sirf_audio_dai_link), - .dapm_widgets = sirf_audio_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sirf_audio_dapm_widgets), - .dapm_routes = intercon, - .num_dapm_routes = ARRAY_SIZE(intercon), -}; - -static int sirf_audio_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &snd_soc_sirf_audio_card; - struct sirf_audio_card *sirf_audio_card; - int ret; - - sirf_audio_card = devm_kzalloc(&pdev->dev, sizeof(struct sirf_audio_card), - GFP_KERNEL); - if (sirf_audio_card == NULL) - return -ENOMEM; - - sirf_audio_dai_link[0].cpus->of_node = - of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); - sirf_audio_dai_link[0].platforms->of_node = - of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); - sirf_audio_dai_link[0].codecs->of_node = - of_parse_phandle(pdev->dev.of_node, "sirf,audio-codec", 0); - sirf_audio_card->gpio_spk_pa = of_get_named_gpio(pdev->dev.of_node, - "spk-pa-gpios", 0); - sirf_audio_card->gpio_hp_pa = of_get_named_gpio(pdev->dev.of_node, - "hp-pa-gpios", 0); - if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) { - ret = devm_gpio_request_one(&pdev->dev, - sirf_audio_card->gpio_spk_pa, - GPIOF_OUT_INIT_LOW, "SPA_PA_SD"); - if (ret) { - dev_err(&pdev->dev, - "Failed to request GPIO_%d for reset: %d\n", - sirf_audio_card->gpio_spk_pa, ret); - return ret; - } - } - if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) { - ret = devm_gpio_request_one(&pdev->dev, - sirf_audio_card->gpio_hp_pa, - GPIOF_OUT_INIT_LOW, "HP_PA_SD"); - if (ret) { - dev_err(&pdev->dev, - "Failed to request GPIO_%d for reset: %d\n", - sirf_audio_card->gpio_hp_pa, ret); - return ret; - } - } - - card->dev = &pdev->dev; - snd_soc_card_set_drvdata(card, sirf_audio_card); - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); - - return ret; -} - -static const struct of_device_id sirf_audio_of_match[] = { - {.compatible = "sirf,sirf-audio-card", }, - { }, -}; -MODULE_DEVICE_TABLE(of, sirf_audio_of_match); - -static struct platform_driver sirf_audio_driver = { - .driver = { - .name = "sirf-audio-card", - .pm = &snd_soc_pm_ops, - .of_match_table = sirf_audio_of_match, - }, - .probe = sirf_audio_probe, -}; -module_platform_driver(sirf_audio_driver); - -MODULE_AUTHOR("RongJun Ying "); -MODULE_DESCRIPTION("ALSA SoC SIRF audio card driver"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c deleted file mode 100644 index 2af0c6f14ee69..0000000000000 --- a/sound/soc/sirf/sirf-usp.c +++ /dev/null @@ -1,435 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SiRF USP in I2S/DSP mode - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sirf-usp.h" - -struct sirf_usp { - struct regmap *regmap; - struct clk *clk; - u32 mode1_reg; - u32 mode2_reg; - int daifmt_format; - struct snd_dmaengine_dai_dma_data playback_dma_data; - struct snd_dmaengine_dai_dma_data capture_dma_data; -}; - -static void sirf_usp_tx_enable(struct sirf_usp *usp) -{ - regmap_update_bits(usp->regmap, USP_TX_FIFO_OP, - USP_TX_FIFO_RESET, USP_TX_FIFO_RESET); - regmap_write(usp->regmap, USP_TX_FIFO_OP, 0); - - regmap_update_bits(usp->regmap, USP_TX_FIFO_OP, - USP_TX_FIFO_START, USP_TX_FIFO_START); - - regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, - USP_TX_ENA, USP_TX_ENA); -} - -static void sirf_usp_tx_disable(struct sirf_usp *usp) -{ - regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, - USP_TX_ENA, ~USP_TX_ENA); - /* FIFO stop */ - regmap_write(usp->regmap, USP_TX_FIFO_OP, 0); -} - -static void sirf_usp_rx_enable(struct sirf_usp *usp) -{ - regmap_update_bits(usp->regmap, USP_RX_FIFO_OP, - USP_RX_FIFO_RESET, USP_RX_FIFO_RESET); - regmap_write(usp->regmap, USP_RX_FIFO_OP, 0); - - regmap_update_bits(usp->regmap, USP_RX_FIFO_OP, - USP_RX_FIFO_START, USP_RX_FIFO_START); - - regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, - USP_RX_ENA, USP_RX_ENA); -} - -static void sirf_usp_rx_disable(struct sirf_usp *usp) -{ - regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, - USP_RX_ENA, ~USP_RX_ENA); - /* FIFO stop */ - regmap_write(usp->regmap, USP_RX_FIFO_OP, 0); -} - -static int sirf_usp_pcm_dai_probe(struct snd_soc_dai *dai) -{ - struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); - - snd_soc_dai_init_dma_data(dai, &usp->playback_dma_data, - &usp->capture_dma_data); - return 0; -} - -static int sirf_usp_pcm_set_dai_fmt(struct snd_soc_dai *dai, - unsigned int fmt) -{ - struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - break; - default: - dev_err(dai->dev, "Only CBM and CFM supported\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - case SND_SOC_DAIFMT_DSP_A: - usp->daifmt_format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK); - break; - default: - dev_err(dai->dev, "Only I2S and DSP_A format supported\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_NF: - usp->daifmt_format |= (fmt & SND_SOC_DAIFMT_INV_MASK); - break; - default: - return -EINVAL; - } - - return 0; -} - -static void sirf_usp_i2s_init(struct sirf_usp *usp) -{ - /* Configure RISC mode */ - regmap_update_bits(usp->regmap, USP_RISC_DSP_MODE, - USP_RISC_DSP_SEL, ~USP_RISC_DSP_SEL); - - /* - * Configure DMA IO Length register - * Set no limit, USP can receive data continuously until it is diabled - */ - regmap_write(usp->regmap, USP_TX_DMA_IO_LEN, 0); - regmap_write(usp->regmap, USP_RX_DMA_IO_LEN, 0); - - /* Configure Mode2 register */ - regmap_write(usp->regmap, USP_MODE2, (1 << USP_RXD_DELAY_LEN_OFFSET) | - (0 << USP_TXD_DELAY_LEN_OFFSET) | - USP_TFS_CLK_SLAVE_MODE | USP_RFS_CLK_SLAVE_MODE); - - /* Configure Mode1 register */ - regmap_write(usp->regmap, USP_MODE1, - USP_SYNC_MODE | USP_EN | USP_TXD_ACT_EDGE_FALLING | - USP_RFS_ACT_LEVEL_LOGIC1 | USP_TFS_ACT_LEVEL_LOGIC1 | - USP_TX_UFLOW_REPEAT_ZERO | USP_CLOCK_MODE_SLAVE); - - /* Configure RX DMA IO Control register */ - regmap_write(usp->regmap, USP_RX_DMA_IO_CTRL, 0); - - /* Congiure RX FIFO Control register */ - regmap_write(usp->regmap, USP_RX_FIFO_CTRL, - (USP_RX_FIFO_THRESHOLD << USP_RX_FIFO_THD_OFFSET) | - (USP_TX_RX_FIFO_WIDTH_DWORD << USP_RX_FIFO_WIDTH_OFFSET)); - - /* Congiure RX FIFO Level Check register */ - regmap_write(usp->regmap, USP_RX_FIFO_LEVEL_CHK, - RX_FIFO_SC(0x04) | RX_FIFO_LC(0x0E) | RX_FIFO_HC(0x1B)); - - /* Configure TX DMA IO Control register*/ - regmap_write(usp->regmap, USP_TX_DMA_IO_CTRL, 0); - - /* Configure TX FIFO Control register */ - regmap_write(usp->regmap, USP_TX_FIFO_CTRL, - (USP_TX_FIFO_THRESHOLD << USP_TX_FIFO_THD_OFFSET) | - (USP_TX_RX_FIFO_WIDTH_DWORD << USP_TX_FIFO_WIDTH_OFFSET)); - /* Congiure TX FIFO Level Check register */ - regmap_write(usp->regmap, USP_TX_FIFO_LEVEL_CHK, - TX_FIFO_SC(0x1B) | TX_FIFO_LC(0x0E) | TX_FIFO_HC(0x04)); -} - -static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -{ - struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); - u32 data_len, frame_len, shifter_len; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - data_len = 16; - frame_len = 16; - break; - case SNDRV_PCM_FORMAT_S24_LE: - data_len = 24; - frame_len = 32; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - data_len = 24; - frame_len = 24; - break; - default: - dev_err(dai->dev, "Format unsupported\n"); - return -EINVAL; - } - - shifter_len = data_len; - - switch (usp->daifmt_format & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, - USP_I2S_SYNC_CHG, USP_I2S_SYNC_CHG); - break; - case SND_SOC_DAIFMT_DSP_A: - regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, - USP_I2S_SYNC_CHG, 0); - frame_len = data_len * params_channels(params); - data_len = frame_len; - break; - default: - dev_err(dai->dev, "Only support I2S and DSP_A mode\n"); - return -EINVAL; - } - - switch (usp->daifmt_format & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_NF: - regmap_update_bits(usp->regmap, USP_MODE1, - USP_RXD_ACT_EDGE_FALLING | USP_TXD_ACT_EDGE_FALLING, - USP_RXD_ACT_EDGE_FALLING); - break; - default: - return -EINVAL; - } - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - regmap_update_bits(usp->regmap, USP_TX_FRAME_CTRL, - USP_TXC_DATA_LEN_MASK | USP_TXC_FRAME_LEN_MASK - | USP_TXC_SHIFTER_LEN_MASK | USP_TXC_SLAVE_CLK_SAMPLE, - ((data_len - 1) << USP_TXC_DATA_LEN_OFFSET) - | ((frame_len - 1) << USP_TXC_FRAME_LEN_OFFSET) - | ((shifter_len - 1) << USP_TXC_SHIFTER_LEN_OFFSET) - | USP_TXC_SLAVE_CLK_SAMPLE); - else - regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, - USP_RXC_DATA_LEN_MASK | USP_RXC_FRAME_LEN_MASK - | USP_RXC_SHIFTER_LEN_MASK | USP_SINGLE_SYNC_MODE, - ((data_len - 1) << USP_RXC_DATA_LEN_OFFSET) - | ((frame_len - 1) << USP_RXC_FRAME_LEN_OFFSET) - | ((shifter_len - 1) << USP_RXC_SHIFTER_LEN_OFFSET) - | USP_SINGLE_SYNC_MODE); - - return 0; -} - -static int sirf_usp_pcm_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - sirf_usp_tx_enable(usp); - else - sirf_usp_rx_enable(usp); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - sirf_usp_tx_disable(usp); - else - sirf_usp_rx_disable(usp); - break; - } - - return 0; -} - -static const struct snd_soc_dai_ops sirf_usp_pcm_dai_ops = { - .trigger = sirf_usp_pcm_trigger, - .set_fmt = sirf_usp_pcm_set_dai_fmt, - .hw_params = sirf_usp_pcm_hw_params, -}; - -static struct snd_soc_dai_driver sirf_usp_pcm_dai = { - .probe = sirf_usp_pcm_dai_probe, - .name = "sirf-usp-pcm", - .id = 0, - .playback = { - .stream_name = "SiRF USP PCM Playback", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S24_3LE, - }, - .capture = { - .stream_name = "SiRF USP PCM Capture", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S24_3LE, - }, - .ops = &sirf_usp_pcm_dai_ops, -}; - -static int sirf_usp_pcm_runtime_suspend(struct device *dev) -{ - struct sirf_usp *usp = dev_get_drvdata(dev); - - clk_disable_unprepare(usp->clk); - return 0; -} - -static int sirf_usp_pcm_runtime_resume(struct device *dev) -{ - struct sirf_usp *usp = dev_get_drvdata(dev); - int ret; - - ret = clk_prepare_enable(usp->clk); - if (ret) { - dev_err(dev, "clk_enable failed: %d\n", ret); - return ret; - } - sirf_usp_i2s_init(usp); - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int sirf_usp_pcm_suspend(struct device *dev) -{ - struct sirf_usp *usp = dev_get_drvdata(dev); - - if (!pm_runtime_status_suspended(dev)) { - regmap_read(usp->regmap, USP_MODE1, &usp->mode1_reg); - regmap_read(usp->regmap, USP_MODE2, &usp->mode2_reg); - sirf_usp_pcm_runtime_suspend(dev); - } - return 0; -} - -static int sirf_usp_pcm_resume(struct device *dev) -{ - struct sirf_usp *usp = dev_get_drvdata(dev); - int ret; - - if (!pm_runtime_status_suspended(dev)) { - ret = sirf_usp_pcm_runtime_resume(dev); - if (ret) - return ret; - regmap_write(usp->regmap, USP_MODE1, usp->mode1_reg); - regmap_write(usp->regmap, USP_MODE2, usp->mode2_reg); - } - return 0; -} -#endif - -static const struct snd_soc_component_driver sirf_usp_component = { - .name = "sirf-usp", -}; - -static const struct regmap_config sirf_usp_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = USP_RX_FIFO_DATA, - .cache_type = REGCACHE_NONE, -}; - -static int sirf_usp_pcm_probe(struct platform_device *pdev) -{ - int ret; - struct sirf_usp *usp; - void __iomem *base; - - usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp), - GFP_KERNEL); - if (!usp) - return -ENOMEM; - - platform_set_drvdata(pdev, usp); - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - usp->regmap = devm_regmap_init_mmio(&pdev->dev, base, - &sirf_usp_regmap_config); - if (IS_ERR(usp->regmap)) - return PTR_ERR(usp->regmap); - - usp->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(usp->clk)) { - dev_err(&pdev->dev, "Get clock failed.\n"); - return PTR_ERR(usp->clk); - } - - pm_runtime_enable(&pdev->dev); - if (!pm_runtime_enabled(&pdev->dev)) { - ret = sirf_usp_pcm_runtime_resume(&pdev->dev); - if (ret) - return ret; - } - - ret = devm_snd_soc_register_component(&pdev->dev, &sirf_usp_component, - &sirf_usp_pcm_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register Audio SoC dai failed.\n"); - return ret; - } - return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); -} - -static int sirf_usp_pcm_remove(struct platform_device *pdev) -{ - if (!pm_runtime_enabled(&pdev->dev)) - sirf_usp_pcm_runtime_suspend(&pdev->dev); - else - pm_runtime_disable(&pdev->dev); - return 0; -} - -static const struct of_device_id sirf_usp_pcm_of_match[] = { - { .compatible = "sirf,prima2-usp-pcm", }, - {} -}; -MODULE_DEVICE_TABLE(of, sirf_usp_pcm_of_match); - -static const struct dev_pm_ops sirf_usp_pcm_pm_ops = { - SET_RUNTIME_PM_OPS(sirf_usp_pcm_runtime_suspend, - sirf_usp_pcm_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(sirf_usp_pcm_suspend, sirf_usp_pcm_resume) -}; - -static struct platform_driver sirf_usp_pcm_driver = { - .driver = { - .name = "sirf-usp-pcm", - .of_match_table = sirf_usp_pcm_of_match, - .pm = &sirf_usp_pcm_pm_ops, - }, - .probe = sirf_usp_pcm_probe, - .remove = sirf_usp_pcm_remove, -}; - -module_platform_driver(sirf_usp_pcm_driver); - -MODULE_DESCRIPTION("SiRF SoC USP PCM bus driver"); -MODULE_AUTHOR("RongJun Ying "); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sirf/sirf-usp.h b/sound/soc/sirf/sirf-usp.h deleted file mode 100644 index 08993b5992c41..0000000000000 --- a/sound/soc/sirf/sirf-usp.h +++ /dev/null @@ -1,292 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * arch/arm/mach-prima2/include/mach/sirfsoc_usp.h - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#ifndef _SIRF_USP_H -#define _SIRF_USP_H - -/* USP Registers */ -#define USP_MODE1 0x00 -#define USP_MODE2 0x04 -#define USP_TX_FRAME_CTRL 0x08 -#define USP_RX_FRAME_CTRL 0x0C -#define USP_TX_RX_ENABLE 0x10 -#define USP_INT_ENABLE 0x14 -#define USP_INT_STATUS 0x18 -#define USP_PIN_IO_DATA 0x1C -#define USP_RISC_DSP_MODE 0x20 -#define USP_AYSNC_PARAM_REG 0x24 -#define USP_IRDA_X_MODE_DIV 0x28 -#define USP_SM_CFG 0x2C -#define USP_TX_DMA_IO_CTRL 0x100 -#define USP_TX_DMA_IO_LEN 0x104 -#define USP_TX_FIFO_CTRL 0x108 -#define USP_TX_FIFO_LEVEL_CHK 0x10C -#define USP_TX_FIFO_OP 0x110 -#define USP_TX_FIFO_STATUS 0x114 -#define USP_TX_FIFO_DATA 0x118 -#define USP_RX_DMA_IO_CTRL 0x120 -#define USP_RX_DMA_IO_LEN 0x124 -#define USP_RX_FIFO_CTRL 0x128 -#define USP_RX_FIFO_LEVEL_CHK 0x12C -#define USP_RX_FIFO_OP 0x130 -#define USP_RX_FIFO_STATUS 0x134 -#define USP_RX_FIFO_DATA 0x138 - -/* USP MODE register-1 */ -#define USP_SYNC_MODE 0x00000001 -#define USP_CLOCK_MODE_SLAVE 0x00000002 -#define USP_LOOP_BACK_EN 0x00000004 -#define USP_HPSIR_EN 0x00000008 -#define USP_ENDIAN_CTRL_LSBF 0x00000010 -#define USP_EN 0x00000020 -#define USP_RXD_ACT_EDGE_FALLING 0x00000040 -#define USP_TXD_ACT_EDGE_FALLING 0x00000080 -#define USP_RFS_ACT_LEVEL_LOGIC1 0x00000100 -#define USP_TFS_ACT_LEVEL_LOGIC1 0x00000200 -#define USP_SCLK_IDLE_MODE_TOGGLE 0x00000400 -#define USP_SCLK_IDLE_LEVEL_LOGIC1 0x00000800 -#define USP_SCLK_PIN_MODE_IO 0x00001000 -#define USP_RFS_PIN_MODE_IO 0x00002000 -#define USP_TFS_PIN_MODE_IO 0x00004000 -#define USP_RXD_PIN_MODE_IO 0x00008000 -#define USP_TXD_PIN_MODE_IO 0x00010000 -#define USP_SCLK_IO_MODE_INPUT 0x00020000 -#define USP_RFS_IO_MODE_INPUT 0x00040000 -#define USP_TFS_IO_MODE_INPUT 0x00080000 -#define USP_RXD_IO_MODE_INPUT 0x00100000 -#define USP_TXD_IO_MODE_INPUT 0x00200000 -#define USP_IRDA_WIDTH_DIV_MASK 0x3FC00000 -#define USP_IRDA_WIDTH_DIV_OFFSET 0 -#define USP_IRDA_IDLE_LEVEL_HIGH 0x40000000 -#define USP_TX_UFLOW_REPEAT_ZERO 0x80000000 -#define USP_TX_ENDIAN_MODE 0x00000020 -#define USP_RX_ENDIAN_MODE 0x00000020 - -/* USP Mode Register-2 */ -#define USP_RXD_DELAY_LEN_MASK 0x000000FF -#define USP_RXD_DELAY_LEN_OFFSET 0 - -#define USP_TXD_DELAY_LEN_MASK 0x0000FF00 -#define USP_TXD_DELAY_LEN_OFFSET 8 - -#define USP_ENA_CTRL_MODE 0x00010000 -#define USP_FRAME_CTRL_MODE 0x00020000 -#define USP_TFS_SOURCE_MODE 0x00040000 -#define USP_TFS_MS_MODE 0x00080000 -#define USP_CLK_DIVISOR_MASK 0x7FE00000 -#define USP_CLK_DIVISOR_OFFSET 21 - -#define USP_TFS_CLK_SLAVE_MODE (1<<20) -#define USP_RFS_CLK_SLAVE_MODE (1<<19) - -#define USP_IRDA_DATA_WIDTH 0x80000000 - -/* USP Transmit Frame Control Register */ - -#define USP_TXC_DATA_LEN_MASK 0x000000FF -#define USP_TXC_DATA_LEN_OFFSET 0 - -#define USP_TXC_SYNC_LEN_MASK 0x0000FF00 -#define USP_TXC_SYNC_LEN_OFFSET 8 - -#define USP_TXC_FRAME_LEN_MASK 0x00FF0000 -#define USP_TXC_FRAME_LEN_OFFSET 16 - -#define USP_TXC_SHIFTER_LEN_MASK 0x1F000000 -#define USP_TXC_SHIFTER_LEN_OFFSET 24 - -#define USP_TXC_SLAVE_CLK_SAMPLE 0x20000000 - -#define USP_TXC_CLK_DIVISOR_MASK 0xC0000000 -#define USP_TXC_CLK_DIVISOR_OFFSET 30 - -/* USP Receive Frame Control Register */ - -#define USP_RXC_DATA_LEN_MASK 0x000000FF -#define USP_RXC_DATA_LEN_OFFSET 0 - -#define USP_RXC_FRAME_LEN_MASK 0x0000FF00 -#define USP_RXC_FRAME_LEN_OFFSET 8 - -#define USP_RXC_SHIFTER_LEN_MASK 0x001F0000 -#define USP_RXC_SHIFTER_LEN_OFFSET 16 - -#define USP_START_EDGE_MODE 0x00800000 -#define USP_I2S_SYNC_CHG 0x00200000 - -#define USP_RXC_CLK_DIVISOR_MASK 0x0F000000 -#define USP_RXC_CLK_DIVISOR_OFFSET 24 -#define USP_SINGLE_SYNC_MODE 0x00400000 - -/* Tx - RX Enable Register */ - -#define USP_RX_ENA 0x00000001 -#define USP_TX_ENA 0x00000002 - -/* USP Interrupt Enable and status Register */ -#define USP_RX_DONE_INT 0x00000001 -#define USP_TX_DONE_INT 0x00000002 -#define USP_RX_OFLOW_INT 0x00000004 -#define USP_TX_UFLOW_INT 0x00000008 -#define USP_RX_IO_DMA_INT 0x00000010 -#define USP_TX_IO_DMA_INT 0x00000020 -#define USP_RXFIFO_FULL_INT 0x00000040 -#define USP_TXFIFO_EMPTY_INT 0x00000080 -#define USP_RXFIFO_THD_INT 0x00000100 -#define USP_TXFIFO_THD_INT 0x00000200 -#define USP_UART_FRM_ERR_INT 0x00000400 -#define USP_RX_TIMEOUT_INT 0x00000800 -#define USP_TX_ALLOUT_INT 0x00001000 -#define USP_RXD_BREAK_INT 0x00008000 - -/* All possible TX interruots */ -#define USP_TX_INTERRUPT (USP_TX_DONE_INT|USP_TX_UFLOW_INT|\ - USP_TX_IO_DMA_INT|\ - USP_TXFIFO_EMPTY_INT|\ - USP_TXFIFO_THD_INT) -/* All possible RX interruots */ -#define USP_RX_INTERRUPT (USP_RX_DONE_INT|USP_RX_OFLOW_INT|\ - USP_RX_IO_DMA_INT|\ - USP_RXFIFO_FULL_INT|\ - USP_RXFIFO_THD_INT|\ - USP_RX_TIMEOUT_INT) - -#define USP_INT_ALL 0x1FFF - -/* USP Pin I/O Data Register */ - -#define USP_RFS_PIN_VALUE_MASK 0x00000001 -#define USP_TFS_PIN_VALUE_MASK 0x00000002 -#define USP_RXD_PIN_VALUE_MASK 0x00000004 -#define USP_TXD_PIN_VALUE_MASK 0x00000008 -#define USP_SCLK_PIN_VALUE_MASK 0x00000010 - -/* USP RISC/DSP Mode Register */ -#define USP_RISC_DSP_SEL 0x00000001 - -/* USP ASYNC PARAMETER Register*/ - -#define USP_ASYNC_TIMEOUT_MASK 0x0000FFFF -#define USP_ASYNC_TIMEOUT_OFFSET 0 -#define USP_ASYNC_TIMEOUT(x) (((x)&USP_ASYNC_TIMEOUT_MASK) \ - < Date: Wed, 20 Jan 2021 17:25:53 +0100 Subject: [PATCH 0412/1084] ASoC: remove zte zx drivers The zte zx platform is getting removed, so this driver is no longer needed. Cc: Jun Nie Cc: Shawn Guo Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20210120162553.21666-3-arnd@kernel.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/zte,tdm.txt | 30 -- .../bindings/sound/zte,zx-aud96p22.txt | 24 - .../devicetree/bindings/sound/zte,zx-i2s.txt | 45 -- .../bindings/sound/zte,zx-spdif.txt | 27 -- sound/soc/Kconfig | 1 - sound/soc/Makefile | 1 - sound/soc/codecs/Makefile | 2 - sound/soc/codecs/zx_aud96p22.c | 401 --------------- sound/soc/zte/Kconfig | 26 - sound/soc/zte/Makefile | 4 - sound/soc/zte/zx-i2s.c | 452 ----------------- sound/soc/zte/zx-spdif.c | 363 -------------- sound/soc/zte/zx-tdm.c | 458 ------------------ 13 files changed, 1834 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/zte,tdm.txt delete mode 100644 Documentation/devicetree/bindings/sound/zte,zx-aud96p22.txt delete mode 100644 Documentation/devicetree/bindings/sound/zte,zx-i2s.txt delete mode 100644 Documentation/devicetree/bindings/sound/zte,zx-spdif.txt delete mode 100644 sound/soc/codecs/zx_aud96p22.c delete mode 100644 sound/soc/zte/Kconfig delete mode 100644 sound/soc/zte/Makefile delete mode 100644 sound/soc/zte/zx-i2s.c delete mode 100644 sound/soc/zte/zx-spdif.c delete mode 100644 sound/soc/zte/zx-tdm.c diff --git a/Documentation/devicetree/bindings/sound/zte,tdm.txt b/Documentation/devicetree/bindings/sound/zte,tdm.txt deleted file mode 100644 index 2a07ca655264c..0000000000000 --- a/Documentation/devicetree/bindings/sound/zte,tdm.txt +++ /dev/null @@ -1,30 +0,0 @@ -ZTE TDM DAI driver - -Required properties: - -- compatible : should be one of the following. - * zte,zx296718-tdm -- reg : physical base address of the controller and length of memory mapped - region. -- clocks : Pairs of phandle and specifier referencing the controller's clocks. -- clock-names: "wclk" for the wclk. - "pclk" for the pclk. --#clock-cells: should be 1. -- zte,tdm-dma-sysctrl : Reference to the sysctrl controller controlling - the dma. includes: - phandle of sysctrl. - register offset in sysctrl for control dma. - mask of the register that be written to sysctrl. - -Example: - - tdm: tdm@1487000 { - compatible = "zte,zx296718-tdm"; - reg = <0x01487000 0x1000>; - clocks = <&audiocrm AUDIO_TDM_WCLK>, <&audiocrm AUDIO_TDM_PCLK>; - clock-names = "wclk", "pclk"; - #clock-cells = <1>; - pinctrl-names = "default"; - pinctrl-0 = <&tdm_global_pin>; - zte,tdm-dma-sysctrl = <&sysctrl 0x10c 4>; - }; diff --git a/Documentation/devicetree/bindings/sound/zte,zx-aud96p22.txt b/Documentation/devicetree/bindings/sound/zte,zx-aud96p22.txt deleted file mode 100644 index 41bb1040eb716..0000000000000 --- a/Documentation/devicetree/bindings/sound/zte,zx-aud96p22.txt +++ /dev/null @@ -1,24 +0,0 @@ -ZTE ZX AUD96P22 Audio Codec - -Required properties: - - compatible: Must be "zte,zx-aud96p22" - - #sound-dai-cells: Should be 0 - - reg: I2C bus slave address of AUD96P22 - -Example: - - i2c0: i2c@1486000 { - compatible = "zte,zx296718-i2c"; - reg = <0x01486000 0x1000>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&audiocrm AUDIO_I2C0_WCLK>; - clock-frequency = <1600000>; - - aud96p22: codec@22 { - compatible = "zte,zx-aud96p22"; - #sound-dai-cells = <0>; - reg = <0x22>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt b/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt deleted file mode 100644 index 3927251464f06..0000000000000 --- a/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt +++ /dev/null @@ -1,45 +0,0 @@ -ZTE ZX296702 I2S controller - -Required properties: - - compatible : Must be one of: - "zte,zx296718-i2s", "zte,zx296702-i2s" - "zte,zx296702-i2s" - - reg : Must contain I2S core's registers location and length - - clocks : Pairs of phandle and specifier referencing the controller's clocks. - - clock-names: "wclk" for the wclk, "pclk" for the pclk to the I2S interface. - - dmas: Pairs of phandle and specifier for the DMA channel that is used by - the core. The core expects two dma channels for transmit. - - dma-names : Must be "tx" and "rx" - -For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties -please check: - * resource-names.txt - * clock/clock-bindings.txt - * dma/dma.txt - -Example: - i2s0: i2s@b005000 { - #sound-dai-cells = <0>; - compatible = "zte,zx296718-i2s", "zte,zx296702-i2s"; - reg = <0x0b005000 0x1000>; - clocks = <&audiocrm AUDIO_I2S0_WCLK>, <&audiocrm AUDIO_I2S0_PCLK>; - clock-names = "wclk", "pclk"; - interrupts = ; - dmas = <&dma 5>, <&dma 6>; - dma-names = "tx", "rx"; - }; - - sound { - compatible = "simple-audio-card"; - simple-audio-card,name = "zx296702_snd"; - simple-audio-card,format = "left_j"; - simple-audio-card,bitclock-master = <&sndcodec>; - simple-audio-card,frame-master = <&sndcodec>; - sndcpu: simple-audio-card,cpu { - sound-dai = <&i2s0>; - }; - - sndcodec: simple-audio-card,codec { - sound-dai = <&acodec>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt deleted file mode 100644 index 09231d7586b2e..0000000000000 --- a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt +++ /dev/null @@ -1,27 +0,0 @@ -ZTE ZX296702 SPDIF controller - -Required properties: - - compatible : Must be "zte,zx296702-spdif" - - reg : Must contain SPDIF core's registers location and length - - clocks : Pairs of phandle and specifier referencing the controller's clocks. - - clock-names: "tx" for the clock to the SPDIF interface. - - dmas: Pairs of phandle and specifier for the DMA channel that is used by - the core. The core expects one dma channel for transmit. - - dma-names : Must be "tx" - -For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties -please check: - * resource-names.txt - * clock/clock-bindings.txt - * dma/dma.txt - -Example: - spdif0: spdif0@b004000 { - compatible = "zte,zx296702-spdif"; - reg = <0x0b004000 0x1000>; - clocks = <&lsp0clk ZX296702_SPDIF0_DIV>; - clock-names = "tx"; - interrupts = ; - dmas = <&dma 4>; - dma-names = "tx"; - }; diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 547b26ca714f5..ba79d5f4e2995 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -74,7 +74,6 @@ source "sound/soc/uniphier/Kconfig" source "sound/soc/ux500/Kconfig" source "sound/soc/xilinx/Kconfig" source "sound/soc/xtensa/Kconfig" -source "sound/soc/zte/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 74508b0f9c477..eee370492eeeb 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -57,4 +57,3 @@ obj-$(CONFIG_SND_SOC) += uniphier/ obj-$(CONFIG_SND_SOC) += ux500/ obj-$(CONFIG_SND_SOC) += xilinx/ obj-$(CONFIG_SND_SOC) += xtensa/ -obj-$(CONFIG_SND_SOC) += zte/ diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index c30762fc9b878..628b0c9b3e2a2 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -301,7 +301,6 @@ snd-soc-wm9713-objs := wm9713.o snd-soc-wm-hubs-objs := wm_hubs.o snd-soc-wsa881x-objs := wsa881x.o snd-soc-zl38060-objs := zl38060.o -snd-soc-zx-aud96p22-objs := zx_aud96p22.o # Amp snd-soc-max9877-objs := max9877.o snd-soc-max98504-objs := max98504.o @@ -616,7 +615,6 @@ obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o -obj-$(CONFIG_SND_SOC_ZX_AUD96P22) += snd-soc-zx-aud96p22.o # Amp obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o diff --git a/sound/soc/codecs/zx_aud96p22.c b/sound/soc/codecs/zx_aud96p22.c deleted file mode 100644 index 16d44efb132df..0000000000000 --- a/sound/soc/codecs/zx_aud96p22.c +++ /dev/null @@ -1,401 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - * - * Author: Baoyou Xie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AUD96P22_RESET 0x00 -#define RST_DAC_DPZ BIT(0) -#define RST_ADC_DPZ BIT(1) -#define AUD96P22_I2S1_CONFIG_0 0x03 -#define I2S1_MS_MODE BIT(3) -#define I2S1_MODE_MASK 0x7 -#define I2S1_MODE_RIGHT_J 0x0 -#define I2S1_MODE_I2S 0x1 -#define I2S1_MODE_LEFT_J 0x2 -#define AUD96P22_PD_0 0x15 -#define AUD96P22_PD_1 0x16 -#define AUD96P22_PD_3 0x18 -#define AUD96P22_PD_4 0x19 -#define AUD96P22_MUTE_0 0x1d -#define AUD96P22_MUTE_2 0x1f -#define AUD96P22_MUTE_4 0x21 -#define AUD96P22_RECVOL_0 0x24 -#define AUD96P22_RECVOL_1 0x25 -#define AUD96P22_PGA1VOL_0 0x26 -#define AUD96P22_PGA1VOL_1 0x27 -#define AUD96P22_LMVOL_0 0x34 -#define AUD96P22_LMVOL_1 0x35 -#define AUD96P22_HS1VOL_0 0x38 -#define AUD96P22_HS1VOL_1 0x39 -#define AUD96P22_PGA1SEL_0 0x47 -#define AUD96P22_PGA1SEL_1 0x48 -#define AUD96P22_LDR1SEL_0 0x59 -#define AUD96P22_LDR1SEL_1 0x60 -#define AUD96P22_LDR2SEL_0 0x5d -#define AUD96P22_REG_MAX 0xfb - -struct aud96p22_priv { - struct regmap *regmap; -}; - -static int aud96p22_adc_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct aud96p22_priv *priv = snd_soc_component_get_drvdata(component); - struct regmap *regmap = priv->regmap; - - if (event != SND_SOC_DAPM_POST_PMU) - return -EINVAL; - - /* Assert/de-assert the bit to reset ADC data path */ - regmap_update_bits(regmap, AUD96P22_RESET, RST_ADC_DPZ, 0); - regmap_update_bits(regmap, AUD96P22_RESET, RST_ADC_DPZ, RST_ADC_DPZ); - - return 0; -} - -static int aud96p22_dac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct aud96p22_priv *priv = snd_soc_component_get_drvdata(component); - struct regmap *regmap = priv->regmap; - - if (event != SND_SOC_DAPM_POST_PMU) - return -EINVAL; - - /* Assert/de-assert the bit to reset DAC data path */ - regmap_update_bits(regmap, AUD96P22_RESET, RST_DAC_DPZ, 0); - regmap_update_bits(regmap, AUD96P22_RESET, RST_DAC_DPZ, RST_DAC_DPZ); - - return 0; -} - -static const DECLARE_TLV_DB_SCALE(lm_tlv, -11550, 50, 0); -static const DECLARE_TLV_DB_SCALE(hs_tlv, -3900, 300, 0); -static const DECLARE_TLV_DB_SCALE(rec_tlv, -9550, 50, 0); -static const DECLARE_TLV_DB_SCALE(pga_tlv, -1800, 100, 0); - -static const struct snd_kcontrol_new aud96p22_snd_controls[] = { - /* Volume control */ - SOC_DOUBLE_R_TLV("Master Playback Volume", AUD96P22_LMVOL_0, - AUD96P22_LMVOL_1, 0, 0xff, 0, lm_tlv), - SOC_DOUBLE_R_TLV("Headphone Volume", AUD96P22_HS1VOL_0, - AUD96P22_HS1VOL_1, 0, 0xf, 0, hs_tlv), - SOC_DOUBLE_R_TLV("Master Capture Volume", AUD96P22_RECVOL_0, - AUD96P22_RECVOL_1, 0, 0xff, 0, rec_tlv), - SOC_DOUBLE_R_TLV("Analogue Capture Volume", AUD96P22_PGA1VOL_0, - AUD96P22_PGA1VOL_1, 0, 0x37, 0, pga_tlv), - - /* Mute control */ - SOC_DOUBLE("Master Playback Switch", AUD96P22_MUTE_2, 0, 1, 1, 1), - SOC_DOUBLE("Headphone Switch", AUD96P22_MUTE_2, 4, 5, 1, 1), - SOC_DOUBLE("Line Out Switch", AUD96P22_MUTE_4, 0, 1, 1, 1), - SOC_DOUBLE("Speaker Switch", AUD96P22_MUTE_4, 2, 3, 1, 1), - SOC_DOUBLE("Master Capture Switch", AUD96P22_MUTE_0, 0, 1, 1, 1), - SOC_DOUBLE("Analogue Capture Switch", AUD96P22_MUTE_0, 2, 3, 1, 1), -}; - -/* Input mux kcontrols */ -static const unsigned int ain_mux_values[] = { - 0, 1, 3, 4, 5, -}; - -static const char * const ainl_mux_texts[] = { - "AINL1 differential", - "AINL1 single-ended", - "AINL3 single-ended", - "AINL2 differential", - "AINL2 single-ended", -}; - -static const char * const ainr_mux_texts[] = { - "AINR1 differential", - "AINR1 single-ended", - "AINR3 single-ended", - "AINR2 differential", - "AINR2 single-ended", -}; - -static SOC_VALUE_ENUM_SINGLE_DECL(ainl_mux_enum, AUD96P22_PGA1SEL_0, - 0, 0x7, ainl_mux_texts, ain_mux_values); -static SOC_VALUE_ENUM_SINGLE_DECL(ainr_mux_enum, AUD96P22_PGA1SEL_1, - 0, 0x7, ainr_mux_texts, ain_mux_values); - -static const struct snd_kcontrol_new ainl_mux_kcontrol = - SOC_DAPM_ENUM("AINL Mux", ainl_mux_enum); -static const struct snd_kcontrol_new ainr_mux_kcontrol = - SOC_DAPM_ENUM("AINR Mux", ainr_mux_enum); - -/* Output mixer kcontrols */ -static const struct snd_kcontrol_new ld1_left_kcontrols[] = { - SOC_DAPM_SINGLE("DACL LD1L Switch", AUD96P22_LDR1SEL_0, 0, 1, 0), - SOC_DAPM_SINGLE("AINL LD1L Switch", AUD96P22_LDR1SEL_0, 1, 1, 0), - SOC_DAPM_SINGLE("AINR LD1L Switch", AUD96P22_LDR1SEL_0, 2, 1, 0), -}; - -static const struct snd_kcontrol_new ld1_right_kcontrols[] = { - SOC_DAPM_SINGLE("DACR LD1R Switch", AUD96P22_LDR1SEL_1, 8, 1, 0), - SOC_DAPM_SINGLE("AINR LD1R Switch", AUD96P22_LDR1SEL_1, 9, 1, 0), - SOC_DAPM_SINGLE("AINL LD1R Switch", AUD96P22_LDR1SEL_1, 10, 1, 0), -}; - -static const struct snd_kcontrol_new ld2_kcontrols[] = { - SOC_DAPM_SINGLE("DACL LD2 Switch", AUD96P22_LDR2SEL_0, 0, 1, 0), - SOC_DAPM_SINGLE("AINL LD2 Switch", AUD96P22_LDR2SEL_0, 1, 1, 0), - SOC_DAPM_SINGLE("DACR LD2 Switch", AUD96P22_LDR2SEL_0, 2, 1, 0), -}; - -static const struct snd_soc_dapm_widget aud96p22_dapm_widgets[] = { - /* Overall power bit */ - SND_SOC_DAPM_SUPPLY("POWER", AUD96P22_PD_0, 0, 0, NULL, 0), - - /* Input pins */ - SND_SOC_DAPM_INPUT("AINL1P"), - SND_SOC_DAPM_INPUT("AINL2P"), - SND_SOC_DAPM_INPUT("AINL3"), - SND_SOC_DAPM_INPUT("AINL1N"), - SND_SOC_DAPM_INPUT("AINL2N"), - SND_SOC_DAPM_INPUT("AINR2N"), - SND_SOC_DAPM_INPUT("AINR1N"), - SND_SOC_DAPM_INPUT("AINR3"), - SND_SOC_DAPM_INPUT("AINR2P"), - SND_SOC_DAPM_INPUT("AINR1P"), - - /* Input muxes */ - SND_SOC_DAPM_MUX("AINLMUX", AUD96P22_PD_1, 2, 0, &ainl_mux_kcontrol), - SND_SOC_DAPM_MUX("AINRMUX", AUD96P22_PD_1, 3, 0, &ainr_mux_kcontrol), - - /* ADCs */ - SND_SOC_DAPM_ADC_E("ADCL", "Capture Left", AUD96P22_PD_1, 0, 0, - aud96p22_adc_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("ADCR", "Capture Right", AUD96P22_PD_1, 1, 0, - aud96p22_adc_event, SND_SOC_DAPM_POST_PMU), - - /* DACs */ - SND_SOC_DAPM_DAC_E("DACL", "Playback Left", AUD96P22_PD_3, 0, 0, - aud96p22_dac_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_DAC_E("DACR", "Playback Right", AUD96P22_PD_3, 1, 0, - aud96p22_dac_event, SND_SOC_DAPM_POST_PMU), - - /* Output mixers */ - SND_SOC_DAPM_MIXER("LD1L", AUD96P22_PD_3, 6, 0, ld1_left_kcontrols, - ARRAY_SIZE(ld1_left_kcontrols)), - SND_SOC_DAPM_MIXER("LD1R", AUD96P22_PD_3, 7, 0, ld1_right_kcontrols, - ARRAY_SIZE(ld1_right_kcontrols)), - SND_SOC_DAPM_MIXER("LD2", AUD96P22_PD_4, 2, 0, ld2_kcontrols, - ARRAY_SIZE(ld2_kcontrols)), - - /* Headset power switch */ - SND_SOC_DAPM_SUPPLY("HS1L", AUD96P22_PD_3, 4, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("HS1R", AUD96P22_PD_3, 5, 0, NULL, 0), - - /* Output pins */ - SND_SOC_DAPM_OUTPUT("HSOUTL"), - SND_SOC_DAPM_OUTPUT("LINEOUTL"), - SND_SOC_DAPM_OUTPUT("LINEOUTMP"), - SND_SOC_DAPM_OUTPUT("LINEOUTMN"), - SND_SOC_DAPM_OUTPUT("LINEOUTR"), - SND_SOC_DAPM_OUTPUT("HSOUTR"), -}; - -static const struct snd_soc_dapm_route aud96p22_dapm_routes[] = { - { "AINLMUX", "AINL1 differential", "AINL1N" }, - { "AINLMUX", "AINL1 single-ended", "AINL1P" }, - { "AINLMUX", "AINL3 single-ended", "AINL3" }, - { "AINLMUX", "AINL2 differential", "AINL2N" }, - { "AINLMUX", "AINL2 single-ended", "AINL2P" }, - - { "AINRMUX", "AINR1 differential", "AINR1N" }, - { "AINRMUX", "AINR1 single-ended", "AINR1P" }, - { "AINRMUX", "AINR3 single-ended", "AINR3" }, - { "AINRMUX", "AINR2 differential", "AINR2N" }, - { "AINRMUX", "AINR2 single-ended", "AINR2P" }, - - { "ADCL", NULL, "AINLMUX" }, - { "ADCR", NULL, "AINRMUX" }, - - { "ADCL", NULL, "POWER" }, - { "ADCR", NULL, "POWER" }, - { "DACL", NULL, "POWER" }, - { "DACR", NULL, "POWER" }, - - { "LD1L", "DACL LD1L Switch", "DACL" }, - { "LD1L", "AINL LD1L Switch", "AINLMUX" }, - { "LD1L", "AINR LD1L Switch", "AINRMUX" }, - - { "LD1R", "DACR LD1R Switch", "DACR" }, - { "LD1R", "AINR LD1R Switch", "AINRMUX" }, - { "LD1R", "AINL LD1R Switch", "AINLMUX" }, - - { "LD2", "DACL LD2 Switch", "DACL" }, - { "LD2", "AINL LD2 Switch", "AINLMUX" }, - { "LD2", "DACR LD2 Switch", "DACR" }, - - { "HSOUTL", NULL, "LD1L" }, - { "HSOUTR", NULL, "LD1R" }, - { "HSOUTL", NULL, "HS1L" }, - { "HSOUTR", NULL, "HS1R" }, - - { "LINEOUTL", NULL, "LD1L" }, - { "LINEOUTR", NULL, "LD1R" }, - - { "LINEOUTMP", NULL, "LD2" }, - { "LINEOUTMN", NULL, "LD2" }, -}; - -static const struct snd_soc_component_driver aud96p22_driver = { - .controls = aud96p22_snd_controls, - .num_controls = ARRAY_SIZE(aud96p22_snd_controls), - .dapm_widgets = aud96p22_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(aud96p22_dapm_widgets), - .dapm_routes = aud96p22_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(aud96p22_dapm_routes), - .idle_bias_on = 1, - .use_pmdown_time = 1, - .endianness = 1, - .non_legacy_dai_naming = 1, -}; - -static int aud96p22_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct aud96p22_priv *priv = snd_soc_component_get_drvdata(dai->component); - struct regmap *regmap = priv->regmap; - unsigned int val; - - /* Master/slave mode */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - val = 0; - break; - case SND_SOC_DAIFMT_CBM_CFM: - val = I2S1_MS_MODE; - break; - default: - return -EINVAL; - } - - regmap_update_bits(regmap, AUD96P22_I2S1_CONFIG_0, I2S1_MS_MODE, val); - - /* Audio format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - val = I2S1_MODE_RIGHT_J; - break; - case SND_SOC_DAIFMT_I2S: - val = I2S1_MODE_I2S; - break; - case SND_SOC_DAIFMT_LEFT_J: - val = I2S1_MODE_LEFT_J; - break; - default: - return -EINVAL; - } - - regmap_update_bits(regmap, AUD96P22_I2S1_CONFIG_0, I2S1_MODE_MASK, val); - - return 0; -} - -static const struct snd_soc_dai_ops aud96p22_dai_ops = { - .set_fmt = aud96p22_set_fmt, -}; - -#define AUD96P22_RATES SNDRV_PCM_RATE_8000_192000 -#define AUD96P22_FORMATS (\ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) - -static struct snd_soc_dai_driver aud96p22_dai = { - .name = "aud96p22-dai", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = AUD96P22_RATES, - .formats = AUD96P22_FORMATS, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = AUD96P22_RATES, - .formats = AUD96P22_FORMATS, - }, - .ops = &aud96p22_dai_ops, -}; - -static const struct regmap_config aud96p22_regmap = { - .reg_bits = 8, - .val_bits = 8, - .max_register = AUD96P22_REG_MAX, - .cache_type = REGCACHE_RBTREE, -}; - -static int aud96p22_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct device *dev = &i2c->dev; - struct aud96p22_priv *priv; - int ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - - priv->regmap = devm_regmap_init_i2c(i2c, &aud96p22_regmap); - if (IS_ERR(priv->regmap)) { - ret = PTR_ERR(priv->regmap); - dev_err(dev, "failed to init i2c regmap: %d\n", ret); - return ret; - } - - i2c_set_clientdata(i2c, priv); - - ret = devm_snd_soc_register_component(dev, &aud96p22_driver, &aud96p22_dai, 1); - if (ret) { - dev_err(dev, "failed to register component: %d\n", ret); - return ret; - } - - return 0; -} - -static int aud96p22_i2c_remove(struct i2c_client *i2c) -{ - return 0; -} - -static const struct of_device_id aud96p22_dt_ids[] = { - { .compatible = "zte,zx-aud96p22", }, - { } -}; -MODULE_DEVICE_TABLE(of, aud96p22_dt_ids); - -static struct i2c_driver aud96p22_i2c_driver = { - .driver = { - .name = "zx_aud96p22", - .of_match_table = aud96p22_dt_ids, - }, - .probe = aud96p22_i2c_probe, - .remove = aud96p22_i2c_remove, -}; -module_i2c_driver(aud96p22_i2c_driver); - -MODULE_DESCRIPTION("ZTE ASoC AUD96P22 CODEC driver"); -MODULE_AUTHOR("Baoyou Xie "); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/zte/Kconfig b/sound/soc/zte/Kconfig deleted file mode 100644 index a23d4f13ca19e..0000000000000 --- a/sound/soc/zte/Kconfig +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config ZX_SPDIF - tristate "ZTE ZX SPDIF Driver Support" - depends on ARCH_ZX || COMPILE_TEST - depends on COMMON_CLK - select SND_SOC_GENERIC_DMAENGINE_PCM - help - Say Y or M if you want to add support for codecs attached to the - ZTE ZX SPDIF interface - -config ZX_I2S - tristate "ZTE ZX I2S Driver Support" - depends on ARCH_ZX || COMPILE_TEST - depends on COMMON_CLK - select SND_SOC_GENERIC_DMAENGINE_PCM - help - Say Y or M if you want to add support for codecs attached to the - ZTE ZX I2S interface - -config ZX_TDM - tristate "ZTE ZX TDM Driver Support" - depends on COMMON_CLK - select SND_SOC_GENERIC_DMAENGINE_PCM - help - Say Y or M if you want to add support for codecs attached to the - ZTE ZX TDM interface diff --git a/sound/soc/zte/Makefile b/sound/soc/zte/Makefile deleted file mode 100644 index 2f7cdefa42dfd..0000000000000 --- a/sound/soc/zte/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_ZX_SPDIF) += zx-spdif.o -obj-$(CONFIG_ZX_I2S) += zx-i2s.o -obj-$(CONFIG_ZX_TDM) += zx-tdm.o diff --git a/sound/soc/zte/zx-i2s.c b/sound/soc/zte/zx-i2s.c deleted file mode 100644 index 1c1a44e08a676..0000000000000 --- a/sound/soc/zte/zx-i2s.c +++ /dev/null @@ -1,452 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2015 Linaro - * - * Author: Jun Nie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define ZX_I2S_PROCESS_CTRL 0x04 -#define ZX_I2S_TIMING_CTRL 0x08 -#define ZX_I2S_FIFO_CTRL 0x0C -#define ZX_I2S_FIFO_STATUS 0x10 -#define ZX_I2S_INT_EN 0x14 -#define ZX_I2S_INT_STATUS 0x18 -#define ZX_I2S_DATA 0x1C -#define ZX_I2S_FRAME_CNTR 0x20 - -#define I2S_DEAGULT_FIFO_THRES (0x10) -#define I2S_MAX_FIFO_THRES (0x20) - -#define ZX_I2S_PROCESS_TX_EN (1 << 0) -#define ZX_I2S_PROCESS_TX_DIS (0 << 0) -#define ZX_I2S_PROCESS_RX_EN (1 << 1) -#define ZX_I2S_PROCESS_RX_DIS (0 << 1) -#define ZX_I2S_PROCESS_I2S_EN (1 << 2) -#define ZX_I2S_PROCESS_I2S_DIS (0 << 2) - -#define ZX_I2S_TIMING_MAST (1 << 0) -#define ZX_I2S_TIMING_SLAVE (0 << 0) -#define ZX_I2S_TIMING_MS_MASK (1 << 0) -#define ZX_I2S_TIMING_LOOP (1 << 1) -#define ZX_I2S_TIMING_NOR (0 << 1) -#define ZX_I2S_TIMING_LOOP_MASK (1 << 1) -#define ZX_I2S_TIMING_PTNR (1 << 2) -#define ZX_I2S_TIMING_NTPR (0 << 2) -#define ZX_I2S_TIMING_PHASE_MASK (1 << 2) -#define ZX_I2S_TIMING_TDM (1 << 3) -#define ZX_I2S_TIMING_I2S (0 << 3) -#define ZX_I2S_TIMING_TIMING_MASK (1 << 3) -#define ZX_I2S_TIMING_LONG_SYNC (1 << 4) -#define ZX_I2S_TIMING_SHORT_SYNC (0 << 4) -#define ZX_I2S_TIMING_SYNC_MASK (1 << 4) -#define ZX_I2S_TIMING_TEAK_EN (1 << 5) -#define ZX_I2S_TIMING_TEAK_DIS (0 << 5) -#define ZX_I2S_TIMING_TEAK_MASK (1 << 5) -#define ZX_I2S_TIMING_STD_I2S (0 << 6) -#define ZX_I2S_TIMING_MSB_JUSTIF (1 << 6) -#define ZX_I2S_TIMING_LSB_JUSTIF (2 << 6) -#define ZX_I2S_TIMING_ALIGN_MASK (3 << 6) -#define ZX_I2S_TIMING_CHN_MASK (7 << 8) -#define ZX_I2S_TIMING_CHN(x) ((x - 1) << 8) -#define ZX_I2S_TIMING_LANE_MASK (3 << 11) -#define ZX_I2S_TIMING_LANE(x) ((x - 1) << 11) -#define ZX_I2S_TIMING_TSCFG_MASK (7 << 13) -#define ZX_I2S_TIMING_TSCFG(x) (x << 13) -#define ZX_I2S_TIMING_TS_WIDTH_MASK (0x1f << 16) -#define ZX_I2S_TIMING_TS_WIDTH(x) ((x - 1) << 16) -#define ZX_I2S_TIMING_DATA_SIZE_MASK (0x1f << 21) -#define ZX_I2S_TIMING_DATA_SIZE(x) ((x - 1) << 21) -#define ZX_I2S_TIMING_CFG_ERR_MASK (1 << 31) - -#define ZX_I2S_FIFO_CTRL_TX_RST (1 << 0) -#define ZX_I2S_FIFO_CTRL_TX_RST_MASK (1 << 0) -#define ZX_I2S_FIFO_CTRL_RX_RST (1 << 1) -#define ZX_I2S_FIFO_CTRL_RX_RST_MASK (1 << 1) -#define ZX_I2S_FIFO_CTRL_TX_DMA_EN (1 << 4) -#define ZX_I2S_FIFO_CTRL_TX_DMA_DIS (0 << 4) -#define ZX_I2S_FIFO_CTRL_TX_DMA_MASK (1 << 4) -#define ZX_I2S_FIFO_CTRL_RX_DMA_EN (1 << 5) -#define ZX_I2S_FIFO_CTRL_RX_DMA_DIS (0 << 5) -#define ZX_I2S_FIFO_CTRL_RX_DMA_MASK (1 << 5) -#define ZX_I2S_FIFO_CTRL_TX_THRES_MASK (0x1F << 8) -#define ZX_I2S_FIFO_CTRL_RX_THRES_MASK (0x1F << 16) - -#define CLK_RAT (32 * 4) - -struct zx_i2s_info { - struct snd_dmaengine_dai_dma_data dma_playback; - struct snd_dmaengine_dai_dma_data dma_capture; - struct clk *dai_wclk; - struct clk *dai_pclk; - void __iomem *reg_base; - int master; - resource_size_t mapbase; -}; - -static void zx_i2s_tx_en(void __iomem *base, bool on) -{ - unsigned long val; - - val = readl_relaxed(base + ZX_I2S_PROCESS_CTRL); - if (on) - val |= ZX_I2S_PROCESS_TX_EN | ZX_I2S_PROCESS_I2S_EN; - else - val &= ~(ZX_I2S_PROCESS_TX_EN | ZX_I2S_PROCESS_I2S_EN); - writel_relaxed(val, base + ZX_I2S_PROCESS_CTRL); -} - -static void zx_i2s_rx_en(void __iomem *base, bool on) -{ - unsigned long val; - - val = readl_relaxed(base + ZX_I2S_PROCESS_CTRL); - if (on) - val |= ZX_I2S_PROCESS_RX_EN | ZX_I2S_PROCESS_I2S_EN; - else - val &= ~(ZX_I2S_PROCESS_RX_EN | ZX_I2S_PROCESS_I2S_EN); - writel_relaxed(val, base + ZX_I2S_PROCESS_CTRL); -} - -static void zx_i2s_tx_dma_en(void __iomem *base, bool on) -{ - unsigned long val; - - val = readl_relaxed(base + ZX_I2S_FIFO_CTRL); - val |= ZX_I2S_FIFO_CTRL_TX_RST | (I2S_DEAGULT_FIFO_THRES << 8); - if (on) - val |= ZX_I2S_FIFO_CTRL_TX_DMA_EN; - else - val &= ~ZX_I2S_FIFO_CTRL_TX_DMA_EN; - writel_relaxed(val, base + ZX_I2S_FIFO_CTRL); -} - -static void zx_i2s_rx_dma_en(void __iomem *base, bool on) -{ - unsigned long val; - - val = readl_relaxed(base + ZX_I2S_FIFO_CTRL); - val |= ZX_I2S_FIFO_CTRL_RX_RST | (I2S_DEAGULT_FIFO_THRES << 16); - if (on) - val |= ZX_I2S_FIFO_CTRL_RX_DMA_EN; - else - val &= ~ZX_I2S_FIFO_CTRL_RX_DMA_EN; - writel_relaxed(val, base + ZX_I2S_FIFO_CTRL); -} - -#define ZX_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000| \ - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) - -#define ZX_I2S_FMTBIT \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE) - -static int zx_i2s_dai_probe(struct snd_soc_dai *dai) -{ - struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev); - - snd_soc_dai_set_drvdata(dai, zx_i2s); - zx_i2s->dma_playback.addr = zx_i2s->mapbase + ZX_I2S_DATA; - zx_i2s->dma_playback.maxburst = 16; - zx_i2s->dma_capture.addr = zx_i2s->mapbase + ZX_I2S_DATA; - zx_i2s->dma_capture.maxburst = 16; - snd_soc_dai_init_dma_data(dai, &zx_i2s->dma_playback, - &zx_i2s->dma_capture); - return 0; -} - -static int zx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) -{ - struct zx_i2s_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); - unsigned long val; - - val = readl_relaxed(i2s->reg_base + ZX_I2S_TIMING_CTRL); - val &= ~(ZX_I2S_TIMING_TIMING_MASK | ZX_I2S_TIMING_ALIGN_MASK | - ZX_I2S_TIMING_TEAK_MASK | ZX_I2S_TIMING_SYNC_MASK | - ZX_I2S_TIMING_MS_MASK); - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_STD_I2S); - break; - case SND_SOC_DAIFMT_LEFT_J: - val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_MSB_JUSTIF); - break; - case SND_SOC_DAIFMT_RIGHT_J: - val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_LSB_JUSTIF); - break; - default: - dev_err(cpu_dai->dev, "Unknown i2s timing\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - /* Codec is master, and I2S is slave. */ - i2s->master = 0; - val |= ZX_I2S_TIMING_SLAVE; - break; - case SND_SOC_DAIFMT_CBS_CFS: - /* Codec is slave, and I2S is master. */ - i2s->master = 1; - val |= ZX_I2S_TIMING_MAST; - break; - default: - dev_err(cpu_dai->dev, "Unknown master/slave format\n"); - return -EINVAL; - } - - writel_relaxed(val, i2s->reg_base + ZX_I2S_TIMING_CTRL); - return 0; -} - -static int zx_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct zx_i2s_info *i2s = snd_soc_dai_get_drvdata(socdai); - struct snd_dmaengine_dai_dma_data *dma_data; - unsigned int lane, ch_num, len, ret = 0; - unsigned int ts_width = 32; - unsigned long val; - unsigned long chn_cfg; - - dma_data = snd_soc_dai_get_dma_data(socdai, substream); - dma_data->addr_width = ts_width >> 3; - - val = readl_relaxed(i2s->reg_base + ZX_I2S_TIMING_CTRL); - val &= ~(ZX_I2S_TIMING_TS_WIDTH_MASK | ZX_I2S_TIMING_DATA_SIZE_MASK | - ZX_I2S_TIMING_LANE_MASK | ZX_I2S_TIMING_CHN_MASK | - ZX_I2S_TIMING_TSCFG_MASK); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - len = 16; - break; - case SNDRV_PCM_FORMAT_S24_LE: - len = 24; - break; - case SNDRV_PCM_FORMAT_S32_LE: - len = 32; - break; - default: - dev_err(socdai->dev, "Unknown data format\n"); - return -EINVAL; - } - val |= ZX_I2S_TIMING_TS_WIDTH(ts_width) | ZX_I2S_TIMING_DATA_SIZE(len); - - ch_num = params_channels(params); - switch (ch_num) { - case 1: - lane = 1; - chn_cfg = 2; - break; - case 2: - case 4: - case 6: - case 8: - lane = ch_num / 2; - chn_cfg = 3; - break; - default: - dev_err(socdai->dev, "Not support channel num %d\n", ch_num); - return -EINVAL; - } - val |= ZX_I2S_TIMING_LANE(lane); - val |= ZX_I2S_TIMING_TSCFG(chn_cfg); - val |= ZX_I2S_TIMING_CHN(ch_num); - writel_relaxed(val, i2s->reg_base + ZX_I2S_TIMING_CTRL); - - if (i2s->master) - ret = clk_set_rate(i2s->dai_wclk, - params_rate(params) * ch_num * CLK_RAT); - - return ret; -} - -static int zx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev); - int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (capture) - zx_i2s_rx_dma_en(zx_i2s->reg_base, true); - else - zx_i2s_tx_dma_en(zx_i2s->reg_base, true); - fallthrough; - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (capture) - zx_i2s_rx_en(zx_i2s->reg_base, true); - else - zx_i2s_tx_en(zx_i2s->reg_base, true); - break; - - case SNDRV_PCM_TRIGGER_STOP: - if (capture) - zx_i2s_rx_dma_en(zx_i2s->reg_base, false); - else - zx_i2s_tx_dma_en(zx_i2s->reg_base, false); - fallthrough; - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (capture) - zx_i2s_rx_en(zx_i2s->reg_base, false); - else - zx_i2s_tx_en(zx_i2s->reg_base, false); - break; - - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static int zx_i2s_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev); - int ret; - - ret = clk_prepare_enable(zx_i2s->dai_wclk); - if (ret) - return ret; - - ret = clk_prepare_enable(zx_i2s->dai_pclk); - if (ret) { - clk_disable_unprepare(zx_i2s->dai_wclk); - return ret; - } - - return ret; -} - -static void zx_i2s_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev); - - clk_disable_unprepare(zx_i2s->dai_wclk); - clk_disable_unprepare(zx_i2s->dai_pclk); -} - -static const struct snd_soc_dai_ops zx_i2s_dai_ops = { - .trigger = zx_i2s_trigger, - .hw_params = zx_i2s_hw_params, - .set_fmt = zx_i2s_set_fmt, - .startup = zx_i2s_startup, - .shutdown = zx_i2s_shutdown, -}; - -static const struct snd_soc_component_driver zx_i2s_component = { - .name = "zx-i2s", -}; - -static struct snd_soc_dai_driver zx_i2s_dai = { - .name = "zx-i2s-dai", - .id = 0, - .probe = zx_i2s_dai_probe, - .playback = { - .channels_min = 1, - .channels_max = 8, - .rates = ZX_I2S_RATES, - .formats = ZX_I2S_FMTBIT, - }, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = ZX_I2S_RATES, - .formats = ZX_I2S_FMTBIT, - }, - .ops = &zx_i2s_dai_ops, -}; - -static int zx_i2s_probe(struct platform_device *pdev) -{ - struct resource *res; - struct zx_i2s_info *zx_i2s; - int ret; - - zx_i2s = devm_kzalloc(&pdev->dev, sizeof(*zx_i2s), GFP_KERNEL); - if (!zx_i2s) - return -ENOMEM; - - zx_i2s->dai_wclk = devm_clk_get(&pdev->dev, "wclk"); - if (IS_ERR(zx_i2s->dai_wclk)) { - dev_err(&pdev->dev, "Fail to get wclk\n"); - return PTR_ERR(zx_i2s->dai_wclk); - } - - zx_i2s->dai_pclk = devm_clk_get(&pdev->dev, "pclk"); - if (IS_ERR(zx_i2s->dai_pclk)) { - dev_err(&pdev->dev, "Fail to get pclk\n"); - return PTR_ERR(zx_i2s->dai_pclk); - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - zx_i2s->mapbase = res->start; - zx_i2s->reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(zx_i2s->reg_base)) { - dev_err(&pdev->dev, "ioremap failed!\n"); - return PTR_ERR(zx_i2s->reg_base); - } - - writel_relaxed(0, zx_i2s->reg_base + ZX_I2S_FIFO_CTRL); - platform_set_drvdata(pdev, zx_i2s); - - ret = devm_snd_soc_register_component(&pdev->dev, &zx_i2s_component, - &zx_i2s_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register DAI failed: %d\n", ret); - return ret; - } - - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); - if (ret) - dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret); - - return ret; -} - -static const struct of_device_id zx_i2s_dt_ids[] = { - { .compatible = "zte,zx296702-i2s", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx_i2s_dt_ids); - -static struct platform_driver i2s_driver = { - .probe = zx_i2s_probe, - .driver = { - .name = "zx-i2s", - .of_match_table = zx_i2s_dt_ids, - }, -}; - -module_platform_driver(i2s_driver); - -MODULE_AUTHOR("Jun Nie "); -MODULE_DESCRIPTION("ZTE I2S SoC DAI"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/zte/zx-spdif.c b/sound/soc/zte/zx-spdif.c deleted file mode 100644 index b4168bd532b74..0000000000000 --- a/sound/soc/zte/zx-spdif.c +++ /dev/null @@ -1,363 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2015 Linaro - * - * Author: Jun Nie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ZX_CTRL 0x04 -#define ZX_FIFOCTRL 0x08 -#define ZX_INT_STATUS 0x10 -#define ZX_INT_MASK 0x14 -#define ZX_DATA 0x18 -#define ZX_VALID_BIT 0x1c -#define ZX_CH_STA_1 0x20 -#define ZX_CH_STA_2 0x24 -#define ZX_CH_STA_3 0x28 -#define ZX_CH_STA_4 0x2c -#define ZX_CH_STA_5 0x30 -#define ZX_CH_STA_6 0x34 - -#define ZX_CTRL_MODA_16 (0 << 6) -#define ZX_CTRL_MODA_18 BIT(6) -#define ZX_CTRL_MODA_20 (2 << 6) -#define ZX_CTRL_MODA_24 (3 << 6) -#define ZX_CTRL_MODA_MASK (3 << 6) - -#define ZX_CTRL_ENB BIT(4) -#define ZX_CTRL_DNB (0 << 4) -#define ZX_CTRL_ENB_MASK BIT(4) - -#define ZX_CTRL_TX_OPEN BIT(0) -#define ZX_CTRL_TX_CLOSE (0 << 0) -#define ZX_CTRL_TX_MASK BIT(0) - -#define ZX_CTRL_OPEN (ZX_CTRL_TX_OPEN | ZX_CTRL_ENB) -#define ZX_CTRL_CLOSE (ZX_CTRL_TX_CLOSE | ZX_CTRL_DNB) - -#define ZX_CTRL_DOUBLE_TRACK (0 << 8) -#define ZX_CTRL_LEFT_TRACK BIT(8) -#define ZX_CTRL_RIGHT_TRACK (2 << 8) -#define ZX_CTRL_TRACK_MASK (3 << 8) - -#define ZX_FIFOCTRL_TXTH_MASK (0x1f << 8) -#define ZX_FIFOCTRL_TXTH(x) (x << 8) -#define ZX_FIFOCTRL_TX_DMA_EN BIT(2) -#define ZX_FIFOCTRL_TX_DMA_DIS (0 << 2) -#define ZX_FIFOCTRL_TX_DMA_EN_MASK BIT(2) -#define ZX_FIFOCTRL_TX_FIFO_RST BIT(0) -#define ZX_FIFOCTRL_TX_FIFO_RST_MASK BIT(0) - -#define ZX_VALID_DOUBLE_TRACK (0 << 0) -#define ZX_VALID_LEFT_TRACK BIT(1) -#define ZX_VALID_RIGHT_TRACK (2 << 0) -#define ZX_VALID_TRACK_MASK (3 << 0) - -#define ZX_SPDIF_CLK_RAT (2 * 32) - -struct zx_spdif_info { - struct snd_dmaengine_dai_dma_data dma_data; - struct clk *dai_clk; - void __iomem *reg_base; - resource_size_t mapbase; -}; - -static int zx_spdif_dai_probe(struct snd_soc_dai *dai) -{ - struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); - - snd_soc_dai_set_drvdata(dai, zx_spdif); - zx_spdif->dma_data.addr = zx_spdif->mapbase + ZX_DATA; - zx_spdif->dma_data.maxburst = 8; - snd_soc_dai_init_dma_data(dai, &zx_spdif->dma_data, NULL); - return 0; -} - -static int zx_spdif_chanstats(void __iomem *base, unsigned int rate) -{ - u32 cstas1; - - switch (rate) { - case 22050: - cstas1 = IEC958_AES3_CON_FS_22050; - break; - case 24000: - cstas1 = IEC958_AES3_CON_FS_24000; - break; - case 32000: - cstas1 = IEC958_AES3_CON_FS_32000; - break; - case 44100: - cstas1 = IEC958_AES3_CON_FS_44100; - break; - case 48000: - cstas1 = IEC958_AES3_CON_FS_48000; - break; - case 88200: - cstas1 = IEC958_AES3_CON_FS_88200; - break; - case 96000: - cstas1 = IEC958_AES3_CON_FS_96000; - break; - case 176400: - cstas1 = IEC958_AES3_CON_FS_176400; - break; - case 192000: - cstas1 = IEC958_AES3_CON_FS_192000; - break; - default: - return -EINVAL; - } - cstas1 = cstas1 << 24; - cstas1 |= IEC958_AES0_CON_NOT_COPYRIGHT; - - writel_relaxed(cstas1, base + ZX_CH_STA_1); - return 0; -} - -static int zx_spdif_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct zx_spdif_info *zx_spdif = dev_get_drvdata(socdai->dev); - struct zx_spdif_info *spdif = snd_soc_dai_get_drvdata(socdai); - struct snd_dmaengine_dai_dma_data *dma_data = - snd_soc_dai_get_dma_data(socdai, substream); - u32 val, ch_num, rate; - int ret; - - dma_data->addr_width = params_width(params) >> 3; - - val = readl_relaxed(zx_spdif->reg_base + ZX_CTRL); - val &= ~ZX_CTRL_MODA_MASK; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - val |= ZX_CTRL_MODA_16; - break; - - case SNDRV_PCM_FORMAT_S18_3LE: - val |= ZX_CTRL_MODA_18; - break; - - case SNDRV_PCM_FORMAT_S20_3LE: - val |= ZX_CTRL_MODA_20; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - val |= ZX_CTRL_MODA_24; - break; - default: - dev_err(socdai->dev, "Format not support!\n"); - return -EINVAL; - } - - ch_num = params_channels(params); - if (ch_num == 2) - val |= ZX_CTRL_DOUBLE_TRACK; - else - val |= ZX_CTRL_LEFT_TRACK; - writel_relaxed(val, zx_spdif->reg_base + ZX_CTRL); - - val = readl_relaxed(zx_spdif->reg_base + ZX_VALID_BIT); - val &= ~ZX_VALID_TRACK_MASK; - if (ch_num == 2) - val |= ZX_VALID_DOUBLE_TRACK; - else - val |= ZX_VALID_RIGHT_TRACK; - writel_relaxed(val, zx_spdif->reg_base + ZX_VALID_BIT); - - rate = params_rate(params); - ret = zx_spdif_chanstats(zx_spdif->reg_base, rate); - if (ret) - return ret; - return clk_set_rate(spdif->dai_clk, rate * ch_num * ZX_SPDIF_CLK_RAT); -} - -static void zx_spdif_cfg_tx(void __iomem *base, int on) -{ - u32 val; - - val = readl_relaxed(base + ZX_CTRL); - val &= ~(ZX_CTRL_ENB_MASK | ZX_CTRL_TX_MASK); - val |= on ? ZX_CTRL_OPEN : ZX_CTRL_CLOSE; - writel_relaxed(val, base + ZX_CTRL); - - val = readl_relaxed(base + ZX_FIFOCTRL); - val &= ~ZX_FIFOCTRL_TX_DMA_EN_MASK; - if (on) - val |= ZX_FIFOCTRL_TX_DMA_EN; - writel_relaxed(val, base + ZX_FIFOCTRL); -} - -static int zx_spdif_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - u32 val; - struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - val = readl_relaxed(zx_spdif->reg_base + ZX_FIFOCTRL); - val |= ZX_FIFOCTRL_TX_FIFO_RST; - writel_relaxed(val, zx_spdif->reg_base + ZX_FIFOCTRL); - fallthrough; - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - zx_spdif_cfg_tx(zx_spdif->reg_base, true); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - zx_spdif_cfg_tx(zx_spdif->reg_base, false); - break; - - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static int zx_spdif_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); - - return clk_prepare_enable(zx_spdif->dai_clk); -} - -static void zx_spdif_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); - - clk_disable_unprepare(zx_spdif->dai_clk); -} - -#define ZX_RATES \ - (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |\ - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) - -#define ZX_FORMAT \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE \ - | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) - -static const struct snd_soc_dai_ops zx_spdif_dai_ops = { - .trigger = zx_spdif_trigger, - .startup = zx_spdif_startup, - .shutdown = zx_spdif_shutdown, - .hw_params = zx_spdif_hw_params, -}; - -static struct snd_soc_dai_driver zx_spdif_dai = { - .name = "spdif", - .id = 0, - .probe = zx_spdif_dai_probe, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = ZX_RATES, - .formats = ZX_FORMAT, - }, - .ops = &zx_spdif_dai_ops, -}; - -static const struct snd_soc_component_driver zx_spdif_component = { - .name = "spdif", -}; - -static void zx_spdif_dev_init(void __iomem *base) -{ - u32 val; - - writel_relaxed(0, base + ZX_CTRL); - writel_relaxed(0, base + ZX_INT_MASK); - writel_relaxed(0xf, base + ZX_INT_STATUS); - writel_relaxed(0x1, base + ZX_FIFOCTRL); - - val = readl_relaxed(base + ZX_FIFOCTRL); - val &= ~(ZX_FIFOCTRL_TXTH_MASK | ZX_FIFOCTRL_TX_FIFO_RST_MASK); - val |= ZX_FIFOCTRL_TXTH(8); - writel_relaxed(val, base + ZX_FIFOCTRL); -} - -static int zx_spdif_probe(struct platform_device *pdev) -{ - struct resource *res; - struct zx_spdif_info *zx_spdif; - int ret; - - zx_spdif = devm_kzalloc(&pdev->dev, sizeof(*zx_spdif), GFP_KERNEL); - if (!zx_spdif) - return -ENOMEM; - - zx_spdif->dai_clk = devm_clk_get(&pdev->dev, "tx"); - if (IS_ERR(zx_spdif->dai_clk)) { - dev_err(&pdev->dev, "Fail to get clk\n"); - return PTR_ERR(zx_spdif->dai_clk); - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - zx_spdif->mapbase = res->start; - zx_spdif->reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(zx_spdif->reg_base)) { - return PTR_ERR(zx_spdif->reg_base); - } - - zx_spdif_dev_init(zx_spdif->reg_base); - platform_set_drvdata(pdev, zx_spdif); - - ret = devm_snd_soc_register_component(&pdev->dev, &zx_spdif_component, - &zx_spdif_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register DAI failed: %d\n", ret); - return ret; - } - - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); - if (ret) - dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret); - - return ret; -} - -static const struct of_device_id zx_spdif_dt_ids[] = { - { .compatible = "zte,zx296702-spdif", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx_spdif_dt_ids); - -static struct platform_driver spdif_driver = { - .probe = zx_spdif_probe, - .driver = { - .name = "zx-spdif", - .of_match_table = zx_spdif_dt_ids, - }, -}; - -module_platform_driver(spdif_driver); - -MODULE_AUTHOR("Jun Nie "); -MODULE_DESCRIPTION("ZTE SPDIF SoC DAI"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/zte/zx-tdm.c b/sound/soc/zte/zx-tdm.c deleted file mode 100644 index 4f787185d6300..0000000000000 --- a/sound/soc/zte/zx-tdm.c +++ /dev/null @@ -1,458 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * ZTE's TDM driver - * - * Copyright (C) 2017 ZTE Ltd - * - * Author: Baoyou Xie - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define REG_TIMING_CTRL 0x04 -#define REG_TX_FIFO_CTRL 0x0C -#define REG_RX_FIFO_CTRL 0x10 -#define REG_INT_EN 0x1C -#define REG_INT_STATUS 0x20 -#define REG_DATABUF 0x24 -#define REG_TS_MASK0 0x44 -#define REG_PROCESS_CTRL 0x54 - -#define FIFO_CTRL_TX_RST BIT(0) -#define FIFO_CTRL_RX_RST BIT(0) -#define DEAGULT_FIFO_THRES GENMASK(4, 2) - -#define FIFO_CTRL_TX_DMA_EN BIT(1) -#define FIFO_CTRL_RX_DMA_EN BIT(1) - -#define TX_FIFO_RST_MASK BIT(0) -#define RX_FIFO_RST_MASK BIT(0) - -#define FIFOCTRL_TX_FIFO_RST BIT(0) -#define FIFOCTRL_RX_FIFO_RST BIT(0) - -#define TXTH_MASK GENMASK(5, 2) -#define RXTH_MASK GENMASK(5, 2) - -#define FIFOCTRL_THRESHOLD(x) ((x) << 2) - -#define TIMING_MS_MASK BIT(1) -/* - * 00: 8 clk cycles every timeslot - * 01: 16 clk cycles every timeslot - * 10: 32 clk cycles every timeslot - */ -#define TIMING_SYNC_WIDTH_MASK GENMASK(6, 5) -#define TIMING_WIDTH_SHIFT 5 -#define TIMING_DEFAULT_WIDTH 0 -#define TIMING_TS_WIDTH(x) ((x) << TIMING_WIDTH_SHIFT) -#define TIMING_WIDTH_FACTOR 8 - -#define TIMING_MASTER_MODE BIT(21) -#define TIMING_LSB_FIRST BIT(20) -#define TIMING_TS_NUM(x) (((x) - 1) << 7) -#define TIMING_CLK_SEL_MASK GENMASK(2, 0) -#define TIMING_CLK_SEL_DEF BIT(2) - -#define PROCESS_TX_EN BIT(0) -#define PROCESS_RX_EN BIT(1) -#define PROCESS_TDM_EN BIT(2) -#define PROCESS_DISABLE_ALL 0 - -#define INT_DISABLE_ALL 0 -#define INT_STATUS_MASK GENMASK(6, 0) - -struct zx_tdm_info { - struct snd_dmaengine_dai_dma_data dma_playback; - struct snd_dmaengine_dai_dma_data dma_capture; - resource_size_t phy_addr; - void __iomem *regbase; - struct clk *dai_wclk; - struct clk *dai_pclk; - int master; - struct device *dev; -}; - -static inline u32 zx_tdm_readl(struct zx_tdm_info *tdm, u16 reg) -{ - return readl_relaxed(tdm->regbase + reg); -} - -static inline void zx_tdm_writel(struct zx_tdm_info *tdm, u16 reg, u32 val) -{ - writel_relaxed(val, tdm->regbase + reg); -} - -static void zx_tdm_tx_en(struct zx_tdm_info *tdm, bool on) -{ - unsigned long val; - - val = zx_tdm_readl(tdm, REG_PROCESS_CTRL); - if (on) - val |= PROCESS_TX_EN | PROCESS_TDM_EN; - else - val &= ~(PROCESS_TX_EN | PROCESS_TDM_EN); - zx_tdm_writel(tdm, REG_PROCESS_CTRL, val); -} - -static void zx_tdm_rx_en(struct zx_tdm_info *tdm, bool on) -{ - unsigned long val; - - val = zx_tdm_readl(tdm, REG_PROCESS_CTRL); - if (on) - val |= PROCESS_RX_EN | PROCESS_TDM_EN; - else - val &= ~(PROCESS_RX_EN | PROCESS_TDM_EN); - zx_tdm_writel(tdm, REG_PROCESS_CTRL, val); -} - -static void zx_tdm_tx_dma_en(struct zx_tdm_info *tdm, bool on) -{ - unsigned long val; - - val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL); - val |= FIFO_CTRL_TX_RST | DEAGULT_FIFO_THRES; - if (on) - val |= FIFO_CTRL_TX_DMA_EN; - else - val &= ~FIFO_CTRL_TX_DMA_EN; - zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val); -} - -static void zx_tdm_rx_dma_en(struct zx_tdm_info *tdm, bool on) -{ - unsigned long val; - - val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL); - val |= FIFO_CTRL_RX_RST | DEAGULT_FIFO_THRES; - if (on) - val |= FIFO_CTRL_RX_DMA_EN; - else - val &= ~FIFO_CTRL_RX_DMA_EN; - zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val); -} - -#define ZX_TDM_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000) - -#define ZX_TDM_FMTBIT \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_MU_LAW | \ - SNDRV_PCM_FMTBIT_A_LAW) - -static int zx_tdm_dai_probe(struct snd_soc_dai *dai) -{ - struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev); - - snd_soc_dai_set_drvdata(dai, zx_tdm); - zx_tdm->dma_playback.addr = zx_tdm->phy_addr + REG_DATABUF; - zx_tdm->dma_playback.maxburst = 16; - zx_tdm->dma_capture.addr = zx_tdm->phy_addr + REG_DATABUF; - zx_tdm->dma_capture.maxburst = 16; - snd_soc_dai_init_dma_data(dai, &zx_tdm->dma_playback, - &zx_tdm->dma_capture); - return 0; -} - -static int zx_tdm_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) -{ - struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(cpu_dai); - unsigned long val; - - val = zx_tdm_readl(tdm, REG_TIMING_CTRL); - val &= ~(TIMING_SYNC_WIDTH_MASK | TIMING_MS_MASK); - val |= TIMING_DEFAULT_WIDTH << TIMING_WIDTH_SHIFT; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - tdm->master = 1; - val |= TIMING_MASTER_MODE; - break; - case SND_SOC_DAIFMT_CBS_CFS: - tdm->master = 0; - val &= ~TIMING_MASTER_MODE; - break; - default: - dev_err(cpu_dai->dev, "Unknown master/slave format\n"); - return -EINVAL; - } - - - zx_tdm_writel(tdm, REG_TIMING_CTRL, val); - - return 0; -} - -static int zx_tdm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(socdai); - struct snd_dmaengine_dai_dma_data *dma_data; - unsigned int ts_width = TIMING_DEFAULT_WIDTH; - unsigned int ch_num = 32; - unsigned int mask = 0; - unsigned int ret = 0; - unsigned long val; - - dma_data = snd_soc_dai_get_dma_data(socdai, substream); - dma_data->addr_width = ch_num >> 3; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_MU_LAW: - case SNDRV_PCM_FORMAT_A_LAW: - case SNDRV_PCM_FORMAT_S16_LE: - ts_width = 1; - break; - default: - dev_err(socdai->dev, "Unknown data format\n"); - return -EINVAL; - } - - val = zx_tdm_readl(tdm, REG_TIMING_CTRL); - val |= TIMING_TS_WIDTH(ts_width) | TIMING_TS_NUM(1); - zx_tdm_writel(tdm, REG_TIMING_CTRL, val); - zx_tdm_writel(tdm, REG_TS_MASK0, mask); - - if (tdm->master) - ret = clk_set_rate(tdm->dai_wclk, - params_rate(params) * TIMING_WIDTH_FACTOR * ch_num); - - return ret; -} - -static int zx_tdm_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); - struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev); - unsigned int val; - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (capture) { - val = zx_tdm_readl(zx_tdm, REG_RX_FIFO_CTRL); - val |= FIFOCTRL_RX_FIFO_RST; - zx_tdm_writel(zx_tdm, REG_RX_FIFO_CTRL, val); - - zx_tdm_rx_dma_en(zx_tdm, true); - } else { - val = zx_tdm_readl(zx_tdm, REG_TX_FIFO_CTRL); - val |= FIFOCTRL_TX_FIFO_RST; - zx_tdm_writel(zx_tdm, REG_TX_FIFO_CTRL, val); - - zx_tdm_tx_dma_en(zx_tdm, true); - } - break; - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (capture) - zx_tdm_rx_en(zx_tdm, true); - else - zx_tdm_tx_en(zx_tdm, true); - break; - case SNDRV_PCM_TRIGGER_STOP: - if (capture) - zx_tdm_rx_dma_en(zx_tdm, false); - else - zx_tdm_tx_dma_en(zx_tdm, false); - break; - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (capture) - zx_tdm_rx_en(zx_tdm, false); - else - zx_tdm_tx_en(zx_tdm, false); - break; - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static int zx_tdm_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev); - int ret; - - ret = clk_prepare_enable(zx_tdm->dai_wclk); - if (ret) - return ret; - - ret = clk_prepare_enable(zx_tdm->dai_pclk); - if (ret) { - clk_disable_unprepare(zx_tdm->dai_wclk); - return ret; - } - - return 0; -} - -static void zx_tdm_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev); - - clk_disable_unprepare(zx_tdm->dai_pclk); - clk_disable_unprepare(zx_tdm->dai_wclk); -} - -static const struct snd_soc_dai_ops zx_tdm_dai_ops = { - .trigger = zx_tdm_trigger, - .hw_params = zx_tdm_hw_params, - .set_fmt = zx_tdm_set_fmt, - .startup = zx_tdm_startup, - .shutdown = zx_tdm_shutdown, -}; - -static const struct snd_soc_component_driver zx_tdm_component = { - .name = "zx-tdm", -}; - -static void zx_tdm_init_state(struct zx_tdm_info *tdm) -{ - unsigned int val; - - zx_tdm_writel(tdm, REG_PROCESS_CTRL, PROCESS_DISABLE_ALL); - - val = zx_tdm_readl(tdm, REG_TIMING_CTRL); - val |= TIMING_LSB_FIRST; - val &= ~TIMING_CLK_SEL_MASK; - val |= TIMING_CLK_SEL_DEF; - zx_tdm_writel(tdm, REG_TIMING_CTRL, val); - - zx_tdm_writel(tdm, REG_INT_EN, INT_DISABLE_ALL); - /* - * write INT_STATUS register to clear it. - */ - zx_tdm_writel(tdm, REG_INT_STATUS, INT_STATUS_MASK); - zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, FIFOCTRL_RX_FIFO_RST); - zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, FIFOCTRL_TX_FIFO_RST); - - val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL); - val &= ~(RXTH_MASK | RX_FIFO_RST_MASK); - val |= FIFOCTRL_THRESHOLD(8); - zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val); - - val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL); - val &= ~(TXTH_MASK | TX_FIFO_RST_MASK); - val |= FIFOCTRL_THRESHOLD(8); - zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val); -} - -static struct snd_soc_dai_driver zx_tdm_dai = { - .name = "zx-tdm-dai", - .id = 0, - .probe = zx_tdm_dai_probe, - .playback = { - .channels_min = 1, - .channels_max = 4, - .rates = ZX_TDM_RATES, - .formats = ZX_TDM_FMTBIT, - }, - .capture = { - .channels_min = 1, - .channels_max = 4, - .rates = ZX_TDM_RATES, - .formats = ZX_TDM_FMTBIT, - }, - .ops = &zx_tdm_dai_ops, -}; - -static int zx_tdm_probe(struct platform_device *pdev) -{ - struct of_phandle_args out_args; - unsigned int dma_reg_offset; - struct zx_tdm_info *zx_tdm; - unsigned int dma_mask; - struct resource *res; - struct regmap *regmap_sysctrl; - int ret; - - zx_tdm = devm_kzalloc(&pdev->dev, sizeof(*zx_tdm), GFP_KERNEL); - if (!zx_tdm) - return -ENOMEM; - - zx_tdm->dev = &pdev->dev; - - zx_tdm->dai_wclk = devm_clk_get(&pdev->dev, "wclk"); - if (IS_ERR(zx_tdm->dai_wclk)) { - dev_err(&pdev->dev, "Fail to get wclk\n"); - return PTR_ERR(zx_tdm->dai_wclk); - } - - zx_tdm->dai_pclk = devm_clk_get(&pdev->dev, "pclk"); - if (IS_ERR(zx_tdm->dai_pclk)) { - dev_err(&pdev->dev, "Fail to get pclk\n"); - return PTR_ERR(zx_tdm->dai_pclk); - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - zx_tdm->phy_addr = res->start; - zx_tdm->regbase = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(zx_tdm->regbase)) - return PTR_ERR(zx_tdm->regbase); - - ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, - "zte,tdm-dma-sysctrl", 2, 0, &out_args); - if (ret) { - dev_err(&pdev->dev, "Fail to get zte,tdm-dma-sysctrl\n"); - return ret; - } - - dma_reg_offset = out_args.args[0]; - dma_mask = out_args.args[1]; - regmap_sysctrl = syscon_node_to_regmap(out_args.np); - if (IS_ERR(regmap_sysctrl)) { - of_node_put(out_args.np); - return PTR_ERR(regmap_sysctrl); - } - - regmap_update_bits(regmap_sysctrl, dma_reg_offset, dma_mask, dma_mask); - of_node_put(out_args.np); - - zx_tdm_init_state(zx_tdm); - platform_set_drvdata(pdev, zx_tdm); - - ret = devm_snd_soc_register_component(&pdev->dev, &zx_tdm_component, - &zx_tdm_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Register DAI failed: %d\n", ret); - return ret; - } - - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); - if (ret) - dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret); - - return ret; -} - -static const struct of_device_id zx_tdm_dt_ids[] = { - { .compatible = "zte,zx296718-tdm", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx_tdm_dt_ids); - -static struct platform_driver tdm_driver = { - .probe = zx_tdm_probe, - .driver = { - .name = "zx-tdm", - .of_match_table = zx_tdm_dt_ids, - }, -}; -module_platform_driver(tdm_driver); - -MODULE_AUTHOR("Baoyou Xie "); -MODULE_DESCRIPTION("ZTE TDM DAI driver"); -MODULE_LICENSE("GPL v2"); -- GitLab From b135b3358d73aa2a8b2be35d08e422421d1c609e Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 19 Jan 2021 16:55:10 +0100 Subject: [PATCH 0413/1084] mtd: rawnand: omap: Use BCH private fields in the specific OOB layout The OMAP driver may leverage software BCH logic to locate errors while using its own hardware to detect the presence of errors. This is achieved with a "mixed" mode which initializes manually the software BCH internal logic while providing its own OOB layout. The issue here comes from the fact that the BCH driver has been updated to only use generic NAND objects, and no longer depend on raw NAND structures as it is usable from SPI-NAND as well. However, at the end of the BCH context initialization, the driver checks the validity of the OOB layout. At this stage, the raw NAND fields have not been populated yet while being used by the layout helpers, leading to an invalid layout. The chosen solution here is to include the BCH structure definition and to refer to the BCH fields directly (de-referenced as a const pointer here) to know as early as possible the number of steps and ECC bytes which have been chosen. Note: I don't know which commit exactly triggered the error, but the entire migration to a generic BCH driver got merged in one go, so this should not be a problem for stable backports. Reported-by: Adam Ford Fixes: 80fe603160a4 ("mtd: nand: ecc-bch: Stop using raw NAND structures") Signed-off-by: Miquel Raynal Tested-by: Adam Ford #logicpd-torpedo-37xx-devkit-28.dts Link: https://lore.kernel.org/linux-mtd/20210119155510.5655-1-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/omap2.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c index fbb9955f24671..2c3e65cb68f33 100644 --- a/drivers/mtd/nand/raw/omap2.c +++ b/drivers/mtd/nand/raw/omap2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1866,18 +1867,19 @@ static const struct mtd_ooblayout_ops omap_ooblayout_ops = { static int omap_sw_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { - struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_device *nand = mtd_to_nanddev(mtd); + const struct nand_ecc_sw_bch_conf *engine_conf = nand->ecc.ctx.priv; int off = BADBLOCK_MARKER_LENGTH; - if (section >= chip->ecc.steps) + if (section >= engine_conf->nsteps) return -ERANGE; /* * When SW correction is employed, one OMAP specific marker byte is * reserved after each ECC step. */ - oobregion->offset = off + (section * (chip->ecc.bytes + 1)); - oobregion->length = chip->ecc.bytes; + oobregion->offset = off + (section * (engine_conf->code_size + 1)); + oobregion->length = engine_conf->code_size; return 0; } @@ -1885,7 +1887,8 @@ static int omap_sw_ooblayout_ecc(struct mtd_info *mtd, int section, static int omap_sw_ooblayout_free(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { - struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_device *nand = mtd_to_nanddev(mtd); + const struct nand_ecc_sw_bch_conf *engine_conf = nand->ecc.ctx.priv; int off = BADBLOCK_MARKER_LENGTH; if (section) @@ -1895,7 +1898,7 @@ static int omap_sw_ooblayout_free(struct mtd_info *mtd, int section, * When SW correction is employed, one OMAP specific marker byte is * reserved after each ECC step. */ - off += ((chip->ecc.bytes + 1) * chip->ecc.steps); + off += ((engine_conf->code_size + 1) * engine_conf->nsteps); if (off >= mtd->oobsize) return -ERANGE; -- GitLab From 9bb48c82aced07698a2d08ee0f1475a6c4f6b266 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 19 Jan 2021 11:41:16 -0800 Subject: [PATCH 0414/1084] tty: implement write_iter This makes the tty layer use the .write_iter() function instead of the traditional .write() functionality. That allows writev(), but more importantly also makes it possible to enable .splice_write() for ttys, reinstating the "splice to tty" functionality that was lost in commit 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops"). Fixes: 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops") Reported-by: Oliver Giles Cc: Christoph Hellwig Cc: Greg Kroah-Hartman Cc: Al Viro Signed-off-by: Linus Torvalds --- drivers/tty/tty_io.c | 48 ++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 56ade99ef99f4..338bc4ef55496 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -143,9 +143,8 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ DEFINE_MUTEX(tty_mutex); static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); -static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); -ssize_t redirected_tty_write(struct file *, const char __user *, - size_t, loff_t *); +static ssize_t tty_write(struct kiocb *, struct iov_iter *); +ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *); static __poll_t tty_poll(struct file *, poll_table *); static int tty_open(struct inode *, struct file *); long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); @@ -478,7 +477,8 @@ static void tty_show_fdinfo(struct seq_file *m, struct file *file) static const struct file_operations tty_fops = { .llseek = no_llseek, .read = tty_read, - .write = tty_write, + .write_iter = tty_write, + .splice_write = iter_file_splice_write, .poll = tty_poll, .unlocked_ioctl = tty_ioctl, .compat_ioctl = tty_compat_ioctl, @@ -491,7 +491,8 @@ static const struct file_operations tty_fops = { static const struct file_operations console_fops = { .llseek = no_llseek, .read = tty_read, - .write = redirected_tty_write, + .write_iter = redirected_tty_write, + .splice_write = iter_file_splice_write, .poll = tty_poll, .unlocked_ioctl = tty_ioctl, .compat_ioctl = tty_compat_ioctl, @@ -607,9 +608,9 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) /* This breaks for file handles being sent over AF_UNIX sockets ? */ list_for_each_entry(priv, &tty->tty_files, list) { filp = priv->file; - if (filp->f_op->write == redirected_tty_write) + if (filp->f_op->write_iter == redirected_tty_write) cons_filp = filp; - if (filp->f_op->write != tty_write) + if (filp->f_op->write_iter != tty_write) continue; closecount++; __tty_fasync(-1, filp, 0); /* can't block */ @@ -902,9 +903,9 @@ static inline ssize_t do_tty_write( ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t), struct tty_struct *tty, struct file *file, - const char __user *buf, - size_t count) + struct iov_iter *from) { + size_t count = iov_iter_count(from); ssize_t ret, written = 0; unsigned int chunk; @@ -956,14 +957,20 @@ static inline ssize_t do_tty_write( size_t size = count; if (size > chunk) size = chunk; + ret = -EFAULT; - if (copy_from_user(tty->write_buf, buf, size)) + if (copy_from_iter(tty->write_buf, size, from) != size) break; + ret = write(tty, file, tty->write_buf, size); if (ret <= 0) break; + + /* FIXME! Have Al check this! */ + if (ret != size) + iov_iter_revert(from, size-ret); + written += ret; - buf += ret; count -= ret; if (!count) break; @@ -1023,9 +1030,9 @@ void tty_write_message(struct tty_struct *tty, char *msg) * write method will not be invoked in parallel for each device. */ -static ssize_t tty_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) +static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from) { + struct file *file = iocb->ki_filp; struct tty_struct *tty = file_tty(file); struct tty_ldisc *ld; ssize_t ret; @@ -1038,18 +1045,15 @@ static ssize_t tty_write(struct file *file, const char __user *buf, if (tty->ops->write_room == NULL) tty_err(tty, "missing write_room method\n"); ld = tty_ldisc_ref_wait(tty); - if (!ld) - return hung_up_tty_write(file, buf, count, ppos); - if (!ld->ops->write) + if (!ld || !ld->ops->write) ret = -EIO; else - ret = do_tty_write(ld->ops->write, tty, file, buf, count); + ret = do_tty_write(ld->ops->write, tty, file, from); tty_ldisc_deref(ld); return ret; } -ssize_t redirected_tty_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) +ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) { struct file *p = NULL; @@ -1060,11 +1064,11 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf, if (p) { ssize_t res; - res = vfs_write(p, buf, count, &p->f_pos); + res = vfs_iocb_iter_write(p, iocb, iter); fput(p); return res; } - return tty_write(file, buf, count, ppos); + return tty_write(iocb, iter); } /** @@ -2293,7 +2297,7 @@ static int tioccons(struct file *file) { if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (file->f_op->write == redirected_tty_write) { + if (file->f_op->write_iter == redirected_tty_write) { struct file *f; spin_lock(&redirect_lock); f = redirect; -- GitLab From 389102a3515b53a38858554a915006be7f0b6a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valdis=20Kl=C4=93tnieks?= Date: Fri, 15 Jan 2021 02:07:03 -0500 Subject: [PATCH 0415/1084] scsi: target: iscsi: Fix typo in comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correct the spelling of Nagle's name in a comment. Link: https://lore.kernel.org/r/2921.1610694423@turing-police Reviewed-by: Chaitanya Kulkarni Signed-off-by: Valdis Klētnieks Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/iscsi_target_login.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 893d1b406c292..1a9c50401bdb5 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -896,7 +896,7 @@ int iscsit_setup_np( else len = sizeof(struct sockaddr_in); /* - * Set SO_REUSEADDR, and disable Nagel Algorithm with TCP_NODELAY. + * Set SO_REUSEADDR, and disable Nagle Algorithm with TCP_NODELAY. */ if (np->np_network_transport == ISCSI_TCP) tcp_sock_set_nodelay(sock->sk); -- GitLab From aa2c24e7f415e9c13635cee22ff4e15a80215551 Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Mon, 18 Jan 2021 15:49:22 -0300 Subject: [PATCH 0416/1084] scsi: qla2xxx: Fix description for parameter ql2xenforce_iocb_limit Parameter ql2xenforce_iocb_limit is enabled by default. Link: https://lore.kernel.org/r/20210118184922.23793-1-ematsumiya@suse.de Fixes: 89c72f4245a8 ("scsi: qla2xxx: Add IOCB resource tracking") Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Signed-off-by: Enzo Matsumiya Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index f80abe28f35a4..0e0fe5b094966 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -42,7 +42,7 @@ MODULE_PARM_DESC(ql2xfulldump_on_mpifail, int ql2xenforce_iocb_limit = 1; module_param(ql2xenforce_iocb_limit, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ql2xenforce_iocb_limit, - "Enforce IOCB throttling, to avoid FW congestion. (default: 0)"); + "Enforce IOCB throttling, to avoid FW congestion. (default: 1)"); /* * CT6 CTX allocation cache -- GitLab From c369d7fc8fddc5e5af4aea73dd403681a74c1a86 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 20 Jan 2021 01:10:45 +0100 Subject: [PATCH 0417/1084] net: dsa: microchip: ksz8795: Fix KSZ8794 port map again The KSZ8795 switch has 4 external ports {0,1,2,3} and 1 CPU port {4}, so does the KSZ8765. The KSZ8794 seems to be repackaged KSZ8795 with different ID and port 3 not routed out, however the port 3 registers are present in the silicon, so the KSZ8794 switch has 3 external ports {0,1,2} and 1 CPU port {4}. Currently the driver always uses the last port as CPU port, on KSZ8795/KSZ8765 that is port 4 and that is OK, but on KSZ8794 that is port 3 and that is not OK, as it must also be port 4. This patch adjusts the driver such that it always registers a switch with 5 ports total (4 external ports, 1 CPU port), always sets the CPU port to switch port 4, and then configures the external port mask according to the switch model -- 3 ports for KSZ8794 and 4 for KSZ8795/KSZ8765. Fixes: 68a1b676db52 ("net: dsa: microchip: ksz8795: remove superfluous port_cnt assignment") Fixes: 4ce2a984abd8 ("net: dsa: microchip: ksz8795: use phy_port_cnt where possible") Fixes: 241ed719bc98 ("net: dsa: microchip: ksz8795: use port_cnt instead of TOTOAL_PORT_NUM") Signed-off-by: Marek Vasut Cc: Michael Grzeschik Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Link: https://lore.kernel.org/r/20210120001045.488506-1-marex@denx.de Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz8795.c | 30 +++++++++++++++++--------- drivers/net/dsa/microchip/ksz_common.c | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index c973db101b729..a4570ba29c831 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -1187,6 +1187,20 @@ static const struct ksz_chip_data ksz8795_switch_chips[] = { .port_cnt = 5, /* total cpu and user ports */ }, { + /* + * WARNING + * ======= + * KSZ8794 is similar to KSZ8795, except the port map + * contains a gap between external and CPU ports, the + * port map is NOT continuous. The per-port register + * map is shifted accordingly too, i.e. registers at + * offset 0x40 are NOT used on KSZ8794 and they ARE + * used on KSZ8795 for external port 3. + * external cpu + * KSZ8794 0,1,2 4 + * KSZ8795 0,1,2,3 4 + * KSZ8765 0,1,2,3 4 + */ .chip_id = 0x8794, .dev_name = "KSZ8794", .num_vlans = 4096, @@ -1220,9 +1234,13 @@ static int ksz8795_switch_init(struct ksz_device *dev) dev->num_vlans = chip->num_vlans; dev->num_alus = chip->num_alus; dev->num_statics = chip->num_statics; - dev->port_cnt = chip->port_cnt; + dev->port_cnt = fls(chip->cpu_ports); + dev->cpu_port = fls(chip->cpu_ports) - 1; + dev->phy_port_cnt = dev->port_cnt - 1; dev->cpu_ports = chip->cpu_ports; - + dev->host_mask = chip->cpu_ports; + dev->port_mask = (BIT(dev->phy_port_cnt) - 1) | + chip->cpu_ports; break; } } @@ -1231,17 +1249,9 @@ static int ksz8795_switch_init(struct ksz_device *dev) if (!dev->cpu_ports) return -ENODEV; - dev->port_mask = BIT(dev->port_cnt) - 1; - dev->port_mask |= dev->host_mask; - dev->reg_mib_cnt = KSZ8795_COUNTER_NUM; dev->mib_cnt = ARRAY_SIZE(mib_names); - dev->phy_port_cnt = dev->port_cnt - 1; - - dev->cpu_port = dev->port_cnt - 1; - dev->host_mask = BIT(dev->cpu_port); - dev->ports = devm_kzalloc(dev->dev, dev->port_cnt * sizeof(struct ksz_port), GFP_KERNEL); diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index cf743133b0b93..4899636644438 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -434,7 +434,7 @@ int ksz_switch_register(struct ksz_device *dev, if (of_property_read_u32(port, "reg", &port_num)) continue; - if (port_num >= dev->port_cnt) + if (!(dev->port_mask & BIT(port_num))) return -EINVAL; of_get_phy_mode(port, &dev->ports[port_num].interface); -- GitLab From 1c45ba93d34cd6af75228f34d0675200c81738b5 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 20 Jan 2021 04:05:02 +0100 Subject: [PATCH 0418/1084] net: dsa: microchip: Adjust reset release timing to match reference reset circuit KSZ8794CNX datasheet section 8.0 RESET CIRCUIT describes recommended circuit for interfacing with CPU/FPGA reset consisting of 10k pullup resistor and 10uF capacitor to ground. This circuit takes ~100 ms to rise enough to release the reset. For maximum supply voltage VDDIO=3.3V VIH=2.0V R=10kR C=10uF that is VDDIO - VIH t = R * C * -ln( ------------- ) = 10000*0.00001*-(-0.93)=0.093 s VDDIO so we need ~95 ms for the reset to really de-assert, and then the original 100us for the switch itself to come out of reset. Simply msleep() for 100 ms which fits the constraint with a bit of extra space. Fixes: 5b797980908a ("net: dsa: microchip: Implement recommended reset timing") Reviewed-by: Florian Fainelli Signed-off-by: Marek Vasut Cc: Michael Grzeschik Reviewed-by: Paul Barker Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20210120030502.617185-1-marex@denx.de Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 4899636644438..389abfd277702 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -400,7 +400,7 @@ int ksz_switch_register(struct ksz_device *dev, gpiod_set_value_cansleep(dev->reset_gpio, 1); usleep_range(10000, 12000); gpiod_set_value_cansleep(dev->reset_gpio, 0); - usleep_range(100, 1000); + msleep(100); } mutex_init(&dev->dev_mutex); -- GitLab From 17cbe03872be8878e2f84047424350d036915df1 Mon Sep 17 00:00:00 2001 From: Levi Yun Date: Wed, 20 Jan 2021 21:28:18 +0900 Subject: [PATCH 0419/1084] mm/memblock: Fix typo in comment of memblock_phys_alloc_try_nid() memblock_phys_alloc_try_nid function's comments has typo NUMA as MUMA. Correct this typo. Signed-off-by: Levi Yun Reviewed-by: David Hildenbrand Signed-off-by: Mike Rapoport --- mm/memblock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memblock.c b/mm/memblock.c index d24bcfa88d2f1..1eaaec1e7687c 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1427,7 +1427,7 @@ phys_addr_t __init memblock_phys_alloc_range(phys_addr_t size, } /** - * memblock_phys_alloc_try_nid - allocate a memory block from specified MUMA node + * memblock_phys_alloc_try_nid - allocate a memory block from specified NUMA node * @size: size of memory block to be allocated in bytes * @align: alignment of the region and block's size * @nid: nid of the free area to find, %NUMA_NO_NODE for any node -- GitLab From e1663372d5ffaa3fc79b7932878c5c860f735412 Mon Sep 17 00:00:00 2001 From: Steven Price Date: Fri, 8 Jan 2021 16:12:54 +0000 Subject: [PATCH 0420/1084] KVM: arm64: Compute TPIDR_EL2 ignoring MTE tag KASAN in HW_TAGS mode will store MTE tags in the top byte of the pointer. When computing the offset for TPIDR_EL2 we don't want anything in the top byte, so remove the tag to ensure the computation is correct no matter what the tag. Fixes: 94ab5b61ee16 ("kasan, arm64: enable CONFIG_KASAN_HW_TAGS") Signed-off-by: Steven Price [maz: added comment] Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210108161254.53674-1-steven.price@arm.com --- arch/arm64/kvm/arm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 04c44853b103b..fe60d25c000e4 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1396,8 +1396,9 @@ static void cpu_init_hyp_mode(void) * Calculate the raw per-cpu offset without a translation from the * kernel's mapping to the linear mapping, and store it in tpidr_el2 * so that we can use adr_l to access per-cpu variables in EL2. + * Also drop the KASAN tag which gets in the way... */ - params->tpidr_el2 = (unsigned long)this_cpu_ptr_nvhe_sym(__per_cpu_start) - + params->tpidr_el2 = (unsigned long)kasan_reset_tag(this_cpu_ptr_nvhe_sym(__per_cpu_start)) - (unsigned long)kvm_ksym_ref(CHOOSE_NVHE_SYM(__per_cpu_start)); params->mair_el2 = read_sysreg(mair_el1); -- GitLab From dcb3b06d9c34f33a249f65c08805461fb0c4325b Mon Sep 17 00:00:00 2001 From: Rouven Czerwinski Date: Tue, 5 Jan 2021 11:28:44 +0100 Subject: [PATCH 0421/1084] tee: optee: replace might_sleep with cond_resched might_sleep() is a debugging aid and triggers rescheduling only for certain kernel configurations. Replace with an explicit check and reschedule to work for all kernel configurations. Fixes the following trace: [ 572.945146] rcu: INFO: rcu_sched self-detected stall on CPU [ 572.949275] rcu: 0-....: (2099 ticks this GP) idle=572/1/0x40000002 softirq=7412/7412 fqs=974 [ 572.957964] (t=2100 jiffies g=10393 q=21) [ 572.962054] NMI backtrace for cpu 0 [ 572.965540] CPU: 0 PID: 165 Comm: xtest Not tainted 5.8.7 #1 [ 572.971188] Hardware name: STM32 (Device Tree Support) [ 572.976354] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 572.984080] [] (show_stack) from [] (dump_stack+0xc4/0xd8) [ 572.991300] [] (dump_stack) from [] (nmi_cpu_backtrace+0x90/0xc4) [ 572.999130] [] (nmi_cpu_backtrace) from [] (nmi_trigger_cpumask_backtrace+0xec/0x130) [ 573.008706] [] (nmi_trigger_cpumask_backtrace) from [] (rcu_dump_cpu_stacks+0xe8/0x110) [ 573.018453] [] (rcu_dump_cpu_stacks) from [] (rcu_sched_clock_irq+0x7fc/0xa88) [ 573.027416] [] (rcu_sched_clock_irq) from [] (update_process_times+0x30/0x8c) [ 573.036291] [] (update_process_times) from [] (tick_sched_timer+0x4c/0xa8) [ 573.044905] [] (tick_sched_timer) from [] (__hrtimer_run_queues+0x174/0x358) [ 573.053696] [] (__hrtimer_run_queues) from [] (hrtimer_interrupt+0x118/0x2bc) [ 573.062573] [] (hrtimer_interrupt) from [] (arch_timer_handler_virt+0x28/0x30) [ 573.071536] [] (arch_timer_handler_virt) from [] (handle_percpu_devid_irq+0x8c/0x240) [ 573.081109] [] (handle_percpu_devid_irq) from [] (generic_handle_irq+0x34/0x44) [ 573.090156] [] (generic_handle_irq) from [] (__handle_domain_irq+0x5c/0xb0) [ 573.098857] [] (__handle_domain_irq) from [] (gic_handle_irq+0x4c/0x90) [ 573.107209] [] (gic_handle_irq) from [] (__irq_svc+0x6c/0x90) [ 573.114682] Exception stack(0xd90dfcf8 to 0xd90dfd40) [ 573.119732] fce0: ffff0004 00000000 [ 573.127917] fd00: 00000000 00000000 00000000 00000000 00000000 00000000 d93493cc ffff0000 [ 573.136098] fd20: d2bc39c0 be926998 d90dfd58 d90dfd48 c09f3384 c01151f0 400d0013 ffffffff [ 573.144281] [] (__irq_svc) from [] (__arm_smccc_smc+0x10/0x20) [ 573.151854] [] (__arm_smccc_smc) from [] (optee_smccc_smc+0x3c/0x44) [ 573.159948] [] (optee_smccc_smc) from [] (optee_do_call_with_arg+0xb8/0x154) [ 573.168735] [] (optee_do_call_with_arg) from [] (optee_invoke_func+0x110/0x190) [ 573.177786] [] (optee_invoke_func) from [] (tee_ioctl+0x10b8/0x11c0) [ 573.185879] [] (tee_ioctl) from [] (ksys_ioctl+0xe0/0xa4c) [ 573.193101] [] (ksys_ioctl) from [] (ret_fast_syscall+0x0/0x54) [ 573.200750] Exception stack(0xd90dffa8 to 0xd90dfff0) [ 573.205803] ffa0: be926bf4 be926a78 00000003 8010a403 be926908 004e3cf8 [ 573.213987] ffc0: be926bf4 be926a78 00000000 00000036 be926908 be926918 be9269b0 bffdf0f8 [ 573.222162] ffe0: b6d76fb0 be9268fc b6d66621 b6c7e0d8 seen on STM32 DK2 with CONFIG_PREEMPT_NONE. Fixes: 9f02b8f61f29 ("tee: optee: add might_sleep for RPC requests") Signed-off-by: Rouven Czerwinski Tested-by: Sumit Garg [jw: added fixes tag + small adjustments in the code] Signed-off-by: Jens Wiklander --- drivers/tee/optee/call.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c index c981757ba0d40..780d7c4fd7565 100644 --- a/drivers/tee/optee/call.c +++ b/drivers/tee/optee/call.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -148,7 +149,8 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg) */ optee_cq_wait_for_completion(&optee->call_queue, &w); } else if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) { - might_sleep(); + if (need_resched()) + cond_resched(); param.a0 = res.a0; param.a1 = res.a1; param.a2 = res.a2; -- GitLab From 9529aaa056edc76b3a41df616c71117ebe11e049 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 21 Jan 2021 10:56:36 +0000 Subject: [PATCH 0422/1084] KVM: arm64: Filter out v8.1+ events on v8.0 HW When running on v8.0 HW, make sure we don't try to advertise events in the 0x4000-0x403f range. Cc: stable@vger.kernel.org Fixes: 88865beca9062 ("KVM: arm64: Mask out filtered events in PCMEID{0,1}_EL1") Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210121105636.1478491-1-maz@kernel.org --- arch/arm64/kvm/pmu-emul.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 4ad66a532e38b..247422ac78a9e 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -788,7 +788,7 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1) { unsigned long *bmap = vcpu->kvm->arch.pmu_filter; u64 val, mask = 0; - int base, i; + int base, i, nr_events; if (!pmceid1) { val = read_sysreg(pmceid0_el0); @@ -801,13 +801,17 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1) if (!bmap) return val; + nr_events = kvm_pmu_event_mask(vcpu->kvm) + 1; + for (i = 0; i < 32; i += 8) { u64 byte; byte = bitmap_get_value8(bmap, base + i); mask |= byte << i; - byte = bitmap_get_value8(bmap, 0x4000 + base + i); - mask |= byte << (32 + i); + if (nr_events >= (0x4000 + base + 32)) { + byte = bitmap_get_value8(bmap, 0x4000 + base + i); + mask |= byte << (32 + i); + } } return val & mask; -- GitLab From e45122893a9870813f9bd7b4add4f613e6f29008 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Wed, 20 Jan 2021 21:09:48 -0800 Subject: [PATCH 0423/1084] x86/fpu: Add kernel_fpu_begin_mask() to selectively initialize state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, requesting kernel FPU access doesn't distinguish which parts of the extended ("FPU") state are needed. This is nice for simplicity, but there are a few cases in which it's suboptimal: - The vast majority of in-kernel FPU users want XMM/YMM/ZMM state but do not use legacy 387 state. These users want MXCSR initialized but don't care about the FPU control word. Skipping FNINIT would save time. (Empirically, FNINIT is several times slower than LDMXCSR.) - Code that wants MMX doesn't want or need MXCSR initialized. _mmx_memcpy(), for example, can run before CR4.OSFXSR gets set, and initializing MXCSR will fail because LDMXCSR generates an #UD when the aforementioned CR4 bit is not set. - Any future in-kernel users of XFD (eXtended Feature Disable)-capable dynamic states will need special handling. Add a more specific API that allows callers to specify exactly what they want. Signed-off-by: Andy Lutomirski Signed-off-by: Borislav Petkov Tested-by: Krzysztof Piotr Olędzki Link: https://lkml.kernel.org/r/aff1cac8b8fc7ee900cf73e8f2369966621b053f.1611205691.git.luto@kernel.org --- arch/x86/include/asm/fpu/api.h | 15 +++++++++++++-- arch/x86/kernel/fpu/core.c | 9 +++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h index a5aba4ab02248..67a4f1cb2aac5 100644 --- a/arch/x86/include/asm/fpu/api.h +++ b/arch/x86/include/asm/fpu/api.h @@ -16,14 +16,25 @@ * Use kernel_fpu_begin/end() if you intend to use FPU in kernel context. It * disables preemption so be careful if you intend to use it for long periods * of time. - * If you intend to use the FPU in softirq you need to check first with + * If you intend to use the FPU in irq/softirq you need to check first with * irq_fpu_usable() if it is possible. */ -extern void kernel_fpu_begin(void); + +/* Kernel FPU states to initialize in kernel_fpu_begin_mask() */ +#define KFPU_387 _BITUL(0) /* 387 state will be initialized */ +#define KFPU_MXCSR _BITUL(1) /* MXCSR will be initialized */ + +extern void kernel_fpu_begin_mask(unsigned int kfpu_mask); extern void kernel_fpu_end(void); extern bool irq_fpu_usable(void); extern void fpregs_mark_activate(void); +/* Code that is unaware of kernel_fpu_begin_mask() can use this */ +static inline void kernel_fpu_begin(void) +{ + kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR); +} + /* * Use fpregs_lock() while editing CPU's FPU registers or fpu->state. * A context switch will (and softirq might) save CPU's FPU registers to diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index eb86a2b831b15..571220ac8beaa 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -121,7 +121,7 @@ int copy_fpregs_to_fpstate(struct fpu *fpu) } EXPORT_SYMBOL(copy_fpregs_to_fpstate); -void kernel_fpu_begin(void) +void kernel_fpu_begin_mask(unsigned int kfpu_mask) { preempt_disable(); @@ -141,13 +141,14 @@ void kernel_fpu_begin(void) } __cpu_invalidate_fpregs_state(); - if (boot_cpu_has(X86_FEATURE_XMM)) + /* Put sane initial values into the control registers. */ + if (likely(kfpu_mask & KFPU_MXCSR) && boot_cpu_has(X86_FEATURE_XMM)) ldmxcsr(MXCSR_DEFAULT); - if (boot_cpu_has(X86_FEATURE_FPU)) + if (unlikely(kfpu_mask & KFPU_387) && boot_cpu_has(X86_FEATURE_FPU)) asm volatile ("fninit"); } -EXPORT_SYMBOL_GPL(kernel_fpu_begin); +EXPORT_SYMBOL_GPL(kernel_fpu_begin_mask); void kernel_fpu_end(void) { -- GitLab From 51dfb6ca3728bd0a0a3c23776a12d2a15a1d2457 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Wed, 20 Jan 2021 23:58:44 +0300 Subject: [PATCH 0424/1084] regulator: consumer: Add missing stubs to regulator/consumer.h Add missing stubs to regulator/consumer.h in order to fix COMPILE_TEST of the kernel. In particular this should fix compile-testing of OPP core because of a missing stub for regulator_sync_voltage(). Reported-by: kernel test robot Signed-off-by: Dmitry Osipenko Link: https://lore.kernel.org/r/20210120205844.12658-1-digetx@gmail.com Signed-off-by: Mark Brown --- include/linux/regulator/consumer.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 2024944fd2f78..20e84a84fb779 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -331,6 +331,12 @@ regulator_get_exclusive(struct device *dev, const char *id) return ERR_PTR(-ENODEV); } +static inline struct regulator *__must_check +devm_regulator_get_exclusive(struct device *dev, const char *id) +{ + return ERR_PTR(-ENODEV); +} + static inline struct regulator *__must_check regulator_get_optional(struct device *dev, const char *id) { @@ -486,6 +492,11 @@ static inline int regulator_get_voltage(struct regulator *regulator) return -EINVAL; } +static inline int regulator_sync_voltage(struct regulator *regulator) +{ + return -EINVAL; +} + static inline int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV) { @@ -578,6 +589,25 @@ static inline int devm_regulator_unregister_notifier(struct regulator *regulator return 0; } +static inline int regulator_suspend_enable(struct regulator_dev *rdev, + suspend_state_t state) +{ + return -EINVAL; +} + +static inline int regulator_suspend_disable(struct regulator_dev *rdev, + suspend_state_t state) +{ + return -EINVAL; +} + +static inline int regulator_set_suspend_voltage(struct regulator *regulator, + int min_uV, int max_uV, + suspend_state_t state) +{ + return -EINVAL; +} + static inline void *regulator_get_drvdata(struct regulator *regulator) { return NULL; -- GitLab From d52bbf747cfa8a2988289009241214a84982cc7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 20 Jan 2021 16:28:44 +0100 Subject: [PATCH 0425/1084] ASoC: topology: KUnit: Add KUnit tests passing various arguments to snd_soc_tplg_component_load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to ensure correct behaviour of topology API, add unit tests exercising topology functionality. Start with adding cases for passing various arguments to snd_soc_tplg_component_load as it is part of exposed topology API. First test case adds test passing NULL component as argument. Following one adds test case for passing NULL ops as argument. Finally add test case passing NULL fw as argument. Signed-off-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210120152846.1703655-4-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/Kconfig | 17 ++ sound/soc/Makefile | 5 + sound/soc/soc-topology-test.c | 303 ++++++++++++++++++++++++++++++++++ 3 files changed, 325 insertions(+) create mode 100644 sound/soc/soc-topology-test.c diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index ba79d5f4e2995..640494f76cbd1 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -37,6 +37,23 @@ config SND_SOC_COMPRESS config SND_SOC_TOPOLOGY bool +config SND_SOC_TOPOLOGY_KUNIT_TESTS + tristate "KUnit tests for SoC topology" + depends on KUNIT + depends on SND_SOC_TOPOLOGY + default KUNIT_ALL_TESTS + help + If you want to perform tests on ALSA SoC topology support say Y here. + + This builds a module which can be later manually loaded to run KUNIT + test cases against soc-topology.c API. This should be primarily used + by developers to test their changes to ASoC. + + Do note that it creates fake playback devices which do not interact + well with userspace. When running tests one may want to disable + userspace applications such as pulseaudio, to prevent unnecessary + problems. + config SND_SOC_ACPI tristate diff --git a/sound/soc/Makefile b/sound/soc/Makefile index eee370492eeeb..f56ad996eae88 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -7,6 +7,11 @@ ifneq ($(CONFIG_SND_SOC_TOPOLOGY),) snd-soc-core-objs += soc-topology.o endif +ifneq ($(CONFIG_SND_SOC_TOPOLOGY_KUNIT_TESTS),) +# snd-soc-test-objs := soc-topology-test.o +obj-$(CONFIG_SND_SOC_TOPOLOGY_KUNIT_TESTS) := soc-topology-test.o +endif + ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) snd-soc-core-objs += soc-generic-dmaengine-pcm.o endif diff --git a/sound/soc/soc-topology-test.c b/sound/soc/soc-topology-test.c new file mode 100644 index 0000000000000..7276ed95d83db --- /dev/null +++ b/sound/soc/soc-topology-test.c @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * soc-topology-test.c -- ALSA SoC Topology Kernel Unit Tests + * + * Copyright(c) 2021 Intel Corporation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +/* ===== HELPER FUNCTIONS =================================================== */ + +/* + * snd_soc_component needs device to operate on (primarily for prints), create + * fake one, as we don't register with PCI or anything else + * device_driver name is used in some of the prints (fmt_single_name) so + * we also mock up minimal one + */ +static struct device *test_dev; + +static struct device_driver test_drv = { + .name = "sound-soc-topology-test-driver", +}; + +static int snd_soc_tplg_test_init(struct kunit *test) +{ + test_dev = root_device_register("sound-soc-topology-test"); + test_dev = get_device(test_dev); + if (!test_dev) + return -ENODEV; + + test_dev->driver = &test_drv; + + return 0; +} + +static void snd_soc_tplg_test_exit(struct kunit *test) +{ + put_device(test_dev); + root_device_unregister(test_dev); +} + +/* + * helper struct we use when registering component, as we load topology during + * component probe, we need to pass struct kunit somehow to probe function, so + * we can report test result + */ +struct kunit_soc_component { + struct kunit *kunit; + int expect; /* what result we expect when loading topology */ + struct snd_soc_component comp; + struct snd_soc_card card; + struct firmware fw; +}; + +static int d_probe(struct snd_soc_component *component) +{ + struct kunit_soc_component *kunit_comp = + container_of(component, struct kunit_soc_component, comp); + int ret; + + ret = snd_soc_tplg_component_load(component, NULL, &kunit_comp->fw); + KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret, + "Failed topology load"); + + return 0; +} + +static void d_remove(struct snd_soc_component *component) +{ + struct kunit_soc_component *kunit_comp = + container_of(component, struct kunit_soc_component, comp); + int ret; + + ret = snd_soc_tplg_component_remove(component); + KUNIT_EXPECT_EQ(kunit_comp->kunit, 0, ret); +} + +/* + * ASoC minimal boiler plate + */ +SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); + +SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("sound-soc-topology-test"))); + +static struct snd_soc_dai_link kunit_dai_links[] = { + { + .name = "KUNIT Audio Port", + .id = 0, + .stream_name = "Audio Playback/Capture", + .nonatomic = 1, + .dynamic = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .dpcm_playback = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(dummy, dummy, platform), + }, +}; + +static const struct snd_soc_component_driver test_component = { + .name = "sound-soc-topology-test", + .probe = d_probe, + .remove = d_remove, + .non_legacy_dai_naming = 1, +}; + +/* ===== TEST CASES ========================================================= */ + +// TEST CASE +// Test passing NULL component as parameter to snd_soc_tplg_component_load + +/* + * need to override generic probe function with one using NULL when calling + * topology load during component initialization, we don't need .remove + * handler as load should fail + */ +static int d_probe_null_comp(struct snd_soc_component *component) +{ + struct kunit_soc_component *kunit_comp = + container_of(component, struct kunit_soc_component, comp); + int ret; + + /* instead of passing component pointer as first argument, pass NULL here */ + ret = snd_soc_tplg_component_load(NULL, NULL, &kunit_comp->fw); + KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret, + "Failed topology load"); + + return 0; +} + +static const struct snd_soc_component_driver test_component_null_comp = { + .name = "sound-soc-topology-test", + .probe = d_probe_null_comp, + .non_legacy_dai_naming = 1, +}; + +static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + int ret; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = -EINVAL; /* expect failure */ + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_comp, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + /* cleanup */ + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); + + snd_soc_unregister_component(test_dev); +} + +// TEST CASE +// Test passing NULL ops as parameter to snd_soc_tplg_component_load + +/* + * NULL ops is default case, we pass empty topology (fw), so we don't have + * anything to parse and just do nothing, which results in return 0; from + * calling soc_tplg_dapm_complete in soc_tplg_process_headers + */ +static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + int ret; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = 0; /* expect success */ + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + /* cleanup */ + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); + + snd_soc_unregister_component(test_dev); +} + +// TEST CASE +// Test passing NULL fw as parameter to snd_soc_tplg_component_load + +/* + * need to override generic probe function with one using NULL pointer to fw + * when calling topology load during component initialization, we don't need + * .remove handler as load should fail + */ +static int d_probe_null_fw(struct snd_soc_component *component) +{ + struct kunit_soc_component *kunit_comp = + container_of(component, struct kunit_soc_component, comp); + int ret; + + /* instead of passing fw pointer as third argument, pass NULL here */ + ret = snd_soc_tplg_component_load(component, NULL, NULL); + KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret, + "Failed topology load"); + + return 0; +} + +static const struct snd_soc_component_driver test_component_null_fw = { + .name = "sound-soc-topology-test", + .probe = d_probe_null_fw, + .non_legacy_dai_naming = 1, +}; + +static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + int ret; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = -EINVAL; /* expect failure */ + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_fw, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + /* cleanup */ + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); + + snd_soc_unregister_component(test_dev); +} + +/* ===== KUNIT MODULE DEFINITIONS =========================================== */ + +static struct kunit_case snd_soc_tplg_test_cases[] = { + KUNIT_CASE(snd_soc_tplg_test_load_with_null_comp), + KUNIT_CASE(snd_soc_tplg_test_load_with_null_ops), + KUNIT_CASE(snd_soc_tplg_test_load_with_null_fw), + {} +}; + +static struct kunit_suite snd_soc_tplg_test_suite = { + .name = "snd_soc_tplg_test", + .init = snd_soc_tplg_test_init, + .exit = snd_soc_tplg_test_exit, + .test_cases = snd_soc_tplg_test_cases, +}; + +kunit_test_suites(&snd_soc_tplg_test_suite); + +MODULE_LICENSE("GPL"); -- GitLab From cec9128dfcf9101f903470e43d46278e5b07ef24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 20 Jan 2021 16:28:45 +0100 Subject: [PATCH 0426/1084] ASoC: topology: KUnit: Add KUnit tests passing empty topology with variants to snd_soc_tplg_component_load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to ensure correct behaviour of topology API, add unit tests exercising topology functionality. Add "empty" topology template and tests for parsing it. Also adds few variants with bad magic numbers. Signed-off-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210120152846.1703655-5-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology-test.c | 311 +++++++++++++++++++++++++++++++++- 1 file changed, 310 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-topology-test.c b/sound/soc/soc-topology-test.c index 7276ed95d83db..bae40c111f9b9 100644 --- a/sound/soc/soc-topology-test.c +++ b/sound/soc/soc-topology-test.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include @@ -108,6 +107,37 @@ static const struct snd_soc_component_driver test_component = { .non_legacy_dai_naming = 1, }; +/* ===== TOPOLOGY TEMPLATES ================================================= */ + +// Structural representation of topology which can be generated with: +// $ touch empty +// $ alsatplg -c empty -o empty.tplg +// $ xxd -i empty.tplg + +struct tplg_tmpl_001 { + struct snd_soc_tplg_hdr header; + struct snd_soc_tplg_manifest manifest; +} __packed; + +static struct tplg_tmpl_001 tplg_tmpl_empty = { + .header = { + .magic = SND_SOC_TPLG_MAGIC, + .abi = 5, + .version = 0, + .type = SND_SOC_TPLG_TYPE_MANIFEST, + .size = sizeof(struct snd_soc_tplg_hdr), + .vendor_type = 0, + .payload_size = sizeof(struct snd_soc_tplg_manifest), + .index = 0, + .count = 1, + }, + + .manifest = { + .size = sizeof(struct snd_soc_tplg_manifest), + /* rest of fields is 0 */ + }, +}; + /* ===== TEST CASES ========================================================= */ // TEST CASE @@ -282,12 +312,291 @@ static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test) snd_soc_unregister_component(test_dev); } +// TEST CASE +// Test passing "empty" topology file +static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + struct tplg_tmpl_001 *data; + int size; + int ret; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = 0; /* expect success */ + + size = sizeof(tplg_tmpl_empty); + data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data); + + memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty)); + + kunit_comp->fw.data = (u8 *)data; + kunit_comp->fw.size = size; + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + /* cleanup */ + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); + + snd_soc_unregister_component(test_dev); +} + +// TEST CASE +// Test "empty" topology file, but with bad "magic" +// In theory we could loop through all possible bad values, but it takes too +// long, so just use SND_SOC_TPLG_MAGIC + 1 +static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + struct tplg_tmpl_001 *data; + int size; + int ret; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = -EINVAL; /* expect failure */ + + size = sizeof(tplg_tmpl_empty); + data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data); + + memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty)); + /* + * override abi + * any value != magic number is wrong + */ + data->header.magic = SND_SOC_TPLG_MAGIC + 1; + + kunit_comp->fw.data = (u8 *)data; + kunit_comp->fw.size = size; + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + /* cleanup */ + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); + + snd_soc_unregister_component(test_dev); +} + +// TEST CASE +// Test "empty" topology file, but with bad "abi" +// In theory we could loop through all possible bad values, but it takes too +// long, so just use SND_SOC_TPLG_ABI_VERSION + 1 +static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + struct tplg_tmpl_001 *data; + int size; + int ret; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = -EINVAL; /* expect failure */ + + size = sizeof(tplg_tmpl_empty); + data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data); + + memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty)); + /* + * override abi + * any value != accepted range is wrong + */ + data->header.abi = SND_SOC_TPLG_ABI_VERSION + 1; + + kunit_comp->fw.data = (u8 *)data; + kunit_comp->fw.size = size; + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + /* cleanup */ + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); + + snd_soc_unregister_component(test_dev); +} + +// TEST CASE +// Test "empty" topology file, but with bad "size" +// In theory we could loop through all possible bad values, but it takes too +// long, so just use sizeof(struct snd_soc_tplg_hdr) + 1 +static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + struct tplg_tmpl_001 *data; + int size; + int ret; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = -EINVAL; /* expect failure */ + + size = sizeof(tplg_tmpl_empty); + data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data); + + memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty)); + /* + * override size + * any value != struct size is wrong + */ + data->header.size = sizeof(struct snd_soc_tplg_hdr) + 1; + + kunit_comp->fw.data = (u8 *)data; + kunit_comp->fw.size = size; + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + /* cleanup */ + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); + + snd_soc_unregister_component(test_dev); +} + +// TEST CASE +// Test "empty" topology file, but with bad "payload_size" +// In theory we could loop through all possible bad values, but it takes too +// long, so just use the known wrong one +static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + struct tplg_tmpl_001 *data; + int size; + int ret; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = -EINVAL; /* expect failure */ + + size = sizeof(tplg_tmpl_empty); + data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data); + + memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty)); + /* + * override payload size + * there is only explicit check for 0, so check with it, other values + * are handled by just not reading behind EOF + */ + data->header.payload_size = 0; + + kunit_comp->fw.data = (u8 *)data; + kunit_comp->fw.size = size; + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + /* cleanup */ + snd_soc_unregister_component(test_dev); + + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); +} + /* ===== KUNIT MODULE DEFINITIONS =========================================== */ static struct kunit_case snd_soc_tplg_test_cases[] = { KUNIT_CASE(snd_soc_tplg_test_load_with_null_comp), KUNIT_CASE(snd_soc_tplg_test_load_with_null_ops), KUNIT_CASE(snd_soc_tplg_test_load_with_null_fw), + KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg), + KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_magic), + KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_abi), + KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_size), + KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_payload_size), {} }; -- GitLab From 3ad8c8e9efc53d14d928b84aabe1a27dd5d3171b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 20 Jan 2021 16:28:46 +0100 Subject: [PATCH 0427/1084] ASoC: topology: KUnit: Add KUnit tests passing topology with PCM to snd_soc_tplg_component_load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to ensure correct behaviour of topology API, add unit tests exercising topology functionality. Add topology containing PCM template and tests for parsing it. Also adds test cases simulating modules reloads in case of separate drivers for card and component. Signed-off-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210120152846.1703655-6-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology-test.c | 231 ++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) diff --git a/sound/soc/soc-topology-test.c b/sound/soc/soc-topology-test.c index bae40c111f9b9..36e2a3486dbfb 100644 --- a/sound/soc/soc-topology-test.c +++ b/sound/soc/soc-topology-test.c @@ -138,6 +138,79 @@ static struct tplg_tmpl_001 tplg_tmpl_empty = { }, }; +// Structural representation of topology containing SectionPCM + +struct tplg_tmpl_002 { + struct snd_soc_tplg_hdr header; + struct snd_soc_tplg_manifest manifest; + struct snd_soc_tplg_hdr pcm_header; + struct snd_soc_tplg_pcm pcm; +} __packed; + +static struct tplg_tmpl_002 tplg_tmpl_with_pcm = { + .header = { + .magic = SND_SOC_TPLG_MAGIC, + .abi = 5, + .version = 0, + .type = SND_SOC_TPLG_TYPE_MANIFEST, + .size = sizeof(struct snd_soc_tplg_hdr), + .vendor_type = 0, + .payload_size = sizeof(struct snd_soc_tplg_manifest), + .index = 0, + .count = 1, + }, + .manifest = { + .size = sizeof(struct snd_soc_tplg_manifest), + .pcm_elems = 1, + /* rest of fields is 0 */ + }, + .pcm_header = { + .magic = SND_SOC_TPLG_MAGIC, + .abi = 5, + .version = 0, + .type = SND_SOC_TPLG_TYPE_PCM, + .size = sizeof(struct snd_soc_tplg_hdr), + .vendor_type = 0, + .payload_size = sizeof(struct snd_soc_tplg_pcm), + .index = 0, + .count = 1, + }, + .pcm = { + .size = sizeof(struct snd_soc_tplg_pcm), + .pcm_name = "KUNIT Audio", + .dai_name = "kunit-audio-dai", + .pcm_id = 0, + .dai_id = 0, + .playback = 1, + .capture = 1, + .compress = 0, + .stream = { + [0] = { + .channels = 2, + }, + [1] = { + .channels = 2, + }, + }, + .num_streams = 0, + .caps = { + [0] = { + .name = "kunit-audio-playback", + .channels_min = 2, + .channels_max = 2, + }, + [1] = { + .name = "kunit-audio-capture", + .channels_min = 2, + .channels_max = 2, + }, + }, + .flag_mask = 0, + .flags = 0, + .priv = { 0 }, + }, +}; + /* ===== TEST CASES ========================================================= */ // TEST CASE @@ -586,6 +659,161 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *tes KUNIT_EXPECT_EQ(test, 0, ret); } +// TEST CASE +// Test passing topology file with PCM definition +static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + u8 *data; + int size; + int ret; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = 0; /* expect success */ + + size = sizeof(tplg_tmpl_with_pcm); + data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data); + + memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm)); + + kunit_comp->fw.data = data; + kunit_comp->fw.size = size; + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + snd_soc_unregister_component(test_dev); + + /* cleanup */ + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); +} + +// TEST CASE +// Test passing topology file with PCM definition +// with component reload +static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + u8 *data; + int size; + int ret; + int i; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = 0; /* expect success */ + + size = sizeof(tplg_tmpl_with_pcm); + data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data); + + memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm)); + + kunit_comp->fw.data = data; + kunit_comp->fw.size = size; + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + for (i = 0; i < 100; i++) { + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + snd_soc_unregister_component(test_dev); + } + + /* cleanup */ + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); +} + +// TEST CASE +// Test passing topology file with PCM definition +// with card reload +static void snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit *test) +{ + struct kunit_soc_component *kunit_comp; + u8 *data; + int size; + int ret; + int i; + + /* prepare */ + kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp); + kunit_comp->kunit = test; + kunit_comp->expect = 0; /* expect success */ + + size = sizeof(tplg_tmpl_with_pcm); + data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data); + + memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm)); + + kunit_comp->fw.data = data; + kunit_comp->fw.size = size; + + kunit_comp->card.dev = test_dev, + kunit_comp->card.name = "kunit-card", + kunit_comp->card.owner = THIS_MODULE, + kunit_comp->card.dai_link = kunit_dai_links, + kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links), + kunit_comp->card.fully_routed = true, + + /* run test */ + ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); + KUNIT_EXPECT_EQ(test, 0, ret); + + ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + KUNIT_EXPECT_EQ(test, 0, ret); + + for (i = 0; i < 100; i++) { + ret = snd_soc_register_card(&kunit_comp->card); + if (ret != 0 && ret != -EPROBE_DEFER) + KUNIT_FAIL(test, "Failed to register card"); + + ret = snd_soc_unregister_card(&kunit_comp->card); + KUNIT_EXPECT_EQ(test, 0, ret); + } + + /* cleanup */ + snd_soc_unregister_component(test_dev); +} + /* ===== KUNIT MODULE DEFINITIONS =========================================== */ static struct kunit_case snd_soc_tplg_test_cases[] = { @@ -597,6 +825,9 @@ static struct kunit_case snd_soc_tplg_test_cases[] = { KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_abi), KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_size), KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_payload_size), + KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg), + KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_comp), + KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_card), {} }; -- GitLab From d40ab86f7db3612074d08a317bdb1eb8ba06a37e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Thu, 14 Jan 2021 11:36:01 -0500 Subject: [PATCH 0428/1084] ASoC: topology: Ensure that needed parameters are set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As snd_soc_tplg_component_load is exported function, which means it is part of API, there should be checks if it is called with proper parameters. Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20210114163602.911205-2-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 950c45008e245..0d182a190c988 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -2659,8 +2659,14 @@ int snd_soc_tplg_component_load(struct snd_soc_component *comp, struct soc_tplg tplg; int ret; - /* component needs to exist to keep and reference data while parsing */ - if (!comp) + /* + * check if we have sane parameters: + * comp - needs to exist to keep and reference data while parsing + * comp->dev - used for resource management and prints + * comp->card - used for setting card related parameters + * fw - we need it, as it is the very thing we parse + */ + if (!comp || !comp->dev || !comp->card || !fw) return -EINVAL; /* setup parsing context */ -- GitLab From 9c88a9838352c43550ab18080c924824bc660546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Thu, 14 Jan 2021 11:36:02 -0500 Subject: [PATCH 0429/1084] ASoC: topology: Check if ops is set before dereference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Topology can be created without ops overrides, in that case trying to assign any value would lead to dereferencing NULL pointer. Other places in code have either checks for tplg->ops or loop using *_count variables, hence they can't dereference NULL pointer and there is no need to add more checks. Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20210114163602.911205-3-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 0d182a190c988..5476854c12b00 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -2674,11 +2674,13 @@ int snd_soc_tplg_component_load(struct snd_soc_component *comp, tplg.fw = fw; tplg.dev = comp->dev; tplg.comp = comp; - tplg.ops = ops; - tplg.io_ops = ops->io_ops; - tplg.io_ops_count = ops->io_ops_count; - tplg.bytes_ext_ops = ops->bytes_ext_ops; - tplg.bytes_ext_ops_count = ops->bytes_ext_ops_count; + if (ops) { + tplg.ops = ops; + tplg.io_ops = ops->io_ops; + tplg.io_ops_count = ops->io_ops_count; + tplg.bytes_ext_ops = ops->bytes_ext_ops; + tplg.bytes_ext_ops_count = ops->bytes_ext_ops_count; + } ret = soc_tplg_load(&tplg); /* free the created components if fail to load topology */ -- GitLab From 80f454e283708c28f5220eda68511fc495e5ffaf Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:52:38 +0900 Subject: [PATCH 0430/1084] ASoC: soc-pcm: revert soc_pcm_apply_symmetry() commit a39748d03cbc ("ASoC: soc-pcm: cleanup soc_pcm_apply_symmetry()") was applied by miscommunication. To more cleanup code, and to be easy review, this patch reverts it. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87y2guoljm.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 67 +++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index f62136f16c2f9..6e9f14d482abe 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -349,26 +349,53 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); int ret; -#define __soc_pcm_apply_symmetry(name, sname, NAME) \ - if (soc_dai->name && (soc_dai->driver->symmetric_##sname || \ - rtd->dai_link->symmetric_##sname)) { \ - dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %s to %d\n",\ - #name, soc_dai->name); \ - \ - ret = snd_pcm_hw_constraint_single(substream->runtime, \ - SNDRV_PCM_HW_PARAM_##NAME,\ - soc_dai->name); \ - if (ret < 0) { \ - dev_err(soc_dai->dev, \ - "ASoC: Unable to apply %s constraint: %d\n",\ - #name, ret); \ - return ret; \ - } \ - } - - __soc_pcm_apply_symmetry(rate, rates, RATE); - __soc_pcm_apply_symmetry(channels, channels, CHANNELS); - __soc_pcm_apply_symmetry(sample_bits, samplebits, SAMPLE_BITS); + if (soc_dai->rate && (soc_dai->driver->symmetric_rates || + rtd->dai_link->symmetric_rates)) { + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", + soc_dai->rate); + + ret = snd_pcm_hw_constraint_single(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, + soc_dai->rate); + if (ret < 0) { + dev_err(soc_dai->dev, + "ASoC: Unable to apply rate constraint: %d\n", + ret); + return ret; + } + } + + if (soc_dai->channels && (soc_dai->driver->symmetric_channels || + rtd->dai_link->symmetric_channels)) { + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n", + soc_dai->channels); + + ret = snd_pcm_hw_constraint_single(substream->runtime, + SNDRV_PCM_HW_PARAM_CHANNELS, + soc_dai->channels); + if (ret < 0) { + dev_err(soc_dai->dev, + "ASoC: Unable to apply channel symmetry constraint: %d\n", + ret); + return ret; + } + } + + if (soc_dai->sample_bits && (soc_dai->driver->symmetric_samplebits || + rtd->dai_link->symmetric_samplebits)) { + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n", + soc_dai->sample_bits); + + ret = snd_pcm_hw_constraint_single(substream->runtime, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + soc_dai->sample_bits); + if (ret < 0) { + dev_err(soc_dai->dev, + "ASoC: Unable to apply sample bits symmetry constraint: %d\n", + ret); + return ret; + } + } return 0; } -- GitLab From f14654ddf2e982537ab476d392a87fcbf90374c3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:52:54 +0900 Subject: [PATCH 0431/1084] ASoC: sync parameter naming : rate / sample_bits snd_pcm_runtime / snd_soc_dai / snd_soc_dai_driver / snd_soc_dai_link have related parameter which is similar but not same naming. struct snd_pcm_runtime { ... (A) unsigned int rate; ... (B) unsigned int sample_bits; ... }; struct snd_soc_dai { ... (A) unsigned int rate; (B) unsigned int sample_bits; ... }; struct snd_soc_dai_driver { ... (A) unsigned int symmetric_rates:1; (B) unsigned int symmetric_samplebits:1; ... }; struct snd_soc_dai_link { ... (A) unsigned int symmetric_rates:1; (B) unsigned int symmetric_samplebits:1; ... }; Because it is similar but not same naming rule, code can be verbose / can't share macro. This patch sync naming rule for framework. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; old name will be removed if all drivers were switched to new naming rule. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87wnweolj6.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 6 ++++-- include/sound/soc.h | 4 ++-- sound/soc/rockchip/rockchip_i2s.c | 2 +- sound/soc/soc-core.c | 9 +++++++++ sound/soc/soc-pcm.c | 24 ++++++++++++------------ sound/soc/soc-topology.c | 8 ++++---- 6 files changed, 32 insertions(+), 21 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 34d0dbf73ca9c..ee3c6deb57191 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -353,9 +353,11 @@ struct snd_soc_dai_driver { /* DAI capabilities */ struct snd_soc_pcm_stream capture; struct snd_soc_pcm_stream playback; - unsigned int symmetric_rates:1; + unsigned int symmetric_rates:1; /* will be removed */ + unsigned int symmetric_rate:1; unsigned int symmetric_channels:1; - unsigned int symmetric_samplebits:1; + unsigned int symmetric_samplebits:1; /* will be removed */ + unsigned int symmetric_sample_bits:1; /* probe ordering - for components with runtime dependencies */ int probe_order; diff --git a/include/sound/soc.h b/include/sound/soc.h index 3fa6c40a63b7e..bd38015d6c6d8 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -685,9 +685,9 @@ struct snd_soc_dai_link { unsigned int ignore_suspend:1; /* Symmetry requirements */ - unsigned int symmetric_rates:1; + unsigned int symmetric_rate:1; unsigned int symmetric_channels:1; - unsigned int symmetric_samplebits:1; + unsigned int symmetric_sample_bits:1; /* Do not create a PCM for this DAI link (Backend link) */ unsigned int no_pcm:1; diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index eae287d905eb2..662de86eca118 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -373,7 +373,7 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, I2S_DMACR_RDL(16)); val = I2S_CKR_TRCM_TXRX; - if (dai->driver->symmetric_rates && rtd->dai_link->symmetric_rates) + if (dai->driver->symmetric_rate && rtd->dai_link->symmetric_rate) val = I2S_CKR_TRCM_TXONLY; regmap_update_bits(i2s->regmap, I2S_CKR, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f6d4e99b590c7..bb8323cad51ad 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2509,6 +2509,15 @@ int snd_soc_register_component(struct device *dev, { struct snd_soc_component *component; int ret; + int i; + + /* Remove ME */ + for (i = 0; i < num_dai; i++) { + if (dai_drv[i].symmetric_rates) + dai_drv[i].symmetric_rate = dai_drv[i].symmetric_rates; + if (dai_drv[i].symmetric_samplebits) + dai_drv[i].symmetric_sample_bits = dai_drv[i].symmetric_samplebits; + } component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL); if (!component) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 6e9f14d482abe..1a5d0cb3dc697 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -349,8 +349,8 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); int ret; - if (soc_dai->rate && (soc_dai->driver->symmetric_rates || - rtd->dai_link->symmetric_rates)) { + if (soc_dai->rate && (soc_dai->driver->symmetric_rate || + rtd->dai_link->symmetric_rate)) { dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", soc_dai->rate); @@ -381,8 +381,8 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, } } - if (soc_dai->sample_bits && (soc_dai->driver->symmetric_samplebits || - rtd->dai_link->symmetric_samplebits)) { + if (soc_dai->sample_bits && (soc_dai->driver->symmetric_sample_bits || + rtd->dai_link->symmetric_sample_bits)) { dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n", soc_dai->sample_bits); @@ -412,10 +412,10 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, soc_pcm_set_dai_params(&d, params); /* reject unmatched parameters when applying symmetry */ - symmetry = rtd->dai_link->symmetric_rates; + symmetry = rtd->dai_link->symmetric_rate; for_each_rtd_cpu_dais(rtd, i, dai) - symmetry |= dai->driver->symmetric_rates; + symmetry |= dai->driver->symmetric_rate; if (symmetry) { for_each_rtd_cpu_dais(rtd, i, cpu_dai) { @@ -443,10 +443,10 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, } } - symmetry = rtd->dai_link->symmetric_samplebits; + symmetry = rtd->dai_link->symmetric_sample_bits; for_each_rtd_dais(rtd, i, dai) - symmetry |= dai->driver->symmetric_samplebits; + symmetry |= dai->driver->symmetric_sample_bits; if (symmetry) { for_each_rtd_cpu_dais(rtd, i, cpu_dai) { @@ -469,15 +469,15 @@ static bool soc_pcm_has_symmetry(struct snd_pcm_substream *substream) struct snd_soc_dai *dai; unsigned int symmetry, i; - symmetry = link->symmetric_rates || + symmetry = link->symmetric_rate || link->symmetric_channels || - link->symmetric_samplebits; + link->symmetric_sample_bits; for_each_rtd_dais(rtd, i, dai) symmetry = symmetry || - dai->driver->symmetric_rates || + dai->driver->symmetric_rate || dai->driver->symmetric_channels || - dai->driver->symmetric_samplebits; + dai->driver->symmetric_sample_bits; return symmetry; } diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 950c45008e245..27f7dd8fb7f69 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1672,7 +1672,7 @@ static void set_dai_flags(struct snd_soc_dai_driver *dai_drv, unsigned int flag_mask, unsigned int flags) { if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES) - dai_drv->symmetric_rates = + dai_drv->symmetric_rate = flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES ? 1 : 0; if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS) @@ -1681,7 +1681,7 @@ static void set_dai_flags(struct snd_soc_dai_driver *dai_drv, 1 : 0; if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS) - dai_drv->symmetric_samplebits = + dai_drv->symmetric_sample_bits = flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS ? 1 : 0; } @@ -1763,7 +1763,7 @@ static void set_link_flags(struct snd_soc_dai_link *link, unsigned int flag_mask, unsigned int flags) { if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES) - link->symmetric_rates = + link->symmetric_rate = flags & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES ? 1 : 0; if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_CHANNELS) @@ -1772,7 +1772,7 @@ static void set_link_flags(struct snd_soc_dai_link *link, 1 : 0; if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS) - link->symmetric_samplebits = + link->symmetric_sample_bits = flags & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS ? 1 : 0; -- GitLab From 55d0056ba6a1bc8be2ae804cadf106ff2ae712ca Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:00 +0900 Subject: [PATCH 0432/1084] ASoC: adi: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87v9byolj1.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/adi/axi-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/adi/axi-i2s.c b/sound/soc/adi/axi-i2s.c index 8c4dc82be0dfb..aa082131fb903 100644 --- a/sound/soc/adi/axi-i2s.c +++ b/sound/soc/adi/axi-i2s.c @@ -156,7 +156,7 @@ static const struct snd_soc_dai_ops axi_i2s_dai_ops = { static struct snd_soc_dai_driver axi_i2s_dai = { .probe = axi_i2s_dai_probe, .ops = &axi_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver axi_i2s_component = { -- GitLab From ba471f8d1655753bd1fad226a1c47ffc4568c02e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:13 +0900 Subject: [PATCH 0433/1084] ASoC: atmel: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87turiolio.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-i2s.c | 2 +- sound/soc/atmel/mchp-i2s-mcc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c index 232300dda5482..7c6187e41f2b9 100644 --- a/sound/soc/atmel/atmel-i2s.c +++ b/sound/soc/atmel/atmel-i2s.c @@ -541,7 +541,7 @@ static struct snd_soc_dai_driver atmel_i2s_dai = { .formats = ATMEL_I2S_FORMATS, }, .ops = &atmel_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver atmel_i2s_component = { diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c index 04acc18f2d72c..6d5ae18f8b382 100644 --- a/sound/soc/atmel/mchp-i2s-mcc.c +++ b/sound/soc/atmel/mchp-i2s-mcc.c @@ -859,8 +859,8 @@ static struct snd_soc_dai_driver mchp_i2s_mcc_dai = { .formats = MCHP_I2SMCC_FORMATS, }, .ops = &mchp_i2s_mcc_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, .symmetric_channels = 1, }; -- GitLab From 3470c2398ce9f6e80a5434c1c8649b036544a1d4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:18 +0900 Subject: [PATCH 0434/1084] ASoC: au1x: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87sg72olij.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/au1x/i2sc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index 7fd08fafa4903..65bd39f5032df 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c @@ -210,7 +210,7 @@ static const struct snd_soc_dai_ops au1xi2s_dai_ops = { }; static struct snd_soc_dai_driver au1xi2s_dai_driver = { - .symmetric_rates = 1, + .symmetric_rate = 1, .playback = { .rates = AU1XI2SC_RATES, .formats = AU1XI2SC_FMTS, -- GitLab From a8e940222bdf60b9957515e80064b1230a3fc774 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:23 +0900 Subject: [PATCH 0435/1084] ASoC: bcm: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87r1mmolie.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/bcm/bcm2835-i2s.c | 4 ++-- sound/soc/bcm/bcm63xx-i2s-whistler.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c index c2f7631e87051..3d668f449bc1c 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -783,8 +783,8 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { | SNDRV_PCM_FMTBIT_S32_LE }, .ops = &bcm2835_i2s_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }; static bool bcm2835_i2s_volatile_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/bcm/bcm63xx-i2s-whistler.c b/sound/soc/bcm/bcm63xx-i2s-whistler.c index 246a57ac66799..527caf430715b 100644 --- a/sound/soc/bcm/bcm63xx-i2s-whistler.c +++ b/sound/soc/bcm/bcm63xx-i2s-whistler.c @@ -212,7 +212,7 @@ static struct snd_soc_dai_driver bcm63xx_i2s_dai = { .formats = SNDRV_PCM_FMTBIT_S32_LE, }, .ops = &bcm63xx_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, .symmetric_channels = 1, }; -- GitLab From f1e6b04baba690e3bd08669c73e8d78032c2b905 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:29 +0900 Subject: [PATCH 0436/1084] ASoC: cirrus: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87pn26oli8.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/cirrus/ep93xx-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 371708b17c09e..0d26550d0df8d 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -404,7 +404,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { #define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) static struct snd_soc_dai_driver ep93xx_i2s_dai = { - .symmetric_rates= 1, + .symmetric_rate = 1, .probe = ep93xx_i2s_dai_probe, .playback = { .channels_min = 2, -- GitLab From c6d152a8de560f50a37e9580b7550dc2001eaccf Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:33 +0900 Subject: [PATCH 0437/1084] ASoC: tegra: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87o8hqoli4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra186_dspk.c | 2 +- sound/soc/tegra/tegra20_i2s.c | 2 +- sound/soc/tegra/tegra210_dmic.c | 2 +- sound/soc/tegra/tegra210_i2s.c | 2 +- sound/soc/tegra/tegra30_i2s.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/tegra/tegra186_dspk.c b/sound/soc/tegra/tegra186_dspk.c index 7d9948fb2ca74..8ee9a77bd83d3 100644 --- a/sound/soc/tegra/tegra186_dspk.c +++ b/sound/soc/tegra/tegra186_dspk.c @@ -217,7 +217,7 @@ static struct snd_soc_dai_driver tegra186_dspk_dais[] = { SNDRV_PCM_FMTBIT_S32_LE, }, .ops = &tegra186_dspk_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 005fc4e645aa5..d7a3d046c8f88 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -260,7 +260,7 @@ static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .ops = &tegra20_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver tegra20_i2s_component = { diff --git a/sound/soc/tegra/tegra210_dmic.c b/sound/soc/tegra/tegra210_dmic.c index ead2c99bf72ef..b096478cd2ef0 100644 --- a/sound/soc/tegra/tegra210_dmic.c +++ b/sound/soc/tegra/tegra210_dmic.c @@ -228,7 +228,7 @@ static struct snd_soc_dai_driver tegra210_dmic_dais[] = { SNDRV_PCM_FMTBIT_S32_LE, }, .ops = &tegra210_dmic_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c index ca31ec92e5082..45f31ccb49d89 100644 --- a/sound/soc/tegra/tegra210_i2s.c +++ b/sound/soc/tegra/tegra210_i2s.c @@ -577,7 +577,7 @@ static struct snd_soc_dai_driver tegra210_i2s_dais[] = { SNDRV_PCM_FMTBIT_S32_LE, }, .ops = &tegra210_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index db5a8587bfa4c..6740df541508f 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -316,7 +316,7 @@ static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .ops = &tegra30_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver tegra30_i2s_component = { -- GitLab From fadaed3023138197000d37c2fafe15b2208ec9bc Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:38 +0900 Subject: [PATCH 0438/1084] ASoC: rockchip: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87mtxaolhz.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 2 +- sound/soc/rockchip/rockchip_pdm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 662de86eca118..0740764e7f71f 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -471,7 +471,7 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = { SNDRV_PCM_FMTBIT_S32_LE), }, .ops = &rockchip_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver rockchip_i2s_component = { diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index e5f732747f711..9295d648624e2 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c @@ -338,7 +338,7 @@ static struct snd_soc_dai_driver rockchip_pdm_dai = { .formats = ROCKCHIP_PDM_FORMATS, }, .ops = &rockchip_pdm_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver rockchip_pdm_component = { -- GitLab From d11ff0bf6ac1a85fcf51f4ca52934b0fb6ac47a6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:43 +0900 Subject: [PATCH 0439/1084] ASoC: samsung: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87lfcuolhu.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 2 +- sound/soc/samsung/pcm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 4bdc268fd981e..b043183174b26 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -1175,7 +1175,7 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv, dai_drv->probe = samsung_i2s_dai_probe; dai_drv->remove = samsung_i2s_dai_remove; - dai_drv->symmetric_rates = 1; + dai_drv->symmetric_rate = 1; dai_drv->ops = &samsung_i2s_dai_ops; dai_drv->playback.channels_min = 1; diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 6f50c7b473260..bfd76e9cc0cad 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -452,7 +452,7 @@ static int s3c_pcm_dai_probe(struct snd_soc_dai *dai) #define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 #define S3C_PCM_DAI_DECLARE \ - .symmetric_rates = 1, \ + .symmetric_rate = 1, \ .probe = s3c_pcm_dai_probe, \ .ops = &s3c_pcm_dai_ops, \ .playback = { \ -- GitLab From f1cd5f3bbcef13980734ea18797f192c344d850e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:49 +0900 Subject: [PATCH 0440/1084] ASoC: sh: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87k0seolho.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 6e670b3e92a00..c405bf3b4c997 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1320,8 +1320,8 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, if (rsnd_ssi_is_pin_sharing(io_capture) || rsnd_ssi_is_pin_sharing(io_playback)) { - /* should have symmetric_rates if pin sharing */ - drv->symmetric_rates = 1; + /* should have symmetric_rate if pin sharing */ + drv->symmetric_rate = 1; } dev_dbg(dev, "%s (%s/%s)\n", rdai->name, -- GitLab From c756316f0027a8659562d7df76fb24a9ff7c2068 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:53 +0900 Subject: [PATCH 0441/1084] ASoC: ti: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87im7yolhk.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/davinci-mcasp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index 6247ec3d3a096..b94220306d1a8 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -1641,7 +1641,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { }, .ops = &davinci_mcasp_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "davinci-mcasp.1", -- GitLab From c658b2185818ac39ca5b71001f30ab14a517219a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:53:58 +0900 Subject: [PATCH 0442/1084] ASoC: pxa: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87h7niolhf.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/pxa/pxa2xx-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 5301859a8453c..bcde4a96c1688 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -353,7 +353,7 @@ static struct snd_soc_dai_driver pxa_i2s_dai = { .rates = PXA2XX_I2S_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &pxa_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver pxa_i2s_component = { -- GitLab From 4b7ead032ecd1b1af5ce0dfbc2479cfdee7063b3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:03 +0900 Subject: [PATCH 0443/1084] ASoC: mediatek: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87ft32olha.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 10 +++++----- sound/soc/mediatek/mt6797/mt6797-dai-pcm.c | 8 ++++---- sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 2 +- sound/soc/mediatek/mt8183/mt8183-dai-pcm.c | 8 ++++---- sound/soc/mediatek/mt8192/mt8192-dai-pcm.c | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c index df29641c74aaa..d5cffe7a7e154 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c @@ -655,7 +655,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { }, .ops = &mt2701_afe_i2s_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "I2S1", @@ -679,7 +679,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { | SNDRV_PCM_FMTBIT_S32_LE) }, .ops = &mt2701_afe_i2s_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "I2S2", @@ -703,7 +703,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { | SNDRV_PCM_FMTBIT_S32_LE) }, .ops = &mt2701_afe_i2s_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "I2S3", @@ -727,7 +727,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { | SNDRV_PCM_FMTBIT_S32_LE) }, .ops = &mt2701_afe_i2s_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "MRG BT", @@ -749,7 +749,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .ops = &mt2701_btmrg_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, } }; diff --git a/sound/soc/mediatek/mt6797/mt6797-dai-pcm.c b/sound/soc/mediatek/mt6797/mt6797-dai-pcm.c index 3136f0bc7827d..51f736f319e42 100644 --- a/sound/soc/mediatek/mt6797/mt6797-dai-pcm.c +++ b/sound/soc/mediatek/mt6797/mt6797-dai-pcm.c @@ -270,8 +270,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { .formats = MTK_PCM_FORMATS, }, .ops = &mtk_dai_pcm_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "PCM 2", @@ -291,8 +291,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { .formats = MTK_PCM_FORMATS, }, .ops = &mtk_dai_pcm_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, }; diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c index 7e7bda70d12e9..685f4074b4e0a 100644 --- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c @@ -571,7 +571,7 @@ static struct snd_soc_dai_driver mt8173_afe_pcm_dais[] = { .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .ops = &mt8173_afe_i2s_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/mediatek/mt8183/mt8183-dai-pcm.c b/sound/soc/mediatek/mt8183/mt8183-dai-pcm.c index bc3ba3228f087..38ce0e36cdb4b 100644 --- a/sound/soc/mediatek/mt8183/mt8183-dai-pcm.c +++ b/sound/soc/mediatek/mt8183/mt8183-dai-pcm.c @@ -270,8 +270,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { .formats = MTK_PCM_FORMATS, }, .ops = &mtk_dai_pcm_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "PCM 2", @@ -291,8 +291,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { .formats = MTK_PCM_FORMATS, }, .ops = &mtk_dai_pcm_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, }; diff --git a/sound/soc/mediatek/mt8192/mt8192-dai-pcm.c b/sound/soc/mediatek/mt8192/mt8192-dai-pcm.c index 6e94cfdf06fc1..239e3f5b53d33 100644 --- a/sound/soc/mediatek/mt8192/mt8192-dai-pcm.c +++ b/sound/soc/mediatek/mt8192/mt8192-dai-pcm.c @@ -360,8 +360,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { .formats = MTK_PCM_FORMATS, }, .ops = &mtk_dai_pcm_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "PCM 2", @@ -381,8 +381,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { .formats = MTK_PCM_FORMATS, }, .ops = &mtk_dai_pcm_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, }; -- GitLab From cb2f6927faf44d0cd3e55d3f9a9211f2aad26850 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:08 +0900 Subject: [PATCH 0444/1084] ASoC: fsl: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87eeimolh5.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 4 ++-- sound/soc/fsl/fsl_sai.c | 8 ++++---- sound/soc/fsl/fsl_ssi.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 614e22a95f537..bac9f059c9fc6 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -1038,9 +1038,9 @@ static int fsl_esai_probe(struct platform_device *pdev) /* Implement full symmetry for synchronous mode */ if (esai_priv->synchronous) { - fsl_esai_dai.symmetric_rates = 1; + fsl_esai_dai.symmetric_rate = 1; fsl_esai_dai.symmetric_channels = 1; - fsl_esai_dai.symmetric_samplebits = 1; + fsl_esai_dai.symmetric_sample_bits = 1; } dev_set_drvdata(&pdev->dev, esai_priv); diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index f3d3d20d35d79..5e65b456d3e21 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -1079,9 +1079,9 @@ static int fsl_sai_probe(struct platform_device *pdev) /* Sync Tx with Rx as default by following old DT binding */ sai->synchronous[RX] = true; sai->synchronous[TX] = false; - sai->cpu_dai_drv.symmetric_rates = 1; + sai->cpu_dai_drv.symmetric_rate = 1; sai->cpu_dai_drv.symmetric_channels = 1; - sai->cpu_dai_drv.symmetric_samplebits = 1; + sai->cpu_dai_drv.symmetric_sample_bits = 1; if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) && of_find_property(np, "fsl,sai-asynchronous", NULL)) { @@ -1098,9 +1098,9 @@ static int fsl_sai_probe(struct platform_device *pdev) /* Discard all settings for asynchronous mode */ sai->synchronous[RX] = false; sai->synchronous[TX] = false; - sai->cpu_dai_drv.symmetric_rates = 0; + sai->cpu_dai_drv.symmetric_rate = 0; sai->cpu_dai_drv.symmetric_channels = 0; - sai->cpu_dai_drv.symmetric_samplebits = 0; + sai->cpu_dai_drv.symmetric_sample_bits = 0; } if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index db4ba5f22b774..57811743c2948 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1531,9 +1531,9 @@ static int fsl_ssi_probe(struct platform_device *pdev) /* Set software limitations for synchronous mode except AC97 */ if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { - ssi->cpu_dai_drv.symmetric_rates = 1; + ssi->cpu_dai_drv.symmetric_rate = 1; ssi->cpu_dai_drv.symmetric_channels = 1; - ssi->cpu_dai_drv.symmetric_samplebits = 1; + ssi->cpu_dai_drv.symmetric_sample_bits = 1; } /* -- GitLab From 0769575294e4c965cc2a4f4817fa696e20c2c05f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:13 +0900 Subject: [PATCH 0445/1084] ASoC: wm*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87czy6olh0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 12 ++++++------ sound/soc/codecs/wm5110.c | 12 ++++++------ sound/soc/codecs/wm8510.c | 2 +- sound/soc/codecs/wm8731.c | 2 +- sound/soc/codecs/wm8770.c | 2 +- sound/soc/codecs/wm8804.c | 2 +- sound/soc/codecs/wm8903.c | 2 +- sound/soc/codecs/wm8904.c | 2 +- sound/soc/codecs/wm8940.c | 2 +- sound/soc/codecs/wm8960.c | 2 +- sound/soc/codecs/wm8962.c | 2 +- sound/soc/codecs/wm8974.c | 2 +- sound/soc/codecs/wm8978.c | 2 +- sound/soc/codecs/wm8983.c | 2 +- sound/soc/codecs/wm8985.c | 2 +- sound/soc/codecs/wm8988.c | 2 +- sound/soc/codecs/wm8993.c | 2 +- sound/soc/codecs/wm8994.c | 4 ++-- sound/soc/codecs/wm8997.c | 8 ++++---- sound/soc/codecs/wm8998.c | 12 ++++++------ sound/soc/codecs/wm9713.c | 2 +- 21 files changed, 40 insertions(+), 40 deletions(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 70d353b63fe03..fe33f2d88f557 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1780,8 +1780,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = { .formats = WM5102_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm5102-aif2", @@ -1802,8 +1802,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = { .formats = WM5102_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm5102-aif3", @@ -1824,8 +1824,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = { .formats = WM5102_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm5102-slim1", diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 4238929b23751..52c0a575cc4f6 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2089,8 +2089,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = { .formats = WM5110_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm5110-aif2", @@ -2111,8 +2111,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = { .formats = WM5110_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm5110-aif3", @@ -2133,8 +2133,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = { .formats = WM5110_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm5110-slim1", diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 73c4a8b9f59e3..a18e2290b8c88 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -569,7 +569,7 @@ static struct snd_soc_dai_driver wm8510_dai = { .rates = WM8510_RATES, .formats = WM8510_FORMATS,}, .ops = &wm8510_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int wm8510_probe(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 304bf725a6132..dcee7b2bd3d79 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -567,7 +567,7 @@ static struct snd_soc_dai_driver wm8731_dai = { .rates = WM8731_RATES, .formats = WM8731_FORMATS,}, .ops = &wm8731_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int wm8731_request_supplies(struct device *dev, diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 1176a6ad269d4..5f394065030d2 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c @@ -562,7 +562,7 @@ static struct snd_soc_dai_driver wm8770_dai = { .formats = WM8770_FORMATS }, .ops = &wm8770_dai_ops, - .symmetric_rates = 1 + .symmetric_rate = 1 }; static int wm8770_probe(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 4ddb5e32df5df..21bf0cfa1e7e7 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -536,7 +536,7 @@ static struct snd_soc_dai_driver wm8804_dai = { .formats = WM8804_FORMATS, }, .ops = &wm8804_dai_ops, - .symmetric_rates = 1 + .symmetric_rate = 1 }; static const struct snd_soc_component_driver soc_component_dev_wm8804 = { diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 09f4980630c7e..026603ae44ce0 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1760,7 +1760,7 @@ static struct snd_soc_dai_driver wm8903_dai = { .formats = WM8903_FORMATS, }, .ops = &wm8903_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int wm8903_resume(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 1c360bae5652c..a02a77fef360b 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1983,7 +1983,7 @@ static struct snd_soc_dai_driver wm8904_dai = { .formats = WM8904_FORMATS, }, .ops = &wm8904_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static void wm8904_handle_retune_mobile_pdata(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 016cd8aeef37c..440d048ef0c02 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -688,7 +688,7 @@ static struct snd_soc_dai_driver wm8940_dai = { .formats = WM8940_FORMATS, }, .ops = &wm8940_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int wm8940_probe(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 660ec46eecf25..df351519a3a6b 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -1338,7 +1338,7 @@ static struct snd_soc_dai_driver wm8960_dai = { .rates = WM8960_RATES, .formats = WM8960_FORMATS,}, .ops = &wm8960_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int wm8960_probe(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 3af456010b9c5..ce4666a74793e 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2973,7 +2973,7 @@ static struct snd_soc_dai_driver wm8962_dai = { .formats = WM8962_FORMATS, }, .ops = &wm8962_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static void wm8962_mic_work(struct work_struct *work) diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index c86231dfcf4f8..fdc68ab497427 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -643,7 +643,7 @@ static struct snd_soc_dai_driver wm8974_dai = { .rates = WM8974_RATES, .formats = WM8974_FORMATS,}, .ops = &wm8974_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct regmap_config wm8974_regmap = { diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index a7acb89817159..4b5ecd1422492 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -918,7 +918,7 @@ static struct snd_soc_dai_driver wm8978_dai = { .formats = WM8978_FORMATS, }, .ops = &wm8978_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int wm8978_suspend(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index d1d2d408ad952..d8ed22a9caac1 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -971,7 +971,7 @@ static struct snd_soc_dai_driver wm8983_dai = { .formats = WM8983_FORMATS, }, .ops = &wm8983_dai_ops, - .symmetric_rates = 1 + .symmetric_rate = 1 }; static const struct snd_soc_component_driver soc_component_dev_wm8983 = { diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 3f27482349b2a..a7e01106fbc0a 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -1100,7 +1100,7 @@ static struct snd_soc_dai_driver wm8985_dai = { .formats = WM8985_FORMATS, }, .ops = &wm8985_dai_ops, - .symmetric_rates = 1 + .symmetric_rate = 1 }; static const struct snd_soc_component_driver soc_component_dev_wm8985 = { diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index d2c2d0d943f09..1d2f881bbcae6 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -787,7 +787,7 @@ static struct snd_soc_dai_driver wm8988_dai = { .formats = WM8988_FORMATS, }, .ops = &wm8988_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int wm8988_probe(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 9f310082e3c1a..c4f41692b806d 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1476,7 +1476,7 @@ static struct snd_soc_dai_driver wm8993_dai = { .sig_bits = 24, }, .ops = &wm8993_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int wm8993_probe(struct snd_soc_component *component) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index f57884113406b..f117ec0c489f0 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4351,7 +4351,7 @@ static int wm8994_component_probe(struct snd_soc_component *component) } if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { wm8994->lrclk_shared[0] = 1; - wm8994_dai[0].symmetric_rates = 1; + wm8994_dai[0].symmetric_rate = 1; } else { wm8994->lrclk_shared[0] = 0; } @@ -4363,7 +4363,7 @@ static int wm8994_component_probe(struct snd_soc_component *component) } if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { wm8994->lrclk_shared[1] = 1; - wm8994_dai[1].symmetric_rates = 1; + wm8994_dai[1].symmetric_rate = 1; } else { wm8994->lrclk_shared[1] = 0; } diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 229f2986cd96b..99c3ebae6ba69 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -969,8 +969,8 @@ static struct snd_soc_dai_driver wm8997_dai[] = { .formats = WM8997_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm8997-aif2", @@ -991,8 +991,8 @@ static struct snd_soc_dai_driver wm8997_dai[] = { .formats = WM8997_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm8997-slim1", diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c index 5413254295b70..b6f717aa5478a 100644 --- a/sound/soc/codecs/wm8998.c +++ b/sound/soc/codecs/wm8998.c @@ -1161,8 +1161,8 @@ static struct snd_soc_dai_driver wm8998_dai[] = { .formats = WM8998_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm8998-aif2", @@ -1183,8 +1183,8 @@ static struct snd_soc_dai_driver wm8998_dai[] = { .formats = WM8998_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm8998-aif3", @@ -1205,8 +1205,8 @@ static struct snd_soc_dai_driver wm8998_dai[] = { .formats = WM8998_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "wm8998-slim1", diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index f333e2ff4a168..e0ce32dd4a811 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1134,7 +1134,7 @@ static struct snd_soc_dai_driver wm9713_dai[] = { .rates = WM9713_PCM_RATES, .formats = WM9713_PCM_FORMATS,}, .ops = &wm9713_dai_ops_voice, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; -- GitLab From a9aef184f7b47c355e4d78aa08792ff74fd5c4f5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:17 +0900 Subject: [PATCH 0446/1084] ASoC: tlv*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87bldqolgw.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adcx140.c | 2 +- sound/soc/codecs/tlv320aic31xx.c | 4 ++-- sound/soc/codecs/tlv320aic32x4.c | 2 +- sound/soc/codecs/tlv320aic3x.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 3f027c8234a60..32b120d624b25 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -1069,7 +1069,7 @@ static struct snd_soc_dai_driver adcx140_dai_driver[] = { .formats = ADCX140_FORMATS, }, .ops = &adcx140_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, } }; diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 5ac7ce2644311..51870d50f4195 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1395,7 +1395,7 @@ static struct snd_soc_dai_driver dac31xx_dai_driver[] = { .formats = AIC31XX_FORMATS, }, .ops = &aic31xx_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, } }; @@ -1417,7 +1417,7 @@ static struct snd_soc_dai_driver aic31xx_dai_driver[] = { .formats = AIC31XX_FORMATS, }, .ops = &aic31xx_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, } }; diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 9e3de9ded0efb..f04f88c8d4251 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -916,7 +916,7 @@ static struct snd_soc_dai_driver aic32x4_dai = { .rates = AIC32X4_RATES, .formats = AIC32X4_FORMATS,}, .ops = &aic32x4_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static void aic32x4_setup_gpios(struct snd_soc_component *component) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 6d066bc58ac8a..db14441274441 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1503,7 +1503,7 @@ static struct snd_soc_dai_driver aic3x_dai = { .rates = AIC3X_RATES, .formats = AIC3X_FORMATS,}, .ops = &aic3x_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static void aic3x_mono_init(struct snd_soc_component *component) -- GitLab From bc03b3910ef6e228ef8b192e08030a1e177ad273 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:21 +0900 Subject: [PATCH 0447/1084] ASoC: rt*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87a6taolgs.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt274.c | 2 +- sound/soc/codecs/rt286.c | 4 ++-- sound/soc/codecs/rt298.c | 4 ++-- sound/soc/codecs/rt5670.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index 70cf17c0aa99e..0d3773c576f8c 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -1056,7 +1056,7 @@ static struct snd_soc_dai_driver rt274_dai[] = { .formats = RT274_FORMATS, }, .ops = &rt274_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 5fb9653d9131f..8abe232ca4a4c 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1017,7 +1017,7 @@ static struct snd_soc_dai_driver rt286_dai[] = { .formats = RT286_FORMATS, }, .ops = &rt286_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "rt286-aif2", @@ -1037,7 +1037,7 @@ static struct snd_soc_dai_driver rt286_dai[] = { .formats = RT286_FORMATS, }, .ops = &rt286_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index dc0273a5a11f7..32cc9b6287d21 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -1084,7 +1084,7 @@ static struct snd_soc_dai_driver rt298_dai[] = { .formats = RT298_FORMATS, }, .ops = &rt298_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "rt298-aif2", @@ -1104,7 +1104,7 @@ static struct snd_soc_dai_driver rt298_dai[] = { .formats = RT298_FORMATS, }, .ops = &rt298_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index a0c8f58d729b3..c29317ea5df2f 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -2741,7 +2741,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { .formats = RT5670_FORMATS, }, .ops = &rt5670_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "rt5670-aif2", @@ -2761,7 +2761,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { .formats = RT5670_FORMATS, }, .ops = &rt5670_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; -- GitLab From 42c9b5bec1c5218b33eda3b519381b38b89d5ccd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:25 +0900 Subject: [PATCH 0448/1084] ASoC: nau*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/878s8uolgo.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8810.c | 2 +- sound/soc/codecs/nau8822.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index 33ebc63984265..13676b544f58a 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c @@ -837,7 +837,7 @@ static struct snd_soc_dai_driver nau8810_dai = { .formats = NAU8810_FORMATS, }, .ops = &nau8810_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct regmap_config nau8810_regmap_config = { diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c index 609aeeb278189..58123390c7a31 100644 --- a/sound/soc/codecs/nau8822.c +++ b/sound/soc/codecs/nau8822.c @@ -991,7 +991,7 @@ static struct snd_soc_dai_driver nau8822_dai = { .formats = NAU8822_FORMATS, }, .ops = &nau8822_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int nau8822_suspend(struct snd_soc_component *component) -- GitLab From fa056c07367e443271837c8500de8c7e6d9b2722 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:29 +0900 Subject: [PATCH 0449/1084] ASoC: tas*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/877doeolgk.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2764.c | 2 +- sound/soc/codecs/tas2770.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index 14a193e48dc76..8ff4d9e8d5681 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -490,7 +490,7 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = { .formats = TAS2764_FORMATS, }, .ops = &tas2764_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c index a91a0a31e74d1..15fca5109e149 100644 --- a/sound/soc/codecs/tas2770.c +++ b/sound/soc/codecs/tas2770.c @@ -499,7 +499,7 @@ static struct snd_soc_dai_driver tas2770_dai_driver[] = { .formats = TAS2770_FORMATS, }, .ops = &tas2770_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; -- GitLab From 1c6d1c4f6874345a31d12a9f3843876c49d637fa Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:33 +0900 Subject: [PATCH 0450/1084] ASoC: da*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/875z3yolgf.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/da7210.c | 2 +- sound/soc/codecs/da7213.c | 2 +- sound/soc/codecs/da7218.c | 4 ++-- sound/soc/codecs/da7219.c | 4 ++-- sound/soc/codecs/da9055.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 3d05c37f676eb..8af344b2fdbf6 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1059,7 +1059,7 @@ static struct snd_soc_dai_driver da7210_dai = { .formats = DA7210_FORMATS, }, .ops = &da7210_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int da7210_probe(struct snd_soc_component *component) diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 72402467adcc6..3ab89387b4e65 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1551,7 +1551,7 @@ static struct snd_soc_dai_driver da7213_dai = { .formats = DA7213_FORMATS, }, .ops = &da7213_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int da7213_set_auto_pll(struct snd_soc_component *component, bool enable) diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index 2bfafbe9e3dce..0e5b91eb420b8 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -2194,9 +2194,9 @@ static struct snd_soc_dai_driver da7218_dai = { .formats = DA7218_FORMATS, }, .ops = &da7218_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, .symmetric_channels = 1, - .symmetric_samplebits = 1, + .symmetric_sample_bits = 1, }; diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index e9b45daec0ca5..13009d08b09ac 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -1692,9 +1692,9 @@ static struct snd_soc_dai_driver da7219_dai = { .formats = DA7219_FORMATS, }, .ops = &da7219_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, .symmetric_channels = 1, - .symmetric_samplebits = 1, + .symmetric_sample_bits = 1, }; diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index aed92f615b023..a9676b261129e 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1347,7 +1347,7 @@ static struct snd_soc_dai_driver da9055_dai = { .formats = DA9055_FORMATS, }, .ops = &da9055_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int da9055_set_bias_level(struct snd_soc_component *component, -- GitLab From 4060064e8baf047a64b6286f5fd87cb0a34d8b89 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:39 +0900 Subject: [PATCH 0451/1084] ASoC: es*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/874kjiolga.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/es8316.c | 2 +- sound/soc/codecs/es8328.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 1ce84f12a4cfc..d632055370e09 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -543,7 +543,7 @@ static struct snd_soc_dai_driver es8316_dai = { .formats = ES8316_FORMATS, }, .ops = &es8316_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static void es8316_enable_micbias_for_mic_gnd_short_detect( diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index b537300d0ce86..9632afc2d4d64 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -715,7 +715,7 @@ static struct snd_soc_dai_driver es8328_dai = { .formats = ES8328_FORMATS, }, .ops = &es8328_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int es8328_suspend(struct snd_soc_component *component) -- GitLab From cb40d1b4581c0f6e2a828ebfcb7cc9a04dca1e11 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:44 +0900 Subject: [PATCH 0452/1084] ASoC: max*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/8735z2olg5.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/max9860.c | 2 +- sound/soc/codecs/max9867.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index d5925c42b4b57..dd29b183ecd6c 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c @@ -489,7 +489,7 @@ static struct snd_soc_dai_driver max9860_dai = { SNDRV_PCM_FMTBIT_S32_LE, }, .ops = &max9860_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int max9860_set_bias_level(struct snd_soc_component *component, diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index 512e6f2513d34..09b2d730e9fd3 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c @@ -520,7 +520,7 @@ static struct snd_soc_dai_driver max9867_dai[] = { .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .ops = &max9867_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, } }; -- GitLab From 260b668cf356dbab5f73e651cfc96a90ed220b98 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:48 +0900 Subject: [PATCH 0453/1084] ASoC: cs*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/871remolg1.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l32.c | 2 +- sound/soc/codecs/cs35l33.c | 2 +- sound/soc/codecs/cs35l34.c | 2 +- sound/soc/codecs/cs35l35.c | 2 +- sound/soc/codecs/cs35l36.c | 2 +- sound/soc/codecs/cs4234.c | 2 +- sound/soc/codecs/cs4271.c | 2 +- sound/soc/codecs/cs42l73.c | 6 +++--- sound/soc/codecs/cs43130.c | 6 +++--- sound/soc/codecs/cs4341.c | 2 +- sound/soc/codecs/cs4349.c | 2 +- sound/soc/codecs/cs47l15.c | 12 ++++++------ sound/soc/codecs/cs47l24.c | 12 ++++++------ sound/soc/codecs/cs47l35.c | 12 ++++++------ sound/soc/codecs/cs47l85.c | 16 ++++++++-------- sound/soc/codecs/cs47l90.c | 16 ++++++++-------- sound/soc/codecs/cs47l92.c | 12 ++++++------ sound/soc/codecs/cs53l30.c | 2 +- 18 files changed, 56 insertions(+), 56 deletions(-) diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 3a644a35c4643..f4067230ac425 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -194,7 +194,7 @@ static struct snd_soc_dai_driver cs35l32_dai[] = { .formats = CS35L32_FORMATS, }, .ops = &cs35l32_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, } }; diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 6042194d95d3e..7ad7b733af9b6 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -691,7 +691,7 @@ static struct snd_soc_dai_driver cs35l33_dai = { .formats = CS35L33_FORMATS, }, .ops = &cs35l33_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int cs35l33_set_hg_data(struct snd_soc_component *component, diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index b792c006e530d..110ee2d063581 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -666,7 +666,7 @@ static struct snd_soc_dai_driver cs35l34_dai = { .formats = CS35L34_FORMATS, }, .ops = &cs35l34_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34, diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index e330427a4314f..55d529aa00112 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c @@ -692,7 +692,7 @@ static struct snd_soc_dai_driver cs35l35_dai[] = { .formats = CS35L35_FORMATS, }, .ops = &cs35l35_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "cs35l35-pdm", diff --git a/sound/soc/codecs/cs35l36.c b/sound/soc/codecs/cs35l36.c index e9b5f76f27a86..4451ca9f49166 100644 --- a/sound/soc/codecs/cs35l36.c +++ b/sound/soc/codecs/cs35l36.c @@ -995,7 +995,7 @@ static struct snd_soc_dai_driver cs35l36_dai[] = { .formats = CS35L36_TX_FORMATS, }, .ops = &cs35l36_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/codecs/cs4234.c b/sound/soc/codecs/cs4234.c index 2ea83233c3f16..20126cc675b13 100644 --- a/sound/soc/codecs/cs4234.c +++ b/sound/soc/codecs/cs4234.c @@ -585,7 +585,7 @@ static struct snd_soc_dai_driver cs4234_dai[] = { .formats = CS4234_FORMATS, }, .ops = &cs4234_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index d43762ae8f3da..7663f89ac6a24 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -481,7 +481,7 @@ static struct snd_soc_dai_driver cs4271_dai = { .formats = CS4271_PCM_FORMATS, }, .ops = &cs4271_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int cs4271_reset(struct snd_soc_component *component) diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 988ca7e19821e..c3f974ec78e58 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1181,7 +1181,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { .formats = CS42L73_FORMATS, }, .ops = &cs42l73_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "cs42l73-asp", @@ -1201,7 +1201,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { .formats = CS42L73_FORMATS, }, .ops = &cs42l73_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "cs42l73-vsp", @@ -1221,7 +1221,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { .formats = CS42L73_FORMATS, }, .ops = &cs42l73_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, } }; diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c index 7fb34422a2a4b..80bc7c10ed757 100644 --- a/sound/soc/codecs/cs43130.c +++ b/sound/soc/codecs/cs43130.c @@ -1581,7 +1581,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = { .formats = CS43130_PCM_FORMATS, }, .ops = &cs43130_pcm_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "cs43130-asp-dop", @@ -1594,7 +1594,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = { .formats = CS43130_DOP_FORMATS, }, .ops = &cs43130_dop_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "cs43130-xsp-dop", @@ -1607,7 +1607,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = { .formats = CS43130_DOP_FORMATS, }, .ops = &cs43130_dop_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "cs43130-xsp-dsd", diff --git a/sound/soc/codecs/cs4341.c b/sound/soc/codecs/cs4341.c index f566604de78cf..7d3e54d8eef36 100644 --- a/sound/soc/codecs/cs4341.c +++ b/sound/soc/codecs/cs4341.c @@ -189,7 +189,7 @@ static struct snd_soc_dai_driver cs4341_dai = { SNDRV_PCM_FMTBIT_S24_LE, }, .ops = &cs4341_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver soc_component_cs4341 = { diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index fd55263197798..786c69a8ec4a2 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -250,7 +250,7 @@ static struct snd_soc_dai_driver cs4349_dai = { .formats = CS4349_PCM_FORMATS, }, .ops = &cs4349_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver soc_component_dev_cs4349 = { diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c index 254f9d96e766d..1ee83160b83fb 100644 --- a/sound/soc/codecs/cs47l15.c +++ b/sound/soc/codecs/cs47l15.c @@ -1160,8 +1160,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l15-aif2", @@ -1182,8 +1182,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l15-aif3", @@ -1204,8 +1204,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l15-cpu-trace", diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index f6d173d0120e3..eaabbb56a1734 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -977,8 +977,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { .formats = CS47L24_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l24-aif2", @@ -999,8 +999,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { .formats = CS47L24_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l24-aif3", @@ -1021,8 +1021,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { .formats = CS47L24_FORMATS, }, .ops = &arizona_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l24-cpu-voicectrl", diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c index e967609da8a30..3f04a2a745217 100644 --- a/sound/soc/codecs/cs47l35.c +++ b/sound/soc/codecs/cs47l35.c @@ -1368,8 +1368,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l35-aif2", @@ -1390,8 +1390,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l35-aif3", @@ -1412,8 +1412,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l35-slim1", diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c index 47b16466b6c17..748a180870bc8 100644 --- a/sound/soc/codecs/cs47l85.c +++ b/sound/soc/codecs/cs47l85.c @@ -2269,8 +2269,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l85-aif2", @@ -2291,8 +2291,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l85-aif3", @@ -2313,8 +2313,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l85-aif4", @@ -2335,8 +2335,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l85-slim1", diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c index 8838dd557321a..d2911c014b863 100644 --- a/sound/soc/codecs/cs47l90.c +++ b/sound/soc/codecs/cs47l90.c @@ -2188,8 +2188,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l90-aif2", @@ -2210,8 +2210,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l90-aif3", @@ -2232,8 +2232,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l90-aif4", @@ -2254,8 +2254,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l90-slim1", diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c index 52dc29942ec27..1a0280416d92a 100644 --- a/sound/soc/codecs/cs47l92.c +++ b/sound/soc/codecs/cs47l92.c @@ -1704,8 +1704,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l92-aif2", @@ -1726,8 +1726,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l92-aif3", @@ -1748,8 +1748,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = { .formats = MADERA_FORMATS, }, .ops = &madera_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }, { .name = "cs47l92-slim1", diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index ed22361b35c14..3d67cbf9eaaa2 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -869,7 +869,7 @@ static struct snd_soc_dai_driver cs53l30_dai = { .formats = CS53L30_FORMATS, }, .ops = &cs53l30_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int cs53l30_component_probe(struct snd_soc_component *component) -- GitLab From 9b4488efdeccbe1d4dceb13aee9e58371f6ba926 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:52 +0900 Subject: [PATCH 0454/1084] ASoC: tscs*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87zh1an6vh.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/tscs42xx.c | 4 ++-- sound/soc/codecs/tscs454.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/tscs42xx.c b/sound/soc/codecs/tscs42xx.c index 6200fab7896ff..fb861baf50e85 100644 --- a/sound/soc/codecs/tscs42xx.c +++ b/sound/soc/codecs/tscs42xx.c @@ -1397,9 +1397,9 @@ static struct snd_soc_dai_driver tscs42xx_dai = { .rates = TSCS42XX_RATES, .formats = TSCS42XX_FORMATS,}, .ops = &tscs42xx_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, .symmetric_channels = 1, - .symmetric_samplebits = 1, + .symmetric_sample_bits = 1, }; static const struct reg_sequence tscs42xx_patch[] = { diff --git a/sound/soc/codecs/tscs454.c b/sound/soc/codecs/tscs454.c index cd1f1a592386c..1bafc9d1101c1 100644 --- a/sound/soc/codecs/tscs454.c +++ b/sound/soc/codecs/tscs454.c @@ -3346,9 +3346,9 @@ static struct snd_soc_dai_driver tscs454_dais[] = { .rates = TSCS454_RATES, .formats = TSCS454_FORMATS,}, .ops = &tscs454_dai1_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, .symmetric_channels = 1, - .symmetric_samplebits = 1, + .symmetric_sample_bits = 1, }, { .name = "tscs454-dai2", @@ -3366,9 +3366,9 @@ static struct snd_soc_dai_driver tscs454_dais[] = { .rates = TSCS454_RATES, .formats = TSCS454_FORMATS,}, .ops = &tscs454_dai23_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, .symmetric_channels = 1, - .symmetric_samplebits = 1, + .symmetric_sample_bits = 1, }, { .name = "tscs454-dai3", @@ -3386,9 +3386,9 @@ static struct snd_soc_dai_driver tscs454_dais[] = { .rates = TSCS454_RATES, .formats = TSCS454_FORMATS,}, .ops = &tscs454_dai23_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, .symmetric_channels = 1, - .symmetric_samplebits = 1, + .symmetric_sample_bits = 1, }, }; -- GitLab From 870b76ea7d0c0e5d6e5f305d8eca9ba45b89241a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:54:56 +0900 Subject: [PATCH 0455/1084] ASoC: ak*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87y2gun6vc.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/ak4554.c | 2 +- sound/soc/codecs/ak4613.c | 2 +- sound/soc/codecs/ak4641.c | 4 ++-- sound/soc/codecs/ak4642.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c index 2fa83a1a84cf1..8e60e2b56ad6d 100644 --- a/sound/soc/codecs/ak4554.c +++ b/sound/soc/codecs/ak4554.c @@ -56,7 +56,7 @@ static struct snd_soc_dai_driver ak4554_dai = { .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver soc_component_dev_ak4554 = { diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 8d663e8d64c49..fe208cfdd3ba5 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -575,7 +575,7 @@ static struct snd_soc_dai_driver ak4613_dai = { .formats = AK4613_PCM_FMTBIT, }, .ops = &ak4613_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int ak4613_suspend(struct snd_soc_component *component) diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 77004cd7caa3e..04aef0e72aa58 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -499,7 +499,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = { .formats = AK4641_FORMATS, }, .ops = &ak4641_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "ak4641-voice", @@ -519,7 +519,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = { .formats = AK4641_FORMATS, }, .ops = &ak4641_pcm_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 3532370255140..c49c58eeb4763 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -516,7 +516,7 @@ static struct snd_soc_dai_driver ak4642_dai = { .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE }, .ops = &ak4642_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int ak4642_suspend(struct snd_soc_component *component) -- GitLab From f88f45861bbd5da303a997f92800fa0d7958c929 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:55:01 +0900 Subject: [PATCH 0456/1084] ASoC: adau*: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87wnwen6v8.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/adau1372.c | 2 +- sound/soc/codecs/adau1373.c | 6 +++--- sound/soc/codecs/adau1701.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/adau1372.c b/sound/soc/codecs/adau1372.c index 5ccbf1b6bcf5a..6811a8b3866dd 100644 --- a/sound/soc/codecs/adau1372.c +++ b/sound/soc/codecs/adau1372.c @@ -890,7 +890,7 @@ static struct snd_soc_dai_driver adau1372_dai_driver = { .sig_bits = 24, }, .ops = &adau1372_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int adau1372_setup_pll(struct adau1372 *adau1372, unsigned int rate) diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index e71fde001b466..9887aa6f0be5c 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1205,7 +1205,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = { .formats = ADAU1373_FORMATS, }, .ops = &adau1373_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .id = 1, @@ -1225,7 +1225,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = { .formats = ADAU1373_FORMATS, }, .ops = &adau1373_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .id = 2, @@ -1245,7 +1245,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = { .formats = ADAU1373_FORMATS, }, .ops = &adau1373_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 68130eaa64a40..5ce74697564af 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -653,7 +653,7 @@ static struct snd_soc_dai_driver adau1701_dai = { .formats = ADAU1701_FORMATS, }, .ops = &adau1701_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; #ifdef CONFIG_OF -- GitLab From 0547dece8dcbb80983b3c37ad20ceca76a1f06a5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:55:20 +0900 Subject: [PATCH 0457/1084] ASoC: jz4740: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87v9byn6uo.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/jz4740.c | 2 +- sound/soc/jz4740/jz4740-i2s.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 5e58bfee2b491..081485f784e9b 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -214,7 +214,7 @@ static struct snd_soc_dai_driver jz4740_codec_dai = { .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, }, .ops = &jz4740_codec_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static void jz4740_codec_wakeup(struct regmap *regmap) diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 0a68f4c3d15a3..52ba0e3a9e954 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -455,7 +455,7 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = { .rates = SNDRV_PCM_RATE_8000_48000, .formats = JZ4740_I2S_FMTS, }, - .symmetric_rates = 1, + .symmetric_rate = 1, .ops = &jz4740_i2s_dai_ops, }; -- GitLab From 813857086191aace3a39c056c8acb6946ff75f03 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:55:25 +0900 Subject: [PATCH 0458/1084] ASoC: sunxi: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87turin6uk.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-i2s.c | 2 +- sound/soc/sunxi/sun8i-codec.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 4b8ca5be0a291..78506c3811dc7 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -1105,7 +1105,7 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = { .formats = SUN4I_FORMATS, }, .ops = &sun4i_i2s_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct snd_soc_component_driver sun4i_i2s_component = { diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 180442c62be13..460924fc173fb 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -640,9 +640,9 @@ static struct snd_soc_dai_driver sun8i_codec_dais[] = { .rates = SUN8I_CODEC_PCM_RATES, .formats = SUN8I_CODEC_PCM_FORMATS, }, - .symmetric_rates = true, + .symmetric_rate = true, .symmetric_channels = true, - .symmetric_samplebits = true, + .symmetric_sample_bits = true, }, { .name = "sun8i-codec-aif2", @@ -665,9 +665,9 @@ static struct snd_soc_dai_driver sun8i_codec_dais[] = { .rates = SUN8I_CODEC_PCM_RATES, .formats = SUN8I_CODEC_PCM_FORMATS, }, - .symmetric_rates = true, + .symmetric_rate = true, .symmetric_channels = true, - .symmetric_samplebits = true, + .symmetric_sample_bits = true, }, { .name = "sun8i-codec-aif3", @@ -690,9 +690,9 @@ static struct snd_soc_dai_driver sun8i_codec_dais[] = { .rates = SUN8I_CODEC_PCM_RATES, .formats = SUN8I_CODEC_PCM_FORMATS, }, - .symmetric_rates = true, + .symmetric_rate = true, .symmetric_channels = true, - .symmetric_samplebits = true, + .symmetric_sample_bits = true, }, }; -- GitLab From b33c088a9b0b15df987dae05177ef9b0816dc4cf Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:55:29 +0900 Subject: [PATCH 0459/1084] ASoC: zl38060: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87sg72n6ug.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/zl38060.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/zl38060.c b/sound/soc/codecs/zl38060.c index 42726dc0ba39a..d21a72314d377 100644 --- a/sound/soc/codecs/zl38060.c +++ b/sound/soc/codecs/zl38060.c @@ -360,8 +360,8 @@ static struct snd_soc_dai_driver zl38_dai = { .formats = ZL38_FORMATS, }, .ops = &zl38_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, .symmetric_channels = 1, }; -- GitLab From 4735c8cadd54ef74726718ad93a27d16b23089b0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:55:34 +0900 Subject: [PATCH 0460/1084] ASoC: ssm2602: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87r1mmn6ub.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/ssm2602.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 9051602466146..7964e922b07f6 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -526,8 +526,8 @@ static struct snd_soc_dai_driver ssm2602_dai = { .rates = SSM2602_RATES, .formats = SSM2602_FORMATS,}, .ops = &ssm2602_dai_ops, - .symmetric_rates = 1, - .symmetric_samplebits = 1, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, }; static int ssm2602_resume(struct snd_soc_component *component) -- GitLab From bea17630c4ad398b6cd9b454c1649a962a7e0258 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:55:40 +0900 Subject: [PATCH 0461/1084] ASoC: sgtl5000: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87pn26n6u4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/sgtl5000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 4d6ff81146228..73551e36695e9 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1187,7 +1187,7 @@ static struct snd_soc_dai_driver sgtl5000_dai = { .formats = SGTL5000_FORMATS, }, .ops = &sgtl5000_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static bool sgtl5000_volatile(struct device *dev, unsigned int reg) -- GitLab From 23df7f69ff134d108ddffcde622b7ffc904ac789 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:55:47 +0900 Subject: [PATCH 0462/1084] ASoC: mc13783: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87o8hqn6ty.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/mc13783.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 9e6a0cda43d0b..a21072503cb95 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -712,7 +712,7 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = { .formats = MC13783_FORMATS, }, .ops = &mc13783_ops_sync, - .symmetric_rates = 1, + .symmetric_rate = 1, } }; -- GitLab From 852d4daa9689188f25cd1aa92d4daf3a88d73101 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:55:51 +0900 Subject: [PATCH 0463/1084] ASoC: mt6660: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87mtxan6tt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/mt6660.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/mt6660.c b/sound/soc/codecs/mt6660.c index d1797003c83dd..358c500377dff 100644 --- a/sound/soc/codecs/mt6660.c +++ b/sound/soc/codecs/mt6660.c @@ -404,9 +404,9 @@ static struct snd_soc_dai_driver mt6660_codec_dai = { .formats = STUB_FORMATS, }, /* dai properties */ - .symmetric_rates = 1, + .symmetric_rate = 1, .symmetric_channels = 1, - .symmetric_samplebits = 1, + .symmetric_sample_bits = 1, /* dai operations */ .ops = &mt6660_component_aif_ops, }; -- GitLab From 65ba325625e74f44fe7c0052a85bcdfac2b012ec Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:55:56 +0900 Subject: [PATCH 0464/1084] ASoC: lochnagar-sc: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87lfcun6tp.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/lochnagar-sc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/lochnagar-sc.c b/sound/soc/codecs/lochnagar-sc.c index 3209b39e46aff..54426a90bc0bf 100644 --- a/sound/soc/codecs/lochnagar-sc.c +++ b/sound/soc/codecs/lochnagar-sc.c @@ -166,8 +166,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { .formats = SNDRV_PCM_FMTBIT_S32_LE, }, .ops = &lochnagar_sc_line_ops, - .symmetric_rates = true, - .symmetric_samplebits = true, + .symmetric_rate = true, + .symmetric_sample_bits = true, }, { .name = "lochnagar-usb1", @@ -186,8 +186,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { .formats = SNDRV_PCM_FMTBIT_S32_LE, }, .ops = &lochnagar_sc_usb_ops, - .symmetric_rates = true, - .symmetric_samplebits = true, + .symmetric_rate = true, + .symmetric_sample_bits = true, }, { .name = "lochnagar-usb2", @@ -206,8 +206,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { .formats = SNDRV_PCM_FMTBIT_S32_LE, }, .ops = &lochnagar_sc_usb_ops, - .symmetric_rates = true, - .symmetric_samplebits = true, + .symmetric_rate = true, + .symmetric_sample_bits = true, }, }; -- GitLab From 6058bcb4974418bdec55738383755b83e57e555e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:56:00 +0900 Subject: [PATCH 0465/1084] ASoC: ab8500: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87k0sen6tl.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/ab8500-codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 31a8c4162d209..c95f007cede1a 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -2384,7 +2384,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = { .formats = AB8500_SUPPORTED_FMT, }, .ops = &ab8500_codec_ops, - .symmetric_rates = 1 + .symmetric_rate = 1 }, { .name = "ab8500-codec-dai.1", @@ -2397,7 +2397,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = { .formats = AB8500_SUPPORTED_FMT, }, .ops = &ab8500_codec_ops, - .symmetric_rates = 1 + .symmetric_rate = 1 } }; -- GitLab From 278eacf3dc717f27463d56d605c2ea919e308e49 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:56:04 +0900 Subject: [PATCH 0466/1084] ASoC: alc5632: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87im7yn6th.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/alc5632.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index bde5ded677542..79813882a9552 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1032,7 +1032,7 @@ static struct snd_soc_dai_driver alc5632_dai = { .formats = ALC5632_FORMATS,}, .ops = &alc5632_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; #ifdef CONFIG_PM -- GitLab From 15d27c2b129fc8234ed709bdcbd17fa3fff0808e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:56:09 +0900 Subject: [PATCH 0467/1084] ASoC: cx2072x: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87h7nin6tc.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cx2072x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/cx2072x.c b/sound/soc/codecs/cx2072x.c index 2f10991a8bdb5..8ab22815c2c97 100644 --- a/sound/soc/codecs/cx2072x.c +++ b/sound/soc/codecs/cx2072x.c @@ -1572,7 +1572,7 @@ static struct snd_soc_dai_driver soc_codec_cx2072x_dai[] = { .formats = CX2072X_FORMATS, }, .ops = &cx2072x_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { /* plabayck only, return echo reference to Conexant DSP chip */ .name = "cx2072x-dsp", -- GitLab From d5d396c8b01e1fea696c68d255c2d7206de6499f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:56:12 +0900 Subject: [PATCH 0468/1084] ASoC: inno_rk3036: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87ft32n6t8.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/inno_rk3036.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c index 4dbce24c5f76f..e05c4f27486e7 100644 --- a/sound/soc/codecs/inno_rk3036.c +++ b/sound/soc/codecs/inno_rk3036.c @@ -325,7 +325,7 @@ static struct snd_soc_dai_driver rk3036_codec_dai_driver[] = { .formats = RK3036_CODEC_FMTS, }, .ops = &rk3036_codec_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; -- GitLab From 3b940ecd2ebfdd9a2b4a7a97aef1f25d1844d3ba Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:56:16 +0900 Subject: [PATCH 0469/1084] ASoC: lm49453: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87eeimn6t4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/lm49453.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 06ab61f6f7199..eb3dd0bd80d9a 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1343,7 +1343,7 @@ static struct snd_soc_dai_driver lm49453_dai[] = { .formats = LM49453_FORMATS, }, .ops = &lm49453_headset_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "LM49453 Speaker", -- GitLab From 6944db0ab8c4b7c19b7ff9fbbe98322efcd9595a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:56:21 +0900 Subject: [PATCH 0470/1084] ASoC: ml26124: sync parameter naming (rate/sample_bits) This patch syncs naming rule. - xxx_rates; + xxx_rate; - xxx_samplebits; + xxx_sample_bits; Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87czy6n6t0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/ml26124.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index 70c17be455cae..4d7c0be2a4aa7 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c @@ -513,7 +513,7 @@ static struct snd_soc_dai_driver ml26124_dai = { .rates = ML26124_RATES, .formats = ML26124_FORMATS,}, .ops = &ml26124_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static int ml26124_probe(struct snd_soc_component *component) -- GitLab From fa31a2c787aeaf61d02b2a57bd9765ca5e67d949 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:56:30 +0900 Subject: [PATCH 0471/1084] ASoC: soc-dai.h: remove symmetric_rates/samplebits All drivers are using new name. Let's remove old one. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87bldqn6sr.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 2 -- sound/soc/soc-core.c | 9 --------- 2 files changed, 11 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index ee3c6deb57191..1358a0ceb4d01 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -353,10 +353,8 @@ struct snd_soc_dai_driver { /* DAI capabilities */ struct snd_soc_pcm_stream capture; struct snd_soc_pcm_stream playback; - unsigned int symmetric_rates:1; /* will be removed */ unsigned int symmetric_rate:1; unsigned int symmetric_channels:1; - unsigned int symmetric_samplebits:1; /* will be removed */ unsigned int symmetric_sample_bits:1; /* probe ordering - for components with runtime dependencies */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index bb8323cad51ad..f6d4e99b590c7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2509,15 +2509,6 @@ int snd_soc_register_component(struct device *dev, { struct snd_soc_component *component; int ret; - int i; - - /* Remove ME */ - for (i = 0; i < num_dai; i++) { - if (dai_drv[i].symmetric_rates) - dai_drv[i].symmetric_rate = dai_drv[i].symmetric_rates; - if (dai_drv[i].symmetric_samplebits) - dai_drv[i].symmetric_sample_bits = dai_drv[i].symmetric_samplebits; - } component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL); if (!component) -- GitLab From fac110cbcddec115c7d4b79d7491aebebbe44469 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:56:35 +0900 Subject: [PATCH 0472/1084] ASoC: soc-pcm: cleanup soc_pcm_apply_symmetry() soc_pcm_apply_symmetry() want to call snd_pcm_hw_constraint_single() for rate/channel/sample_bits, but, it needs many condition checks. These are very similar but different, thus, it needs to have very verbose code. This patch use macro for it and make code more simple. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87a6tan6sm.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 67 ++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 47 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 1a5d0cb3dc697..57341a0fd67c4 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -349,53 +349,26 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); int ret; - if (soc_dai->rate && (soc_dai->driver->symmetric_rate || - rtd->dai_link->symmetric_rate)) { - dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", - soc_dai->rate); - - ret = snd_pcm_hw_constraint_single(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - soc_dai->rate); - if (ret < 0) { - dev_err(soc_dai->dev, - "ASoC: Unable to apply rate constraint: %d\n", - ret); - return ret; - } - } - - if (soc_dai->channels && (soc_dai->driver->symmetric_channels || - rtd->dai_link->symmetric_channels)) { - dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n", - soc_dai->channels); - - ret = snd_pcm_hw_constraint_single(substream->runtime, - SNDRV_PCM_HW_PARAM_CHANNELS, - soc_dai->channels); - if (ret < 0) { - dev_err(soc_dai->dev, - "ASoC: Unable to apply channel symmetry constraint: %d\n", - ret); - return ret; - } - } - - if (soc_dai->sample_bits && (soc_dai->driver->symmetric_sample_bits || - rtd->dai_link->symmetric_sample_bits)) { - dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n", - soc_dai->sample_bits); - - ret = snd_pcm_hw_constraint_single(substream->runtime, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - soc_dai->sample_bits); - if (ret < 0) { - dev_err(soc_dai->dev, - "ASoC: Unable to apply sample bits symmetry constraint: %d\n", - ret); - return ret; - } - } +#define __soc_pcm_apply_symmetry(name, NAME) \ + if (soc_dai->name && (soc_dai->driver->symmetric_##name || \ + rtd->dai_link->symmetric_##name)) { \ + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %s to %d\n",\ + #name, soc_dai->name); \ + \ + ret = snd_pcm_hw_constraint_single(substream->runtime, \ + SNDRV_PCM_HW_PARAM_##NAME,\ + soc_dai->name); \ + if (ret < 0) { \ + dev_err(soc_dai->dev, \ + "ASoC: Unable to apply %s constraint: %d\n",\ + #name, ret); \ + return ret; \ + } \ + } + + __soc_pcm_apply_symmetry(rate, RATE); + __soc_pcm_apply_symmetry(channels, CHANNELS); + __soc_pcm_apply_symmetry(sample_bits, SAMPLE_BITS); return 0; } -- GitLab From 3a906721112263f1698d7752f6f0133c78fc12c2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Jan 2021 13:56:39 +0900 Subject: [PATCH 0473/1084] ASoC: soc-pcm: cleanup soc_pcm_params_symmetry() soc_pcm_params_symmetry() checks rate/channel/sample_bits state. These are very similar but different, thus, it needs to have very verbose code. This patch use macro for it and make code more simple. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/878s8un6si.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 60 ++++++++++++--------------------------------- 1 file changed, 15 insertions(+), 45 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 57341a0fd67c4..7079a301ec31d 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -384,53 +384,23 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, soc_pcm_set_dai_params(&d, params); - /* reject unmatched parameters when applying symmetry */ - symmetry = rtd->dai_link->symmetric_rate; - - for_each_rtd_cpu_dais(rtd, i, dai) - symmetry |= dai->driver->symmetric_rate; - - if (symmetry) { - for_each_rtd_cpu_dais(rtd, i, cpu_dai) { - if (cpu_dai->rate && cpu_dai->rate != d.rate) { - dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n", - cpu_dai->rate, d.rate); - return -EINVAL; - } - } - } - - symmetry = rtd->dai_link->symmetric_channels; - - for_each_rtd_dais(rtd, i, dai) - symmetry |= dai->driver->symmetric_channels; - - if (symmetry) { - for_each_rtd_cpu_dais(rtd, i, cpu_dai) { - if (cpu_dai->channels && - cpu_dai->channels != d.channels) { - dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n", - cpu_dai->channels, d.channels); - return -EINVAL; +#define __soc_pcm_params_symmetry(name) \ + symmetry = rtd->dai_link->symmetric_##name; \ + for_each_rtd_dais(rtd, i, dai) \ + symmetry |= dai->driver->symmetric_##name; \ + \ + if (symmetry) \ + for_each_rtd_cpu_dais(rtd, i, cpu_dai) \ + if (cpu_dai->name && cpu_dai->name != d.name) { \ + dev_err(rtd->dev, "ASoC: unmatched %s symmetry: %d - %d\n", \ + #name, cpu_dai->name, d.name); \ + return -EINVAL; \ } - } - } - symmetry = rtd->dai_link->symmetric_sample_bits; - - for_each_rtd_dais(rtd, i, dai) - symmetry |= dai->driver->symmetric_sample_bits; - - if (symmetry) { - for_each_rtd_cpu_dais(rtd, i, cpu_dai) { - if (cpu_dai->sample_bits && - cpu_dai->sample_bits != d.sample_bits) { - dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n", - cpu_dai->sample_bits, d.sample_bits); - return -EINVAL; - } - } - } + /* reject unmatched parameters when applying symmetry */ + __soc_pcm_params_symmetry(rate); + __soc_pcm_params_symmetry(channels); + __soc_pcm_params_symmetry(sample_bits); return 0; } -- GitLab From dcf3c8fb32ddbfa3b8227db38aa6746405bd4527 Mon Sep 17 00:00:00 2001 From: Shay Bar Date: Tue, 22 Dec 2020 08:47:14 +0200 Subject: [PATCH 0474/1084] mac80211: 160MHz with extended NSS BW in CSA Upon receiving CSA with 160MHz extended NSS BW from associated AP, STA should set the HT operation_mode based on new_center_freq_seg1 because it is later used as ccfs2 in ieee80211_chandef_vht_oper(). Signed-off-by: Aviad Brikman Signed-off-by: Shay Bar Link: https://lore.kernel.org/r/20201222064714.24888-1-shay.bar@celeno.com Signed-off-by: Johannes Berg --- net/mac80211/spectmgmt.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index ae1cb2c687224..76747bfdaddd0 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c @@ -133,16 +133,20 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, } if (wide_bw_chansw_ie) { + u8 new_seg1 = wide_bw_chansw_ie->new_center_freq_seg1; struct ieee80211_vht_operation vht_oper = { .chan_width = wide_bw_chansw_ie->new_channel_width, .center_freq_seg0_idx = wide_bw_chansw_ie->new_center_freq_seg0, - .center_freq_seg1_idx = - wide_bw_chansw_ie->new_center_freq_seg1, + .center_freq_seg1_idx = new_seg1, /* .basic_mcs_set doesn't matter */ }; - struct ieee80211_ht_operation ht_oper = {}; + struct ieee80211_ht_operation ht_oper = { + .operation_mode = + cpu_to_le16(new_seg1 << + IEEE80211_HT_OP_MODE_CCFS2_SHIFT), + }; /* default, for the case of IEEE80211_VHT_CHANWIDTH_USE_HT, * to the previously parsed chandef -- GitLab From 67de8dca50c027ca0fa3b62a488ee5035036a0da Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Wed, 20 Jan 2021 21:09:49 -0800 Subject: [PATCH 0475/1084] x86/mmx: Use KFPU_387 for MMX string operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default kernel_fpu_begin() doesn't work on systems that support XMM but haven't yet enabled CR4.OSFXSR. This causes crashes when _mmx_memcpy() is called too early because LDMXCSR generates #UD when the aforementioned bit is clear. Fix it by using kernel_fpu_begin_mask(KFPU_387) explicitly. Fixes: 7ad816762f9b ("x86/fpu: Reset MXCSR to default in kernel_fpu_begin()") Reported-by: Krzysztof Mazur Signed-off-by: Andy Lutomirski Signed-off-by: Borislav Petkov Tested-by: Krzysztof Piotr Olędzki Tested-by: Krzysztof Mazur Cc: Link: https://lkml.kernel.org/r/e7bf21855fe99e5f3baa27446e32623358f69e8d.1611205691.git.luto@kernel.org --- arch/x86/lib/mmx_32.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/x86/lib/mmx_32.c b/arch/x86/lib/mmx_32.c index 4321fa02e18df..419365c48b2ad 100644 --- a/arch/x86/lib/mmx_32.c +++ b/arch/x86/lib/mmx_32.c @@ -26,6 +26,16 @@ #include #include +/* + * Use KFPU_387. MMX instructions are not affected by MXCSR, + * but both AMD and Intel documentation states that even integer MMX + * operations will result in #MF if an exception is pending in FCW. + * + * EMMS is not needed afterwards because, after calling kernel_fpu_end(), + * any subsequent user of the 387 stack will reinitialize it using + * KFPU_387. + */ + void *_mmx_memcpy(void *to, const void *from, size_t len) { void *p; @@ -37,7 +47,7 @@ void *_mmx_memcpy(void *to, const void *from, size_t len) p = to; i = len >> 6; /* len/64 */ - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); __asm__ __volatile__ ( "1: prefetch (%0)\n" /* This set is 28 bytes */ @@ -127,7 +137,7 @@ static void fast_clear_page(void *page) { int i; - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); __asm__ __volatile__ ( " pxor %%mm0, %%mm0\n" : : @@ -160,7 +170,7 @@ static void fast_copy_page(void *to, void *from) { int i; - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); /* * maybe the prefetch stuff can go before the expensive fnsave... @@ -247,7 +257,7 @@ static void fast_clear_page(void *page) { int i; - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); __asm__ __volatile__ ( " pxor %%mm0, %%mm0\n" : : @@ -282,7 +292,7 @@ static void fast_copy_page(void *to, void *from) { int i; - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); __asm__ __volatile__ ( "1: prefetch (%0)\n" -- GitLab From 06c8456753f6fc89ff5894cc8cca24b1ac92a5d6 Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Thu, 21 Jan 2021 18:03:53 +0800 Subject: [PATCH 0476/1084] ASoC: rt5682: remove connection with LDO2 in DAPM graph The application circuit shall provide MICVDD power. In default, the codec driver doesn't need to enable LDO2. In case, a board wants to use VBAT for micbias, it should add a DAPM route which IN1P connects with LDO2 in the machine driver. e.g. { "IN1P", NULL, "LDO2" }, Signed-off-by: Shuming Fan Link: https://lore.kernel.org/r/20210121100353.6402-1-shumingf@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 42ad5bea86b50..185906d6d4e01 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -1854,8 +1854,6 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { {"CLKDET SYS", NULL, "CLKDET"}, - {"IN1P", NULL, "LDO2"}, - {"BST1 CBJ", NULL, "IN1P"}, {"RECMIX1L", "CBJ Switch", "BST1 CBJ"}, -- GitLab From 97784481757fba7570121a70dd37ca74a29f50a8 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Wed, 20 Jan 2021 23:22:02 -0800 Subject: [PATCH 0477/1084] lightnvm: fix memory leak when submit fails The allocated page is not released if error occurs in nvm_submit_io_sync_raw(). __free_page() is moved ealier to avoid possible memory leak issue. Fixes: aff3fb18f957 ("lightnvm: move bad block and chunk state logic to core") Signed-off-by: Pan Bian Signed-off-by: Jens Axboe --- drivers/lightnvm/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index c1bcac71008c6..28ddcaa5358b1 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -844,11 +844,10 @@ static int nvm_bb_chunk_sense(struct nvm_dev *dev, struct ppa_addr ppa) rqd.ppa_addr = generic_to_dev_addr(dev, ppa); ret = nvm_submit_io_sync_raw(dev, &rqd); + __free_page(page); if (ret) return ret; - __free_page(page); - return rqd.error; } -- GitLab From 139bc8a6146d92822c866cf2fd410159c56b3648 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 21 Jan 2021 12:08:15 +0000 Subject: [PATCH 0478/1084] KVM: Forbid the use of tagged userspace addresses for memslots The use of a tagged address could be pretty confusing for the whole memslot infrastructure as well as the MMU notifiers. Forbid it altogether, as it never quite worked the first place. Cc: stable@vger.kernel.org Reported-by: Rick Edgecombe Reviewed-by: Catalin Marinas Signed-off-by: Marc Zyngier --- Documentation/virt/kvm/api.rst | 3 +++ virt/kvm/kvm_main.c | 1 + 2 files changed, 4 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 4e5316ed10e90..c347b7083abf4 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -1269,6 +1269,9 @@ field userspace_addr, which must point at user addressable memory for the entire memory slot size. Any object may back this memory, including anonymous memory, ordinary files, and hugetlbfs. +On architectures that support a form of address tagging, userspace_addr must +be an untagged address. + It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr be identical. This allows large pages in the guest to be backed by large pages in the host. diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2541a17ff1c45..a9abaf5f8e53c 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1290,6 +1290,7 @@ int __kvm_set_memory_region(struct kvm *kvm, return -EINVAL; /* We can read the guest memory with __xxx_user() later on. */ if ((mem->userspace_addr & (PAGE_SIZE - 1)) || + (mem->userspace_addr != untagged_addr(mem->userspace_addr)) || !access_ok((void __user *)(unsigned long)mem->userspace_addr, mem->memory_size)) return -EINVAL; -- GitLab From 348fe1ca5ccdca0f8c285e2ab99004fdcd531430 Mon Sep 17 00:00:00 2001 From: Sung Lee Date: Tue, 5 Jan 2021 14:32:29 -0500 Subject: [PATCH 0479/1084] drm/amd/display: DCN2X Find Secondary Pipe properly in MPO + ODM Case [WHY] Previously as MPO + ODM Combine was not supported, finding secondary pipes for each case was mutually exclusive. Now that both are supported at the same time, both cases should be taken into account when finding a secondary pipe. [HOW] If a secondary pipe cannot be found based on previous bottom pipe, search for a second pipe using next_odm_pipe instead. Tested-by: Daniel Wheeler Signed-off-by: Sung Lee Reviewed-by: Dmytro Laktyushkin Acked-by: Anson Jacob Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 5.10.x --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index e04ecf0fc0dbc..5ed18cac57e8d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2517,8 +2517,7 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, * if this primary pipe has a bottom pipe in prev. state * and if the bottom pipe is still available (which it should be), * pick that pipe as secondary - * Same logic applies for ODM pipes. Since mpo is not allowed with odm - * check in else case. + * Same logic applies for ODM pipes */ if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe) { preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe->pipe_idx; @@ -2526,7 +2525,9 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx]; secondary_pipe->pipe_idx = preferred_pipe_idx; } - } else if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) { + } + if (secondary_pipe == NULL && + dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) { preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe->pipe_idx; if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) { secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx]; -- GitLab From acc214bfafbafcd29d5d25d1ede5f11c14ffc147 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 19 Jan 2021 13:35:21 +0800 Subject: [PATCH 0480/1084] drm/amdgpu: remove gpu info firmware of green sardine The ip discovery is supported on green sardine, it doesn't need gpu info firmware anymore. Signed-off-by: Huang Rui Reviewed-by: Prike Liang Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 5.10.x --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 087afab67e221..cab1ebaf6d629 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -81,7 +81,6 @@ MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/vangogh_gpu_info.bin"); -MODULE_FIRMWARE("amdgpu/green_sardine_gpu_info.bin"); #define AMDGPU_RESUME_MS 2000 -- GitLab From bdfc6fd6c8df1a9d481c4417df571e94a33168bf Mon Sep 17 00:00:00 2001 From: Jake Wang Date: Fri, 8 Jan 2021 12:27:51 -0500 Subject: [PATCH 0481/1084] drm/amd/display: Update dram_clock_change_latency for DCN2.1 [WHY] dram clock change latencies get updated using ddr4 latency table, but that update does not happen before validation. This value should not be the default and should be number received from df for better mode support. This may cause a PState hang on high refresh panels with short vblanks such as on 1080p 360hz or 300hz panels. [HOW] Update latency from 23.84 to 11.72. Tested-by: Daniel Wheeler Signed-off-by: Jake Wang Reviewed-by: Sung Lee Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index 1c88d2edd381c..b000b43a820d4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -296,7 +296,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { .num_banks = 8, .num_chans = 4, .vmm_page_size_bytes = 4096, - .dram_clock_change_latency_us = 23.84, + .dram_clock_change_latency_us = 11.72, .return_bus_width_bytes = 64, .dispclk_dppclk_vco_speed_mhz = 3600, .xfc_bus_transport_time_us = 4, -- GitLab From 8bc3d461d0a95bbcc2a0a908bbadc87e198a86a8 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Thu, 29 Oct 2020 17:45:19 -0400 Subject: [PATCH 0482/1084] drm/amd/display: Allow PSTATE chnage when no displays are enabled [Why] When no displays are currently enabled, display driver should not disallow PSTATE switching. [How] Allow PSTATE switching if either the active configuration supports it, or there are no active displays. Tested-by: Daniel Wheeler Signed-off-by: Aric Cyr Reviewed-by: Jun Lei Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c index 5b466f440d671..ab98c259ef695 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c @@ -251,6 +251,7 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu; bool force_reset = false; bool update_uclk = false; + bool p_state_change_support; if (dc->work_arounds.skip_clock_update || !clk_mgr->smu_present) return; @@ -291,8 +292,9 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz; clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support; - if (should_update_pstate_support(safe_to_lower, new_clocks->p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { - clk_mgr_base->clks.p_state_change_support = new_clocks->p_state_change_support; + p_state_change_support = new_clocks->p_state_change_support || (display_count == 0); + if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { + clk_mgr_base->clks.p_state_change_support = p_state_change_support; /* to disable P-State switching, set UCLK min = max */ if (!clk_mgr_base->clks.p_state_change_support) -- GitLab From 4716a7c50c5c66d6ddc42401e1e0ba13b492e105 Mon Sep 17 00:00:00 2001 From: Bing Guo Date: Mon, 4 Jan 2021 14:09:41 -0500 Subject: [PATCH 0483/1084] drm/amd/display: Change function decide_dp_link_settings to avoid infinite looping Why: Function decide_dp_link_settings() loops infinitely when required bandwidth can't be supported. How: Check the required bandwidth against verified_link_cap before trying to find a link setting for it. Tested-by: Daniel Wheeler Signed-off-by: Bing Guo Reviewed-by: Jun Lei Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 1bd1a09352906..28b4b084199c2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2399,6 +2399,9 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting initial_link_setting; uint32_t link_bw; + if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap)) + return false; + /* search for the minimum link setting that: * 1. is supported according to the link training result * 2. could support the b/w requested by the timing -- GitLab From c74f865f14318217350aa33363577cb95b06eb82 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Sun, 13 Dec 2020 10:59:01 -0500 Subject: [PATCH 0484/1084] drm/amd/display: Use hardware sequencer functions for PG control [Why & How] These can differ per ASIC or not be present. Don't call the dcn20 ones directly but rather the ones defined by the ASIC init table. Tested-by: Daniel Wheeler Signed-off-by: Nicholas Kazlauskas Reviewed-by: Eric Yang Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 18 ++++++++++++++---- .../gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 9 +++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index cfc130e2d6fd0..017b67b830e66 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -647,8 +647,13 @@ static void power_on_plane( if (REG(DC_IP_REQUEST_CNTL)) { REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); - hws->funcs.dpp_pg_control(hws, plane_id, true); - hws->funcs.hubp_pg_control(hws, plane_id, true); + + if (hws->funcs.dpp_pg_control) + hws->funcs.dpp_pg_control(hws, plane_id, true); + + if (hws->funcs.hubp_pg_control) + hws->funcs.hubp_pg_control(hws, plane_id, true); + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); DC_LOG_DEBUG( @@ -1082,8 +1087,13 @@ void dcn10_plane_atomic_power_down(struct dc *dc, if (REG(DC_IP_REQUEST_CNTL)) { REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); - hws->funcs.dpp_pg_control(hws, dpp->inst, false); - hws->funcs.hubp_pg_control(hws, hubp->inst, false); + + if (hws->funcs.dpp_pg_control) + hws->funcs.dpp_pg_control(hws, dpp->inst, false); + + if (hws->funcs.hubp_pg_control) + hws->funcs.hubp_pg_control(hws, hubp->inst, false); + dpp->funcs->dpp_reset(dpp); REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index cb822df21b7c5..480d928cb1ca6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1062,8 +1062,13 @@ static void dcn20_power_on_plane( if (REG(DC_IP_REQUEST_CNTL)) { REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); - dcn20_dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true); - dcn20_hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true); + + if (hws->funcs.dpp_pg_control) + hws->funcs.dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true); + + if (hws->funcs.hubp_pg_control) + hws->funcs.hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true); + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); DC_LOG_DEBUG( -- GitLab From 4b08d8c78360241d270396a9de6eb774e88acd00 Mon Sep 17 00:00:00 2001 From: Vladimir Stempen Date: Mon, 4 Jan 2021 12:05:26 -0500 Subject: [PATCH 0485/1084] drm/amd/display: Fixed corruptions on HPDRX link loss restore [why] Heavy corruption or blank screen reported on wake, with 6k display connected and FEC enabled [how] When Disable/Enable stream for display pipes on HPDRX, DC should take into account ODM split pipes. Tested-by: Daniel Wheeler Signed-off-by: Vladimir Stempen Reviewed-by: Aric Cyr Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 28b4b084199c2..f95bade596242 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -3048,14 +3048,14 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && - pipe_ctx->stream->link == link) + pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) core_link_disable_stream(pipe_ctx); } for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && - pipe_ctx->stream->link == link) + pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) core_link_enable_stream(link->dc->current_state, pipe_ctx); } -- GitLab From 51e87da7d4014f49769dcf60b8626a81492df2c4 Mon Sep 17 00:00:00 2001 From: Prike Liang Date: Thu, 17 Dec 2020 13:55:46 +0800 Subject: [PATCH 0486/1084] drm/amdgpu/pm: no need GPU status set since mmnbif_gpu_BIF_DOORBELL_FENCE_CNTL added in FSDL In the renoir there is no need GpuChangeState message set to exit gfxoff in the s0i3 resume since mmnbif_gpu_BIF_DOORBELL_FENCE_CNTL has been added in the s0i3 FSDL. Signed-off-by: Prike Liang Reviewed-by: Huang Rui Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c index f743685a20e8a..9a96970380160 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -1121,7 +1121,7 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu, static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state) { - return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GpuChangeState, state, NULL); + return 0; } static const struct pptable_funcs renoir_ppt_funcs = { -- GitLab From 8f0d60fe8bf24fd79892a1a22f16c0629d5af6d3 Mon Sep 17 00:00:00 2001 From: Jinzhou Su Date: Mon, 18 Jan 2021 19:14:27 +0800 Subject: [PATCH 0487/1084] drm/amdgpu: modify GCR_GENERAL_CNTL for Vangogh GCR_GENERAL_CNTL is defined differently in gc_10_1_0_offset.h and gc_10_3_0_offset.h. Update GCR_GENERAL_CNTL for Vangogh. Signed-off-by: Jinzhou Su Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 619d34c041ee0..346963e3cf731 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -119,6 +119,8 @@ #define mmVGT_ESGS_RING_SIZE_Vangogh_BASE_IDX 1 #define mmSPI_CONFIG_CNTL_Vangogh 0x2440 #define mmSPI_CONFIG_CNTL_Vangogh_BASE_IDX 1 +#define mmGCR_GENERAL_CNTL_Vangogh 0x1580 +#define mmGCR_GENERAL_CNTL_Vangogh_BASE_IDX 0 #define mmCP_HYP_PFP_UCODE_ADDR 0x5814 #define mmCP_HYP_PFP_UCODE_ADDR_BASE_IDX 1 @@ -3244,7 +3246,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_3_vangogh[] = SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_EXCEPTION_CONTROL, 0x7fff0f1f, 0x00b80000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1807ff, 0x00000142), - SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL_Vangogh, 0x1ff1ffff, 0x00000500), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0x000000ff, 0x000000e4), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_0, 0x77777777, 0x32103210), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_1, 0x77777777, 0x32103210), -- GitLab From 39263a2f886817a376fc27ba9af14c5053f0934b Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Mon, 18 Jan 2021 17:05:00 +0800 Subject: [PATCH 0488/1084] drm/amdgpu: update mmhub mgcg&ls for mmhub_v2_3 Starting from vangogh, the ATCL2 and DAGB0 registers relative to mgcg/ls has changed. For MGCG: Replace mmMM_ATC_L2_MISC_CG with mmMM_ATC_L2_CGTT_CLK_CTRL. For MGLS: Replace mmMM_ATC_L2_MISC_CG with mmMM_ATC_L2_CGTT_CLK_CTRL. Add DAGB0_(WR/RD)_CGTT_CLK_CTRL registers. Signed-off-by: Aaron Liu Acked-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c | 84 ++++++++++++++++++------- 1 file changed, 61 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c index 07104a1de3082..1961745e89c73 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c @@ -491,12 +491,11 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev, { uint32_t def, data, def1, data1; - def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); + def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL); def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2); if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)) { - data |= MM_ATC_L2_MISC_CG__ENABLE_MASK; - + data &= ~MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK; data1 &= ~(DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | @@ -505,8 +504,7 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev, DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); } else { - data &= ~MM_ATC_L2_MISC_CG__ENABLE_MASK; - + data |= MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK; data1 |= (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | @@ -516,7 +514,7 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev, } if (def != data) - WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data); + WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL, data); if (def1 != data1) WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2, data1); } @@ -525,17 +523,44 @@ static void mmhub_v2_3_update_medium_grain_light_sleep(struct amdgpu_device *adev, bool enable) { - uint32_t def, data; - - def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); - - if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS)) - data |= MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; - else - data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; + uint32_t def, data, def1, data1, def2, data2; + + def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL); + def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL); + def2 = data2 = RREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL); + + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS)) { + data &= ~MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK; + data1 &= !(DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK); + data2 &= !(DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK); + } else { + data |= MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK; + data1 |= (DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK); + data2 |= (DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK); + } if (def != data) - WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data); + WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL, data); + if (def1 != data1) + WREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL, data1); + if (def2 != data2) + WREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL, data2); } static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev, @@ -554,26 +579,39 @@ static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev, static void mmhub_v2_3_get_clockgating(struct amdgpu_device *adev, u32 *flags) { - int data, data1; + int data, data1, data2, data3; if (amdgpu_sriov_vf(adev)) *flags = 0; - data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); - data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2); + data = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2); + data1 = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL); + data2 = RREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL); + data3 = RREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL); /* AMD_CG_SUPPORT_MC_MGCG */ - if ((data & MM_ATC_L2_MISC_CG__ENABLE_MASK) && - !(data1 & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | + if (!(data & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | - DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK))) - *flags |= AMD_CG_SUPPORT_MC_MGCG; + DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK)) + && !(data1 & MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK)) { + *flags |= AMD_CG_SUPPORT_MC_MGCG; + } /* AMD_CG_SUPPORT_MC_LS */ - if (data & MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK) + if (!(data1 & MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK) + && !(data2 & (DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | + DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK)) + && !(data3 & (DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK | + DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK))) *flags |= AMD_CG_SUPPORT_MC_LS; } -- GitLab From 9d5ae6f3c50a6f718b6d4be3c7b0828966e01b05 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Wed, 20 Jan 2021 14:49:07 +0100 Subject: [PATCH 0489/1084] libceph: fix "Boolean result is used in bitwise operation" warning This line dates back to 2013, but cppcheck complained because commit 2f713615ddd9 ("libceph: move msgr1 protocol implementation to its own file") moved it. Add parenthesis to silence the warning. Reported-by: kernel test robot Signed-off-by: Ilya Dryomov --- net/ceph/messenger_v1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ceph/messenger_v1.c b/net/ceph/messenger_v1.c index 04f653b3c8973..2cb5ffdf071af 100644 --- a/net/ceph/messenger_v1.c +++ b/net/ceph/messenger_v1.c @@ -1100,7 +1100,7 @@ static int read_partial_message(struct ceph_connection *con) if (ret < 0) return ret; - BUG_ON(!con->in_msg ^ skip); + BUG_ON((!con->in_msg) ^ skip); if (skip) { /* skip this message */ dout("alloc_msg said skip message\n"); -- GitLab From 4eaad21a6ac9865df7f31983232ed5928450458d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 20 Jan 2021 21:46:29 +0100 Subject: [PATCH 0490/1084] kernfs: implement ->read_iter Switch kernfs to implement the read_iter method instead of plain old read to prepare to supporting splice and sendfile again. Signed-off-by: Christoph Hellwig Link: https://lore.kernel.org/r/20210120204631.274206-2-hch@lst.de Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index f277d023ebcd1..8276e4c8722d8 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "kernfs-internal.h" @@ -180,11 +181,10 @@ static const struct seq_operations kernfs_seq_ops = { * it difficult to use seq_file. Implement simplistic custom buffering for * bin files. */ -static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, - char __user *user_buf, size_t count, - loff_t *ppos) +static ssize_t kernfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) { - ssize_t len = min_t(size_t, count, PAGE_SIZE); + struct kernfs_open_file *of = kernfs_of(iocb->ki_filp); + ssize_t len = min_t(size_t, iov_iter_count(iter), PAGE_SIZE); const struct kernfs_ops *ops; char *buf; @@ -210,7 +210,7 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, of->event = atomic_read(&of->kn->attr.open->event); ops = kernfs_ops(of->kn); if (ops->read) - len = ops->read(of, buf, len, *ppos); + len = ops->read(of, buf, len, iocb->ki_pos); else len = -EINVAL; @@ -220,12 +220,12 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, if (len < 0) goto out_free; - if (copy_to_user(user_buf, buf, len)) { + if (copy_to_iter(buf, len, iter) != len) { len = -EFAULT; goto out_free; } - *ppos += len; + iocb->ki_pos += len; out_free: if (buf == of->prealloc_buf) @@ -235,22 +235,11 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, return len; } -/** - * kernfs_fop_read - kernfs vfs read callback - * @file: file pointer - * @user_buf: data to write - * @count: number of bytes - * @ppos: starting offset - */ -static ssize_t kernfs_fop_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t kernfs_fop_read_iter(struct kiocb *iocb, struct iov_iter *iter) { - struct kernfs_open_file *of = kernfs_of(file); - - if (of->kn->flags & KERNFS_HAS_SEQ_SHOW) - return seq_read(file, user_buf, count, ppos); - else - return kernfs_file_direct_read(of, user_buf, count, ppos); + if (kernfs_of(iocb->ki_filp)->kn->flags & KERNFS_HAS_SEQ_SHOW) + return seq_read_iter(iocb, iter); + return kernfs_file_read_iter(iocb, iter); } /** @@ -960,7 +949,7 @@ void kernfs_notify(struct kernfs_node *kn) EXPORT_SYMBOL_GPL(kernfs_notify); const struct file_operations kernfs_file_fops = { - .read = kernfs_fop_read, + .read_iter = kernfs_fop_read_iter, .write = kernfs_fop_write, .llseek = generic_file_llseek, .mmap = kernfs_fop_mmap, -- GitLab From cc099e0b399889c6485c88368b19824b087c9f8c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 20 Jan 2021 21:46:30 +0100 Subject: [PATCH 0491/1084] kernfs: implement ->write_iter Switch kernfs to implement the write_iter method instead of plain old write to prepare to supporting splice and sendfile again. Signed-off-by: Christoph Hellwig Link: https://lore.kernel.org/r/20210120204631.274206-3-hch@lst.de Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 8276e4c8722d8..b1a5cccf189ec 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -242,13 +242,7 @@ static ssize_t kernfs_fop_read_iter(struct kiocb *iocb, struct iov_iter *iter) return kernfs_file_read_iter(iocb, iter); } -/** - * kernfs_fop_write - kernfs vfs write callback - * @file: file pointer - * @user_buf: data to write - * @count: number of bytes - * @ppos: starting offset - * +/* * Copy data in from userland and pass it to the matching kernfs write * operation. * @@ -258,20 +252,18 @@ static ssize_t kernfs_fop_read_iter(struct kiocb *iocb, struct iov_iter *iter) * modify only the the value you're changing, then write entire buffer * back. */ -static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t kernfs_fop_write_iter(struct kiocb *iocb, struct iov_iter *iter) { - struct kernfs_open_file *of = kernfs_of(file); + struct kernfs_open_file *of = kernfs_of(iocb->ki_filp); + ssize_t len = iov_iter_count(iter); const struct kernfs_ops *ops; - ssize_t len; char *buf; if (of->atomic_write_len) { - len = count; if (len > of->atomic_write_len) return -E2BIG; } else { - len = min_t(size_t, count, PAGE_SIZE); + len = min_t(size_t, len, PAGE_SIZE); } buf = of->prealloc_buf; @@ -282,7 +274,7 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, if (!buf) return -ENOMEM; - if (copy_from_user(buf, user_buf, len)) { + if (copy_from_iter(buf, len, iter) != len) { len = -EFAULT; goto out_free; } @@ -301,7 +293,7 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, ops = kernfs_ops(of->kn); if (ops->write) - len = ops->write(of, buf, len, *ppos); + len = ops->write(of, buf, len, iocb->ki_pos); else len = -EINVAL; @@ -309,7 +301,7 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, mutex_unlock(&of->mutex); if (len > 0) - *ppos += len; + iocb->ki_pos += len; out_free: if (buf == of->prealloc_buf) @@ -662,7 +654,7 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) /* * Write path needs to atomic_write_len outside active reference. - * Cache it in open_file. See kernfs_fop_write() for details. + * Cache it in open_file. See kernfs_fop_write_iter() for details. */ of->atomic_write_len = ops->atomic_write_len; @@ -950,7 +942,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify); const struct file_operations kernfs_file_fops = { .read_iter = kernfs_fop_read_iter, - .write = kernfs_fop_write, + .write_iter = kernfs_fop_write_iter, .llseek = generic_file_llseek, .mmap = kernfs_fop_mmap, .open = kernfs_fop_open, -- GitLab From f2d6c2708bd84ca953fa6b6ca5717e79eb0140c7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 20 Jan 2021 21:46:31 +0100 Subject: [PATCH 0492/1084] kernfs: wire up ->splice_read and ->splice_write Wire up the splice_read and splice_write methods to the default helpers using ->read_iter and ->write_iter now that those are implemented for kernfs. This restores support to use splice and sendfile on kernfs files. Fixes: 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops") Reported-by: Siddharth Gupta Tested-by: Siddharth Gupta Signed-off-by: Christoph Hellwig Link: https://lore.kernel.org/r/20210120204631.274206-4-hch@lst.de Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index b1a5cccf189ec..c757193121475 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -949,6 +949,8 @@ const struct file_operations kernfs_file_fops = { .release = kernfs_fop_release, .poll = kernfs_fop_poll, .fsync = noop_fsync, + .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, }; /** -- GitLab From 3d1cf435e201d1fd63e4346b141881aed086effd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 15 Jan 2021 19:30:51 +0100 Subject: [PATCH 0493/1084] driver core: Extend device_is_dependent() If the device passed as the target (second argument) to device_is_dependent() is not completely registered (that is, it has been initialized, but not added yet), but the parent pointer of it is set, it may be missing from the list of the parent's children and device_for_each_child() called by device_is_dependent() cannot be relied on to catch that dependency. For this reason, modify device_is_dependent() to check the ancestors of the target device by following its parent pointer in addition to the device_for_each_child() walk. Fixes: 9ed9895370ae ("driver core: Functional dependencies tracking support") Reported-by: Stephan Gerhold Tested-by: Stephan Gerhold Reviewed-by: Saravana Kannan Signed-off-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/17705994.d592GUb2YH@kreacher Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 25e08e5f40bd9..3819fd012e271 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -208,6 +208,16 @@ int device_links_read_lock_held(void) #endif #endif /* !CONFIG_SRCU */ +static bool device_is_ancestor(struct device *dev, struct device *target) +{ + while (target->parent) { + target = target->parent; + if (dev == target) + return true; + } + return false; +} + /** * device_is_dependent - Check if one device depends on another one * @dev: Device to check dependencies for. @@ -221,7 +231,12 @@ int device_is_dependent(struct device *dev, void *target) struct device_link *link; int ret; - if (dev == target) + /* + * The "ancestors" check is needed to catch the case when the target + * device has not been completely initialized yet and it is still + * missing from the list of children of its parent device. + */ + if (dev == target || device_is_ancestor(dev, target)) return 1; ret = device_for_each_child(dev, target, device_is_dependent); -- GitLab From 927633a6d20af319d986f3e42c3ef9f6d7835008 Mon Sep 17 00:00:00 2001 From: Wang Hui Date: Fri, 15 Jan 2021 22:59:16 +0300 Subject: [PATCH 0494/1084] stm class: Fix module init return on allocation failure In stm_heartbeat_init(): return value gets reset after the first iteration by stm_source_register_device(), so allocation failures after that will, after a clean up, return success. Fix that. Fixes: 119291853038 ("stm class: Add heartbeat stm source device") Reported-by: Hulk Robot Signed-off-by: Wang Hui Signed-off-by: Alexander Shishkin Link: https://lore.kernel.org/r/20210115195917.3184-2-alexander.shishkin@linux.intel.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/stm/heartbeat.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/hwtracing/stm/heartbeat.c b/drivers/hwtracing/stm/heartbeat.c index 3e7df1c0477f7..81d7b21d31ec2 100644 --- a/drivers/hwtracing/stm/heartbeat.c +++ b/drivers/hwtracing/stm/heartbeat.c @@ -64,7 +64,7 @@ static void stm_heartbeat_unlink(struct stm_source_data *data) static int stm_heartbeat_init(void) { - int i, ret = -ENOMEM; + int i, ret; if (nr_devs < 0 || nr_devs > STM_HEARTBEAT_MAX) return -EINVAL; @@ -72,8 +72,10 @@ static int stm_heartbeat_init(void) for (i = 0; i < nr_devs; i++) { stm_heartbeat[i].data.name = kasprintf(GFP_KERNEL, "heartbeat.%d", i); - if (!stm_heartbeat[i].data.name) + if (!stm_heartbeat[i].data.name) { + ret = -ENOMEM; goto fail_unregister; + } stm_heartbeat[i].data.nr_chans = 1; stm_heartbeat[i].data.link = stm_heartbeat_link; -- GitLab From cb5c681ab9037e25fcca20689c82cf034566d610 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 15 Jan 2021 22:59:17 +0300 Subject: [PATCH 0495/1084] intel_th: pci: Add Alder Lake-P support This adds support for the Trace Hub in Alder Lake-P. Signed-off-by: Alexander Shishkin Link: https://lore.kernel.org/r/20210115195917.3184-3-alexander.shishkin@linux.intel.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 52acd77438ede..251e75c9ba9d0 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -268,6 +268,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7aa6), .driver_data = (kernel_ulong_t)&intel_th_2x, }, + { + /* Alder Lake-P */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x51a6), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, { /* Alder Lake CPU */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f), -- GitLab From 9354f1b421f76f8368be13954f87d07bcbd6fffe Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Sun, 17 Jan 2021 09:39:37 +0200 Subject: [PATCH 0496/1084] habanalabs: zero pci counters packet before submit to FW Driver does not zero some pci counters packets before sending to FW. This causes an out of sync PI/CI between driver and FW. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/firmware_if.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c index 20f77f58edef5..c9a12980218ac 100644 --- a/drivers/misc/habanalabs/common/firmware_if.c +++ b/drivers/misc/habanalabs/common/firmware_if.c @@ -402,6 +402,10 @@ int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev, } counters->rx_throughput = result; + memset(&pkt, 0, sizeof(pkt)); + pkt.ctl = cpu_to_le32(CPUCP_PACKET_PCIE_THROUGHPUT_GET << + CPUCP_PKT_CTL_OPCODE_SHIFT); + /* Fetch PCI tx counter */ pkt.index = cpu_to_le32(cpucp_pcie_throughput_tx); rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), @@ -414,6 +418,7 @@ int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev, counters->tx_throughput = result; /* Fetch PCI replay counter */ + memset(&pkt, 0, sizeof(pkt)); pkt.ctl = cpu_to_le32(CPUCP_PACKET_PCIE_REPLAY_CNT_GET << CPUCP_PKT_CTL_OPCODE_SHIFT); -- GitLab From f8abaf379bfe19600f96ae79a6759eb37039ae05 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Mon, 18 Jan 2021 13:19:51 +0200 Subject: [PATCH 0497/1084] habanalabs: fix backward compatibility of idle check Need to take the lower 32 bits of the driver's 64-bit idle mask and put it in the legacy 32-bit variable that the userspace reads to know the idle mask. Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/habanalabs_ioctl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c index 12efbd9d2e3a0..d25892d61ec9d 100644 --- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c +++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c @@ -133,6 +133,8 @@ static int hw_idle(struct hl_device *hdev, struct hl_info_args *args) hw_idle.is_idle = hdev->asic_funcs->is_device_idle(hdev, &hw_idle.busy_engines_mask_ext, NULL); + hw_idle.busy_engines_mask = + lower_32_bits(hw_idle.busy_engines_mask_ext); return copy_to_user(out, &hw_idle, min((size_t) max_size, sizeof(hw_idle))) ? -EFAULT : 0; -- GitLab From 2dc4a6d79168e7e426e8ddf8e7219c9ffd13b2b1 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Mon, 18 Jan 2021 21:39:46 +0200 Subject: [PATCH 0498/1084] habanalabs: disable FW events on device removal When device is removed, we need to make sure the F/W won't send us any more events because during the remove process we disable the interrupts. Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/device.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 1ea57d86caa37..69d04eca767f5 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -1487,6 +1487,15 @@ void hl_device_fini(struct hl_device *hdev) } } + /* Disable PCI access from device F/W so it won't send us additional + * interrupts. We disable MSI/MSI-X at the halt_engines function and we + * can't have the F/W sending us interrupts after that. We need to + * disable the access here because if the device is marked disable, the + * message won't be send. Also, in case of heartbeat, the device CPU is + * marked as disable so this message won't be sent + */ + hl_fw_send_pci_access_msg(hdev, CPUCP_PACKET_DISABLE_PCI_ACCESS); + /* Mark device as disabled */ hdev->disabled = true; -- GitLab From e020ff611ba9be54e959e6b548038f8a020da1c9 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Sun, 10 Jan 2021 09:54:07 -0800 Subject: [PATCH 0499/1084] driver core: Fix device link device name collision The device link device's name was of the form: -- This can cause name collision as reported here [1] as device names are not globally unique. Since device names have to be unique within the bus/class, add the bus/class name as a prefix to the device names used to construct the device link device name. So the devuce link device's name will be of the form: :--: [1] - https://lore.kernel.org/lkml/20201229033440.32142-1-michael@walle.cc/ Fixes: 287905e68dd2 ("driver core: Expose device link details in sysfs") Cc: stable@vger.kernel.org Reported-by: Michael Walle Tested-by: Michael Walle Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20210110175408.1465657-1-saravanak@google.com Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-class-devlink | 4 +-- .../ABI/testing/sysfs-devices-consumer | 5 ++-- .../ABI/testing/sysfs-devices-supplier | 5 ++-- drivers/base/core.c | 27 ++++++++++--------- include/linux/device.h | 12 +++++++++ 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-devlink b/Documentation/ABI/testing/sysfs-class-devlink index b662f747c83eb..8a21ce515f61f 100644 --- a/Documentation/ABI/testing/sysfs-class-devlink +++ b/Documentation/ABI/testing/sysfs-class-devlink @@ -5,8 +5,8 @@ Description: Provide a place in sysfs for the device link objects in the kernel at any given time. The name of a device link directory, denoted as ... above, is of the form -- - where is the supplier device name and is - the consumer device name. + where is the supplier bus:device name and + is the consumer bus:device name. What: /sys/class/devlink/.../auto_remove_on Date: May 2020 diff --git a/Documentation/ABI/testing/sysfs-devices-consumer b/Documentation/ABI/testing/sysfs-devices-consumer index 1f06d74d1c3cc..0809fda092e66 100644 --- a/Documentation/ABI/testing/sysfs-devices-consumer +++ b/Documentation/ABI/testing/sysfs-devices-consumer @@ -4,5 +4,6 @@ Contact: Saravana Kannan Description: The /sys/devices/.../consumer: are symlinks to device links where this device is the supplier. denotes the - name of the consumer in that device link. There can be zero or - more of these symlinks for a given device. + name of the consumer in that device link and is of the form + bus:device name. There can be zero or more of these symlinks + for a given device. diff --git a/Documentation/ABI/testing/sysfs-devices-supplier b/Documentation/ABI/testing/sysfs-devices-supplier index a919e0db5e902..207f5972e98d8 100644 --- a/Documentation/ABI/testing/sysfs-devices-supplier +++ b/Documentation/ABI/testing/sysfs-devices-supplier @@ -4,5 +4,6 @@ Contact: Saravana Kannan Description: The /sys/devices/.../supplier: are symlinks to device links where this device is the consumer. denotes the - name of the supplier in that device link. There can be zero or - more of these symlinks for a given device. + name of the supplier in that device link and is of the form + bus:device name. There can be zero or more of these symlinks + for a given device. diff --git a/drivers/base/core.c b/drivers/base/core.c index 3819fd012e271..78f6db169d476 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -471,7 +471,9 @@ static int devlink_add_symlinks(struct device *dev, struct device *con = link->consumer; char *buf; - len = max(strlen(dev_name(sup)), strlen(dev_name(con))); + len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)), + strlen(dev_bus_name(con)) + strlen(dev_name(con))); + len += strlen(":"); len += strlen("supplier:") + 1; buf = kzalloc(len, GFP_KERNEL); if (!buf) @@ -485,12 +487,12 @@ static int devlink_add_symlinks(struct device *dev, if (ret) goto err_con; - snprintf(buf, len, "consumer:%s", dev_name(con)); + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); ret = sysfs_create_link(&sup->kobj, &link->link_dev.kobj, buf); if (ret) goto err_con_dev; - snprintf(buf, len, "supplier:%s", dev_name(sup)); + snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); ret = sysfs_create_link(&con->kobj, &link->link_dev.kobj, buf); if (ret) goto err_sup_dev; @@ -498,7 +500,7 @@ static int devlink_add_symlinks(struct device *dev, goto out; err_sup_dev: - snprintf(buf, len, "consumer:%s", dev_name(con)); + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); sysfs_remove_link(&sup->kobj, buf); err_con_dev: sysfs_remove_link(&link->link_dev.kobj, "consumer"); @@ -521,7 +523,9 @@ static void devlink_remove_symlinks(struct device *dev, sysfs_remove_link(&link->link_dev.kobj, "consumer"); sysfs_remove_link(&link->link_dev.kobj, "supplier"); - len = max(strlen(dev_name(sup)), strlen(dev_name(con))); + len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)), + strlen(dev_bus_name(con)) + strlen(dev_name(con))); + len += strlen(":"); len += strlen("supplier:") + 1; buf = kzalloc(len, GFP_KERNEL); if (!buf) { @@ -529,9 +533,9 @@ static void devlink_remove_symlinks(struct device *dev, return; } - snprintf(buf, len, "supplier:%s", dev_name(sup)); + snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); sysfs_remove_link(&con->kobj, buf); - snprintf(buf, len, "consumer:%s", dev_name(con)); + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); sysfs_remove_link(&sup->kobj, buf); kfree(buf); } @@ -752,8 +756,9 @@ struct device_link *device_link_add(struct device *consumer, link->link_dev.class = &devlink_class; device_set_pm_not_required(&link->link_dev); - dev_set_name(&link->link_dev, "%s--%s", - dev_name(supplier), dev_name(consumer)); + dev_set_name(&link->link_dev, "%s:%s--%s:%s", + dev_bus_name(supplier), dev_name(supplier), + dev_bus_name(consumer), dev_name(consumer)); if (device_register(&link->link_dev)) { put_device(consumer); put_device(supplier); @@ -1823,9 +1828,7 @@ const char *dev_driver_string(const struct device *dev) * never change once they are set, so they don't need special care. */ drv = READ_ONCE(dev->driver); - return drv ? drv->name : - (dev->bus ? dev->bus->name : - (dev->class ? dev->class->name : "")); + return drv ? drv->name : dev_bus_name(dev); } EXPORT_SYMBOL(dev_driver_string); diff --git a/include/linux/device.h b/include/linux/device.h index 89bb8b84173e4..1779f90eeb4cb 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -609,6 +609,18 @@ static inline const char *dev_name(const struct device *dev) return kobject_name(&dev->kobj); } +/** + * dev_bus_name - Return a device's bus/class name, if at all possible + * @dev: struct device to get the bus/class name of + * + * Will return the name of the bus/class the device is attached to. If it is + * not attached to a bus/class, an empty string will be returned. + */ +static inline const char *dev_bus_name(const struct device *dev) +{ + return dev->bus ? dev->bus->name : (dev->class ? dev->class->name : ""); +} + __printf(2, 3) int dev_set_name(struct device *dev, const char *name, ...); #ifdef CONFIG_NUMA -- GitLab From 2d06dfecb132a1cc2e374a44eae83b5c4356b8b4 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 20 Jan 2021 06:02:31 -0500 Subject: [PATCH 0500/1084] dm integrity: fix a crash if "recalculate" used without "internal_hash" Recalculate can only be specified with internal_hash. Cc: stable@vger.kernel.org # v4.19+ Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- drivers/md/dm-integrity.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 81df019ab284a..cce203adcf777 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -4235,6 +4235,12 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) r = -ENOMEM; goto bad; } + } else { + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) { + ti->error = "Recalculate can only be specified with internal_hash"; + r = -EINVAL; + goto bad; + } } ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev, -- GitLab From 5c02406428d5219c367c5f53457698c58bc5f917 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 20 Jan 2021 13:59:11 -0500 Subject: [PATCH 0501/1084] dm integrity: conditionally disable "recalculate" feature Otherwise a malicious user could (ab)use the "recalculate" feature that makes dm-integrity calculate the checksums in the background while the device is already usable. When the system restarts before all checksums have been calculated, the calculation continues where it was interrupted even if the recalculate feature is not requested the next time the dm device is set up. Disable recalculating if we use internal_hash or journal_hash with a key (e.g. HMAC) and we don't have the "legacy_recalculate" flag. This may break activation of a volume, created by an older kernel, that is not yet fully recalculated -- if this happens, the user should add the "legacy_recalculate" flag to constructor parameters. Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka Reported-by: Daniel Glockner Signed-off-by: Mike Snitzer --- .../device-mapper/dm-integrity.rst | 12 ++++++--- drivers/md/dm-integrity.c | 26 +++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/Documentation/admin-guide/device-mapper/dm-integrity.rst b/Documentation/admin-guide/device-mapper/dm-integrity.rst index 4e6f504474ac2..2cc5488acbd97 100644 --- a/Documentation/admin-guide/device-mapper/dm-integrity.rst +++ b/Documentation/admin-guide/device-mapper/dm-integrity.rst @@ -177,14 +177,20 @@ bitmap_flush_interval:number The bitmap flush interval in milliseconds. The metadata buffers are synchronized when this interval expires. +allow_discards + Allow block discard requests (a.k.a. TRIM) for the integrity device. + Discards are only allowed to devices using internal hash. + fix_padding Use a smaller padding of the tag area that is more space-efficient. If this option is not present, large padding is used - that is for compatibility with older kernels. -allow_discards - Allow block discard requests (a.k.a. TRIM) for the integrity device. - Discards are only allowed to devices using internal hash. +legacy_recalculate + Allow recalculating of volumes with HMAC keys. This is disabled by + default for security reasons - an attacker could modify the volume, + set recalc_sector to zero, and the kernel would not detect the + modification. The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and allow_discards can be changed when reloading the target (load an inactive diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index cce203adcf777..b64fede032dc5 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -257,8 +257,9 @@ struct dm_integrity_c { bool journal_uptodate; bool just_formatted; bool recalculate_flag; - bool fix_padding; bool discard; + bool fix_padding; + bool legacy_recalculate; struct alg_spec internal_hash_alg; struct alg_spec journal_crypt_alg; @@ -386,6 +387,14 @@ static int dm_integrity_failed(struct dm_integrity_c *ic) return READ_ONCE(ic->failed); } +static bool dm_integrity_disable_recalculate(struct dm_integrity_c *ic) +{ + if ((ic->internal_hash_alg.key || ic->journal_mac_alg.key) && + !ic->legacy_recalculate) + return true; + return false; +} + static commit_id_t dm_integrity_commit_id(struct dm_integrity_c *ic, unsigned i, unsigned j, unsigned char seq) { @@ -3140,6 +3149,7 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type, arg_count += !!ic->journal_crypt_alg.alg_string; arg_count += !!ic->journal_mac_alg.alg_string; arg_count += (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) != 0; + arg_count += ic->legacy_recalculate; DMEMIT("%s %llu %u %c %u", ic->dev->name, ic->start, ic->tag_size, ic->mode, arg_count); if (ic->meta_dev) @@ -3163,6 +3173,8 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type, } if ((ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) != 0) DMEMIT(" fix_padding"); + if (ic->legacy_recalculate) + DMEMIT(" legacy_recalculate"); #define EMIT_ALG(a, n) \ do { \ @@ -3792,7 +3804,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) unsigned extra_args; struct dm_arg_set as; static const struct dm_arg _args[] = { - {0, 15, "Invalid number of feature args"}, + {0, 16, "Invalid number of feature args"}, }; unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec; bool should_write_sb; @@ -3940,6 +3952,8 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) ic->discard = true; } else if (!strcmp(opt_string, "fix_padding")) { ic->fix_padding = true; + } else if (!strcmp(opt_string, "legacy_recalculate")) { + ic->legacy_recalculate = true; } else { r = -EINVAL; ti->error = "Invalid argument"; @@ -4243,6 +4257,14 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) } } + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) && + le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors && + dm_integrity_disable_recalculate(ic)) { + ti->error = "Recalculating with HMAC is disabled for security reasons - if you really need it, use the argument \"legacy_recalculate\""; + r = -EOPNOTSUPP; + goto bad; + } + ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev, 1U << (SECTOR_SHIFT + ic->log2_buffer_sectors), 1, 0, NULL, NULL); if (IS_ERR(ic->bufio)) { -- GitLab From 004b8ae9e2de55ca7857ba8471209dd3179e088c Mon Sep 17 00:00:00 2001 From: Ignat Korchagin Date: Tue, 19 Jan 2021 20:40:15 +0000 Subject: [PATCH 0502/1084] dm crypt: fix copy and paste bug in crypt_alloc_req_aead In commit d68b29584c25 ("dm crypt: use GFP_ATOMIC when allocating crypto requests from softirq") code was incorrectly copy and pasted from crypt_alloc_req_skcipher()'s crypto request allocation code to crypt_alloc_req_aead(). It is OK from runtime perspective as both simple encryption request pointer and AEAD request pointer are part of a union, but may confuse code reviewers. Fixes: d68b29584c25 ("dm crypt: use GFP_ATOMIC when allocating crypto requests from softirq") Cc: stable@vger.kernel.org # v5.9+ Reported-by: Pavel Machek Signed-off-by: Ignat Korchagin Signed-off-by: Mike Snitzer --- drivers/md/dm-crypt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 8c874710f0bcf..5a55617a08e68 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1481,9 +1481,9 @@ static int crypt_alloc_req_skcipher(struct crypt_config *cc, static int crypt_alloc_req_aead(struct crypt_config *cc, struct convert_context *ctx) { - if (!ctx->r.req) { - ctx->r.req = mempool_alloc(&cc->req_pool, in_interrupt() ? GFP_ATOMIC : GFP_NOIO); - if (!ctx->r.req) + if (!ctx->r.req_aead) { + ctx->r.req_aead = mempool_alloc(&cc->req_pool, in_interrupt() ? GFP_ATOMIC : GFP_NOIO); + if (!ctx->r.req_aead) return -ENOMEM; } -- GitLab From 809b1e4945774c9ec5619a8f4e2189b7b3833c0c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 21 Jan 2021 18:50:56 +0100 Subject: [PATCH 0503/1084] dm: avoid filesystem lookup in dm_get_dev_t() This reverts commit 644bda6f3460 ("dm table: fall back to getting device using name_to_dev_t()") dm_get_dev_t() is just used to convert an arbitrary 'path' string into a dev_t. It doesn't presume that the device is present; that check will be done later, as the only caller is dm_get_device(), which does a dm_get_table_device() later on, which will properly open the device. So if the path string already _is_ in major:minor representation we can convert it directly, avoiding a recursion into the filesystem to lookup the block device. This avoids a hang in multipath_message() when the filesystem is inaccessible. Fixes: 644bda6f3460 ("dm table: fall back to getting device using name_to_dev_t()") Cc: stable@vger.kernel.org Signed-off-by: Hannes Reinecke Signed-off-by: Martin Wilck Reviewed-by: Christoph Hellwig Signed-off-by: Mike Snitzer --- drivers/md/dm-table.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 188f41287f180..4acf2342f7adf 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -363,14 +363,23 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, { int r; dev_t dev; + unsigned int major, minor; + char dummy; struct dm_dev_internal *dd; struct dm_table *t = ti->table; BUG_ON(!t); - dev = dm_get_dev_t(path); - if (!dev) - return -ENODEV; + if (sscanf(path, "%u:%u%c", &major, &minor, &dummy) == 2) { + /* Extract the major/minor numbers */ + dev = MKDEV(major, minor); + if (MAJOR(dev) != major || MINOR(dev) != minor) + return -EOVERFLOW; + } else { + dev = dm_get_dev_t(path); + if (!dev) + return -ENODEV; + } dd = find_device(&t->devices, dev); if (!dd) { -- GitLab From fc705fecf3a0c9128933cc6db59159c050aaca33 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 21 Jan 2021 14:54:46 +0200 Subject: [PATCH 0504/1084] perf evlist: Fix id index for heterogeneous systems perf_evlist__set_sid_idx() updates perf_sample_id with the evlist map index, CPU number and TID. It is passed indexes to the evsel's cpu and thread maps, but references the evlist's maps instead. That results in using incorrect CPU numbers on heterogeneous systems. Fix it by using evsel maps. The id index (PERF_RECORD_ID_INDEX) is used by AUX area tracing when in sampling mode. Having an incorrect CPU number causes the trace data to be attributed to the wrong CPU, and can result in decoder errors because the trace data is then associated with the wrong process. Committer notes: Keep the class prefix convention in the function name, switching from perf_evlist__set_sid_idx() to perf_evsel__set_sid_idx(). Fixes: 3c659eedada2fbf9 ("perf tools: Add id index") Signed-off-by: Adrian Hunter Cc: Jin Yao Cc: Jiri Olsa Link: http://lore.kernel.org/lkml/20210121125446.11287-1-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/evlist.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c index cfcdbd7be066e..17465d454a0e3 100644 --- a/tools/lib/perf/evlist.c +++ b/tools/lib/perf/evlist.c @@ -367,21 +367,13 @@ static struct perf_mmap* perf_evlist__alloc_mmap(struct perf_evlist *evlist, boo return map; } -static void perf_evlist__set_sid_idx(struct perf_evlist *evlist, - struct perf_evsel *evsel, int idx, int cpu, - int thread) +static void perf_evsel__set_sid_idx(struct perf_evsel *evsel, int idx, int cpu, int thread) { struct perf_sample_id *sid = SID(evsel, cpu, thread); sid->idx = idx; - if (evlist->cpus && cpu >= 0) - sid->cpu = evlist->cpus->map[cpu]; - else - sid->cpu = -1; - if (!evsel->system_wide && evlist->threads && thread >= 0) - sid->tid = perf_thread_map__pid(evlist->threads, thread); - else - sid->tid = -1; + sid->cpu = perf_cpu_map__cpu(evsel->cpus, cpu); + sid->tid = perf_thread_map__pid(evsel->threads, thread); } static struct perf_mmap* @@ -500,8 +492,7 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) return -1; - perf_evlist__set_sid_idx(evlist, evsel, idx, cpu, - thread); + perf_evsel__set_sid_idx(evsel, idx, cpu, thread); } } -- GitLab From 9c880c24cb0db49d6e62e6d882df1470b0be8038 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 21 Jan 2021 00:18:38 +0800 Subject: [PATCH 0505/1084] perf metricgroup: Fix for metrics containing duration_time Metrics containing duration_time cause a segfault: $ perf stat -v -M L1D_Cache_Fill_BW sleep 1 Using CPUID GenuineIntel-6-3D-4 metric expr 64 * l1d.replacement / 1000000000 / duration_time for L1D_Cache_Fill_BW found event duration_time found event l1d.replacement adding {l1d.replacement}:W,duration_time l1d.replacement -> cpu/umask=0x1,(null)=0x1e8483,event=0x51/ Segmentation fault $ In commit c2337d67199a1ea1 ("perf metricgroup: Fix metrics using aliases covering multiple PMUs"), the logic in find_evsel_group() when iter'ing events was changed to not only select events in same group, but also for aliased PMUs. Checking whether events were for aliased PMUs was done by comparing the event PMU name. This was not safe for duration_time event, which has no associated PMU (and no PMU name), so fix by checking if the event PMU name is set also. Committer testing: Reproduced the bug, then, on a: $ grep -m1 ^'model name' /proc/cpuinfo model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz $ We now get: $ perf stat -M L1D_Cache_Fill_BW sleep 1 Performance counter stats for 'sleep 1': 4,141 l1d.replacement:u 1,001,285,107 ns duration_time:u 1.001285107 seconds time elapsed 0.000000000 seconds user 0.001119000 seconds sys $ Detais from -v: Using CPUID GenuineIntel-6-8E-A metric expr 64 * l1d.replacement / 1000000000 / duration_time for L1D_Cache_Fill_BW found event duration_time found event l1d.replacement adding {l1d.replacement}:W,duration_time l1d.replacement -> cpu/(null)=0x1e8483,umask=0x1,event=0x51/ Control descriptor is not initialized Warning: kernel.perf_event_paranoid=2, trying to fall back to excluding kernel and hypervisor samples Warning: kernel.perf_event_paranoid=2, trying to fall back to excluding kernel and hypervisor samples l1d.replacement:u: 4592 612201 612201 duration_time:u: 1001478621 1001478621 1001478621 Fixes: c2337d67199a1ea1 ("perf metricgroup: Fix metrics using aliases covering multiple PMUs") Reported-by: Joakim Zhang Signed-off-by: John Garry Tested-by: Arnaldo Carvalho de Melo Tested-by: Jiri Olsa Acked-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Kajol Jain Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@openeuler.org Link: https://lore.kernel.org/r/1611159518-226883-1-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/metricgroup.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index ee94d3e8dd654..8cb164ad06c1a 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -162,6 +162,14 @@ static bool contains_event(struct evsel **metric_events, int num_events, return false; } +static bool evsel_same_pmu(struct evsel *ev1, struct evsel *ev2) +{ + if (!ev1->pmu_name || !ev2->pmu_name) + return false; + + return !strcmp(ev1->pmu_name, ev2->pmu_name); +} + /** * Find a group of events in perf_evlist that correspond to those from a parsed * metric expression. Note, as find_evsel_group is called in the same order as @@ -280,8 +288,7 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, */ if (!has_constraint && ev->leader != metric_events[i]->leader && - !strcmp(ev->leader->pmu_name, - metric_events[i]->leader->pmu_name)) + evsel_same_pmu(ev->leader, metric_events[i]->leader)) break; if (!strcmp(metric_events[i]->name, ev->name)) { set_bit(ev->idx, evlist_used); -- GitLab From 3d6e79ee9e8f8c6604312382c2be1d1bd1cffc9e Mon Sep 17 00:00:00 2001 From: John Garry Date: Tue, 19 Jan 2021 18:04:15 +0800 Subject: [PATCH 0506/1084] perf metricgroup: Fix system PMU metrics Joakim reports that getting "perf stat" for multiple system PMU metrics segfaults: $ perf stat -a -I 1000 -M imx8mm_ddr_write.all,imx8mm_ddr_write.all Segmentation fault $ While the same works without issue for a single metric. The logic in metricgroup__add_metric_sys_event_iter() is broken, in that add_metric() @m argument should be NULL for each new metric. Fix by not passing a holder for that, and rather make local in metricgroup__add_metric_sys_event_iter(). Fixes: be335ec28efa ("perf metricgroup: Support adding metrics for system PMUs") Reported-by: Joakim Zhang Signed-off-by: John Garry Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Kajol Jain Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@openeuler.org Link: https://lore.kernel.org/r/1611050655-44020-1-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/metricgroup.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8cb164ad06c1a..e6d3452031e52 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -773,7 +773,6 @@ int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) struct metricgroup_add_iter_data { struct list_head *metric_list; const char *metric; - struct metric **m; struct expr_ids *ids; int *ret; bool *has_match; @@ -1065,12 +1064,13 @@ static int metricgroup__add_metric_sys_event_iter(struct pmu_event *pe, void *data) { struct metricgroup_add_iter_data *d = data; + struct metric *m = NULL; int ret; if (!match_pe_metric(pe, d->metric)) return 0; - ret = add_metric(d->metric_list, pe, d->metric_no_group, d->m, NULL, d->ids); + ret = add_metric(d->metric_list, pe, d->metric_no_group, &m, NULL, d->ids); if (ret) return ret; @@ -1121,7 +1121,6 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group, .metric_list = &list, .metric = metric, .metric_no_group = metric_no_group, - .m = &m, .ids = &ids, .has_match = &has_match, .ret = &ret, -- GitLab From 8adc0a06d68a2e433b960377e515e7a6b19b429f Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Wed, 9 Dec 2020 08:58:28 +0800 Subject: [PATCH 0507/1084] perf script: Fix overrun issue for dynamically-allocated PMU type number When unpacking the event which is from dynamic PMU, the array output[OUTPUT_TYPE_MAX] may be overrun. For example, type number of SKL uncore_imc is 10, but OUTPUT_TYPE_MAX is 7 now (OUTPUT_TYPE_MAX = PERF_TYPE_MAX + 1). /* In builtin-script.c */ process_event() { unsigned int type = output_type(attr->type); if (output[type].fields == 0) return; } output[10] is overrun. Create a type OUTPUT_TYPE_OTHER for dynamic PMU events, then output_type(attr->type) will return OUTPUT_TYPE_OTHER here. Note that if PERF_TYPE_MAX ever changed, then there would be a conflict between old perf.data files that had a dynamicaliy allocated PMU number that would then be the same as a fixed PERF_TYPE. Example: # perf record --switch-events -C 0 -e "{cpu-clock,uncore_imc/data_reads/,uncore_imc/data_writes/}:SD" -a -- sleep 1 # perf script Before: swapper 0 [000] 1479253.987551: 277766 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1479253.987797: 246709 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1479253.988127: 329883 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1479253.988273: 146393 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1479253.988523: 249977 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1479253.988877: 354090 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1479253.989023: 145940 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1479253.989383: 359856 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1479253.989523: 140082 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) After: swapper 0 [000] 1397040.402011: 272384 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1397040.402011: 5396 uncore_imc/data_reads/: swapper 0 [000] 1397040.402011: 967 uncore_imc/data_writes/: swapper 0 [000] 1397040.402259: 249153 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1397040.402259: 7231 uncore_imc/data_reads/: swapper 0 [000] 1397040.402259: 1297 uncore_imc/data_writes/: swapper 0 [000] 1397040.402508: 249108 cpu-clock: ffffffff9d4ddb6f cpuidle_enter_state+0xdf ([kernel.kallsyms]) swapper 0 [000] 1397040.402508: 5333 uncore_imc/data_reads/: swapper 0 [000] 1397040.402508: 1008 uncore_imc/data_writes/: Signed-off-by: Jin Yao Acked-by: Adrian Hunter Acked-by: Jiri Olsa Cc: Peter Zijlstra Cc: Kan Liang Cc: Andi Kleen Cc: Alexander Shishkin Cc: Ingo Molnar Link: https://lore.kernel.org/r/20201209005828.21302-1-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index edacfa98d073b..42dad4a0f8cf4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -186,6 +186,7 @@ struct output_option { enum { OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX, + OUTPUT_TYPE_OTHER, OUTPUT_TYPE_MAX }; @@ -283,6 +284,18 @@ static struct { .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, }, + + [OUTPUT_TYPE_OTHER] = { + .user_set = false, + + .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | + PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | + PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | + PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET | + PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD, + + .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, + }, }; struct evsel_script { @@ -343,8 +356,11 @@ static inline int output_type(unsigned int type) case PERF_TYPE_SYNTH: return OUTPUT_TYPE_SYNTH; default: - return type; + if (type < PERF_TYPE_MAX) + return type; } + + return OUTPUT_TYPE_OTHER; } static inline unsigned int attr_type(unsigned int type) -- GitLab From 51839e29cb5954470ea4db7236ef8c3d77a6e0bb Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Dec 2020 13:50:17 +0200 Subject: [PATCH 0508/1084] scripts: switch explicitly to Python 3 Some distributions are about to switch to Python 3 support only. This means that /usr/bin/python, which is Python 2, is not available anymore. Hence, switch scripts to use Python 3 explicitly. Signed-off-by: Andy Shevchenko Signed-off-by: Masahiro Yamada --- scripts/bloat-o-meter | 2 +- scripts/diffconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index 652e9542043f2..dcd8d8750b8bf 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # # Copyright 2004 Matt Mackall # diff --git a/scripts/diffconfig b/scripts/diffconfig index 627eba5849b5c..d5da5fa05d1d3 100755 --- a/scripts/diffconfig +++ b/scripts/diffconfig @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 # # diffconfig - a tool to compare .config files. -- GitLab From 655cf86548a3938538642a6df27dd359e13c86bd Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 14 Jan 2021 16:32:42 -0600 Subject: [PATCH 0509/1084] objtool: Don't fail the kernel build on fatal errors This is basically a revert of commit 644592d32837 ("objtool: Fail the kernel build on fatal errors"). That change turned out to be more trouble than it's worth. Failing the build is an extreme measure which sometimes gets too much attention and blocks CI build testing. These fatal-type warnings aren't yet as rare as we'd hope, due to the ever-increasing matrix of supported toolchains/plugins and their fast-changing nature as of late. Also, there are more people (and bots) looking for objtool warnings than ever before, so even non-fatal warnings aren't likely to be ignored for long. Suggested-by: Nick Desaulniers Reviewed-by: Miroslav Benes Reviewed-by: Nick Desaulniers Reviewed-by: Kamalesh Babulal Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 5f8d3eed78a18..4bd30315eb62b 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2928,14 +2928,10 @@ int check(struct objtool_file *file) warnings += ret; out: - if (ret < 0) { - /* - * Fatal error. The binary is corrupt or otherwise broken in - * some way, or objtool itself is broken. Fail the kernel - * build. - */ - return ret; - } - + /* + * For now, don't fail the kernel build on fatal warnings. These + * errors are still fairly common due to the growing matrix of + * supported toolchains and their recent pace of change. + */ return 0; } -- GitLab From 1d489151e9f9d1647110277ff77282fe4d96d09b Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 14 Jan 2021 16:14:01 -0600 Subject: [PATCH 0510/1084] objtool: Don't fail on missing symbol table Thanks to a recent binutils change which doesn't generate unused symbols, it's now possible for thunk_64.o be completely empty without CONFIG_PREEMPTION: no text, no data, no symbols. We could edit the Makefile to only build that file when CONFIG_PREEMPTION is enabled, but that will likely create confusion if/when the thunks end up getting used by some other code again. Just ignore it and move on. Reported-by: Nathan Chancellor Reviewed-by: Nathan Chancellor Reviewed-by: Miroslav Benes Tested-by: Nathan Chancellor Link: https://github.com/ClangBuiltLinux/linux/issues/1254 Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index f9682db33ccab..d8421e1d06bed 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -380,8 +380,11 @@ static int read_symbols(struct elf *elf) symtab = find_section_by_name(elf, ".symtab"); if (!symtab) { - WARN("missing symbol table"); - return -1; + /* + * A missing symbol table is actually possible if it's an empty + * .o file. This can happen for thunk_64.o. + */ + return 0; } symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); -- GitLab From 6e1239c13953f3c2a76e70031f74ddca9ae57cd3 Mon Sep 17 00:00:00 2001 From: Gayatri Kammela Date: Thu, 21 Jan 2021 13:50:04 -0800 Subject: [PATCH 0511/1084] x86/cpu: Add another Alder Lake CPU to the Intel family Add Alder Lake mobile CPU model number to Intel family. Signed-off-by: Gayatri Kammela Signed-off-by: Tony Luck Signed-off-by: Borislav Petkov Link: https://lkml.kernel.org/r/20210121215004.11618-1-tony.luck@intel.com --- arch/x86/include/asm/intel-family.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 5e658ba2654a7..9abe842dbd843 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -97,6 +97,7 @@ #define INTEL_FAM6_LAKEFIELD 0x8A #define INTEL_FAM6_ALDERLAKE 0x97 +#define INTEL_FAM6_ALDERLAKE_L 0x9A /* "Small Core" Processors (Atom) */ -- GitLab From 4f6543f28bb05433d87b6de6c21e9c14c35ecf33 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 20 Jan 2021 16:40:45 +1100 Subject: [PATCH 0512/1084] crypto: marvel/cesa - Fix tdma descriptor on 64-bit The patch that added src_dma/dst_dma to struct mv_cesa_tdma_desc is broken on 64-bit systems as the size of the descriptor has been changed. This patch fixes it by using u32 instead of dma_addr_t. Fixes: e62291c1d9f4 ("crypto: marvell/cesa - Fix sparse warnings") Cc: Reported-by: Sven Auhagen Signed-off-by: Herbert Xu --- drivers/crypto/marvell/cesa/cesa.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/marvell/cesa/cesa.h b/drivers/crypto/marvell/cesa/cesa.h index fabfaaccca872..fa56b45620c79 100644 --- a/drivers/crypto/marvell/cesa/cesa.h +++ b/drivers/crypto/marvell/cesa/cesa.h @@ -300,11 +300,11 @@ struct mv_cesa_tdma_desc { __le32 byte_cnt; union { __le32 src; - dma_addr_t src_dma; + u32 src_dma; }; union { __le32 dst; - dma_addr_t dst_dma; + u32 dst_dma; }; __le32 next_dma; -- GitLab From a4166340a6e4d501c9e3aee81c20a269726ecde0 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 19 Jan 2021 23:41:23 -0300 Subject: [PATCH 0513/1084] Revert "i2c: imx: Remove unused .id_table support" Coldfire platforms are non-DT users of this driver, so keep the .id_table support. This reverts commit c610199cd392e6e2d41811ef83d85355c1b862b3. Fixes: c610199cd392 (i2c: imx: Remove unused .id_table support") Reported-by: Sascha Hauer Signed-off-by: Fabio Estevam Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index b444fbf1a2625..a8e8af57e33f4 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -241,6 +241,19 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = { }; +static const struct platform_device_id imx_i2c_devtype[] = { + { + .name = "imx1-i2c", + .driver_data = (kernel_ulong_t)&imx1_i2c_hwdata, + }, { + .name = "imx21-i2c", + .driver_data = (kernel_ulong_t)&imx21_i2c_hwdata, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(platform, imx_i2c_devtype); + static const struct of_device_id i2c_imx_dt_ids[] = { { .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, }, { .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, }, @@ -1330,7 +1343,11 @@ static int i2c_imx_probe(struct platform_device *pdev) return -ENOMEM; match = device_get_match_data(&pdev->dev); - i2c_imx->hwdata = match; + if (match) + i2c_imx->hwdata = match; + else + i2c_imx->hwdata = (struct imx_i2c_hwdata *) + platform_get_device_id(pdev)->driver_data; /* Setup i2c_imx driver structure */ strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name)); @@ -1498,6 +1515,7 @@ static struct platform_driver i2c_imx_driver = { .of_match_table = i2c_imx_dt_ids, .acpi_match_table = i2c_imx_acpi_ids, }, + .id_table = imx_i2c_devtype, }; static int __init i2c_adap_imx_init(void) -- GitLab From 9ecd1d2b302b600351fac50779f43fcb680c1a16 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 17 Jan 2021 12:43:13 +0100 Subject: [PATCH 0514/1084] i2c: sprd: depend on COMMON_CLK to fix compile tests The I2C_SPRD uses Common Clock Framework thus it cannot be built on platforms without it (e.g. compile test on MIPS with LANTIQ): /usr/bin/mips-linux-gnu-ld: drivers/i2c/busses/i2c-sprd.o: in function `sprd_i2c_probe': i2c-sprd.c:(.text.sprd_i2c_probe+0x254): undefined reference to `clk_set_parent' Fixes: 4a2d5f663dab ("i2c: Enable compile testing for more drivers") Reported-by: kernel test robot Signed-off-by: Krzysztof Kozlowski Reviewed-by: Baolin Wang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index d4d60ad0eda0b..ab1f39ac39f4f 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -1013,6 +1013,7 @@ config I2C_SIRF config I2C_SPRD tristate "Spreadtrum I2C interface" depends on I2C=y && (ARCH_SPRD || COMPILE_TEST) + depends on COMMON_CLK help If you say yes to this option, support will be included for the Spreadtrum I2C interface. -- GitLab From 17749851eb9ca2298e7c3b81aae4228961b36f28 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 21 Jan 2021 10:04:27 -0800 Subject: [PATCH 0515/1084] tty: fix up hung_up_tty_write() conversion In commit "tty: implement write_iter", I left the write_iter conversion of the hung up tty case alone, because I incorrectly thought it didn't matter. Jiri showed me the errors of my ways, and pointed out the problems with that incomplete conversion. Fix it all up. Reported-by: Jiri Slaby Signed-off-by: Linus Torvalds Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/CAHk-=wh+-rGsa=xruEWdg_fJViFG8rN9bpLrfLz=_yBYh2tBhA@mail.gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 502862626b2bc..4a208a95e9219 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -437,8 +437,7 @@ static ssize_t hung_up_tty_read(struct file *file, char __user *buf, return 0; } -static ssize_t hung_up_tty_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) +static ssize_t hung_up_tty_write(struct kiocb *iocb, struct iov_iter *from) { return -EIO; } @@ -504,7 +503,7 @@ static const struct file_operations console_fops = { static const struct file_operations hung_up_tty_fops = { .llseek = no_llseek, .read = hung_up_tty_read, - .write = hung_up_tty_write, + .write_iter = hung_up_tty_write, .poll = hung_up_tty_poll, .unlocked_ioctl = hung_up_tty_ioctl, .compat_ioctl = hung_up_tty_compat_ioctl, @@ -1044,7 +1043,9 @@ static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from) if (tty->ops->write_room == NULL) tty_err(tty, "missing write_room method\n"); ld = tty_ldisc_ref_wait(tty); - if (!ld || !ld->ops->write) + if (!ld) + return hung_up_tty_write(iocb, from); + if (!ld->ops->write) ret = -EIO; else ret = do_tty_write(ld->ops->write, tty, file, from); -- GitLab From 31b081066e9c8f4a931a3d20dc0c6ca63c595c44 Mon Sep 17 00:00:00 2001 From: Ricky Wu Date: Fri, 22 Jan 2021 16:19:06 +0800 Subject: [PATCH 0516/1084] misc: rtsx: init value of aspm_enabled make sure ASPM state sync with pcr->aspm_enabled init value pcr->aspm_enabled Cc: stable@vger.kernel.org Signed-off-by: Ricky Wu Link: https://lore.kernel.org/r/20210122081906.19100-1-ricky_wu@realtek.com Fixes: d928061c3143 ("misc: rtsx: modify en/disable aspm function") Signed-off-by: Greg Kroah-Hartman --- drivers/misc/cardreader/rtsx_pcr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c index 2aa6648fa41f9..5a491d2cd1ae6 100644 --- a/drivers/misc/cardreader/rtsx_pcr.c +++ b/drivers/misc/cardreader/rtsx_pcr.c @@ -1512,6 +1512,7 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, struct pcr_handle *handle; u32 base, len; int ret, i, bar = 0; + u8 val; dev_dbg(&(pcidev->dev), ": Realtek PCI-E Card Reader found at %s [%04x:%04x] (rev %x)\n", @@ -1577,7 +1578,11 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, pcr->host_cmds_addr = pcr->rtsx_resv_buf_addr; pcr->host_sg_tbl_ptr = pcr->rtsx_resv_buf + HOST_CMDS_BUF_LEN; pcr->host_sg_tbl_addr = pcr->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN; - + rtsx_pci_read_register(pcr, ASPM_FORCE_CTL, &val); + if (val & FORCE_ASPM_CTL0 && val & FORCE_ASPM_CTL1) + pcr->aspm_enabled = false; + else + pcr->aspm_enabled = true; pcr->card_inserted = 0; pcr->card_removed = 0; INIT_DELAYED_WORK(&pcr->carddet_work, rtsx_pci_card_detect); -- GitLab From 14a71d509ac809dcf56d7e3ca376b15d17bd0ddd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 22 Jan 2021 13:20:42 +0000 Subject: [PATCH 0517/1084] regulator: Fix lockdep warning resolving supplies With commit eaa7995c529b54 (regulator: core: avoid regulator_resolve_supply() race condition) we started holding the rdev lock while resolving supplies, an operation that requires holding the regulator_list_mutex. This results in lockdep warnings since in other places we take the list mutex then the mutex on an individual rdev. Since the goal is to make sure that we don't call set_supply() twice rather than a concern about the cost of resolution pull the rdev lock and check for duplicate resolution down to immediately before we do the set_supply() and drop it again once the allocation is done. Fixes: eaa7995c529b54 (regulator: core: avoid regulator_resolve_supply() race condition) Reported-by: Marek Szyprowski Tested-by: Marek Szyprowski Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20210122132042.10306-1-broonie@kernel.org Signed-off-by: Mark Brown --- drivers/regulator/core.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index cfc3bc9df93a0..67a768fe5b2a3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1823,17 +1823,6 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) if (rdev->supply) return 0; - /* - * Recheck rdev->supply with rdev->mutex lock held to avoid a race - * between rdev->supply null check and setting rdev->supply in - * set_supply() from concurrent tasks. - */ - regulator_lock(rdev); - - /* Supply just resolved by a concurrent task? */ - if (rdev->supply) - goto out; - r = regulator_dev_lookup(dev, rdev->supply_name); if (IS_ERR(r)) { ret = PTR_ERR(r); @@ -1885,12 +1874,29 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) goto out; } + /* + * Recheck rdev->supply with rdev->mutex lock held to avoid a race + * between rdev->supply null check and setting rdev->supply in + * set_supply() from concurrent tasks. + */ + regulator_lock(rdev); + + /* Supply just resolved by a concurrent task? */ + if (rdev->supply) { + regulator_unlock(rdev); + put_device(&r->dev); + goto out; + } + ret = set_supply(rdev, r); if (ret < 0) { + regulator_unlock(rdev); put_device(&r->dev); goto out; } + regulator_unlock(rdev); + /* * In set_machine_constraints() we may have turned this regulator on * but we couldn't propagate to the supply if it hadn't been resolved @@ -1906,7 +1912,6 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) } out: - regulator_unlock(rdev); return ret; } -- GitLab From 36c6e17bf16922935a5a0dd073d5b032d34aa73d Mon Sep 17 00:00:00 2001 From: Valentin Schneider Date: Wed, 13 Jan 2021 18:31:41 +0000 Subject: [PATCH 0518/1084] sched/core: Print out straggler tasks in sched_cpu_dying() Since commit 1cf12e08bc4d ("sched/hotplug: Consolidate task migration on CPU unplug") tasks are expected to move themselves out of a out-going CPU. For most tasks this will be done automagically via BALANCE_PUSH, but percpu kthreads will have to cooperate and move themselves away one way or another. Currently, some percpu kthreads (workqueues being a notable exemple) do not cooperate nicely and can end up on an out-going CPU at the time sched_cpu_dying() is invoked. Print the dying rq's tasks to shed some light on the stragglers. Signed-off-by: Valentin Schneider Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Valentin Schneider Tested-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210113183141.11974-1-valentin.schneider@arm.com --- kernel/sched/core.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 15d2562118d17..627534fa91961 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7574,6 +7574,25 @@ static void calc_load_migrate(struct rq *rq) atomic_long_add(delta, &calc_load_tasks); } +static void dump_rq_tasks(struct rq *rq, const char *loglvl) +{ + struct task_struct *g, *p; + int cpu = cpu_of(rq); + + lockdep_assert_held(&rq->lock); + + printk("%sCPU%d enqueued tasks (%u total):\n", loglvl, cpu, rq->nr_running); + for_each_process_thread(g, p) { + if (task_cpu(p) != cpu) + continue; + + if (!task_on_rq_queued(p)) + continue; + + printk("%s\tpid: %d, name: %s\n", loglvl, p->pid, p->comm); + } +} + int sched_cpu_dying(unsigned int cpu) { struct rq *rq = cpu_rq(cpu); @@ -7583,7 +7602,10 @@ int sched_cpu_dying(unsigned int cpu) sched_tick_stop(cpu); rq_lock_irqsave(rq, &rf); - BUG_ON(rq->nr_running != 1 || rq_has_pinned_tasks(rq)); + if (rq->nr_running != 1 || rq_has_pinned_tasks(rq)) { + WARN(true, "Dying CPU not properly vacated!"); + dump_rq_tasks(rq, KERN_WARNING); + } rq_unlock_irqrestore(rq, &rf); calc_load_migrate(rq); -- GitLab From 547a77d02f8cfb345631ce23b5b548d27afa0fc4 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Mon, 11 Jan 2021 23:26:33 +0800 Subject: [PATCH 0519/1084] workqueue: Use cpu_possible_mask instead of cpu_active_mask to break affinity The scheduler won't break affinity for us any more, and we should "emulate" the same behavior when the scheduler breaks affinity for us. The behavior is "changing the cpumask to cpu_possible_mask". And there might be some other CPUs online later while the worker is still running with the pending work items. The worker should be allowed to use the later online CPUs as before and process the work items ASAP. If we use cpu_active_mask here, we can't achieve this goal but using cpu_possible_mask can. Fixes: 06249738a41a ("workqueue: Manually break affinity on hotplug") Signed-off-by: Lai Jiangshan Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Valentin Schneider Acked-by: Tejun Heo Tested-by: Paul E. McKenney Tested-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210111152638.2417-4-jiangshanlai@gmail.com --- kernel/workqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 9880b6c0e2721..1646331546eb6 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -4920,7 +4920,7 @@ static void unbind_workers(int cpu) raw_spin_unlock_irq(&pool->lock); for_each_pool_worker(worker, pool) - WARN_ON_ONCE(set_cpus_allowed_ptr(worker->task, cpu_active_mask) < 0); + WARN_ON_ONCE(set_cpus_allowed_ptr(worker->task, cpu_possible_mask) < 0); mutex_unlock(&wq_pool_attach_mutex); -- GitLab From 22f667c97aadbf481e2cae2d6feabdf431e27b31 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 15 Jan 2021 18:17:45 +0100 Subject: [PATCH 0520/1084] sched: Don't run cpu-online with balance_push() enabled We don't need to push away tasks when we come online, mark the push complete right before the CPU dies. XXX hotplug state machine has trouble with rollback here. Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Valentin Schneider Tested-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210121103506.415606087@infradead.org --- kernel/sched/core.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 627534fa91961..8da0fd7f3cca1 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7320,10 +7320,12 @@ static void balance_push_set(int cpu, bool on) struct rq_flags rf; rq_lock_irqsave(rq, &rf); - if (on) + if (on) { + WARN_ON_ONCE(rq->balance_callback); rq->balance_callback = &balance_push_callback; - else + } else if (rq->balance_callback == &balance_push_callback) { rq->balance_callback = NULL; + } rq_unlock_irqrestore(rq, &rf); } @@ -7441,6 +7443,10 @@ int sched_cpu_activate(unsigned int cpu) struct rq *rq = cpu_rq(cpu); struct rq_flags rf; + /* + * Make sure that when the hotplug state machine does a roll-back + * we clear balance_push. Ideally that would happen earlier... + */ balance_push_set(cpu, false); #ifdef CONFIG_SCHED_SMT @@ -7608,6 +7614,12 @@ int sched_cpu_dying(unsigned int cpu) } rq_unlock_irqrestore(rq, &rf); + /* + * Now that the CPU is offline, make sure we're welcome + * to new tasks once we come back up. + */ + balance_push_set(cpu, false); + calc_load_migrate(rq); update_max_interval(); nohz_balance_exit_idle(rq); -- GitLab From ac687e6e8c26181a33270efd1a2e2241377924b0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 12 Jan 2021 11:24:04 +0100 Subject: [PATCH 0521/1084] kthread: Extract KTHREAD_IS_PER_CPU There is a need to distinguish geniune per-cpu kthreads from kthreads that happen to have a single CPU affinity. Geniune per-cpu kthreads are kthreads that are CPU affine for correctness, these will obviously have PF_KTHREAD set, but must also have PF_NO_SETAFFINITY set, lest userspace modify their affinity and ruins things. However, these two things are not sufficient, PF_NO_SETAFFINITY is also set on other tasks that have their affinities controlled through other means, like for instance workqueues. Therefore another bit is needed; it turns out kthread_create_per_cpu() already has such a bit: KTHREAD_IS_PER_CPU, which is used to make kthread_park()/kthread_unpark() work correctly. Expose this flag and remove the implicit setting of it from kthread_create_on_cpu(); the io_uring usage of it seems dubious at best. Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Valentin Schneider Tested-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210121103506.557620262@infradead.org --- include/linux/kthread.h | 3 +++ kernel/kthread.c | 27 ++++++++++++++++++++++++++- kernel/smpboot.c | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 65b81e0c494d2..2484ed97e72f5 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -33,6 +33,9 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), unsigned int cpu, const char *namefmt); +void kthread_set_per_cpu(struct task_struct *k, int cpu); +bool kthread_is_per_cpu(struct task_struct *k); + /** * kthread_run - create and wake a thread. * @threadfn: the function to run until signal_pending(current). diff --git a/kernel/kthread.c b/kernel/kthread.c index a5eceecd4513c..e0e4a423f184c 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -493,11 +493,36 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), return p; kthread_bind(p, cpu); /* CPU hotplug need to bind once again when unparking the thread. */ - set_bit(KTHREAD_IS_PER_CPU, &to_kthread(p)->flags); to_kthread(p)->cpu = cpu; return p; } +void kthread_set_per_cpu(struct task_struct *k, int cpu) +{ + struct kthread *kthread = to_kthread(k); + if (!kthread) + return; + + WARN_ON_ONCE(!(k->flags & PF_NO_SETAFFINITY)); + + if (cpu < 0) { + clear_bit(KTHREAD_IS_PER_CPU, &kthread->flags); + return; + } + + kthread->cpu = cpu; + set_bit(KTHREAD_IS_PER_CPU, &kthread->flags); +} + +bool kthread_is_per_cpu(struct task_struct *k) +{ + struct kthread *kthread = to_kthread(k); + if (!kthread) + return false; + + return test_bit(KTHREAD_IS_PER_CPU, &kthread->flags); +} + /** * kthread_unpark - unpark a thread created by kthread_create(). * @k: thread created by kthread_create(). diff --git a/kernel/smpboot.c b/kernel/smpboot.c index 2efe1e206167c..f25208e8df836 100644 --- a/kernel/smpboot.c +++ b/kernel/smpboot.c @@ -188,6 +188,7 @@ __smpboot_create_thread(struct smp_hotplug_thread *ht, unsigned int cpu) kfree(td); return PTR_ERR(tsk); } + kthread_set_per_cpu(tsk, cpu); /* * Park the thread so that it could start right on the CPU * when it is available. -- GitLab From 5c25b5ff89f004c30b04759dc34ace8585a4085f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 12 Jan 2021 11:26:49 +0100 Subject: [PATCH 0522/1084] workqueue: Tag bound workers with KTHREAD_IS_PER_CPU Mark the per-cpu workqueue workers as KTHREAD_IS_PER_CPU. Workqueues have unfortunate semantics in that per-cpu workers are not default flushed and parked during hotplug, however a subset does manual flush on hotplug and hard relies on them for correctness. Therefore play silly games.. Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Valentin Schneider Tested-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210121103506.693465814@infradead.org --- kernel/workqueue.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 1646331546eb6..cce34336fbd7a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1861,6 +1861,8 @@ static void worker_attach_to_pool(struct worker *worker, */ if (pool->flags & POOL_DISASSOCIATED) worker->flags |= WORKER_UNBOUND; + else + kthread_set_per_cpu(worker->task, pool->cpu); list_add_tail(&worker->node, &pool->workers); worker->pool = pool; @@ -1883,6 +1885,7 @@ static void worker_detach_from_pool(struct worker *worker) mutex_lock(&wq_pool_attach_mutex); + kthread_set_per_cpu(worker->task, -1); list_del(&worker->node); worker->pool = NULL; @@ -4919,8 +4922,10 @@ static void unbind_workers(int cpu) raw_spin_unlock_irq(&pool->lock); - for_each_pool_worker(worker, pool) + for_each_pool_worker(worker, pool) { + kthread_set_per_cpu(worker->task, -1); WARN_ON_ONCE(set_cpus_allowed_ptr(worker->task, cpu_possible_mask) < 0); + } mutex_unlock(&wq_pool_attach_mutex); @@ -4972,9 +4977,11 @@ static void rebind_workers(struct worker_pool *pool) * of all workers first and then clear UNBOUND. As we're called * from CPU_ONLINE, the following shouldn't fail. */ - for_each_pool_worker(worker, pool) + for_each_pool_worker(worker, pool) { + kthread_set_per_cpu(worker->task, pool->cpu); WARN_ON_ONCE(set_cpus_allowed_ptr(worker->task, pool->attrs->cpumask) < 0); + } raw_spin_lock_irq(&pool->lock); -- GitLab From 640f17c82460e9724fd256f0a1f5d99e7ff0bda4 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 15 Jan 2021 19:08:36 +0100 Subject: [PATCH 0523/1084] workqueue: Restrict affinity change to rescuer create_worker() will already set the right affinity using kthread_bind_mask(), this means only the rescuer will need to change it's affinity. Howveer, while in cpu-hot-unplug a regular task is not allowed to run on online&&!active as it would be pushed away quite agressively. We need KTHREAD_IS_PER_CPU to survive in that environment. Therefore set the affinity after getting that magic flag. Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Valentin Schneider Tested-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210121103506.826629830@infradead.org --- kernel/workqueue.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index cce34336fbd7a..894bb885b40b1 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1848,12 +1848,6 @@ static void worker_attach_to_pool(struct worker *worker, { mutex_lock(&wq_pool_attach_mutex); - /* - * set_cpus_allowed_ptr() will fail if the cpumask doesn't have any - * online CPUs. It'll be re-applied when any of the CPUs come up. - */ - set_cpus_allowed_ptr(worker->task, pool->attrs->cpumask); - /* * The wq_pool_attach_mutex ensures %POOL_DISASSOCIATED remains * stable across this function. See the comments above the flag @@ -1864,6 +1858,9 @@ static void worker_attach_to_pool(struct worker *worker, else kthread_set_per_cpu(worker->task, pool->cpu); + if (worker->rescue_wq) + set_cpus_allowed_ptr(worker->task, pool->attrs->cpumask); + list_add_tail(&worker->node, &pool->workers); worker->pool = pool; -- GitLab From 975707f227b07a8212060f94447171d15d7a681b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 20 Jan 2021 15:05:41 +0100 Subject: [PATCH 0524/1084] sched: Prepare to use balance_push in ttwu() In preparation of using the balance_push state in ttwu() we need it to provide a reliable and consistent state. The immediate problem is that rq->balance_callback gets cleared every schedule() and then re-set in the balance_push_callback() itself. This is not a reliable signal, so add a variable that stays set during the entire time. Also move setting it before the synchronize_rcu() in sched_cpu_deactivate(), such that we get guaranteed visibility to ttwu(), which is a preempt-disable region. Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Valentin Schneider Tested-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210121103506.966069627@infradead.org --- kernel/sched/core.c | 11 ++++++----- kernel/sched/sched.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 8da0fd7f3cca1..16946b55e8e78 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7320,6 +7320,7 @@ static void balance_push_set(int cpu, bool on) struct rq_flags rf; rq_lock_irqsave(rq, &rf); + rq->balance_push = on; if (on) { WARN_ON_ONCE(rq->balance_callback); rq->balance_callback = &balance_push_callback; @@ -7489,17 +7490,17 @@ int sched_cpu_deactivate(unsigned int cpu) int ret; set_cpu_active(cpu, false); + balance_push_set(cpu, true); + /* - * We've cleared cpu_active_mask, wait for all preempt-disabled and RCU - * users of this state to go away such that all new such users will - * observe it. + * We've cleared cpu_active_mask / set balance_push, wait for all + * preempt-disabled and RCU users of this state to go away such that + * all new such users will observe it. * * Do sync before park smpboot threads to take care the rcu boost case. */ synchronize_rcu(); - balance_push_set(cpu, true); - rq_lock_irqsave(rq, &rf); if (rq->rd) { update_rq_clock(rq); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 12ada79d40f33..bb09988451a04 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -975,6 +975,7 @@ struct rq { unsigned long cpu_capacity_orig; struct callback_head *balance_callback; + unsigned char balance_push; unsigned char nohz_idle_balance; unsigned char idle_balance; -- GitLab From 5ba2ffba13a1e24e7b153683e97300f9cc6f605a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 12 Jan 2021 11:28:16 +0100 Subject: [PATCH 0525/1084] sched: Fix CPU hotplug / tighten is_per_cpu_kthread() Prior to commit 1cf12e08bc4d ("sched/hotplug: Consolidate task migration on CPU unplug") we'd leave any task on the dying CPU and break affinity and force them off at the very end. This scheme had to change in order to enable migrate_disable(). One cannot wait for migrate_disable() to complete while stuck in stop_machine(). Furthermore, since we need at the very least: idle, hotplug and stop threads at any point before stop_machine, we can't break affinity and/or push those away. Under the assumption that all per-cpu kthreads are sanely handled by CPU hotplug, the new code no long breaks affinity or migrates any of them (which then includes the critical ones above). However, there's an important difference between per-cpu kthreads and kthreads that happen to have a single CPU affinity which is lost. The latter class very much relies on the forced affinity breaking and migration semantics previously provided. Use the new kthread_is_per_cpu() infrastructure to tighten is_per_cpu_kthread() and fix the hot-unplug problems stemming from the change. Fixes: 1cf12e08bc4d ("sched/hotplug: Consolidate task migration on CPU unplug") Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Valentin Schneider Tested-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210121103507.102416009@infradead.org --- kernel/sched/core.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 16946b55e8e78..56b09628692aa 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1796,13 +1796,28 @@ static inline bool rq_has_pinned_tasks(struct rq *rq) */ static inline bool is_cpu_allowed(struct task_struct *p, int cpu) { + /* When not in the task's cpumask, no point in looking further. */ if (!cpumask_test_cpu(cpu, p->cpus_ptr)) return false; - if (is_per_cpu_kthread(p) || is_migration_disabled(p)) + /* migrate_disabled() must be allowed to finish. */ + if (is_migration_disabled(p)) return cpu_online(cpu); - return cpu_active(cpu); + /* Non kernel threads are not allowed during either online or offline. */ + if (!(p->flags & PF_KTHREAD)) + return cpu_active(cpu); + + /* KTHREAD_IS_PER_CPU is always allowed. */ + if (kthread_is_per_cpu(p)) + return cpu_online(cpu); + + /* Regular kernel threads don't get to stay during offline. */ + if (cpu_rq(cpu)->balance_push) + return false; + + /* But are allowed during online. */ + return cpu_online(cpu); } /* @@ -3121,6 +3136,13 @@ bool cpus_share_cache(int this_cpu, int that_cpu) static inline bool ttwu_queue_cond(int cpu, int wake_flags) { + /* + * Do not complicate things with the async wake_list while the CPU is + * in hotplug state. + */ + if (!cpu_active(cpu)) + return false; + /* * If the CPU does not share cache, then queue the task on the * remote rqs wakelist to avoid accessing remote data. @@ -7276,8 +7298,14 @@ static void balance_push(struct rq *rq) /* * Both the cpu-hotplug and stop task are in this case and are * required to complete the hotplug process. + * + * XXX: the idle task does not match kthread_is_per_cpu() due to + * histerical raisins. */ - if (is_per_cpu_kthread(push_task) || is_migration_disabled(push_task)) { + if (rq->idle == push_task || + ((push_task->flags & PF_KTHREAD) && kthread_is_per_cpu(push_task)) || + is_migration_disabled(push_task)) { + /* * If this is the idle task on the outgoing CPU try to wake * up the hotplug control thread which might wait for the @@ -7309,7 +7337,7 @@ static void balance_push(struct rq *rq) /* * At this point need_resched() is true and we'll take the loop in * schedule(). The next pick is obviously going to be the stop task - * which is_per_cpu_kthread() and will push this task away. + * which kthread_is_per_cpu() and will push this task away. */ raw_spin_lock(&rq->lock); } @@ -7497,6 +7525,9 @@ int sched_cpu_deactivate(unsigned int cpu) * preempt-disabled and RCU users of this state to go away such that * all new such users will observe it. * + * Specifically, we rely on ttwu to no longer target this CPU, see + * ttwu_queue_cond() and is_cpu_allowed(). + * * Do sync before park smpboot threads to take care the rcu boost case. */ synchronize_rcu(); -- GitLab From 741ba80f6f9a4702089c122129f22df9774b3e64 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 16 Jan 2021 11:56:37 +0100 Subject: [PATCH 0526/1084] sched: Relax the set_cpus_allowed_ptr() semantics Now that we have KTHREAD_IS_PER_CPU to denote the critical per-cpu tasks to retain during CPU offline, we can relax the warning in set_cpus_allowed_ptr(). Any spurious kthread that wants to get on at the last minute will get pushed off before it can run. While during CPU online there is no harm, and actual benefit, to allowing kthreads back on early, it simplifies hotplug code and fixes a number of outstanding races. Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Lai jiangshan Reviewed-by: Valentin Schneider Tested-by: Valentin Schneider Link: https://lkml.kernel.org/r/20210121103507.240724591@infradead.org --- kernel/sched/core.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 56b09628692aa..ff74fca39ed21 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2342,7 +2342,9 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, if (p->flags & PF_KTHREAD || is_migration_disabled(p)) { /* - * Kernel threads are allowed on online && !active CPUs. + * Kernel threads are allowed on online && !active CPUs, + * however, during cpu-hot-unplug, even these might get pushed + * away if not KTHREAD_IS_PER_CPU. * * Specifically, migration_disabled() tasks must not fail the * cpumask_any_and_distribute() pick below, esp. so on @@ -2386,16 +2388,6 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, __do_set_cpus_allowed(p, new_mask, flags); - if (p->flags & PF_KTHREAD) { - /* - * For kernel threads that do indeed end up on online && - * !active we want to ensure they are strict per-CPU threads. - */ - WARN_ON(cpumask_intersects(new_mask, cpu_online_mask) && - !cpumask_intersects(new_mask, cpu_active_mask) && - p->nr_cpus_allowed != 1); - } - return affine_move_task(rq, p, &rf, dest_cpu, flags); out: @@ -7518,6 +7510,13 @@ int sched_cpu_deactivate(unsigned int cpu) int ret; set_cpu_active(cpu, false); + + /* + * From this point forward, this CPU will refuse to run any task that + * is not: migrate_disable() or KTHREAD_IS_PER_CPU, and will actively + * push those tasks away until this gets cleared, see + * sched_cpu_dying(). + */ balance_push_set(cpu, true); /* -- GitLab From 75bd4bff300b3c5252d4a0e7a959569c62d1dbae Mon Sep 17 00:00:00 2001 From: Qais Yousef Date: Fri, 22 Jan 2021 11:09:09 +0000 Subject: [PATCH 0527/1084] arm64: kprobes: Fix Uexpected kernel BRK exception at EL1 I was hitting the below panic continuously when attaching kprobes to scheduler functions [ 159.045212] Unexpected kernel BRK exception at EL1 [ 159.053753] Internal error: BRK handler: f2000006 [#1] PREEMPT SMP [ 159.059954] Modules linked in: [ 159.063025] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 5.11.0-rc4-00008-g1e2a199f6ccd #56 [rt-app] [1] Exiting.[ 159.071166] Hardware name: ARM Juno development board (r2) (DT) [ 159.079689] pstate: 600003c5 (nZCv DAIF -PAN -UAO -TCO BTYPE=--) [ 159.085723] pc : 0xffff80001624501c [ 159.089377] lr : attach_entity_load_avg+0x2ac/0x350 [ 159.094271] sp : ffff80001622b640 [rt-app] [0] Exiting.[ 159.097591] x29: ffff80001622b640 x28: 0000000000000001 [ 159.105515] x27: 0000000000000049 x26: ffff000800b79980 [ 159.110847] x25: ffff00097ef37840 x24: 0000000000000000 [ 159.116331] x23: 00000024eacec1ec x22: ffff00097ef12b90 [ 159.121663] x21: ffff00097ef37700 x20: ffff800010119170 [rt-app] [11] Exiting.[ 159.126995] x19: ffff00097ef37840 x18: 000000000000000e [ 159.135003] x17: 0000000000000001 x16: 0000000000000019 [ 159.140335] x15: 0000000000000000 x14: 0000000000000000 [ 159.145666] x13: 0000000000000002 x12: 0000000000000002 [ 159.150996] x11: ffff80001592f9f0 x10: 0000000000000060 [ 159.156327] x9 : ffff8000100f6f9c x8 : be618290de0999a1 [ 159.161659] x7 : ffff80096a4b1000 x6 : 0000000000000000 [ 159.166990] x5 : ffff00097ef37840 x4 : 0000000000000000 [ 159.172321] x3 : ffff000800328948 x2 : 0000000000000000 [ 159.177652] x1 : 0000002507d52fec x0 : ffff00097ef12b90 [ 159.182983] Call trace: [ 159.185433] 0xffff80001624501c [ 159.188581] update_load_avg+0x2d0/0x778 [ 159.192516] enqueue_task_fair+0x134/0xe20 [ 159.196625] enqueue_task+0x4c/0x2c8 [ 159.200211] ttwu_do_activate+0x70/0x138 [ 159.204147] sched_ttwu_pending+0xbc/0x160 [ 159.208253] flush_smp_call_function_queue+0x16c/0x320 [ 159.213408] generic_smp_call_function_single_interrupt+0x1c/0x28 [ 159.219521] ipi_handler+0x1e8/0x3c8 [ 159.223106] handle_percpu_devid_irq+0xd8/0x460 [ 159.227650] generic_handle_irq+0x38/0x50 [ 159.231672] __handle_domain_irq+0x6c/0xc8 [ 159.235781] gic_handle_irq+0xcc/0xf0 [ 159.239452] el1_irq+0xb4/0x180 [ 159.242600] rcu_is_watching+0x28/0x70 [ 159.246359] rcu_read_lock_held_common+0x44/0x88 [ 159.250991] rcu_read_lock_any_held+0x30/0xc0 [ 159.255360] kretprobe_dispatcher+0xc4/0xf0 [ 159.259555] __kretprobe_trampoline_handler+0xc0/0x150 [ 159.264710] trampoline_probe_handler+0x38/0x58 [ 159.269255] kretprobe_trampoline+0x70/0xc4 [ 159.273450] run_rebalance_domains+0x54/0x80 [ 159.277734] __do_softirq+0x164/0x684 [ 159.281406] irq_exit+0x198/0x1b8 [ 159.284731] __handle_domain_irq+0x70/0xc8 [ 159.288840] gic_handle_irq+0xb0/0xf0 [ 159.292510] el1_irq+0xb4/0x180 [ 159.295658] arch_cpu_idle+0x18/0x28 [ 159.299245] default_idle_call+0x9c/0x3e8 [ 159.303265] do_idle+0x25c/0x2a8 [ 159.306502] cpu_startup_entry+0x2c/0x78 [ 159.310436] secondary_start_kernel+0x160/0x198 [ 159.314984] Code: d42000c0 aa1e03e9 d42000c0 aa1e03e9 (d42000c0) After a bit of head scratching and debugging it turned out that it is due to kprobe handler being interrupted by a tick that causes us to go into (I think another) kprobe handler. The culprit was kprobe_breakpoint_ss_handler() returning DBG_HOOK_ERROR which leads to the Unexpected kernel BRK exception. Reverting commit ba090f9cafd5 ("arm64: kprobes: Remove redundant kprobe_step_ctx") seemed to fix the problem for me. Further analysis showed that kcb->kprobe_status is set to KPROBE_REENTER when the error occurs. By teaching kprobe_breakpoint_ss_handler() to handle this status I can no longer reproduce the problem. Fixes: ba090f9cafd5 ("arm64: kprobes: Remove redundant kprobe_step_ctx") Signed-off-by: Qais Yousef Acked-by: Will Deacon Acked-by: Masami Hiramatsu Link: https://lore.kernel.org/r/20210122110909.3324607-1-qais.yousef@arm.com Signed-off-by: Catalin Marinas --- arch/arm64/kernel/probes/kprobes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index 89c64ada87324..66aac2881ba84 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -352,8 +352,8 @@ kprobe_breakpoint_ss_handler(struct pt_regs *regs, unsigned int esr) unsigned long addr = instruction_pointer(regs); struct kprobe *cur = kprobe_running(); - if (cur && (kcb->kprobe_status == KPROBE_HIT_SS) - && ((unsigned long)&cur->ainsn.api.insn[1] == addr)) { + if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) && + ((unsigned long)&cur->ainsn.api.insn[1] == addr)) { kprobes_restore_local_irqflag(kcb, regs); post_kprobe_handler(cur, kcb, regs); -- GitLab From 607ec89ed18f49ca59689572659b9c0076f1991f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 19 Jan 2021 10:10:54 -0700 Subject: [PATCH 0528/1084] io_uring: fix SQPOLL IORING_OP_CLOSE cancelation state IORING_OP_CLOSE is special in terms of cancelation, since it has an intermediate state where we've removed the file descriptor but hasn't closed the file yet. For that reason, it's currently marked with IO_WQ_WORK_NO_CANCEL to prevent cancelation. This ensures that the op is always run even if canceled, to prevent leaving us with a live file but an fd that is gone. However, with SQPOLL, since a cancel request doesn't carry any resources on behalf of the request being canceled, if we cancel before any of the close op has been run, we can end up with io-wq not having the ->files assigned. This can result in the following oops reported by Joseph: BUG: kernel NULL pointer dereference, address: 00000000000000d8 PGD 800000010b76f067 P4D 800000010b76f067 PUD 10b462067 PMD 0 Oops: 0000 [#1] SMP PTI CPU: 1 PID: 1788 Comm: io_uring-sq Not tainted 5.11.0-rc4 #1 Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 RIP: 0010:__lock_acquire+0x19d/0x18c0 Code: 00 00 8b 1d fd 56 dd 08 85 db 0f 85 43 05 00 00 48 c7 c6 98 7b 95 82 48 c7 c7 57 96 93 82 e8 9a bc f5 ff 0f 0b e9 2b 05 00 00 <48> 81 3f c0 ca 67 8a b8 00 00 00 00 41 0f 45 c0 89 04 24 e9 81 fe RSP: 0018:ffffc90001933828 EFLAGS: 00010002 RAX: 0000000000000001 RBX: 0000000000000001 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000000000d8 RBP: 0000000000000246 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000000 R14: ffff888106e8a140 R15: 00000000000000d8 FS: 0000000000000000(0000) GS:ffff88813bd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000000d8 CR3: 0000000106efa004 CR4: 00000000003706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: lock_acquire+0x31a/0x440 ? close_fd_get_file+0x39/0x160 ? __lock_acquire+0x647/0x18c0 _raw_spin_lock+0x2c/0x40 ? close_fd_get_file+0x39/0x160 close_fd_get_file+0x39/0x160 io_issue_sqe+0x1334/0x14e0 ? lock_acquire+0x31a/0x440 ? __io_free_req+0xcf/0x2e0 ? __io_free_req+0x175/0x2e0 ? find_held_lock+0x28/0xb0 ? io_wq_submit_work+0x7f/0x240 io_wq_submit_work+0x7f/0x240 io_wq_cancel_cb+0x161/0x580 ? io_wqe_wake_worker+0x114/0x360 ? io_uring_get_socket+0x40/0x40 io_async_find_and_cancel+0x3b/0x140 io_issue_sqe+0xbe1/0x14e0 ? __lock_acquire+0x647/0x18c0 ? __io_queue_sqe+0x10b/0x5f0 __io_queue_sqe+0x10b/0x5f0 ? io_req_prep+0xdb/0x1150 ? mark_held_locks+0x6d/0xb0 ? mark_held_locks+0x6d/0xb0 ? io_queue_sqe+0x235/0x4b0 io_queue_sqe+0x235/0x4b0 io_submit_sqes+0xd7e/0x12a0 ? _raw_spin_unlock_irq+0x24/0x30 ? io_sq_thread+0x3ae/0x940 io_sq_thread+0x207/0x940 ? do_wait_intr_irq+0xc0/0xc0 ? __ia32_sys_io_uring_enter+0x650/0x650 kthread+0x134/0x180 ? kthread_create_worker_on_cpu+0x90/0x90 ret_from_fork+0x1f/0x30 Fix this by moving the IO_WQ_WORK_NO_CANCEL until _after_ we've modified the fdtable. Canceling before this point is totally fine, and running it in the io-wq context _after_ that point is also fine. For 5.12, we'll handle this internally and get rid of the no-cancel flag, as IORING_OP_CLOSE is the only user of it. Cc: stable@vger.kernel.org Fixes: b5dba59e0cf7 ("io_uring: add support for IORING_OP_CLOSE") Reported-by: "Abaci " Reviewed-and-tested-by: Joseph Qi Signed-off-by: Jens Axboe --- fs/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 383ff6ed37342..e4c1cdf0325d5 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -4472,7 +4472,6 @@ static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) * io_wq_work.flags, so initialize io_wq_work firstly. */ io_req_init_async(req); - req->work.flags |= IO_WQ_WORK_NO_CANCEL; if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; @@ -4505,6 +4504,8 @@ static int io_close(struct io_kiocb *req, bool force_nonblock, /* if the file has a flush method, be safe and punt to async */ if (close->put_file->f_op->flush && force_nonblock) { + /* not safe to cancel at this point */ + req->work.flags |= IO_WQ_WORK_NO_CANCEL; /* was never set, but play safe */ req->flags &= ~REQ_F_NOWAIT; /* avoid grabbing files - we don't need the files */ -- GitLab From 9a173346bd9e16ab19c7addb8862d95a5cea9feb Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Thu, 21 Jan 2021 12:01:08 +0000 Subject: [PATCH 0529/1084] io_uring: fix short read retries for non-reg files Sockets and other non-regular files may actually expect short reads to happen, don't retry reads for them. Because non-reg files don't set FMODE_BUF_RASYNC and so it won't do second/retry do_read, we can filter out those cases after first do_read() attempt with ret>0. Cc: stable@vger.kernel.org # 5.9+ Suggested-by: Jens Axboe Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index e4c1cdf0325d5..862113a9364f8 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -3552,7 +3552,7 @@ static int io_read(struct io_kiocb *req, bool force_nonblock, /* read it all, or we did blocking attempt. no retry. */ if (!iov_iter_count(iter) || !force_nonblock || - (req->file->f_flags & O_NONBLOCK)) + (req->file->f_flags & O_NONBLOCK) || !(req->flags & REQ_F_ISREG)) goto done; io_size -= ret; -- GitLab From bb8b81e396f7afbe7c50d789e2107512274d2a35 Mon Sep 17 00:00:00 2001 From: Loris Reiff Date: Fri, 22 Jan 2021 17:42:31 +0100 Subject: [PATCH 0530/1084] bpf, cgroup: Fix optlen WARN_ON_ONCE toctou A toctou issue in `__cgroup_bpf_run_filter_getsockopt` can trigger a WARN_ON_ONCE in a check of `copy_from_user`. `*optlen` is checked to be non-negative in the individual getsockopt functions beforehand. Changing `*optlen` in a race to a negative value will result in a `copy_from_user(ctx.optval, optval, ctx.optlen)` with `ctx.optlen` being a negative integer. Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks") Signed-off-by: Loris Reiff Signed-off-by: Daniel Borkmann Reviewed-by: Stanislav Fomichev Link: https://lore.kernel.org/bpf/20210122164232.61770-1-loris.reiff@liblor.ch --- kernel/bpf/cgroup.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 96555a8a2c545..6ec8f02f463b6 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1442,6 +1442,11 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, goto out; } + if (ctx.optlen < 0) { + ret = -EFAULT; + goto out; + } + if (copy_from_user(ctx.optval, optval, min(ctx.optlen, max_optlen)) != 0) { ret = -EFAULT; -- GitLab From f4a2da755a7e1f5d845c52aee71336cee289935a Mon Sep 17 00:00:00 2001 From: Loris Reiff Date: Fri, 22 Jan 2021 17:42:32 +0100 Subject: [PATCH 0531/1084] bpf, cgroup: Fix problematic bounds check Since ctx.optlen is signed, a larger value than max_value could be passed, as it is later on used as unsigned, which causes a WARN_ON_ONCE in the copy_to_user. Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks") Signed-off-by: Loris Reiff Signed-off-by: Daniel Borkmann Reviewed-by: Stanislav Fomichev Link: https://lore.kernel.org/bpf/20210122164232.61770-2-loris.reiff@liblor.ch --- kernel/bpf/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 6ec8f02f463b6..6aa9e10c6335a 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1464,7 +1464,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, goto out; } - if (ctx.optlen > max_optlen) { + if (ctx.optlen > max_optlen || ctx.optlen < 0) { ret = -EFAULT; goto out; } -- GitLab From b9557caaf872271671bdc1ef003d72f421eb72f6 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Wed, 20 Jan 2021 18:08:56 -0800 Subject: [PATCH 0532/1084] bpf, inode_storage: Put file handler if no storage was found Put file f if inode_storage_ptr() returns NULL. Fixes: 8ea636848aca ("bpf: Implement bpf_local_storage for inodes") Signed-off-by: Pan Bian Signed-off-by: Daniel Borkmann Acked-by: KP Singh Link: https://lore.kernel.org/bpf/20210121020856.25507-1-bianpan2016@163.com --- kernel/bpf/bpf_inode_storage.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/bpf_inode_storage.c b/kernel/bpf/bpf_inode_storage.c index 2f0597320b6d2..6639640523c0b 100644 --- a/kernel/bpf/bpf_inode_storage.c +++ b/kernel/bpf/bpf_inode_storage.c @@ -125,8 +125,12 @@ static int bpf_fd_inode_storage_update_elem(struct bpf_map *map, void *key, fd = *(int *)key; f = fget_raw(fd); - if (!f || !inode_storage_ptr(f->f_inode)) + if (!f) + return -EBADF; + if (!inode_storage_ptr(f->f_inode)) { + fput(f); return -EBADF; + } sdata = bpf_local_storage_update(f->f_inode, (struct bpf_local_storage_map *)map, -- GitLab From caab13b4960416b9fee83169a758eb0f31e65109 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 11 Dec 2020 13:58:46 +0000 Subject: [PATCH 0533/1084] drivers: soc: atmel: Avoid calling at91_soc_init on non AT91 SoCs Since at91_soc_init is called unconditionally from atmel_soc_device_init, we get the following warning on all non AT91 SoCs: " AT91: Could not find identification node" Fix the same by filtering with allowed AT91 SoC list. Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Ludovic Desroches Cc: stable@vger.kernel.org #4.12+ Signed-off-by: Sudeep Holla Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20201211135846.1334322-1-sudeep.holla@arm.com Signed-off-by: Arnd Bergmann --- drivers/soc/atmel/soc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index c4472b68b7c2a..728d461ad6d65 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -271,8 +271,20 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) return soc_dev; } +static const struct of_device_id at91_soc_allowed_list[] __initconst = { + { .compatible = "atmel,at91rm9200", }, + { .compatible = "atmel,at91sam9", }, + { .compatible = "atmel,sama5", }, + { .compatible = "atmel,samv7", } +}; + static int __init atmel_soc_device_init(void) { + struct device_node *np = of_find_node_by_path("/"); + + if (!of_match_node(at91_soc_allowed_list, np)) + return 0; + at91_soc_init(socs); return 0; -- GitLab From 680896556805d3ad3fa47f6002b87b3041a45ac2 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 22 Jan 2021 14:21:34 +0200 Subject: [PATCH 0534/1084] drivers: soc: atmel: add null entry at the end of at91_soc_allowed_list[] of_match_node() calls __of_match_node() which loops though the entries of matches array. It stops when condition: (matches->name[0] || matches->type[0] || matches->compatible[0]) is false. Thus, add a null entry at the end of at91_soc_allowed_list[] array. Fixes: caab13b49604 ("drivers: soc: atmel: Avoid calling at91_soc_init on non AT91 SoCs") Cc: stable@vger.kernel.org #4.12+ Signed-off-by: Claudiu Beznea Signed-off-by: Arnd Bergmann --- drivers/soc/atmel/soc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index 728d461ad6d65..698d21f505165 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -275,7 +275,8 @@ static const struct of_device_id at91_soc_allowed_list[] __initconst = { { .compatible = "atmel,at91rm9200", }, { .compatible = "atmel,at91sam9", }, { .compatible = "atmel,sama5", }, - { .compatible = "atmel,samv7", } + { .compatible = "atmel,samv7", }, + { } }; static int __init atmel_soc_device_init(void) -- GitLab From da8ee66f56071aef0b5b0de41d2c2a97fa30c8a1 Mon Sep 17 00:00:00 2001 From: Bharat Gooty Date: Tue, 19 Jan 2021 11:04:44 +0530 Subject: [PATCH 0535/1084] arm64: dts: broadcom: Fix USB DMA address translation for Stingray Add a non-empty dma-ranges so that DMA address translation happens. Fixes: 2013a4b684b6 ("arm64: dts: broadcom: clear the warnings caused by empty dma-ranges") Signed-off-by: Bharat Gooty Signed-off-by: Rayagonda Kokatanur Reviewed-by: Arnd Bergmann Acked-by: Ray Jui Signed-off-by: Florian Fainelli Signed-off-by: Arnd Bergmann --- arch/arm64/boot/dts/broadcom/stingray/stingray-usb.dtsi | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-usb.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-usb.dtsi index aef8f2b00778d..5401a646c8406 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/stingray-usb.dtsi +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray-usb.dtsi @@ -4,11 +4,16 @@ */ usb { compatible = "simple-bus"; - dma-ranges; #address-cells = <2>; #size-cells = <2>; ranges = <0x0 0x0 0x0 0x68500000 0x0 0x00400000>; + /* + * Internally, USB bus to the interconnect can only address up + * to 40-bit + */ + dma-ranges = <0 0 0 0 0x100 0x0>; + usbphy0: usb-phy@0 { compatible = "brcm,sr-usb-combo-phy"; reg = <0x0 0x00000000 0x0 0x100>; -- GitLab From 68e89bc868e190365930f914fdbe154064851ec9 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 3 Jan 2021 13:24:35 +0100 Subject: [PATCH 0536/1084] MAINTAINERS: Include bcm2835 subsequents into search Change the bcm2835 maintainer info in order to handle subsequent SoCs. After this get_maintainers.pl provides the proper maintainers for irqchip-bcm2836. Signed-off-by: Stefan Wahren Signed-off-by: Florian Fainelli Signed-off-by: Arnd Bergmann --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index cc1e6a5ee6e67..f545261885f10 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3413,7 +3413,7 @@ F: Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml F: drivers/pci/controller/pcie-brcmstb.c F: drivers/staging/vc04_services N: bcm2711 -N: bcm2835 +N: bcm283* BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE M: Florian Fainelli -- GitLab From 7e0e63d09516e96994c879f07c5a3c3269d7015e Mon Sep 17 00:00:00 2001 From: Giacinto Cifelli Date: Wed, 20 Jan 2021 05:56:50 +0100 Subject: [PATCH 0537/1084] net: usb: qmi_wwan: added support for Thales Cinterion PLSx3 modem family MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bus 003 Device 009: ID 1e2d:006f Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 239 Miscellaneous Device bDeviceSubClass 2 ? bDeviceProtocol 1 Interface Association bMaxPacketSize0 64 idVendor 0x1e2d idProduct 0x006f bcdDevice 0.00 iManufacturer 3 Cinterion Wireless Modules iProduct 2 PLSx3 iSerial 4 fa3c1419 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 303 bNumInterfaces 9 bConfigurationValue 1 iConfiguration 1 Cinterion Configuration bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 500mA Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 0 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 2 Abstract (modem) bFunctionProtocol 1 AT-commands (v.25ter) iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 1.10 CDC ACM: bmCapabilities 0x02 line coding and serial state CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 1 CDC Union: bMasterInterface 0 bSlaveInterface 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 2 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 2 Abstract (modem) bFunctionProtocol 1 AT-commands (v.25ter) iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 1.10 CDC ACM: bmCapabilities 0x02 line coding and serial state CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 3 CDC Union: bMasterInterface 2 bSlaveInterface 3 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 3 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 4 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 2 Abstract (modem) bFunctionProtocol 1 AT-commands (v.25ter) iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 4 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 1.10 CDC ACM: bmCapabilities 0x02 line coding and serial state CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 5 CDC Union: bMasterInterface 4 bSlaveInterface 5 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x85 EP 5 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 5 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x86 EP 6 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 6 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 2 Abstract (modem) bFunctionProtocol 1 AT-commands (v.25ter) iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 6 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 1.10 CDC ACM: bmCapabilities 0x02 line coding and serial state CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 7 CDC Union: bMasterInterface 6 bSlaveInterface 7 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x87 EP 7 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 7 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x88 EP 8 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x04 EP 4 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 8 bAlternateSetting 0 bNumEndpoints 3 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x89 EP 9 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x8a EP 10 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x05 EP 5 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 239 Miscellaneous Device bDeviceSubClass 2 ? bDeviceProtocol 1 Interface Association bMaxPacketSize0 64 bNumConfigurations 1 Device Status: 0x0000 (Bus Powered) Cc: stable@vger.kernel.org Signed-off-by: Giacinto Cifelli Acked-by: Bjørn Mork Link: https://lore.kernel.org/r/20210120045650.10855-1-gciofono@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index af19513a9f75b..cc4819282820b 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1302,6 +1302,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x0b3c, 0xc00a, 6)}, /* Olivetti Olicard 160 */ {QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)}, /* Olivetti Olicard 500 */ {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ + {QMI_QUIRK_SET_DTR(0x1e2d, 0x006f, 8)}, /* Cinterion PLS83/PLS63 */ {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ {QMI_FIXED_INTF(0x1e2d, 0x0063, 10)}, /* Cinterion ALASxx (1 RmNet) */ {QMI_FIXED_INTF(0x1e2d, 0x0082, 4)}, /* Cinterion PHxx,PXxx (2 RmNet) */ -- GitLab From db2805150a0f27c00ad286a29109397a7723adad Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Thu, 21 Jan 2021 15:09:06 +0800 Subject: [PATCH 0538/1084] net: octeontx2: Make sure the buffer is 128 byte aligned The octeontx2 hardware needs the buffer to be 128 byte aligned. But in the current implementation of napi_alloc_frag(), it can't guarantee the return address is 128 byte aligned even the request size is a multiple of 128 bytes, so we have to request an extra 128 bytes and use the PTR_ALIGN() to make sure that the buffer is aligned correctly. Fixes: 7a36e4918e30 ("octeontx2-pf: Use the napi_alloc_frag() to alloc the pool buffers") Reported-by: Subbaraya Sundeep Signed-off-by: Kevin Hao Tested-by: Subbaraya Sundeep Link: https://lore.kernel.org/r/20210121070906.25380-1-haokexin@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c index 73fb94dd5fbcc..e6869435e1f32 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -478,10 +478,11 @@ dma_addr_t __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool) dma_addr_t iova; u8 *buf; - buf = napi_alloc_frag(pool->rbsize); + buf = napi_alloc_frag(pool->rbsize + OTX2_ALIGN); if (unlikely(!buf)) return -ENOMEM; + buf = PTR_ALIGN(buf, OTX2_ALIGN); iova = dma_map_single_attrs(pfvf->dev, buf, pool->rbsize, DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); if (unlikely(dma_mapping_error(pfvf->dev, iova))) { -- GitLab From 3765d86ffcd346913c372d69cdc05dc8d56119ac Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Wed, 20 Jan 2021 03:07:44 -0800 Subject: [PATCH 0539/1084] net: stmmac: dwmac-intel-plat: remove config data on error Remove the config data when rate setting fails. Fixes: 9efc9b2b04c7 ("net: stmmac: Add dwmac-intel-plat for GBE driver") Signed-off-by: Pan Bian Link: https://lore.kernel.org/r/20210120110745.36412-1-bianpan2016@163.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c index 82b1c7a5a7a94..ba0e4d2b256a4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c @@ -129,7 +129,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Failed to set tx_clk\n"); - return ret; + goto err_remove_config_dt; } } } @@ -143,7 +143,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Failed to set clk_ptp_ref\n"); - return ret; + goto err_remove_config_dt; } } } -- GitLab From 0607a2cddb60f4548b55e28ac56a8d73493a45bb Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Wed, 20 Jan 2021 04:20:37 -0800 Subject: [PATCH 0540/1084] net: fec: put child node on error path Also decrement the reference count of child device on error path. Fixes: 3e782985cb3c ("net: ethernet: fec: Allow configuration of MDIO bus speed") Signed-off-by: Pan Bian Link: https://lore.kernel.org/r/20210120122037.83897-1-bianpan2016@163.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/freescale/fec_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 04f24c66cf366..55c28fbc5f9ea 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -2165,9 +2165,9 @@ static int fec_enet_mii_init(struct platform_device *pdev) fep->mii_bus->parent = &pdev->dev; err = of_mdiobus_register(fep->mii_bus, node); - of_node_put(node); if (err) goto err_out_free_mdiobus; + of_node_put(node); mii_cnt++; @@ -2180,6 +2180,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) err_out_free_mdiobus: mdiobus_free(fep->mii_bus); err_out: + of_node_put(node); return err; } -- GitLab From 336e8eb2a3cfe2285c314cd85630076da365f6c6 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Thu, 21 Jan 2021 14:31:17 +0800 Subject: [PATCH 0541/1084] riscv: Fixup pfn_valid error with wrong max_mapnr The max_mapnr is the number of PFNs, not absolute PFN offset. Signed-off-by: Guo Ren Fixes: d0d8aae64566 ("RISC-V: Set maximum number of mapped pages correctly") Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt --- arch/riscv/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 7cd4993f4ff21..f9f9568d689ef 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -196,7 +196,7 @@ void __init setup_bootmem(void) max_pfn = PFN_DOWN(dram_end); max_low_pfn = max_pfn; dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn)); - set_max_mapnr(max_low_pfn); + set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET); #ifdef CONFIG_BLK_DEV_INITRD setup_initrd(); -- GitLab From 214a5ea081e77346e4963dd6d20c5539ff8b6ae6 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Thu, 21 Jan 2021 08:22:48 +1000 Subject: [PATCH 0542/1084] cifs: do not fail __smb_send_rqst if non-fatal signals are pending RHBZ 1848178 The original intent of returning an error in this function in the patch: "CIFS: Mask off signals when sending SMB packets" was to avoid interrupting packet send in the middle of sending the data (and thus breaking an SMB connection), but we also don't want to fail the request for non-fatal signals even before we have had a chance to try to send it (the reported problem could be reproduced e.g. by exiting a child process when the parent process was in the midst of calling futimens to update a file's timestamps). In addition, since the signal may remain pending when we enter the sending loop, we may end up not sending the whole packet before TCP buffers become full. In this case the code returns -EINTR but what we need here is to return -ERESTARTSYS instead to allow system calls to be restarted. Fixes: b30c74c73c78 ("CIFS: Mask off signals when sending SMB packets") Cc: stable@vger.kernel.org # v5.1+ Signed-off-by: Ronnie Sahlberg Reviewed-by: Pavel Shilovsky Signed-off-by: Steve French --- fs/cifs/transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index e9abb41aa89bc..95ef26b555b91 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -338,7 +338,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, if (ssocket == NULL) return -EAGAIN; - if (signal_pending(current)) { + if (fatal_signal_pending(current)) { cifs_dbg(FYI, "signal pending before send request\n"); return -ERESTARTSYS; } @@ -429,7 +429,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, if (signal_pending(current) && (total_len != send_length)) { cifs_dbg(FYI, "signal is pending after attempt to send\n"); - rc = -EINTR; + rc = -ERESTARTSYS; } /* uncork it */ -- GitLab From 1cabe74f148f7b99d9f08274a62467f96c870f07 Mon Sep 17 00:00:00 2001 From: Robert Karszniewicz Date: Fri, 22 Jan 2021 19:04:13 +0100 Subject: [PATCH 0543/1084] Documentation/Kbuild: Remove references to gcc-plugin.sh gcc-plugin.sh has been removed in commit 1e860048c53e ("gcc-plugins: simplify GCC plugin-dev capability test"). Signed-off-by: Robert Karszniewicz Reviewed-by: Kees Cook Signed-off-by: Masahiro Yamada --- Documentation/kbuild/gcc-plugins.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Documentation/kbuild/gcc-plugins.rst b/Documentation/kbuild/gcc-plugins.rst index 4b1c10f88e304..63379d0150e37 100644 --- a/Documentation/kbuild/gcc-plugins.rst +++ b/Documentation/kbuild/gcc-plugins.rst @@ -47,12 +47,6 @@ Files This is a compatibility header for GCC plugins. It should be always included instead of individual gcc headers. -**$(src)/scripts/gcc-plugin.sh** - - This script checks the availability of the included headers in - gcc-common.h and chooses the proper host compiler to build the plugins - (gcc-4.7 can be built by either gcc or g++). - **$(src)/scripts/gcc-plugins/gcc-generate-gimple-pass.h, $(src)/scripts/gcc-plugins/gcc-generate-ipa-pass.h, $(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h, -- GitLab From f4c3b83b75b91c5059726cb91e3165cc01764ce7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 23 Jan 2021 18:16:30 +0900 Subject: [PATCH 0544/1084] kbuild: simplify GCC_PLUGINS enablement in dummy-tools/gcc With commit 1e860048c53e ("gcc-plugins: simplify GCC plugin-dev capability test") applied, this hunk can be way simplified because now scripts/gcc-plugins/Kconfig only checks plugin-version.h Signed-off-by: Masahiro Yamada --- scripts/dummy-tools/gcc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/scripts/dummy-tools/gcc b/scripts/dummy-tools/gcc index 33487e99d83e5..5c113cad56017 100755 --- a/scripts/dummy-tools/gcc +++ b/scripts/dummy-tools/gcc @@ -75,16 +75,12 @@ if arg_contain -S "$@"; then fi fi -# For scripts/gcc-plugin.sh +# To set GCC_PLUGINS if arg_contain -print-file-name=plugin "$@"; then plugin_dir=$(mktemp -d) - sed -n 's/.*#include "\(.*\)"/\1/p' $(dirname $0)/../gcc-plugins/gcc-common.h | - while read header - do - mkdir -p $plugin_dir/include/$(dirname $header) - touch $plugin_dir/include/$header - done + mkdir -p $plugin_dir/include + touch $plugin_dir/include/plugin-version.h echo $plugin_dir exit 0 -- GitLab From dc090de854b9d7fdbc6f4df70bd7fc1b43eeccf8 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 21 Jan 2021 21:40:36 +0100 Subject: [PATCH 0545/1084] net: mrp: fix definitions of MRP test packets Wireshark says that the MRP test packets cannot be decoded - and the reason for that is that there's a two-byte hole filled with garbage between the "transitions" and "timestamp" members. So Wireshark decodes the two garbage bytes and the top two bytes of the timestamp written by the kernel as the timestamp value (which thus fluctuates wildly), and interprets the lower two bytes of the timestamp as a new (type, length) pair, which is of course broken. Even though this makes the timestamp field in the struct unaligned, it actually makes it end up on a 32 bit boundary in the frame as mandated by the standard, since it is preceded by a two byte TLV header. The struct definitions live under include/uapi/, but they are not really part of any kernel<->userspace API/ABI, so fixing the definitions by adding the packed attribute should not cause any compatibility issues. Signed-off-by: Rasmus Villemoes Reviewed-by: Horatiu Vultur Signed-off-by: Jakub Kicinski --- include/uapi/linux/mrp_bridge.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/mrp_bridge.h b/include/uapi/linux/mrp_bridge.h index 9744773de5ffa..5ce771327e326 100644 --- a/include/uapi/linux/mrp_bridge.h +++ b/include/uapi/linux/mrp_bridge.h @@ -97,7 +97,7 @@ struct br_mrp_ring_test_hdr { __be16 state; __be16 transitions; __be32 timestamp; -}; +} __attribute__((__packed__)); struct br_mrp_ring_topo_hdr { __be16 prio; @@ -142,7 +142,7 @@ struct br_mrp_in_test_hdr { __be16 state; __be16 transitions; __be32 timestamp; -}; +} __attribute__((__packed__)); struct br_mrp_in_topo_hdr { __u8 sa[ETH_ALEN]; -- GitLab From 6781939054a1a161e06e7a7955a4846be770a711 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 21 Jan 2021 21:40:37 +0100 Subject: [PATCH 0546/1084] net: mrp: move struct definitions out of uapi None of these are actually used in the kernel/userspace interface - there's a userspace component of implementing MRP, and userspace will need to construct certain frames to put on the wire, but there's no reason the kernel should provide the relevant definitions in a UAPI header. In fact, some of those definitions were broken until previous commit, so only keep the few that are actually referenced in the kernel code, and move them to the br_private_mrp.h header. Signed-off-by: Rasmus Villemoes Signed-off-by: Jakub Kicinski --- include/uapi/linux/mrp_bridge.h | 86 --------------------------------- net/bridge/br_private_mrp.h | 29 +++++++++++ 2 files changed, 29 insertions(+), 86 deletions(-) diff --git a/include/uapi/linux/mrp_bridge.h b/include/uapi/linux/mrp_bridge.h index 5ce771327e326..bd4424de56ff5 100644 --- a/include/uapi/linux/mrp_bridge.h +++ b/include/uapi/linux/mrp_bridge.h @@ -71,90 +71,4 @@ enum br_mrp_sub_tlv_header_type { BR_MRP_SUB_TLV_HEADER_TEST_AUTO_MGR = 0x3, }; -struct br_mrp_tlv_hdr { - __u8 type; - __u8 length; -}; - -struct br_mrp_sub_tlv_hdr { - __u8 type; - __u8 length; -}; - -struct br_mrp_end_hdr { - struct br_mrp_tlv_hdr hdr; -}; - -struct br_mrp_common_hdr { - __be16 seq_id; - __u8 domain[MRP_DOMAIN_UUID_LENGTH]; -}; - -struct br_mrp_ring_test_hdr { - __be16 prio; - __u8 sa[ETH_ALEN]; - __be16 port_role; - __be16 state; - __be16 transitions; - __be32 timestamp; -} __attribute__((__packed__)); - -struct br_mrp_ring_topo_hdr { - __be16 prio; - __u8 sa[ETH_ALEN]; - __be16 interval; -}; - -struct br_mrp_ring_link_hdr { - __u8 sa[ETH_ALEN]; - __be16 port_role; - __be16 interval; - __be16 blocked; -}; - -struct br_mrp_sub_opt_hdr { - __u8 type; - __u8 manufacture_data[MRP_MANUFACTURE_DATA_LENGTH]; -}; - -struct br_mrp_test_mgr_nack_hdr { - __be16 prio; - __u8 sa[ETH_ALEN]; - __be16 other_prio; - __u8 other_sa[ETH_ALEN]; -}; - -struct br_mrp_test_prop_hdr { - __be16 prio; - __u8 sa[ETH_ALEN]; - __be16 other_prio; - __u8 other_sa[ETH_ALEN]; -}; - -struct br_mrp_oui_hdr { - __u8 oui[MRP_OUI_LENGTH]; -}; - -struct br_mrp_in_test_hdr { - __be16 id; - __u8 sa[ETH_ALEN]; - __be16 port_role; - __be16 state; - __be16 transitions; - __be32 timestamp; -} __attribute__((__packed__)); - -struct br_mrp_in_topo_hdr { - __u8 sa[ETH_ALEN]; - __be16 id; - __be16 interval; -}; - -struct br_mrp_in_link_hdr { - __u8 sa[ETH_ALEN]; - __be16 port_role; - __be16 id; - __be16 interval; -}; - #endif diff --git a/net/bridge/br_private_mrp.h b/net/bridge/br_private_mrp.h index 1883118aae55b..32a48e5418dac 100644 --- a/net/bridge/br_private_mrp.h +++ b/net/bridge/br_private_mrp.h @@ -88,4 +88,33 @@ int br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp, int br_mrp_ring_port_open(struct net_device *dev, u8 loc); int br_mrp_in_port_open(struct net_device *dev, u8 loc); +/* MRP protocol data units */ +struct br_mrp_tlv_hdr { + __u8 type; + __u8 length; +}; + +struct br_mrp_common_hdr { + __be16 seq_id; + __u8 domain[MRP_DOMAIN_UUID_LENGTH]; +}; + +struct br_mrp_ring_test_hdr { + __be16 prio; + __u8 sa[ETH_ALEN]; + __be16 port_role; + __be16 state; + __be16 transitions; + __be32 timestamp; +} __attribute__((__packed__)); + +struct br_mrp_in_test_hdr { + __be16 id; + __u8 sa[ETH_ALEN]; + __be16 port_role; + __be16 state; + __be16 transitions; + __be32 timestamp; +} __attribute__((__packed__)); + #endif /* _BR_PRIVATE_MRP_H */ -- GitLab From cf3c46631e1637582f517a574c77cd6c05793817 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Thu, 21 Jan 2021 04:33:43 -0800 Subject: [PATCH 0547/1084] net: dsa: bcm_sf2: put device node before return Put the device node dn before return error code on failure path. Fixes: 461cd1b03e32 ("net: dsa: bcm_sf2: Register our slave MDIO bus") Signed-off-by: Pan Bian Link: https://lore.kernel.org/r/20210121123343.26330-1-bianpan2016@163.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/bcm_sf2.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 1e9a0adda2d69..445226720ff29 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -509,15 +509,19 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) /* Find our integrated MDIO bus node */ dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio"); priv->master_mii_bus = of_mdio_find_bus(dn); - if (!priv->master_mii_bus) + if (!priv->master_mii_bus) { + of_node_put(dn); return -EPROBE_DEFER; + } get_device(&priv->master_mii_bus->dev); priv->master_mii_dn = dn; priv->slave_mii_bus = devm_mdiobus_alloc(ds->dev); - if (!priv->slave_mii_bus) + if (!priv->slave_mii_bus) { + of_node_put(dn); return -ENOMEM; + } priv->slave_mii_bus->priv = priv; priv->slave_mii_bus->name = "sf2 slave mii"; -- GitLab From b6011966ac6f402847eb5326beee8da3a80405c7 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Thu, 21 Jan 2021 06:57:38 -0800 Subject: [PATCH 0548/1084] chtls: Fix potential resource leak The dst entry should be released if no neighbour is found. Goto label free_dst to fix the issue. Besides, the check of ndev against NULL is redundant. Signed-off-by: Pan Bian Link: https://lore.kernel.org/r/20210121145738.51091-1-bianpan2016@163.com Signed-off-by: Jakub Kicinski --- .../net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c index e5cfbe196ba66..19dc7dc054a29 100644 --- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c +++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c @@ -1158,11 +1158,9 @@ static struct sock *chtls_recv_sock(struct sock *lsk, #endif } if (!n || !n->dev) - goto free_sk; + goto free_dst; ndev = n->dev; - if (!ndev) - goto free_dst; if (is_vlan_dev(ndev)) ndev = vlan_dev_real_dev(ndev); @@ -1250,7 +1248,8 @@ static struct sock *chtls_recv_sock(struct sock *lsk, free_csk: chtls_sock_release(&csk->kref); free_dst: - neigh_release(n); + if (n) + neigh_release(n); dst_release(dst); free_sk: inet_csk_prepare_forced_close(newsk); -- GitLab From fc024c5c07aa2463d36e8c85943343741ba356b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 21 Jan 2021 16:02:44 +0100 Subject: [PATCH 0549/1084] doc: networking: ip-sysctl: Document conf/all/disable_ipv6 and conf/default/disable_ipv6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds documentation for sysctl conf/all/disable_ipv6 and conf/default/disable_ipv6 settings which is currently missing. Signed-off-by: Pali Rohár Link: https://lore.kernel.org/r/20210121150244.20483-1-pali@kernel.org Signed-off-by: Jakub Kicinski --- Documentation/networking/ip-sysctl.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index dd2b12a32b739..c7b775da95542 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -1807,12 +1807,24 @@ seg6_flowlabel - INTEGER ``conf/default/*``: Change the interface-specific default settings. + These settings would be used during creating new interfaces. + ``conf/all/*``: Change all the interface-specific settings. [XXX: Other special features than forwarding?] +conf/all/disable_ipv6 - BOOLEAN + Changing this value is same as changing ``conf/default/disable_ipv6`` + setting and also all per-interface ``disable_ipv6`` settings to the same + value. + + Reading this value does not have any particular meaning. It does not say + whether IPv6 support is enabled or disabled. Returned value can be 1 + also in the case when some interface has ``disable_ipv6`` set to 0 and + has configured IPv6 addresses. + conf/all/forwarding - BOOLEAN Enable global IPv6 forwarding between all interfaces. -- GitLab From d8f923c3ab96dbbb4e3c22d1afc1dc1d3b195cd8 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Thu, 21 Jan 2021 07:37:45 -0800 Subject: [PATCH 0550/1084] NFC: fix possible resource leak Put the device to avoid resource leak on path that the polling flag is invalid. Fixes: a831b9132065 ("NFC: Do not return EBUSY when stopping a poll that's already stopped") Signed-off-by: Pan Bian Link: https://lore.kernel.org/r/20210121153745.122184-1-bianpan2016@163.com Signed-off-by: Jakub Kicinski --- net/nfc/netlink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 573b38ad2f8ed..e161ef2d4720d 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -852,6 +852,7 @@ static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info) if (!dev->polling) { device_unlock(&dev->dev); + nfc_put_device(dev); return -EINVAL; } -- GitLab From 3a30537cee233fb7da302491b28c832247d89bbe Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Thu, 21 Jan 2021 07:27:48 -0800 Subject: [PATCH 0551/1084] NFC: fix resource leak when target index is invalid Goto to the label put_dev instead of the label error to fix potential resource leak on path that the target index is invalid. Fixes: c4fbb6515a4d ("NFC: The core part should generate the target index") Signed-off-by: Pan Bian Link: https://lore.kernel.org/r/20210121152748.98409-1-bianpan2016@163.com Signed-off-by: Jakub Kicinski --- net/nfc/rawsock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 955c195ae14bc..9c7eb8455ba8e 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -105,7 +105,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr, if (addr->target_idx > dev->target_next_idx - 1 || addr->target_idx < dev->target_next_idx - dev->n_targets) { rc = -EINVAL; - goto error; + goto put_dev; } rc = nfc_activate_target(dev, addr->target_idx, addr->nfc_protocol); -- GitLab From 344db93ae3ee69fc137bd6ed89a8ff1bf5b0db08 Mon Sep 17 00:00:00 2001 From: Enke Chen Date: Fri, 22 Jan 2021 11:13:06 -0800 Subject: [PATCH 0552/1084] tcp: make TCP_USER_TIMEOUT accurate for zero window probes The TCP_USER_TIMEOUT is checked by the 0-window probe timer. As the timer has backoff with a max interval of about two minutes, the actual timeout for TCP_USER_TIMEOUT can be off by up to two minutes. In this patch the TCP_USER_TIMEOUT is made more accurate by taking it into account when computing the timer value for the 0-window probes. This patch is similar to and builds on top of the one that made TCP_USER_TIMEOUT accurate for RTOs in commit b701a99e431d ("tcp: Add tcp_clamp_rto_to_user_timeout() helper to improve accuracy"). Fixes: 9721e709fa68 ("tcp: simplify window probe aborting on USER_TIMEOUT") Signed-off-by: Enke Chen Reviewed-by: Neal Cardwell Signed-off-by: Eric Dumazet Link: https://lore.kernel.org/r/20210122191306.GA99540@localhost.localdomain Signed-off-by: Jakub Kicinski --- include/net/tcp.h | 1 + net/ipv4/tcp_input.c | 4 ++-- net/ipv4/tcp_output.c | 2 ++ net/ipv4/tcp_timer.c | 18 ++++++++++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 78d13c88720fd..ca7e2c6cc663e 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -630,6 +630,7 @@ static inline void tcp_clear_xmit_timers(struct sock *sk) unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu); unsigned int tcp_current_mss(struct sock *sk); +u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when); /* Bound MSS / TSO packet size with the half of the window */ static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a7dfca0a38cd7..55c6fd6b5d139 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3392,8 +3392,8 @@ static void tcp_ack_probe(struct sock *sk) } else { unsigned long when = tcp_probe0_when(sk, TCP_RTO_MAX); - tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0, - when, TCP_RTO_MAX); + when = tcp_clamp_probe0_to_user_timeout(sk, when); + tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0, when, TCP_RTO_MAX); } } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ab458697881ed..8478cf749821a 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -4099,6 +4099,8 @@ void tcp_send_probe0(struct sock *sk) */ timeout = TCP_RESOURCE_PROBE_INTERVAL; } + + timeout = tcp_clamp_probe0_to_user_timeout(sk, timeout); tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0, timeout, TCP_RTO_MAX); } diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index faa92948441ba..4ef08079ccfa9 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -40,6 +40,24 @@ static u32 tcp_clamp_rto_to_user_timeout(const struct sock *sk) return min_t(u32, icsk->icsk_rto, msecs_to_jiffies(remaining)); } +u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when) +{ + struct inet_connection_sock *icsk = inet_csk(sk); + u32 remaining; + s32 elapsed; + + if (!icsk->icsk_user_timeout || !icsk->icsk_probes_tstamp) + return when; + + elapsed = tcp_jiffies32 - icsk->icsk_probes_tstamp; + if (unlikely(elapsed < 0)) + elapsed = 0; + remaining = msecs_to_jiffies(icsk->icsk_user_timeout) - elapsed; + remaining = max_t(u32, remaining, TCP_TIMEOUT_MIN); + + return min_t(u32, remaining, when); +} + /** * tcp_write_err() - close socket and save error info * @sk: The socket the error has appeared on. -- GitLab From 62d9f1a6945ba69c125e548e72a36d203b30596e Mon Sep 17 00:00:00 2001 From: Pengcheng Yang Date: Sun, 24 Jan 2021 13:07:14 +0800 Subject: [PATCH 0553/1084] tcp: fix TLP timer not set when CA_STATE changes from DISORDER to OPEN Upon receiving a cumulative ACK that changes the congestion state from Disorder to Open, the TLP timer is not set. If the sender is app-limited, it can only wait for the RTO timer to expire and retransmit. The reason for this is that the TLP timer is set before the congestion state changes in tcp_ack(), so we delay the time point of calling tcp_set_xmit_timer() until after tcp_fastretrans_alert() returns and remove the FLAG_SET_XMIT_TIMER from ack_flag when the RACK reorder timer is set. This commit has two additional benefits: 1) Make sure to reset RTO according to RFC6298 when receiving ACK, to avoid spurious RTO caused by RTO timer early expires. 2) Reduce the xmit timer reschedule once per ACK when the RACK reorder timer is set. Fixes: df92c8394e6e ("tcp: fix xmit timer to only be reset if data ACKed/SACKed") Link: https://lore.kernel.org/netdev/1611311242-6675-1-git-send-email-yangpc@wangsu.com Signed-off-by: Pengcheng Yang Acked-by: Neal Cardwell Acked-by: Yuchung Cheng Cc: Eric Dumazet Link: https://lore.kernel.org/r/1611464834-23030-1-git-send-email-yangpc@wangsu.com Signed-off-by: Jakub Kicinski --- include/net/tcp.h | 2 +- net/ipv4/tcp_input.c | 10 ++++++---- net/ipv4/tcp_recovery.c | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index ca7e2c6cc663e..25bbada379c46 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -2061,7 +2061,7 @@ void tcp_mark_skb_lost(struct sock *sk, struct sk_buff *skb); void tcp_newreno_mark_lost(struct sock *sk, bool snd_una_advanced); extern s32 tcp_rack_skb_timeout(struct tcp_sock *tp, struct sk_buff *skb, u32 reo_wnd); -extern void tcp_rack_mark_lost(struct sock *sk); +extern bool tcp_rack_mark_lost(struct sock *sk); extern void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq, u64 xmit_time); extern void tcp_rack_reo_timeout(struct sock *sk); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 55c6fd6b5d139..9b44caa4b9562 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2859,7 +2859,8 @@ static void tcp_identify_packet_loss(struct sock *sk, int *ack_flag) } else if (tcp_is_rack(sk)) { u32 prior_retrans = tp->retrans_out; - tcp_rack_mark_lost(sk); + if (tcp_rack_mark_lost(sk)) + *ack_flag &= ~FLAG_SET_XMIT_TIMER; if (prior_retrans > tp->retrans_out) *ack_flag |= FLAG_LOST_RETRANS; } @@ -3816,9 +3817,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) if (tp->tlp_high_seq) tcp_process_tlp_ack(sk, ack, flag); - /* If needed, reset TLP/RTO timer; RACK may later override this. */ - if (flag & FLAG_SET_XMIT_TIMER) - tcp_set_xmit_timer(sk); if (tcp_ack_is_dubious(sk, flag)) { if (!(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP))) { @@ -3831,6 +3829,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) &rexmit); } + /* If needed, reset TLP/RTO timer when RACK doesn't set. */ + if (flag & FLAG_SET_XMIT_TIMER) + tcp_set_xmit_timer(sk); + if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP)) sk_dst_confirm(sk); diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c index 177307a3081f9..6f1b4ac7fe99c 100644 --- a/net/ipv4/tcp_recovery.c +++ b/net/ipv4/tcp_recovery.c @@ -96,13 +96,13 @@ static void tcp_rack_detect_loss(struct sock *sk, u32 *reo_timeout) } } -void tcp_rack_mark_lost(struct sock *sk) +bool tcp_rack_mark_lost(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); u32 timeout; if (!tp->rack.advanced) - return; + return false; /* Reset the advanced flag to avoid unnecessary queue scanning */ tp->rack.advanced = 0; @@ -112,6 +112,7 @@ void tcp_rack_mark_lost(struct sock *sk) inet_csk_reset_xmit_timer(sk, ICSK_TIME_REO_TIMEOUT, timeout, inet_csk(sk)->icsk_rto); } + return !!timeout; } /* Record the most recently (re)sent time among the (s)acked packets -- GitLab From 4025c784c573cab7e3f84746cc82b8033923ec62 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 23 Jan 2021 16:12:44 +1000 Subject: [PATCH 0554/1084] powerpc/64s: prevent recursive replay_soft_interrupts causing superfluous interrupt When an asynchronous interrupt calls irq_exit, it checks for softirqs that may have been created, and runs them. Running softirqs enables local irqs, which can replay pending interrupts causing recursion in replay_soft_interrupts. This abridged trace shows how this can occur: ! NIP replay_soft_interrupts LR interrupt_exit_kernel_prepare Call Trace: interrupt_exit_kernel_prepare (unreliable) interrupt_return --- interrupt: ea0 at __rb_reserve_next NIP __rb_reserve_next LR __rb_reserve_next Call Trace: ring_buffer_lock_reserve trace_function function_trace_call ftrace_call __do_softirq irq_exit timer_interrupt ! replay_soft_interrupts interrupt_exit_kernel_prepare interrupt_return --- interrupt: ea0 at arch_local_irq_restore This can not be prevented easily, because softirqs must not block hard irqs, so it has to be dealt with. The recursion is bounded by design in the softirq code because softirq replay disables softirqs and loops around again to check for new softirqs created while it ran, so that's not a problem. However it does mess up interrupt replay state, causing superfluous interrupts when the second replay_soft_interrupts clears a pending interrupt, leaving it still set in the first call in the 'happened' local variable. Fix this by not caching a copy of irqs_happened across interrupt handler calls. Fixes: 3282a3da25bd ("powerpc/64: Implement soft interrupt replay in C") Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210123061244.2076145-1-npiggin@gmail.com --- arch/powerpc/kernel/irq.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 6b1eca53e36cc..cc7a6271b6b4e 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -180,13 +180,18 @@ void notrace restore_interrupts(void) void replay_soft_interrupts(void) { + struct pt_regs regs; + /* - * We use local_paca rather than get_paca() to avoid all - * the debug_smp_processor_id() business in this low level - * function + * Be careful here, calling these interrupt handlers can cause + * softirqs to be raised, which they may run when calling irq_exit, + * which will cause local_irq_enable() to be run, which can then + * recurse into this function. Don't keep any state across + * interrupt handler calls which may change underneath us. + * + * We use local_paca rather than get_paca() to avoid all the + * debug_smp_processor_id() business in this low level function. */ - unsigned char happened = local_paca->irq_happened; - struct pt_regs regs; ppc_save_regs(®s); regs.softe = IRQS_ENABLED; @@ -209,7 +214,7 @@ void replay_soft_interrupts(void) * This is a higher priority interrupt than the others, so * replay it first. */ - if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_HMI)) { + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_HMI)) { local_paca->irq_happened &= ~PACA_IRQ_HMI; regs.trap = 0xe60; handle_hmi_exception(®s); @@ -217,7 +222,7 @@ void replay_soft_interrupts(void) hard_irq_disable(); } - if (happened & PACA_IRQ_DEC) { + if (local_paca->irq_happened & PACA_IRQ_DEC) { local_paca->irq_happened &= ~PACA_IRQ_DEC; regs.trap = 0x900; timer_interrupt(®s); @@ -225,7 +230,7 @@ void replay_soft_interrupts(void) hard_irq_disable(); } - if (happened & PACA_IRQ_EE) { + if (local_paca->irq_happened & PACA_IRQ_EE) { local_paca->irq_happened &= ~PACA_IRQ_EE; regs.trap = 0x500; do_IRQ(®s); @@ -233,7 +238,7 @@ void replay_soft_interrupts(void) hard_irq_disable(); } - if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (happened & PACA_IRQ_DBELL)) { + if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (local_paca->irq_happened & PACA_IRQ_DBELL)) { local_paca->irq_happened &= ~PACA_IRQ_DBELL; if (IS_ENABLED(CONFIG_PPC_BOOK3E)) regs.trap = 0x280; @@ -245,7 +250,7 @@ void replay_soft_interrupts(void) } /* Book3E does not support soft-masking PMI interrupts */ - if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_PMI)) { + if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_PMI)) { local_paca->irq_happened &= ~PACA_IRQ_PMI; regs.trap = 0xf00; performance_monitor_exception(®s); @@ -253,8 +258,7 @@ void replay_soft_interrupts(void) hard_irq_disable(); } - happened = local_paca->irq_happened; - if (happened & ~PACA_IRQ_HARD_DIS) { + if (local_paca->irq_happened & ~PACA_IRQ_HARD_DIS) { /* * We are responding to the next interrupt, so interrupt-off * latencies should be reset here. -- GitLab From 9d5c8190683a462dbc787658467a0da17011ea5f Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sun, 24 Jan 2021 15:08:14 +0000 Subject: [PATCH 0555/1084] io_uring: fix sleeping under spin in __io_clean_op [ 27.629441] BUG: sleeping function called from invalid context at fs/file.c:402 [ 27.631317] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 1012, name: io_wqe_worker-0 [ 27.633220] 1 lock held by io_wqe_worker-0/1012: [ 27.634286] #0: ffff888105e26c98 (&ctx->completion_lock) {....}-{2:2}, at: __io_req_complete.part.102+0x30/0x70 [ 27.649249] Call Trace: [ 27.649874] dump_stack+0xac/0xe3 [ 27.650666] ___might_sleep+0x284/0x2c0 [ 27.651566] put_files_struct+0xb8/0x120 [ 27.652481] __io_clean_op+0x10c/0x2a0 [ 27.653362] __io_cqring_fill_event+0x2c1/0x350 [ 27.654399] __io_req_complete.part.102+0x41/0x70 [ 27.655464] io_openat2+0x151/0x300 [ 27.656297] io_issue_sqe+0x6c/0x14e0 [ 27.660991] io_wq_submit_work+0x7f/0x240 [ 27.662890] io_worker_handle_work+0x501/0x8a0 [ 27.664836] io_wqe_worker+0x158/0x520 [ 27.667726] kthread+0x134/0x180 [ 27.669641] ret_from_fork+0x1f/0x30 Instead of cleaning files on overflow, return back overflow cancellation into io_uring_cancel_files(). Previously it was racy to clean REQ_F_OVERFLOW flag, but we got rid of it, and can do it through repetitive attempts targeting all matching requests. Reported-by: Abaci Reported-by: Joseph Qi Cc: Xiaoguang Wang Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 862113a9364f8..8a98afed50cd9 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1025,6 +1025,7 @@ static ssize_t io_import_iovec(int rw, struct io_kiocb *req, static int io_setup_async_rw(struct io_kiocb *req, const struct iovec *iovec, const struct iovec *fast_iov, struct iov_iter *iter, bool force); +static void io_req_drop_files(struct io_kiocb *req); static struct kmem_cache *req_cachep; @@ -1048,8 +1049,7 @@ EXPORT_SYMBOL(io_uring_get_socket); static inline void io_clean_op(struct io_kiocb *req) { - if (req->flags & (REQ_F_NEED_CLEANUP | REQ_F_BUFFER_SELECTED | - REQ_F_INFLIGHT)) + if (req->flags & (REQ_F_NEED_CLEANUP | REQ_F_BUFFER_SELECTED)) __io_clean_op(req); } @@ -1394,6 +1394,8 @@ static void io_req_clean_work(struct io_kiocb *req) free_fs_struct(fs); req->work.flags &= ~IO_WQ_WORK_FS; } + if (req->flags & REQ_F_INFLIGHT) + io_req_drop_files(req); io_put_identity(req->task->io_uring, req); } @@ -6230,9 +6232,6 @@ static void __io_clean_op(struct io_kiocb *req) } req->flags &= ~REQ_F_NEED_CLEANUP; } - - if (req->flags & REQ_F_INFLIGHT) - io_req_drop_files(req); } static int io_issue_sqe(struct io_kiocb *req, bool force_nonblock, @@ -8879,6 +8878,7 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx, io_wq_cancel_cb(ctx->io_wq, io_cancel_task_cb, &cancel, true); io_poll_remove_all(ctx, task, files); io_kill_timeouts(ctx, task, files); + io_cqring_overflow_flush(ctx, true, task, files); /* cancellations _may_ trigger task work */ io_run_task_work(); schedule(); -- GitLab From 02a13674fa0e8dd326de8b9f4514b41b03d99003 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 23 Jan 2021 15:49:31 -0700 Subject: [PATCH 0556/1084] io_uring: account io_uring internal files as REQ_F_INFLIGHT We need to actively cancel anything that introduces a potential circular loop, where io_uring holds a reference to itself. If the file in question is an io_uring file, then add the request to the inflight list. Cc: stable@vger.kernel.org # 5.9+ Signed-off-by: Jens Axboe --- fs/io_uring.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 8a98afed50cd9..c07913ec0ccac 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1075,8 +1075,11 @@ static bool io_match_task(struct io_kiocb *head, return true; io_for_each_link(req, head) { - if ((req->flags & REQ_F_WORK_INITIALIZED) && - (req->work.flags & IO_WQ_WORK_FILES) && + if (!(req->flags & REQ_F_WORK_INITIALIZED)) + continue; + if (req->file && req->file->f_op == &io_uring_fops) + return true; + if ((req->work.flags & IO_WQ_WORK_FILES) && req->work.identity->files == files) return true; } @@ -1505,11 +1508,14 @@ static bool io_grab_identity(struct io_kiocb *req) return false; atomic_inc(&id->files->count); get_nsproxy(id->nsproxy); - req->flags |= REQ_F_INFLIGHT; - spin_lock_irq(&ctx->inflight_lock); - list_add(&req->inflight_entry, &ctx->inflight_list); - spin_unlock_irq(&ctx->inflight_lock); + if (!(req->flags & REQ_F_INFLIGHT)) { + req->flags |= REQ_F_INFLIGHT; + + spin_lock_irq(&ctx->inflight_lock); + list_add(&req->inflight_entry, &ctx->inflight_list); + spin_unlock_irq(&ctx->inflight_lock); + } req->work.flags |= IO_WQ_WORK_FILES; } if (!(req->work.flags & IO_WQ_WORK_MM) && @@ -6164,8 +6170,10 @@ static void io_req_drop_files(struct io_kiocb *req) struct io_uring_task *tctx = req->task->io_uring; unsigned long flags; - put_files_struct(req->work.identity->files); - put_nsproxy(req->work.identity->nsproxy); + if (req->work.flags & IO_WQ_WORK_FILES) { + put_files_struct(req->work.identity->files); + put_nsproxy(req->work.identity->nsproxy); + } spin_lock_irqsave(&ctx->inflight_lock, flags); list_del(&req->inflight_entry); spin_unlock_irqrestore(&ctx->inflight_lock, flags); @@ -6450,6 +6458,15 @@ static struct file *io_file_get(struct io_submit_state *state, file = __io_file_get(state, fd); } + if (file && file->f_op == &io_uring_fops) { + io_req_init_async(req); + req->flags |= REQ_F_INFLIGHT; + + spin_lock_irq(&ctx->inflight_lock); + list_add(&req->inflight_entry, &ctx->inflight_list); + spin_unlock_irq(&ctx->inflight_lock); + } + return file; } @@ -8860,8 +8877,7 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx, spin_lock_irq(&ctx->inflight_lock); list_for_each_entry(req, &ctx->inflight_list, inflight_entry) { - if (req->task != task || - req->work.identity->files != files) + if (!io_match_task(req, task, files)) continue; found = true; break; -- GitLab From bde9cfa3afe4324ec251e4af80ebf9b7afaf7afe Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Sat, 23 Jan 2021 21:00:57 -0800 Subject: [PATCH 0557/1084] x86/setup: don't remove E820_TYPE_RAM for pfn 0 Patch series "mm: fix initialization of struct page for holes in memory layout", v3. Commit 73a6e474cb37 ("mm: memmap_init: iterate over memblock regions rather that check each PFN") exposed several issues with the memory map initialization and these patches fix those issues. Initially there were crashes during compaction that Qian Cai reported back in April [1]. It seemed back then that the problem was fixed, but a few weeks ago Andrea Arcangeli hit the same bug [2] and there was an additional discussion at [3]. [1] https://lore.kernel.org/lkml/8C537EB7-85EE-4DCF-943E-3CC0ED0DF56D@lca.pw [2] https://lore.kernel.org/lkml/20201121194506.13464-1-aarcange@redhat.com [3] https://lore.kernel.org/mm-commits/20201206005401.qKuAVgOXr%akpm@linux-foundation.org This patch (of 2): The first 4Kb of memory is a BIOS owned area and to avoid its allocation for the kernel it was not listed in e820 tables as memory. As the result, pfn 0 was never recognised by the generic memory management and it is not a part of neither node 0 nor ZONE_DMA. If set_pfnblock_flags_mask() would be ever called for the pageblock corresponding to the first 2Mbytes of memory, having pfn 0 outside of ZONE_DMA would trigger VM_BUG_ON_PAGE(!zone_spans_pfn(page_zone(page), pfn), page); Along with reserving the first 4Kb in e820 tables, several first pages are reserved with memblock in several places during setup_arch(). These reservations are enough to ensure the kernel does not touch the BIOS area and it is not necessary to remove E820_TYPE_RAM for pfn 0. Remove the update of e820 table that changes the type of pfn 0 and move the comment describing why it was done to trim_low_memory_range() that reserves the beginning of the memory. Link: https://lkml.kernel.org/r/20210111194017.22696-2-rppt@kernel.org Signed-off-by: Mike Rapoport Cc: Baoquan He Cc: Borislav Petkov Cc: David Hildenbrand Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Mel Gorman Cc: Michal Hocko Cc: Qian Cai Cc: Thomas Gleixner Cc: Vlastimil Babka Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/kernel/setup.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 740f3bdb3f619..3412c4595efd8 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -660,17 +660,6 @@ static void __init trim_platform_memory_ranges(void) static void __init trim_bios_range(void) { - /* - * A special case is the first 4Kb of memory; - * This is a BIOS owned area, not kernel ram, but generally - * not listed as such in the E820 table. - * - * This typically reserves additional memory (64KiB by default) - * since some BIOSes are known to corrupt low memory. See the - * Kconfig help text for X86_RESERVE_LOW. - */ - e820__range_update(0, PAGE_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); - /* * special case: Some BIOSes report the PC BIOS * area (640Kb -> 1Mb) as RAM even though it is not. @@ -728,6 +717,15 @@ early_param("reservelow", parse_reservelow); static void __init trim_low_memory_range(void) { + /* + * A special case is the first 4Kb of memory; + * This is a BIOS owned area, not kernel ram, but generally + * not listed as such in the E820 table. + * + * This typically reserves additional memory (64KiB by default) + * since some BIOSes are known to corrupt low memory. See the + * Kconfig help text for X86_RESERVE_LOW. + */ memblock_reserve(0, ALIGN(reserve_low, PAGE_SIZE)); } -- GitLab From d3921cb8be29ce5668c64e23ffdaeec5f8c69399 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Sat, 23 Jan 2021 21:01:02 -0800 Subject: [PATCH 0558/1084] mm: fix initialization of struct page for holes in memory layout There could be struct pages that are not backed by actual physical memory. This can happen when the actual memory bank is not a multiple of SECTION_SIZE or when an architecture does not register memory holes reserved by the firmware as memblock.memory. Such pages are currently initialized using init_unavailable_mem() function that iterates through PFNs in holes in memblock.memory and if there is a struct page corresponding to a PFN, the fields if this page are set to default values and the page is marked as Reserved. init_unavailable_mem() does not take into account zone and node the page belongs to and sets both zone and node links in struct page to zero. On a system that has firmware reserved holes in a zone above ZONE_DMA, for instance in a configuration below: # grep -A1 E820 /proc/iomem 7a17b000-7a216fff : Unknown E820 type 7a217000-7bffffff : System RAM unset zone link in struct page will trigger VM_BUG_ON_PAGE(!zone_spans_pfn(page_zone(page), pfn), page); because there are pages in both ZONE_DMA32 and ZONE_DMA (unset zone link in struct page) in the same pageblock. Update init_unavailable_mem() to use zone constraints defined by an architecture to properly setup the zone link and use node ID of the adjacent range in memblock.memory to set the node link. Link: https://lkml.kernel.org/r/20210111194017.22696-3-rppt@kernel.org Fixes: 73a6e474cb37 ("mm: memmap_init: iterate over memblock regions rather that check each PFN") Signed-off-by: Mike Rapoport Reported-by: Andrea Arcangeli Cc: Andrea Arcangeli Cc: Baoquan He Cc: Borislav Petkov Cc: David Hildenbrand Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Mel Gorman Cc: Michal Hocko Cc: Qian Cai Cc: Thomas Gleixner Cc: Vlastimil Babka Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 84 +++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 027f6481ba59b..85ecaa6d0d064 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -7078,23 +7078,26 @@ void __init free_area_init_memoryless_node(int nid) * Initialize all valid struct pages in the range [spfn, epfn) and mark them * PageReserved(). Return the number of struct pages that were initialized. */ -static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn) +static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn, + int zone, int nid) { - unsigned long pfn; + unsigned long pfn, zone_spfn, zone_epfn; u64 pgcnt = 0; + zone_spfn = arch_zone_lowest_possible_pfn[zone]; + zone_epfn = arch_zone_highest_possible_pfn[zone]; + + spfn = clamp(spfn, zone_spfn, zone_epfn); + epfn = clamp(epfn, zone_spfn, zone_epfn); + for (pfn = spfn; pfn < epfn; pfn++) { if (!pfn_valid(ALIGN_DOWN(pfn, pageblock_nr_pages))) { pfn = ALIGN_DOWN(pfn, pageblock_nr_pages) + pageblock_nr_pages - 1; continue; } - /* - * Use a fake node/zone (0) for now. Some of these pages - * (in memblock.reserved but not in memblock.memory) will - * get re-initialized via reserve_bootmem_region() later. - */ - __init_single_page(pfn_to_page(pfn), pfn, 0, 0); + + __init_single_page(pfn_to_page(pfn), pfn, zone, nid); __SetPageReserved(pfn_to_page(pfn)); pgcnt++; } @@ -7103,51 +7106,64 @@ static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn) } /* - * Only struct pages that are backed by physical memory are zeroed and - * initialized by going through __init_single_page(). But, there are some - * struct pages which are reserved in memblock allocator and their fields - * may be accessed (for example page_to_pfn() on some configuration accesses - * flags). We must explicitly initialize those struct pages. + * Only struct pages that correspond to ranges defined by memblock.memory + * are zeroed and initialized by going through __init_single_page() during + * memmap_init(). + * + * But, there could be struct pages that correspond to holes in + * memblock.memory. This can happen because of the following reasons: + * - phyiscal memory bank size is not necessarily the exact multiple of the + * arbitrary section size + * - early reserved memory may not be listed in memblock.memory + * - memory layouts defined with memmap= kernel parameter may not align + * nicely with memmap sections * - * This function also addresses a similar issue where struct pages are left - * uninitialized because the physical address range is not covered by - * memblock.memory or memblock.reserved. That could happen when memblock - * layout is manually configured via memmap=, or when the highest physical - * address (max_pfn) does not end on a section boundary. + * Explicitly initialize those struct pages so that: + * - PG_Reserved is set + * - zone link is set accorging to the architecture constrains + * - node is set to node id of the next populated region except for the + * trailing hole where last node id is used */ -static void __init init_unavailable_mem(void) +static void __init init_zone_unavailable_mem(int zone) { - phys_addr_t start, end; - u64 i, pgcnt; - phys_addr_t next = 0; + unsigned long start, end; + int i, nid; + u64 pgcnt; + unsigned long next = 0; /* - * Loop through unavailable ranges not covered by memblock.memory. + * Loop through holes in memblock.memory and initialize struct + * pages corresponding to these holes */ pgcnt = 0; - for_each_mem_range(i, &start, &end) { + for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, &nid) { if (next < start) - pgcnt += init_unavailable_range(PFN_DOWN(next), - PFN_UP(start)); + pgcnt += init_unavailable_range(next, start, zone, nid); next = end; } /* - * Early sections always have a fully populated memmap for the whole - * section - see pfn_valid(). If the last section has holes at the - * end and that section is marked "online", the memmap will be - * considered initialized. Make sure that memmap has a well defined - * state. + * Last section may surpass the actual end of memory (e.g. we can + * have 1Gb section and 512Mb of RAM pouplated). + * Make sure that memmap has a well defined state in this case. */ - pgcnt += init_unavailable_range(PFN_DOWN(next), - round_up(max_pfn, PAGES_PER_SECTION)); + end = round_up(max_pfn, PAGES_PER_SECTION); + pgcnt += init_unavailable_range(next, end, zone, nid); /* * Struct pages that do not have backing memory. This could be because * firmware is using some of this memory, or for some other reasons. */ if (pgcnt) - pr_info("Zeroed struct page in unavailable ranges: %lld pages", pgcnt); + pr_info("Zone %s: zeroed struct page in unavailable ranges: %lld pages", zone_names[zone], pgcnt); +} + +static void __init init_unavailable_mem(void) +{ + int zone; + + for (zone = 0; zone < ZONE_MOVABLE; zone++) + init_zone_unavailable_mem(zone); } #else static inline void __init init_unavailable_mem(void) -- GitLab From 3de7d4f25a7438f09fef4e71ef111f1805cd8e7c Mon Sep 17 00:00:00 2001 From: Roman Gushchin Date: Sat, 23 Jan 2021 21:01:07 -0800 Subject: [PATCH 0559/1084] mm: memcg/slab: optimize objcg stock draining MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Imran Khan reported a 16% regression in hackbench results caused by the commit f2fe7b09a52b ("mm: memcg/slab: charge individual slab objects instead of pages"). The regression is noticeable in the case of a consequent allocation of several relatively large slab objects, e.g. skb's. As soon as the amount of stocked bytes exceeds PAGE_SIZE, drain_obj_stock() and __memcg_kmem_uncharge() are called, and it leads to a number of atomic operations in page_counter_uncharge(). The corresponding call graph is below (provided by Imran Khan): |__alloc_skb | | | |__kmalloc_reserve.isra.61 | | | | | |__kmalloc_node_track_caller | | | | | | | |slab_pre_alloc_hook.constprop.88 | | | obj_cgroup_charge | | | | | | | | | |__memcg_kmem_charge | | | | | | | | | | | |page_counter_try_charge | | | | | | | | | |refill_obj_stock | | | | | | | | | | | |drain_obj_stock.isra.68 | | | | | | | | | | | | | |__memcg_kmem_uncharge | | | | | | | | | | | | | | | |page_counter_uncharge | | | | | | | | | | | | | | | | | |page_counter_cancel | | | | | | | | | | | |__slab_alloc | | | | | | | | | |___slab_alloc | | | | | | | | |slab_post_alloc_hook Instead of directly uncharging the accounted kernel memory, it's possible to refill the generic page-sized per-cpu stock instead. It's a much faster operation, especially on a default hierarchy. As a bonus, __memcg_kmem_uncharge_page() will also get faster, so the freeing of page-sized kernel allocations (e.g. large kmallocs) will become faster. A similar change has been done earlier for the socket memory by the commit 475d0487a2ad ("mm: memcontrol: use per-cpu stocks for socket memory uncharging"). Link: https://lkml.kernel.org/r/20210106042239.2860107-1-guro@fb.com Fixes: f2fe7b09a52b ("mm: memcg/slab: charge individual slab objects instead of pages") Signed-off-by: Roman Gushchin Reported-by: Imran Khan Tested-by: Imran Khan Reviewed-by: Shakeel Butt Reviewed-by: Michal Koutn Cc: Michal Koutný Cc: Johannes Weiner Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 605f671203efb..e2de77b5bcc2f 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3115,9 +3115,7 @@ void __memcg_kmem_uncharge(struct mem_cgroup *memcg, unsigned int nr_pages) if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) page_counter_uncharge(&memcg->kmem, nr_pages); - page_counter_uncharge(&memcg->memory, nr_pages); - if (do_memsw_account()) - page_counter_uncharge(&memcg->memsw, nr_pages); + refill_stock(memcg, nr_pages); } /** -- GitLab From 8a8792f600abacd7e1b9bb667759dca1c153f64c Mon Sep 17 00:00:00 2001 From: Shakeel Butt Date: Sat, 23 Jan 2021 21:01:11 -0800 Subject: [PATCH 0560/1084] mm: memcg: fix memcg file_dirty numa stat The kernel updates the per-node NR_FILE_DIRTY stats on page migration but not the memcg numa stats. That was not an issue until recently the commit 5f9a4f4a7096 ("mm: memcontrol: add the missing numa_stat interface for cgroup v2") exposed numa stats for the memcg. So fix the file_dirty per-memcg numa stat. Link: https://lkml.kernel.org/r/20210108155813.2914586-1-shakeelb@google.com Fixes: 5f9a4f4a7096 ("mm: memcontrol: add the missing numa_stat interface for cgroup v2") Signed-off-by: Shakeel Butt Reviewed-by: Muchun Song Acked-by: Yang Shi Reviewed-by: Roman Gushchin Cc: Johannes Weiner Cc: Michal Hocko Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/migrate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index ee5e612b4cd87..613794f6a4335 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -500,9 +500,9 @@ int migrate_page_move_mapping(struct address_space *mapping, __inc_lruvec_state(new_lruvec, NR_SHMEM); } if (dirty && mapping_can_writeback(mapping)) { - __dec_node_state(oldzone->zone_pgdat, NR_FILE_DIRTY); + __dec_lruvec_state(old_lruvec, NR_FILE_DIRTY); __dec_zone_state(oldzone, NR_ZONE_WRITE_PENDING); - __inc_node_state(newzone->zone_pgdat, NR_FILE_DIRTY); + __inc_lruvec_state(new_lruvec, NR_FILE_DIRTY); __inc_zone_state(newzone, NR_ZONE_WRITE_PENDING); } } -- GitLab From 5c447d274f3746fbed6e695e7b9a2d7bd8b31b71 Mon Sep 17 00:00:00 2001 From: Shakeel Butt Date: Sat, 23 Jan 2021 21:01:15 -0800 Subject: [PATCH 0561/1084] mm: fix numa stats for thp migration Currently the kernel is not correctly updating the numa stats for NR_FILE_PAGES and NR_SHMEM on THP migration. Fix that. For NR_FILE_DIRTY and NR_ZONE_WRITE_PENDING, although at the moment there is no need to handle THP migration as kernel still does not have write support for file THP but to be more future proof, this patch adds the THP support for those stats as well. Link: https://lkml.kernel.org/r/20210108155813.2914586-2-shakeelb@google.com Fixes: e71769ae52609 ("mm: enable thp migration for shmem thp") Signed-off-by: Shakeel Butt Acked-by: Yang Shi Reviewed-by: Roman Gushchin Cc: Johannes Weiner Cc: Michal Hocko Cc: Muchun Song Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/migrate.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index 613794f6a4335..c0efe921bca5c 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -402,6 +402,7 @@ int migrate_page_move_mapping(struct address_space *mapping, struct zone *oldzone, *newzone; int dirty; int expected_count = expected_page_refs(mapping, page) + extra_count; + int nr = thp_nr_pages(page); if (!mapping) { /* Anonymous page without mapping */ @@ -437,7 +438,7 @@ int migrate_page_move_mapping(struct address_space *mapping, */ newpage->index = page->index; newpage->mapping = page->mapping; - page_ref_add(newpage, thp_nr_pages(page)); /* add cache reference */ + page_ref_add(newpage, nr); /* add cache reference */ if (PageSwapBacked(page)) { __SetPageSwapBacked(newpage); if (PageSwapCache(page)) { @@ -459,7 +460,7 @@ int migrate_page_move_mapping(struct address_space *mapping, if (PageTransHuge(page)) { int i; - for (i = 1; i < HPAGE_PMD_NR; i++) { + for (i = 1; i < nr; i++) { xas_next(&xas); xas_store(&xas, newpage); } @@ -470,7 +471,7 @@ int migrate_page_move_mapping(struct address_space *mapping, * to one less reference. * We know this isn't the last reference. */ - page_ref_unfreeze(page, expected_count - thp_nr_pages(page)); + page_ref_unfreeze(page, expected_count - nr); xas_unlock(&xas); /* Leave irq disabled to prevent preemption while updating stats */ @@ -493,17 +494,17 @@ int migrate_page_move_mapping(struct address_space *mapping, old_lruvec = mem_cgroup_lruvec(memcg, oldzone->zone_pgdat); new_lruvec = mem_cgroup_lruvec(memcg, newzone->zone_pgdat); - __dec_lruvec_state(old_lruvec, NR_FILE_PAGES); - __inc_lruvec_state(new_lruvec, NR_FILE_PAGES); + __mod_lruvec_state(old_lruvec, NR_FILE_PAGES, -nr); + __mod_lruvec_state(new_lruvec, NR_FILE_PAGES, nr); if (PageSwapBacked(page) && !PageSwapCache(page)) { - __dec_lruvec_state(old_lruvec, NR_SHMEM); - __inc_lruvec_state(new_lruvec, NR_SHMEM); + __mod_lruvec_state(old_lruvec, NR_SHMEM, -nr); + __mod_lruvec_state(new_lruvec, NR_SHMEM, nr); } if (dirty && mapping_can_writeback(mapping)) { - __dec_lruvec_state(old_lruvec, NR_FILE_DIRTY); - __dec_zone_state(oldzone, NR_ZONE_WRITE_PENDING); - __inc_lruvec_state(new_lruvec, NR_FILE_DIRTY); - __inc_zone_state(newzone, NR_ZONE_WRITE_PENDING); + __mod_lruvec_state(old_lruvec, NR_FILE_DIRTY, -nr); + __mod_zone_page_state(oldzone, NR_ZONE_WRITE_PENDING, -nr); + __mod_lruvec_state(new_lruvec, NR_FILE_DIRTY, nr); + __mod_zone_page_state(newzone, NR_ZONE_WRITE_PENDING, nr); } } local_irq_enable(); -- GitLab From a11a496ee6e2ab6ed850233c96b94caf042af0b9 Mon Sep 17 00:00:00 2001 From: Lecopzer Chen Date: Sat, 23 Jan 2021 21:01:25 -0800 Subject: [PATCH 0562/1084] kasan: fix unaligned address is unhandled in kasan_remove_zero_shadow During testing kasan_populate_early_shadow and kasan_remove_zero_shadow, if the shadow start and end address in kasan_remove_zero_shadow() is not aligned to PMD_SIZE, the remain unaligned PTE won't be removed. In the test case for kasan_remove_zero_shadow(): shadow_start: 0xffffffb802000000, shadow end: 0xffffffbfbe000000 3-level page table: PUD_SIZE: 0x40000000 PMD_SIZE: 0x200000 PAGE_SIZE: 4K 0xffffffbf80000000 ~ 0xffffffbfbdf80000 will not be removed because in kasan_remove_pud_table(), kasan_pmd_table(*pud) is true but the next address is 0xffffffbfbdf80000 which is not aligned to PUD_SIZE. In the correct condition, this should fallback to the next level kasan_remove_pmd_table() but the condition flow always continue to skip the unaligned part. Fix by correcting the condition when next and addr are neither aligned. Link: https://lkml.kernel.org/r/20210103135621.83129-1-lecopzer@gmail.com Fixes: 0207df4fa1a86 ("kernel/memremap, kasan: make ZONE_DEVICE with work with KASAN") Signed-off-by: Lecopzer Chen Cc: Andrey Ryabinin Cc: Dan Williams Cc: Dmitry Vyukov Cc: Alexander Potapenko Cc: YJ Chiang Cc: Andrey Konovalov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/kasan/init.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mm/kasan/init.c b/mm/kasan/init.c index 7ca0b92d5886d..91049c1b8994c 100644 --- a/mm/kasan/init.c +++ b/mm/kasan/init.c @@ -373,9 +373,10 @@ static void kasan_remove_pmd_table(pmd_t *pmd, unsigned long addr, if (kasan_pte_table(*pmd)) { if (IS_ALIGNED(addr, PMD_SIZE) && - IS_ALIGNED(next, PMD_SIZE)) + IS_ALIGNED(next, PMD_SIZE)) { pmd_clear(pmd); - continue; + continue; + } } pte = pte_offset_kernel(pmd, addr); kasan_remove_pte_table(pte, addr, next); @@ -398,9 +399,10 @@ static void kasan_remove_pud_table(pud_t *pud, unsigned long addr, if (kasan_pmd_table(*pud)) { if (IS_ALIGNED(addr, PUD_SIZE) && - IS_ALIGNED(next, PUD_SIZE)) + IS_ALIGNED(next, PUD_SIZE)) { pud_clear(pud); - continue; + continue; + } } pmd = pmd_offset(pud, addr); pmd_base = pmd_offset(pud, 0); @@ -424,9 +426,10 @@ static void kasan_remove_p4d_table(p4d_t *p4d, unsigned long addr, if (kasan_pud_table(*p4d)) { if (IS_ALIGNED(addr, P4D_SIZE) && - IS_ALIGNED(next, P4D_SIZE)) + IS_ALIGNED(next, P4D_SIZE)) { p4d_clear(p4d); - continue; + continue; + } } pud = pud_offset(p4d, addr); kasan_remove_pud_table(pud, addr, next); @@ -457,9 +460,10 @@ void kasan_remove_zero_shadow(void *start, unsigned long size) if (kasan_p4d_table(*pgd)) { if (IS_ALIGNED(addr, PGDIR_SIZE) && - IS_ALIGNED(next, PGDIR_SIZE)) + IS_ALIGNED(next, PGDIR_SIZE)) { pgd_clear(pgd); - continue; + continue; + } } p4d = p4d_offset(pgd, addr); -- GitLab From 5dabd1712cd056814f9ab15f1d68157ceb04e741 Mon Sep 17 00:00:00 2001 From: Lecopzer Chen Date: Sat, 23 Jan 2021 21:01:29 -0800 Subject: [PATCH 0563/1084] kasan: fix incorrect arguments passing in kasan_add_zero_shadow kasan_remove_zero_shadow() shall use original virtual address, start and size, instead of shadow address. Link: https://lkml.kernel.org/r/20210103063847.5963-1-lecopzer@gmail.com Fixes: 0207df4fa1a86 ("kernel/memremap, kasan: make ZONE_DEVICE with work with KASAN") Signed-off-by: Lecopzer Chen Reviewed-by: Andrey Konovalov Cc: Andrey Ryabinin Cc: Dan Williams Cc: Dmitry Vyukov Cc: Alexander Potapenko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/kasan/init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mm/kasan/init.c b/mm/kasan/init.c index 91049c1b8994c..c4605ac9837b0 100644 --- a/mm/kasan/init.c +++ b/mm/kasan/init.c @@ -486,7 +486,6 @@ int kasan_add_zero_shadow(void *start, unsigned long size) ret = kasan_populate_early_shadow(shadow_start, shadow_end); if (ret) - kasan_remove_zero_shadow(shadow_start, - size >> KASAN_SHADOW_SCALE_SHIFT); + kasan_remove_zero_shadow(start, size); return ret; } -- GitLab From 76bc99e81a7cb78a78e058107e4b5b1d8ed3c874 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Sat, 23 Jan 2021 21:01:34 -0800 Subject: [PATCH 0564/1084] kasan: fix HW_TAGS boot parameters The initially proposed KASAN command line parameters are redundant. This change drops the complex "kasan.mode=off/prod/full" parameter and adds a simpler kill switch "kasan=off/on" instead. The new parameter together with the already existing ones provides a cleaner way to express the same set of features. The full set of parameters with this change: kasan=off/on - whether KASAN is enabled kasan.fault=report/panic - whether to only print a report or also panic kasan.stacktrace=off/on - whether to collect alloc/free stack traces Default values: kasan=on kasan.fault=report kasan.stacktrace=on (if CONFIG_DEBUG_KERNEL=y) kasan.stacktrace=off (otherwise) Link: https://linux-review.googlesource.com/id/Ib3694ed90b1e8ccac6cf77dfd301847af4aba7b8 Link: https://lkml.kernel.org/r/4e9c4a4bdcadc168317deb2419144582a9be6e61.1610736745.git.andreyknvl@google.com Signed-off-by: Andrey Konovalov Reviewed-by: Vincenzo Frascino Reviewed-by: Marco Elver Cc: Dmitry Vyukov Cc: Alexander Potapenko Cc: Catalin Marinas Cc: Will Deacon Cc: Andrey Ryabinin Cc: Peter Collingbourne Cc: Evgenii Stepanov Cc: Branislav Rankov Cc: Kevin Brodsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/dev-tools/kasan.rst | 27 +++-------- mm/kasan/hw_tags.c | 77 +++++++++++++------------------ 2 files changed, 38 insertions(+), 66 deletions(-) diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst index 0fc3fb1860c4a..1651d961f06a6 100644 --- a/Documentation/dev-tools/kasan.rst +++ b/Documentation/dev-tools/kasan.rst @@ -160,29 +160,14 @@ intended for use in production as a security mitigation. Therefore it supports boot parameters that allow to disable KASAN competely or otherwise control particular KASAN features. -The things that can be controlled are: +- ``kasan=off`` or ``=on`` controls whether KASAN is enabled (default: ``on``). -1. Whether KASAN is enabled at all. -2. Whether KASAN collects and saves alloc/free stacks. -3. Whether KASAN panics on a detected bug or not. +- ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack + traces collection (default: ``on`` for ``CONFIG_DEBUG_KERNEL=y``, otherwise + ``off``). -The ``kasan.mode`` boot parameter allows to choose one of three main modes: - -- ``kasan.mode=off`` - KASAN is disabled, no tag checks are performed -- ``kasan.mode=prod`` - only essential production features are enabled -- ``kasan.mode=full`` - all KASAN features are enabled - -The chosen mode provides default control values for the features mentioned -above. However it's also possible to override the default values by providing: - -- ``kasan.stacktrace=off`` or ``=on`` - enable alloc/free stack collection - (default: ``on`` for ``mode=full``, - otherwise ``off``) -- ``kasan.fault=report`` or ``=panic`` - only print KASAN report or also panic - (default: ``report``) - -If ``kasan.mode`` parameter is not provided, it defaults to ``full`` when -``CONFIG_DEBUG_KERNEL`` is enabled, and to ``prod`` otherwise. +- ``kasan.fault=report`` or ``=panic`` controls whether to only print a KASAN + report or also panic the kernel (default: ``report``). For developers ~~~~~~~~~~~~~~ diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c index 55bd6f09c70ff..e529428e7a111 100644 --- a/mm/kasan/hw_tags.c +++ b/mm/kasan/hw_tags.c @@ -19,11 +19,10 @@ #include "kasan.h" -enum kasan_arg_mode { - KASAN_ARG_MODE_DEFAULT, - KASAN_ARG_MODE_OFF, - KASAN_ARG_MODE_PROD, - KASAN_ARG_MODE_FULL, +enum kasan_arg { + KASAN_ARG_DEFAULT, + KASAN_ARG_OFF, + KASAN_ARG_ON, }; enum kasan_arg_stacktrace { @@ -38,7 +37,7 @@ enum kasan_arg_fault { KASAN_ARG_FAULT_PANIC, }; -static enum kasan_arg_mode kasan_arg_mode __ro_after_init; +static enum kasan_arg kasan_arg __ro_after_init; static enum kasan_arg_stacktrace kasan_arg_stacktrace __ro_after_init; static enum kasan_arg_fault kasan_arg_fault __ro_after_init; @@ -52,26 +51,24 @@ DEFINE_STATIC_KEY_FALSE(kasan_flag_stacktrace); /* Whether panic or disable tag checking on fault. */ bool kasan_flag_panic __ro_after_init; -/* kasan.mode=off/prod/full */ -static int __init early_kasan_mode(char *arg) +/* kasan=off/on */ +static int __init early_kasan_flag(char *arg) { if (!arg) return -EINVAL; if (!strcmp(arg, "off")) - kasan_arg_mode = KASAN_ARG_MODE_OFF; - else if (!strcmp(arg, "prod")) - kasan_arg_mode = KASAN_ARG_MODE_PROD; - else if (!strcmp(arg, "full")) - kasan_arg_mode = KASAN_ARG_MODE_FULL; + kasan_arg = KASAN_ARG_OFF; + else if (!strcmp(arg, "on")) + kasan_arg = KASAN_ARG_ON; else return -EINVAL; return 0; } -early_param("kasan.mode", early_kasan_mode); +early_param("kasan", early_kasan_flag); -/* kasan.stack=off/on */ +/* kasan.stacktrace=off/on */ static int __init early_kasan_flag_stacktrace(char *arg) { if (!arg) @@ -113,8 +110,8 @@ void kasan_init_hw_tags_cpu(void) * as this function is only called for MTE-capable hardware. */ - /* If KASAN is disabled, do nothing. */ - if (kasan_arg_mode == KASAN_ARG_MODE_OFF) + /* If KASAN is disabled via command line, don't initialize it. */ + if (kasan_arg == KASAN_ARG_OFF) return; hw_init_tags(KASAN_TAG_MAX); @@ -124,43 +121,28 @@ void kasan_init_hw_tags_cpu(void) /* kasan_init_hw_tags() is called once on boot CPU. */ void __init kasan_init_hw_tags(void) { - /* If hardware doesn't support MTE, do nothing. */ + /* If hardware doesn't support MTE, don't initialize KASAN. */ if (!system_supports_mte()) return; - /* Choose KASAN mode if kasan boot parameter is not provided. */ - if (kasan_arg_mode == KASAN_ARG_MODE_DEFAULT) { - if (IS_ENABLED(CONFIG_DEBUG_KERNEL)) - kasan_arg_mode = KASAN_ARG_MODE_FULL; - else - kasan_arg_mode = KASAN_ARG_MODE_PROD; - } - - /* Preset parameter values based on the mode. */ - switch (kasan_arg_mode) { - case KASAN_ARG_MODE_DEFAULT: - /* Shouldn't happen as per the check above. */ - WARN_ON(1); - return; - case KASAN_ARG_MODE_OFF: - /* If KASAN is disabled, do nothing. */ + /* If KASAN is disabled via command line, don't initialize it. */ + if (kasan_arg == KASAN_ARG_OFF) return; - case KASAN_ARG_MODE_PROD: - static_branch_enable(&kasan_flag_enabled); - break; - case KASAN_ARG_MODE_FULL: - static_branch_enable(&kasan_flag_enabled); - static_branch_enable(&kasan_flag_stacktrace); - break; - } - /* Now, optionally override the presets. */ + /* Enable KASAN. */ + static_branch_enable(&kasan_flag_enabled); switch (kasan_arg_stacktrace) { case KASAN_ARG_STACKTRACE_DEFAULT: + /* + * Default to enabling stack trace collection for + * debug kernels. + */ + if (IS_ENABLED(CONFIG_DEBUG_KERNEL)) + static_branch_enable(&kasan_flag_stacktrace); break; case KASAN_ARG_STACKTRACE_OFF: - static_branch_disable(&kasan_flag_stacktrace); + /* Do nothing, kasan_flag_stacktrace keeps its default value. */ break; case KASAN_ARG_STACKTRACE_ON: static_branch_enable(&kasan_flag_stacktrace); @@ -169,11 +151,16 @@ void __init kasan_init_hw_tags(void) switch (kasan_arg_fault) { case KASAN_ARG_FAULT_DEFAULT: + /* + * Default to no panic on report. + * Do nothing, kasan_flag_panic keeps its default value. + */ break; case KASAN_ARG_FAULT_REPORT: - kasan_flag_panic = false; + /* Do nothing, kasan_flag_panic keeps its default value. */ break; case KASAN_ARG_FAULT_PANIC: + /* Enable panic on report. */ kasan_flag_panic = true; break; } -- GitLab From ce5716c618524241a3cea821e18ee1e0d16f6c70 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Sat, 23 Jan 2021 21:01:38 -0800 Subject: [PATCH 0565/1084] kasan, mm: fix conflicts with init_on_alloc/free A few places where SLUB accesses object's data or metadata were missed in a previous patch. This leads to false positives with hardware tag-based KASAN when bulk allocations are used with init_on_alloc/free. Fix the false-positives by resetting pointer tags during these accesses. (The kasan_reset_tag call is removed from slab_alloc_node, as it's added into maybe_wipe_obj_freeptr.) Link: https://linux-review.googlesource.com/id/I50dd32838a666e173fe06c3c5c766f2c36aae901 Link: https://lkml.kernel.org/r/093428b5d2ca8b507f4a79f92f9929b35f7fada7.1610731872.git.andreyknvl@google.com Fixes: aa1ef4d7b3f67 ("kasan, mm: reset tags when accessing metadata") Signed-off-by: Andrey Konovalov Reported-by: Dmitry Vyukov Acked-by: Vlastimil Babka Cc: Catalin Marinas Cc: Vincenzo Frascino Cc: Alexander Potapenko Cc: Marco Elver Cc: Will Deacon Cc: Andrey Ryabinin Cc: Peter Collingbourne Cc: Evgenii Stepanov Cc: Branislav Rankov Cc: Kevin Brodsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slub.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index d9e4e10683cc1..69742ab9a21d3 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2791,7 +2791,8 @@ static __always_inline void maybe_wipe_obj_freeptr(struct kmem_cache *s, void *obj) { if (unlikely(slab_want_init_on_free(s)) && obj) - memset((void *)((char *)obj + s->offset), 0, sizeof(void *)); + memset((void *)((char *)kasan_reset_tag(obj) + s->offset), + 0, sizeof(void *)); } /* @@ -2883,7 +2884,7 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s, stat(s, ALLOC_FASTPATH); } - maybe_wipe_obj_freeptr(s, kasan_reset_tag(object)); + maybe_wipe_obj_freeptr(s, object); if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object) memset(kasan_reset_tag(object), 0, s->object_size); @@ -3329,7 +3330,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, int j; for (j = 0; j < i; j++) - memset(p[j], 0, s->object_size); + memset(kasan_reset_tag(p[j]), 0, s->object_size); } /* memcg and kmem_cache debug support */ -- GitLab From acb35b177c71d3d39b9a3b9ea213d926235066e3 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Sat, 23 Jan 2021 21:01:43 -0800 Subject: [PATCH 0566/1084] kasan, mm: fix resetting page_alloc tags for HW_TAGS A previous commit added resetting KASAN page tags to kernel_init_free_pages() to avoid false-positives due to accesses to metadata with the hardware tag-based mode. That commit did reset page tags before the metadata access, but didn't restore them after. As the result, KASAN fails to detect bad accesses to page_alloc allocations on some configurations. Fix this by recovering the tag after the metadata access. Link: https://lkml.kernel.org/r/02b5bcd692e912c27d484030f666b350ad7e4ae4.1611074450.git.andreyknvl@google.com Fixes: aa1ef4d7b3f6 ("kasan, mm: reset tags when accessing metadata") Signed-off-by: Andrey Konovalov Cc: Dmitry Vyukov Cc: Alexander Potapenko Cc: Marco Elver Cc: Catalin Marinas Cc: Will Deacon Cc: Vincenzo Frascino Cc: Andrey Ryabinin Cc: Peter Collingbourne Cc: Evgenii Stepanov Cc: Branislav Rankov Cc: Kevin Brodsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 85ecaa6d0d064..783913e41f65d 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1207,8 +1207,10 @@ static void kernel_init_free_pages(struct page *page, int numpages) /* s390's use of memset() could override KASAN redzones. */ kasan_disable_current(); for (i = 0; i < numpages; i++) { + u8 tag = page_kasan_tag(page + i); page_kasan_tag_reset(page + i); clear_highpage(page + i); + page_kasan_tag_set(page + i, tag); } kasan_enable_current(); } -- GitLab From 251b5497c5c95e4548e3d33cbda3f638fea2c11e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 23 Jan 2021 21:01:48 -0800 Subject: [PATCH 0567/1084] ubsan: disable unsigned-overflow check for i386 Building ubsan kernels even for compile-testing introduced these warnings in my randconfig environment: crypto/blake2b_generic.c:98:13: error: stack frame size of 9636 bytes in function 'blake2b_compress' [-Werror,-Wframe-larger-than=] static void blake2b_compress(struct blake2b_state *S, crypto/sha512_generic.c:151:13: error: stack frame size of 1292 bytes in function 'sha512_generic_block_fn' [-Werror,-Wframe-larger-than=] static void sha512_generic_block_fn(struct sha512_state *sst, u8 const *src, lib/crypto/curve25519-fiat32.c:312:22: error: stack frame size of 2180 bytes in function 'fe_mul_impl' [-Werror,-Wframe-larger-than=] static noinline void fe_mul_impl(u32 out[10], const u32 in1[10], const u32 in2[10]) lib/crypto/curve25519-fiat32.c:444:22: error: stack frame size of 1588 bytes in function 'fe_sqr_impl' [-Werror,-Wframe-larger-than=] static noinline void fe_sqr_impl(u32 out[10], const u32 in1[10]) Further testing showed that this is caused by -fsanitize=unsigned-integer-overflow, but is isolated to the 32-bit x86 architecture. The one in blake2b immediately overflows the 8KB stack area architectures, so better ensure this never happens by disabling the option for 32-bit x86. Link: https://lkml.kernel.org/r/20210112202922.2454435-1-arnd@kernel.org Link: https://lore.kernel.org/lkml/20201230154749.746641-1-arnd@kernel.org/ Fixes: d0a3ac549f38 ("ubsan: enable for all*config builds") Signed-off-by: Arnd Bergmann Acked-by: Kees Cook Reviewed-by: Nathan Chancellor Cc: Nick Desaulniers Cc: Stephen Rothwell Cc: Marco Elver Cc: George Popescu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/Kconfig.ubsan | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan index 8b635fd75fe41..3a0b1c930733a 100644 --- a/lib/Kconfig.ubsan +++ b/lib/Kconfig.ubsan @@ -123,6 +123,7 @@ config UBSAN_SIGNED_OVERFLOW config UBSAN_UNSIGNED_OVERFLOW bool "Perform checking for unsigned arithmetic overflow" depends on $(cc-option,-fsanitize=unsigned-integer-overflow) + depends on !X86_32 # avoid excessive stack usage on x86-32/clang help This option enables -fsanitize=unsigned-integer-overflow which checks for overflow of any arithmetic operations with unsigned integers. This -- GitLab From dad4e5b390866ca902653df0daa864ae4b8d4147 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 23 Jan 2021 21:01:52 -0800 Subject: [PATCH 0568/1084] mm: fix page reference leak in soft_offline_page() The conversion to move pfn_to_online_page() internal to soft_offline_page() missed that the get_user_pages() reference taken by the madvise() path needs to be dropped when pfn_to_online_page() fails. Note the direct sysfs-path to soft_offline_page() does not perform a get_user_pages() lookup. When soft_offline_page() is handed a pfn_valid() && !pfn_to_online_page() pfn the kernel hangs at dax-device shutdown due to a leaked reference. Link: https://lkml.kernel.org/r/161058501210.1840162.8108917599181157327.stgit@dwillia2-desk3.amr.corp.intel.com Fixes: feec24a6139d ("mm, soft-offline: convert parameter to pfn") Signed-off-by: Dan Williams Reviewed-by: David Hildenbrand Reviewed-by: Oscar Salvador Reviewed-by: Naoya Horiguchi Cc: Michal Hocko Cc: Qian Cai Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory-failure.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 04d9f154a130d..e9481632fcd1b 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1885,6 +1885,12 @@ static int soft_offline_free_page(struct page *page) return rc; } +static void put_ref_page(struct page *page) +{ + if (page) + put_page(page); +} + /** * soft_offline_page - Soft offline a page. * @pfn: pfn to soft-offline @@ -1910,20 +1916,26 @@ static int soft_offline_free_page(struct page *page) int soft_offline_page(unsigned long pfn, int flags) { int ret; - struct page *page; bool try_again = true; + struct page *page, *ref_page = NULL; + + WARN_ON_ONCE(!pfn_valid(pfn) && (flags & MF_COUNT_INCREASED)); if (!pfn_valid(pfn)) return -ENXIO; + if (flags & MF_COUNT_INCREASED) + ref_page = pfn_to_page(pfn); + /* Only online pages can be soft-offlined (esp., not ZONE_DEVICE). */ page = pfn_to_online_page(pfn); - if (!page) + if (!page) { + put_ref_page(ref_page); return -EIO; + } if (PageHWPoison(page)) { pr_info("%s: %#lx page already poisoned\n", __func__, pfn); - if (flags & MF_COUNT_INCREASED) - put_page(page); + put_ref_page(ref_page); return 0; } -- GitLab From f99e02372af2e7ee72a6da497712ec9152964347 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 23 Jan 2021 21:01:57 -0800 Subject: [PATCH 0569/1084] sparc/mm/highmem: flush cache and TLB Patch series "mm/highmem: Fix fallout from generic kmap_local conversions". The kmap_local conversion wreckaged sparc, mips and powerpc as it missed some of the details in the original implementation. This patch (of 4): The recent conversion to the generic kmap_local infrastructure failed to assign the proper pre/post map/unmap flush operations for sparc. Sparc requires cache flush before map/unmap and tlb flush afterwards. Link: https://lkml.kernel.org/r/20210112170136.078559026@linutronix.de Link: https://lkml.kernel.org/r/20210112170410.905976187@linutronix.de Fixes: 3293efa97807 ("sparc/mm/highmem: Switch to generic kmap atomic") Signed-off-by: Thomas Gleixner Reported-by: Andreas Larsson Cc: "David S. Miller" Cc: Peter Zijlstra Cc: Paul Cercueil Cc: Thomas Bogendoerfer Cc: Michael Ellerman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc/include/asm/highmem.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h index 875116209ec14..c7b2e208328b5 100644 --- a/arch/sparc/include/asm/highmem.h +++ b/arch/sparc/include/asm/highmem.h @@ -50,10 +50,11 @@ extern pte_t *pkmap_page_table; #define flush_cache_kmaps() flush_cache_all() -/* FIXME: Use __flush_tlb_one(vaddr) instead of flush_cache_all() -- Anton */ -#define arch_kmap_local_post_map(vaddr, pteval) flush_cache_all() -#define arch_kmap_local_post_unmap(vaddr) flush_cache_all() - +/* FIXME: Use __flush_*_one(vaddr) instead of flush_*_all() -- Anton */ +#define arch_kmap_local_pre_map(vaddr, pteval) flush_cache_all() +#define arch_kmap_local_pre_unmap(vaddr) flush_cache_all() +#define arch_kmap_local_post_map(vaddr, pteval) flush_tlb_all() +#define arch_kmap_local_post_unmap(vaddr) flush_tlb_all() #endif /* __KERNEL__ */ -- GitLab From a1dce7fd2ade8e71e5f95e58b99aa512607f52b0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 23 Jan 2021 21:02:02 -0800 Subject: [PATCH 0570/1084] mm/highmem: prepare for overriding set_pte_at() The generic kmap_local() map function uses set_pte_at(), but MIPS requires set_pte() and PowerPC wants __set_pte_at(). Provide arch_kmap_local_set_pte() and default it to set_pte_at(). Link: https://lkml.kernel.org/r/20210112170411.056306194@linutronix.de Signed-off-by: Thomas Gleixner Cc: Andreas Larsson Cc: "David S. Miller" Cc: Michael Ellerman Cc: Paul Cercueil Cc: Peter Zijlstra Cc: Thomas Bogendoerfer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/highmem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mm/highmem.c b/mm/highmem.c index c3a9ea7875ef8..874b732b120ce 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -473,6 +473,11 @@ static inline void *arch_kmap_local_high_get(struct page *page) } #endif +#ifndef arch_kmap_local_set_pte +#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) \ + set_pte_at(mm, vaddr, ptep, ptev) +#endif + /* Unmap a local mapping which was obtained by kmap_high_get() */ static inline bool kmap_high_unmap_local(unsigned long vaddr) { @@ -515,7 +520,7 @@ void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot) vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); BUG_ON(!pte_none(*(kmap_pte - idx))); pteval = pfn_pte(pfn, prot); - set_pte_at(&init_mm, vaddr, kmap_pte - idx, pteval); + arch_kmap_local_set_pte(&init_mm, vaddr, kmap_pte - idx, pteval); arch_kmap_local_post_map(vaddr, pteval); current->kmap_ctrl.pteval[kmap_local_idx()] = pteval; preempt_enable(); -- GitLab From 8c0d5d78f3596e203e9cd27563a8380649c03ad0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 23 Jan 2021 21:02:07 -0800 Subject: [PATCH 0571/1084] mips/mm/highmem: use set_pte() for kmap_local() set_pte_at() on MIPS invokes update_cache() which might recurse into kmap_local(). Use set_pte() like the original MIPS highmem implementation did. Link: https://lkml.kernel.org/r/20210112170411.187513575@linutronix.de Fixes: a4c33e83bca1 ("mips/mm/highmem: Switch to generic kmap atomic") Signed-off-by: Thomas Gleixner Reported-by: Paul Cercueil Reported-by: Thomas Bogendoerfer Acked-by: Thomas Bogendoerfer Cc: Andreas Larsson Cc: "David S. Miller" Cc: Michael Ellerman Cc: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/include/asm/highmem.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index 19edf8e699712..292d0425717f3 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h @@ -51,6 +51,7 @@ extern void kmap_flush_tlb(unsigned long addr); #define flush_cache_kmaps() BUG_ON(cpu_has_dc_aliases) +#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) set_pte(ptep, ptev) #define arch_kmap_local_post_map(vaddr, pteval) local_flush_tlb_one(vaddr) #define arch_kmap_local_post_unmap(vaddr) local_flush_tlb_one(vaddr) -- GitLab From 785025820a6a565185ce9d47fdd8d23dbf91dee8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 23 Jan 2021 21:02:11 -0800 Subject: [PATCH 0572/1084] powerpc/mm/highmem: use __set_pte_at() for kmap_local() The original PowerPC highmem mapping function used __set_pte_at() to denote that the mapping is per CPU. This got lost with the conversion to the generic implementation. Override the default map function. Link: https://lkml.kernel.org/r/20210112170411.281464308@linutronix.de Fixes: 47da42b27a56 ("powerpc/mm/highmem: Switch to generic kmap atomic") Signed-off-by: Thomas Gleixner Cc: Michael Ellerman Cc: Andreas Larsson Cc: "David S. Miller" Cc: Paul Cercueil Cc: Peter Zijlstra Cc: Thomas Bogendoerfer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/include/asm/highmem.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h index 80a5ae771c653..c0fcd1bbdba98 100644 --- a/arch/powerpc/include/asm/highmem.h +++ b/arch/powerpc/include/asm/highmem.h @@ -58,6 +58,8 @@ extern pte_t *pkmap_page_table; #define flush_cache_kmaps() flush_cache_all() +#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) \ + __set_pte_at(mm, vaddr, ptep, ptev, 1) #define arch_kmap_local_post_map(vaddr, pteval) \ local_flush_tlb_page(NULL, vaddr) #define arch_kmap_local_post_unmap(vaddr) \ -- GitLab From 697edcb0e4eadc41645fe88c991fe6a206b1a08d Mon Sep 17 00:00:00 2001 From: Xiaoming Ni Date: Sat, 23 Jan 2021 21:02:16 -0800 Subject: [PATCH 0573/1084] proc_sysctl: fix oops caused by incorrect command parameters The process_sysctl_arg() does not check whether val is empty before invoking strlen(val). If the command line parameter () is incorrectly configured and val is empty, oops is triggered. For example: "hung_task_panic=1" is incorrectly written as "hung_task_panic", oops is triggered. The call stack is as follows: Kernel command line: .... hung_task_panic ...... Call trace: __pi_strlen+0x10/0x98 parse_args+0x278/0x344 do_sysctl_args+0x8c/0xfc kernel_init+0x5c/0xf4 ret_from_fork+0x10/0x30 To fix it, check whether "val" is empty when "phram" is a sysctl field. Error codes are returned in the failure branch, and error logs are generated by parse_args(). Link: https://lkml.kernel.org/r/20210118133029.28580-1-nixiaoming@huawei.com Fixes: 3db978d480e2843 ("kernel/sysctl: support setting sysctl parameters from kernel command line") Signed-off-by: Xiaoming Ni Acked-by: Vlastimil Babka Cc: Luis Chamberlain Cc: Kees Cook Cc: Iurii Zaikin Cc: Alexey Dobriyan Cc: Michal Hocko Cc: Masami Hiramatsu Cc: Heiner Kallweit Cc: Randy Dunlap Cc: [5.8+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/proc_sysctl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 317899222d7fd..d2018f70d1fae 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -1770,6 +1770,12 @@ static int process_sysctl_arg(char *param, char *val, return 0; } + if (!val) + return -EINVAL; + len = strlen(val); + if (len == 0) + return -EINVAL; + /* * To set sysctl options, we use a temporary mount of proc, look up the * respective sys/ file and write to it. To avoid mounting it when no @@ -1811,7 +1817,6 @@ static int process_sysctl_arg(char *param, char *val, file, param, val); goto out; } - len = strlen(val); wret = kernel_write(file, val, len, &pos); if (wret < 0) { err = wret; -- GitLab From e82d891a63afebefde5d26971768f5cb91627f73 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Sat, 23 Jan 2021 21:02:21 -0800 Subject: [PATCH 0574/1084] MAINTAINERS: add a couple more files to the Clang/LLVM section The K: entry should ensure that Nick and I always get CC'd on patches that touch these files but it is better to be explicit rather than implicit. Link: https://lkml.kernel.org/r/20210114004059.2129921-1-natechancellor@gmail.com Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index f79ec98bbb291..91c6dee7850e9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4311,7 +4311,9 @@ W: https://clangbuiltlinux.github.io/ B: https://github.com/ClangBuiltLinux/linux/issues C: irc://chat.freenode.net/clangbuiltlinux F: Documentation/kbuild/llvm.rst +F: include/linux/compiler-clang.h F: scripts/clang-tools/ +F: scripts/clang-version.sh F: scripts/lld-version.sh K: \b(?i:clang|llvm)\b -- GitLab From 6ee1d745b7c9fd573fba142a2efdad76a9f1cb04 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 24 Jan 2021 16:47:14 -0800 Subject: [PATCH 0575/1084] Linux 5.11-rc5 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b0e4767735dca..e0af7a4a55985 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 11 SUBLEVEL = 0 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc5 NAME = Kleptomaniac Octopus # *DOCUMENTATION* -- GitLab From 84965ff8a84f0368b154c9b367b62e59c1193f30 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 23 Jan 2021 15:51:11 -0700 Subject: [PATCH 0576/1084] io_uring: if we see flush on exit, cancel related tasks Ensure we match tasks that belong to a dead or dying task as well, as we need to reap those in addition to those belonging to the exiting task. Cc: stable@vger.kernel.org # 5.9+ Reported-by: Josef Grieb Signed-off-by: Jens Axboe --- fs/io_uring.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index c07913ec0ccac..695fe00bafdcd 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1069,8 +1069,12 @@ static bool io_match_task(struct io_kiocb *head, { struct io_kiocb *req; - if (task && head->task != task) + if (task && head->task != task) { + /* in terms of cancelation, always match if req task is dead */ + if (head->task->flags & PF_EXITING) + return true; return false; + } if (!files) return true; @@ -9136,6 +9140,9 @@ static int io_uring_flush(struct file *file, void *data) struct io_uring_task *tctx = current->io_uring; struct io_ring_ctx *ctx = file->private_data; + if (fatal_signal_pending(current) || (current->flags & PF_EXITING)) + io_uring_cancel_task_requests(ctx, NULL); + if (!tctx) return 0; -- GitLab From b18032bb0a883cd7edd22a7fe6c57e1059b81ed0 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 24 Jan 2021 16:58:56 -0700 Subject: [PATCH 0577/1084] io_uring: only call io_cqring_ev_posted() if events were posted This normally doesn't cause any extra harm, but it does mean that we'll increment the eventfd notification count, if one has been registered with the ring. This can confuse applications, when they see more notifications on the eventfd side than are available in the ring. Do the nice thing and only increment this count, if we actually posted (or even overflowed) events. Reported-and-tested-by: Dan Melnic Signed-off-by: Jens Axboe --- fs/io_uring.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 695fe00bafdcd..2166c469789d5 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1779,12 +1779,13 @@ static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force, struct io_kiocb *req, *tmp; struct io_uring_cqe *cqe; unsigned long flags; - bool all_flushed; + bool all_flushed, posted; LIST_HEAD(list); if (!force && __io_cqring_events(ctx) == rings->cq_ring_entries) return false; + posted = false; spin_lock_irqsave(&ctx->completion_lock, flags); list_for_each_entry_safe(req, tmp, &ctx->cq_overflow_list, compl.list) { if (!io_match_task(req, tsk, files)) @@ -1804,6 +1805,7 @@ static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force, WRITE_ONCE(ctx->rings->cq_overflow, ctx->cached_cq_overflow); } + posted = true; } all_flushed = list_empty(&ctx->cq_overflow_list); @@ -1813,9 +1815,11 @@ static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force, ctx->rings->sq_flags &= ~IORING_SQ_CQ_OVERFLOW; } - io_commit_cqring(ctx); + if (posted) + io_commit_cqring(ctx); spin_unlock_irqrestore(&ctx->completion_lock, flags); - io_cqring_ev_posted(ctx); + if (posted) + io_cqring_ev_posted(ctx); while (!list_empty(&list)) { req = list_first_entry(&list, struct io_kiocb, compl.list); -- GitLab From 814b84971388cd5fb182f2e914265b3827758455 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 21 Jan 2021 16:34:37 -0500 Subject: [PATCH 0578/1084] pNFS/NFSv4: Fix a layout segment leak in pnfs_layout_process() If the server returns a new stateid that does not match the one in our cache, then pnfs_layout_process() will leak the layout segments returned by pnfs_mark_layout_stateid_invalid(). Fixes: 9888d837f3cf ("pNFS: Force a retry of LAYOUTGET if the stateid doesn't match our cache") Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 4f274f21c4abc..e68e6f8cb4079 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -2417,6 +2417,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) spin_unlock(&ino->i_lock); lseg->pls_layout = lo; NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg); + pnfs_free_lseg_list(&free_me); return ERR_PTR(-EAGAIN); } -- GitLab From 08bd8dbe88825760e953759d7ec212903a026c75 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 21 Jan 2021 17:11:42 -0500 Subject: [PATCH 0579/1084] pNFS/NFSv4: Try to return invalid layout in pnfs_layout_process() If the server returns a new stateid that does not match the one in our cache, then try to return the one we hold instead of just invalidating it on the client side. This ensures that both client and server will agree that the stateid is invalid. Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index e68e6f8cb4079..d6262289cf4aa 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -2398,7 +2398,13 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) * We got an entirely new state ID. Mark all segments for the * inode invalid, and retry the layoutget */ - pnfs_mark_layout_stateid_invalid(lo, &free_me); + struct pnfs_layout_range range = { + .iomode = IOMODE_ANY, + .length = NFS4_MAX_UINT64, + }; + pnfs_set_plh_return_info(lo, IOMODE_ANY, 0); + pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, + &range, 0); goto out_forget; } @@ -2417,7 +2423,6 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) spin_unlock(&ino->i_lock); lseg->pls_layout = lo; NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg); - pnfs_free_lseg_list(&free_me); return ERR_PTR(-EAGAIN); } -- GitLab From 1bcf34fdac5f8c2fcd16796495db75744612ca27 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 21 Jan 2021 13:51:50 -0500 Subject: [PATCH 0580/1084] pNFS/NFSv4: Update the layout barrier when we schedule a layoutreturn When we're scheduling a layoutreturn, we need to ignore any further incoming layouts with sequence ids that are going to be affected by the layout return. Fixes: 44ea8dfce021 ("NFS/pnfs: Reference the layout cred in pnfs_prepare_layoutreturn()") Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index d6262289cf4aa..acb63ec000539 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -324,6 +324,21 @@ pnfs_grab_inode_layout_hdr(struct pnfs_layout_hdr *lo) return NULL; } +/* + * Compare 2 layout stateid sequence ids, to see which is newer, + * taking into account wraparound issues. + */ +static bool pnfs_seqid_is_newer(u32 s1, u32 s2) +{ + return (s32)(s1 - s2) > 0; +} + +static void pnfs_barrier_update(struct pnfs_layout_hdr *lo, u32 newseq) +{ + if (pnfs_seqid_is_newer(newseq, lo->plh_barrier)) + lo->plh_barrier = newseq; +} + static void pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode, u32 seq) @@ -335,6 +350,7 @@ pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode, if (seq != 0) { WARN_ON_ONCE(lo->plh_return_seq != 0 && lo->plh_return_seq != seq); lo->plh_return_seq = seq; + pnfs_barrier_update(lo, seq); } } @@ -639,15 +655,6 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg, return rv; } -/* - * Compare 2 layout stateid sequence ids, to see which is newer, - * taking into account wraparound issues. - */ -static bool pnfs_seqid_is_newer(u32 s1, u32 s2) -{ - return (s32)(s1 - s2) > 0; -} - static bool pnfs_should_free_range(const struct pnfs_layout_range *lseg_range, const struct pnfs_layout_range *recall_range) @@ -984,8 +991,7 @@ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, new_barrier = be32_to_cpu(new->seqid); else if (new_barrier == 0) return; - if (pnfs_seqid_is_newer(new_barrier, lo->plh_barrier)) - lo->plh_barrier = new_barrier; + pnfs_barrier_update(lo, new_barrier); } static bool @@ -1183,20 +1189,17 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo, return false; set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags); pnfs_get_layout_hdr(lo); + nfs4_stateid_copy(stateid, &lo->plh_stateid); + *cred = get_cred(lo->plh_lc_cred); if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) { - nfs4_stateid_copy(stateid, &lo->plh_stateid); - *cred = get_cred(lo->plh_lc_cred); if (lo->plh_return_seq != 0) stateid->seqid = cpu_to_be32(lo->plh_return_seq); if (iomode != NULL) *iomode = lo->plh_return_iomode; pnfs_clear_layoutreturn_info(lo); - return true; - } - nfs4_stateid_copy(stateid, &lo->plh_stateid); - *cred = get_cred(lo->plh_lc_cred); - if (iomode != NULL) + } else if (iomode != NULL) *iomode = IOMODE_ANY; + pnfs_barrier_update(lo, be32_to_cpu(stateid->seqid)); return true; } -- GitLab From d29b468da4f940bd2bff2628ba8d2d652671d244 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 22 Jan 2021 10:05:51 -0500 Subject: [PATCH 0581/1084] pNFS/NFSv4: Improve rejection of out-of-order layouts If a layoutget ends up being reordered w.r.t. a layoutreturn, e.g. due to a layoutget-on-open not knowing a priori which file to lock, then we must assume the layout is no longer being considered valid state by the server. Incrementally improve our ability to reject such states by using the cached old stateid in conjunction with the plh_barrier to try to identify them. Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index acb63ec000539..af64b4e6fd1ff 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1000,7 +1000,7 @@ pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo, { u32 seqid = be32_to_cpu(stateid->seqid); - return !pnfs_seqid_is_newer(seqid, lo->plh_barrier); + return !pnfs_seqid_is_newer(seqid, lo->plh_barrier) && lo->plh_barrier; } /* lget is set to 1 if called from inside send_layoutget call chain */ @@ -1912,6 +1912,11 @@ static void nfs_layoutget_end(struct pnfs_layout_hdr *lo) wake_up_var(&lo->plh_outstanding); } +static bool pnfs_is_first_layoutget(struct pnfs_layout_hdr *lo) +{ + return test_bit(NFS_LAYOUT_FIRST_LAYOUTGET, &lo->plh_flags); +} + static void pnfs_clear_first_layoutget(struct pnfs_layout_hdr *lo) { unsigned long *bitlock = &lo->plh_flags; @@ -2386,17 +2391,17 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) goto out_forget; } - if (!pnfs_layout_is_valid(lo)) { - /* We have a completely new layout */ - pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true); - } else if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) { + if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) { /* existing state ID, make sure the sequence number matches. */ if (pnfs_layout_stateid_blocked(lo, &res->stateid)) { + if (!pnfs_layout_is_valid(lo) && + pnfs_is_first_layoutget(lo)) + lo->plh_barrier = 0; dprintk("%s forget reply due to sequence\n", __func__); goto out_forget; } pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, false); - } else { + } else if (pnfs_layout_is_valid(lo)) { /* * We got an entirely new state ID. Mark all segments for the * inode invalid, and retry the layoutget @@ -2409,6 +2414,11 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, &range, 0); goto out_forget; + } else { + /* We have a completely new layout */ + if (!pnfs_is_first_layoutget(lo)) + goto out_forget; + pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true); } pnfs_get_lseg(lseg); -- GitLab From 9bbd77d5bbc9aff8cb74d805c31751f5f0691ba8 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 21 Jan 2021 19:24:17 -0800 Subject: [PATCH 0582/1084] Input: xpad - sync supported devices with fork on GitHub There is a fork of this driver on GitHub [0] that has been updated with new device IDs. Merge those into the mainline driver, so the out-of-tree fork is not needed for users of those devices anymore. [0] https://github.com/paroj/xpad Signed-off-by: Benjamin Valentin Link: https://lore.kernel.org/r/20210121142523.1b6b050f@rechenknecht2k11 Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 0687f0ed60b83..8cc8ca4a9ac01 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -215,9 +215,17 @@ static const struct xpad_device { { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE }, - { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a0, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a1, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a2, "PDP Wired Controller for Xbox One - Crimson Red", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x02a4, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x02a6, "PDP Wired Controller for Xbox One - Camo Series", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a7, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a8, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02ad, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02b3, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02b8, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 }, { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 }, @@ -296,6 +304,9 @@ static const struct xpad_device { { 0x1bad, 0xfa01, "MadCatz GamePad", 0, XTYPE_XBOX360 }, { 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 }, { 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 }, + { 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE }, + { 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 }, + { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 }, { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, @@ -429,8 +440,12 @@ static const struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ + XPAD_XBOX360_VENDOR(0x20d6), /* PowerA Controllers */ + XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA Controllers */ XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */ XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */ + XPAD_XBOXONE_VENDOR(0x2e24), /* Hyperkin Duke X-Box One pad */ + XPAD_XBOX360_VENDOR(0x2f24), /* GameSir Controllers */ { } }; -- GitLab From 2569063c7140c65a0d0ad075e95ddfbcda9ba3c0 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sun, 27 Dec 2020 19:34:58 +0800 Subject: [PATCH 0583/1084] blk-mq: test QUEUE_FLAG_HCTX_ACTIVE for sbitmap_shared in hctx_may_queue In case of blk_mq_is_sbitmap_shared(), we should test QUEUE_FLAG_HCTX_ACTIVE against q->queue_flags instead of BLK_MQ_S_TAG_ACTIVE. So fix it. Cc: John Garry Cc: Kashyap Desai Fixes: f1b49fdc1c64 ("blk-mq: Record active_queues_shared_sbitmap per tag_set for when using shared sbitmap") Signed-off-by: Ming Lei Reviewed-by: John Garry Signed-off-by: Jens Axboe --- block/blk-mq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-mq.h b/block/blk-mq.h index c1458d9502f1c..3616453ca28c8 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h @@ -304,7 +304,7 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx, struct request_queue *q = hctx->queue; struct blk_mq_tag_set *set = q->tag_set; - if (!test_bit(BLK_MQ_S_TAG_ACTIVE, &q->queue_flags)) + if (!test_bit(QUEUE_FLAG_HCTX_ACTIVE, &q->queue_flags)) return true; users = atomic_read(&set->active_queues_shared_sbitmap); } else { -- GitLab From ef49d40b61a3e18a11edd5eb1c30b0183af9e850 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Sun, 17 Jan 2021 16:50:17 +0800 Subject: [PATCH 0584/1084] block: Fix an error handling in add_partition Once we have called device_initialize(), we should use put_device() to give up the reference on error, just like what we have done on failure of device_add(). Signed-off-by: Dinghao Liu Reviewed-by: Christoph Hellwig Signed-off-by: Jens Axboe --- block/partitions/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/partitions/core.c b/block/partitions/core.c index e7d776db803b1..23460cee9de50 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -384,7 +384,7 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, err = blk_alloc_devt(bdev, &devt); if (err) - goto out_bdput; + goto out_put; pdev->devt = devt; /* delay uevent until 'holders' subdir is created */ -- GitLab From 177d8f1f7f47fe7c18ceb1d87893890d7e9c95a7 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 30 Dec 2020 17:07:40 +0200 Subject: [PATCH 0585/1084] ARM: dts: omap4-droid4: Fix lost keypad slide interrupts for droid4 We may lose edge interrupts for gpio banks other than the first gpio bank as they are not always powered. Instead, we must use the padconf interrupt as that is always powered. Note that we still also use the gpio for reading the pin state as that can't be done with the padconf device. Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap4-droid4-xt894.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts index 3ea4c5b9fd319..e833c21f1c014 100644 --- a/arch/arm/boot/dts/omap4-droid4-xt894.dts +++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts @@ -16,8 +16,13 @@ debounce-interval = <10>; }; + /* + * We use pad 0x4a100116 abe_dmic_din3.gpio_122 as the irq instead + * of the gpio interrupt to avoid lost events in deeper idle states. + */ slider { label = "Keypad Slide"; + interrupts-extended = <&omap4_pmx_core 0xd6>; gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio122 */ linux,input-type = ; linux,code = ; -- GitLab From 794c613383433ffc4fceec8eaa081b9f1962e287 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Mon, 18 Jan 2021 21:45:23 +0800 Subject: [PATCH 0586/1084] HID: multitouch: Apply MT_QUIRK_CONFIDENCE quirk for multi-input devices Palm ejection stops working on some Elan and Synaptics touchpad after commit 40d5bb87377a ("HID: multitouch: enable multi-input as a quirk for some devices"). The commit changes the mt_class from MT_CLS_WIN_8 to MT_CLS_WIN_8_FORCE_MULTI_INPUT, so MT_QUIRK_CONFIDENCE isn't applied anymore. So also apply the quirk since MT_CLS_WIN_8_FORCE_MULTI_INPUT is essentially MT_CLS_WIN_8. Fixes: 40d5bb87377a ("HID: multitouch: enable multi-input as a quirk for some devices") Cc: stable@vger.kernel.org Signed-off-by: Kai-Heng Feng Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-multitouch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 0743ef51d3b24..8429ebe7097e4 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -758,7 +758,8 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, MT_STORE_FIELD(inrange_state); return 1; case HID_DG_CONFIDENCE: - if (cls->name == MT_CLS_WIN_8 && + if ((cls->name == MT_CLS_WIN_8 || + cls->name == MT_CLS_WIN_8_FORCE_MULTI_INPUT) && (field->application == HID_DG_TOUCHPAD || field->application == HID_DG_TOUCHSCREEN)) app->quirks |= MT_QUIRK_CONFIDENCE; -- GitLab From 08d60e5999540110576e7c1346d486220751b7f9 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Sun, 24 Jan 2021 21:33:28 +0106 Subject: [PATCH 0587/1084] printk: fix string termination for record_print_text() Commit f0e386ee0c0b ("printk: fix buffer overflow potential for print_text()") added string termination in record_print_text(). However it used the wrong base pointer for adding the terminator. This led to a 0-byte being written somewhere beyond the buffer. Use the correct base pointer when adding the terminator. Fixes: f0e386ee0c0b ("printk: fix buffer overflow potential for print_text()") Reported-by: Sven Schnelle Signed-off-by: John Ogness Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20210124202728.4718-1-john.ogness@linutronix.de --- kernel/printk/printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 17fa6dc77053b..c55cd18206895 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1399,7 +1399,7 @@ static size_t record_print_text(struct printk_record *r, bool syslog, * not counted in the return value. */ if (buf_size > 0) - text[len] = 0; + r->text_buf[len] = 0; return len; } -- GitLab From 78e5330329ee206d6aa4593a90320fd837f7966e Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Thu, 21 Jan 2021 11:57:58 +0100 Subject: [PATCH 0588/1084] drm/vc4: Correct lbm size and calculation LBM base address is measured in units of pixels per cycle. That is 4 for 2711 (hvs5) and 2 for 2708. We are wasting 75% of lbm by indexing without the scaling. But we were also using too high a size for the lbm resulting in partial corruption (right hand side) of vertically scaled images, usually at 4K or lower resolutions with more layers. The physical RAM of LBM on 2711 is 8 * 1920 * 16 * 12-bit (pixels are stored 12-bits per component regardless of format). The LBM address indexes work in units of pixels per clock, so for 4 pixels per clock that means we have 32 * 1920 = 60K Fixes: c54619b0bfb3 ("drm/vc4: Add support for the BCM2711 HVS5") Signed-off-by: Dom Cobley Signed-off-by: Maxime Ripard Reviewed-by: Dave Stevenson Tested-By: Lucas Nussbaum Tested-By: Ryutaroh Matsumoto Link: https://patchwork.freedesktop.org/patch/msgid/20210121105759.1262699-1-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_hvs.c | 8 ++++---- drivers/gpu/drm/vc4/vc4_plane.c | 7 ++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index cccd341e5d670..3b722252d1fbe 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -620,11 +620,11 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) * for now we just allocate globally. */ if (!hvs->hvs5) - /* 96kB */ - drm_mm_init(&hvs->lbm_mm, 0, 96 * 1024); + /* 48k words of 2x12-bit pixels */ + drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024); else - /* 70k words */ - drm_mm_init(&hvs->lbm_mm, 0, 70 * 2 * 1024); + /* 60k words of 4x12-bit pixels */ + drm_mm_init(&hvs->lbm_mm, 0, 60 * 1024); /* Upload filter kernels. We only have the one for now, so we * keep it around for the lifetime of the driver. diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 6b39cc2ca18d0..1a4369c1fb164 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -437,6 +437,7 @@ static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst) static u32 vc4_lbm_size(struct drm_plane_state *state) { struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); + struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev); u32 pix_per_line; u32 lbm; @@ -472,7 +473,11 @@ static u32 vc4_lbm_size(struct drm_plane_state *state) lbm = pix_per_line * 16; } - lbm = roundup(lbm, 32); + /* Align it to 64 or 128 (hvs5) bytes */ + lbm = roundup(lbm, vc4->hvs->hvs5 ? 128 : 64); + + /* Each "word" of the LBM memory contains 2 or 4 (hvs5) pixels */ + lbm /= vc4->hvs->hvs5 ? 4 : 2; return lbm; } -- GitLab From f6b57101a6b31277a4bde1d8028c46e898bd2ff2 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Thu, 21 Jan 2021 11:57:59 +0100 Subject: [PATCH 0589/1084] drm/vc4: Correct POS1_SCL for hvs5 Fixes failure with 4096x1080 resolutions [ 284.315379] WARNING: CPU: 1 PID: 901 at drivers/gpu/drm/vc4/vc4_plane.c:981 vc4_plane_mode_set+0x1374/0x13c4 [ 284.315385] Modules linked in: ir_rc5_decoder rpivid_hevc(C) bcm2835_codec(C) bcm2835_isp(C) bcm2835_mmal_vchiq(C) bcm2835_gpiomem v4l2_mem2mem videobuf2_dma_contig videobuf2_memops videobuf2_v4l2 videobuf2_common videodev mc cdc_acm xpad ir_rc6_decoder rc_rc6_mce gpio_ir_recv fuse [ 284.315509] CPU: 1 PID: 901 Comm: kodi.bin Tainted: G C 5.10.7 #1 [ 284.315514] Hardware name: BCM2711 [ 284.315518] Backtrace: [ 284.315533] [] (dump_backtrace) from [] (show_stack+0x20/0x24) [ 284.315540] r7:ffffffff r6:00000000 r5:68000013 r4:c18ecf1c [ 284.315549] [] (show_stack) from [] (dump_stack+0xc4/0xf0) [ 284.315558] [] (dump_stack) from [] (__warn+0xfc/0x158) [ 284.315564] r9:00000000 r8:00000009 r7:000003d5 r6:00000009 r5:c08cc7dc r4:c0fd09b8 [ 284.315572] [] (__warn) from [] (warn_slowpath_fmt+0x74/0xe4) [ 284.315577] r7:c08cc7dc r6:000003d5 r5:c0fd09b8 r4:00000000 [ 284.315584] [] (warn_slowpath_fmt) from [] (vc4_plane_mode_set+0x1374/0x13c4) [ 284.315589] r8:00000000 r7:00000000 r6:00001000 r5:c404c600 r4:c2e34600 [ 284.315596] [] (vc4_plane_mode_set) from [] (vc4_plane_atomic_check+0x40/0x1c0) [ 284.315601] r10:00000001 r9:c2e34600 r8:c0e67068 r7:c0fc44e0 r6:c2ce3640 r5:c3d636c0 [ 284.315605] r4:c2e34600 [ 284.315614] [] (vc4_plane_atomic_check) from [] (drm_atomic_helper_check_planes+0xec/0x1ec) [ 284.315620] r9:c2e34600 r8:c0e67068 r7:c0fc44e0 r6:c2ce3640 r5:c3d636c0 r4:00000006 [ 284.315627] [] (drm_atomic_helper_check_planes) from [] (drm_atomic_helper_check+0x54/0x9c) [ 284.315633] r9:c2e35400 r8:00000006 r7:00000000 r6:c2ba7800 r5:c3d636c0 r4:00000000 [ 284.315641] [] (drm_atomic_helper_check) from [] (vc4_atomic_check+0x25c/0x454) [ 284.315645] r7:00000000 r6:c2ba7800 r5:00000001 r4:c3d636c0 [ 284.315652] [] (vc4_atomic_check) from [] (drm_atomic_check_only+0x5cc/0x7e0) [ 284.315658] r10:c404c6c8 r9:ffffffff r8:c472c480 r7:00000003 r6:c3d636c0 r5:00000000 [ 284.315662] r4:0000003c r3:c08b7a4c [ 284.315670] [] (drm_atomic_check_only) from [] (drm_mode_atomic_ioctl+0x758/0xa7c) [ 284.315675] r10:c3d46000 r9:c3d636c0 r8:c2ce8a70 r7:027e3a54 r6:00000043 r5:c1fbb800 [ 284.315679] r4:0281a858 [ 284.315688] [] (drm_mode_atomic_ioctl) from [] (drm_ioctl_kernel+0xc4/0x108) [ 284.315693] r10:c03864bc r9:c1fbb800 r8:c3d47e64 r7:c089b308 r6:00000002 r5:c2ba7800 [ 284.315697] r4:00000000 [ 284.315705] [] (drm_ioctl_kernel) from [] (drm_ioctl+0x1e8/0x3a0) [ 284.315711] r9:c1fbb800 r8:000000bc r7:c3d47e64 r6:00000038 r5:c0e59570 r4:00000038 [ 284.315719] [] (drm_ioctl) from [] (sys_ioctl+0x35c/0x914) [ 284.315724] r10:c2d08200 r9:00000000 r8:c36fa300 r7:befdd870 r6:c03864bc r5:c36fa301 [ 284.315728] r4:c03864bc [ 284.315735] [] (sys_ioctl) from [] (ret_fast_syscall+0x0/0x28) [ 284.315739] Exception stack(0xc3d47fa8 to 0xc3d47ff0) [ 284.315745] 7fa0: 027eb750 befdd870 00000000 c03864bc befdd870 00000000 [ 284.315750] 7fc0: 027eb750 befdd870 c03864bc 00000036 027e3948 0281a640 0281a850 027e3a50 [ 284.315756] 7fe0: b4b64100 befdd844 b4b5ba2c b49c994c [ 284.315762] r10:00000036 r9:c3d46000 r8:c0200204 r7:00000036 r6:c03864bc r5:befdd870 [ 284.315765] r4:027eb750 Fixes: c54619b0bfb3 ("drm/vc4: Add support for the BCM2711 HVS5") Signed-off-by: Dom Cobley Signed-off-by: Maxime Ripard Reviewed-by: Dave Stevenson Tested-By: Lucas Nussbaum Tested-By: Ryutaroh Matsumoto Link: https://patchwork.freedesktop.org/patch/msgid/20210121105759.1262699-2-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_plane.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 1a4369c1fb164..5612cab552270 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -917,9 +917,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane, if (!vc4_state->is_unity) { vc4_dlist_write(vc4_state, VC4_SET_FIELD(vc4_state->crtc_w, - SCALER_POS1_SCL_WIDTH) | + SCALER5_POS1_SCL_WIDTH) | VC4_SET_FIELD(vc4_state->crtc_h, - SCALER_POS1_SCL_HEIGHT)); + SCALER5_POS1_SCL_HEIGHT)); } /* Position Word 2: Source Image Size */ -- GitLab From 396cf2a46adddbf51373e16225c1d25254310046 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 21 Jan 2021 15:12:36 -0800 Subject: [PATCH 0590/1084] spidev: Add cisco device compatible Add compatible string for Cisco device present on the Cisco Petra platform. Signed-off-by: Daniel Walker Cc: xe-linux-external@cisco.com Link: https://lore.kernel.org/r/20210121231237.30664-2-danielwa@cisco.com Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 859910ec8d9f6..8cb4d923aeaab 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -682,6 +682,7 @@ static const struct of_device_id spidev_dt_ids[] = { { .compatible = "lwn,bk4" }, { .compatible = "dh,dhcom-board" }, { .compatible = "menlo,m53cpld" }, + { .compatible = "cisco,spi-petra" }, {}, }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); -- GitLab From bf544e9aa570034e094a8a40d5f9e1e2c4916d18 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Fri, 15 Jan 2021 13:05:47 +0200 Subject: [PATCH 0591/1084] iwlwifi: mvm: skip power command when unbinding vif during CSA In the new CSA flow, we remain associated during CSA, but still do a unbind-bind to the vif. However, sending the power command right after when vif is unbound but still associated causes FW to assert (0x3400) since it cannot tell the LMAC id. Just skip this command, we will send it again in a bit, when assigning the new context. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.64a2254ac5c3.Iaa3a9050bf3d7c9cd5beaf561e932e6defc12ec3@changeid --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index da32937ba9a78..43ff0407916af 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4194,6 +4194,9 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, iwl_mvm_binding_remove_vif(mvm, vif); out: + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD) && + switching_chanctx) + return; mvmvif->phy_ctxt = NULL; iwl_mvm_power_update_mac(mvm); } -- GitLab From 5c56d862c749669d45c256f581eac4244be00d4d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jan 2021 13:05:48 +0200 Subject: [PATCH 0592/1084] iwlwifi: mvm: take mutex for calling iwl_mvm_get_sync_time() We need to take the mutex to call iwl_mvm_get_sync_time(), do it. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.4bb5ccf881a6.I62973cbb081e80aa5b0447a5c3b9c3251a65cf6b@changeid --- drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c index 573e46956c14d..38d0bfb649ccc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c @@ -459,7 +459,10 @@ static ssize_t iwl_dbgfs_os_device_timediff_read(struct file *file, const size_t bufsz = sizeof(buf); int pos = 0; + mutex_lock(&mvm->mutex); iwl_mvm_get_sync_time(mvm, &curr_gp2, &curr_os); + mutex_unlock(&mvm->mutex); + do_div(curr_os, NSEC_PER_USEC); diff = curr_os - curr_gp2; pos += scnprintf(buf + pos, bufsz - pos, "diff=%lld\n", diff); -- GitLab From 34b9434cd0d425330a0467e767f8d047ef62964d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jan 2021 13:05:49 +0200 Subject: [PATCH 0593/1084] iwlwifi: pcie: avoid potential PNVM leaks If we erroneously try to set the PNVM data again after it has already been set, we could leak the old DMA memory. Avoid that and warn, we shouldn't be doing this. Signed-off-by: Johannes Berg Fixes: 6972592850c0 ("iwlwifi: read and parse PNVM file") Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.929c2d680429.I086b9490e6c005f3bcaa881b617e9f61908160f3@changeid --- drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index 36bf414a388af..afe5852284356 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -294,6 +294,9 @@ int iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans, return ret; } + if (WARN_ON(prph_sc_ctrl->pnvm_cfg.pnvm_size)) + return -EBUSY; + prph_sc_ctrl->pnvm_cfg.pnvm_base_addr = cpu_to_le64(trans_pcie->pnvm_dram.physical); prph_sc_ctrl->pnvm_cfg.pnvm_size = -- GitLab From 1c58bed4b7f7551239b9005ad0a9a6566a3d9fbe Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jan 2021 13:05:50 +0200 Subject: [PATCH 0594/1084] iwlwifi: pnvm: don't skip everything when not reloading Even if we don't reload the file from disk, we still need to trigger the PNVM load flow with the device; fix that. Signed-off-by: Johannes Berg Fixes: 6972592850c0 ("iwlwifi: read and parse PNVM file") Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.85ef56c4ef8c.I3b853ce041a0755d45e448035bef1837995d191b@changeid --- drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 50 ++++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index 6d8f7bff12432..ebd1a09a2fb8a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -224,40 +224,40 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data, int iwl_pnvm_load(struct iwl_trans *trans, struct iwl_notif_wait_data *notif_wait) { - const struct firmware *pnvm; struct iwl_notification_wait pnvm_wait; static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP, PNVM_INIT_COMPLETE_NTFY) }; - char pnvm_name[64]; - int ret; /* if the SKU_ID is empty, there's nothing to do */ if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2]) return 0; - /* if we already have it, nothing to do either */ - if (trans->pnvm_loaded) - return 0; + /* load from disk only if we haven't done it before */ + if (!trans->pnvm_loaded) { + const struct firmware *pnvm; + char pnvm_name[64]; + int ret; + + /* + * The prefix unfortunately includes a hyphen at the end, so + * don't add the dot here... + */ + snprintf(pnvm_name, sizeof(pnvm_name), "%spnvm", + trans->cfg->fw_name_pre); + + /* ...but replace the hyphen with the dot here. */ + if (strlen(trans->cfg->fw_name_pre) < sizeof(pnvm_name)) + pnvm_name[strlen(trans->cfg->fw_name_pre) - 1] = '.'; + + ret = firmware_request_nowarn(&pnvm, pnvm_name, trans->dev); + if (ret) { + IWL_DEBUG_FW(trans, "PNVM file %s not found %d\n", + pnvm_name, ret); + } else { + iwl_pnvm_parse(trans, pnvm->data, pnvm->size); - /* - * The prefix unfortunately includes a hyphen at the end, so - * don't add the dot here... - */ - snprintf(pnvm_name, sizeof(pnvm_name), "%spnvm", - trans->cfg->fw_name_pre); - - /* ...but replace the hyphen with the dot here. */ - if (strlen(trans->cfg->fw_name_pre) < sizeof(pnvm_name)) - pnvm_name[strlen(trans->cfg->fw_name_pre) - 1] = '.'; - - ret = firmware_request_nowarn(&pnvm, pnvm_name, trans->dev); - if (ret) { - IWL_DEBUG_FW(trans, "PNVM file %s not found %d\n", - pnvm_name, ret); - } else { - iwl_pnvm_parse(trans, pnvm->data, pnvm->size); - - release_firmware(pnvm); + release_firmware(pnvm); + } } iwl_init_notification_wait(notif_wait, &pnvm_wait, -- GitLab From 82a08d0cd7b503be426fb856a0fb73c9c976aae1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jan 2021 13:05:51 +0200 Subject: [PATCH 0595/1084] iwlwifi: pnvm: don't try to load after failures If loading the PNVM file failed on the first try during the interface up, the file is unlikely to show up later, and we already don't try to reload it if it changes, so just don't try loading it again and again. This also fixes some issues where we may try to load it at resume time, which may not be possible yet. Signed-off-by: Johannes Berg Fixes: 6972592850c0 ("iwlwifi: read and parse PNVM file") Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.5ac6828a0bbe.I7d308358b21d3c0c84b1086999dbc7267f86e219@changeid --- drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index ebd1a09a2fb8a..895a907acdf0f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -232,7 +232,7 @@ int iwl_pnvm_load(struct iwl_trans *trans, if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2]) return 0; - /* load from disk only if we haven't done it before */ + /* load from disk only if we haven't done it (or tried) before */ if (!trans->pnvm_loaded) { const struct firmware *pnvm; char pnvm_name[64]; @@ -253,6 +253,12 @@ int iwl_pnvm_load(struct iwl_trans *trans, if (ret) { IWL_DEBUG_FW(trans, "PNVM file %s not found %d\n", pnvm_name, ret); + /* + * Pretend we've loaded it - at least we've tried and + * couldn't load it at all, so there's no point in + * trying again over and over. + */ + trans->pnvm_loaded = true; } else { iwl_pnvm_parse(trans, pnvm->data, pnvm->size); -- GitLab From a800f95858d02a9174c48b4286c0799d3905890f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 15 Jan 2021 13:05:52 +0200 Subject: [PATCH 0596/1084] iwlwifi: fix the NMI flow for old devices I noticed that the flow that triggers an NMI on the firmware for old devices (tested on 7265) doesn't work. Apparently, the firmware / device is still in low power when we write the register that triggers the NMI. We call the "grab_nic_access" function to make sure the device is awake but that wasn't enough. I played with this and noticed that if we wait 1 ms after the device reports it is awake before we write to the NMI register, the device always sees our write and the firmware gets properly asserted. Triggering an NMI to the firmware can be done with the debugfs hook: echo 1 > /sys/kernel/debug/iwlwifi/0000\:00\:03.0/iwlmvm/fw_nmi What happened before is that the firmware would just stall without running its NMI routine. Because of that the driver wouldn't get the "firmware crashed" interrupt. After a while the driver would notice that the firmware is not responding to some command and it would read the error data from the firmware, but this data is populated in the NMI service routine in the firmware which was not called. So in the logs it looked like: iwlwifi 0000:00:03.0: Error sending REPLY_ERROR: time out after 2000ms. iwlwifi 0000:00:03.0: Current CMD queue read_ptr 33 write_ptr 34 iwlwifi 0000:00:03.0: Loaded firmware version: 29.09bd31e1.0 7265D-29.ucode iwlwifi 0000:00:03.0: 0x00000000 | ADVANCED_SYSASSERT iwlwifi 0000:00:03.0: 0x00000000 | trm_hw_status0 iwlwifi 0000:00:03.0: 0x00000000 | trm_hw_status1 iwlwifi 0000:00:03.0: 0x00000000 | branchlink2 iwlwifi 0000:00:03.0: 0x00000000 | interruptlink1 iwlwifi 0000:00:03.0: 0x00000000 | interruptlink2 iwlwifi 0000:00:03.0: 0x00000000 | data1 iwlwifi 0000:00:03.0: 0x00000000 | data2 iwlwifi 0000:00:03.0: 0x00000000 | data3 iwlwifi 0000:00:03.0: 0x00000000 | beacon time iwlwifi 0000:00:03.0: 0x00000000 | tsf low ... With this fix, immediately after we trigger the NMI to the firmware, we get the expected: iwlwifi 0000:00:03.0: Microcode SW error detected. Restarting 0x2000000. iwlwifi 0000:00:03.0: Start IWL Error Log Dump: iwlwifi 0000:00:03.0: Status: 0x00000040, count: 6 iwlwifi 0000:00:03.0: Loaded firmware version: 29.09bd31e1.0 7265D-29.ucode iwlwifi 0000:00:03.0: 0x00000084 | NMI_INTERRUPT_UNKNOWN iwlwifi 0000:00:03.0: 0x000002F1 | trm_hw_status0 iwlwifi 0000:00:03.0: 0x00000000 | trm_hw_status1 iwlwifi 0000:00:03.0: 0x00043D6C | branchlink2 iwlwifi 0000:00:03.0: 0x0004AFD6 | interruptlink1 iwlwifi 0000:00:03.0: 0x000008C4 | interruptlink2 iwlwifi 0000:00:03.0: 0x00000000 | data1 iwlwifi 0000:00:03.0: 0x00000080 | data2 iwlwifi 0000:00:03.0: 0x07030000 | data3 iwlwifi 0000:00:03.0: 0x003FD4C3 | beacon time iwlwifi 0000:00:03.0: 0x00C22AC3 | tsf low iwlwifi 0000:00:03.0: 0x00000000 | tsf hi iwlwifi 0000:00:03.0: 0x00000000 | time gp1 iwlwifi 0000:00:03.0: 0x00C22AC3 | time gp2 iwlwifi 0000:00:03.0: 0x00000001 | uCode revision type iwlwifi 0000:00:03.0: 0x0000001D | uCode version major Notice the first line: "Microcode SW error detected:" which is printed in the driver's ISR, which means that the driver actually got an interrupt from the firmware saying that it crashed. And then we have the properly populated error data. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.70e67cc75d88.I6615cad4361862e7f3c9f2d3cafb6a8c61e16781@changeid --- drivers/net/wireless/intel/iwlwifi/iwl-io.c | 9 +++++---- drivers/net/wireless/intel/iwlwifi/iwl-io.h | 10 ++++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c index 2ac20d0a30eb6..2b7ef1583e7fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c @@ -150,16 +150,17 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) } IWL_EXPORT_SYMBOL(iwl_read_prph); -void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) +void iwl_write_prph_delay(struct iwl_trans *trans, u32 ofs, u32 val, u32 delay_ms) { unsigned long flags; if (iwl_trans_grab_nic_access(trans, &flags)) { + mdelay(delay_ms); iwl_write_prph_no_grab(trans, ofs, val); iwl_trans_release_nic_access(trans, &flags); } } -IWL_EXPORT_SYMBOL(iwl_write_prph); +IWL_EXPORT_SYMBOL(iwl_write_prph_delay); int iwl_poll_prph_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout) @@ -219,8 +220,8 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); void iwl_force_nmi(struct iwl_trans *trans) { if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) - iwl_write_prph(trans, DEVICE_SET_NMI_REG, - DEVICE_SET_NMI_VAL_DRV); + iwl_write_prph_delay(trans, DEVICE_SET_NMI_REG, + DEVICE_SET_NMI_VAL_DRV, 1); else if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER, UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-io.h index 39bceee4e9e76..3c21c0e081f8e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2018-2019 Intel Corporation + * Copyright (C) 2018-2020 Intel Corporation */ #ifndef __iwl_io_h__ #define __iwl_io_h__ @@ -37,7 +37,13 @@ u32 iwl_read_prph_no_grab(struct iwl_trans *trans, u32 ofs); u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs); void iwl_write_prph_no_grab(struct iwl_trans *trans, u32 ofs, u32 val); void iwl_write_prph64_no_grab(struct iwl_trans *trans, u64 ofs, u64 val); -void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val); +void iwl_write_prph_delay(struct iwl_trans *trans, u32 ofs, + u32 val, u32 delay_ms); +static inline void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) +{ + iwl_write_prph_delay(trans, ofs, val, 0); +} + int iwl_poll_prph_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout); void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); -- GitLab From 0f8d5656b3fd100c132b02aa72038f032fc6e30e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 15 Jan 2021 13:05:53 +0200 Subject: [PATCH 0597/1084] iwlwifi: queue: don't crash if txq->entries is NULL The code was really awkward, we would first dereference txq->entries when calling iwl_txq_genX_tfd_unmap and then we would check that txq->entries is non-NULL. Fix that by exiting if txq->entries is NULL. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.173359fc236d.I75c7c2397d20df8d7fbc24cb16a5232d5c551889@changeid --- drivers/net/wireless/intel/iwlwifi/queue/tx.c | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c index 27eea909e32da..62c0c4cbe481a 100644 --- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c @@ -142,26 +142,25 @@ void iwl_txq_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) * idx is bounded by n_window */ int idx = iwl_txq_get_cmd_index(txq, txq->read_ptr); + struct sk_buff *skb; lockdep_assert_held(&txq->lock); + if (!txq->entries) + return; + iwl_txq_gen2_tfd_unmap(trans, &txq->entries[idx].meta, iwl_txq_get_tfd(trans, txq, idx)); - /* free SKB */ - if (txq->entries) { - struct sk_buff *skb; - - skb = txq->entries[idx].skb; + skb = txq->entries[idx].skb; - /* Can be called from irqs-disabled context - * If skb is not NULL, it means that the whole queue is being - * freed and that the queue is not empty - free the skb - */ - if (skb) { - iwl_op_mode_free_skb(trans->op_mode, skb); - txq->entries[idx].skb = NULL; - } + /* Can be called from irqs-disabled context + * If skb is not NULL, it means that the whole queue is being + * freed and that the queue is not empty - free the skb + */ + if (skb) { + iwl_op_mode_free_skb(trans->op_mode, skb); + txq->entries[idx].skb = NULL; } } @@ -1494,28 +1493,28 @@ void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) */ int rd_ptr = txq->read_ptr; int idx = iwl_txq_get_cmd_index(txq, rd_ptr); + struct sk_buff *skb; lockdep_assert_held(&txq->lock); + if (!txq->entries) + return; + /* We have only q->n_window txq->entries, but we use * TFD_QUEUE_SIZE_MAX tfds */ iwl_txq_gen1_tfd_unmap(trans, &txq->entries[idx].meta, txq, rd_ptr); /* free SKB */ - if (txq->entries) { - struct sk_buff *skb; - - skb = txq->entries[idx].skb; + skb = txq->entries[idx].skb; - /* Can be called from irqs-disabled context - * If skb is not NULL, it means that the whole queue is being - * freed and that the queue is not empty - free the skb - */ - if (skb) { - iwl_op_mode_free_skb(trans->op_mode, skb); - txq->entries[idx].skb = NULL; - } + /* Can be called from irqs-disabled context + * If skb is not NULL, it means that the whole queue is being + * freed and that the queue is not empty - free the skb + */ + if (skb) { + iwl_op_mode_free_skb(trans->op_mode, skb); + txq->entries[idx].skb = NULL; } } -- GitLab From ed0022da8bd9a3ba1c0e1497457be28d52afa7e1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jan 2021 13:05:54 +0200 Subject: [PATCH 0598/1084] iwlwifi: pcie: set LTR on more devices To avoid completion timeouts during device boot, set up the LTR timeouts on more devices - similar to what we had before for AX210. This also corrects the AX210 workaround to be done only on discrete (non-integrated) devices, otherwise the registers have no effect. Signed-off-by: Johannes Berg Fixes: edb625208d84 ("iwlwifi: pcie: set LTR to avoid completion timeout") Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.fb819e19530b.I0396f82922db66426f52fbb70d32a29c8fd66951@changeid --- drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 6 +++ .../intel/iwlwifi/pcie/ctxt-info-gen3.c | 39 +++++++++++-------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index 0b03fdedc1f70..1158e256f6012 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h @@ -301,6 +301,12 @@ #define RADIO_RSP_ADDR_POS (6) #define RADIO_RSP_RD_CMD (3) +/* LTR control (Qu only) */ +#define HPM_MAC_LTR_CSR 0xa0348c +#define HPM_MAC_LRT_ENABLE_ALL 0xf +/* also uses CSR_LTR_* for values */ +#define HPM_UMAC_LTR 0xa03480 + /* FW monitor */ #define MON_BUFF_SAMPLE_CTL (0xa03c00) #define MON_BUFF_BASE_ADDR (0xa03c1c) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index afe5852284356..342a53e4488c7 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -75,6 +75,15 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, const struct fw_img *fw) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ | + u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, + CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) | + u32_encode_bits(250, + CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) | + CSR_LTR_LONG_VAL_AD_SNOOP_REQ | + u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, + CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) | + u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL); struct iwl_context_info_gen3 *ctxt_info_gen3; struct iwl_prph_scratch *prph_scratch; struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl; @@ -206,23 +215,19 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, CSR_AUTO_FUNC_BOOT_ENA); - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) { - /* - * The firmware initializes this again later (to a smaller - * value), but for the boot process initialize the LTR to - * ~250 usec. - */ - u32 val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ | - u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, - CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) | - u32_encode_bits(250, - CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) | - CSR_LTR_LONG_VAL_AD_SNOOP_REQ | - u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, - CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) | - u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL); - - iwl_write32(trans, CSR_LTR_LONG_VAL_AD, val); + /* + * To workaround hardware latency issues during the boot process, + * initialize the LTR to ~250 usec (see ltr_val above). + * The firmware initializes this again later (to a smaller value). + */ + if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 || + trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) && + !trans->trans_cfg->integrated) { + iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val); + } else if (trans->trans_cfg->integrated && + trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) { + iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL); + iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val); } if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) -- GitLab From 98c7d21f957b10d9c07a3a60a3a5a8f326a197e5 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 15 Jan 2021 13:05:55 +0200 Subject: [PATCH 0599/1084] iwlwifi: pcie: add a NULL check in iwl_pcie_txq_unmap I hit a NULL pointer exception in this function when the init flow went really bad. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.2e8da9f2c132.I0234d4b8ddaf70aaa5028a20c863255e05bc1f84@changeid --- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 5dda0015522dd..83f4964f3cb29 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -201,6 +201,11 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_txq *txq = trans->txqs.txq[txq_id]; + if (!txq) { + IWL_ERR(trans, "Trying to free a queue that wasn't allocated?\n"); + return; + } + spin_lock_bh(&txq->lock); while (txq->write_ptr != txq->read_ptr) { IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n", -- GitLab From 2d6bc752cc2806366d9a4fd577b3f6c1f7a7e04e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jan 2021 13:05:56 +0200 Subject: [PATCH 0600/1084] iwlwifi: pcie: fix context info memory leak If the image loader allocation fails, we leak all the previously allocated memory. Fix this. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130252.97172cbaa67c.I3473233d0ad01a71aa9400832fb2b9f494d88a11@changeid --- .../net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index 342a53e4488c7..5b5134dd49af8 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -198,8 +198,10 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, /* Allocate IML */ iml_img = dma_alloc_coherent(trans->dev, trans->iml_len, &trans_pcie->iml_dma_addr, GFP_KERNEL); - if (!iml_img) - return -ENOMEM; + if (!iml_img) { + ret = -ENOMEM; + goto err_free_ctxt_info; + } memcpy(iml_img, trans->iml, trans->iml_len); @@ -237,6 +239,11 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, return 0; +err_free_ctxt_info: + dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3), + trans_pcie->ctxt_info_gen3, + trans_pcie->ctxt_info_dma_addr); + trans_pcie->ctxt_info_gen3 = NULL; err_free_prph_info: dma_free_coherent(trans->dev, sizeof(*prph_info), -- GitLab From 6701317476bbfb1f341aa935ddf75eb73af784f9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jan 2021 13:05:57 +0200 Subject: [PATCH 0601/1084] iwlwifi: pcie: use jiffies for memory read spin time limit There's no reason to use ktime_get() since we don't need any better precision than jiffies, and since we no longer disable interrupts around this code (when grabbing NIC access), jiffies will work fine. Use jiffies instead of ktime_get(). This cleanup is preparation for the following patch "iwlwifi: pcie: reschedule in long-running memory reads". The code gets simpler with the weird clock use etc. removed before we add cond_resched(). Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130253.621c948b1fad.I3ee9f4bc4e74a0c9125d42fb7c35cd80df4698a1@changeid --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 285e0d5860210..e3760c41b31e5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2107,7 +2107,7 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, while (offs < dwords) { /* limit the time we spin here under lock to 1/2s */ - ktime_t timeout = ktime_add_us(ktime_get(), 500 * USEC_PER_MSEC); + unsigned long end = jiffies + HZ / 2; if (iwl_trans_grab_nic_access(trans, &flags)) { iwl_write32(trans, HBUS_TARG_MEM_RADDR, @@ -2118,11 +2118,7 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, HBUS_TARG_MEM_RDAT); offs++; - /* calling ktime_get is expensive so - * do it once in 128 reads - */ - if (offs % 128 == 0 && ktime_after(ktime_get(), - timeout)) + if (time_after(jiffies, end)) break; } iwl_trans_release_nic_access(trans, &flags); -- GitLab From 3d372c4edfd4dffb7dea71c6b096fb414782b776 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jan 2021 13:05:58 +0200 Subject: [PATCH 0602/1084] iwlwifi: pcie: reschedule in long-running memory reads If we spin for a long time in memory reads that (for some reason in hardware) take a long time, then we'll eventually get messages such as watchdog: BUG: soft lockup - CPU#2 stuck for 24s! [kworker/2:2:272] This is because the reading really does take a very long time, and we don't schedule, so we're hogging the CPU with this task, at least if CONFIG_PREEMPT is not set, e.g. with CONFIG_PREEMPT_VOLUNTARY=y. Previously I misinterpreted the situation and thought that this was only going to happen if we had interrupts disabled, and then fixed this (which is good anyway, however), but that didn't always help; looking at it again now I realized that the spin unlock will only reschedule if CONFIG_PREEMPT is used. In order to avoid this issue, change the code to cond_resched() if we've been spinning for too long here. Signed-off-by: Johannes Berg Fixes: 04516706bb99 ("iwlwifi: pcie: limit memory read spin time") Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210115130253.217a9d6a6a12.If964cb582ab0aaa94e81c4ff3b279eaafda0fd3f@changeid --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index e3760c41b31e5..ab93a848a4667 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2108,6 +2108,7 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, while (offs < dwords) { /* limit the time we spin here under lock to 1/2s */ unsigned long end = jiffies + HZ / 2; + bool resched = false; if (iwl_trans_grab_nic_access(trans, &flags)) { iwl_write32(trans, HBUS_TARG_MEM_RADDR, @@ -2118,10 +2119,15 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, HBUS_TARG_MEM_RDAT); offs++; - if (time_after(jiffies, end)) + if (time_after(jiffies, end)) { + resched = true; break; + } } iwl_trans_release_nic_access(trans, &flags); + + if (resched) + cond_resched(); } else { return -EBUSY; } -- GitLab From 3c4f6ecd93442f4376a58b38bb40ee0b8c46e0e6 Mon Sep 17 00:00:00 2001 From: Pho Tran Date: Mon, 25 Jan 2021 09:26:54 +0000 Subject: [PATCH 0603/1084] USB: serial: cp210x: add pid/vid for WSDA-200-USB Information pid/vid of WSDA-200-USB, Lord corporation company: vid: 199b pid: ba30 Signed-off-by: Pho Tran [ johan: amend comment with product name ] Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 06f3cfc9f19aa..7bec1e730b209 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -202,6 +202,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */ { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */ + { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */ { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ -- GitLab From aefbe5c445c7e2f0e082b086ba1e45502dac4b0e Mon Sep 17 00:00:00 2001 From: Matt Chen Date: Fri, 22 Jan 2021 14:52:36 +0200 Subject: [PATCH 0604/1084] iwlwifi: mvm: fix the return type for DSM functions 1 and 2 The return type value of functions 1 and 2 were considered to be an integer inside a buffer, but they can also be only an integer, without the buffer. Fix the code in iwl_acpi_get_dsm_u8() to handle it as a single integer value, as well as packed inside a buffer. Signed-off-by: Matt Chen Fixes: 9db93491f29e ("iwlwifi: acpi: support device specific method (DSM)") Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210122144849.5757092adcd6.Ic24524627b899c9a01af38107a62a626bdf5ae3a@changeid --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 65 +++++++++++++++----- drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 7 ++- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 25 ++++---- 3 files changed, 68 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 15248b0643803..d8b7776a8dde1 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -80,19 +80,45 @@ static void *iwl_acpi_get_dsm_object(struct device *dev, int rev, int func, } /* - * Evaluate a DSM with no arguments and a single u8 return value (inside a - * buffer object), verify and return that value. + * Generic function to evaluate a DSM with no arguments + * and an integer return value, + * (as an integer object or inside a buffer object), + * verify and assign the value in the "value" parameter. + * return 0 in success and the appropriate errno otherwise. */ -int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func) +static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, + u64 *value, size_t expected_size) { union acpi_object *obj; - int ret; + int ret = 0; obj = iwl_acpi_get_dsm_object(dev, rev, func, NULL); - if (IS_ERR(obj)) + if (IS_ERR(obj)) { + IWL_DEBUG_DEV_RADIO(dev, + "Failed to get DSM object. func= %d\n", + func); return -ENOENT; + } + + if (obj->type == ACPI_TYPE_INTEGER) { + *value = obj->integer.value; + } else if (obj->type == ACPI_TYPE_BUFFER) { + __le64 le_value = 0; - if (obj->type != ACPI_TYPE_BUFFER) { + if (WARN_ON_ONCE(expected_size > sizeof(le_value))) + return -EINVAL; + + /* if the buffer size doesn't match the expected size */ + if (obj->buffer.length != expected_size) + IWL_DEBUG_DEV_RADIO(dev, + "ACPI: DSM invalid buffer size, padding or truncating (%d)\n", + obj->buffer.length); + + /* assuming LE from Intel BIOS spec */ + memcpy(&le_value, obj->buffer.pointer, + min_t(size_t, expected_size, (size_t)obj->buffer.length)); + *value = le64_to_cpu(le_value); + } else { IWL_DEBUG_DEV_RADIO(dev, "ACPI: DSM method did not return a valid object, type=%d\n", obj->type); @@ -100,15 +126,6 @@ int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func) goto out; } - if (obj->buffer.length != sizeof(u8)) { - IWL_DEBUG_DEV_RADIO(dev, - "ACPI: DSM method returned invalid buffer, length=%d\n", - obj->buffer.length); - ret = -EINVAL; - goto out; - } - - ret = obj->buffer.pointer[0]; IWL_DEBUG_DEV_RADIO(dev, "ACPI: DSM method evaluated: func=%d, ret=%d\n", func, ret); @@ -116,6 +133,24 @@ int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func) ACPI_FREE(obj); return ret; } + +/* + * Evaluate a DSM with no arguments and a u8 return value, + */ +int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func, u8 *value) +{ + int ret; + u64 val; + + ret = iwl_acpi_get_dsm_integer(dev, rev, func, &val, sizeof(u8)); + + if (ret < 0) + return ret; + + /* cast val (u64) to be u8 */ + *value = (u8)val; + return 0; +} IWL_EXPORT_SYMBOL(iwl_acpi_get_dsm_u8); union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 042dd247d387d..1cce30d1ef559 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2020 Intel Corporation + * Copyright (C) 2018-2021 Intel Corporation */ #ifndef __iwl_fw_acpi__ #define __iwl_fw_acpi__ @@ -99,7 +99,7 @@ struct iwl_fw_runtime; void *iwl_acpi_get_object(struct device *dev, acpi_string method); -int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func); +int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func, u8 *value); union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev, union acpi_object *data, @@ -159,7 +159,8 @@ static inline void *iwl_acpi_get_dsm_object(struct device *dev, int rev, return ERR_PTR(-ENOENT); } -static inline int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func) +static inline +int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func, u8 *value) { return -ENOENT; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 0637eb1cff4e5..313e9f106f465 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1090,20 +1090,22 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm) static u8 iwl_mvm_eval_dsm_indonesia_5g2(struct iwl_mvm *mvm) { + u8 value; + int ret = iwl_acpi_get_dsm_u8((&mvm->fwrt)->dev, 0, - DSM_FUNC_ENABLE_INDONESIA_5G2); + DSM_FUNC_ENABLE_INDONESIA_5G2, &value); if (ret < 0) IWL_DEBUG_RADIO(mvm, "Failed to evaluate DSM function ENABLE_INDONESIA_5G2, ret=%d\n", ret); - else if (ret >= DSM_VALUE_INDONESIA_MAX) + else if (value >= DSM_VALUE_INDONESIA_MAX) IWL_DEBUG_RADIO(mvm, - "DSM function ENABLE_INDONESIA_5G2 return invalid value, ret=%d\n", - ret); + "DSM function ENABLE_INDONESIA_5G2 return invalid value, value=%d\n", + value); - else if (ret == DSM_VALUE_INDONESIA_ENABLE) { + else if (value == DSM_VALUE_INDONESIA_ENABLE) { IWL_DEBUG_RADIO(mvm, "Evaluated DSM function ENABLE_INDONESIA_5G2: Enabling 5g2\n"); return DSM_VALUE_INDONESIA_ENABLE; @@ -1114,25 +1116,26 @@ static u8 iwl_mvm_eval_dsm_indonesia_5g2(struct iwl_mvm *mvm) static u8 iwl_mvm_eval_dsm_disable_srd(struct iwl_mvm *mvm) { + u8 value; int ret = iwl_acpi_get_dsm_u8((&mvm->fwrt)->dev, 0, - DSM_FUNC_DISABLE_SRD); + DSM_FUNC_DISABLE_SRD, &value); if (ret < 0) IWL_DEBUG_RADIO(mvm, "Failed to evaluate DSM function DISABLE_SRD, ret=%d\n", ret); - else if (ret >= DSM_VALUE_SRD_MAX) + else if (value >= DSM_VALUE_SRD_MAX) IWL_DEBUG_RADIO(mvm, - "DSM function DISABLE_SRD return invalid value, ret=%d\n", - ret); + "DSM function DISABLE_SRD return invalid value, value=%d\n", + value); - else if (ret == DSM_VALUE_SRD_PASSIVE) { + else if (value == DSM_VALUE_SRD_PASSIVE) { IWL_DEBUG_RADIO(mvm, "Evaluated DSM function DISABLE_SRD: setting SRD to passive\n"); return DSM_VALUE_SRD_PASSIVE; - } else if (ret == DSM_VALUE_SRD_DISABLE) { + } else if (value == DSM_VALUE_SRD_DISABLE) { IWL_DEBUG_RADIO(mvm, "Evaluated DSM function DISABLE_SRD: disabling SRD\n"); return DSM_VALUE_SRD_DISABLE; -- GitLab From e223e42aac30bf81f9302c676cdf58cf2bf36950 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Fri, 22 Jan 2021 14:52:37 +0200 Subject: [PATCH 0605/1084] iwlwifi: mvm: invalidate IDs of internal stations at mvm start Having sta_id not set for aux_sta and snif_sta can potentially lead to a hard to debug issue in case remove station is called without an add. In this case sta_id 0, an unrelated regular station, will be removed. In fact, we do have a FW assert that occures rarely and from the debug data analysis it looks like sta_id 0 is removed by mistake, though it's hard to pinpoint the exact flow. The WARN_ON in this patch should help to find it. Signed-off-by: Gregory Greenman Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210122144849.5dc6dd9b22d5.I2add1b5ad24d0d0a221de79d439c09f88fcaf15d@changeid --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 ++++ drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 98f62d78cf9ca..03b41d911338d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -791,6 +791,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (!mvm->scan_cmd) goto out_free; + /* invalidate ids to prevent accidental removal of sta_id 0 */ + mvm->aux_sta.sta_id = IWL_MVM_INVALID_STA; + mvm->snif_sta.sta_id = IWL_MVM_INVALID_STA; + /* Set EBS as successful as long as not stated otherwise by the FW. */ mvm->last_ebs_successful = true; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index dc174410bf9c2..578c353ae02c9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -2057,6 +2057,9 @@ int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) lockdep_assert_held(&mvm->mutex); + if (WARN_ON_ONCE(mvm->snif_sta.sta_id == IWL_MVM_INVALID_STA)) + return -EINVAL; + iwl_mvm_disable_txq(mvm, NULL, mvm->snif_queue, IWL_MAX_TID_COUNT, 0); ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id); if (ret) @@ -2071,6 +2074,9 @@ int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm) lockdep_assert_held(&mvm->mutex); + if (WARN_ON_ONCE(mvm->aux_sta.sta_id == IWL_MVM_INVALID_STA)) + return -EINVAL; + iwl_mvm_disable_txq(mvm, NULL, mvm->aux_queue, IWL_MAX_TID_COUNT, 0); ret = iwl_mvm_rm_sta_common(mvm, mvm->aux_sta.sta_id); if (ret) -- GitLab From 16062c12edb8ed2dfb15e6a914ff4edf858ab9e0 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 22 Jan 2021 14:52:38 +0200 Subject: [PATCH 0606/1084] iwlwifi: pcie: add rules to match Qu with Hr2 Until now we have been relying on matching the PCI ID and subsystem device ID in order to recognize Qu devices with Hr2. Add rules to match these devices, so that we don't have to add a new rule for every new ID we get. Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210122144849.591ce253ddd8.Ia4b9cc2c535625890c6d6b560db97ee9f2d5ca3b@changeid --- .../net/wireless/intel/iwlwifi/cfg/22000.c | 25 +++++++++++++++++++ .../net/wireless/intel/iwlwifi/iwl-config.h | 3 +++ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 10 ++++++++ 3 files changed, 38 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 7220fc8fd9b0d..8280092066e77 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -314,6 +314,7 @@ const struct iwl_cfg_trans_params iwl_ma_trans_cfg = { const char iwl_ax101_name[] = "Intel(R) Wi-Fi 6 AX101"; const char iwl_ax200_name[] = "Intel(R) Wi-Fi 6 AX200 160MHz"; const char iwl_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz"; +const char iwl_ax203_name[] = "Intel(R) Wi-Fi 6 AX203"; const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6 AX211 160MHz"; const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6 AX411 160MHz"; const char iwl_ma_name[] = "Intel(R) Wi-Fi 6"; @@ -340,6 +341,18 @@ const struct iwl_cfg iwl_qu_b0_hr1_b0 = { .num_rbds = IWL_NUM_RBDS_22000_HE, }; +const struct iwl_cfg iwl_qu_b0_hr_b0 = { + .fw_name_pre = IWL_QU_B_HR_B_FW_PRE, + IWL_DEVICE_22500, + /* + * This device doesn't support receiving BlockAck with a large bitmap + * so we need to restrict the size of transmitted aggregation to the + * HT size; mac80211 would otherwise pick the HE max (256) by default. + */ + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, +}; + const struct iwl_cfg iwl_ax201_cfg_qu_hr = { .name = "Intel(R) Wi-Fi 6 AX201 160MHz", .fw_name_pre = IWL_QU_B_HR_B_FW_PRE, @@ -366,6 +379,18 @@ const struct iwl_cfg iwl_qu_c0_hr1_b0 = { .num_rbds = IWL_NUM_RBDS_22000_HE, }; +const struct iwl_cfg iwl_qu_c0_hr_b0 = { + .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, + IWL_DEVICE_22500, + /* + * This device doesn't support receiving BlockAck with a large bitmap + * so we need to restrict the size of transmitted aggregation to the + * HT size; mac80211 would otherwise pick the HE max (256) by default. + */ + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, +}; + const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0 = { .name = "Intel(R) Wi-Fi 6 AX201 160MHz", .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 27cb0406ba9a2..4826f5575dae6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -491,6 +491,7 @@ extern const char iwl9260_killer_1550_name[]; extern const char iwl9560_killer_1550i_name[]; extern const char iwl9560_killer_1550s_name[]; extern const char iwl_ax200_name[]; +extern const char iwl_ax203_name[]; extern const char iwl_ax201_name[]; extern const char iwl_ax101_name[]; extern const char iwl_ax200_killer_1650w_name[]; @@ -574,6 +575,8 @@ extern const struct iwl_cfg iwl9560_2ac_cfg_soc; extern const struct iwl_cfg iwl_qu_b0_hr1_b0; extern const struct iwl_cfg iwl_qu_c0_hr1_b0; extern const struct iwl_cfg iwl_quz_a0_hr1_b0; +extern const struct iwl_cfg iwl_qu_b0_hr_b0; +extern const struct iwl_cfg iwl_qu_c0_hr_b0; extern const struct iwl_cfg iwl_ax200_cfg_cc; extern const struct iwl_cfg iwl_ax201_cfg_qu_hr; extern const struct iwl_cfg iwl_ax201_cfg_qu_hr; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 965982612e740..ed3f5b7aa71e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -910,6 +910,11 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_qu_b0_hr1_b0, iwl_ax101_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, + iwl_qu_b0_hr_b0, iwl_ax203_name), /* Qu C step */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, @@ -917,6 +922,11 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_qu_c0_hr1_b0, iwl_ax101_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, + iwl_qu_c0_hr_b0, iwl_ax203_name), /* QuZ */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, -- GitLab From 96d2bfb7948a96709ba57084d64ac56c1730557c Mon Sep 17 00:00:00 2001 From: Shaul Triebitz Date: Fri, 22 Jan 2021 14:52:39 +0200 Subject: [PATCH 0607/1084] iwlwifi: mvm: clear IN_D3 after wowlan status cmd In D3 resume flow, avoid the following race where sending packets before updating the sequence number (sequence number received from the wowlan status command response): Thread 1: __iwl_mvm_resume clears IWL_MVM_STATUS_IN_D3 and is cut by thread 2 before reaching iwl_mvm_query_wakeup_reasons. Thread 2: iwl_mvm_mac_itxq_xmit calls iwl_mvm_tx_skb since IWL_MVM_STATUS_IN_D3 is not set using a wrong sequence number. Thread 1: __iwl_mvm_resume continues and calls iwl_mvm_query_wakeup_reasons updating the sequence number received from the firmware. The next packet that will be sent now will cause sysassert 0x1096. Fix the bug by moving 'clear IWL_MVM_STATUS_IN_D3' to after sending the wowlan status command and updating the sequence number. Signed-off-by: Shaul Triebitz Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210122144849.fe927ec939c6.I103d3321fb55da7e6c6c51582cfadf94eb8b6c58@changeid --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index c025188fa9bc5..df018972a46bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2020 Intel Corporation + * Copyright (C) 2012-2014, 2018-2021 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -2032,8 +2032,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) mutex_lock(&mvm->mutex); - clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); - /* get the BSS vif pointer again */ vif = iwl_mvm_get_bss_vif(mvm); if (IS_ERR_OR_NULL(vif)) @@ -2148,6 +2146,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) iwl_mvm_d3_disconnect_iter, keep ? vif : NULL); out: + clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); + /* no need to reset the device in unified images, if successful */ if (unified_image && !ret) { /* nothing else to do if we already sent D0I3_END_CMD */ -- GitLab From 4886460c4d1576e85b12601b8b328278a483df86 Mon Sep 17 00:00:00 2001 From: Matti Gottlieb Date: Fri, 22 Jan 2021 14:52:40 +0200 Subject: [PATCH 0608/1084] iwlwifi: Fix IWL_SUBDEVICE_NO_160 macro to use the correct bit. The bit that indicates if the device supports 160MHZ is bit #9. The macro checks bit #8. Fix IWL_SUBDEVICE_NO_160 macro to use the correct bit. Signed-off-by: Matti Gottlieb Fixes: d6f2134a3831 ("iwlwifi: add mac/rf types and 160MHz to the device tables") Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210122144849.bddbf9b57a75.I16e09e2b1404b16bfff70852a5a654aa468579e2@changeid --- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 4826f5575dae6..86e1d57df65ed 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2018-2020 Intel Corporation + * Copyright (C) 2005-2014, 2018-2021 Intel Corporation * Copyright (C) 2016-2017 Intel Deutschland GmbH */ #ifndef __IWL_CONFIG_H__ @@ -445,7 +445,7 @@ struct iwl_cfg { #define IWL_CFG_CORES_BT_GNSS 0x5 #define IWL_SUBDEVICE_RF_ID(subdevice) ((u16)((subdevice) & 0x00F0) >> 4) -#define IWL_SUBDEVICE_NO_160(subdevice) ((u16)((subdevice) & 0x0100) >> 9) +#define IWL_SUBDEVICE_NO_160(subdevice) ((u16)((subdevice) & 0x0200) >> 9) #define IWL_SUBDEVICE_CORES(subdevice) ((u16)((subdevice) & 0x1C00) >> 10) struct iwl_dev_info { -- GitLab From 7a21b1d4a728a483f07c638ccd8610d4b4f12684 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jan 2021 14:52:41 +0200 Subject: [PATCH 0609/1084] iwlwifi: mvm: guard against device removal in reprobe If we get into a problem severe enough to attempt a reprobe, we schedule a worker to do that. However, if the problem gets more severe and the device is actually destroyed before this worker has a chance to run, we use a free device. Bump up the reference count of the device until the worker runs to avoid this situation. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210122144849.871f0892e4b2.I94819e11afd68d875f3e242b98bef724b8236f1e@changeid --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 03b41d911338d..61618f607927d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1209,6 +1209,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk) reprobe = container_of(wk, struct iwl_mvm_reprobe, work); if (device_reprobe(reprobe->dev)) dev_err(reprobe->dev, "reprobe failed!\n"); + put_device(reprobe->dev); kfree(reprobe); module_put(THIS_MODULE); } @@ -1259,7 +1260,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) module_put(THIS_MODULE); return; } - reprobe->dev = mvm->trans->dev; + reprobe->dev = get_device(mvm->trans->dev); INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); schedule_work(&reprobe->work); } else if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, -- GitLab From 0bed6a2a14afaae240cc431e49c260568488b51c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jan 2021 14:52:42 +0200 Subject: [PATCH 0610/1084] iwlwifi: queue: bail out on invalid freeing If we find an entry without an SKB, we currently continue, but that will just result in an infinite loop since we won't increment the read pointer, and will try the same thing over and over again. Fix this. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20210122144849.abe2dedcc3ac.Ia6b03f9eeb617fd819e56dd5376f4bb8edc7b98a@changeid --- drivers/net/wireless/intel/iwlwifi/queue/tx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c index 62c0c4cbe481a..7ff1bb0ccc9cd 100644 --- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c @@ -840,10 +840,8 @@ void iwl_txq_gen2_unmap(struct iwl_trans *trans, int txq_id) int idx = iwl_txq_get_cmd_index(txq, txq->read_ptr); struct sk_buff *skb = txq->entries[idx].skb; - if (WARN_ON_ONCE(!skb)) - continue; - - iwl_txq_free_tso_page(trans, skb); + if (!WARN_ON_ONCE(!skb)) + iwl_txq_free_tso_page(trans, skb); } iwl_txq_gen2_free_tfd(trans, txq); txq->read_ptr = iwl_txq_inc_wrap(trans, txq->read_ptr); -- GitLab From 0acb20a5438c36e0cf2b8bf255f314b59fcca6ef Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 17 Jan 2021 22:46:01 +0100 Subject: [PATCH 0611/1084] mt7601u: fix kernel crash unplugging the device The following crash log can occur unplugging the usb dongle since, after the urb poison in mt7601u_free_tx_queue(), usb_submit_urb() will always fail resulting in a skb kfree while the skb has been already queued. Fix the issue enqueuing the skb only if usb_submit_urb() succeed. Hardware name: Hewlett-Packard 500-539ng/2B2C, BIOS 80.06 04/01/2015 Workqueue: usb_hub_wq hub_event RIP: 0010:skb_trim+0x2c/0x30 RSP: 0000:ffffb4c88005bba8 EFLAGS: 00010206 RAX: 000000004ad483ee RBX: ffff9a236625dee0 RCX: 000000000000662f RDX: 000000000000000c RSI: 0000000000000000 RDI: ffff9a2343179300 RBP: ffff9a2343179300 R08: 0000000000000001 R09: 0000000000000000 R10: ffff9a23748f7840 R11: 0000000000000001 R12: ffff9a236625e4d4 R13: ffff9a236625dee0 R14: 0000000000001080 R15: 0000000000000008 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fd410a34ef8 CR3: 00000001416ee001 CR4: 00000000001706f0 Call Trace: mt7601u_tx_status+0x3e/0xa0 [mt7601u] mt7601u_dma_cleanup+0xca/0x110 [mt7601u] mt7601u_cleanup+0x22/0x30 [mt7601u] mt7601u_disconnect+0x22/0x60 [mt7601u] usb_unbind_interface+0x8a/0x270 ? kernfs_find_ns+0x35/0xd0 __device_release_driver+0x17a/0x230 device_release_driver+0x24/0x30 bus_remove_device+0xdb/0x140 device_del+0x18b/0x430 ? kobject_put+0x98/0x1d0 usb_disable_device+0xc6/0x1f0 usb_disconnect.cold+0x7e/0x20a hub_event+0xbf3/0x1870 process_one_work+0x1b6/0x350 worker_thread+0x53/0x3e0 ? process_one_work+0x350/0x350 kthread+0x11b/0x140 ? __kthread_bind_mask+0x60/0x60 ret_from_fork+0x22/0x30 Fixes: 23377c200b2eb ("mt7601u: fix possible memory leak when the device is disconnected") Signed-off-by: Lorenzo Bianconi Acked-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/3b85219f669a63a8ced1f43686de05915a580489.1610919247.git.lorenzo@kernel.org --- drivers/net/wireless/mediatek/mt7601u/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c index 47710da5b2a58..af7d1ecb777c0 100644 --- a/drivers/net/wireless/mediatek/mt7601u/dma.c +++ b/drivers/net/wireless/mediatek/mt7601u/dma.c @@ -309,7 +309,6 @@ static int mt7601u_dma_submit_tx(struct mt7601u_dev *dev, } e = &q->e[q->end]; - e->skb = skb; usb_fill_bulk_urb(e->urb, usb_dev, snd_pipe, skb->data, skb->len, mt7601u_complete_tx, q); ret = usb_submit_urb(e->urb, GFP_ATOMIC); @@ -327,6 +326,7 @@ static int mt7601u_dma_submit_tx(struct mt7601u_dev *dev, q->end = (q->end + 1) % q->entries; q->used++; + e->skb = skb; if (q->used >= q->entries) ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb)); -- GitLab From e500b805c39daff2670494fff94909d7e3d094d9 Mon Sep 17 00:00:00 2001 From: Andrew Scull Date: Mon, 25 Jan 2021 14:54:15 +0000 Subject: [PATCH 0612/1084] KVM: arm64: Don't clobber x4 in __do_hyp_init arm_smccc_1_1_hvc() only adds write contraints for x0-3 in the inline assembly for the HVC instruction so make sure those are the only registers that change when __do_hyp_init is called. Tested-by: David Brazdil Signed-off-by: Andrew Scull Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210125145415.122439-3-ascull@google.com --- arch/arm64/kvm/hyp/nvhe/hyp-init.S | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-init.S b/arch/arm64/kvm/hyp/nvhe/hyp-init.S index 31b060a440452..b17bf19217f11 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-init.S +++ b/arch/arm64/kvm/hyp/nvhe/hyp-init.S @@ -47,6 +47,8 @@ __invalid: b . /* + * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers. + * * x0: SMCCC function ID * x1: struct kvm_nvhe_init_params PA */ @@ -70,9 +72,9 @@ __do_hyp_init: eret 1: mov x0, x1 - mov x4, lr - bl ___kvm_hyp_init - mov lr, x4 + mov x3, lr + bl ___kvm_hyp_init // Clobbers x0..x2 + mov lr, x3 /* Hello, World! */ mov x0, #SMCCC_RET_SUCCESS @@ -82,8 +84,8 @@ SYM_CODE_END(__kvm_hyp_init) /* * Initialize the hypervisor in EL2. * - * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers - * and leave x4 for the caller. + * Only uses x0..x2 so as to not clobber callee-saved SMCCC registers + * and leave x3 for the caller. * * x0: struct kvm_nvhe_init_params PA */ @@ -112,9 +114,9 @@ alternative_else_nop_endif /* * Set the PS bits in TCR_EL2. */ - ldr x1, [x0, #NVHE_INIT_TCR_EL2] - tcr_compute_pa_size x1, #TCR_EL2_PS_SHIFT, x2, x3 - msr tcr_el2, x1 + ldr x0, [x0, #NVHE_INIT_TCR_EL2] + tcr_compute_pa_size x0, #TCR_EL2_PS_SHIFT, x1, x2 + msr tcr_el2, x0 isb @@ -193,7 +195,7 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu) /* Enable MMU, set vectors and stack. */ mov x0, x28 - bl ___kvm_hyp_init // Clobbers x0..x3 + bl ___kvm_hyp_init // Clobbers x0..x2 /* Leave idmap. */ mov x0, x29 -- GitLab From 36af2d5c4433fb40ee2af912c4ac0a30991aecfc Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Fri, 22 Jan 2021 20:53:02 +0800 Subject: [PATCH 0613/1084] ACPI: sysfs: Prefer "compatible" modalias Commit 8765c5ba1949 ("ACPI / scan: Rework modalias creation when "compatible" is present") may create two "MODALIAS=" in one uevent file if specific conditions are met. This breaks systemd-udevd, which assumes each "key" in one uevent file to be unique. The internal implementation of systemd-udevd overwrites the first MODALIAS with the second one, so its kmod rule doesn't load the driver for the first MODALIAS. So if both the ACPI modalias and the OF modalias are present, use the latter to ensure that there will be only one MODALIAS. Link: https://github.com/systemd/systemd/pull/18163 Suggested-by: Mika Westerberg Fixes: 8765c5ba1949 ("ACPI / scan: Rework modalias creation when "compatible" is present") Signed-off-by: Kai-Heng Feng Reviewed-by: Mika Westerberg Reviewed-by: Greg Kroah-Hartman Cc: 4.1+ # 4.1+ [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_sysfs.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 96869f1538b93..bfca116482b8b 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -251,20 +251,12 @@ int __acpi_device_uevent_modalias(struct acpi_device *adev, if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM; - len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], - sizeof(env->buf) - env->buflen); - if (len < 0) - return len; - - env->buflen += len; - if (!adev->data.of_compatible) - return 0; - - if (len > 0 && add_uevent_var(env, "MODALIAS=")) - return -ENOMEM; - - len = create_of_modalias(adev, &env->buf[env->buflen - 1], - sizeof(env->buf) - env->buflen); + if (adev->data.of_compatible) + len = create_of_modalias(adev, &env->buf[env->buflen - 1], + sizeof(env->buf) - env->buflen); + else + len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], + sizeof(env->buf) - env->buflen); if (len < 0) return len; -- GitLab From 81b704d3e4674e09781d331df73d76675d5ad8cb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 14 Jan 2021 19:34:22 +0100 Subject: [PATCH 0614/1084] ACPI: thermal: Do not call acpi_thermal_check() directly Calling acpi_thermal_check() from acpi_thermal_notify() directly is problematic if _TMP triggers Notify () on the thermal zone for which it has been evaluated (which happens on some systems), because it causes a new acpi_thermal_notify() invocation to be queued up every time and if that takes place too often, an indefinite number of pending work items may accumulate in kacpi_notify_wq over time. Besides, it is not really useful to queue up a new invocation of acpi_thermal_check() if one of them is pending already. For these reasons, rework acpi_thermal_notify() to queue up a thermal check instead of calling acpi_thermal_check() directly and only allow one thermal check to be pending at a time. Moreover, only allow one acpi_thermal_check_fn() instance at a time to run thermal_zone_device_update() for one thermal zone and make it return early if it sees other instances running for the same thermal zone. While at it, fold acpi_thermal_check() into acpi_thermal_check_fn(), as it is only called from there after the other changes made here. [This issue appears to have been exposed by commit 6d25be5782e4 ("sched/core, workqueues: Distangle worker accounting from rq lock"), but it is unclear why it was not visible earlier.] BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208877 Reported-by: Stephen Berman Diagnosed-by: Sebastian Andrzej Siewior Signed-off-by: Rafael J. Wysocki Reviewed-by: Sebastian Andrzej Siewior Tested-by: Stephen Berman Cc: All applicable --- drivers/acpi/thermal.c | 46 ++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 12c0ece746f04..859b1de31ddc0 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -174,6 +174,8 @@ struct acpi_thermal { struct thermal_zone_device *thermal_zone; int kelvin_offset; /* in millidegrees */ struct work_struct thermal_check_work; + struct mutex thermal_check_lock; + refcount_t thermal_check_count; }; /* -------------------------------------------------------------------------- @@ -495,14 +497,6 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) return 0; } -static void acpi_thermal_check(void *data) -{ - struct acpi_thermal *tz = data; - - thermal_zone_device_update(tz->thermal_zone, - THERMAL_EVENT_UNSPECIFIED); -} - /* sys I/F for generic thermal sysfs support */ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) @@ -900,6 +894,12 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) Driver Interface -------------------------------------------------------------------------- */ +static void acpi_queue_thermal_check(struct acpi_thermal *tz) +{ + if (!work_pending(&tz->thermal_check_work)) + queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); +} + static void acpi_thermal_notify(struct acpi_device *device, u32 event) { struct acpi_thermal *tz = acpi_driver_data(device); @@ -910,17 +910,17 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event) switch (event) { case ACPI_THERMAL_NOTIFY_TEMPERATURE: - acpi_thermal_check(tz); + acpi_queue_thermal_check(tz); break; case ACPI_THERMAL_NOTIFY_THRESHOLDS: acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); - acpi_thermal_check(tz); + acpi_queue_thermal_check(tz); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); break; case ACPI_THERMAL_NOTIFY_DEVICES: acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); - acpi_thermal_check(tz); + acpi_queue_thermal_check(tz); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); break; @@ -1020,7 +1020,25 @@ static void acpi_thermal_check_fn(struct work_struct *work) { struct acpi_thermal *tz = container_of(work, struct acpi_thermal, thermal_check_work); - acpi_thermal_check(tz); + + /* + * In general, it is not sufficient to check the pending bit, because + * subsequent instances of this function may be queued after one of them + * has started running (e.g. if _TMP sleeps). Avoid bailing out if just + * one of them is running, though, because it may have done the actual + * check some time ago, so allow at least one of them to block on the + * mutex while another one is running the update. + */ + if (!refcount_dec_not_one(&tz->thermal_check_count)) + return; + + mutex_lock(&tz->thermal_check_lock); + + thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); + + refcount_inc(&tz->thermal_check_count); + + mutex_unlock(&tz->thermal_check_lock); } static int acpi_thermal_add(struct acpi_device *device) @@ -1052,6 +1070,8 @@ static int acpi_thermal_add(struct acpi_device *device) if (result) goto free_memory; + refcount_set(&tz->thermal_check_count, 3); + mutex_init(&tz->thermal_check_lock); INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), @@ -1117,7 +1137,7 @@ static int acpi_thermal_resume(struct device *dev) tz->state.active |= tz->trips.active[i].flags.enabled; } - queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); + acpi_queue_thermal_check(tz); return AE_OK; } -- GitLab From ac55ad2b5fadb6af8826963d7d3331c9950a2608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Mon, 18 Jan 2021 17:55:18 +0100 Subject: [PATCH 0615/1084] s390/dasd: Fix inconsistent kobject removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Our intention was to only remove path kobjects whenever a device is being set offline. However, one corner case was missing. If a device is disabled and enabled (using the IOCTLs BIODASDDISABLE and BIODASDENABLE respectively), the enabling process will call dasd_eckd_reload_device() which itself calls dasd_eckd_read_conf() in order to update path information. During that update, dasd_eckd_clear_conf_data() clears all old data and also removes all kobjects. This will leave us with an inconsistent state of path kobjects and a subsequent path verification leads to a failing kobject creation. Fix this by removing kobjects only in the context of offlining a device as initially intended. Fixes: 19508b204740 ("s390/dasd: Display FC Endpoint Security information via sysfs") Reported-by: Stefan Haberland Signed-off-by: Jan Höppner Reviewed-by: Stefan Haberland Reviewed-by: Cornelia Huck Signed-off-by: Jens Axboe --- drivers/s390/block/dasd_devmap.c | 20 ++++++++++++++------ drivers/s390/block/dasd_eckd.c | 3 ++- drivers/s390/block/dasd_int.h | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 16bb135c20aa5..03d27ee9cac65 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -1874,18 +1874,26 @@ void dasd_path_create_kobjects(struct dasd_device *device) } EXPORT_SYMBOL(dasd_path_create_kobjects); -/* - * As we keep kobjects for the lifetime of a device, this function must not be - * called anywhere but in the context of offlining a device. - */ -void dasd_path_remove_kobj(struct dasd_device *device, int chp) +static void dasd_path_remove_kobj(struct dasd_device *device, int chp) { if (device->path[chp].in_sysfs) { kobject_put(&device->path[chp].kobj); device->path[chp].in_sysfs = false; } } -EXPORT_SYMBOL(dasd_path_remove_kobj); + +/* + * As we keep kobjects for the lifetime of a device, this function must not be + * called anywhere but in the context of offlining a device. + */ +void dasd_path_remove_kobjects(struct dasd_device *device) +{ + int i; + + for (i = 0; i < 8; i++) + dasd_path_remove_kobj(device, i); +} +EXPORT_SYMBOL(dasd_path_remove_kobjects); int dasd_add_sysfs_files(struct ccw_device *cdev) { diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 3caa1ee5f4b0a..65eb87cbbb9b2 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -1036,7 +1036,6 @@ static void dasd_eckd_clear_conf_data(struct dasd_device *device) device->path[i].ssid = 0; device->path[i].chpid = 0; dasd_path_notoper(device, i); - dasd_path_remove_kobj(device, i); } } @@ -2173,6 +2172,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) device->block = NULL; out_err1: dasd_eckd_clear_conf_data(device); + dasd_path_remove_kobjects(device); kfree(device->private); device->private = NULL; return rc; @@ -2191,6 +2191,7 @@ static void dasd_eckd_uncheck_device(struct dasd_device *device) private->vdsneq = NULL; private->gneq = NULL; dasd_eckd_clear_conf_data(device); + dasd_path_remove_kobjects(device); } static struct dasd_ccw_req * diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 3bc008f9136cc..b8a04c42d1d2e 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -858,7 +858,7 @@ int dasd_add_sysfs_files(struct ccw_device *); void dasd_remove_sysfs_files(struct ccw_device *); void dasd_path_create_kobj(struct dasd_device *, int); void dasd_path_create_kobjects(struct dasd_device *); -void dasd_path_remove_kobj(struct dasd_device *, int); +void dasd_path_remove_kobjects(struct dasd_device *); struct dasd_device *dasd_device_from_cdev(struct ccw_device *); struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *); -- GitLab From 24a41a38dd2df065ee942221c2fae5e314770865 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Wed, 20 Jan 2021 03:31:52 +0300 Subject: [PATCH 0616/1084] ASoC: tegra: ahub: Add missing resets AHUB driver misses D_AUDIO and APBIF resets. CPU hangs on trying to access hardware if resets aren't de-asserted. This problem is currently masked by the tegra-clk driver which implicitly de-asserts the resets when the corresponding clocks are enabled. Soon the implicit de-assertion will be gone from the tegra-clk driver, thus we need to fix the AHUB driver. Add the missing resets to the driver. Tested-by: Peter Geis # Ouya T30 audio works Tested-by: Matt Merhar # Ouya T30 boot-tested Tested-by: Dmitry Osipenko # Nexus7 T30 audio works Tested-by: Nicolas Chauvet # TK1 boot-tested Signed-off-by: Dmitry Osipenko Link: https://lore.kernel.org/r/20210120003154.26749-5-digetx@gmail.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra30_ahub.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 156e3b9d613c6..8c32333cc08cc 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -337,6 +337,8 @@ static const struct { const char *rst_name; u32 mod_list_mask; } configlink_mods[] = { + { "d_audio", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "apbif", MOD_LIST_MASK_TEGRA30_OR_LATER }, { "i2s0", MOD_LIST_MASK_TEGRA30_OR_LATER }, { "i2s1", MOD_LIST_MASK_TEGRA30_OR_LATER }, { "i2s2", MOD_LIST_MASK_TEGRA30_OR_LATER }, -- GitLab From 6d8ac9b1dd2f138f4aa39008994600f561eeede8 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Wed, 20 Jan 2021 03:31:53 +0300 Subject: [PATCH 0617/1084] ASoC: tegra: ahub: Use clk_bulk helpers Use clk_bulk helpers to make code cleaner. Tested-by: Peter Geis # Ouya T30 audio works Tested-by: Matt Merhar # Ouya T30 boot-tested Tested-by: Dmitry Osipenko # Nexus7 T30 audio works Tested-by: Nicolas Chauvet # TK1 boot-tested Acked-by: Thierry Reding Signed-off-by: Dmitry Osipenko Link: https://lore.kernel.org/r/20210120003154.26749-6-digetx@gmail.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra30_ahub.c | 30 +++++++----------------------- sound/soc/tegra/tegra30_ahub.h | 4 ++-- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 8c32333cc08cc..12ca8e3ca4f6e 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -45,8 +45,7 @@ static int tegra30_ahub_runtime_suspend(struct device *dev) regcache_cache_only(ahub->regmap_apbif, true); regcache_cache_only(ahub->regmap_ahub, true); - clk_disable_unprepare(ahub->clk_apbif); - clk_disable_unprepare(ahub->clk_d_audio); + clk_bulk_disable_unprepare(ahub->nclocks, ahub->clocks); return 0; } @@ -66,17 +65,9 @@ static int tegra30_ahub_runtime_resume(struct device *dev) { int ret; - ret = clk_prepare_enable(ahub->clk_d_audio); - if (ret) { - dev_err(dev, "clk_enable d_audio failed: %d\n", ret); + ret = clk_bulk_prepare_enable(ahub->nclocks, ahub->clocks); + if (ret) return ret; - } - ret = clk_prepare_enable(ahub->clk_apbif); - if (ret) { - dev_err(dev, "clk_enable apbif failed: %d\n", ret); - clk_disable(ahub->clk_d_audio); - return ret; - } regcache_cache_only(ahub->regmap_apbif, false); regcache_cache_only(ahub->regmap_ahub, false); @@ -559,19 +550,12 @@ static int tegra30_ahub_probe(struct platform_device *pdev) ahub->soc_data = soc_data; ahub->dev = &pdev->dev; - ahub->clk_d_audio = devm_clk_get(&pdev->dev, "d_audio"); - if (IS_ERR(ahub->clk_d_audio)) { - dev_err(&pdev->dev, "Can't retrieve ahub d_audio clock\n"); - ret = PTR_ERR(ahub->clk_d_audio); - return ret; - } + ahub->clocks[ahub->nclocks++].id = "apbif"; + ahub->clocks[ahub->nclocks++].id = "d_audio"; - ahub->clk_apbif = devm_clk_get(&pdev->dev, "apbif"); - if (IS_ERR(ahub->clk_apbif)) { - dev_err(&pdev->dev, "Can't retrieve ahub apbif clock\n"); - ret = PTR_ERR(ahub->clk_apbif); + ret = devm_clk_bulk_get(&pdev->dev, ahub->nclocks, ahub->clocks); + if (ret) return ret; - } res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs_apbif = devm_ioremap_resource(&pdev->dev, res0); diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index 6889c5f23d021..01480d7dc940b 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h @@ -511,8 +511,8 @@ struct tegra30_ahub_soc_data { struct tegra30_ahub { const struct tegra30_ahub_soc_data *soc_data; struct device *dev; - struct clk *clk_d_audio; - struct clk *clk_apbif; + struct clk_bulk_data clocks[2]; + unsigned int nclocks; resource_size_t apbif_addr; struct regmap *regmap_apbif; struct regmap *regmap_ahub; -- GitLab From ed9ce1ed2239909c23d48c723c6549417c476246 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Wed, 20 Jan 2021 03:31:54 +0300 Subject: [PATCH 0618/1084] ASoC: tegra: ahub: Reset hardware properly Assert hardware resets before clocks are enabled and then de-assert them after clocks are enabled. This brings hardware into a predictable state. Tested-by: Peter Geis # Ouya T30 audio works Tested-by: Matt Merhar # Ouya T30 boot-tested Tested-by: Dmitry Osipenko # Nexus7 T30 audio works Tested-by: Nicolas Chauvet # TK1 boot-tested Signed-off-by: Dmitry Osipenko Link: https://lore.kernel.org/r/20210120003154.26749-7-digetx@gmail.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra30_ahub.c | 36 ++++++++++++++++++++++++++++++---- sound/soc/tegra/tegra30_ahub.h | 1 + 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 12ca8e3ca4f6e..9ef05ca4f6c4d 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -65,14 +65,39 @@ static int tegra30_ahub_runtime_resume(struct device *dev) { int ret; + ret = reset_control_assert(ahub->reset); + if (ret) + return ret; + ret = clk_bulk_prepare_enable(ahub->nclocks, ahub->clocks); if (ret) return ret; + usleep_range(10, 100); + + ret = reset_control_deassert(ahub->reset); + if (ret) + goto disable_clocks; + regcache_cache_only(ahub->regmap_apbif, false); regcache_cache_only(ahub->regmap_ahub, false); + regcache_mark_dirty(ahub->regmap_apbif); + regcache_mark_dirty(ahub->regmap_ahub); + + ret = regcache_sync(ahub->regmap_apbif); + if (ret) + goto disable_clocks; + + ret = regcache_sync(ahub->regmap_ahub); + if (ret) + goto disable_clocks; return 0; + +disable_clocks: + clk_bulk_disable_unprepare(ahub->nclocks, ahub->clocks); + + return ret; } int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, @@ -519,7 +544,6 @@ static int tegra30_ahub_probe(struct platform_device *pdev) /* * The AHUB hosts a register bus: the "configlink". For this to * operate correctly, all devices on this bus must be out of reset. - * Ensure that here. */ for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) { if (!(configlink_mods[i].mod_list_mask & @@ -535,10 +559,8 @@ static int tegra30_ahub_probe(struct platform_device *pdev) return ret; } - ret = reset_control_deassert(rst); + /* just check presence of the reset control in DT */ reset_control_put(rst); - if (ret) - return ret; } ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), @@ -557,6 +579,12 @@ static int tegra30_ahub_probe(struct platform_device *pdev) if (ret) return ret; + ahub->reset = devm_reset_control_array_get_exclusive(&pdev->dev); + if (IS_ERR(ahub->reset)) { + dev_err(&pdev->dev, "Can't get resets: %pe\n", ahub->reset); + return PTR_ERR(ahub->reset); + } + res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs_apbif = devm_ioremap_resource(&pdev->dev, res0); if (IS_ERR(regs_apbif)) diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index 01480d7dc940b..3b85244f87f19 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h @@ -511,6 +511,7 @@ struct tegra30_ahub_soc_data { struct tegra30_ahub { const struct tegra30_ahub_soc_data *soc_data; struct device *dev; + struct reset_control *reset; struct clk_bulk_data clocks[2]; unsigned int nclocks; resource_size_t apbif_addr; -- GitLab From 56c91a18432b631ca18438841fd1831ef756cabf Mon Sep 17 00:00:00 2001 From: Baoquan He Date: Fri, 22 Jan 2021 15:42:14 +0800 Subject: [PATCH 0619/1084] kernel: kexec: remove the lock operation of system_transition_mutex Function kernel_kexec() is called with lock system_transition_mutex held in reboot system call. While inside kernel_kexec(), it will acquire system_transition_mutex agin. This will lead to dead lock. The dead lock should be easily triggered, it hasn't caused any failure report just because the feature 'kexec jump' is almost not used by anyone as far as I know. An inquiry can be made about who is using 'kexec jump' and where it's used. Before that, let's simply remove the lock operation inside CONFIG_KEXEC_JUMP ifdeffery scope. Fixes: 55f2503c3b69 ("PM / reboot: Eliminate race between reboot and suspend") Signed-off-by: Baoquan He Reported-by: Dan Carpenter Reviewed-by: Pingfan Liu Cc: 4.19+ # 4.19+ Signed-off-by: Rafael J. Wysocki --- kernel/kexec_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 4f8efc278aa75..aa919585c24b4 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1134,7 +1134,6 @@ int kernel_kexec(void) #ifdef CONFIG_KEXEC_JUMP if (kexec_image->preserve_context) { - lock_system_sleep(); pm_prepare_console(); error = freeze_processes(); if (error) { @@ -1197,7 +1196,6 @@ int kernel_kexec(void) thaw_processes(); Restore_console: pm_restore_console(); - unlock_system_sleep(); } #endif -- GitLab From 2f96e40212d435b328459ba6b3956395eed8fa9f Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 15 Jan 2021 16:26:17 -0500 Subject: [PATCH 0620/1084] btrfs: fix possible free space tree corruption with online conversion While running btrfs/011 in a loop I would often ASSERT() while trying to add a new free space entry that already existed, or get an EEXIST while adding a new block to the extent tree, which is another indication of double allocation. This occurs because when we do the free space tree population, we create the new root and then populate the tree and commit the transaction. The problem is when you create a new root, the root node and commit root node are the same. During this initial transaction commit we will run all of the delayed refs that were paused during the free space tree generation, and thus begin to cache block groups. While caching block groups the caching thread will be reading from the main root for the free space tree, so as we make allocations we'll be changing the free space tree, which can cause us to add the same range twice which results in either the ASSERT(ret != -EEXIST); in __btrfs_add_free_space, or in a variety of different errors when running delayed refs because of a double allocation. Fix this by marking the fs_info as unsafe to load the free space tree, and fall back on the old slow method. We could be smarter than this, for example caching the block group while we're populating the free space tree, but since this is a serious problem I've opted for the simplest solution. CC: stable@vger.kernel.org # 4.9+ Fixes: a5ed91828518 ("Btrfs: implement the free space B-tree") Reviewed-by: Filipe Manana Signed-off-by: Josef Bacik Signed-off-by: David Sterba --- fs/btrfs/block-group.c | 10 +++++++++- fs/btrfs/ctree.h | 3 +++ fs/btrfs/free-space-tree.c | 10 +++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 0886e81e55402..48ebc106a606c 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -673,7 +673,15 @@ static noinline void caching_thread(struct btrfs_work *work) wake_up(&caching_ctl->wait); } - if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) + /* + * If we are in the transaction that populated the free space tree we + * can't actually cache from the free space tree as our commit root and + * real root are the same, so we could change the contents of the blocks + * while caching. Instead do the slow caching in this case, and after + * the transaction has committed we will be safe. + */ + if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) && + !(test_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags))) ret = load_free_space_tree(caching_ctl); else ret = load_extent_tree_free(caching_ctl); diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 0225c5208f44c..47ca8edafb5e6 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -564,6 +564,9 @@ enum { /* Indicate that we need to cleanup space cache v1 */ BTRFS_FS_CLEANUP_SPACE_CACHE_V1, + + /* Indicate that we can't trust the free space tree for caching yet */ + BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, }; /* diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c index e33a65bd9a0c2..a33bca94d133e 100644 --- a/fs/btrfs/free-space-tree.c +++ b/fs/btrfs/free-space-tree.c @@ -1150,6 +1150,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info) return PTR_ERR(trans); set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); + set_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags); free_space_root = btrfs_create_tree(trans, BTRFS_FREE_SPACE_TREE_OBJECTID); if (IS_ERR(free_space_root)) { @@ -1171,11 +1172,18 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info) btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE); btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID); clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); + ret = btrfs_commit_transaction(trans); - return btrfs_commit_transaction(trans); + /* + * Now that we've committed the transaction any reading of our commit + * root will be safe, so we can cache from the free space tree now. + */ + clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags); + return ret; abort: clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); + clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags); btrfs_abort_transaction(trans, ret); btrfs_end_transaction(trans); return ret; -- GitLab From c41ec4529d3448df8998950d7bada757a1b321cf Mon Sep 17 00:00:00 2001 From: Su Yue Date: Thu, 21 Jan 2021 19:39:10 +0800 Subject: [PATCH 0621/1084] btrfs: fix lockdep warning due to seqcount_mutex on 32bit arch This effectively reverts commit d5c8238849e7 ("btrfs: convert data_seqcount to seqcount_mutex_t"). While running fstests on 32 bits test box, many tests failed because of warnings in dmesg. One of those warnings (btrfs/003): [66.441317] WARNING: CPU: 6 PID: 9251 at include/linux/seqlock.h:279 btrfs_remove_chunk+0x58b/0x7b0 [btrfs] [66.441446] CPU: 6 PID: 9251 Comm: btrfs Tainted: G O 5.11.0-rc4-custom+ #5 [66.441449] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ArchLinux 1.14.0-1 04/01/2014 [66.441451] EIP: btrfs_remove_chunk+0x58b/0x7b0 [btrfs] [66.441472] EAX: 00000000 EBX: 00000001 ECX: c576070c EDX: c6b15803 [66.441475] ESI: 10000000 EDI: 00000000 EBP: c56fbcfc ESP: c56fbc70 [66.441477] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010246 [66.441481] CR0: 80050033 CR2: 05c8da20 CR3: 04b20000 CR4: 00350ed0 [66.441485] Call Trace: [66.441510] btrfs_relocate_chunk+0xb1/0x100 [btrfs] [66.441529] ? btrfs_lookup_block_group+0x17/0x20 [btrfs] [66.441562] btrfs_balance+0x8ed/0x13b0 [btrfs] [66.441586] ? btrfs_ioctl_balance+0x333/0x3c0 [btrfs] [66.441619] ? __this_cpu_preempt_check+0xf/0x11 [66.441643] btrfs_ioctl_balance+0x333/0x3c0 [btrfs] [66.441664] ? btrfs_ioctl_get_supported_features+0x30/0x30 [btrfs] [66.441683] btrfs_ioctl+0x414/0x2ae0 [btrfs] [66.441700] ? __lock_acquire+0x35f/0x2650 [66.441717] ? lockdep_hardirqs_on+0x87/0x120 [66.441720] ? lockdep_hardirqs_on_prepare+0xd0/0x1e0 [66.441724] ? call_rcu+0x2d3/0x530 [66.441731] ? __might_fault+0x41/0x90 [66.441736] ? kvm_sched_clock_read+0x15/0x50 [66.441740] ? sched_clock+0x8/0x10 [66.441745] ? sched_clock_cpu+0x13/0x180 [66.441750] ? btrfs_ioctl_get_supported_features+0x30/0x30 [btrfs] [66.441750] ? btrfs_ioctl_get_supported_features+0x30/0x30 [btrfs] [66.441768] __ia32_sys_ioctl+0x165/0x8a0 [66.441773] ? __this_cpu_preempt_check+0xf/0x11 [66.441785] ? __might_fault+0x89/0x90 [66.441791] __do_fast_syscall_32+0x54/0x80 [66.441796] do_fast_syscall_32+0x32/0x70 [66.441801] do_SYSENTER_32+0x15/0x20 [66.441805] entry_SYSENTER_32+0x9f/0xf2 [66.441808] EIP: 0xab7b5549 [66.441814] EAX: ffffffda EBX: 00000003 ECX: c4009420 EDX: bfa91f5c [66.441816] ESI: 00000003 EDI: 00000001 EBP: 00000000 ESP: bfa91e98 [66.441818] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b EFLAGS: 00000292 [66.441833] irq event stamp: 42579 [66.441835] hardirqs last enabled at (42585): [] console_unlock+0x495/0x590 [66.441838] hardirqs last disabled at (42590): [] console_unlock+0x405/0x590 [66.441840] softirqs last enabled at (41698): [] call_on_stack+0x1c/0x60 [66.441843] softirqs last disabled at (41681): [] call_on_stack+0x1c/0x60 ======================================================================== btrfs_remove_chunk+0x58b/0x7b0: __seqprop_mutex_assert at linux/./include/linux/seqlock.h:279 (inlined by) btrfs_device_set_bytes_used at linux/fs/btrfs/volumes.h:212 (inlined by) btrfs_remove_chunk at linux/fs/btrfs/volumes.c:2994 ======================================================================== The warning is produced by lockdep_assert_held() in __seqprop_mutex_assert() if CONFIG_LOCKDEP is enabled. And "olumes.c:2994 is btrfs_device_set_bytes_used() with mutex lock fs_info->chunk_mutex held already. After adding some debug prints, the cause was found that many __alloc_device() are called with NULL @fs_info (during scanning ioctl). Inside the function, btrfs_device_data_ordered_init() is expanded to seqcount_mutex_init(). In this scenario, its second parameter info->chunk_mutex is &NULL->chunk_mutex which equals to offsetof(struct btrfs_fs_info, chunk_mutex) unexpectedly. Thus, seqcount_mutex_init() is called in wrong way. And later btrfs_device_get/set helpers trigger lockdep warnings. The device and filesystem object lifetimes are different and we'd have to synchronize initialization of the btrfs_device::data_seqcount with the fs_info, possibly using some additional synchronization. It would still not prevent concurrent access to the seqcount lock when it's used for read and initialization. Commit d5c8238849e7 ("btrfs: convert data_seqcount to seqcount_mutex_t") does not mention a particular problem being fixed so revert should not cause any harm and we'll get the lockdep warning fixed. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=210139 Reported-by: Erhard F Fixes: d5c8238849e7 ("btrfs: convert data_seqcount to seqcount_mutex_t") CC: stable@vger.kernel.org # 5.10 CC: Davidlohr Bueso Signed-off-by: Su Yue Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/volumes.c | 2 +- fs/btrfs/volumes.h | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 0c7f4f6237e8c..b900cc7849b6a 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -433,7 +433,7 @@ static struct btrfs_device *__alloc_device(struct btrfs_fs_info *fs_info) atomic_set(&dev->reada_in_flight, 0); atomic_set(&dev->dev_stats_ccnt, 0); - btrfs_device_data_ordered_init(dev, fs_info); + btrfs_device_data_ordered_init(dev); INIT_RADIX_TREE(&dev->reada_zones, GFP_NOFS & ~__GFP_DIRECT_RECLAIM); INIT_RADIX_TREE(&dev->reada_extents, GFP_NOFS & ~__GFP_DIRECT_RECLAIM); extent_io_tree_init(fs_info, &dev->alloc_state, diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 1997a4649a66c..c43663d9c22e0 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -39,10 +39,10 @@ struct btrfs_io_geometry { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) #include #define __BTRFS_NEED_DEVICE_DATA_ORDERED -#define btrfs_device_data_ordered_init(device, info) \ - seqcount_mutex_init(&device->data_seqcount, &info->chunk_mutex) +#define btrfs_device_data_ordered_init(device) \ + seqcount_init(&device->data_seqcount) #else -#define btrfs_device_data_ordered_init(device, info) do { } while (0) +#define btrfs_device_data_ordered_init(device) do { } while (0) #endif #define BTRFS_DEV_STATE_WRITEABLE (0) @@ -76,8 +76,7 @@ struct btrfs_device { blk_status_t last_flush_error; #ifdef __BTRFS_NEED_DEVICE_DATA_ORDERED - /* A seqcount_t with associated chunk_mutex (for lockdep) */ - seqcount_mutex_t data_seqcount; + seqcount_t data_seqcount; #endif /* the internal btrfs device id */ @@ -168,9 +167,11 @@ btrfs_device_get_##name(const struct btrfs_device *dev) \ static inline void \ btrfs_device_set_##name(struct btrfs_device *dev, u64 size) \ { \ + preempt_disable(); \ write_seqcount_begin(&dev->data_seqcount); \ dev->name = size; \ write_seqcount_end(&dev->data_seqcount); \ + preempt_enable(); \ } #elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPTION) #define BTRFS_DEVICE_GETSET_FUNCS(name) \ -- GitLab From 9ad6d91f056b99dbe59a262810cb342519ea8d39 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Fri, 22 Jan 2021 19:07:45 +0000 Subject: [PATCH 0622/1084] btrfs: fix log replay failure due to race with space cache rebuild After a sudden power failure we may end up with a space cache on disk that is not valid and needs to be rebuilt from scratch. If that happens, during log replay when we attempt to pin an extent buffer from a log tree, at btrfs_pin_extent_for_log_replay(), we do not wait for the space cache to be rebuilt through the call to: btrfs_cache_block_group(cache, 1); That is because that only waits for the task (work queue job) that loads the space cache to change the cache state from BTRFS_CACHE_FAST to any other value. That is ok when the space cache on disk exists and is valid, but when the cache is not valid and needs to be rebuilt, it ends up returning as soon as the cache state changes to BTRFS_CACHE_STARTED (done at caching_thread()). So this means that we can end up trying to unpin a range which is not yet marked as free in the block group. This results in the call to btrfs_remove_free_space() to return -EINVAL to btrfs_pin_extent_for_log_replay(), which in turn makes the log replay fail as well as mounting the filesystem. More specifically the -EINVAL comes from free_space_cache.c:remove_from_bitmap(), because the requested range is not marked as free space (ones in the bitmap), we have the following condition triggered: static noinline int remove_from_bitmap(struct btrfs_free_space_ctl *ctl, (...) if (ret < 0 || search_start != *offset) return -EINVAL; (...) It's the "search_start != *offset" that results in the condition being evaluated to true. When this happens we got the following in dmesg/syslog: [72383.415114] BTRFS: device fsid 32b95b69-0ea9-496a-9f02-3f5a56dc9322 devid 1 transid 1432 /dev/sdb scanned by mount (3816007) [72383.417837] BTRFS info (device sdb): disk space caching is enabled [72383.418536] BTRFS info (device sdb): has skinny extents [72383.423846] BTRFS info (device sdb): start tree-log replay [72383.426416] BTRFS warning (device sdb): block group 30408704 has wrong amount of free space [72383.427686] BTRFS warning (device sdb): failed to load free space cache for block group 30408704, rebuilding it now [72383.454291] BTRFS: error (device sdb) in btrfs_recover_log_trees:6203: errno=-22 unknown (Failed to pin buffers while recovering log root tree.) [72383.456725] BTRFS: error (device sdb) in btrfs_replay_log:2253: errno=-22 unknown (Failed to recover log tree) [72383.460241] BTRFS error (device sdb): open_ctree failed We also mark the range for the extent buffer in the excluded extents io tree. That is fine when the space cache is valid on disk and we can load it, in which case it causes no problems. However, for the case where we need to rebuild the space cache, because it is either invalid or it is missing, having the extent buffer range marked in the excluded extents io tree leads to a -EINVAL failure from the call to btrfs_remove_free_space(), resulting in the log replay and mount to fail. This is because by having the range marked in the excluded extents io tree, the caching thread ends up never adding the range of the extent buffer as free space in the block group since the calls to add_new_free_space(), called from load_extent_tree_free(), filter out any ranges that are marked as excluded extents. So fix this by making sure that during log replay we wait for the caching task to finish completely when we need to rebuild a space cache, and also drop the need to mark the extent buffer range in the excluded extents io tree, as well as clearing ranges from that tree at btrfs_finish_extent_commit(). This started to happen with some frequency on large filesystems having block groups with a lot of fragmentation since the recent commit e747853cae3ae3 ("btrfs: load free space cache asynchronously"), but in fact the issue has been there for years, it was just much less likely to happen. Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/extent-tree.c | 61 +++++++++++++----------------------------- 1 file changed, 18 insertions(+), 43 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 30b1a630dc2f8..0c335dae5af7a 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2602,8 +2602,6 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans, struct btrfs_block_group *cache; int ret; - btrfs_add_excluded_extent(trans->fs_info, bytenr, num_bytes); - cache = btrfs_lookup_block_group(trans->fs_info, bytenr); if (!cache) return -EINVAL; @@ -2615,11 +2613,19 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans, * the pinned extents. */ btrfs_cache_block_group(cache, 1); + /* + * Make sure we wait until the cache is completely built in case it is + * missing or is invalid and therefore needs to be rebuilt. + */ + ret = btrfs_wait_block_group_cache_done(cache); + if (ret) + goto out; pin_down_extent(trans, cache, bytenr, num_bytes, 0); /* remove us from the free space cache (if we're there at all) */ ret = btrfs_remove_free_space(cache, bytenr, num_bytes); +out: btrfs_put_block_group(cache); return ret; } @@ -2629,50 +2635,22 @@ static int __exclude_logged_extent(struct btrfs_fs_info *fs_info, { int ret; struct btrfs_block_group *block_group; - struct btrfs_caching_control *caching_ctl; block_group = btrfs_lookup_block_group(fs_info, start); if (!block_group) return -EINVAL; - btrfs_cache_block_group(block_group, 0); - caching_ctl = btrfs_get_caching_control(block_group); - - if (!caching_ctl) { - /* Logic error */ - BUG_ON(!btrfs_block_group_done(block_group)); - ret = btrfs_remove_free_space(block_group, start, num_bytes); - } else { - /* - * We must wait for v1 caching to finish, otherwise we may not - * remove our space. - */ - btrfs_wait_space_cache_v1_finished(block_group, caching_ctl); - mutex_lock(&caching_ctl->mutex); - - if (start >= caching_ctl->progress) { - ret = btrfs_add_excluded_extent(fs_info, start, - num_bytes); - } else if (start + num_bytes <= caching_ctl->progress) { - ret = btrfs_remove_free_space(block_group, - start, num_bytes); - } else { - num_bytes = caching_ctl->progress - start; - ret = btrfs_remove_free_space(block_group, - start, num_bytes); - if (ret) - goto out_lock; + btrfs_cache_block_group(block_group, 1); + /* + * Make sure we wait until the cache is completely built in case it is + * missing or is invalid and therefore needs to be rebuilt. + */ + ret = btrfs_wait_block_group_cache_done(block_group); + if (ret) + goto out; - num_bytes = (start + num_bytes) - - caching_ctl->progress; - start = caching_ctl->progress; - ret = btrfs_add_excluded_extent(fs_info, start, - num_bytes); - } -out_lock: - mutex_unlock(&caching_ctl->mutex); - btrfs_put_caching_control(caching_ctl); - } + ret = btrfs_remove_free_space(block_group, start, num_bytes); +out: btrfs_put_block_group(block_group); return ret; } @@ -2863,9 +2841,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans) mutex_unlock(&fs_info->unused_bg_unpin_mutex); break; } - if (test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) - clear_extent_bits(&fs_info->excluded_extents, start, - end, EXTENT_UPTODATE); if (btrfs_test_opt(fs_info, DISCARD_SYNC)) ret = btrfs_discard_extent(fs_info, start, -- GitLab From fef9c8d28e28a808274a18fbd8cc2685817fd62a Mon Sep 17 00:00:00 2001 From: Laurent Badel Date: Fri, 22 Jan 2021 17:19:41 +0100 Subject: [PATCH 0623/1084] PM: hibernate: flush swap writer after marking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flush the swap writer after, not before, marking the files, to ensure the signature is properly written. Fixes: 6f612af57821 ("PM / Hibernate: Group swap ops") Signed-off-by: Laurent Badel Cc: All applicable Signed-off-by: Rafael J. Wysocki --- kernel/power/swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/power/swap.c b/kernel/power/swap.c index c73f2e295167d..72e33054a2e1b 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -497,10 +497,10 @@ static int swap_writer_finish(struct swap_map_handle *handle, unsigned int flags, int error) { if (!error) { - flush_swap_writer(handle); pr_info("S"); error = mark_swapfiles(handle, flags); pr_cont("|\n"); + flush_swap_writer(handle); } if (error) -- GitLab From b98e762e3d71e893b221f871825dc64694cfb258 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 25 Jan 2021 12:21:02 -0500 Subject: [PATCH 0624/1084] nbd: freeze the queue while we're adding connections When setting up a device, we can krealloc the config->socks array to add new sockets to the configuration. However if we happen to get a IO request in at this point even though we aren't setup we could hit a UAF, as we deref config->socks without any locking, assuming that the configuration was setup already and that ->socks is safe to access it as we have a reference on the configuration. But there's nothing really preventing IO from occurring at this point of the device setup, we don't want to incur the overhead of a lock to access ->socks when it will never change while the device is running. To fix this UAF scenario simply freeze the queue if we are adding sockets. This will protect us from this particular case without adding any additional overhead for the normal running case. Cc: stable@vger.kernel.org Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 6727358e147dd..e6ea5d344f87b 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1022,6 +1022,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, if (!sock) return err; + /* + * We need to make sure we don't get any errant requests while we're + * reallocating the ->socks array. + */ + blk_mq_freeze_queue(nbd->disk->queue); + if (!netlink && !nbd->task_setup && !test_bit(NBD_RT_BOUND, &config->runtime_flags)) nbd->task_setup = current; @@ -1060,10 +1066,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, nsock->cookie = 0; socks[config->num_connections++] = nsock; atomic_inc(&config->live_connections); + blk_mq_unfreeze_queue(nbd->disk->queue); return 0; put_socket: + blk_mq_unfreeze_queue(nbd->disk->queue); sockfd_put(sock); return err; } -- GitLab From 0bc92e7f0d9ab06afacff7e5b0e08b5ce8f3f32f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:21 +0100 Subject: [PATCH 0625/1084] ASoC: audio-graph-card: update audio-graph-card.yaml reference Changeset 97198614f6c3 ("ASoC: audio-graph-card: switch to yaml base Documentation") renamed: Documentation/devicetree/bindings/sound/audio-graph-card.txt to: Documentation/devicetree/bindings/sound/audio-graph-card.yaml. Update its cross-reference accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/8a779e6b9644d19c5d77b382059f6ccf9781434d.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/display/bridge/sii902x.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/sii902x.txt b/Documentation/devicetree/bindings/display/bridge/sii902x.txt index 02c21b5847418..3bc760cc31cbb 100644 --- a/Documentation/devicetree/bindings/display/bridge/sii902x.txt +++ b/Documentation/devicetree/bindings/display/bridge/sii902x.txt @@ -40,7 +40,7 @@ Optional properties: documents on how to describe the way the sii902x device is connected to the rest of the audio system: Documentation/devicetree/bindings/sound/simple-card.yaml - Documentation/devicetree/bindings/sound/audio-graph-card.txt + Documentation/devicetree/bindings/sound/audio-graph-card.yaml Note: In case of the audio-graph-card binding the used port index should be 3. -- GitLab From 601bd38ccd25e831865dd8442e3491fc8ce9604d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:22 +0100 Subject: [PATCH 0626/1084] dt-bindings: display: mediatek: update mediatek,dpi.yaml reference Changeset 9273cf7d3942 ("dt-bindings: display: mediatek: convert the dpi bindings to yaml") renamed: Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt to: Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml. Update its cross-reference accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/3bf906f39b797d18800abd387187cce71296e5eb.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Rob Herring --- .../devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index 33977e15bebdf..865e1e1b88ac5 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -23,7 +23,7 @@ connected to. For a description of the display interface sink function blocks, see Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and -Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt. +Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml. Required properties (all function blocks): - compatible: "mediatek,-disp-", one of -- GitLab From c5dde04b9059c91515d609a41e9c1a148ee4d850 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:23 +0100 Subject: [PATCH 0627/1084] dt-bindings: memory: mediatek: update mediatek,smi-larb.yaml references Changeset 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema") renamed: Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt to: Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml. Update its cross-references accordingly. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/c70bd79b311a65babe7374eaf81974563400a943.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Rob Herring --- .../devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +- .../devicetree/bindings/media/mediatek-jpeg-decoder.txt | 2 +- .../devicetree/bindings/media/mediatek-jpeg-encoder.txt | 2 +- Documentation/devicetree/bindings/media/mediatek-mdp.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index 865e1e1b88ac5..ed76332ec01e8 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -61,7 +61,7 @@ Required properties (DMA function blocks): "mediatek,-disp-wdma" the supported chips are mt2701, mt8167 and mt8173. - larb: Should contain a phandle pointing to the local arbiter device as defined - in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt + in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml - iommus: Should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt for details. diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt index 044b11913c49b..cf60c5acc0e4e 100644 --- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt +++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt @@ -16,7 +16,7 @@ Required properties: - power-domains: a phandle to the power domain, see Documentation/devicetree/bindings/power/power_domain.txt for details. - mediatek,larb: must contain the local arbiters in the current Socs, see - Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml for details. - iommus: should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt index 736be7cad3857..acfb50375b8ac 100644 --- a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt +++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt @@ -14,7 +14,7 @@ Required properties: - power-domains: a phandle to the power domain, see Documentation/devicetree/bindings/power/power_domain.txt for details. - mediatek,larb: must contain the local arbiters in the current SoCs, see - Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml for details. - iommus: should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt index 0d03e3ae2be2f..f4798d04e9252 100644 --- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt +++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt @@ -28,7 +28,7 @@ Required properties (DMA function blocks, child node): argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt for details. - mediatek,larb: must contain the local arbiters in the current Socs, see - Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml for details. Example: -- GitLab From 3490e333bda0709a5a2c9b7ab9b0209bb16619d8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Jan 2021 11:59:24 +0100 Subject: [PATCH 0628/1084] dt-bindings:iio:adc: update adc.yaml reference Changeset b70d154d6558 ("dt-bindings:iio:adc: convert adc.txt to yaml") renamed: Documentation/devicetree/bindings/iio/adc/adc.txt to: Documentation/devicetree/bindings/iio/adc/adc.yaml. Update its cross-reference accordingly. Signed-off-by: Mauro Carvalho Chehab Acked-by: Jonathan Cameron Link: https://lore.kernel.org/r/8e37dba8ae9099acd649bab8a1cf718caa4f3e6a.1610535350.git.mchehab+huawei@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml index e0cc3b2e89574..22b7ed3723f67 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml @@ -80,7 +80,7 @@ properties: type: boolean bipolar: - description: see Documentation/devicetree/bindings/iio/adc/adc.txt + description: see Documentation/devicetree/bindings/iio/adc/adc.yaml type: boolean required: -- GitLab From 9f12e37cae44a96132fc3031535a0b165486941a Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Mon, 25 Jan 2021 11:09:25 -0800 Subject: [PATCH 0629/1084] Commit 9bb48c82aced ("tty: implement write_iter") converted the tty layer to use write_iter. Fix the redirected_tty_write declaration also in n_tty and change the comparisons to use write_iter instead of write. [ Also moved the declaration of redirected_tty_write() to the proper location in a header file. The reason for the bug was the bogus extern declaration in n_tty.c silently not matching the changed definition in tty_io.c, and because it wasn't in a shared header file, there was no cross-checking of the declaration. Sami noticed because Clang's Control Flow Integrity checking ended up incidentally noticing the inconsistent declaration. - Linus ] Fixes: 9bb48c82aced ("tty: implement write_iter") Signed-off-by: Sami Tolvanen Signed-off-by: Linus Torvalds --- drivers/tty/n_tty.c | 7 ++----- drivers/tty/tty_io.c | 2 -- include/linux/tty.h | 1 + 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 319d68c8a5df3..219e85756171b 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2081,9 +2081,6 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, return 0; } -extern ssize_t redirected_tty_write(struct file *, const char __user *, - size_t, loff_t *); - /** * job_control - check job control * @tty: tty @@ -2105,7 +2102,7 @@ static int job_control(struct tty_struct *tty, struct file *file) /* NOTE: not yet done after every sleep pending a thorough check of the logic of this change. -- jlc */ /* don't stop on /dev/console */ - if (file->f_op->write == redirected_tty_write) + if (file->f_op->write_iter == redirected_tty_write) return 0; return __tty_check_change(tty, SIGTTIN); @@ -2309,7 +2306,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, ssize_t retval = 0; /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */ - if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) { + if (L_TOSTOP(tty) && file->f_op->write_iter != redirected_tty_write) { retval = tty_check_change(tty); if (retval) return retval; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 4a208a95e9219..48de20916ca78 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -144,10 +144,8 @@ DEFINE_MUTEX(tty_mutex); static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); static ssize_t tty_write(struct kiocb *, struct iov_iter *); -ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *); static __poll_t tty_poll(struct file *, poll_table *); static int tty_open(struct inode *, struct file *); -long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); #ifdef CONFIG_COMPAT static long tty_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); diff --git a/include/linux/tty.h b/include/linux/tty.h index c873f475f0a76..37803f3e6d49e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -421,6 +421,7 @@ extern void tty_kclose(struct tty_struct *tty); extern int tty_dev_name_to_number(const char *name, dev_t *number); extern int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout); extern void tty_ldisc_unlock(struct tty_struct *tty); +extern ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *); #else static inline void tty_kref_put(struct tty_struct *tty) { } -- GitLab From f8ad8187c3b536ee2b10502a8340c014204a1af0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 25 Jan 2021 10:16:15 +0100 Subject: [PATCH 0630/1084] fs/pipe: allow sendfile() to pipe again After commit 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops") sendfile() could no longer send data from a real file to a pipe, breaking for example certain cgit setups (e.g. when running behind fcgiwrap), because in this case cgit will try to do exactly this: sendfile() to a pipe. Fix this by using iter_file_splice_write for the splice_write method of pipes, as suggested by Christoph. Cc: stable@vger.kernel.org Fixes: 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops") Suggested-by: Christoph Hellwig Reviewed-by: Christoph Hellwig Tested-by: Johannes Berg Signed-off-by: Johannes Berg Signed-off-by: Linus Torvalds --- fs/pipe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/pipe.c b/fs/pipe.c index c5989cfd564d4..39c96845a72fb 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1206,6 +1206,7 @@ const struct file_operations pipefifo_fops = { .unlocked_ioctl = pipe_ioctl, .release = pipe_release, .fasync = pipe_fasync, + .splice_write = iter_file_splice_write, }; /* -- GitLab From ba6dfce47c4d002d96cd02a304132fca76981172 Mon Sep 17 00:00:00 2001 From: Dave Wysochanski Date: Thu, 21 Jan 2021 16:17:23 -0500 Subject: [PATCH 0631/1084] SUNRPC: Move simple_get_bytes and simple_get_netobj into private header Remove duplicated helper functions to parse opaque XDR objects and place inside new file net/sunrpc/auth_gss/auth_gss_internal.h. In the new file carry the license and copyright from the source file net/sunrpc/auth_gss/auth_gss.c. Finally, update the comment inside include/linux/sunrpc/xdr.h since lockd is not the only user of struct xdr_netobj. Signed-off-by: Dave Wysochanski Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xdr.h | 3 +- net/sunrpc/auth_gss/auth_gss.c | 30 +----------------- net/sunrpc/auth_gss/auth_gss_internal.h | 42 +++++++++++++++++++++++++ net/sunrpc/auth_gss/gss_krb5_mech.c | 31 ++---------------- 4 files changed, 46 insertions(+), 60 deletions(-) create mode 100644 net/sunrpc/auth_gss/auth_gss_internal.h diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 19b6dea27367b..b26213ae8c1ab 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -25,8 +25,7 @@ struct rpc_rqst; #define XDR_QUADLEN(l) (((l) + 3) >> 2) /* - * Generic opaque `network object.' At the kernel level, this type - * is used only by lockd. + * Generic opaque `network object.' */ #define XDR_MAX_NETOBJ 1024 struct xdr_netobj { diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 4ecc2a9595674..5f42aa5fc6128 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -29,6 +29,7 @@ #include #include +#include "auth_gss_internal.h" #include "../netns.h" #include @@ -125,35 +126,6 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); } -static const void * -simple_get_bytes(const void *p, const void *end, void *res, size_t len) -{ - const void *q = (const void *)((const char *)p + len); - if (unlikely(q > end || q < p)) - return ERR_PTR(-EFAULT); - memcpy(res, p, len); - return q; -} - -static inline const void * -simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) -{ - const void *q; - unsigned int len; - - p = simple_get_bytes(p, end, &len, sizeof(len)); - if (IS_ERR(p)) - return p; - q = (const void *)((const char *)p + len); - if (unlikely(q > end || q < p)) - return ERR_PTR(-EFAULT); - dest->data = kmemdup(p, len, GFP_NOFS); - if (unlikely(dest->data == NULL)) - return ERR_PTR(-ENOMEM); - dest->len = len; - return q; -} - static struct gss_cl_ctx * gss_cred_get_ctx(struct rpc_cred *cred) { diff --git a/net/sunrpc/auth_gss/auth_gss_internal.h b/net/sunrpc/auth_gss/auth_gss_internal.h new file mode 100644 index 0000000000000..c5603242b54bf --- /dev/null +++ b/net/sunrpc/auth_gss/auth_gss_internal.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * linux/net/sunrpc/auth_gss/auth_gss_internal.h + * + * Internal definitions for RPCSEC_GSS client authentication + * + * Copyright (c) 2000 The Regents of the University of Michigan. + * All rights reserved. + * + */ +#include +#include +#include + +static inline const void * +simple_get_bytes(const void *p, const void *end, void *res, size_t len) +{ + const void *q = (const void *)((const char *)p + len); + if (unlikely(q > end || q < p)) + return ERR_PTR(-EFAULT); + memcpy(res, p, len); + return q; +} + +static inline const void * +simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) +{ + const void *q; + unsigned int len; + + p = simple_get_bytes(p, end, &len, sizeof(len)); + if (IS_ERR(p)) + return p; + q = (const void *)((const char *)p + len); + if (unlikely(q > end || q < p)) + return ERR_PTR(-EFAULT); + dest->data = kmemdup(p, len, GFP_NOFS); + if (unlikely(dest->data == NULL)) + return ERR_PTR(-ENOMEM); + dest->len = len; + return q; +} diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index ae9acf3a73898..1c092b05c2bba 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -21,6 +21,8 @@ #include #include +#include "auth_gss_internal.h" + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif @@ -143,35 +145,6 @@ get_gss_krb5_enctype(int etype) return NULL; } -static const void * -simple_get_bytes(const void *p, const void *end, void *res, int len) -{ - const void *q = (const void *)((const char *)p + len); - if (unlikely(q > end || q < p)) - return ERR_PTR(-EFAULT); - memcpy(res, p, len); - return q; -} - -static const void * -simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) -{ - const void *q; - unsigned int len; - - p = simple_get_bytes(p, end, &len, sizeof(len)); - if (IS_ERR(p)) - return p; - q = (const void *)((const char *)p + len); - if (unlikely(q > end || q < p)) - return ERR_PTR(-EFAULT); - res->data = kmemdup(p, len, GFP_NOFS); - if (unlikely(res->data == NULL)) - return ERR_PTR(-ENOMEM); - res->len = len; - return q; -} - static inline const void * get_key(const void *p, const void *end, struct krb5_ctx *ctx, struct crypto_sync_skcipher **res) -- GitLab From e4a7d1f7707eb44fd953a31dd59eff82009d879c Mon Sep 17 00:00:00 2001 From: Dave Wysochanski Date: Thu, 21 Jan 2021 16:17:24 -0500 Subject: [PATCH 0632/1084] SUNRPC: Handle 0 length opaque XDR object data properly When handling an auth_gss downcall, it's possible to get 0-length opaque object for the acceptor. In the case of a 0-length XDR object, make sure simple_get_netobj() fills in dest->data = NULL, and does not continue to kmemdup() which will set dest->data = ZERO_SIZE_PTR for the acceptor. The trace event code can handle NULL but not ZERO_SIZE_PTR for a string, and so without this patch the rpcgss_context trace event will crash the kernel as follows: [ 162.887992] BUG: kernel NULL pointer dereference, address: 0000000000000010 [ 162.898693] #PF: supervisor read access in kernel mode [ 162.900830] #PF: error_code(0x0000) - not-present page [ 162.902940] PGD 0 P4D 0 [ 162.904027] Oops: 0000 [#1] SMP PTI [ 162.905493] CPU: 4 PID: 4321 Comm: rpc.gssd Kdump: loaded Not tainted 5.10.0 #133 [ 162.908548] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 [ 162.910978] RIP: 0010:strlen+0x0/0x20 [ 162.912505] Code: 48 89 f9 74 09 48 83 c1 01 80 39 00 75 f7 31 d2 44 0f b6 04 16 44 88 04 11 48 83 c2 01 45 84 c0 75 ee c3 0f 1f 80 00 00 00 00 <80> 3f 00 74 10 48 89 f8 48 83 c0 01 80 38 00 75 f7 48 29 f8 c3 31 [ 162.920101] RSP: 0018:ffffaec900c77d90 EFLAGS: 00010202 [ 162.922263] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000000fffde697 [ 162.925158] RDX: 000000000000002f RSI: 0000000000000080 RDI: 0000000000000010 [ 162.928073] RBP: 0000000000000010 R08: 0000000000000e10 R09: 0000000000000000 [ 162.930976] R10: ffff8e698a590cb8 R11: 0000000000000001 R12: 0000000000000e10 [ 162.933883] R13: 00000000fffde697 R14: 000000010034d517 R15: 0000000000070028 [ 162.936777] FS: 00007f1e1eb93700(0000) GS:ffff8e6ab7d00000(0000) knlGS:0000000000000000 [ 162.940067] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 162.942417] CR2: 0000000000000010 CR3: 0000000104eba000 CR4: 00000000000406e0 [ 162.945300] Call Trace: [ 162.946428] trace_event_raw_event_rpcgss_context+0x84/0x140 [auth_rpcgss] [ 162.949308] ? __kmalloc_track_caller+0x35/0x5a0 [ 162.951224] ? gss_pipe_downcall+0x3a3/0x6a0 [auth_rpcgss] [ 162.953484] gss_pipe_downcall+0x585/0x6a0 [auth_rpcgss] [ 162.955953] rpc_pipe_write+0x58/0x70 [sunrpc] [ 162.957849] vfs_write+0xcb/0x2c0 [ 162.959264] ksys_write+0x68/0xe0 [ 162.960706] do_syscall_64+0x33/0x40 [ 162.962238] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 162.964346] RIP: 0033:0x7f1e1f1e57df Signed-off-by: Dave Wysochanski Signed-off-by: Trond Myklebust --- net/sunrpc/auth_gss/auth_gss_internal.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/sunrpc/auth_gss/auth_gss_internal.h b/net/sunrpc/auth_gss/auth_gss_internal.h index c5603242b54bf..f6d9631bd9d00 100644 --- a/net/sunrpc/auth_gss/auth_gss_internal.h +++ b/net/sunrpc/auth_gss/auth_gss_internal.h @@ -34,9 +34,12 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) q = (const void *)((const char *)p + len); if (unlikely(q > end || q < p)) return ERR_PTR(-EFAULT); - dest->data = kmemdup(p, len, GFP_NOFS); - if (unlikely(dest->data == NULL)) - return ERR_PTR(-ENOMEM); + if (len) { + dest->data = kmemdup(p, len, GFP_NOFS); + if (unlikely(dest->data == NULL)) + return ERR_PTR(-ENOMEM); + } else + dest->data = NULL; dest->len = len; return q; } -- GitLab From 67fbe02a5cebc3c653610f12e3c0424e58450153 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 20 Jan 2021 13:49:41 +0100 Subject: [PATCH 0633/1084] platform/x86: hp-wmi: Disable tablet-mode reporting by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recently userspace has started making more use of SW_TABLET_MODE (when an input-dev reports this). Specifically recent GNOME3 versions will: 1. When SW_TABLET_MODE is reported and is reporting 0: 1.1 Disable accelerometer-based screen auto-rotation 1.2 Disable automatically showing the on-screen keyboard when a text-input field is focussed 2. When SW_TABLET_MODE is reported and is reporting 1: 2.1 Ignore input-events from the builtin keyboard and touchpad (this is for 360° hinges style 2-in-1s where the keyboard and touchpads are accessible on the back of the tablet when folded into tablet-mode) This means that claiming to support SW_TABLET_MODE when it does not actually work / reports correct values has bad side-effects. The check in the hp-wmi code which is used to decide if the input-dev should claim SW_TABLET_MODE support, only checks if the HPWMI_HARDWARE_QUERY is supported. It does *not* check if the hardware actually is capable of reporting SW_TABLET_MODE. This leads to the hp-wmi input-dev claiming SW_TABLET_MODE support, while in reality it will always report 0 as SW_TABLET_MODE value. This has been seen on a "HP ENVY x360 Convertible 15-cp0xxx" and this likely is the case on a whole lot of other HP models. This problem causes both auto-rotation and on-screen keyboard support to not work on affected x360 models. There is no easy fix for this, but since userspace expects SW_TABLET_MODE reporting to be reliable when advertised it is better to not claim/report SW_TABLET_MODE support at all, then to claim to support it while it does not work. To avoid the mentioned problems, add a new enable_tablet_mode_sw module-parameter which defaults to false. Note I've made this an int using the standard -1=auto, 0=off, 1=on triplett, with the hope that in the future we can come up with a better way to detect SW_TABLET_MODE support. ATM the default auto option just does the same as off. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1918255 Cc: Stefan Brüns Signed-off-by: Hans de Goede Acked-by: Mark Gross Link: https://lore.kernel.org/r/20210120124941.73409-1-hdegoede@redhat.com --- drivers/platform/x86/hp-wmi.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 18bf8aeb5f870..e94e59283ecb9 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -32,6 +32,10 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C"); MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); +static int enable_tablet_mode_sw = -1; +module_param(enable_tablet_mode_sw, int, 0444); +MODULE_PARM_DESC(enable_tablet_mode_sw, "Enable SW_TABLET_MODE reporting (-1=auto, 0=no, 1=yes)"); + #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" #define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4" @@ -654,10 +658,12 @@ static int __init hp_wmi_input_setup(void) } /* Tablet mode */ - val = hp_wmi_hw_state(HPWMI_TABLET_MASK); - if (!(val < 0)) { - __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit); - input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val); + if (enable_tablet_mode_sw > 0) { + val = hp_wmi_hw_state(HPWMI_TABLET_MASK); + if (val >= 0) { + __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit); + input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val); + } } err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL); -- GitLab From 9b6164342e981d751e69f5a165dd596ffcdfd6fe Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 23 Jan 2021 22:33:33 +0900 Subject: [PATCH 0634/1084] doc: gcc-plugins: update gcc-plugins.rst This document was written a long time ago. Update it. [1] Drop the version information The range of the supported GCC versions are always changing. The current minimal GCC version is 4.9, and commit 1e860048c53e ("gcc-plugins: simplify GCC plugin-dev capability test") removed the old code accordingly. We do not need to mention specific version ranges like "all gcc versions from 4.5 to 6.0" since we forget to update the documentation when we raise the minimal compiler version. [2] Drop the C compiler statements Since commit 77342a02ff6e ("gcc-plugins: drop support for GCC <= 4.7") the GCC plugin infrastructure only supports g++. [3] Drop supported architectures As of v5.11-rc4, the infrastructure supports more architectures; arm, arm64, mips, powerpc, riscv, s390, um, and x86. (just grep "select HAVE_GCC_PLUGINS") Again, we miss to update this document when a new architecture is supported. Let's just say "only some architectures". [4] Update the apt-get example We are now discussing to bump the minimal version to GCC 5. The GCC 4.9 support will be removed sooner or later. Change the package example to gcc-10-plugin-dev while we are here. [5] Update the build target Since commit ce2fd53a10c7 ("kbuild: descend into scripts/gcc-plugins/ via scripts/Makefile"), "make gcc-plugins" is not supported. "make scripts" builds all the enabled plugins, including some other tools. [6] Update the steps for adding a new plugin At first, all CONFIG options for GCC plugins were located in arch/Kconfig. After commit 45332b1bdfdc ("gcc-plugins: split out Kconfig entries to scripts/gcc-plugins/Kconfig"), scripts/gcc-plugins/Kconfig became the central place to collect plugin CONFIG options. In my understanding, this requirement no longer exists because commit 9f671e58159a ("security: Create "kernel hardening" config area") moved some of plugin CONFIG options to another file. Find an appropriate place to add the new CONFIG. The sub-directory support was never used by anyone, and removed by commit c17d6179ad5a ("gcc-plugins: remove unused GCC_PLUGIN_SUBDIR"). Remove the useless $(src)/ prefix. Signed-off-by: Masahiro Yamada --- Documentation/kbuild/gcc-plugins.rst | 41 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/Documentation/kbuild/gcc-plugins.rst b/Documentation/kbuild/gcc-plugins.rst index 63379d0150e37..3349966f213dc 100644 --- a/Documentation/kbuild/gcc-plugins.rst +++ b/Documentation/kbuild/gcc-plugins.rst @@ -11,16 +11,13 @@ compiler [1]_. They are useful for runtime instrumentation and static analysis. We can analyse, change and add further code during compilation via callbacks [2]_, GIMPLE [3]_, IPA [4]_ and RTL passes [5]_. -The GCC plugin infrastructure of the kernel supports all gcc versions from -4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a -separate directory. -Plugin source files have to be compilable by both a C and a C++ compiler as well -because gcc versions 4.5 and 4.6 are compiled by a C compiler, -gcc-4.7 can be compiled by a C or a C++ compiler, -and versions 4.8+ can only be compiled by a C++ compiler. +The GCC plugin infrastructure of the kernel supports building out-of-tree +modules, cross-compilation and building in a separate directory. +Plugin source files have to be compilable by a C++ compiler. -Currently the GCC plugin infrastructure supports only the x86, arm, arm64 and -powerpc architectures. +Currently the GCC plugin infrastructure supports only some architectures. +Grep "select HAVE_GCC_PLUGINS" to find out which architectures support +GCC plugins. This infrastructure was ported from grsecurity [6]_ and PaX [7]_. @@ -53,8 +50,7 @@ $(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h, $(src)/scripts/gcc-plugins/gcc-generate-rtl-pass.h** These headers automatically generate the registration structures for - GIMPLE, SIMPLE_IPA, IPA and RTL passes. They support all gcc versions - from 4.5 to 6.0. + GIMPLE, SIMPLE_IPA, IPA and RTL passes. They should be preferred to creating the structures by hand. @@ -62,21 +58,25 @@ Usage ===== You must install the gcc plugin headers for your gcc version, -e.g., on Ubuntu for gcc-4.9:: +e.g., on Ubuntu for gcc-10:: - apt-get install gcc-4.9-plugin-dev + apt-get install gcc-10-plugin-dev Or on Fedora:: dnf install gcc-plugin-devel -Enable a GCC plugin based feature in the kernel config:: +Enable the GCC plugin infrastructure and some plugin(s) you want to use +in the kernel config:: - CONFIG_GCC_PLUGIN_CYC_COMPLEXITY = y + CONFIG_GCC_PLUGINS=y + CONFIG_GCC_PLUGIN_CYC_COMPLEXITY=y + CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y + ... -To compile only the plugin(s):: +To compile the minimum tool set including the plugin(s):: - make gcc-plugins + make scripts or just run the kernel make and compile the whole kernel with the cyclomatic complexity GCC plugin. @@ -85,7 +85,8 @@ the cyclomatic complexity GCC plugin. 4. How to add a new GCC plugin ============================== -The GCC plugins are in $(src)/scripts/gcc-plugins/. You can use a file or a directory -here. It must be added to $(src)/scripts/gcc-plugins/Makefile, -$(src)/scripts/Makefile.gcc-plugins and $(src)/arch/Kconfig. +The GCC plugins are in scripts/gcc-plugins/. You need to put plugin source files +right under scripts/gcc-plugins/. Creating subdirectories is not supported. +It must be added to scripts/gcc-plugins/Makefile, scripts/Makefile.gcc-plugins +and a relevant Kconfig file. See the cyc_complexity_plugin.c (CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) GCC plugin. -- GitLab From 74532de460ec664e5a725507d1b59aa9e4d40776 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Wed, 20 Jan 2021 23:41:39 +0000 Subject: [PATCH 0635/1084] arm64: dts: rockchip: Disable display for NanoPi R2S NanoPi R2S is headless, so rightly does not enable any of the display interface hardware, which currently provokes an obnoxious error in the boot log from the fake DRM device failing to find anything to bind to. It probably isn't *too* hard to obviate the fake device shenanigans entirely with a bit of driver reshuffling, but for now let's just disable it here to shut up the spurious error. Signed-off-by: Robin Murphy Link: https://lore.kernel.org/r/c4553dfad1ad6792c4f22454c135ff55de77e2d6.1611186099.git.robin.murphy@arm.com Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts index 2ee07d15a6e37..1eecad724f04c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts @@ -114,6 +114,10 @@ cpu-supply = <&vdd_arm>; }; +&display_subsystem { + status = "disabled"; +}; + &gmac2io { assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; -- GitLab From 453b674178327950e8517172c82107c43af222e4 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 15 Jan 2021 21:31:24 +0200 Subject: [PATCH 0636/1084] dt-bindings: usb: j721e: add ranges and dma-coherent props Add missed 'ranges' and 'dma-coherent' properties as cdns-usb DT nodes has child node and DMA IO is coherent on TI K3 J721E/J7200 SoCs. This also fixes dtbs_check warning: cdns-usb@4104000: 'dma-coherent', 'ranges' do not match any of the regexes: '^usb@', 'pinctrl-[0-9]+' Signed-off-by: Grygorii Strashko Acked-by: Aswath Govindraju Reviewed-by: Aswath Govindraju Link: https://lore.kernel.org/r/20210115193124.5706-1-grygorii.strashko@ti.com Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml index 388245b91a55b..64b0b92aa0502 100644 --- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml +++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml @@ -17,6 +17,8 @@ properties: reg: description: module registers + ranges: true + power-domains: description: PM domain provider node and an args specifier containing @@ -58,6 +60,8 @@ properties: '#size-cells': const: 2 + dma-coherent: true + patternProperties: "^usb@": type: object -- GitLab From 07d46d93c9acdfe0614071d73c415dd5f745cc6e Mon Sep 17 00:00:00 2001 From: Justin Iurman Date: Thu, 21 Jan 2021 23:00:44 +0100 Subject: [PATCH 0637/1084] uapi: fix big endian definition of ipv6_rpl_sr_hdr Following RFC 6554 [1], the current order of fields is wrong for big endian definition. Indeed, here is how the header looks like: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Next Header | Hdr Ext Len | Routing Type | Segments Left | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | CmprI | CmprE | Pad | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ This patch reorders fields so that big endian definition is now correct. [1] https://tools.ietf.org/html/rfc6554#section-3 Fixes: cfa933d938d8 ("include: uapi: linux: add rpl sr header definition") Signed-off-by: Justin Iurman Signed-off-by: Jakub Kicinski --- include/uapi/linux/rpl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/uapi/linux/rpl.h b/include/uapi/linux/rpl.h index 1dccb55cf8c64..708adddf9f138 100644 --- a/include/uapi/linux/rpl.h +++ b/include/uapi/linux/rpl.h @@ -28,10 +28,10 @@ struct ipv6_rpl_sr_hdr { pad:4, reserved1:16; #elif defined(__BIG_ENDIAN_BITFIELD) - __u32 reserved:20, + __u32 cmpri:4, + cmpre:4, pad:4, - cmpri:4, - cmpre:4; + reserved:20; #else #error "Please fix " #endif -- GitLab From a10f373ad3c760dd40b41e2f69a800ee7b8da15e Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Fri, 8 Jan 2021 16:53:49 +0000 Subject: [PATCH 0638/1084] KVM: Documentation: Fix spec for KVM_CAP_ENABLE_CAP_VM The documentation classifies KVM_ENABLE_CAP with KVM_CAP_ENABLE_CAP_VM as a vcpu ioctl, which is incorrect. Fix it by specifying it as a VM ioctl. Fixes: e5d83c74a580 ("kvm: make KVM_CAP_ENABLE_CAP_VM architecture agnostic") Signed-off-by: Quentin Perret Message-Id: <20210108165349.747359-1-qperret@google.com> Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index a9bf7f2ab76f5..40b943a9bd1da 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -1336,7 +1336,7 @@ documentation when it pops into existence). :Capability: KVM_CAP_ENABLE_CAP_VM :Architectures: all -:Type: vcpu ioctl +:Type: vm ioctl :Parameters: struct kvm_enable_cap (in) :Returns: 0 on success; -1 on error -- GitLab From eb79cd00ce25974c21f34f1eeb92a580ff572971 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 13 Jan 2021 12:45:15 -0800 Subject: [PATCH 0639/1084] KVM: x86: Add more protection against undefined behavior in rsvd_bits() Add compile-time asserts in rsvd_bits() to guard against KVM passing in garbage hardcoded values, and cap the upper bound at '63' for dynamic values to prevent generating a mask that would overflow a u64. Suggested-by: Paolo Bonzini Signed-off-by: Sean Christopherson Message-Id: <20210113204515.3473079-1-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 581925e476d6c..261be1d2032ba 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -44,8 +44,15 @@ #define PT32_ROOT_LEVEL 2 #define PT32E_ROOT_LEVEL 3 -static inline u64 rsvd_bits(int s, int e) +static __always_inline u64 rsvd_bits(int s, int e) { + BUILD_BUG_ON(__builtin_constant_p(e) && __builtin_constant_p(s) && e < s); + + if (__builtin_constant_p(e)) + BUILD_BUG_ON(e > 63); + else + e &= 63; + if (e < s) return 0; -- GitLab From e61ab2a320c3dfd6209efe18a575979e07470597 Mon Sep 17 00:00:00 2001 From: Like Xu Date: Mon, 18 Jan 2021 10:58:00 +0800 Subject: [PATCH 0640/1084] KVM: x86/pmu: Fix UBSAN shift-out-of-bounds warning in intel_pmu_refresh() Since we know vPMU will not work properly when (1) the guest bit_width(s) of the [gp|fixed] counters are greater than the host ones, or (2) guest requested architectural events exceeds the range supported by the host, so we can setup a smaller left shift value and refresh the guest cpuid entry, thus fixing the following UBSAN shift-out-of-bounds warning: shift exponent 197 is too large for 64-bit type 'long long unsigned int' Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x107/0x163 lib/dump_stack.c:120 ubsan_epilogue+0xb/0x5a lib/ubsan.c:148 __ubsan_handle_shift_out_of_bounds.cold+0xb1/0x181 lib/ubsan.c:395 intel_pmu_refresh.cold+0x75/0x99 arch/x86/kvm/vmx/pmu_intel.c:348 kvm_vcpu_after_set_cpuid+0x65a/0xf80 arch/x86/kvm/cpuid.c:177 kvm_vcpu_ioctl_set_cpuid2+0x160/0x440 arch/x86/kvm/cpuid.c:308 kvm_arch_vcpu_ioctl+0x11b6/0x2d70 arch/x86/kvm/x86.c:4709 kvm_vcpu_ioctl+0x7b9/0xdb0 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3386 vfs_ioctl fs/ioctl.c:48 [inline] __do_sys_ioctl fs/ioctl.c:753 [inline] __se_sys_ioctl fs/ioctl.c:739 [inline] __x64_sys_ioctl+0x193/0x200 fs/ioctl.c:739 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Reported-by: syzbot+ae488dc136a4cc6ba32b@syzkaller.appspotmail.com Signed-off-by: Like Xu Message-Id: <20210118025800.34620-1-like.xu@linux.intel.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/pmu_intel.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index a886a47daebda..d1584ae6625a1 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -345,7 +345,9 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters, x86_pmu.num_counters_gp); + eax.split.bit_width = min_t(int, eax.split.bit_width, x86_pmu.bit_width_gp); pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1; + eax.split.mask_length = min_t(int, eax.split.mask_length, x86_pmu.events_mask_len); pmu->available_event_types = ~entry->ebx & ((1ull << eax.split.mask_length) - 1); @@ -355,6 +357,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->nr_arch_fixed_counters = min_t(int, edx.split.num_counters_fixed, x86_pmu.num_counters_fixed); + edx.split.bit_width_fixed = min_t(int, + edx.split.bit_width_fixed, x86_pmu.bit_width_fixed); pmu->counter_bitmask[KVM_PMC_FIXED] = ((u64)1 << edx.split.bit_width_fixed) - 1; } -- GitLab From 98dd2f108e448988d91e296173e773b06fb978b8 Mon Sep 17 00:00:00 2001 From: Like Xu Date: Wed, 30 Dec 2020 16:19:16 +0800 Subject: [PATCH 0641/1084] KVM: x86/pmu: Fix HW_REF_CPU_CYCLES event pseudo-encoding in intel_arch_events[] The HW_REF_CPU_CYCLES event on the fixed counter 2 is pseudo-encoded as 0x0300 in the intel_perfmon_event_map[]. Correct its usage. Fixes: 62079d8a4312 ("KVM: PMU: add proper support for fixed counter 2") Signed-off-by: Like Xu Message-Id: <20201230081916.63417-1-like.xu@linux.intel.com> Reviewed-by: Sean Christopherson Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/pmu_intel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index d1584ae6625a1..cdf5f34518f43 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -29,7 +29,7 @@ static struct kvm_event_hw_type_mapping intel_arch_events[] = { [4] = { 0x2e, 0x41, PERF_COUNT_HW_CACHE_MISSES }, [5] = { 0xc4, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, [6] = { 0xc5, 0x00, PERF_COUNT_HW_BRANCH_MISSES }, - [7] = { 0x00, 0x30, PERF_COUNT_HW_REF_CPU_CYCLES }, + [7] = { 0x00, 0x03, PERF_COUNT_HW_REF_CPU_CYCLES }, }; /* mapping between fixed pmc index and intel_arch_events array */ -- GitLab From 1f7becf1b7e21794fc9d460765fe09679bc9b9e0 Mon Sep 17 00:00:00 2001 From: Jay Zhou Date: Mon, 18 Jan 2021 16:47:20 +0800 Subject: [PATCH 0642/1084] KVM: x86: get smi pending status correctly The injection process of smi has two steps: Qemu KVM Step1: cpu->interrupt_request &= \ ~CPU_INTERRUPT_SMI; kvm_vcpu_ioctl(cpu, KVM_SMI) call kvm_vcpu_ioctl_smi() and kvm_make_request(KVM_REQ_SMI, vcpu); Step2: kvm_vcpu_ioctl(cpu, KVM_RUN, 0) call process_smi() if kvm_check_request(KVM_REQ_SMI, vcpu) is true, mark vcpu->arch.smi_pending = true; The vcpu->arch.smi_pending will be set true in step2, unfortunately if vcpu paused between step1 and step2, the kvm_run->immediate_exit will be set and vcpu has to exit to Qemu immediately during step2 before mark vcpu->arch.smi_pending true. During VM migration, Qemu will get the smi pending status from KVM using KVM_GET_VCPU_EVENTS ioctl at the downtime, then the smi pending status will be lost. Signed-off-by: Jay Zhou Signed-off-by: Shengen Zhuang Message-Id: <20210118084720.1585-1-jianjay.zhou@huawei.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9a8969a6dd063..9025c7673af61 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -105,6 +105,7 @@ static u64 __read_mostly cr4_reserved_bits = CR4_RESERVED_BITS; static void update_cr8_intercept(struct kvm_vcpu *vcpu); static void process_nmi(struct kvm_vcpu *vcpu); +static void process_smi(struct kvm_vcpu *vcpu); static void enter_smm(struct kvm_vcpu *vcpu); static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags); static void store_regs(struct kvm_vcpu *vcpu); @@ -4230,6 +4231,9 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, { process_nmi(vcpu); + if (kvm_check_request(KVM_REQ_SMI, vcpu)) + process_smi(vcpu); + /* * In guest mode, payload delivery should be deferred, * so that the L1 hypervisor can intercept #PF before -- GitLab From 01ead84ccd23afadebe66aea0eda002ac29ca9be Mon Sep 17 00:00:00 2001 From: Zenghui Yu Date: Tue, 8 Dec 2020 12:34:39 +0800 Subject: [PATCH 0643/1084] KVM: Documentation: Update description of KVM_{GET,CLEAR}_DIRTY_LOG Update various words, including the wrong parameter name and the vague description of the usage of "slot" field. Signed-off-by: Zenghui Yu Message-Id: <20201208043439.895-1-yuzenghui@huawei.com> Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/api.rst | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 40b943a9bd1da..99ceb978c8b08 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -360,10 +360,9 @@ since the last call to this ioctl. Bit 0 is the first page in the memory slot. Ensure the entire structure is cleared to avoid padding issues. -If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies -the address space for which you want to return the dirty bitmap. -They must be less than the value that KVM_CHECK_EXTENSION returns for -the KVM_CAP_MULTI_ADDRESS_SPACE capability. +If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies +the address space for which you want to return the dirty bitmap. See +KVM_SET_USER_MEMORY_REGION for details on the usage of slot field. The bits in the dirty bitmap are cleared before the ioctl returns, unless KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is enabled. For more information, @@ -4435,7 +4434,7 @@ to I/O ports. :Capability: KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 :Architectures: x86, arm, arm64, mips :Type: vm ioctl -:Parameters: struct kvm_dirty_log (in) +:Parameters: struct kvm_clear_dirty_log (in) :Returns: 0 on success, -1 on error :: @@ -4462,10 +4461,9 @@ in KVM's dirty bitmap, and dirty tracking is re-enabled for that page (for example via write-protection, or by clearing the dirty bit in a page table entry). -If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies -the address space for which you want to return the dirty bitmap. -They must be less than the value that KVM_CHECK_EXTENSION returns for -the KVM_CAP_MULTI_ADDRESS_SPACE capability. +If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies +the address space for which you want to clear the dirty status. See +KVM_SET_USER_MEMORY_REGION for details on the usage of slot field. This ioctl is mostly useful when KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is enabled; for more information, see the description of the capability. -- GitLab From d95df9510679757bdfc22376d351cdf367b3a604 Mon Sep 17 00:00:00 2001 From: Lorenzo Brescia Date: Wed, 23 Dec 2020 14:45:07 +0000 Subject: [PATCH 0644/1084] kvm: tracing: Fix unmatched kvm_entry and kvm_exit events On VMX, if we exit and then re-enter immediately without leaving the vmx_vcpu_run() function, the kvm_entry event is not logged. That means we will see one (or more) kvm_exit, without its (their) corresponding kvm_entry, as shown here: CPU-1979 [002] 89.871187: kvm_entry: vcpu 1 CPU-1979 [002] 89.871218: kvm_exit: reason MSR_WRITE CPU-1979 [002] 89.871259: kvm_exit: reason MSR_WRITE It also seems possible for a kvm_entry event to be logged, but then we leave vmx_vcpu_run() right away (if vmx->emulation_required is true). In this case, we will have a spurious kvm_entry event in the trace. Fix these situations by moving trace_kvm_entry() inside vmx_vcpu_run() (where trace_kvm_exit() already is). A trace obtained with this patch applied looks like this: CPU-14295 [000] 8388.395387: kvm_entry: vcpu 0 CPU-14295 [000] 8388.395392: kvm_exit: reason MSR_WRITE CPU-14295 [000] 8388.395393: kvm_entry: vcpu 0 CPU-14295 [000] 8388.395503: kvm_exit: reason EXTERNAL_INTERRUPT Of course, not calling trace_kvm_entry() in common x86 code any longer means that we need to adjust the SVM side of things too. Signed-off-by: Lorenzo Brescia Signed-off-by: Dario Faggioli Message-Id: <160873470698.11652.13483635328769030605.stgit@Wayrath> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 2 ++ arch/x86/kvm/vmx/vmx.c | 2 ++ arch/x86/kvm/x86.c | 3 +-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 7ef171790d02b..f923e14e87df2 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3739,6 +3739,8 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + trace_kvm_entry(vcpu); + svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; svm->vmcb->save.rip = vcpu->arch.regs[VCPU_REGS_RIP]; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 2af05d3b05909..cc60b1fc3ee71 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6653,6 +6653,8 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu) if (vmx->emulation_required) return EXIT_FASTPATH_NONE; + trace_kvm_entry(vcpu); + if (vmx->ple_window_dirty) { vmx->ple_window_dirty = false; vmcs_write32(PLE_WINDOW, vmx->ple_window); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9025c7673af61..1f64e8b97605d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8992,8 +8992,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) kvm_x86_ops.request_immediate_exit(vcpu); } - trace_kvm_entry(vcpu); - fpregs_assert_state_consistent(); if (test_thread_flag(TIF_NEED_FPU_LOAD)) switch_fpu_return(); @@ -11560,6 +11558,7 @@ int kvm_sev_es_string_io(struct kvm_vcpu *vcpu, unsigned int size, } EXPORT_SYMBOL_GPL(kvm_sev_es_string_io); +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_entry); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_fast_mmio); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); -- GitLab From d51e1d3f6b4236e0352407d8a63f5c5f71ce193d Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Thu, 14 Jan 2021 22:54:47 +0200 Subject: [PATCH 0645/1084] KVM: nVMX: Sync unsync'd vmcs02 state to vmcs12 on migration Even when we are outside the nested guest, some vmcs02 fields may not be in sync vs vmcs12. This is intentional, even across nested VM-exit, because the sync can be delayed until the nested hypervisor performs a VMCLEAR or a VMREAD/VMWRITE that affects those rarely accessed fields. However, during KVM_GET_NESTED_STATE, the vmcs12 has to be up to date to be able to restore it. To fix that, call copy_vmcs02_to_vmcs12_rare() before the vmcs12 contents are copied to userspace. Fixes: 7952d769c29ca ("KVM: nVMX: Sync rarely accessed guest fields only when needed") Reviewed-by: Sean Christopherson Signed-off-by: Maxim Levitsky Message-Id: <20210114205449.8715-2-mlevitsk@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/nested.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 0fbb46990dfce..776688f9d1017 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -6077,11 +6077,14 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu, if (is_guest_mode(vcpu)) { sync_vmcs02_to_vmcs12(vcpu, vmcs12); sync_vmcs02_to_vmcs12_rare(vcpu, vmcs12); - } else if (!vmx->nested.need_vmcs12_to_shadow_sync) { - if (vmx->nested.hv_evmcs) - copy_enlightened_to_vmcs12(vmx); - else if (enable_shadow_vmcs) - copy_shadow_to_vmcs12(vmx); + } else { + copy_vmcs02_to_vmcs12_rare(vcpu, get_vmcs12(vcpu)); + if (!vmx->nested.need_vmcs12_to_shadow_sync) { + if (vmx->nested.hv_evmcs) + copy_enlightened_to_vmcs12(vmx); + else if (enable_shadow_vmcs) + copy_shadow_to_vmcs12(vmx); + } } BUILD_BUG_ON(sizeof(user_vmx_nested_state->vmcs12) < VMCS12_SIZE); -- GitLab From 250091409a4ac567581c1f929eb39139b57b56ec Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 22 Jan 2021 15:50:47 -0800 Subject: [PATCH 0646/1084] KVM: SVM: Unconditionally sync GPRs to GHCB on VMRUN of SEV-ES guest Drop the per-GPR dirty checks when synchronizing GPRs to the GHCB, the GRPs' dirty bits are set from time zero and never cleared, i.e. will always be seen as dirty. The obvious alternative would be to clear the dirty bits when appropriate, but removing the dirty checks is desirable as it allows reverting GPR dirty+available tracking, which adds overhead to all flavors of x86 VMs. Note, unconditionally writing the GPRs in the GHCB is tacitly allowed by the GHCB spec, which allows the hypervisor (or guest) to provide unnecessary info; it's the guest's responsibility to consume only what it needs (the hypervisor is untrusted after all). The guest and hypervisor can supply additional state if desired but must not rely on that additional state being provided. Cc: Brijesh Singh Cc: Tom Lendacky Fixes: 291bd20d5d88 ("KVM: SVM: Add initial support for a VMGEXIT VMEXIT") Signed-off-by: Sean Christopherson Message-Id: <20210122235049.3107620-2-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/sev.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index c8ffdbc81709e..ac652bc476ae7 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -1415,16 +1415,13 @@ static void sev_es_sync_to_ghcb(struct vcpu_svm *svm) * to be returned: * GPRs RAX, RBX, RCX, RDX * - * Copy their values to the GHCB if they are dirty. + * Copy their values, even if they may not have been written during the + * VM-Exit. It's the guest's responsibility to not consume random data. */ - if (kvm_register_is_dirty(vcpu, VCPU_REGS_RAX)) - ghcb_set_rax(ghcb, vcpu->arch.regs[VCPU_REGS_RAX]); - if (kvm_register_is_dirty(vcpu, VCPU_REGS_RBX)) - ghcb_set_rbx(ghcb, vcpu->arch.regs[VCPU_REGS_RBX]); - if (kvm_register_is_dirty(vcpu, VCPU_REGS_RCX)) - ghcb_set_rcx(ghcb, vcpu->arch.regs[VCPU_REGS_RCX]); - if (kvm_register_is_dirty(vcpu, VCPU_REGS_RDX)) - ghcb_set_rdx(ghcb, vcpu->arch.regs[VCPU_REGS_RDX]); + ghcb_set_rax(ghcb, vcpu->arch.regs[VCPU_REGS_RAX]); + ghcb_set_rbx(ghcb, vcpu->arch.regs[VCPU_REGS_RBX]); + ghcb_set_rcx(ghcb, vcpu->arch.regs[VCPU_REGS_RCX]); + ghcb_set_rdx(ghcb, vcpu->arch.regs[VCPU_REGS_RDX]); } static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) -- GitLab From aed89418de9a881419516fa0a5643577f521efc9 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 22 Jan 2021 15:50:48 -0800 Subject: [PATCH 0647/1084] KVM: x86: Revert "KVM: x86: Mark GPRs dirty when written" Revert the dirty/available tracking of GPRs now that KVM copies the GPRs to the GHCB on any post-VMGEXIT VMRUN, even if a GPR is not dirty. Per commit de3cd117ed2f ("KVM: x86: Omit caching logic for always-available GPRs"), tracking for GPRs noticeably impacts KVM's code footprint. This reverts commit 1c04d8c986567c27c56c05205dceadc92efb14ff. Signed-off-by: Sean Christopherson Message-Id: <20210122235049.3107620-3-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/kvm_cache_regs.h | 51 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index f15bc16de07c3..a889563ad02d5 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h @@ -9,31 +9,6 @@ (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \ | X86_CR4_OSXMMEXCPT | X86_CR4_PGE | X86_CR4_TSD | X86_CR4_FSGSBASE) -static inline bool kvm_register_is_available(struct kvm_vcpu *vcpu, - enum kvm_reg reg) -{ - return test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); -} - -static inline bool kvm_register_is_dirty(struct kvm_vcpu *vcpu, - enum kvm_reg reg) -{ - return test_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty); -} - -static inline void kvm_register_mark_available(struct kvm_vcpu *vcpu, - enum kvm_reg reg) -{ - __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); -} - -static inline void kvm_register_mark_dirty(struct kvm_vcpu *vcpu, - enum kvm_reg reg) -{ - __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); - __set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty); -} - #define BUILD_KVM_GPR_ACCESSORS(lname, uname) \ static __always_inline unsigned long kvm_##lname##_read(struct kvm_vcpu *vcpu)\ { \ @@ -43,7 +18,6 @@ static __always_inline void kvm_##lname##_write(struct kvm_vcpu *vcpu, \ unsigned long val) \ { \ vcpu->arch.regs[VCPU_REGS_##uname] = val; \ - kvm_register_mark_dirty(vcpu, VCPU_REGS_##uname); \ } BUILD_KVM_GPR_ACCESSORS(rax, RAX) BUILD_KVM_GPR_ACCESSORS(rbx, RBX) @@ -63,6 +37,31 @@ BUILD_KVM_GPR_ACCESSORS(r14, R14) BUILD_KVM_GPR_ACCESSORS(r15, R15) #endif +static inline bool kvm_register_is_available(struct kvm_vcpu *vcpu, + enum kvm_reg reg) +{ + return test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); +} + +static inline bool kvm_register_is_dirty(struct kvm_vcpu *vcpu, + enum kvm_reg reg) +{ + return test_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty); +} + +static inline void kvm_register_mark_available(struct kvm_vcpu *vcpu, + enum kvm_reg reg) +{ + __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); +} + +static inline void kvm_register_mark_dirty(struct kvm_vcpu *vcpu, + enum kvm_reg reg) +{ + __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); + __set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty); +} + static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu, int reg) { if (WARN_ON_ONCE((unsigned int)reg >= NR_VCPU_REGS)) -- GitLab From 9a78e15802a87de2b08dfd1bd88e855201d2c8fa Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 8 Jan 2021 11:43:08 -0500 Subject: [PATCH 0648/1084] KVM: x86: allow KVM_REQ_GET_NESTED_STATE_PAGES outside guest mode for VMX VMX also uses KVM_REQ_GET_NESTED_STATE_PAGES for the Hyper-V eVMCS, which may need to be loaded outside guest mode. Therefore we cannot WARN in that case. However, that part of nested_get_vmcs12_pages is _not_ needed at vmentry time. Split it out of KVM_REQ_GET_NESTED_STATE_PAGES handling, so that both vmentry and migration (and in the latter case, independent of is_guest_mode) do the parts that are needed. Cc: # 5.10.x: f2c7ef3ba: KVM: nSVM: cancel KVM_REQ_GET_NESTED_STATE_PAGES Cc: # 5.10.x Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/nested.c | 3 +++ arch/x86/kvm/vmx/nested.c | 31 +++++++++++++++++++++++++------ arch/x86/kvm/x86.c | 4 +--- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index cb4c6ee10029c..7a605ad8254db 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -200,6 +200,9 @@ static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + if (WARN_ON(!is_guest_mode(vcpu))) + return true; + if (!nested_svm_vmrun_msrpm(svm)) { vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; vcpu->run->internal.suberror = diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 776688f9d1017..f2b9bfb582067 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -3124,13 +3124,9 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu) return 0; } -static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) +static bool nested_get_evmcs_page(struct kvm_vcpu *vcpu) { - struct vmcs12 *vmcs12 = get_vmcs12(vcpu); struct vcpu_vmx *vmx = to_vmx(vcpu); - struct kvm_host_map *map; - struct page *page; - u64 hpa; /* * hv_evmcs may end up being not mapped after migration (when @@ -3153,6 +3149,17 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) } } + return true; +} + +static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) +{ + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); + struct vcpu_vmx *vmx = to_vmx(vcpu); + struct kvm_host_map *map; + struct page *page; + u64 hpa; + if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { /* * Translate L1 physical address to host physical @@ -3221,6 +3228,18 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) exec_controls_setbit(vmx, CPU_BASED_USE_MSR_BITMAPS); else exec_controls_clearbit(vmx, CPU_BASED_USE_MSR_BITMAPS); + + return true; +} + +static bool vmx_get_nested_state_pages(struct kvm_vcpu *vcpu) +{ + if (!nested_get_evmcs_page(vcpu)) + return false; + + if (is_guest_mode(vcpu) && !nested_get_vmcs12_pages(vcpu)) + return false; + return true; } @@ -6605,7 +6624,7 @@ struct kvm_x86_nested_ops vmx_nested_ops = { .hv_timer_pending = nested_vmx_preemption_timer_pending, .get_state = vmx_get_nested_state, .set_state = vmx_set_nested_state, - .get_nested_state_pages = nested_get_vmcs12_pages, + .get_nested_state_pages = vmx_get_nested_state_pages, .write_log_dirty = nested_vmx_write_pml_buffer, .enable_evmcs = nested_enable_evmcs, .get_evmcs_version = nested_get_evmcs_version, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1f64e8b97605d..76bce832cade2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8806,9 +8806,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) if (kvm_request_pending(vcpu)) { if (kvm_check_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu)) { - if (WARN_ON_ONCE(!is_guest_mode(vcpu))) - ; - else if (unlikely(!kvm_x86_ops.nested_ops->get_nested_state_pages(vcpu))) { + if (unlikely(!kvm_x86_ops.nested_ops->get_nested_state_pages(vcpu))) { r = 0; goto out; } -- GitLab From 0b964446c63f9d7d7cd1809ee39277b4f73916b5 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 19 Jan 2021 17:22:03 +0100 Subject: [PATCH 0649/1084] ecryptfs: fix uid translation for setxattr on security.capability Prior to commit 7c03e2cda4a5 ("vfs: move cap_convert_nscap() call into vfs_setxattr()") the translation of nscap->rootid did not take stacked filesystems (overlayfs and ecryptfs) into account. That patch fixed the overlay case, but made the ecryptfs case worse. Restore old the behavior for ecryptfs that existed before the overlayfs fix. This does not fix ecryptfs's handling of complex user namespace setups, but it does make sure existing setups don't regress. Reported-by: Eric W. Biederman Cc: Tyler Hicks Fixes: 7c03e2cda4a5 ("vfs: move cap_convert_nscap() call into vfs_setxattr()") Signed-off-by: Miklos Szeredi Signed-off-by: Tyler Hicks --- fs/ecryptfs/inode.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index e23752d9a79f3..58d0f71879979 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -1016,15 +1016,19 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode, { int rc; struct dentry *lower_dentry; + struct inode *lower_inode; lower_dentry = ecryptfs_dentry_to_lower(dentry); - if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) { + lower_inode = d_inode(lower_dentry); + if (!(lower_inode->i_opflags & IOP_XATTR)) { rc = -EOPNOTSUPP; goto out; } - rc = vfs_setxattr(lower_dentry, name, value, size, flags); + inode_lock(lower_inode); + rc = __vfs_setxattr_locked(lower_dentry, name, value, size, flags, NULL); + inode_unlock(lower_inode); if (!rc && inode) - fsstack_copy_attr_all(inode, d_inode(lower_dentry)); + fsstack_copy_attr_all(inode, lower_inode); out: return rc; } -- GitLab From 0549cd67b01016b579047bce045b386202a8bcfc Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Tue, 19 Jan 2021 11:57:27 +0100 Subject: [PATCH 0650/1084] xen-blkfront: allow discard-* nodes to be optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is inline with the specification described in blkif.h: * discard-granularity: should be set to the physical block size if node is not present. * discard-alignment, discard-secure: should be set to 0 if node not present. This was detected as QEMU would only create the discard-granularity node but not discard-alignment, and thus the setup done in blkfront_setup_discard would fail. Fix blkfront_setup_discard to not fail on missing nodes, and also fix blkif_set_queue_limits to set the discard granularity to the physical block size if none is specified in xenbus. Fixes: ed30bf317c5ce ('xen-blkfront: Handle discard requests.') Reported-by: Arthur Borsboom Signed-off-by: Roger Pau Monné Reviewed-by: Juergen Gross Tested-By: Arthur Borsboom Link: https://lore.kernel.org/r/20210119105727.95173-1-roger.pau@citrix.com Signed-off-by: Juergen Gross --- drivers/block/xen-blkfront.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 34b028be78ab1..1ee9545ea2f11 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -945,7 +945,8 @@ static void blkif_set_queue_limits(struct blkfront_info *info) if (info->feature_discard) { blk_queue_flag_set(QUEUE_FLAG_DISCARD, rq); blk_queue_max_discard_sectors(rq, get_capacity(gd)); - rq->limits.discard_granularity = info->discard_granularity; + rq->limits.discard_granularity = info->discard_granularity ?: + info->physical_sector_size; rq->limits.discard_alignment = info->discard_alignment; if (info->feature_secdiscard) blk_queue_flag_set(QUEUE_FLAG_SECERASE, rq); @@ -2179,19 +2180,12 @@ static void blkfront_closing(struct blkfront_info *info) static void blkfront_setup_discard(struct blkfront_info *info) { - int err; - unsigned int discard_granularity; - unsigned int discard_alignment; - info->feature_discard = 1; - err = xenbus_gather(XBT_NIL, info->xbdev->otherend, - "discard-granularity", "%u", &discard_granularity, - "discard-alignment", "%u", &discard_alignment, - NULL); - if (!err) { - info->discard_granularity = discard_granularity; - info->discard_alignment = discard_alignment; - } + info->discard_granularity = xenbus_read_unsigned(info->xbdev->otherend, + "discard-granularity", + 0); + info->discard_alignment = xenbus_read_unsigned(info->xbdev->otherend, + "discard-alignment", 0); info->feature_secdiscard = !!xenbus_read_unsigned(info->xbdev->otherend, "discard-secure", 0); -- GitLab From 179e8e47c02a1950f1c556f2b854bdb2259078fb Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Thu, 21 Jan 2021 10:46:49 -0800 Subject: [PATCH 0651/1084] HID: wacom: Correct NULL dereference on AES pen proximity The recent commit to fix a memory leak introduced an inadvertant NULL pointer dereference. The `wacom_wac->pen_fifo` variable was never intialized, resuling in a crash whenever functions tried to use it. Since the FIFO is only used by AES pens (to buffer events from pen proximity until the hardware reports the pen serial number) this would have been easily overlooked without testing an AES device. This patch converts `wacom_wac->pen_fifo` over to a pointer (since the call to `devres_alloc` allocates memory for us) and ensures that we assign it to point to the allocated and initalized `pen_fifo` before the function returns. Link: https://github.com/linuxwacom/input-wacom/issues/230 Fixes: 37309f47e2f5 ("HID: wacom: Fix memory leakage caused by kfifo_alloc") CC: stable@vger.kernel.org # v4.19+ Signed-off-by: Jason Gerecke Tested-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 7 ++++--- drivers/hid/wacom_wac.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index e8acd235db2a9..aa9e48876ceda 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -147,9 +147,9 @@ static int wacom_wac_pen_serial_enforce(struct hid_device *hdev, } if (flush) - wacom_wac_queue_flush(hdev, &wacom_wac->pen_fifo); + wacom_wac_queue_flush(hdev, wacom_wac->pen_fifo); else if (insert) - wacom_wac_queue_insert(hdev, &wacom_wac->pen_fifo, + wacom_wac_queue_insert(hdev, wacom_wac->pen_fifo, raw_data, report_size); return insert && !flush; @@ -1280,7 +1280,7 @@ static void wacom_devm_kfifo_release(struct device *dev, void *res) static int wacom_devm_kfifo_alloc(struct wacom *wacom) { struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct kfifo_rec_ptr_2 *pen_fifo = &wacom_wac->pen_fifo; + struct kfifo_rec_ptr_2 *pen_fifo; int error; pen_fifo = devres_alloc(wacom_devm_kfifo_release, @@ -1297,6 +1297,7 @@ static int wacom_devm_kfifo_alloc(struct wacom *wacom) } devres_add(&wacom->hdev->dev, pen_fifo); + wacom_wac->pen_fifo = pen_fifo; return 0; } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index da612b6e9c779..195910dd2154e 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -342,7 +342,7 @@ struct wacom_wac { struct input_dev *pen_input; struct input_dev *touch_input; struct input_dev *pad_input; - struct kfifo_rec_ptr_2 pen_fifo; + struct kfifo_rec_ptr_2 *pen_fifo; int pid; int num_contacts_left; u8 bt_features; -- GitLab From 5122565188bae59d507d90a9a9fd2fd6107f4439 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 21 Jan 2021 17:16:22 +0100 Subject: [PATCH 0652/1084] wext: fix NULL-ptr-dereference with cfg80211's lack of commit() Since cfg80211 doesn't implement commit, we never really cared about that code there (and it's configured out w/o CONFIG_WIRELESS_EXT). After all, since it has no commit, it shouldn't return -EIWCOMMIT to indicate commit is needed. However, EIWCOMMIT is actually an alias for EINPROGRESS, which _can_ happen if e.g. we try to change the frequency but we're already in the process of connecting to some network, and drivers could return that value (or even cfg80211 itself might). This then causes us to crash because dev->wireless_handlers is NULL but we try to check dev->wireless_handlers->standard[0]. Fix this by also checking dev->wireless_handlers. Also simplify the code a little bit. Cc: stable@vger.kernel.org Reported-by: syzbot+444248c79e117bc99f46@syzkaller.appspotmail.com Reported-by: syzbot+8b2a88a09653d4084179@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/20210121171621.2076e4a37d5a.I5d9c72220fe7bb133fb718751da0180a57ecba4e@changeid Signed-off-by: Johannes Berg --- net/wireless/wext-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 69102fda9ebd4..76a80a41615be 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -896,8 +896,9 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, int call_commit_handler(struct net_device *dev) { #ifdef CONFIG_WIRELESS_EXT - if ((netif_running(dev)) && - (dev->wireless_handlers->standard[0] != NULL)) + if (netif_running(dev) && + dev->wireless_handlers && + dev->wireless_handlers->standard[0]) /* Call the commit handler on the driver */ return dev->wireless_handlers->standard[0](dev, NULL, NULL, NULL); -- GitLab From 054c9939b4800a91475d8d89905827bf9e1ad97a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jan 2021 17:11:16 +0100 Subject: [PATCH 0653/1084] mac80211: pause TX while changing interface type syzbot reported a crash that happened when changing the interface type around a lot, and while it might have been easy to fix just the symptom there, a little deeper investigation found that really the reason is that we allowed packets to be transmitted while in the middle of changing the interface type. Disallow TX by stopping the queues while changing the type. Fixes: 34d4bc4d41d2 ("mac80211: support runtime interface type changes") Reported-by: syzbot+d7a3b15976bf7de2238a@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/20210122171115.b321f98f4d4f.I6997841933c17b093535c31d29355be3c0c39628@changeid Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 1 + net/mac80211/iface.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8bf9c0e974d62..8e281c2e644d5 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1078,6 +1078,7 @@ enum queue_stop_reason { IEEE80211_QUEUE_STOP_REASON_FLUSH, IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN, IEEE80211_QUEUE_STOP_REASON_RESERVE_TID, + IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE, IEEE80211_QUEUE_STOP_REASONS, }; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 3b9ec4ef81c3b..b31417f40bd56 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1617,6 +1617,10 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, if (ret) return ret; + ieee80211_stop_vif_queues(local, sdata, + IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE); + synchronize_net(); + ieee80211_do_stop(sdata, false); ieee80211_teardown_sdata(sdata); @@ -1639,6 +1643,8 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, err = ieee80211_do_open(&sdata->wdev, false); WARN(err, "type change: do_open returned %d", err); + ieee80211_wake_vif_queues(local, sdata, + IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE); return ret; } -- GitLab From 81f153faacd04c049e5482d6ff33daddc30ed44e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Jan 2021 11:54:09 +0100 Subject: [PATCH 0654/1084] staging: rtl8723bs: fix wireless regulatory API misuse This code ends up calling wiphy_apply_custom_regulatory(), for which we document that it should be called before wiphy_register(). This driver doesn't do that, but calls it from ndo_open() with the RTNL held, which caused deadlocks. Since the driver just registers static regdomain data and then the notifier applies the channel changes if any, there's no reason for it to call this in ndo_open(), move it earlier to fix the deadlock. Reported-and-tested-by: Hans de Goede Fixes: 51d62f2f2c50 ("cfg80211: Save the regulatory domain with a lock") Link: https://lore.kernel.org/r/20210126115409.d5fd6f8fe042.Ib5823a6feb2e2aa01ca1a565d2505367f38ad246@changeid Acked-by: Greg Kroah-Hartman Signed-off-by: Johannes Berg --- drivers/staging/rtl8723bs/include/rtw_wifi_regd.h | 6 +++--- drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 6 +++--- drivers/staging/rtl8723bs/os_dep/wifi_regd.c | 10 +++------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8723bs/include/rtw_wifi_regd.h b/drivers/staging/rtl8723bs/include/rtw_wifi_regd.h index ab5a8627d3712..f798b0c744a4f 100644 --- a/drivers/staging/rtl8723bs/include/rtw_wifi_regd.h +++ b/drivers/staging/rtl8723bs/include/rtw_wifi_regd.h @@ -20,9 +20,9 @@ enum country_code_type_t { COUNTRY_CODE_MAX }; -int rtw_regd_init(struct adapter *padapter, - void (*reg_notifier)(struct wiphy *wiphy, - struct regulatory_request *request)); +void rtw_regd_init(struct wiphy *wiphy, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)); void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index bf14172361618..11032316c53dc 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -3211,9 +3211,6 @@ void rtw_cfg80211_init_wiphy(struct adapter *padapter) rtw_cfg80211_init_ht_capab(&bands->ht_cap, NL80211_BAND_2GHZ, rf_type); } - /* init regulary domain */ - rtw_regd_init(padapter, rtw_reg_notifier); - /* copy mac_addr to wiphy */ memcpy(wiphy->perm_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); @@ -3328,6 +3325,9 @@ int rtw_wdev_alloc(struct adapter *padapter, struct device *dev) *((struct adapter **)wiphy_priv(wiphy)) = padapter; rtw_cfg80211_preinit_wiphy(padapter, wiphy); + /* init regulary domain */ + rtw_regd_init(wiphy, rtw_reg_notifier); + ret = wiphy_register(wiphy); if (ret < 0) { DBG_8192C("Couldn't register wiphy device\n"); diff --git a/drivers/staging/rtl8723bs/os_dep/wifi_regd.c b/drivers/staging/rtl8723bs/os_dep/wifi_regd.c index 578b9f734231e..2833fc6901e6e 100644 --- a/drivers/staging/rtl8723bs/os_dep/wifi_regd.c +++ b/drivers/staging/rtl8723bs/os_dep/wifi_regd.c @@ -139,15 +139,11 @@ static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, _rtw_reg_apply_flags(wiphy); } -int rtw_regd_init(struct adapter *padapter, - void (*reg_notifier)(struct wiphy *wiphy, - struct regulatory_request *request)) +void rtw_regd_init(struct wiphy *wiphy, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) { - struct wiphy *wiphy = padapter->rtw_wdev->wiphy; - _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier); - - return 0; } void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) -- GitLab From ef99a60ffd9b918354e038bc5e61f007ff7e901d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 17 Jan 2021 09:30:15 +0000 Subject: [PATCH 0655/1084] drm/i915/gt: Clear CACHE_MODE prior to clearing residuals Since we do a bare context switch with no restore, the clear residual kernel runs on dirty state, and we must be careful to avoid executing with bad state from context registers inherited from a malicious client. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2955 Fixes: 09aa9e45863e ("drm/i915/gt: Restore clear-residual mitigations for Ivybridge, Baytrail") Testcase: igt/gem_ctx_isolation # ivb,vlv Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Akeem G Abodunrin Reviewed-by: Akeem G Abodunrin Link: https://patchwork.freedesktop.org/patch/msgid/20210117093015.29143-1-chris@chris-wilson.co.uk (cherry picked from commit ace44e13e577c2ae59980e9a6ff5ca253b1cf831) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gt/gen7_renderclear.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/gen7_renderclear.c b/drivers/gpu/drm/i915/gt/gen7_renderclear.c index 94465374ca2fe..e961ad6a31294 100644 --- a/drivers/gpu/drm/i915/gt/gen7_renderclear.c +++ b/drivers/gpu/drm/i915/gt/gen7_renderclear.c @@ -390,6 +390,16 @@ static void emit_batch(struct i915_vma * const vma, &cb_kernel_ivb, desc_count); + /* Reset inherited context registers */ + gen7_emit_pipeline_invalidate(&cmds); + batch_add(&cmds, MI_LOAD_REGISTER_IMM(2)); + batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7)); + batch_add(&cmds, 0xffff0000); + batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_1)); + batch_add(&cmds, 0xffff0000 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE); + gen7_emit_pipeline_flush(&cmds); + + /* Switch to the media pipeline and our base address */ gen7_emit_pipeline_invalidate(&cmds); batch_add(&cmds, PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); batch_add(&cmds, MI_NOOP); @@ -399,9 +409,11 @@ static void emit_batch(struct i915_vma * const vma, gen7_emit_state_base_address(&cmds, descriptors); gen7_emit_pipeline_invalidate(&cmds); + /* Set the clear-residual kernel state */ gen7_emit_vfe_state(&cmds, bv, urb_size - 1, 0, 0); gen7_emit_interface_descriptor_load(&cmds, descriptors, desc_count); + /* Execute the kernel on all HW threads */ for (i = 0; i < num_primitives(bv); i++) gen7_emit_media_object(&cmds, i); -- GitLab From a2a5f5628e5494ca9353f761f7fe783dfa82fb9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 7 Dec 2020 22:35:11 +0200 Subject: [PATCH 0656/1084] drm/i915: Fix ICL MG PHY vswing handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MH PHY vswing table does have all the entries these days. Get rid of the old hacks in the code which claim otherwise. This hack was totally bogus anyway. The correct way to handle the lack of those two entries would have been to declare our max vswing and pre-emph to both be level 2. Cc: José Roberto de Souza Cc: Clinton Taylor Fixes: 9f7ffa297978 ("drm/i915/tc/icl: Update TC vswing tables") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201207203512.1718-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak Reviewed-by: José Roberto de Souza (cherry picked from commit 5ec346476e795089b7dac8ab9dcee30c8d80ad84) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index d5ace48b1acee..bf17365857caf 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2755,12 +2755,11 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32 val; ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries); - /* The table does not have values for level 3 and level 9. */ - if (level >= n_entries || level == 3 || level == 9) { + if (level >= n_entries) { drm_dbg_kms(&dev_priv->drm, "DDI translation not found for level %d. Using %d instead.", - level, n_entries - 2); - level = n_entries - 2; + level, n_entries - 1); + level = n_entries - 1; } /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */ -- GitLab From 8f6d08c9af284d74276da6681348e4673f13caea Mon Sep 17 00:00:00 2001 From: Umesh Nerlige Ramappa Date: Thu, 21 Jan 2021 16:19:35 +0000 Subject: [PATCH 0657/1084] drm/i915: Check for all subplatform bits Current code is checking only 2 bits in the subplatform, but actually 3 bits are allocated for the field. Check all 3 bits. Fixes: 805446c8347c ("drm/i915: Introduce concept of a sub-platform") Cc: Tvrtko Ursulin Signed-off-by: Umesh Nerlige Ramappa Reviewed-by: Tvrtko Ursulin Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20210121161936.746591-1-tvrtko.ursulin@linux.intel.com (cherry picked from commit 27b695ee1af9bb36605e67055874ec081306ac28) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 632c713227dc7..c6964f82a1bb6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1346,7 +1346,7 @@ intel_subplatform(const struct intel_runtime_info *info, enum intel_platform p) { const unsigned int pi = __platform_mask_index(info, p); - return info->platform_mask[pi] & INTEL_SUBPLATFORM_BITS; + return info->platform_mask[pi] & ((1 << INTEL_SUBPLATFORM_BITS) - 1); } static __always_inline bool -- GitLab From 3d480fe1befa0ef434f5c25199e7d45c26870555 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Thu, 21 Jan 2021 17:56:40 -0800 Subject: [PATCH 0658/1084] drm/i915/selftest: Fix potential memory leak Object out is not released on path that no VMA instance found. The root cause is jumping to an unexpected label on the error path. Fixes: a47e788c2310 ("drm/i915/selftests: Exercise CS TLB invalidation") Signed-off-by: Pan Bian Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20210122015640.16002-1-bianpan2016@163.com (cherry picked from commit 2b015017d5cb01477a79ca184ac25c247d664568) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index c53a222e3dece..713770fb2b92d 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -1880,7 +1880,7 @@ static int igt_cs_tlb(void *arg) vma = i915_vma_instance(out, vm, NULL); if (IS_ERR(vma)) { err = PTR_ERR(vma); - goto out_put_batch; + goto out_put_out; } err = i915_vma_pin(vma, 0, 0, -- GitLab From f6e98a1809faa02f40e0d089d6cfc1aa372a34c0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 21 Jan 2021 23:28:07 +0000 Subject: [PATCH 0659/1084] drm/i915: Always flush the active worker before returning from the wait The first thing the active retirement worker does is decrement the i915_active count. The first thing we do during i915_active_wait is try to increment the i915_active count, but only if already active [non-zero]. The wait may see that the retirement is already started and so marked the i915_active as idle, and skip waiting for the retirement handler. However, the caller of i915_active_wait may immediately free the i915_active upon returning (e.g. i915_vma_destroy) so we must not return before the concurrent access from the worker is completed. We must always flush the worker. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2473 Fixes: 274cbf20fd10 ("drm/i915: Push the i915_active.retire into a worker") Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: Tvrtko Ursulin Cc: # v5.5+ Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20210121232807.16618-1-chris@chris-wilson.co.uk (cherry picked from commit 977a372e972cb42799746c284035a33c64ebace9) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_active.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c index 10a865f3dc09a..9ed19b8bca600 100644 --- a/drivers/gpu/drm/i915/i915_active.c +++ b/drivers/gpu/drm/i915/i915_active.c @@ -631,24 +631,26 @@ static int flush_lazy_signals(struct i915_active *ref) int __i915_active_wait(struct i915_active *ref, int state) { - int err; - might_sleep(); - if (!i915_active_acquire_if_busy(ref)) - return 0; - /* Any fence added after the wait begins will not be auto-signaled */ - err = flush_lazy_signals(ref); - i915_active_release(ref); - if (err) - return err; + if (i915_active_acquire_if_busy(ref)) { + int err; - if (!i915_active_is_idle(ref) && - ___wait_var_event(ref, i915_active_is_idle(ref), - state, 0, 0, schedule())) - return -EINTR; + err = flush_lazy_signals(ref); + i915_active_release(ref); + if (err) + return err; + if (___wait_var_event(ref, i915_active_is_idle(ref), + state, 0, 0, schedule())) + return -EINTR; + } + + /* + * After the wait is complete, the caller may free the active. + * We have to flush any concurrent retirement before returning. + */ flush_work(&ref->work); return 0; } -- GitLab From 489140b5ba2e7cc4b853c29e0591895ddb462a82 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 Jan 2021 12:50:33 +0000 Subject: [PATCH 0660/1084] drm/i915/gt: Always try to reserve GGTT address 0x0 Since writing to address 0 is a very common mistake, let's try to avoid putting anything sensitive there. References: https://gitlab.freedesktop.org/drm/intel/-/issues/2989 Signed-off-by: Chris Wilson Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20210125125033.23656-1-chris@chris-wilson.co.uk Cc: stable@vger.kernel.org (cherry picked from commit 56b429cc584c6ed8b895d8d8540959655db1ff73) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gt/intel_ggtt.c | 47 +++++++++++++++++++++------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index cf94525be2c18..db8c66dde6558 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -526,16 +526,39 @@ static int init_ggtt(struct i915_ggtt *ggtt) mutex_init(&ggtt->error_mutex); if (ggtt->mappable_end) { - /* Reserve a mappable slot for our lockless error capture */ - ret = drm_mm_insert_node_in_range(&ggtt->vm.mm, - &ggtt->error_capture, - PAGE_SIZE, 0, - I915_COLOR_UNEVICTABLE, - 0, ggtt->mappable_end, - DRM_MM_INSERT_LOW); - if (ret) - return ret; + /* + * Reserve a mappable slot for our lockless error capture. + * + * We strongly prefer taking address 0x0 in order to protect + * other critical buffers against accidental overwrites, + * as writing to address 0 is a very common mistake. + * + * Since 0 may already be in use by the system (e.g. the BIOS + * framebuffer), we let the reservation fail quietly and hope + * 0 remains reserved always. + * + * If we fail to reserve 0, and then fail to find any space + * for an error-capture, remain silent. We can afford not + * to reserve an error_capture node as we have fallback + * paths, and we trust that 0 will remain reserved. However, + * the only likely reason for failure to insert is a driver + * bug, which we expect to cause other failures... + */ + ggtt->error_capture.size = I915_GTT_PAGE_SIZE; + ggtt->error_capture.color = I915_COLOR_UNEVICTABLE; + if (drm_mm_reserve_node(&ggtt->vm.mm, &ggtt->error_capture)) + drm_mm_insert_node_in_range(&ggtt->vm.mm, + &ggtt->error_capture, + ggtt->error_capture.size, 0, + ggtt->error_capture.color, + 0, ggtt->mappable_end, + DRM_MM_INSERT_LOW); } + if (drm_mm_node_allocated(&ggtt->error_capture)) + drm_dbg(&ggtt->vm.i915->drm, + "Reserved GGTT:[%llx, %llx] for use by error capture\n", + ggtt->error_capture.start, + ggtt->error_capture.start + ggtt->error_capture.size); /* * The upper portion of the GuC address space has a sizeable hole @@ -548,9 +571,9 @@ static int init_ggtt(struct i915_ggtt *ggtt) /* Clear any non-preallocated blocks */ drm_mm_for_each_hole(entry, &ggtt->vm.mm, hole_start, hole_end) { - drm_dbg_kms(&ggtt->vm.i915->drm, - "clearing unused GTT space: [%lx, %lx]\n", - hole_start, hole_end); + drm_dbg(&ggtt->vm.i915->drm, + "clearing unused GTT space: [%lx, %lx]\n", + hole_start, hole_end); ggtt->vm.clear_range(&ggtt->vm, hole_start, hole_end - hole_start); } -- GitLab From 12bb3f7f1b03d5913b3f9d4236a488aa7774dfe9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 20 Jan 2021 16:00:24 +0100 Subject: [PATCH 0661/1084] futex: Ensure the correct return value from futex_lock_pi() In case that futex_lock_pi() was aborted by a signal or a timeout and the task returned without acquiring the rtmutex, but is the designated owner of the futex due to a concurrent futex_unlock_pi() fixup_owner() is invoked to establish consistent state. In that case it invokes fixup_pi_state_owner() which in turn tries to acquire the rtmutex again. If that succeeds then it does not propagate this success to fixup_owner() and futex_lock_pi() returns -EINTR or -ETIMEOUT despite having the futex locked. Return success from fixup_pi_state_owner() in all cases where the current task owns the rtmutex and therefore the futex and propagate it correctly through fixup_owner(). Fixup the other callsite which does not expect a positive return value. Fixes: c1e2f0eaf015 ("futex: Avoid violating the 10th rule of futex") Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org --- kernel/futex.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index c47d1015d7591..d5e61c2e865e4 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -2373,8 +2373,8 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, } if (__rt_mutex_futex_trylock(&pi_state->pi_mutex)) { - /* We got the lock after all, nothing to fix. */ - ret = 0; + /* We got the lock. pi_state is correct. Tell caller. */ + ret = 1; goto out_unlock; } @@ -2402,7 +2402,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, * We raced against a concurrent self; things are * already fixed up. Nothing to do. */ - ret = 0; + ret = 1; goto out_unlock; } newowner = argowner; @@ -2448,7 +2448,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, raw_spin_unlock(&newowner->pi_lock); raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - return 0; + return argowner == current; /* * In order to reschedule or handle a page fault, we need to drop the @@ -2490,7 +2490,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, * Check if someone else fixed it for us: */ if (pi_state->owner != oldowner) { - ret = 0; + ret = argowner == current; goto out_unlock; } @@ -2523,8 +2523,6 @@ static long futex_wait_restart(struct restart_block *restart); */ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) { - int ret = 0; - if (locked) { /* * Got the lock. We might not be the anticipated owner if we @@ -2535,8 +2533,8 @@ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) * stable state, anything else needs more attention. */ if (q->pi_state->owner != current) - ret = fixup_pi_state_owner(uaddr, q, current); - return ret ? ret : locked; + return fixup_pi_state_owner(uaddr, q, current); + return 1; } /* @@ -2547,10 +2545,8 @@ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) * Another speculative read; pi_state->owner == current is unstable * but needs our attention. */ - if (q->pi_state->owner == current) { - ret = fixup_pi_state_owner(uaddr, q, NULL); - return ret; - } + if (q->pi_state->owner == current) + return fixup_pi_state_owner(uaddr, q, NULL); /* * Paranoia check. If we did not take the lock, then we should not be @@ -2563,7 +2559,7 @@ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) q->pi_state->owner); } - return ret; + return 0; } /** @@ -3261,7 +3257,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (q.pi_state && (q.pi_state->owner != current)) { spin_lock(q.lock_ptr); ret = fixup_pi_state_owner(uaddr2, &q, current); - if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { + if (ret < 0 && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { pi_state = q.pi_state; get_pi_state(pi_state); } @@ -3271,6 +3267,11 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, */ put_pi_state(q.pi_state); spin_unlock(q.lock_ptr); + /* + * Adjust the return value. It's either -EFAULT or + * success (1) but the caller expects 0 for success. + */ + ret = ret < 0 ? ret : 0; } } else { struct rt_mutex *pi_mutex; -- GitLab From 04b79c55201f02ffd675e1231d731365e335c307 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 19 Jan 2021 16:06:10 +0100 Subject: [PATCH 0662/1084] futex: Replace pointless printk in fixup_owner() If that unexpected case of inconsistent arguments ever happens then the futex state is left completely inconsistent and the printk is not really helpful. Replace it with a warning and make the state consistent. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org --- kernel/futex.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index d5e61c2e865e4..5dc8f893d5235 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -2550,14 +2550,10 @@ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) /* * Paranoia check. If we did not take the lock, then we should not be - * the owner of the rt_mutex. + * the owner of the rt_mutex. Warn and establish consistent state. */ - if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) { - printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p " - "pi-state %p\n", ret, - q->pi_state->pi_mutex.owner, - q->pi_state->owner); - } + if (WARN_ON_ONCE(rt_mutex_owner(&q->pi_state->pi_mutex) == current)) + return fixup_pi_state_owner(uaddr, q, current); return 0; } -- GitLab From c5cade200ab9a2a3be9e7f32a752c8d86b502ec7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 19 Jan 2021 15:21:35 +0100 Subject: [PATCH 0663/1084] futex: Provide and use pi_state_update_owner() Updating pi_state::owner is done at several places with the same code. Provide a function for it and use that at the obvious places. This is also a preparation for a bug fix to avoid yet another copy of the same code or alternatively introducing a completely unpenetratable mess of gotos. Originally-by: Peter Zijlstra Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org --- kernel/futex.c | 66 +++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 5dc8f893d5235..7837f9e561fae 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -763,6 +763,29 @@ static struct futex_pi_state *alloc_pi_state(void) return pi_state; } +static void pi_state_update_owner(struct futex_pi_state *pi_state, + struct task_struct *new_owner) +{ + struct task_struct *old_owner = pi_state->owner; + + lockdep_assert_held(&pi_state->pi_mutex.wait_lock); + + if (old_owner) { + raw_spin_lock(&old_owner->pi_lock); + WARN_ON(list_empty(&pi_state->list)); + list_del_init(&pi_state->list); + raw_spin_unlock(&old_owner->pi_lock); + } + + if (new_owner) { + raw_spin_lock(&new_owner->pi_lock); + WARN_ON(!list_empty(&pi_state->list)); + list_add(&pi_state->list, &new_owner->pi_state_list); + pi_state->owner = new_owner; + raw_spin_unlock(&new_owner->pi_lock); + } +} + static void get_pi_state(struct futex_pi_state *pi_state) { WARN_ON_ONCE(!refcount_inc_not_zero(&pi_state->refcount)); @@ -1521,26 +1544,15 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_pi_state *pi_ ret = -EINVAL; } - if (ret) - goto out_unlock; - - /* - * This is a point of no return; once we modify the uval there is no - * going back and subsequent operations must not fail. - */ - - raw_spin_lock(&pi_state->owner->pi_lock); - WARN_ON(list_empty(&pi_state->list)); - list_del_init(&pi_state->list); - raw_spin_unlock(&pi_state->owner->pi_lock); - - raw_spin_lock(&new_owner->pi_lock); - WARN_ON(!list_empty(&pi_state->list)); - list_add(&pi_state->list, &new_owner->pi_state_list); - pi_state->owner = new_owner; - raw_spin_unlock(&new_owner->pi_lock); - - postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); + if (!ret) { + /* + * This is a point of no return; once we modified the uval + * there is no going back and subsequent operations must + * not fail. + */ + pi_state_update_owner(pi_state, new_owner); + postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); + } out_unlock: raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); @@ -2433,19 +2445,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, * We fixed up user space. Now we need to fix the pi_state * itself. */ - if (pi_state->owner != NULL) { - raw_spin_lock(&pi_state->owner->pi_lock); - WARN_ON(list_empty(&pi_state->list)); - list_del_init(&pi_state->list); - raw_spin_unlock(&pi_state->owner->pi_lock); - } - - pi_state->owner = newowner; - - raw_spin_lock(&newowner->pi_lock); - WARN_ON(!list_empty(&pi_state->list)); - list_add(&pi_state->list, &newowner->pi_state_list); - raw_spin_unlock(&newowner->pi_lock); + pi_state_update_owner(pi_state, newowner); raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); return argowner == current; -- GitLab From 2156ac1934166d6deb6cd0f6ffc4c1076ec63697 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 20 Jan 2021 11:32:07 +0100 Subject: [PATCH 0664/1084] rtmutex: Remove unused argument from rt_mutex_proxy_unlock() Nothing uses the argument. Remove it as preparation to use pi_state_update_owner(). Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org --- kernel/futex.c | 2 +- kernel/locking/rtmutex.c | 3 +-- kernel/locking/rtmutex_common.h | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 7837f9e561fae..cfca221c1bc59 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -818,7 +818,7 @@ static void put_pi_state(struct futex_pi_state *pi_state) list_del_init(&pi_state->list); raw_spin_unlock(&owner->pi_lock); } - rt_mutex_proxy_unlock(&pi_state->pi_mutex, owner); + rt_mutex_proxy_unlock(&pi_state->pi_mutex); raw_spin_unlock_irqrestore(&pi_state->pi_mutex.wait_lock, flags); } diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index cfdd5b93264d7..2f8cd616d3b29 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1716,8 +1716,7 @@ void rt_mutex_init_proxy_locked(struct rt_mutex *lock, * possible because it belongs to the pi_state which is about to be freed * and it is not longer visible to other tasks. */ -void rt_mutex_proxy_unlock(struct rt_mutex *lock, - struct task_struct *proxy_owner) +void rt_mutex_proxy_unlock(struct rt_mutex *lock) { debug_rt_mutex_proxy_unlock(lock); rt_mutex_set_owner(lock, NULL); diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h index d1d62f942be22..ca6fb489007b6 100644 --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h @@ -133,8 +133,7 @@ enum rtmutex_chainwalk { extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock); extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock, struct task_struct *proxy_owner); -extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, - struct task_struct *proxy_owner); +extern void rt_mutex_proxy_unlock(struct rt_mutex *lock); extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter); extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, struct rt_mutex_waiter *waiter, -- GitLab From 6ccc84f917d33312eb2846bd7b567639f585ad6d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 20 Jan 2021 11:35:19 +0100 Subject: [PATCH 0665/1084] futex: Use pi_state_update_owner() in put_pi_state() No point in open coding it. This way it gains the extra sanity checks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org --- kernel/futex.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index cfca221c1bc59..a0fe63c342487 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -808,16 +808,10 @@ static void put_pi_state(struct futex_pi_state *pi_state) * and has cleaned up the pi_state already */ if (pi_state->owner) { - struct task_struct *owner; unsigned long flags; raw_spin_lock_irqsave(&pi_state->pi_mutex.wait_lock, flags); - owner = pi_state->owner; - if (owner) { - raw_spin_lock(&owner->pi_lock); - list_del_init(&pi_state->list); - raw_spin_unlock(&owner->pi_lock); - } + pi_state_update_owner(pi_state, NULL); rt_mutex_proxy_unlock(&pi_state->pi_mutex); raw_spin_unlock_irqrestore(&pi_state->pi_mutex.wait_lock, flags); } -- GitLab From f2dac39d93987f7de1e20b3988c8685523247ae2 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 19 Jan 2021 16:26:38 +0100 Subject: [PATCH 0666/1084] futex: Simplify fixup_pi_state_owner() Too many gotos already and an upcoming fix would make it even more unreadable. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org --- kernel/futex.c | 53 +++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index a0fe63c342487..7a38ead96cae7 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -2329,18 +2329,13 @@ static void unqueue_me_pi(struct futex_q *q) spin_unlock(q->lock_ptr); } -static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, - struct task_struct *argowner) +static int __fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, + struct task_struct *argowner) { struct futex_pi_state *pi_state = q->pi_state; - u32 uval, curval, newval; struct task_struct *oldowner, *newowner; - u32 newtid; - int ret, err = 0; - - lockdep_assert_held(q->lock_ptr); - - raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); + u32 uval, curval, newval, newtid; + int err = 0; oldowner = pi_state->owner; @@ -2374,14 +2369,12 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, * We raced against a concurrent self; things are * already fixed up. Nothing to do. */ - ret = 0; - goto out_unlock; + return 0; } if (__rt_mutex_futex_trylock(&pi_state->pi_mutex)) { /* We got the lock. pi_state is correct. Tell caller. */ - ret = 1; - goto out_unlock; + return 1; } /* @@ -2408,8 +2401,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, * We raced against a concurrent self; things are * already fixed up. Nothing to do. */ - ret = 1; - goto out_unlock; + return 1; } newowner = argowner; } @@ -2440,7 +2432,6 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, * itself. */ pi_state_update_owner(pi_state, newowner); - raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); return argowner == current; @@ -2463,17 +2454,16 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, switch (err) { case -EFAULT: - ret = fault_in_user_writeable(uaddr); + err = fault_in_user_writeable(uaddr); break; case -EAGAIN: cond_resched(); - ret = 0; + err = 0; break; default: WARN_ON_ONCE(1); - ret = err; break; } @@ -2483,17 +2473,26 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, /* * Check if someone else fixed it for us: */ - if (pi_state->owner != oldowner) { - ret = argowner == current; - goto out_unlock; - } + if (pi_state->owner != oldowner) + return argowner == current; - if (ret) - goto out_unlock; + /* Retry if err was -EAGAIN or the fault in succeeded */ + if (!err) + goto retry; - goto retry; + return err; +} -out_unlock: +static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, + struct task_struct *argowner) +{ + struct futex_pi_state *pi_state = q->pi_state; + int ret; + + lockdep_assert_held(q->lock_ptr); + + raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); + ret = __fixup_pi_state_owner(uaddr, q, argowner); raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); return ret; } -- GitLab From 34b1a1ce1458f50ef27c54e28eb9b1947012907a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 18 Jan 2021 19:01:21 +0100 Subject: [PATCH 0667/1084] futex: Handle faults correctly for PI futexes fixup_pi_state_owner() tries to ensure that the state of the rtmutex, pi_state and the user space value related to the PI futex are consistent before returning to user space. In case that the user space value update faults and the fault cannot be resolved by faulting the page in via fault_in_user_writeable() the function returns with -EFAULT and leaves the rtmutex and pi_state owner state inconsistent. A subsequent futex_unlock_pi() operates on the inconsistent pi_state and releases the rtmutex despite not owning it which can corrupt the RB tree of the rtmutex and cause a subsequent kernel stack use after free. It was suggested to loop forever in fixup_pi_state_owner() if the fault cannot be resolved, but that results in runaway tasks which is especially undesired when the problem happens due to a programming error and not due to malice. As the user space value cannot be fixed up, the proper solution is to make the rtmutex and the pi_state consistent so both have the same owner. This leaves the user space value out of sync. Any subsequent operation on the futex will fail because the 10th rule of PI futexes (pi_state owner and user space value are consistent) has been violated. As a consequence this removes the inept attempts of 'fixing' the situation in case that the current task owns the rtmutex when returning with an unresolvable fault by unlocking the rtmutex which left pi_state::owner and rtmutex::owner out of sync in a different and only slightly less dangerous way. Fixes: 1b7558e457ed ("futexes: fix fault handling in futex_lock_pi") Reported-by: gzobqq@gmail.com Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org --- kernel/futex.c | 57 ++++++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 7a38ead96cae7..45a13eb8894e5 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -958,7 +958,8 @@ static inline void exit_pi_state_list(struct task_struct *curr) { } * FUTEX_OWNER_DIED bit. See [4] * * [10] There is no transient state which leaves owner and user space - * TID out of sync. + * TID out of sync. Except one error case where the kernel is denied + * write access to the user address, see fixup_pi_state_owner(). * * * Serialization and lifetime rules: @@ -2480,6 +2481,24 @@ static int __fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, if (!err) goto retry; + /* + * fault_in_user_writeable() failed so user state is immutable. At + * best we can make the kernel state consistent but user state will + * be most likely hosed and any subsequent unlock operation will be + * rejected due to PI futex rule [10]. + * + * Ensure that the rtmutex owner is also the pi_state owner despite + * the user space value claiming something different. There is no + * point in unlocking the rtmutex if current is the owner as it + * would need to wait until the next waiter has taken the rtmutex + * to guarantee consistent state. Keep it simple. Userspace asked + * for this wreckaged state. + * + * The rtmutex has an owner - either current or some other + * task. See the EAGAIN loop above. + */ + pi_state_update_owner(pi_state, rt_mutex_owner(&pi_state->pi_mutex)); + return err; } @@ -2756,7 +2775,6 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, ktime_t *time, int trylock) { struct hrtimer_sleeper timeout, *to; - struct futex_pi_state *pi_state = NULL; struct task_struct *exiting = NULL; struct rt_mutex_waiter rt_waiter; struct futex_hash_bucket *hb; @@ -2892,23 +2910,8 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, if (res) ret = (res < 0) ? res : 0; - /* - * If fixup_owner() faulted and was unable to handle the fault, unlock - * it and return the fault to userspace. - */ - if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current)) { - pi_state = q.pi_state; - get_pi_state(pi_state); - } - /* Unqueue and drop the lock */ unqueue_me_pi(&q); - - if (pi_state) { - rt_mutex_futex_unlock(&pi_state->pi_mutex); - put_pi_state(pi_state); - } - goto out; out_unlock_put_key: @@ -3168,7 +3171,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, u32 __user *uaddr2) { struct hrtimer_sleeper timeout, *to; - struct futex_pi_state *pi_state = NULL; struct rt_mutex_waiter rt_waiter; struct futex_hash_bucket *hb; union futex_key key2 = FUTEX_KEY_INIT; @@ -3246,10 +3248,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (q.pi_state && (q.pi_state->owner != current)) { spin_lock(q.lock_ptr); ret = fixup_pi_state_owner(uaddr2, &q, current); - if (ret < 0 && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { - pi_state = q.pi_state; - get_pi_state(pi_state); - } /* * Drop the reference to the pi state which * the requeue_pi() code acquired for us. @@ -3291,25 +3289,10 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (res) ret = (res < 0) ? res : 0; - /* - * If fixup_pi_state_owner() faulted and was unable to handle - * the fault, unlock the rt_mutex and return the fault to - * userspace. - */ - if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { - pi_state = q.pi_state; - get_pi_state(pi_state); - } - /* Unqueue and drop the lock. */ unqueue_me_pi(&q); } - if (pi_state) { - rt_mutex_futex_unlock(&pi_state->pi_mutex); - put_pi_state(pi_state); - } - if (ret == -EINTR) { /* * We've already been requeued, but cannot restart by calling -- GitLab From d8c6edfa3f4ee0d45d7ce5ef18d1245b78774b9d Mon Sep 17 00:00:00 2001 From: Jeremy Figgins Date: Sat, 23 Jan 2021 18:21:36 -0600 Subject: [PATCH 0668/1084] USB: usblp: don't call usb_set_interface if there's a single alt Some devices, such as the Winbond Electronics Corp. Virtual Com Port (Vendor=0416, ProdId=5011), lockup when usb_set_interface() or usb_clear_halt() are called. This device has only a single altsetting, so it should not be necessary to call usb_set_interface(). Acked-by: Pete Zaitcev Signed-off-by: Jeremy Figgins Link: https://lore.kernel.org/r/YAy9kJhM/rG8EQXC@watson Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usblp.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 134dc2005ce97..c9f6e97582885 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -1329,14 +1329,17 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol) if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL) return -EINVAL; - alts = usblp->protocol[protocol].alt_setting; - if (alts < 0) - return -EINVAL; - r = usb_set_interface(usblp->dev, usblp->ifnum, alts); - if (r < 0) { - printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n", - alts, usblp->ifnum); - return r; + /* Don't unnecessarily set the interface if there's a single alt. */ + if (usblp->intf->num_altsetting > 1) { + alts = usblp->protocol[protocol].alt_setting; + if (alts < 0) + return -EINVAL; + r = usb_set_interface(usblp->dev, usblp->ifnum, alts); + if (r < 0) { + printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n", + alts, usblp->ifnum); + return r; + } } usblp->bidir = (usblp->protocol[protocol].epread != NULL); -- GitLab From a55a9a4c5c6253f6e4dea268af728664ac997790 Mon Sep 17 00:00:00 2001 From: kernel test robot Date: Thu, 21 Jan 2021 19:12:54 +0100 Subject: [PATCH 0669/1084] usb: gadget: aspeed: add missing of_node_put Breaking out of for_each_child_of_node requires a put on the child value. Generated by: scripts/coccinelle/iterators/for_each_child.cocci Fixes: 82c2d81361ec ("coccinelle: iterators: Add for_each_child.cocci script") CC: Sumera Priyadarsini Reported-by: kernel test robot Signed-off-by: kernel test robot Signed-off-by: Julia Lawall Cc: stable Link: https://lore.kernel.org/r/alpine.DEB.2.22.394.2101211907060.14700@hadrien Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/aspeed-vhub/hub.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c index 6497185ec4e7a..bfd8e77788e29 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c @@ -999,8 +999,10 @@ static int ast_vhub_of_parse_str_desc(struct ast_vhub *vhub, str_array[offset].s = NULL; ret = ast_vhub_str_alloc_add(vhub, &lang_str); - if (ret) + if (ret) { + of_node_put(child); break; + } } return ret; -- GitLab From 1d69f9d901ef14d81c3b004e3282b8cc7b456280 Mon Sep 17 00:00:00 2001 From: Ikjoon Jang Date: Wed, 13 Jan 2021 18:05:11 +0800 Subject: [PATCH 0670/1084] usb: xhci-mtk: fix unreleased bandwidth data xhci-mtk needs XHCI_MTK_HOST quirk functions in add_endpoint() and drop_endpoint() to handle its own sw bandwidth management. It stores bandwidth data into an internal table every time add_endpoint() is called, and drops those in drop_endpoint(). But when bandwidth allocation fails at one endpoint, all earlier allocation from the same interface could still remain at the table. This patch moves bandwidth management codes to check_bandwidth() and reset_bandwidth() path. To do so, this patch also adds those functions to xhci_driver_overrides and lets mtk-xhci to release all failed endpoints in reset_bandwidth() path. Fixes: 08e469de87a2 ("usb: xhci-mtk: supports bandwidth scheduling with multi-TT") Signed-off-by: Ikjoon Jang Link: https://lore.kernel.org/r/20210113180444.v6.1.Id0d31b5f3ddf5e734d2ab11161ac5821921b1e1e@changeid Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mtk-sch.c | 123 ++++++++++++++++++++++---------- drivers/usb/host/xhci-mtk.c | 2 + drivers/usb/host/xhci-mtk.h | 13 ++++ drivers/usb/host/xhci.c | 8 ++- drivers/usb/host/xhci.h | 4 ++ 5 files changed, 111 insertions(+), 39 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 45c54d56ecbd5..a313e75ff1c6b 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -200,6 +200,7 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, sch_ep->sch_tt = tt; sch_ep->ep = ep; + INIT_LIST_HEAD(&sch_ep->tt_endpoint); return sch_ep; } @@ -583,6 +584,8 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) mtk->sch_array = sch_array; + INIT_LIST_HEAD(&mtk->bw_ep_list_new); + return 0; } EXPORT_SYMBOL_GPL(xhci_mtk_sch_init); @@ -601,19 +604,14 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, struct xhci_ep_ctx *ep_ctx; struct xhci_slot_ctx *slot_ctx; struct xhci_virt_device *virt_dev; - struct mu3h_sch_bw_info *sch_bw; struct mu3h_sch_ep_info *sch_ep; - struct mu3h_sch_bw_info *sch_array; unsigned int ep_index; - int bw_index; - int ret = 0; xhci = hcd_to_xhci(hcd); virt_dev = xhci->devs[udev->slot_id]; ep_index = xhci_get_endpoint_index(&ep->desc); slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); - sch_array = mtk->sch_array; xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n", __func__, usb_endpoint_type(&ep->desc), udev->speed, @@ -632,39 +630,34 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, return 0; } - bw_index = get_bw_index(xhci, udev, ep); - sch_bw = &sch_array[bw_index]; - sch_ep = create_sch_ep(udev, ep, ep_ctx); if (IS_ERR_OR_NULL(sch_ep)) return -ENOMEM; setup_sch_info(udev, ep_ctx, sch_ep); - ret = check_sch_bw(udev, sch_bw, sch_ep); - if (ret) { - xhci_err(xhci, "Not enough bandwidth!\n"); - if (is_fs_or_ls(udev->speed)) - drop_tt(udev); - - kfree(sch_ep); - return -ENOSPC; - } + list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_list_new); - list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); + return 0; +} +EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); - ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) - | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode)); - ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset) - | EP_BREPEAT(sch_ep->repeat)); +static void xhci_mtk_drop_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, + struct mu3h_sch_ep_info *sch_ep) +{ + struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); + int bw_index = get_bw_index(xhci, udev, sch_ep->ep); + struct mu3h_sch_bw_info *sch_bw = &mtk->sch_array[bw_index]; - xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n", - sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode, - sch_ep->offset, sch_ep->repeat); + update_bus_bw(sch_bw, sch_ep, 0); + list_del(&sch_ep->endpoint); - return 0; + if (sch_ep->sch_tt) { + list_del(&sch_ep->tt_endpoint); + drop_tt(udev); + } + kfree(sch_ep); } -EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep) @@ -675,7 +668,7 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, struct xhci_virt_device *virt_dev; struct mu3h_sch_bw_info *sch_array; struct mu3h_sch_bw_info *sch_bw; - struct mu3h_sch_ep_info *sch_ep; + struct mu3h_sch_ep_info *sch_ep, *tmp; int bw_index; xhci = hcd_to_xhci(hcd); @@ -694,17 +687,73 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, bw_index = get_bw_index(xhci, udev, ep); sch_bw = &sch_array[bw_index]; - list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) { + list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { if (sch_ep->ep == ep) { - update_bus_bw(sch_bw, sch_ep, 0); - list_del(&sch_ep->endpoint); - if (is_fs_or_ls(udev->speed)) { - list_del(&sch_ep->tt_endpoint); - drop_tt(udev); - } - kfree(sch_ep); - break; + xhci_mtk_drop_ep(mtk, udev, sch_ep); } } } EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk); + +int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; + struct mu3h_sch_bw_info *sch_bw; + struct mu3h_sch_ep_info *sch_ep, *tmp; + int bw_index, ret; + + dev_dbg(&udev->dev, "%s\n", __func__); + + list_for_each_entry(sch_ep, &mtk->bw_ep_list_new, endpoint) { + bw_index = get_bw_index(xhci, udev, sch_ep->ep); + sch_bw = &mtk->sch_array[bw_index]; + + ret = check_sch_bw(udev, sch_bw, sch_ep); + if (ret) { + xhci_err(xhci, "Not enough bandwidth!\n"); + return -ENOSPC; + } + } + + list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { + struct xhci_ep_ctx *ep_ctx; + struct usb_host_endpoint *ep = sch_ep->ep; + unsigned int ep_index = xhci_get_endpoint_index(&ep->desc); + + bw_index = get_bw_index(xhci, udev, ep); + sch_bw = &mtk->sch_array[bw_index]; + + list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); + + ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); + ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) + | EP_BCSCOUNT(sch_ep->cs_count) + | EP_BBM(sch_ep->burst_mode)); + ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset) + | EP_BREPEAT(sch_ep->repeat)); + + xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n", + sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode, + sch_ep->offset, sch_ep->repeat); + } + + return xhci_check_bandwidth(hcd, udev); +} +EXPORT_SYMBOL_GPL(xhci_mtk_check_bandwidth); + +void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); + struct mu3h_sch_ep_info *sch_ep, *tmp; + + dev_dbg(&udev->dev, "%s\n", __func__); + + list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { + xhci_mtk_drop_ep(mtk, udev, sch_ep); + } + + xhci_reset_bandwidth(hcd, udev); +} +EXPORT_SYMBOL_GPL(xhci_mtk_reset_bandwidth); diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 8f321f39ab960..fe010cc61f19b 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -347,6 +347,8 @@ static void usb_wakeup_set(struct xhci_hcd_mtk *mtk, bool enable) static int xhci_mtk_setup(struct usb_hcd *hcd); static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = { .reset = xhci_mtk_setup, + .check_bandwidth = xhci_mtk_check_bandwidth, + .reset_bandwidth = xhci_mtk_reset_bandwidth, }; static struct hc_driver __read_mostly xhci_mtk_hc_driver; diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index a93cfe8179049..577f431c5c93c 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -130,6 +130,7 @@ struct mu3c_ippc_regs { struct xhci_hcd_mtk { struct device *dev; struct usb_hcd *hcd; + struct list_head bw_ep_list_new; struct mu3h_sch_bw_info *sch_array; struct mu3c_ippc_regs __iomem *ippc_regs; bool has_ippc; @@ -166,6 +167,8 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); +int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); +void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); #else static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, @@ -179,6 +182,16 @@ static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, { } +static inline int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, + struct usb_device *udev) +{ + return 0; +} + +static inline void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, + struct usb_device *udev) +{ +} #endif #endif /* _XHCI_MTK_H_ */ diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e86940571b4cf..345a221028c6f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2985,7 +2985,7 @@ static void xhci_check_bw_drop_ep_streams(struct xhci_hcd *xhci, * else should be touching the xhci->devs[slot_id] structure, so we * don't need to take the xhci->lock for manipulating that. */ -static int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) +int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) { int i; int ret = 0; @@ -3083,7 +3083,7 @@ static int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) return ret; } -static void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) +void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) { struct xhci_hcd *xhci; struct xhci_virt_device *virt_dev; @@ -5510,6 +5510,10 @@ void xhci_init_driver(struct hc_driver *drv, drv->reset = over->reset; if (over->start) drv->start = over->start; + if (over->check_bandwidth) + drv->check_bandwidth = over->check_bandwidth; + if (over->reset_bandwidth) + drv->reset_bandwidth = over->reset_bandwidth; } } EXPORT_SYMBOL_GPL(xhci_init_driver); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 25e57bc9c3cc6..07ff95016f119 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1920,6 +1920,8 @@ struct xhci_driver_overrides { size_t extra_priv_size; int (*reset)(struct usb_hcd *hcd); int (*start)(struct usb_hcd *hcd); + int (*check_bandwidth)(struct usb_hcd *, struct usb_device *); + void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); }; #define XHCI_CFC_DELAY 10 @@ -2074,6 +2076,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); void xhci_shutdown(struct usb_hcd *hcd); void xhci_init_driver(struct hc_driver *drv, const struct xhci_driver_overrides *over); +int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); +void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); int xhci_ext_cap_init(struct xhci_hcd *xhci); -- GitLab From a1bb3cd58913338e1b627ea6b8c03c2ae82d293f Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Tue, 26 Jan 2021 15:28:26 +0000 Subject: [PATCH 0671/1084] io_uring: fix __io_uring_files_cancel() with TASK_UNINTERRUPTIBLE If the tctx inflight number haven't changed because of cancellation, __io_uring_task_cancel() will continue leaving the task in TASK_UNINTERRUPTIBLE state, that's not expected by __io_uring_files_cancel(). Ensure we always call finish_wait() before retrying. Cc: stable@vger.kernel.org # 5.9+ Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 2166c469789d5..09aada153a71b 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -9124,16 +9124,15 @@ void __io_uring_task_cancel(void) prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE); /* - * If we've seen completions, retry. This avoids a race where - * a completion comes in before we did prepare_to_wait(). + * If we've seen completions, retry without waiting. This + * avoids a race where a completion comes in before we did + * prepare_to_wait(). */ - if (inflight != tctx_inflight(tctx)) - continue; - schedule(); + if (inflight == tctx_inflight(tctx)) + schedule(); finish_wait(&tctx->wait, &wait); } while (1); - finish_wait(&tctx->wait, &wait); atomic_dec(&tctx->in_idle); io_uring_remove_task_files(tctx); -- GitLab From ca70f00bed6cb255b7a9b91aa18a2717c9217f70 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Tue, 26 Jan 2021 15:28:27 +0000 Subject: [PATCH 0672/1084] io_uring: fix cancellation taking mutex while TASK_UNINTERRUPTIBLE do not call blocking ops when !TASK_RUNNING; state=2 set at [<00000000ced9dbfc>] prepare_to_wait+0x1f4/0x3b0 kernel/sched/wait.c:262 WARNING: CPU: 1 PID: 19888 at kernel/sched/core.c:7853 __might_sleep+0xed/0x100 kernel/sched/core.c:7848 RIP: 0010:__might_sleep+0xed/0x100 kernel/sched/core.c:7848 Call Trace: __mutex_lock_common+0xc4/0x2ef0 kernel/locking/mutex.c:935 __mutex_lock kernel/locking/mutex.c:1103 [inline] mutex_lock_nested+0x1a/0x20 kernel/locking/mutex.c:1118 io_wq_submit_work+0x39a/0x720 fs/io_uring.c:6411 io_run_cancel fs/io-wq.c:856 [inline] io_wqe_cancel_pending_work fs/io-wq.c:990 [inline] io_wq_cancel_cb+0x614/0xcb0 fs/io-wq.c:1027 io_uring_cancel_files fs/io_uring.c:8874 [inline] io_uring_cancel_task_requests fs/io_uring.c:8952 [inline] __io_uring_files_cancel+0x115d/0x19e0 fs/io_uring.c:9038 io_uring_files_cancel include/linux/io_uring.h:51 [inline] do_exit+0x2e6/0x2490 kernel/exit.c:780 do_group_exit+0x168/0x2d0 kernel/exit.c:922 get_signal+0x16b5/0x2030 kernel/signal.c:2770 arch_do_signal_or_restart+0x8e/0x6a0 arch/x86/kernel/signal.c:811 handle_signal_work kernel/entry/common.c:147 [inline] exit_to_user_mode_loop kernel/entry/common.c:171 [inline] exit_to_user_mode_prepare+0xac/0x1e0 kernel/entry/common.c:201 __syscall_exit_to_user_mode_work kernel/entry/common.c:291 [inline] syscall_exit_to_user_mode+0x48/0x190 kernel/entry/common.c:302 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Rewrite io_uring_cancel_files() to mimic __io_uring_task_cancel()'s counting scheme, so it does all the heavy work before setting TASK_UNINTERRUPTIBLE. Cc: stable@vger.kernel.org # 5.9+ Reported-by: syzbot+f655445043a26a7cfab8@syzkaller.appspotmail.com Signed-off-by: Pavel Begunkov [axboe: fix inverted task check] Signed-off-by: Jens Axboe --- fs/io_uring.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 09aada153a71b..bb0270eeb8cb6 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -8873,30 +8873,31 @@ static void io_cancel_defer_files(struct io_ring_ctx *ctx, } } +static int io_uring_count_inflight(struct io_ring_ctx *ctx, + struct task_struct *task, + struct files_struct *files) +{ + struct io_kiocb *req; + int cnt = 0; + + spin_lock_irq(&ctx->inflight_lock); + list_for_each_entry(req, &ctx->inflight_list, inflight_entry) + cnt += io_match_task(req, task, files); + spin_unlock_irq(&ctx->inflight_lock); + return cnt; +} + static void io_uring_cancel_files(struct io_ring_ctx *ctx, struct task_struct *task, struct files_struct *files) { while (!list_empty_careful(&ctx->inflight_list)) { struct io_task_cancel cancel = { .task = task, .files = files }; - struct io_kiocb *req; DEFINE_WAIT(wait); - bool found = false; - - spin_lock_irq(&ctx->inflight_lock); - list_for_each_entry(req, &ctx->inflight_list, inflight_entry) { - if (!io_match_task(req, task, files)) - continue; - found = true; - break; - } - if (found) - prepare_to_wait(&task->io_uring->wait, &wait, - TASK_UNINTERRUPTIBLE); - spin_unlock_irq(&ctx->inflight_lock); + int inflight; - /* We need to keep going until we don't find a matching req */ - if (!found) + inflight = io_uring_count_inflight(ctx, task, files); + if (!inflight) break; io_wq_cancel_cb(ctx->io_wq, io_cancel_task_cb, &cancel, true); @@ -8905,7 +8906,11 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx, io_cqring_overflow_flush(ctx, true, task, files); /* cancellations _may_ trigger task work */ io_run_task_work(); - schedule(); + + prepare_to_wait(&task->io_uring->wait, &wait, + TASK_UNINTERRUPTIBLE); + if (inflight == io_uring_count_inflight(ctx, task, files)) + schedule(); finish_wait(&task->io_uring->wait, &wait); } } -- GitLab From 19f6fe976a61f9afc289b062b7ef67f99b72e7b9 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 26 Jan 2021 09:09:51 +0100 Subject: [PATCH 0673/1084] Revert "arm64: dts: amlogic: add missing ethernet reset ID" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It has been reported on IRC and in KernelCI boot tests, this change breaks internal PHY support on the Amlogic G12A/SM1 Based boards. We suspect the added signal to reset more than the Ethernet MAC but also the MDIO/(RG)MII mux used to redirect the MAC signals to the internal PHY. This reverts commit f3362f0c18174a1f334a419ab7d567a36bd1b3f3 while we find and acceptable solution to cleanly reset the Ethernet MAC. Reported-by: Corentin Labbe Acked-by: Jérôme Brunet Signed-off-by: Neil Armstrong Signed-off-by: Kevin Hilman Link: https://lore.kernel.org/r/20210126080951.2383740-1-narmstrong@baylibre.com --- arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 2 -- arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 2 -- arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 3 --- 3 files changed, 7 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi index ba1c6dfdc4b6b..d945c84ab697a 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -280,8 +280,6 @@ "timing-adjustment"; rx-fifo-depth = <4096>; tx-fifo-depth = <2048>; - resets = <&reset RESET_ETHERNET>; - reset-names = "stmmaceth"; power-domains = <&pwrc PWRC_AXG_ETHERNET_MEM_ID>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi index 221fcca3b0b93..b858c5e43cc88 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi @@ -224,8 +224,6 @@ "timing-adjustment"; rx-fifo-depth = <4096>; tx-fifo-depth = <2048>; - resets = <&reset RESET_ETHERNET>; - reset-names = "stmmaceth"; status = "disabled"; mdio0: mdio { diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 726b91d3a905a..0edd137151f89 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -13,7 +13,6 @@ #include #include #include -#include #include / { @@ -576,8 +575,6 @@ interrupt-names = "macirq"; rx-fifo-depth = <4096>; tx-fifo-depth = <2048>; - resets = <&reset RESET_ETHERNET>; - reset-names = "stmmaceth"; power-domains = <&pwrc PWRC_GXBB_ETHERNET_MEM_ID>; status = "disabled"; }; -- GitLab From 78031381ae9c88f4f914d66154f4745122149c58 Mon Sep 17 00:00:00 2001 From: Mikko Ylinen Date: Mon, 25 Jan 2021 08:39:36 +0200 Subject: [PATCH 0674/1084] bpf: Drop disabled LSM hooks from the sleepable set Some networking and keys LSM hooks are conditionally enabled and when building the new sleepable BPF LSM hooks with those LSM hooks disabled, the following build error occurs: BTFIDS vmlinux FAILED unresolved symbol bpf_lsm_socket_socketpair To fix the error, conditionally add the relevant networking/keys LSM hooks to the sleepable set. Fixes: 423f16108c9d8 ("bpf: Augment the set of sleepable LSM hooks") Signed-off-by: Mikko Ylinen Signed-off-by: Daniel Borkmann Acked-by: KP Singh Link: https://lore.kernel.org/bpf/20210125063936.89365-1-mikko.ylinen@linux.intel.com --- kernel/bpf/bpf_lsm.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c index 70e5e0b6d69d0..1622a44d1617e 100644 --- a/kernel/bpf/bpf_lsm.c +++ b/kernel/bpf/bpf_lsm.c @@ -149,7 +149,11 @@ BTF_ID(func, bpf_lsm_file_ioctl) BTF_ID(func, bpf_lsm_file_lock) BTF_ID(func, bpf_lsm_file_open) BTF_ID(func, bpf_lsm_file_receive) + +#ifdef CONFIG_SECURITY_NETWORK BTF_ID(func, bpf_lsm_inet_conn_established) +#endif /* CONFIG_SECURITY_NETWORK */ + BTF_ID(func, bpf_lsm_inode_create) BTF_ID(func, bpf_lsm_inode_free_security) BTF_ID(func, bpf_lsm_inode_getattr) @@ -166,7 +170,11 @@ BTF_ID(func, bpf_lsm_inode_symlink) BTF_ID(func, bpf_lsm_inode_unlink) BTF_ID(func, bpf_lsm_kernel_module_request) BTF_ID(func, bpf_lsm_kernfs_init_security) + +#ifdef CONFIG_KEYS BTF_ID(func, bpf_lsm_key_free) +#endif /* CONFIG_KEYS */ + BTF_ID(func, bpf_lsm_mmap_file) BTF_ID(func, bpf_lsm_netlink_send) BTF_ID(func, bpf_lsm_path_notify) @@ -181,6 +189,8 @@ BTF_ID(func, bpf_lsm_sb_show_options) BTF_ID(func, bpf_lsm_sb_statfs) BTF_ID(func, bpf_lsm_sb_umount) BTF_ID(func, bpf_lsm_settime) + +#ifdef CONFIG_SECURITY_NETWORK BTF_ID(func, bpf_lsm_socket_accept) BTF_ID(func, bpf_lsm_socket_bind) BTF_ID(func, bpf_lsm_socket_connect) @@ -195,6 +205,8 @@ BTF_ID(func, bpf_lsm_socket_recvmsg) BTF_ID(func, bpf_lsm_socket_sendmsg) BTF_ID(func, bpf_lsm_socket_shutdown) BTF_ID(func, bpf_lsm_socket_socketpair) +#endif /* CONFIG_SECURITY_NETWORK */ + BTF_ID(func, bpf_lsm_syslog) BTF_ID(func, bpf_lsm_task_alloc) BTF_ID(func, bpf_lsm_task_getsecid) -- GitLab From 519ea6f1c82fcdc9842908155ae379de47818778 Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Tue, 26 Jan 2021 13:40:56 +0000 Subject: [PATCH 0675/1084] arm64: Fix kernel address detection of __is_lm_address() Currently, the __is_lm_address() check just masks out the top 12 bits of the address, but if they are 0, it still yields a true result. This has as a side effect that virt_addr_valid() returns true even for invalid virtual addresses (e.g. 0x0). Fix the detection checking that it's actually a kernel address starting at PAGE_OFFSET. Fixes: 68dd8ef32162 ("arm64: memory: Fix virt_addr_valid() using __is_lm_address()") Cc: # 5.4.x Cc: Will Deacon Suggested-by: Catalin Marinas Reviewed-by: Catalin Marinas Acked-by: Mark Rutland Signed-off-by: Vincenzo Frascino Link: https://lore.kernel.org/r/20210126134056.45747-1-vincenzo.frascino@arm.com Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/memory.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 18fce223b67b2..99d7e1494aaa6 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -247,9 +247,11 @@ static inline const void *__tag_set(const void *addr, u8 tag) /* - * The linear kernel range starts at the bottom of the virtual address space. + * Check whether an arbitrary address is within the linear map, which + * lives in the [PAGE_OFFSET, PAGE_END) interval at the bottom of the + * kernel's TTBR1 address range. */ -#define __is_lm_address(addr) (((u64)(addr) & ~PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET)) +#define __is_lm_address(addr) (((u64)(addr) ^ PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET)) #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET) #define __kimg_to_phys(addr) ((addr) - kimage_voffset) -- GitLab From a53e3c189cc6460b60e152af3fc24edf8e0ea9d2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 Jan 2021 16:37:00 +0100 Subject: [PATCH 0676/1084] media: v4l2-subdev.h: BIT() is not available in userspace The BIT macro is not available in userspace, so replace BIT(0) by 0x00000001. Signed-off-by: Hans Verkuil Fixes: 6446ec6cbf46 ("media: v4l2-subdev: add VIDIOC_SUBDEV_QUERYCAP ioctl") Cc: Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/v4l2-subdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h index 00850b98078a2..a38454d9e0f54 100644 --- a/include/uapi/linux/v4l2-subdev.h +++ b/include/uapi/linux/v4l2-subdev.h @@ -176,7 +176,7 @@ struct v4l2_subdev_capability { }; /* The v4l2 sub-device video device node is registered in read-only mode. */ -#define V4L2_SUBDEV_CAP_RO_SUBDEV BIT(0) +#define V4L2_SUBDEV_CAP_RO_SUBDEV 0x00000001 /* Backwards compatibility define --- to be removed */ #define v4l2_subdev_edid v4l2_edid -- GitLab From 73bc0b0c2a96b31199da0ce6c3d04be81ef73bb9 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Wed, 23 Dec 2020 12:06:59 +0100 Subject: [PATCH 0677/1084] media: cedrus: Fix H264 decoding During H264 API overhaul subtle bug was introduced Cedrus driver. Progressive references have both, top and bottom reference flags set. Cedrus reference list expects only bottom reference flag and only when interlaced frames are decoded. However, due to a bug in Cedrus check, exclusivity is not tested and that flag is set also for progressive references. That causes "jumpy" background with many videos. Fix that by checking that only bottom reference flag is set in control and nothing else. Tested-by: Andre Heider Fixes: cfc8c3ed533e ("media: cedrus: h264: Properly configure reference field") Signed-off-by: Jernej Skrabec Signed-off-by: Hans Verkuil Cc: Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c index 781c84a9b1b79..de7442d4834dc 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c @@ -203,7 +203,7 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx, position = cedrus_buf->codec.h264.position; sram_array[i] |= position << 1; - if (ref_list[i].fields & V4L2_H264_BOTTOM_FIELD_REF) + if (ref_list[i].fields == V4L2_H264_BOTTOM_FIELD_REF) sram_array[i] |= BIT(0); } -- GitLab From eaf18a4165141f04dd26f0c48a7e53438e5a3ea2 Mon Sep 17 00:00:00 2001 From: Yannick Fertre Date: Fri, 15 Jan 2021 15:31:44 +0100 Subject: [PATCH 0678/1084] media: cec: add stm32 driver Missing stm32 directory to Makefile. Signed-off-by: Yannick Fertre Signed-off-by: Hans Verkuil Fixes: 4be5e8648b0c ("media: move CEC platform drivers to a separate directory") Cc: Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/platform/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/cec/platform/Makefile b/drivers/media/cec/platform/Makefile index 3a947159b25ac..ea6f8ee8161c9 100644 --- a/drivers/media/cec/platform/Makefile +++ b/drivers/media/cec/platform/Makefile @@ -10,5 +10,6 @@ obj-$(CONFIG_CEC_MESON_AO) += meson/ obj-$(CONFIG_CEC_SAMSUNG_S5P) += s5p/ obj-$(CONFIG_CEC_SECO) += seco/ obj-$(CONFIG_CEC_STI) += sti/ +obj-$(CONFIG_CEC_STM32) += stm32/ obj-$(CONFIG_CEC_TEGRA) += tegra/ -- GitLab From e081863ab48d9b2eee9e899cbd05752a2a30308d Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Thu, 14 Jan 2021 14:03:16 +0100 Subject: [PATCH 0679/1084] media: hantro: Fix reset_raw_fmt initialization raw_fmt->height in never initialized. But width in initialized twice. Fixes: 88d06362d1d05 ("media: hantro: Refactor for V4L2 API spec compliancy") Signed-off-by: Ricardo Ribalda Signed-off-by: Hans Verkuil Cc: Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c index b668a82d40ad4..f5fbdbc4ffdb1 100644 --- a/drivers/staging/media/hantro/hantro_v4l2.c +++ b/drivers/staging/media/hantro/hantro_v4l2.c @@ -367,7 +367,7 @@ hantro_reset_raw_fmt(struct hantro_ctx *ctx) hantro_reset_fmt(raw_fmt, raw_vpu_fmt); raw_fmt->width = encoded_fmt->width; - raw_fmt->width = encoded_fmt->width; + raw_fmt->height = encoded_fmt->height; if (ctx->is_encoder) hantro_set_fmt_out(ctx, raw_fmt); else -- GitLab From cf81c3abe1b84c4b82fbe771f72e6d181a3d1b7c Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Thu, 14 Jan 2021 11:02:16 +0100 Subject: [PATCH 0680/1084] kconfig: mconf: fix HOSTCC call Commit c0f975af1745 ("kconfig: Support building mconf with vendor sysroot ncurses") introduces a bug when HOSTCC contains parameters: the whole command line is treated as the program name (with spaces in it). Therefore, we have to remove the quotes. Fixes: c0f975af1745 ("kconfig: Support building mconf with vendor sysroot ncurses") Signed-off-by: Enrico Weigelt, metux IT consult Signed-off-by: Masahiro Yamada --- scripts/kconfig/mconf-cfg.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kconfig/mconf-cfg.sh b/scripts/kconfig/mconf-cfg.sh index fcd4acd4e9cbc..b520e407a8ebb 100755 --- a/scripts/kconfig/mconf-cfg.sh +++ b/scripts/kconfig/mconf-cfg.sh @@ -35,7 +35,7 @@ fi # As a final fallback before giving up, check if $HOSTCC knows of a default # ncurses installation (e.g. from a vendor-specific sysroot). -if echo '#include ' | "${HOSTCC}" -E - >/dev/null 2>&1; then +if echo '#include ' | ${HOSTCC} -E - >/dev/null 2>&1; then echo cflags=\"-D_GNU_SOURCE\" echo libs=\"-lncurses\" exit 0 -- GitLab From 377bf660d07a47269510435d11f3b65d53edca20 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 26 Jan 2021 10:39:46 -0800 Subject: [PATCH 0681/1084] Revert "mm: fix initialization of struct page for holes in memory layout" This reverts commit d3921cb8be29ce5668c64e23ffdaeec5f8c69399. Chris Wilson reports that it causes boot problems: "We have half a dozen or so different machines in CI that are silently failing to boot, that we believe is bisected to this patch" and the CI team confirmed that a revert fixed the issues. The cause is unknown for now, so let's revert it. Link: https://lore.kernel.org/lkml/161160687463.28991.354987542182281928@build.alporthouse.com/ Reported-and-tested-by: Chris Wilson Acked-by: Mike Rapoport Cc: Andrea Arcangeli Cc: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 84 ++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 50 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 783913e41f65d..519a60d5b6f7d 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -7080,26 +7080,23 @@ void __init free_area_init_memoryless_node(int nid) * Initialize all valid struct pages in the range [spfn, epfn) and mark them * PageReserved(). Return the number of struct pages that were initialized. */ -static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn, - int zone, int nid) +static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn) { - unsigned long pfn, zone_spfn, zone_epfn; + unsigned long pfn; u64 pgcnt = 0; - zone_spfn = arch_zone_lowest_possible_pfn[zone]; - zone_epfn = arch_zone_highest_possible_pfn[zone]; - - spfn = clamp(spfn, zone_spfn, zone_epfn); - epfn = clamp(epfn, zone_spfn, zone_epfn); - for (pfn = spfn; pfn < epfn; pfn++) { if (!pfn_valid(ALIGN_DOWN(pfn, pageblock_nr_pages))) { pfn = ALIGN_DOWN(pfn, pageblock_nr_pages) + pageblock_nr_pages - 1; continue; } - - __init_single_page(pfn_to_page(pfn), pfn, zone, nid); + /* + * Use a fake node/zone (0) for now. Some of these pages + * (in memblock.reserved but not in memblock.memory) will + * get re-initialized via reserve_bootmem_region() later. + */ + __init_single_page(pfn_to_page(pfn), pfn, 0, 0); __SetPageReserved(pfn_to_page(pfn)); pgcnt++; } @@ -7108,64 +7105,51 @@ static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn, } /* - * Only struct pages that correspond to ranges defined by memblock.memory - * are zeroed and initialized by going through __init_single_page() during - * memmap_init(). - * - * But, there could be struct pages that correspond to holes in - * memblock.memory. This can happen because of the following reasons: - * - phyiscal memory bank size is not necessarily the exact multiple of the - * arbitrary section size - * - early reserved memory may not be listed in memblock.memory - * - memory layouts defined with memmap= kernel parameter may not align - * nicely with memmap sections + * Only struct pages that are backed by physical memory are zeroed and + * initialized by going through __init_single_page(). But, there are some + * struct pages which are reserved in memblock allocator and their fields + * may be accessed (for example page_to_pfn() on some configuration accesses + * flags). We must explicitly initialize those struct pages. * - * Explicitly initialize those struct pages so that: - * - PG_Reserved is set - * - zone link is set accorging to the architecture constrains - * - node is set to node id of the next populated region except for the - * trailing hole where last node id is used + * This function also addresses a similar issue where struct pages are left + * uninitialized because the physical address range is not covered by + * memblock.memory or memblock.reserved. That could happen when memblock + * layout is manually configured via memmap=, or when the highest physical + * address (max_pfn) does not end on a section boundary. */ -static void __init init_zone_unavailable_mem(int zone) +static void __init init_unavailable_mem(void) { - unsigned long start, end; - int i, nid; - u64 pgcnt; - unsigned long next = 0; + phys_addr_t start, end; + u64 i, pgcnt; + phys_addr_t next = 0; /* - * Loop through holes in memblock.memory and initialize struct - * pages corresponding to these holes + * Loop through unavailable ranges not covered by memblock.memory. */ pgcnt = 0; - for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, &nid) { + for_each_mem_range(i, &start, &end) { if (next < start) - pgcnt += init_unavailable_range(next, start, zone, nid); + pgcnt += init_unavailable_range(PFN_DOWN(next), + PFN_UP(start)); next = end; } /* - * Last section may surpass the actual end of memory (e.g. we can - * have 1Gb section and 512Mb of RAM pouplated). - * Make sure that memmap has a well defined state in this case. + * Early sections always have a fully populated memmap for the whole + * section - see pfn_valid(). If the last section has holes at the + * end and that section is marked "online", the memmap will be + * considered initialized. Make sure that memmap has a well defined + * state. */ - end = round_up(max_pfn, PAGES_PER_SECTION); - pgcnt += init_unavailable_range(next, end, zone, nid); + pgcnt += init_unavailable_range(PFN_DOWN(next), + round_up(max_pfn, PAGES_PER_SECTION)); /* * Struct pages that do not have backing memory. This could be because * firmware is using some of this memory, or for some other reasons. */ if (pgcnt) - pr_info("Zone %s: zeroed struct page in unavailable ranges: %lld pages", zone_names[zone], pgcnt); -} - -static void __init init_unavailable_mem(void) -{ - int zone; - - for (zone = 0; zone < ZONE_MOVABLE; zone++) - init_zone_unavailable_mem(zone); + pr_info("Zeroed struct page in unavailable ranges: %lld pages", pgcnt); } #else static inline void __init init_unavailable_mem(void) -- GitLab From 29e2d9eb82647654abff150ff02fa1e07362214f Mon Sep 17 00:00:00 2001 From: Henry Tieman Date: Fri, 20 Nov 2020 16:38:30 -0800 Subject: [PATCH 0682/1084] ice: fix FDir IPv6 flexbyte The packet classifier would occasionally misrecognize an IPv6 training packet when the next protocol field was 0. The correct value for unspecified protocol is IPPROTO_NONE. Fixes: 165d80d6adab ("ice: Support IPv6 Flow Director filters") Signed-off-by: Henry Tieman Reviewed-by: Paul Menzel Tested-by: Tony Brelinski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c index 2d27f66ac8534..192729546bbfc 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c @@ -1576,7 +1576,13 @@ ice_set_fdir_input_set(struct ice_vsi *vsi, struct ethtool_rx_flow_spec *fsp, sizeof(struct in6_addr)); input->ip.v6.l4_header = fsp->h_u.usr_ip6_spec.l4_4_bytes; input->ip.v6.tc = fsp->h_u.usr_ip6_spec.tclass; - input->ip.v6.proto = fsp->h_u.usr_ip6_spec.l4_proto; + + /* if no protocol requested, use IPPROTO_NONE */ + if (!fsp->m_u.usr_ip6_spec.l4_proto) + input->ip.v6.proto = IPPROTO_NONE; + else + input->ip.v6.proto = fsp->h_u.usr_ip6_spec.l4_proto; + memcpy(input->mask.v6.dst_ip, fsp->m_u.usr_ip6_spec.ip6dst, sizeof(struct in6_addr)); memcpy(input->mask.v6.src_ip, fsp->m_u.usr_ip6_spec.ip6src, -- GitLab From 1b0b0b581b945ee27beb70e8199270a22dd5a2f6 Mon Sep 17 00:00:00 2001 From: Nick Nunley Date: Fri, 20 Nov 2020 16:38:31 -0800 Subject: [PATCH 0683/1084] ice: Implement flow for IPv6 next header (extension header) This patch is based on a similar change to i40e by Slawomir Laba: "i40e: Implement flow for IPv6 next header (extension header)". When a packet contains an IPv6 header with next header which is an extension header and not a protocol one, the kernel function skb_transport_header called with such sk_buff will return a pointer to the extension header and not to the TCP one. The above explained call caused a problem with packet processing for skb with encapsulation for tunnel with ICE_TX_CTX_EIPT_IPV6. The extension header was not skipped at all. The ipv6_skip_exthdr function does check if next header of the IPV6 header is an extension header and doesn't modify the l4_proto pointer if it points to a protocol header value so its safe to omit the comparison of exthdr and l4.hdr pointers. The ipv6_skip_exthdr can return value -1. This means that the skipping process failed and there is something wrong with the packet so it will be dropped. Fixes: a4e82a81f573 ("ice: Add support for tunnel offloads") Signed-off-by: Nick Nunley Tested-by: Tony Brelinski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_txrx.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index a2d0aad8cfdd7..b6fa83c619dd7 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -1923,12 +1923,15 @@ int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off) ICE_TX_CTX_EIPT_IPV4_NO_CSUM; l4_proto = ip.v4->protocol; } else if (first->tx_flags & ICE_TX_FLAGS_IPV6) { + int ret; + tunnel |= ICE_TX_CTX_EIPT_IPV6; exthdr = ip.hdr + sizeof(*ip.v6); l4_proto = ip.v6->nexthdr; - if (l4.hdr != exthdr) - ipv6_skip_exthdr(skb, exthdr - skb->data, - &l4_proto, &frag_off); + ret = ipv6_skip_exthdr(skb, exthdr - skb->data, + &l4_proto, &frag_off); + if (ret < 0) + return -1; } /* define outer transport */ -- GitLab From 13ed5e8a9b9ccd140a79e80283f69d724c9bb2be Mon Sep 17 00:00:00 2001 From: Nick Nunley Date: Fri, 20 Nov 2020 16:38:33 -0800 Subject: [PATCH 0684/1084] ice: update dev_addr in ice_set_mac_address even if HW filter exists Fix the driver to copy the MAC address configured in ndo_set_mac_address into dev_addr, even if the MAC filter already exists in HW. In some situations (e.g. bonding) the netdev's dev_addr could have been modified outside of the driver, with no change to the HW filter, so the driver cannot assume that they match. Fixes: 757976ab16be ("ice: Fix check for removing/adding mac filters") Signed-off-by: Nick Nunley Tested-by: Tony Brelinski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index c52b9bb0e3ab1..fb81aa5979e3e 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -4884,9 +4884,15 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi) goto err_update_filters; } - /* Add filter for new MAC. If filter exists, just return success */ + /* Add filter for new MAC. If filter exists, return success */ status = ice_fltr_add_mac(vsi, mac, ICE_FWD_TO_VSI); if (status == ICE_ERR_ALREADY_EXISTS) { + /* Although this MAC filter is already present in hardware it's + * possible in some cases (e.g. bonding) that dev_addr was + * modified outside of the driver and needs to be restored back + * to this value. + */ + memcpy(netdev->dev_addr, mac, netdev->addr_len); netdev_dbg(netdev, "filter for MAC %pM already exists\n", mac); return 0; } -- GitLab From 943b881e35829403da638fcb34a959125deafef3 Mon Sep 17 00:00:00 2001 From: Brett Creeley Date: Thu, 21 Jan 2021 10:38:05 -0800 Subject: [PATCH 0685/1084] ice: Don't allow more channels than LAN MSI-X available Currently users could create more channels than LAN MSI-X available. This is happening because there is no check against pf->num_lan_msix when checking the max allowed channels and will cause performance issues if multiple Tx and Rx queues are tied to a single MSI-X. Fix this by not allowing more channels than LAN MSI-X available in pf->num_lan_msix. Fixes: 87324e747fde ("ice: Implement ethtool ops for channels") Signed-off-by: Brett Creeley Tested-by: Tony Brelinski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_ethtool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index 9e8e9531cd871..69c113a4de7e6 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -3258,8 +3258,8 @@ ice_set_rxfh(struct net_device *netdev, const u32 *indir, const u8 *key, */ static int ice_get_max_txq(struct ice_pf *pf) { - return min_t(int, num_online_cpus(), - pf->hw.func_caps.common_cap.num_txq); + return min3(pf->num_lan_msix, (u16)num_online_cpus(), + (u16)pf->hw.func_caps.common_cap.num_txq); } /** @@ -3268,8 +3268,8 @@ static int ice_get_max_txq(struct ice_pf *pf) */ static int ice_get_max_rxq(struct ice_pf *pf) { - return min_t(int, num_online_cpus(), - pf->hw.func_caps.common_cap.num_rxq); + return min3(pf->num_lan_msix, (u16)num_online_cpus(), + (u16)pf->hw.func_caps.common_cap.num_rxq); } /** -- GitLab From f3fe97f64384fa4073d9dc0278c4b351c92e295c Mon Sep 17 00:00:00 2001 From: Brett Creeley Date: Thu, 21 Jan 2021 10:38:06 -0800 Subject: [PATCH 0686/1084] ice: Fix MSI-X vector fallback logic The current MSI-X enablement logic tries to enable best-case MSI-X vectors and if that fails we only support a bare-minimum set. This includes a single MSI-X for 1 Tx and 1 Rx queue and a single MSI-X for the OICR interrupt. Unfortunately, the driver fails to load when we don't get as many MSI-X as requested for a couple reasons. First, the code to allocate MSI-X in the driver tries to allocate num_online_cpus() MSI-X for LAN traffic without caring about the number of MSI-X actually enabled/requested from the kernel for LAN traffic. So, when calling ice_get_res() for the PF VSI, it returns failure because the number of available vectors is less than requested. Fix this by not allowing the PF VSI to allocation more than pf->num_lan_msix MSI-X vectors and pf->num_lan_msix Rx/Tx queues. Limiting the number of queues is done because we don't want more than 1 Tx/Rx queue per interrupt due to performance conerns. Second, the driver assigns pf->num_lan_msix = 2, to account for LAN traffic and the OICR. However, pf->num_lan_msix is only meant for LAN MSI-X. This is causing a failure when the PF VSI tries to allocate/reserve the minimum pf->num_lan_msix because the OICR MSI-X has already been reserved, so there may not be enough MSI-X vectors left. Fix this by setting pf->num_lan_msix = 1 for the failure case. Then the ICE_MIN_MSIX accounts for the LAN MSI-X and the OICR MSI-X needed for the failure case. Update the related defines used in ice_ena_msix_range() to align with the above behavior and remove the unused RDMA defines because RDMA is currently not supported. Also, remove the now incorrect comment. Fixes: 152b978a1f90 ("ice: Rework ice_ena_msix_range") Signed-off-by: Brett Creeley Tested-by: Tony Brelinski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice.h | 4 +++- drivers/net/ethernet/intel/ice/ice_lib.c | 14 +++++++++----- drivers/net/ethernet/intel/ice/ice_main.c | 8 ++------ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index 56725356a17b8..fa1e128c24eca 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -68,7 +68,9 @@ #define ICE_INT_NAME_STR_LEN (IFNAMSIZ + 16) #define ICE_AQ_LEN 64 #define ICE_MBXSQ_LEN 64 -#define ICE_MIN_MSIX 2 +#define ICE_MIN_LAN_TXRX_MSIX 1 +#define ICE_MIN_LAN_OICR_MSIX 1 +#define ICE_MIN_MSIX (ICE_MIN_LAN_TXRX_MSIX + ICE_MIN_LAN_OICR_MSIX) #define ICE_FDIR_MSIX 1 #define ICE_NO_VSI 0xffff #define ICE_VSI_MAP_CONTIG 0 diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 3df67486d42d9..ad9c22a1b97a0 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -161,8 +161,9 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id) switch (vsi->type) { case ICE_VSI_PF: - vsi->alloc_txq = min_t(int, ice_get_avail_txq_count(pf), - num_online_cpus()); + vsi->alloc_txq = min3(pf->num_lan_msix, + ice_get_avail_txq_count(pf), + (u16)num_online_cpus()); if (vsi->req_txq) { vsi->alloc_txq = vsi->req_txq; vsi->num_txq = vsi->req_txq; @@ -174,8 +175,9 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id) if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { vsi->alloc_rxq = 1; } else { - vsi->alloc_rxq = min_t(int, ice_get_avail_rxq_count(pf), - num_online_cpus()); + vsi->alloc_rxq = min3(pf->num_lan_msix, + ice_get_avail_rxq_count(pf), + (u16)num_online_cpus()); if (vsi->req_rxq) { vsi->alloc_rxq = vsi->req_rxq; vsi->num_rxq = vsi->req_rxq; @@ -184,7 +186,9 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id) pf->num_lan_rx = vsi->alloc_rxq; - vsi->num_q_vectors = max_t(int, vsi->alloc_rxq, vsi->alloc_txq); + vsi->num_q_vectors = min_t(int, pf->num_lan_msix, + max_t(int, vsi->alloc_rxq, + vsi->alloc_txq)); break; case ICE_VSI_VF: vf = &pf->vf[vsi->vf_id]; diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index fb81aa5979e3e..e10ca8929f85e 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -3430,18 +3430,14 @@ static int ice_ena_msix_range(struct ice_pf *pf) if (v_actual < v_budget) { dev_warn(dev, "not enough OS MSI-X vectors. requested = %d, obtained = %d\n", v_budget, v_actual); -/* 2 vectors each for LAN and RDMA (traffic + OICR), one for flow director */ -#define ICE_MIN_LAN_VECS 2 -#define ICE_MIN_RDMA_VECS 2 -#define ICE_MIN_VECS (ICE_MIN_LAN_VECS + ICE_MIN_RDMA_VECS + 1) - if (v_actual < ICE_MIN_LAN_VECS) { + if (v_actual < ICE_MIN_MSIX) { /* error if we can't get minimum vectors */ pci_disable_msix(pf->pdev); err = -ERANGE; goto msix_err; } else { - pf->num_lan_msix = ICE_MIN_LAN_VECS; + pf->num_lan_msix = ICE_MIN_LAN_TXRX_MSIX; } } -- GitLab From 67a3c6b3cc40bb217c3ff947a55053151a00fea0 Mon Sep 17 00:00:00 2001 From: Stefan Assmann Date: Mon, 30 Nov 2020 14:12:57 +0100 Subject: [PATCH 0687/1084] i40e: acquire VSI pointer only after VF is initialized This change simplifies the VF initialization check and also minimizes the delay between acquiring the VSI pointer and using it. As known by the commit being fixed, there is a risk of the VSI pointer getting changed. Therefore minimize the delay between getting and using the pointer. Fixes: 9889707b06ac ("i40e: Fix crash caused by stress setting of VF MAC addresses") Signed-off-by: Stefan Assmann Reviewed-by: Jacob Keller Tested-by: Konrad Jankowski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 21ee56420c3ae..7efc61aacb0a5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -4046,20 +4046,16 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) goto error_param; vf = &pf->vf[vf_id]; - vsi = pf->vsi[vf->lan_vsi_idx]; /* When the VF is resetting wait until it is done. * It can take up to 200 milliseconds, * but wait for up to 300 milliseconds to be safe. - * If the VF is indeed in reset, the vsi pointer has - * to show on the newly loaded vsi under pf->vsi[id]. + * Acquire the VSI pointer only after the VF has been + * properly initialized. */ for (i = 0; i < 15; i++) { - if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) { - if (i > 0) - vsi = pf->vsi[vf->lan_vsi_idx]; + if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) break; - } msleep(20); } if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) { @@ -4068,6 +4064,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) ret = -EAGAIN; goto error_param; } + vsi = pf->vsi[vf->lan_vsi_idx]; if (is_multicast_ether_addr(mac)) { dev_err(&pf->pdev->dev, -- GitLab From 0aa91f84b1804b59841c834128b2c15330a1ec59 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Thu, 14 Jan 2021 16:14:48 -0800 Subject: [PATCH 0688/1084] parisc: Remove leftover reference to the power_tasklet This was removed long ago, back in: 6e16d9409e1 ([PARISC] Convert soft power switch driver to kthread) Signed-off-by: Davidlohr Bueso Signed-off-by: Helge Deller --- arch/parisc/include/asm/irq.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/parisc/include/asm/irq.h b/arch/parisc/include/asm/irq.h index 959e79cd2c148..378f63c4015b4 100644 --- a/arch/parisc/include/asm/irq.h +++ b/arch/parisc/include/asm/irq.h @@ -47,7 +47,4 @@ extern unsigned long txn_affinity_addr(unsigned int irq, int cpu); extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *); extern int cpu_check_affinity(struct irq_data *d, const struct cpumask *dest); -/* soft power switch support (power.c) */ -extern struct tasklet_struct power_tasklet; - #endif /* _ASM_PARISC_IRQ_H */ -- GitLab From 00e35f2b0e8acb88d4e1aa96ff0490e3bfe46580 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 26 Jan 2021 20:16:21 +0100 Subject: [PATCH 0689/1084] parisc: Enable -mlong-calls gcc option by default when !CONFIG_MODULES When building a kernel without module support, the CONFIG_MLONGCALL option needs to be enabled in order to reach symbols which are outside of a 22-bit branch. This patch changes the autodetection in the Kconfig script to always enable CONFIG_MLONGCALL when modules are disabled and uses a far call to preempt_schedule_irq() in intr_do_preempt() to reach the symbol in all cases. Signed-off-by: Helge Deller Reported-by: kernel test robot Cc: stable@vger.kernel.org # v5.6+ --- arch/parisc/Kconfig | 5 ++--- arch/parisc/kernel/entry.S | 13 ++++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 78b17621ee4a5..278462186ac47 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -202,9 +202,8 @@ config PREFETCH depends on PA8X00 || PA7200 config MLONGCALLS - bool "Enable the -mlong-calls compiler option for big kernels" - default y if !MODULES || UBSAN || FTRACE - default n + def_bool y if !MODULES || UBSAN || FTRACE + bool "Enable the -mlong-calls compiler option for big kernels" if MODULES && !UBSAN && !FTRACE depends on PA8X00 help If you configure the kernel to include many drivers built-in instead diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index beba9816cc6c1..4d37cc9cba37c 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -997,10 +997,17 @@ intr_do_preempt: bb,<,n %r20, 31 - PSW_SM_I, intr_restore nop + /* ssm PSW_SM_I done later in intr_restore */ +#ifdef CONFIG_MLONGCALLS + ldil L%intr_restore, %r2 + load32 preempt_schedule_irq, %r1 + bv %r0(%r1) + ldo R%intr_restore(%r2), %r2 +#else + ldil L%intr_restore, %r1 BL preempt_schedule_irq, %r2 - nop - - b,n intr_restore /* ssm PSW_SM_I done by intr_restore */ + ldo R%intr_restore(%r1), %r2 +#endif #endif /* CONFIG_PREEMPTION */ /* -- GitLab From 2ab38c17aac10bf55ab3efde4c4db3893d8691d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Tue, 26 Jan 2021 01:04:38 +0100 Subject: [PATCH 0690/1084] mailmap: remove the "repo-abbrev" comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the magical "repo-abbrev" comment added when this file was introduced in e0ab1ec9fcd3 ([PATCH] add .mailmap for proper git-shortlog output, 2007-02-14). It's been an undocumented feature of git-shortlog(1), originally added to git for Linus's use. Since then he's no longer using it[1], and I've removed the feature in git.git's 4e168333a87 (shortlog: remove unused(?) "repo-abbrev" feature, 2021-01-12). It's on the "master" branch, but not yet in a release version. Let's also remove it from linux.git, both as a heads-up to any potential users of it in linux.git whose use would be broken sooner than later by git itself, and because it'll eventually be entirely redundant. 1. https://lore.kernel.org/git/CAHk-=wixHyBKZVUcxq+NCWMbkrX0xnppb7UCopRWw1+oExYpYw@mail.gmail.com/ Acked-by: Linus Torvalds Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Linus Torvalds --- .mailmap | 3 --- 1 file changed, 3 deletions(-) diff --git a/.mailmap b/.mailmap index b1ab0129c7d6b..cc4e91d3075e8 100644 --- a/.mailmap +++ b/.mailmap @@ -9,9 +9,6 @@ # # Please keep this list dictionary sorted. # -# This comment is parsed by git-shortlog: -# repo-abbrev: /pub/scm/linux/kernel/git/ -# Aaron Durbin Adam Oldham Adam Radford -- GitLab From 94c41b3a7c370b0d6afc5ace8fafa0531865a940 Mon Sep 17 00:00:00 2001 From: Hajime Tazaki Date: Mon, 21 Dec 2020 11:24:34 +0900 Subject: [PATCH 0691/1084] um: ubd: fix command line handling of ubd This commit fixes a regression to handle command line parameters of ubd. With a simple line "./linux ubd0="./disk-ext4.img", it fails at ubd_setup_common(). The commit adds additional checks to the variables in order to properly parse the paremeters which previously worked. Fixes: ef3ba87cb7c9 ("um: ubd: Set device serial attribute from cmdline") Cc: Christopher Obbard Signed-off-by: Hajime Tazaki Acked-by: Christopher Obbard Signed-off-by: Richard Weinberger --- arch/um/drivers/ubd_kern.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 13b1fe694b904..bd16b17ba4d63 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -375,11 +375,11 @@ static int ubd_setup_common(char *str, int *index_out, char **error_out) file = NULL; backing_file = strsep(&str, ",:"); - if (*backing_file == '\0') + if (backing_file && *backing_file == '\0') backing_file = NULL; serial = strsep(&str, ",:"); - if (*serial == '\0') + if (serial && *serial == '\0') serial = NULL; if (backing_file && ubd_dev->no_cow) { -- GitLab From 1cdcfb44370b28187a0c33cdbcb4705103ed81aa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 17 Dec 2020 13:15:56 +0100 Subject: [PATCH 0692/1084] um: return error from ioremap() Back a few years ago, ioremap() was added to UML so that we'd not break the build for everything all the time. However, for some reason, v1 of the patch got applied, rather than the v2 that returned NULL, which was discussed here: https://lore.kernel.org/lkml/1495726955-27497-1-git-send-email-logang@deltatee.com/ Fix that now. Signed-off-by: Johannes Berg Acked-by: Arnd Bergmann Signed-off-by: Richard Weinberger --- arch/um/include/asm/io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/include/asm/io.h b/arch/um/include/asm/io.h index 96f77b5232aaf..cef03e3aa0f99 100644 --- a/arch/um/include/asm/io.h +++ b/arch/um/include/asm/io.h @@ -5,7 +5,7 @@ #define ioremap ioremap static inline void __iomem *ioremap(phys_addr_t offset, size_t size) { - return (void __iomem *)(unsigned long)offset; + return NULL; } #define iounmap iounmap -- GitLab From d7ffac33631b2f72ec4cbbf9a64be6aa011b5cfd Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Tue, 5 Jan 2021 13:01:28 +0100 Subject: [PATCH 0693/1084] um: stdio_console: Make preferred console The addition of the "ttynull" console driver did break the ordering of the UML stdio console driver. The UML stdio console driver is added in late_initcall (7), whereby the ttynull driver is added in device_initcall (6), which always does make the ttynull driver the default console. Fix it by explicitly adding the UML stdio console as the preferred console, in case no 'console=' command line option was specified. Signed-off-by: Thomas Meyer Signed-off-by: Richard Weinberger --- arch/um/kernel/um_arch.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 31d356b1ffd82..80e2660782a05 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -26,7 +26,8 @@ #include #include -#define DEFAULT_COMMAND_LINE "root=98:0" +#define DEFAULT_COMMAND_LINE_ROOT "root=98:0" +#define DEFAULT_COMMAND_LINE_CONSOLE "console=tty" /* Changed in add_arg and setup_arch, which run before SMP is started */ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 }; @@ -109,7 +110,8 @@ unsigned long end_vm; int ncpus = 1; /* Set in early boot */ -static int have_root __initdata = 0; +static int have_root __initdata; +static int have_console __initdata; /* Set in uml_mem_setup and modified in linux_main */ long long physmem_size = 32 * 1024 * 1024; @@ -161,6 +163,17 @@ __uml_setup("debug", no_skas_debug_setup, " this flag is not needed to run gdb on UML in skas mode\n\n" ); +static int __init uml_console_setup(char *line, int *add) +{ + have_console = 1; + return 0; +} + +__uml_setup("console=", uml_console_setup, +"console=\n" +" Specify the preferred console output driver\n\n" +); + static int __init Usage(char *line, int *add) { const char **p; @@ -264,7 +277,10 @@ int __init linux_main(int argc, char **argv) add_arg(argv[i]); } if (have_root == 0) - add_arg(DEFAULT_COMMAND_LINE); + add_arg(DEFAULT_COMMAND_LINE_ROOT); + + if (have_console == 0) + add_arg(DEFAULT_COMMAND_LINE_CONSOLE); host_task_size = os_get_top_address(); /* -- GitLab From e23fe90dec286cd77e9059033aa640fc45603602 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 7 Jan 2021 09:05:31 +0100 Subject: [PATCH 0694/1084] um: kmsg_dumper: always dump when not tty console With the addition of the ttynull console driver, the chance that a console driver was already registerd did increase. Refine the logic when to dump the kernel message buffer: always dump the buffer, when the UML stdio console driver is not active and the preferred console. Signed-off-by: Thomas Meyer Signed-off-by: Richard Weinberger --- arch/um/kernel/kmsg_dump.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c index e4abac6c9727c..6516ef1f82745 100644 --- a/arch/um/kernel/kmsg_dump.c +++ b/arch/um/kernel/kmsg_dump.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include @@ -16,8 +17,12 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper, if (!console_trylock()) return; - for_each_console(con) - break; + for_each_console(con) { + if(strcmp(con->name, "tty") == 0 && + (con->flags & (CON_ENABLED | CON_CONSDEV)) != 0) { + break; + } + } console_unlock(); -- GitLab From f4172b084342fd3f9e38c10650ffe19eac30d8ce Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Jan 2021 22:15:21 +0100 Subject: [PATCH 0695/1084] um: virtio: free vu_dev only with the contained struct device Since struct device is refcounted, we shouldn't free the vu_dev immediately when it's removed from the platform device, but only when the references actually all go away. Move the freeing to the release to accomplish that. Fixes: 5d38f324993f ("um: drivers: Add virtio vhost-user driver") Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/virtio_uml.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 27e92d3881ff4..5d957b7e7fd52 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -1084,6 +1084,7 @@ static void virtio_uml_release_dev(struct device *d) } os_close_file(vu_dev->sock); + kfree(vu_dev); } /* Platform device */ @@ -1097,7 +1098,7 @@ static int virtio_uml_probe(struct platform_device *pdev) if (!pdata) return -EINVAL; - vu_dev = devm_kzalloc(&pdev->dev, sizeof(*vu_dev), GFP_KERNEL); + vu_dev = kzalloc(sizeof(*vu_dev), GFP_KERNEL); if (!vu_dev) return -ENOMEM; -- GitLab From 2fcb4090cd7352665ecb756990a3087bfd86a295 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 10 Jan 2021 19:05:08 +0100 Subject: [PATCH 0696/1084] Revert "um: allocate a guard page to helper threads" This reverts commit ef4459a6da09 ("um: allocate a guard page to helper threads"), it's broken in multiple ways: 1) the free no longer matches the alloc; and 2) more importantly, the set_memory_ro() causes allocation of page tables for the normal memory that doesn't have any, and that later causes corruption and crashes (usually but not always in vfree()). We could fix the first bug and use vmalloc() to work around the second, but set_memory_ro() actually doesn't do anything either so I'll just revert that as well. Reported-by: Benjamin Berg Fixes: ef4459a6da09 ("um: allocate a guard page to helper threads") Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/ubd_kern.c | 2 +- arch/um/include/shared/kern_util.h | 2 +- arch/um/kernel/process.c | 11 ++++------- arch/um/os-Linux/helper.c | 4 ++-- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index bd16b17ba4d63..8e0b43cf089f4 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1241,7 +1241,7 @@ static int __init ubd_driver_init(void){ /* Letting ubd=sync be like using ubd#s= instead of ubd#= is * enough. So use anyway the io thread. */ } - stack = alloc_stack(0); + stack = alloc_stack(0, 0); io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), &thread_fd); if(io_pid < 0){ diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index d8c279e3312fe..2888ec812f6ec 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -19,7 +19,7 @@ extern int kmalloc_ok; #define UML_ROUND_UP(addr) \ ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK) -extern unsigned long alloc_stack(int atomic); +extern unsigned long alloc_stack(int order, int atomic); extern void free_stack(unsigned long stack, int order); struct pt_regs; diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 2a986ece54780..81d508daf67cb 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -32,7 +32,6 @@ #include #include #include -#include /* * This is a per-cpu array. A processor only modifies its entry and it only @@ -63,18 +62,16 @@ void free_stack(unsigned long stack, int order) free_pages(stack, order); } -unsigned long alloc_stack(int atomic) +unsigned long alloc_stack(int order, int atomic) { - unsigned long addr; + unsigned long page; gfp_t flags = GFP_KERNEL; if (atomic) flags = GFP_ATOMIC; - addr = __get_free_pages(flags, 1); + page = __get_free_pages(flags, order); - set_memory_ro(addr, 1); - - return addr + PAGE_SIZE; + return page; } static inline void set_current(struct task_struct *task) diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index feb48d796e005..9fa6e4187d4fb 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -45,7 +45,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) unsigned long stack, sp; int pid, fds[2], ret, n; - stack = alloc_stack(__cant_sleep()); + stack = alloc_stack(0, __cant_sleep()); if (stack == 0) return -ENOMEM; @@ -116,7 +116,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, unsigned long stack, sp; int pid, status, err; - stack = alloc_stack(__cant_sleep()); + stack = alloc_stack(0, __cant_sleep()); if (stack == 0) return -ENOMEM; -- GitLab From a31e9c4e7247d182192e9b85abbea498d63dd850 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 10 Jan 2021 19:05:09 +0100 Subject: [PATCH 0697/1084] Revert "um: support some of ARCH_HAS_SET_MEMORY" This reverts commit 963285b0b47a ("um: support some of ARCH_HAS_SET_MEMORY"), as it turns out that it's not only not working (due to um never using the protection bits in the page tables) but also corrupts the page tables if used on a non-vmalloc page, since um never allocates proper page tables for the 'physmem' in the first place. Fixing all this will take more effort, so for now revert it. Reported-by: Benjamin Berg Fixes: 963285b0b47a ("um: support some of ARCH_HAS_SET_MEMORY") Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- arch/um/Kconfig | 1 - arch/um/include/asm/pgtable.h | 3 -- arch/um/include/asm/set_memory.h | 1 - arch/um/kernel/tlb.c | 54 -------------------------------- 4 files changed, 59 deletions(-) delete mode 100644 arch/um/include/asm/set_memory.h diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 34d302d1a07ff..c3030db3325f1 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -15,7 +15,6 @@ config UML select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_BUGVERBOSE select NO_DMA - select ARCH_HAS_SET_MEMORY select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select HAVE_GCC_PLUGINS diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index 39376bb63abf5..def376194dce6 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -55,15 +55,12 @@ extern unsigned long end_iomem; #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) #define __PAGE_KERNEL_EXEC \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) -#define __PAGE_KERNEL_RO \ - (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED) #define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) #define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) -#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) /* * The i386 can't do page protection for execute, and considers that the same diff --git a/arch/um/include/asm/set_memory.h b/arch/um/include/asm/set_memory.h deleted file mode 100644 index 24266c63720d2..0000000000000 --- a/arch/um/include/asm/set_memory.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 437d1f1cc5ecd..61776790cd678 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -608,57 +608,3 @@ void force_flush_all(void) vma = vma->vm_next; } } - -struct page_change_data { - unsigned int set_mask, clear_mask; -}; - -static int change_page_range(pte_t *ptep, unsigned long addr, void *data) -{ - struct page_change_data *cdata = data; - pte_t pte = READ_ONCE(*ptep); - - pte_clear_bits(pte, cdata->clear_mask); - pte_set_bits(pte, cdata->set_mask); - - set_pte(ptep, pte); - return 0; -} - -static int change_memory(unsigned long start, unsigned long pages, - unsigned int set_mask, unsigned int clear_mask) -{ - unsigned long size = pages * PAGE_SIZE; - struct page_change_data data; - int ret; - - data.set_mask = set_mask; - data.clear_mask = clear_mask; - - ret = apply_to_page_range(&init_mm, start, size, change_page_range, - &data); - - flush_tlb_kernel_range(start, start + size); - - return ret; -} - -int set_memory_ro(unsigned long addr, int numpages) -{ - return change_memory(addr, numpages, 0, _PAGE_RW); -} - -int set_memory_rw(unsigned long addr, int numpages) -{ - return change_memory(addr, numpages, _PAGE_RW, 0); -} - -int set_memory_nx(unsigned long addr, int numpages) -{ - return -EOPNOTSUPP; -} - -int set_memory_x(unsigned long addr, int numpages) -{ - return -EOPNOTSUPP; -} -- GitLab From 9868c2081d071f7c309796c8dffc94364fc07582 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jan 2021 21:40:23 +0100 Subject: [PATCH 0698/1084] um: fix os_idle_sleep() to not hang Changing os_idle_sleep() to use pause() (I accidentally described it as an empty select() in the commit log because I had changed it from that to pause() in a later revision) exposed a race condition in the idle code. The following can happen: timer_settime(0, 0, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=0, tv_nsec=624017}}, NULL) = 0 ... pause() and we now hang forever. This was previously possible as well, but it could never cause UML to hang for more than a second since we could only sleep for that much, so at most you'd notice a "hiccup" in the UML. Obviously, any sort of external interrupt also "saves" it and interrupts pause(). Fix this by properly handling the race, rather than papering over it again: - first, block SIGALRM, and obtain the old signal set - check the timer - suspend, waiting for any signal out of the old set, if, and only if, the timer will fire in the future - restore the old signal mask This ensures race-free operation: as it's blocked, the signal won't be delivered while we're looking at the timer even if it were to be triggered right _after_ we've returned from timer_gettime() with a non-zero value (telling us the timer will trigger). Thus, despite getting to sigsuspend() because timer_gettime() told us we're still waiting, we'll not hang because sigsuspend() will return immediately due to the pending signal. Fixes: 49da38a3ef33 ("um: Simplify os_idle_sleep() and sleep longer") Signed-off-by: Johannes Berg Acked-By: Anton Ivanov Signed-off-by: Richard Weinberger --- arch/um/os-Linux/time.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index a61cbf73a179d..6c5041c5560b2 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -104,5 +104,18 @@ long long os_nsecs(void) */ void os_idle_sleep(void) { - pause(); + struct itimerspec its; + sigset_t set, old; + + /* block SIGALRM while we analyze the timer state */ + sigemptyset(&set); + sigaddset(&set, SIGALRM); + sigprocmask(SIG_BLOCK, &set, &old); + + /* check the timer, and if it'll fire then wait for it */ + timer_gettime(event_high_res_timer, &its); + if (its.it_value.tv_sec || its.it_value.tv_nsec) + sigsuspend(&old); + /* either way, restore the signal mask */ + sigprocmask(SIG_UNBLOCK, &set, NULL); } -- GitLab From 7f3414226b58b0df0426104c8ab5e8d50ae71d11 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jan 2021 12:49:45 +0100 Subject: [PATCH 0699/1084] um: time: fix initialization in time-travel mode In time-travel mode, since my previous patch, the start time was initialized too late, so that the system would read it before we set it, thus always starting system time at 0 (1970-01-01). This happens because timekeeping_init() reads the time and is called before time_init(). Unfortunately, I didn't see this before because I was testing it only with the RTC patch applied (and enabled), and then the time is read again by the RTC a little - after time_init() this time. Fix this by just doing the initialization whenever necessary. Fixes: 2701c1bd91dd ("um: time: Fix read_persistent_clock64() in time-travel") Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- arch/um/kernel/time.c | 50 +++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index f4db89b5b5a6f..315248b039414 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -535,6 +535,31 @@ static int time_travel_connect_external(const char *socket) return 1; } + +static void time_travel_set_start(void) +{ + if (time_travel_start_set) + return; + + switch (time_travel_mode) { + case TT_MODE_EXTERNAL: + time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); + /* controller gave us the *current* time, so adjust by that */ + time_travel_ext_get_time(); + time_travel_start -= time_travel_time; + break; + case TT_MODE_INFCPU: + case TT_MODE_BASIC: + if (!time_travel_start_set) + time_travel_start = os_persistent_clock_emulation(); + break; + case TT_MODE_OFF: + /* we just read the host clock with os_persistent_clock_emulation() */ + break; + } + + time_travel_start_set = true; +} #else /* CONFIG_UML_TIME_TRAVEL_SUPPORT */ #define time_travel_start_set 0 #define time_travel_start 0 @@ -553,6 +578,10 @@ static void time_travel_set_interval(unsigned long long interval) { } +static inline void time_travel_set_start(void) +{ +} + /* fail link if this actually gets used */ extern u64 time_travel_ext_req(u32 op, u64 time); @@ -731,6 +760,8 @@ void read_persistent_clock64(struct timespec64 *ts) { long long nsecs; + time_travel_set_start(); + if (time_travel_mode != TT_MODE_OFF) nsecs = time_travel_start + time_travel_time; else @@ -742,25 +773,6 @@ void read_persistent_clock64(struct timespec64 *ts) void __init time_init(void) { -#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT - switch (time_travel_mode) { - case TT_MODE_EXTERNAL: - time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); - /* controller gave us the *current* time, so adjust by that */ - time_travel_ext_get_time(); - time_travel_start -= time_travel_time; - break; - case TT_MODE_INFCPU: - case TT_MODE_BASIC: - if (!time_travel_start_set) - time_travel_start = os_persistent_clock_emulation(); - break; - case TT_MODE_OFF: - /* we just read the host clock with os_persistent_clock_emulation() */ - break; - } -#endif - timer_set_signal_handler(); late_time_init = um_timer_setup; } -- GitLab From 329a3678ec69962aa67c91397efbd46d36635f91 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 17 Nov 2020 20:50:40 +0100 Subject: [PATCH 0700/1084] igc: fix link speed advertising Link speed advertising in igc has two problems: - When setting the advertisement via ethtool, the link speed is converted to the legacy 32 bit representation for the intel PHY code. This inadvertently drops ETHTOOL_LINK_MODE_2500baseT_Full_BIT (being beyond bit 31). As a result, any call to `ethtool -s ...' drops the 2500Mbit/s link speed from the PHY settings. Only reloading the driver alleviates that problem. Fix this by converting the ETHTOOL_LINK_MODE_2500baseT_Full_BIT to the Intel PHY ADVERTISE_2500_FULL bit explicitly. - Rather than checking the actual PHY setting, the .get_link_ksettings function always fills link_modes.advertising with all link speeds the device is capable of. Fix this by checking the PHY autoneg_advertised settings and report only the actually advertised speeds up to ethtool. Fixes: 8c5ad0dae93c ("igc: Add ethtool support") Signed-off-by: Corinna Vinschen Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/igc/igc_ethtool.c | 24 +++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index 61d331ce38cdd..831f2f09de5fb 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -1675,12 +1675,18 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev, cmd->base.phy_address = hw->phy.addr; /* advertising link modes */ - ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Full); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Half); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Full); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full); + if (hw->phy.autoneg_advertised & ADVERTISE_10_HALF) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half); + if (hw->phy.autoneg_advertised & ADVERTISE_10_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Full); + if (hw->phy.autoneg_advertised & ADVERTISE_100_HALF) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Half); + if (hw->phy.autoneg_advertised & ADVERTISE_100_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Full); + if (hw->phy.autoneg_advertised & ADVERTISE_1000_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full); + if (hw->phy.autoneg_advertised & ADVERTISE_2500_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full); /* set autoneg settings */ if (hw->mac.autoneg == 1) { @@ -1792,6 +1798,12 @@ igc_ethtool_set_link_ksettings(struct net_device *netdev, ethtool_convert_link_mode_to_legacy_u32(&advertising, cmd->link_modes.advertising); + /* Converting to legacy u32 drops ETHTOOL_LINK_MODE_2500baseT_Full_BIT. + * We have to check this and convert it to ADVERTISE_2500_FULL + * (aka ETHTOOL_LINK_MODE_2500baseX_Full_BIT) explicitly. + */ + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 2500baseT_Full)) + advertising |= ADVERTISE_2500_FULL; if (cmd->base.autoneg == AUTONEG_ENABLE) { hw->mac.autoneg = 1; -- GitLab From 150a27328b681425c8cab239894a48f2aeb870e9 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Tue, 26 Jan 2021 16:13:20 +0000 Subject: [PATCH 0701/1084] bpf, preload: Fix build when $(O) points to a relative path Building the kernel with CONFIG_BPF_PRELOAD, and by providing a relative path for the output directory, may fail with the following error: $ make O=build bindeb-pkg ... /.../linux/tools/scripts/Makefile.include:5: *** O=build does not exist. Stop. make[7]: *** [/.../linux/kernel/bpf/preload/Makefile:9: kernel/bpf/preload/libbpf.a] Error 2 make[6]: *** [/.../linux/scripts/Makefile.build:500: kernel/bpf/preload] Error 2 make[5]: *** [/.../linux/scripts/Makefile.build:500: kernel/bpf] Error 2 make[4]: *** [/.../linux/Makefile:1799: kernel] Error 2 make[4]: *** Waiting for unfinished jobs.... In the case above, for the "bindeb-pkg" target, the error is produced by the "dummy" check in Makefile.include, called from libbpf's Makefile. This check changes directory to $(PWD) before checking for the existence of $(O). But at this step we have $(PWD) pointing to "/.../linux/build", and $(O) pointing to "build". So the Makefile.include tries in fact to assert the existence of a directory named "/.../linux/build/build", which does not exist. Note that the error does not occur for all make targets and architectures combinations. This was observed on x86 for "bindeb-pkg", or for a regular build for UML [0]. Here are some details. The root Makefile recursively calls itself once, after changing directory to $(O). The content for the variable $(PWD) is preserved across recursive calls to make, so it is unchanged at this step. For "bindeb-pkg", $(PWD) is eventually updated because the target writes a new Makefile (as debian/rules) and calls it indirectly through dpkg-buildpackage. This script does not preserve $(PWD), which is reset to the current working directory when the target in debian/rules is called. Although not investigated, it seems likely that something similar causes UML to change its value for $(PWD). Non-trivial fixes could be to remove the use of $(PWD) from the "dummy" check, or to make sure that $(PWD) and $(O) are preserved or updated to always play well and form a valid $(PWD)/$(O) path across the different targets and architectures. Instead, we take a simpler approach and just update $(O) when calling libbpf's Makefile, so it points to an absolute path which should always resolve for the "dummy" check run (through includes) by that Makefile. David Gow previously posted a slightly different version of this patch as a RFC [0], two months ago or so. [0] https://lore.kernel.org/bpf/20201119085022.3606135-1-davidgow@google.com/t/#u Fixes: d71fa5c9763c ("bpf: Add kernel module with user mode driver that populates bpffs.") Reported-by: David Gow Signed-off-by: Quentin Monnet Signed-off-by: Daniel Borkmann Acked-by: Andrii Nakryiko Cc: Brendan Higgins Cc: Masahiro Yamada Link: https://lore.kernel.org/bpf/20210126161320.24561-1-quentin@isovalent.com --- kernel/bpf/preload/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/preload/Makefile b/kernel/bpf/preload/Makefile index 23ee310b6eb49..1951332dd15f5 100644 --- a/kernel/bpf/preload/Makefile +++ b/kernel/bpf/preload/Makefile @@ -4,8 +4,11 @@ LIBBPF_SRCS = $(srctree)/tools/lib/bpf/ LIBBPF_A = $(obj)/libbpf.a LIBBPF_OUT = $(abspath $(obj)) +# Although not in use by libbpf's Makefile, set $(O) so that the "dummy" test +# in tools/scripts/Makefile.include always succeeds when building the kernel +# with $(O) pointing to a relative path, as in "make O=build bindeb-pkg". $(LIBBPF_A): - $(Q)$(MAKE) -C $(LIBBPF_SRCS) OUTPUT=$(LIBBPF_OUT)/ $(LIBBPF_OUT)/libbpf.a + $(Q)$(MAKE) -C $(LIBBPF_SRCS) O=$(LIBBPF_OUT)/ OUTPUT=$(LIBBPF_OUT)/ $(LIBBPF_OUT)/libbpf.a userccflags += -I $(srctree)/tools/include/ -I $(srctree)/tools/include/uapi \ -I $(srctree)/tools/lib/ -Wno-unused-result -- GitLab From 81a86e1bd8e7060ebba1718b284d54f1238e9bf9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 25 Jan 2021 07:09:49 -0800 Subject: [PATCH 0702/1084] iwlwifi: provide gso_type to GSO packets net/core/tso.c got recent support for USO, and this broke iwlfifi because the driver implemented a limited form of GSO. Providing ->gso_type allows for skb_is_gso_tcp() to provide a correct result. Fixes: 3d5b459ba0e3 ("net: tso: add UDP segmentation support") Signed-off-by: Eric Dumazet Reported-by: Ben Greear Tested-by: Ben Greear Cc: Luca Coelho Cc: Johannes Berg Link: https://bugzilla.kernel.org/show_bug.cgi?id=209913 Link: https://lore.kernel.org/r/20210125150949.619309-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index a983c215df310..3712adc3ccc25 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -773,6 +773,7 @@ iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes, next = skb_gso_segment(skb, netdev_flags); skb_shinfo(skb)->gso_size = mss; + skb_shinfo(skb)->gso_type = ipv4 ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6; if (WARN_ON_ONCE(IS_ERR(next))) return -EINVAL; else if (next) @@ -795,6 +796,8 @@ iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes, if (tcp_payload_len > mss) { skb_shinfo(tmp)->gso_size = mss; + skb_shinfo(tmp)->gso_type = ipv4 ? SKB_GSO_TCPV4 : + SKB_GSO_TCPV6; } else { if (qos) { u8 *qc; -- GitLab From 487c6ef81eb98d0a43cb08be91b1fcc9b4250626 Mon Sep 17 00:00:00 2001 From: Roi Dayan Date: Tue, 12 Jan 2021 14:04:29 +0200 Subject: [PATCH 0703/1084] net/mlx5: Fix memory leak on flow table creation error flow When we create the ft object we also init rhltable in ft->fgs_hash. So in error flow before kfree of ft we need to destroy that rhltable. Fixes: 693c6883bbc4 ("net/mlx5: Add hash table for flow groups in flow table") Signed-off-by: Roi Dayan Reviewed-by: Maor Dickman Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index b899539a07860..0fcee702b808b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1141,6 +1141,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa destroy_ft: root->cmds->destroy_flow_table(root, ft); free_ft: + rhltable_destroy(&ft->fgs_hash); kfree(ft); unlock_root: mutex_unlock(&root->chain_lock); -- GitLab From 1fe3e3166b35240615ab7f8276af2bbf2e51f559 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Tue, 12 Jan 2021 16:13:22 +0200 Subject: [PATCH 0704/1084] net/mlx5e: E-switch, Fix rate calculation for overflow rate_bytes_ps is a 64-bit field. It passed as 32-bit field to apply_police_params(). Due to this when police rate is higher than 4Gbps, 32-bit calculation ignores the carry. This results in incorrect rate configurationn the device. Fix it by performing 64-bit calculation. Fixes: fcb64c0f5640 ("net/mlx5: E-Switch, add ingress rate support") Signed-off-by: Parav Pandit Reviewed-by: Eli Cohen Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 4cdf834fa74af..661235027b476 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -67,6 +67,7 @@ #include "lib/geneve.h" #include "lib/fs_chains.h" #include "diag/en_tc_tracepoint.h" +#include #define nic_chains(priv) ((priv)->fs.tc.chains) #define MLX5_MH_ACT_SZ MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto) @@ -5007,13 +5008,13 @@ int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv, return err; } -static int apply_police_params(struct mlx5e_priv *priv, u32 rate, +static int apply_police_params(struct mlx5e_priv *priv, u64 rate, struct netlink_ext_ack *extack) { struct mlx5e_rep_priv *rpriv = priv->ppriv; struct mlx5_eswitch *esw; + u32 rate_mbps = 0; u16 vport_num; - u32 rate_mbps; int err; vport_num = rpriv->rep->vport; @@ -5030,7 +5031,11 @@ static int apply_police_params(struct mlx5e_priv *priv, u32 rate, * Moreover, if rate is non zero we choose to configure to a minimum of * 1 mbit/sec. */ - rate_mbps = rate ? max_t(u32, (rate * 8 + 500000) / 1000000, 1) : 0; + if (rate) { + rate = (rate * BITS_PER_BYTE) + 500000; + rate_mbps = max_t(u32, do_div(rate, 1000000), 1); + } + err = mlx5_esw_modify_vport_rate(esw, vport_num, rate_mbps); if (err) NL_SET_ERR_MSG_MOD(extack, "failed applying action to hardware"); -- GitLab From 258ed19f075fbc834fe5d69d8b54983fc11e0d4a Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Wed, 20 Jan 2021 20:58:30 -0800 Subject: [PATCH 0705/1084] net/mlx5e: free page before return Instead of directly return, goto the error handling label to free allocated page. Fixes: 5f29458b77d5 ("net/mlx5e: Support dump callback in TX reporter") Signed-off-by: Pan Bian Reviewed-by: Leon Romanovsky Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en/health.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/health.c b/drivers/net/ethernet/mellanox/mlx5/core/en/health.c index 718f8c0a4f6b7..84e501e057b4f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/health.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/health.c @@ -273,7 +273,7 @@ int mlx5e_health_rsc_fmsg_dump(struct mlx5e_priv *priv, struct mlx5_rsc_key *key err = devlink_fmsg_binary_pair_nest_start(fmsg, "data"); if (err) - return err; + goto free_page; cmd = mlx5_rsc_dump_cmd_create(mdev, key); if (IS_ERR(cmd)) { -- GitLab From 48470a90a42a64dd2f70743a149894a292b356e0 Mon Sep 17 00:00:00 2001 From: Maor Dickman Date: Tue, 19 Jan 2021 17:21:38 +0200 Subject: [PATCH 0706/1084] net/mlx5e: Reduce tc unsupported key print level "Unsupported key used:" appears in kernel log when flows with unsupported key are used, arp fields for example. OpenVSwitch was changed to match on arp fields by default that caused this warning to appear in kernel log for every arp rule, which can be a lot. Fix by lowering print level from warning to debug. Fixes: e3a2b7ed018e ("net/mlx5e: Support offload cls_flower with drop action") Signed-off-by: Maor Dickman Reviewed-by: Roi Dayan Reviewed-by: Saeed Mahameed Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 661235027b476..f4ce5e208e02b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -2270,8 +2270,8 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) | BIT(FLOW_DISSECTOR_KEY_MPLS))) { NL_SET_ERR_MSG_MOD(extack, "Unsupported key"); - netdev_warn(priv->netdev, "Unsupported key used: 0x%x\n", - dissector->used_keys); + netdev_dbg(priv->netdev, "Unsupported key used: 0x%x\n", + dissector->used_keys); return -EOPNOTSUPP; } -- GitLab From 45c9a30835d84009dfe711f5c8836720767c286e Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Wed, 25 Nov 2020 13:52:36 +0200 Subject: [PATCH 0707/1084] net/mlx5e: Fix IPSEC stats When IPSEC offload isn't active, the number of stats is not zero, but the strings are not filled, leading to exposing stats with empty names. Fix this by using the same condition for NUM_STATS and FILL_STRS. Fixes: 0aab3e1b04ae ("net/mlx5e: IPSec, Expose IPsec HW stat only for supporting HW") Signed-off-by: Maxim Mikityanskiy Reviewed-by: Raed Salem Reviewed-by: Tariq Toukan Signed-off-by: Saeed Mahameed --- .../net/ethernet/mellanox/mlx5/core/en_accel/ipsec_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_stats.c index 6c5c54bcd9be0..5cb936541b9e9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_stats.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_stats.c @@ -76,7 +76,7 @@ static const struct counter_desc mlx5e_ipsec_sw_stats_desc[] = { static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(ipsec_sw) { - return NUM_IPSEC_SW_COUNTERS; + return priv->ipsec ? NUM_IPSEC_SW_COUNTERS : 0; } static inline MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ipsec_sw) {} @@ -105,7 +105,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(ipsec_sw) static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(ipsec_hw) { - return (mlx5_fpga_ipsec_device_caps(priv->mdev)) ? NUM_IPSEC_HW_COUNTERS : 0; + return (priv->ipsec && mlx5_fpga_ipsec_device_caps(priv->mdev)) ? NUM_IPSEC_HW_COUNTERS : 0; } static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ipsec_hw) -- GitLab From 0aa128475d33d2d0095947eeab6b3e4d22dbd578 Mon Sep 17 00:00:00 2001 From: Daniel Jurgens Date: Fri, 22 Jan 2021 23:13:53 +0200 Subject: [PATCH 0708/1084] net/mlx5: Maintain separate page trees for ECPF and PF functions Pages for the host PF and ECPF were stored in the same tree, so the ECPF pages were being freed along with the host PF's when the host driver unloaded. Combine the function ID and ECPF flag to use as an index into the x-array containing the trees to get a different tree for the host PF and ECPF. Fixes: c6168161f693 ("net/mlx5: Add support for release all pages event") Signed-off-by: Daniel Jurgens Signed-off-by: Saeed Mahameed --- .../ethernet/mellanox/mlx5/core/pagealloc.c | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c index eb956ce904bc0..eaa8958e24d79 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c @@ -58,7 +58,7 @@ struct fw_page { struct rb_node rb_node; u64 addr; struct page *page; - u16 func_id; + u32 function; unsigned long bitmask; struct list_head list; unsigned free_count; @@ -74,12 +74,17 @@ enum { MLX5_NUM_4K_IN_PAGE = PAGE_SIZE / MLX5_ADAPTER_PAGE_SIZE, }; -static struct rb_root *page_root_per_func_id(struct mlx5_core_dev *dev, u16 func_id) +static u32 get_function(u16 func_id, bool ec_function) +{ + return func_id & (ec_function << 16); +} + +static struct rb_root *page_root_per_function(struct mlx5_core_dev *dev, u32 function) { struct rb_root *root; int err; - root = xa_load(&dev->priv.page_root_xa, func_id); + root = xa_load(&dev->priv.page_root_xa, function); if (root) return root; @@ -87,7 +92,7 @@ static struct rb_root *page_root_per_func_id(struct mlx5_core_dev *dev, u16 func if (!root) return ERR_PTR(-ENOMEM); - err = xa_insert(&dev->priv.page_root_xa, func_id, root, GFP_KERNEL); + err = xa_insert(&dev->priv.page_root_xa, function, root, GFP_KERNEL); if (err) { kfree(root); return ERR_PTR(err); @@ -98,7 +103,7 @@ static struct rb_root *page_root_per_func_id(struct mlx5_core_dev *dev, u16 func return root; } -static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u16 func_id) +static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u32 function) { struct rb_node *parent = NULL; struct rb_root *root; @@ -107,7 +112,7 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u struct fw_page *tfp; int i; - root = page_root_per_func_id(dev, func_id); + root = page_root_per_function(dev, function); if (IS_ERR(root)) return PTR_ERR(root); @@ -130,7 +135,7 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u nfp->addr = addr; nfp->page = page; - nfp->func_id = func_id; + nfp->function = function; nfp->free_count = MLX5_NUM_4K_IN_PAGE; for (i = 0; i < MLX5_NUM_4K_IN_PAGE; i++) set_bit(i, &nfp->bitmask); @@ -143,14 +148,14 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u } static struct fw_page *find_fw_page(struct mlx5_core_dev *dev, u64 addr, - u32 func_id) + u32 function) { struct fw_page *result = NULL; struct rb_root *root; struct rb_node *tmp; struct fw_page *tfp; - root = xa_load(&dev->priv.page_root_xa, func_id); + root = xa_load(&dev->priv.page_root_xa, function); if (WARN_ON_ONCE(!root)) return NULL; @@ -194,14 +199,14 @@ static int mlx5_cmd_query_pages(struct mlx5_core_dev *dev, u16 *func_id, return err; } -static int alloc_4k(struct mlx5_core_dev *dev, u64 *addr, u16 func_id) +static int alloc_4k(struct mlx5_core_dev *dev, u64 *addr, u32 function) { struct fw_page *fp = NULL; struct fw_page *iter; unsigned n; list_for_each_entry(iter, &dev->priv.free_list, list) { - if (iter->func_id != func_id) + if (iter->function != function) continue; fp = iter; } @@ -231,7 +236,7 @@ static void free_fwp(struct mlx5_core_dev *dev, struct fw_page *fwp, { struct rb_root *root; - root = xa_load(&dev->priv.page_root_xa, fwp->func_id); + root = xa_load(&dev->priv.page_root_xa, fwp->function); if (WARN_ON_ONCE(!root)) return; @@ -244,12 +249,12 @@ static void free_fwp(struct mlx5_core_dev *dev, struct fw_page *fwp, kfree(fwp); } -static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 func_id) +static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 function) { struct fw_page *fwp; int n; - fwp = find_fw_page(dev, addr & MLX5_U64_4K_PAGE_MASK, func_id); + fwp = find_fw_page(dev, addr & MLX5_U64_4K_PAGE_MASK, function); if (!fwp) { mlx5_core_warn_rl(dev, "page not found\n"); return; @@ -263,7 +268,7 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 func_id) list_add(&fwp->list, &dev->priv.free_list); } -static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id) +static int alloc_system_page(struct mlx5_core_dev *dev, u32 function) { struct device *device = mlx5_core_dma_dev(dev); int nid = dev_to_node(device); @@ -291,7 +296,7 @@ static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id) goto map; } - err = insert_page(dev, addr, page, func_id); + err = insert_page(dev, addr, page, function); if (err) { mlx5_core_err(dev, "failed to track allocated page\n"); dma_unmap_page(device, addr, PAGE_SIZE, DMA_BIDIRECTIONAL); @@ -328,6 +333,7 @@ static void page_notify_fail(struct mlx5_core_dev *dev, u16 func_id, static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, int notify_fail, bool ec_function) { + u32 function = get_function(func_id, ec_function); u32 out[MLX5_ST_SZ_DW(manage_pages_out)] = {0}; int inlen = MLX5_ST_SZ_BYTES(manage_pages_in); u64 addr; @@ -345,10 +351,10 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, for (i = 0; i < npages; i++) { retry: - err = alloc_4k(dev, &addr, func_id); + err = alloc_4k(dev, &addr, function); if (err) { if (err == -ENOMEM) - err = alloc_system_page(dev, func_id); + err = alloc_system_page(dev, function); if (err) goto out_4k; @@ -384,7 +390,7 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, out_4k: for (i--; i >= 0; i--) - free_4k(dev, MLX5_GET64(manage_pages_in, in, pas[i]), func_id); + free_4k(dev, MLX5_GET64(manage_pages_in, in, pas[i]), function); out_free: kvfree(in); if (notify_fail) @@ -392,14 +398,15 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, return err; } -static void release_all_pages(struct mlx5_core_dev *dev, u32 func_id, +static void release_all_pages(struct mlx5_core_dev *dev, u16 func_id, bool ec_function) { + u32 function = get_function(func_id, ec_function); struct rb_root *root; struct rb_node *p; int npages = 0; - root = xa_load(&dev->priv.page_root_xa, func_id); + root = xa_load(&dev->priv.page_root_xa, function); if (WARN_ON_ONCE(!root)) return; @@ -446,6 +453,7 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev, struct rb_root *root; struct fw_page *fwp; struct rb_node *p; + bool ec_function; u32 func_id; u32 npages; u32 i = 0; @@ -456,8 +464,9 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev, /* No hard feelings, we want our pages back! */ npages = MLX5_GET(manage_pages_in, in, input_num_entries); func_id = MLX5_GET(manage_pages_in, in, function_id); + ec_function = MLX5_GET(manage_pages_in, in, embedded_cpu_function); - root = xa_load(&dev->priv.page_root_xa, func_id); + root = xa_load(&dev->priv.page_root_xa, get_function(func_id, ec_function)); if (WARN_ON_ONCE(!root)) return -EEXIST; @@ -473,9 +482,10 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev, return 0; } -static int reclaim_pages(struct mlx5_core_dev *dev, u32 func_id, int npages, +static int reclaim_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, int *nclaimed, bool ec_function) { + u32 function = get_function(func_id, ec_function); int outlen = MLX5_ST_SZ_BYTES(manage_pages_out); u32 in[MLX5_ST_SZ_DW(manage_pages_in)] = {}; int num_claimed; @@ -514,7 +524,7 @@ static int reclaim_pages(struct mlx5_core_dev *dev, u32 func_id, int npages, } for (i = 0; i < num_claimed; i++) - free_4k(dev, MLX5_GET64(manage_pages_out, out, pas[i]), func_id); + free_4k(dev, MLX5_GET64(manage_pages_out, out, pas[i]), function); if (nclaimed) *nclaimed = num_claimed; -- GitLab From 156878d0e697187c7d207ee6c22afe50b7f3678c Mon Sep 17 00:00:00 2001 From: Maor Dickman Date: Sun, 24 Jan 2021 17:21:25 +0200 Subject: [PATCH 0709/1084] net/mlx5e: Disable hw-tc-offload when MLX5_CLS_ACT config is disabled The cited commit introduce new CONFIG_MLX5_CLS_ACT kconfig variable to control compilation of TC hardware offloads implementation. When this configuration is disabled the driver is still wrongly reports in ethtool that hw-tc-offload is supported. Fixed by reporting hw-tc-offload is supported only when CONFIG_MLX5_CLS_ACT is enabled. Fixes: d956873f908c ("net/mlx5e: Introduce kconfig var for TC support") Signed-off-by: Maor Dickman Reviewed-by: Vlad Buslov Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 6a852b4901aa0..300e0e9f96b60 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -5027,7 +5027,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) FT_CAP(modify_root) && FT_CAP(identified_miss_table_mode) && FT_CAP(flow_table_modify)) { -#ifdef CONFIG_MLX5_ESWITCH +#if IS_ENABLED(CONFIG_MLX5_CLS_ACT) netdev->hw_features |= NETIF_F_HW_TC; #endif #ifdef CONFIG_MLX5_EN_ARFS diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 989c70c1eda37..f0ceae65f6cfa 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -737,7 +737,9 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev) netdev->features |= NETIF_F_NETNS_LOCAL; +#if IS_ENABLED(CONFIG_MLX5_CLS_ACT) netdev->hw_features |= NETIF_F_HW_TC; +#endif netdev->hw_features |= NETIF_F_SG; netdev->hw_features |= NETIF_F_IP_CSUM; netdev->hw_features |= NETIF_F_IPV6_CSUM; -- GitLab From 89e394675818bde8e30e135611c506455fa03fb7 Mon Sep 17 00:00:00 2001 From: Paul Blakey Date: Thu, 21 Jan 2021 10:06:45 +0200 Subject: [PATCH 0710/1084] net/mlx5e: Fix CT rule + encap slow path offload and deletion Currently, if a neighbour isn't valid when offloading tunnel encap rules, we offload the original match and replace the original action with "goto slow path" action. For this we use a temporary flow attribute based on the original flow attribute and then change the action. Flow flags, which among those is the CT flag, are still shared for the slow path rule offload, so we end up parsing this flow as a CT + goto slow path rule. Besides being unnecessary, CT action offload saves extra information in the passed flow attribute, such as created ct_flow and mod_hdr, which is lost onces the temporary flow attribute is freed. When a neigh is updated and is valid, we offload the original CT rule with original CT action, which again creates a ct_flow and mod_hdr and saves it in the flow's original attribute. Then we delete the slow path rule with a temporary flow attribute based on original updated flow attribute, and we free the relevant ct_flow and mod_hdr. Then when tc deletes this flow, we try to free the ct_flow and mod_hdr on the flow's attribute again. To fix the issue, skip all furture proccesing (CT/Sample/Split rules) in offload/unoffload of slow path rules. Call trace: [ 758.850525] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000218 [ 758.952987] Internal error: Oops: 96000005 [#1] PREEMPT SMP [ 758.964170] Modules linked in: act_csum(E) act_pedit(E) act_tunnel_key(E) act_ct(E) nf_flow_table(E) xt_nat(E) ip6table_filter(E) ip6table_nat(E) xt_comment(E) ip6_tables(E) xt_conntrack(E) xt_MASQUERADE(E) nf_conntrack_netlink(E) xt_addrtype(E) iptable_filter(E) iptable_nat(E) bpfilter(E) br_netfilter(E) bridge(E) stp(E) llc(E) xfrm_user(E) overlay(E) act_mirred(E) act_skbedit(E) rdma_ucm(OE) rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) ib_umad(OE) esp6_offload(E) esp6(E) esp4_offload(E) esp4(E) xfrm_algo(E) mlx5_ib(OE) ib_uverbs(OE) geneve(E) ip6_udp_tunnel(E) udp_tunnel(E) nfnetlink_cttimeout(E) nfnetlink(E) mlx5_core(OE) act_gact(E) cls_flower(E) sch_ingress(E) openvswitch(E) nsh(E) nf_conncount(E) nf_nat(E) mlxfw(OE) psample(E) nf_conntrack(E) nf_defrag_ipv4(E) vfio_mdev(E) mdev(E) ib_core(OE) mlx_compat(OE) crct10dif_ce(E) uio_pdrv_genirq(E) uio(E) i2c_mlx(E) mlxbf_pmc(E) sbsa_gwdt(E) mlxbf_gige(E) gpio_mlxbf2(E) mlxbf_pka(E) mlx_trio(E) mlx_bootctl(E) bluefield_edac(E) knem(O) [ 758.964225] ip_tables(E) mlxbf_tmfifo(E) ipv6(E) crc_ccitt(E) nf_defrag_ipv6(E) [ 759.154186] CPU: 5 PID: 122 Comm: kworker/u16:1 Tainted: G OE 5.4.60-mlnx.52.gde81e85 #1 [ 759.172870] Hardware name: https://www.mellanox.com BlueField SoC/BlueField SoC, BIOS BlueField:3.5.0-2-gc1b5d64 Jan 4 2021 [ 759.195466] Workqueue: mlx5e mlx5e_rep_neigh_update [mlx5_core] [ 759.207344] pstate: a0000005 (NzCv daif -PAN -UAO) [ 759.217003] pc : mlx5_del_flow_rules+0x5c/0x160 [mlx5_core] [ 759.228229] lr : mlx5_del_flow_rules+0x34/0x160 [mlx5_core] [ 759.405858] Call trace: [ 759.410804] mlx5_del_flow_rules+0x5c/0x160 [mlx5_core] [ 759.421337] __mlx5_eswitch_del_rule.isra.43+0x5c/0x1c8 [mlx5_core] [ 759.433963] mlx5_eswitch_del_offloaded_rule_ct+0x34/0x40 [mlx5_core] [ 759.446942] mlx5_tc_rule_delete_ct+0x68/0x74 [mlx5_core] [ 759.457821] mlx5_tc_ct_delete_flow+0x160/0x21c [mlx5_core] [ 759.469051] mlx5e_tc_unoffload_fdb_rules+0x158/0x168 [mlx5_core] [ 759.481325] mlx5e_tc_encap_flows_del+0x140/0x26c [mlx5_core] [ 759.492901] mlx5e_rep_update_flows+0x11c/0x1ec [mlx5_core] [ 759.504127] mlx5e_rep_neigh_update+0x160/0x200 [mlx5_core] [ 759.515314] process_one_work+0x178/0x400 [ 759.523350] worker_thread+0x58/0x3e8 [ 759.530685] kthread+0x100/0x12c [ 759.537152] ret_from_fork+0x10/0x18 [ 759.544320] Code: 97ffef55 51000673 3100067f 54ffff41 (b9421ab3) [ 759.556548] ---[ end trace fab818bb1085832d ]--- Fixes: 4c3844d9e97e ("net/mlx5e: CT: Introduce connection tracking") Signed-off-by: Paul Blakey Reviewed-by: Roi Dayan Reviewed-by: Vlad Buslov Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index f4ce5e208e02b..dd0bfbacad474 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1163,6 +1163,9 @@ mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw, struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts; struct mlx5_flow_handle *rule; + if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) + return mlx5_eswitch_add_offloaded_rule(esw, spec, attr); + if (flow_flag_test(flow, CT)) { mod_hdr_acts = &attr->parse_attr->mod_hdr_acts; @@ -1193,6 +1196,9 @@ mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw, { flow_flag_clear(flow, OFFLOADED); + if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) + goto offload_rule_0; + if (flow_flag_test(flow, CT)) { mlx5_tc_ct_delete_flow(get_ct_priv(flow->priv), flow, attr); return; @@ -1201,6 +1207,7 @@ mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw, if (attr->esw_attr->split_count) mlx5_eswitch_del_fwd_rule(esw, flow->rule[1], attr); +offload_rule_0: mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], attr); } -- GitLab From 57ac4a31c48377a3e675b2a731ceacbefefcd34d Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Fri, 11 Dec 2020 12:56:56 +0200 Subject: [PATCH 0711/1084] net/mlx5e: Correctly handle changing the number of queues when the interface is down This commit addresses two issues related to changing the number of queues when the channels are closed: 1. Missing call to mlx5e_num_channels_changed to update real_num_tx_queues when the number of TCs is changed. 2. When mlx5e_num_channels_changed returns an error, the channel parameters must be reverted. Two Fixes: tags correspond to the first commits where these two issues were introduced. Fixes: 3909a12e7913 ("net/mlx5e: Fix configuration of XPS cpumasks and netdev queues in corner cases") Fixes: fa3748775b92 ("net/mlx5e: Handle errors from netif_set_real_num_{tx,rx}_queues") Signed-off-by: Maxim Mikityanskiy Reviewed-by: Tariq Toukan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 8 +++++++- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 2d37742a888c1..302001d6661ea 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -447,12 +447,18 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv, goto out; } - new_channels.params = priv->channels.params; + new_channels.params = *cur_params; new_channels.params.num_channels = count; if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { + struct mlx5e_params old_params; + + old_params = *cur_params; *cur_params = new_channels.params; err = mlx5e_num_channels_changed(priv); + if (err) + *cur_params = old_params; + goto out; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 300e0e9f96b60..ac76d32bad7de 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3614,7 +3614,14 @@ static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv, new_channels.params.num_tc = tc ? tc : 1; if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { + struct mlx5e_params old_params; + + old_params = priv->channels.params; priv->channels.params = new_channels.params; + err = mlx5e_num_channels_changed(priv); + if (err) + priv->channels.params = old_params; + goto out; } -- GitLab From 912c9b5fcca1ab65b806c19dd3b3cb12d73c6fe2 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Thu, 14 Jan 2021 12:34:01 +0200 Subject: [PATCH 0712/1084] net/mlx5e: Revert parameters on errors when changing trust state without reset Trust state may be changed without recreating the channels. It happens when the channels are closed, and when channel parameters (min inline mode) stay the same after changing the trust state. Changing the trust state is a hardware command that may fail. The current code didn't restore the channel parameters to their old values if an error happened and the channels were closed. This commit adds handling for this case. Fixes: 6e0504c69811 ("net/mlx5e: Change inline mode correctly when changing trust state") Signed-off-by: Maxim Mikityanskiy Reviewed-by: Tariq Toukan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index d20243d6a0326..f23c67575073a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c @@ -1151,6 +1151,7 @@ static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state) { struct mlx5e_channels new_channels = {}; bool reset_channels = true; + bool opened; int err = 0; mutex_lock(&priv->state_lock); @@ -1159,22 +1160,24 @@ static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state) mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &new_channels.params, trust_state); - if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { - priv->channels.params = new_channels.params; + opened = test_bit(MLX5E_STATE_OPENED, &priv->state); + if (!opened) reset_channels = false; - } /* Skip if tx_min_inline is the same */ if (new_channels.params.tx_min_inline_mode == priv->channels.params.tx_min_inline_mode) reset_channels = false; - if (reset_channels) + if (reset_channels) { err = mlx5e_safe_switch_channels(priv, &new_channels, mlx5e_update_trust_state_hw, &trust_state); - else + } else { err = mlx5e_update_trust_state_hw(priv, &trust_state); + if (!err && !opened) + priv->channels.params = new_channels.params; + } mutex_unlock(&priv->state_lock); -- GitLab From 8355060f5ec381abda77659f91f56302203df535 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Fri, 11 Dec 2020 16:05:01 +0200 Subject: [PATCH 0713/1084] net/mlx5e: Revert parameters on errors when changing MTU and LRO state without reset Sometimes, channel params are changed without recreating the channels. It happens in two basic cases: when the channels are closed, and when the parameter being changed doesn't affect how channels are configured. Such changes invoke a hardware command that might fail. The whole operation should be reverted in such cases, but the code that restores the parameters' values in the driver was missing. This commit adds this handling. Fixes: 2e20a151205b ("net/mlx5e: Fail safe mtu and lro setting") Signed-off-by: Maxim Mikityanskiy Reviewed-by: Tariq Toukan Signed-off-by: Saeed Mahameed --- .../net/ethernet/mellanox/mlx5/core/en_main.c | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index ac76d32bad7de..a9d824a9cb05a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3764,7 +3764,7 @@ static int set_feature_lro(struct net_device *netdev, bool enable) struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5_core_dev *mdev = priv->mdev; struct mlx5e_channels new_channels = {}; - struct mlx5e_params *old_params; + struct mlx5e_params *cur_params; int err = 0; bool reset; @@ -3777,8 +3777,8 @@ static int set_feature_lro(struct net_device *netdev, bool enable) goto out; } - old_params = &priv->channels.params; - if (enable && !MLX5E_GET_PFLAG(old_params, MLX5E_PFLAG_RX_STRIDING_RQ)) { + cur_params = &priv->channels.params; + if (enable && !MLX5E_GET_PFLAG(cur_params, MLX5E_PFLAG_RX_STRIDING_RQ)) { netdev_warn(netdev, "can't set LRO with legacy RQ\n"); err = -EINVAL; goto out; @@ -3786,18 +3786,23 @@ static int set_feature_lro(struct net_device *netdev, bool enable) reset = test_bit(MLX5E_STATE_OPENED, &priv->state); - new_channels.params = *old_params; + new_channels.params = *cur_params; new_channels.params.lro_en = enable; - if (old_params->rq_wq_type != MLX5_WQ_TYPE_CYCLIC) { - if (mlx5e_rx_mpwqe_is_linear_skb(mdev, old_params, NULL) == + if (cur_params->rq_wq_type != MLX5_WQ_TYPE_CYCLIC) { + if (mlx5e_rx_mpwqe_is_linear_skb(mdev, cur_params, NULL) == mlx5e_rx_mpwqe_is_linear_skb(mdev, &new_channels.params, NULL)) reset = false; } if (!reset) { - *old_params = new_channels.params; + struct mlx5e_params old_params; + + old_params = *cur_params; + *cur_params = new_channels.params; err = mlx5e_modify_tirs_lro(priv); + if (err) + *cur_params = old_params; goto out; } @@ -4074,9 +4079,16 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu, } if (!reset) { + unsigned int old_mtu = params->sw_mtu; + params->sw_mtu = new_mtu; - if (preactivate) - preactivate(priv, NULL); + if (preactivate) { + err = preactivate(priv, NULL); + if (err) { + params->sw_mtu = old_mtu; + goto out; + } + } netdev->mtu = params->sw_mtu; goto out; } -- GitLab From e2194a1744e8594e82a861687808c1adca419b85 Mon Sep 17 00:00:00 2001 From: Paul Blakey Date: Mon, 25 Jan 2021 17:31:26 +0200 Subject: [PATCH 0714/1084] net/mlx5: CT: Fix incorrect removal of tuple_nat_node from nat rhashtable If a non nat tuple entry is inserted just to the regular tuples rhashtable (ct_tuples_ht) and not to natted tuples rhashtable (ct_nat_tuples_ht). Commit bc562be9674b ("net/mlx5e: CT: Save ct entries tuples in hashtables") mixed up the return labels and names sot that on cleanup or failure we still try to remove for the natted tuples rhashtable. Fix that by correctly checking if a natted tuples insertion before removing it. While here make it more readable. Fixes: bc562be9674b ("net/mlx5e: CT: Save ct entries tuples in hashtables") Reviewed-by: Roi Dayan Signed-off-by: Paul Blakey Signed-off-by: Saeed Mahameed --- .../ethernet/mellanox/mlx5/core/en/tc_ct.c | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c index 072363e73f1ce..6bc6b48a56dc7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c @@ -167,6 +167,12 @@ static const struct rhashtable_params tuples_nat_ht_params = { .min_size = 16 * 1024, }; +static bool +mlx5_tc_ct_entry_has_nat(struct mlx5_ct_entry *entry) +{ + return !!(entry->tuple_nat_node.next); +} + static int mlx5_tc_ct_rule_to_tuple(struct mlx5_ct_tuple *tuple, struct flow_rule *rule) { @@ -911,13 +917,13 @@ mlx5_tc_ct_block_flow_offload_add(struct mlx5_ct_ft *ft, err_insert: mlx5_tc_ct_entry_del_rules(ct_priv, entry); err_rules: - rhashtable_remove_fast(&ct_priv->ct_tuples_nat_ht, - &entry->tuple_nat_node, tuples_nat_ht_params); + if (mlx5_tc_ct_entry_has_nat(entry)) + rhashtable_remove_fast(&ct_priv->ct_tuples_nat_ht, + &entry->tuple_nat_node, tuples_nat_ht_params); err_tuple_nat: - if (entry->tuple_node.next) - rhashtable_remove_fast(&ct_priv->ct_tuples_ht, - &entry->tuple_node, - tuples_ht_params); + rhashtable_remove_fast(&ct_priv->ct_tuples_ht, + &entry->tuple_node, + tuples_ht_params); err_tuple: err_set: kfree(entry); @@ -932,7 +938,7 @@ mlx5_tc_ct_del_ft_entry(struct mlx5_tc_ct_priv *ct_priv, { mlx5_tc_ct_entry_del_rules(ct_priv, entry); mutex_lock(&ct_priv->shared_counter_lock); - if (entry->tuple_node.next) + if (mlx5_tc_ct_entry_has_nat(entry)) rhashtable_remove_fast(&ct_priv->ct_tuples_nat_ht, &entry->tuple_nat_node, tuples_nat_ht_params); -- GitLab From 5cfeb5626d4acef8df993eceec442f7b54943976 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 22 Jan 2021 09:32:20 -0800 Subject: [PATCH 0715/1084] MAINTAINERS: add David Ahern to IPv4/IPv6 maintainers David has been the de-facto maintainer for much of the IP code for the last couple of years, let's make it official. Link: https://lore.kernel.org/r/20210122173220.3579491-1-kuba@kernel.org Signed-off-by: Jakub Kicinski --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 705776b31c8de..1a5facde5a908 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12413,6 +12413,7 @@ F: tools/testing/selftests/net/ipsec.c NETWORKING [IPv4/IPv6] M: "David S. Miller" M: Hideaki YOSHIFUJI +M: David Ahern L: netdev@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git -- GitLab From f0947d0d21b219e03940b9be6628a43445c0de7a Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Mon, 25 Jan 2021 08:44:16 +0100 Subject: [PATCH 0716/1084] team: protect features update by RCU to avoid deadlock Function __team_compute_features() is protected by team->lock mutex when it is called from team_compute_features() used when features of an underlying device is changed. This causes a deadlock when NETDEV_FEAT_CHANGE notifier for underlying device is fired due to change propagated from team driver (e.g. MTU change). It's because callbacks like team_change_mtu() or team_vlan_rx_{add,del}_vid() protect their port list traversal by team->lock mutex. Example (r8169 case where this driver disables TSO for certain MTU values): ... [ 6391.348202] __mutex_lock.isra.6+0x2d0/0x4a0 [ 6391.358602] team_device_event+0x9d/0x160 [team] [ 6391.363756] notifier_call_chain+0x47/0x70 [ 6391.368329] netdev_update_features+0x56/0x60 [ 6391.373207] rtl8169_change_mtu+0x14/0x50 [r8169] [ 6391.378457] dev_set_mtu_ext+0xe1/0x1d0 [ 6391.387022] dev_set_mtu+0x52/0x90 [ 6391.390820] team_change_mtu+0x64/0xf0 [team] [ 6391.395683] dev_set_mtu_ext+0xe1/0x1d0 [ 6391.399963] do_setlink+0x231/0xf50 ... In fact team_compute_features() called from team_device_event() does not need to be protected by team->lock mutex and rcu_read_lock() is sufficient there for port list traversal. Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device") Cc: Saeed Mahameed Signed-off-by: Ivan Vecera Reviewed-by: Cong Wang Reviewed-by: Jiri Pirko Link: https://lore.kernel.org/r/20210125074416.4056484-1-ivecera@redhat.com Signed-off-by: Jakub Kicinski --- drivers/net/team/team.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index c19dac21c468b..dd7917cab2b12 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -992,7 +992,8 @@ static void __team_compute_features(struct team *team) unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM; - list_for_each_entry(port, &team->port_list, list) { + rcu_read_lock(); + list_for_each_entry_rcu(port, &team->port_list, list) { vlan_features = netdev_increment_features(vlan_features, port->dev->vlan_features, TEAM_VLAN_FEATURES); @@ -1006,6 +1007,7 @@ static void __team_compute_features(struct team *team) if (port->dev->hard_header_len > max_hard_header_len) max_hard_header_len = port->dev->hard_header_len; } + rcu_read_unlock(); team->dev->vlan_features = vlan_features; team->dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL | @@ -1020,9 +1022,7 @@ static void __team_compute_features(struct team *team) static void team_compute_features(struct team *team) { - mutex_lock(&team->lock); __team_compute_features(team); - mutex_unlock(&team->lock); netdev_change_features(team->dev); } -- GitLab From 30596ae0547dbda469d31a2678d9072fb0a3fa27 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 25 Jan 2021 20:39:05 -0600 Subject: [PATCH 0717/1084] ARM: zImage: atags_to_fdt: Fix node names on added root nodes Commit 7536c7e03e74 ("of/fdt: Remove redundant kbasename function call") exposed a bug creating DT nodes in the ATAGS to DT fixup code. Non-existent nodes would mistaken get created with a leading '/'. The problem was fdt_path_offset() takes a full path while creating a node with fdt_add_subnode() takes just the basename. Since this we only add root child nodes, we can just skip over the '/'. Fixes: 7536c7e03e74 ("of/fdt: Remove redundant kbasename function call") Reported-by: Chris Packham Cc: Qi Zheng Cc: Russell King Signed-off-by: Rob Herring Tested-by: Chris Packham Link: https://lore.kernel.org/r/20210126023905.1631161-1-robh@kernel.org --- arch/arm/boot/compressed/atags_to_fdt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c index 8452753efebe5..31927d2fe2972 100644 --- a/arch/arm/boot/compressed/atags_to_fdt.c +++ b/arch/arm/boot/compressed/atags_to_fdt.c @@ -15,7 +15,8 @@ static int node_offset(void *fdt, const char *node_path) { int offset = fdt_path_offset(fdt, node_path); if (offset == -FDT_ERR_NOTFOUND) - offset = fdt_add_subnode(fdt, 0, node_path); + /* Add the node to root if not found, dropping the leading '/' */ + offset = fdt_add_subnode(fdt, 0, node_path + 1); return offset; } -- GitLab From b491e6a7391e3ecdebdd7a097550195cc878924a Mon Sep 17 00:00:00 2001 From: Xie He Date: Mon, 25 Jan 2021 20:09:39 -0800 Subject: [PATCH 0718/1084] net: lapb: Add locking to the lapb module In the lapb module, the timers may run concurrently with other code in this module, and there is currently no locking to prevent the code from racing on "struct lapb_cb". This patch adds locking to prevent racing. 1. Add "spinlock_t lock" to "struct lapb_cb"; Add "spin_lock_bh" and "spin_unlock_bh" to APIs, timer functions and notifier functions. 2. Add "bool t1timer_stop, t2timer_stop" to "struct lapb_cb" to make us able to ask running timers to abort; Modify "lapb_stop_t1timer" and "lapb_stop_t2timer" to make them able to abort running timers; Modify "lapb_t2timer_expiry" and "lapb_t1timer_expiry" to make them abort after they are stopped by "lapb_stop_t1timer", "lapb_stop_t2timer", and "lapb_start_t1timer", "lapb_start_t2timer". 3. Let lapb_unregister wait for other API functions and running timers to stop. 4. The lapb_device_event function calls lapb_disconnect_request. In order to avoid trying to hold the lock twice, add a new function named "__lapb_disconnect_request" which assumes the lock is held, and make it called by lapb_disconnect_request and lapb_device_event. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: Martin Schiller Signed-off-by: Xie He Link: https://lore.kernel.org/r/20210126040939.69995-1-xie.he.0141@gmail.com Signed-off-by: Jakub Kicinski --- include/net/lapb.h | 2 ++ net/lapb/lapb_iface.c | 70 +++++++++++++++++++++++++++++++++---------- net/lapb/lapb_timer.c | 30 ++++++++++++++++--- 3 files changed, 82 insertions(+), 20 deletions(-) diff --git a/include/net/lapb.h b/include/net/lapb.h index ccc3d1f020b0c..eee73442a1ba1 100644 --- a/include/net/lapb.h +++ b/include/net/lapb.h @@ -92,6 +92,7 @@ struct lapb_cb { unsigned short n2, n2count; unsigned short t1, t2; struct timer_list t1timer, t2timer; + bool t1timer_stop, t2timer_stop; /* Internal control information */ struct sk_buff_head write_queue; @@ -103,6 +104,7 @@ struct lapb_cb { struct lapb_frame frmr_data; unsigned char frmr_type; + spinlock_t lock; refcount_t refcnt; }; diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c index 40961889e9c01..0511bbe4af7b4 100644 --- a/net/lapb/lapb_iface.c +++ b/net/lapb/lapb_iface.c @@ -122,6 +122,8 @@ static struct lapb_cb *lapb_create_cb(void) timer_setup(&lapb->t1timer, NULL, 0); timer_setup(&lapb->t2timer, NULL, 0); + lapb->t1timer_stop = true; + lapb->t2timer_stop = true; lapb->t1 = LAPB_DEFAULT_T1; lapb->t2 = LAPB_DEFAULT_T2; @@ -129,6 +131,8 @@ static struct lapb_cb *lapb_create_cb(void) lapb->mode = LAPB_DEFAULT_MODE; lapb->window = LAPB_DEFAULT_WINDOW; lapb->state = LAPB_STATE_0; + + spin_lock_init(&lapb->lock); refcount_set(&lapb->refcnt, 1); out: return lapb; @@ -178,11 +182,23 @@ int lapb_unregister(struct net_device *dev) goto out; lapb_put(lapb); + /* Wait for other refs to "lapb" to drop */ + while (refcount_read(&lapb->refcnt) > 2) + usleep_range(1, 10); + + spin_lock_bh(&lapb->lock); + lapb_stop_t1timer(lapb); lapb_stop_t2timer(lapb); lapb_clear_queues(lapb); + spin_unlock_bh(&lapb->lock); + + /* Wait for running timers to stop */ + del_timer_sync(&lapb->t1timer); + del_timer_sync(&lapb->t2timer); + __lapb_remove_cb(lapb); lapb_put(lapb); @@ -201,6 +217,8 @@ int lapb_getparms(struct net_device *dev, struct lapb_parms_struct *parms) if (!lapb) goto out; + spin_lock_bh(&lapb->lock); + parms->t1 = lapb->t1 / HZ; parms->t2 = lapb->t2 / HZ; parms->n2 = lapb->n2; @@ -219,6 +237,7 @@ int lapb_getparms(struct net_device *dev, struct lapb_parms_struct *parms) else parms->t2timer = (lapb->t2timer.expires - jiffies) / HZ; + spin_unlock_bh(&lapb->lock); lapb_put(lapb); rc = LAPB_OK; out: @@ -234,6 +253,8 @@ int lapb_setparms(struct net_device *dev, struct lapb_parms_struct *parms) if (!lapb) goto out; + spin_lock_bh(&lapb->lock); + rc = LAPB_INVALUE; if (parms->t1 < 1 || parms->t2 < 1 || parms->n2 < 1) goto out_put; @@ -256,6 +277,7 @@ int lapb_setparms(struct net_device *dev, struct lapb_parms_struct *parms) rc = LAPB_OK; out_put: + spin_unlock_bh(&lapb->lock); lapb_put(lapb); out: return rc; @@ -270,6 +292,8 @@ int lapb_connect_request(struct net_device *dev) if (!lapb) goto out; + spin_lock_bh(&lapb->lock); + rc = LAPB_OK; if (lapb->state == LAPB_STATE_1) goto out_put; @@ -285,24 +309,18 @@ int lapb_connect_request(struct net_device *dev) rc = LAPB_OK; out_put: + spin_unlock_bh(&lapb->lock); lapb_put(lapb); out: return rc; } EXPORT_SYMBOL(lapb_connect_request); -int lapb_disconnect_request(struct net_device *dev) +static int __lapb_disconnect_request(struct lapb_cb *lapb) { - struct lapb_cb *lapb = lapb_devtostruct(dev); - int rc = LAPB_BADTOKEN; - - if (!lapb) - goto out; - switch (lapb->state) { case LAPB_STATE_0: - rc = LAPB_NOTCONNECTED; - goto out_put; + return LAPB_NOTCONNECTED; case LAPB_STATE_1: lapb_dbg(1, "(%p) S1 TX DISC(1)\n", lapb->dev); @@ -310,12 +328,10 @@ int lapb_disconnect_request(struct net_device *dev) lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND); lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); - rc = LAPB_NOTCONNECTED; - goto out_put; + return LAPB_NOTCONNECTED; case LAPB_STATE_2: - rc = LAPB_OK; - goto out_put; + return LAPB_OK; } lapb_clear_queues(lapb); @@ -328,8 +344,22 @@ int lapb_disconnect_request(struct net_device *dev) lapb_dbg(1, "(%p) S3 DISC(1)\n", lapb->dev); lapb_dbg(0, "(%p) S3 -> S2\n", lapb->dev); - rc = LAPB_OK; -out_put: + return LAPB_OK; +} + +int lapb_disconnect_request(struct net_device *dev) +{ + struct lapb_cb *lapb = lapb_devtostruct(dev); + int rc = LAPB_BADTOKEN; + + if (!lapb) + goto out; + + spin_lock_bh(&lapb->lock); + + rc = __lapb_disconnect_request(lapb); + + spin_unlock_bh(&lapb->lock); lapb_put(lapb); out: return rc; @@ -344,6 +374,8 @@ int lapb_data_request(struct net_device *dev, struct sk_buff *skb) if (!lapb) goto out; + spin_lock_bh(&lapb->lock); + rc = LAPB_NOTCONNECTED; if (lapb->state != LAPB_STATE_3 && lapb->state != LAPB_STATE_4) goto out_put; @@ -352,6 +384,7 @@ int lapb_data_request(struct net_device *dev, struct sk_buff *skb) lapb_kick(lapb); rc = LAPB_OK; out_put: + spin_unlock_bh(&lapb->lock); lapb_put(lapb); out: return rc; @@ -364,7 +397,9 @@ int lapb_data_received(struct net_device *dev, struct sk_buff *skb) int rc = LAPB_BADTOKEN; if (lapb) { + spin_lock_bh(&lapb->lock); lapb_data_input(lapb, skb); + spin_unlock_bh(&lapb->lock); lapb_put(lapb); rc = LAPB_OK; } @@ -435,6 +470,8 @@ static int lapb_device_event(struct notifier_block *this, unsigned long event, if (!lapb) return NOTIFY_DONE; + spin_lock_bh(&lapb->lock); + switch (event) { case NETDEV_UP: lapb_dbg(0, "(%p) Interface up: %s\n", dev, dev->name); @@ -454,7 +491,7 @@ static int lapb_device_event(struct notifier_block *this, unsigned long event, break; case NETDEV_GOING_DOWN: if (netif_carrier_ok(dev)) - lapb_disconnect_request(dev); + __lapb_disconnect_request(lapb); break; case NETDEV_DOWN: lapb_dbg(0, "(%p) Interface down: %s\n", dev, dev->name); @@ -489,6 +526,7 @@ static int lapb_device_event(struct notifier_block *this, unsigned long event, break; } + spin_unlock_bh(&lapb->lock); lapb_put(lapb); return NOTIFY_DONE; } diff --git a/net/lapb/lapb_timer.c b/net/lapb/lapb_timer.c index baa247fe4ed05..0230b272b7d1d 100644 --- a/net/lapb/lapb_timer.c +++ b/net/lapb/lapb_timer.c @@ -40,6 +40,7 @@ void lapb_start_t1timer(struct lapb_cb *lapb) lapb->t1timer.function = lapb_t1timer_expiry; lapb->t1timer.expires = jiffies + lapb->t1; + lapb->t1timer_stop = false; add_timer(&lapb->t1timer); } @@ -50,16 +51,19 @@ void lapb_start_t2timer(struct lapb_cb *lapb) lapb->t2timer.function = lapb_t2timer_expiry; lapb->t2timer.expires = jiffies + lapb->t2; + lapb->t2timer_stop = false; add_timer(&lapb->t2timer); } void lapb_stop_t1timer(struct lapb_cb *lapb) { + lapb->t1timer_stop = true; del_timer(&lapb->t1timer); } void lapb_stop_t2timer(struct lapb_cb *lapb) { + lapb->t2timer_stop = true; del_timer(&lapb->t2timer); } @@ -72,16 +76,31 @@ static void lapb_t2timer_expiry(struct timer_list *t) { struct lapb_cb *lapb = from_timer(lapb, t, t2timer); + spin_lock_bh(&lapb->lock); + if (timer_pending(&lapb->t2timer)) /* A new timer has been set up */ + goto out; + if (lapb->t2timer_stop) /* The timer has been stopped */ + goto out; + if (lapb->condition & LAPB_ACK_PENDING_CONDITION) { lapb->condition &= ~LAPB_ACK_PENDING_CONDITION; lapb_timeout_response(lapb); } + +out: + spin_unlock_bh(&lapb->lock); } static void lapb_t1timer_expiry(struct timer_list *t) { struct lapb_cb *lapb = from_timer(lapb, t, t1timer); + spin_lock_bh(&lapb->lock); + if (timer_pending(&lapb->t1timer)) /* A new timer has been set up */ + goto out; + if (lapb->t1timer_stop) /* The timer has been stopped */ + goto out; + switch (lapb->state) { /* @@ -108,7 +127,7 @@ static void lapb_t1timer_expiry(struct timer_list *t) lapb->state = LAPB_STATE_0; lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev); - return; + goto out; } else { lapb->n2count++; if (lapb->mode & LAPB_EXTENDED) { @@ -132,7 +151,7 @@ static void lapb_t1timer_expiry(struct timer_list *t) lapb->state = LAPB_STATE_0; lapb_disconnect_confirmation(lapb, LAPB_TIMEDOUT); lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev); - return; + goto out; } else { lapb->n2count++; lapb_dbg(1, "(%p) S2 TX DISC(1)\n", lapb->dev); @@ -150,7 +169,7 @@ static void lapb_t1timer_expiry(struct timer_list *t) lapb_stop_t2timer(lapb); lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev); - return; + goto out; } else { lapb->n2count++; lapb_requeue_frames(lapb); @@ -167,7 +186,7 @@ static void lapb_t1timer_expiry(struct timer_list *t) lapb->state = LAPB_STATE_0; lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); lapb_dbg(0, "(%p) S4 -> S0\n", lapb->dev); - return; + goto out; } else { lapb->n2count++; lapb_transmit_frmr(lapb); @@ -176,4 +195,7 @@ static void lapb_t1timer_expiry(struct timer_list *t) } lapb_start_t1timer(lapb); + +out: + spin_unlock_bh(&lapb->lock); } -- GitLab From c730ab423bfa1ae99b688a9abdedf74477d44955 Mon Sep 17 00:00:00 2001 From: Laurent Badel Date: Mon, 25 Jan 2021 11:07:45 +0100 Subject: [PATCH 0719/1084] net: fec: Fix temporary RMII clock reset on link up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fec_restart() does a hard reset of the MAC module when the link status changes to up. This temporarily resets the R_CNTRL register which controls the MII mode of the ENET_OUT clock. In the case of RMII, the clock frequency momentarily drops from 50MHz to 25MHz until the register is reconfigured. Some link partners do not tolerate this glitch and invalidate the link causing failure to establish a stable link when using PHY polling mode. Since as per IEEE802.3 the criteria for link validity are PHY-specific, what the partner should tolerate cannot be assumed, so avoid resetting the MII clock by using software reset instead of hardware reset when the link is up. This is generally relevant only if the SoC provides the clock to an external PHY and the PHY is configured for RMII. Signed-off-by: Laurent Badel Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/freescale/fec.h | 5 +++++ drivers/net/ethernet/freescale/fec_main.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index c527f4ee1d3ae..0602d5d5d2eee 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -462,6 +462,11 @@ struct bufdesc_ex { */ #define FEC_QUIRK_CLEAR_SETUP_MII (1 << 17) +/* Some link partners do not tolerate the momentary reset of the REF_CLK + * frequency when the RNCTL register is cleared by hardware reset. + */ +#define FEC_QUIRK_NO_HARD_RESET (1 << 18) + struct bufdesc_prop { int qid; /* Address of Rx and Tx buffers */ diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 55c28fbc5f9ea..9ebdb0e54291b 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -100,7 +100,8 @@ static const struct fec_devinfo fec_imx27_info = { static const struct fec_devinfo fec_imx28_info = { .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC | - FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII, + FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII | + FEC_QUIRK_NO_HARD_RESET, }; static const struct fec_devinfo fec_imx6q_info = { @@ -953,7 +954,8 @@ fec_restart(struct net_device *ndev) * For i.MX6SX SOC, enet use AXI bus, we use disable MAC * instead of reset MAC itself. */ - if (fep->quirks & FEC_QUIRK_HAS_AVB) { + if (fep->quirks & FEC_QUIRK_HAS_AVB || + ((fep->quirks & FEC_QUIRK_NO_HARD_RESET) && fep->link)) { writel(0, fep->hwp + FEC_ECNTRL); } else { writel(1, fep->hwp + FEC_ECNTRL); -- GitLab From 907d1df30a51cc1a1d25414a00cde0494b83df7b Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Tue, 26 Jan 2021 23:35:10 +0000 Subject: [PATCH 0720/1084] io_uring: fix wqe->lock/completion_lock deadlock Joseph reports following deadlock: CPU0: ... io_kill_linked_timeout // &ctx->completion_lock io_commit_cqring __io_queue_deferred __io_queue_async_work io_wq_enqueue io_wqe_enqueue // &wqe->lock CPU1: ... __io_uring_files_cancel io_wq_cancel_cb io_wqe_cancel_pending_work // &wqe->lock io_cancel_task_cb // &ctx->completion_lock Only __io_queue_deferred() calls queue_async_work() while holding ctx->completion_lock, enqueue drained requests via io_req_task_queue() instead. Cc: stable@vger.kernel.org # 5.9+ Reported-by: Joseph Qi Tested-by: Joseph Qi Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index bb0270eeb8cb6..c218deaf73a9f 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1026,6 +1026,7 @@ static int io_setup_async_rw(struct io_kiocb *req, const struct iovec *iovec, const struct iovec *fast_iov, struct iov_iter *iter, bool force); static void io_req_drop_files(struct io_kiocb *req); +static void io_req_task_queue(struct io_kiocb *req); static struct kmem_cache *req_cachep; @@ -1634,18 +1635,11 @@ static void __io_queue_deferred(struct io_ring_ctx *ctx) do { struct io_defer_entry *de = list_first_entry(&ctx->defer_list, struct io_defer_entry, list); - struct io_kiocb *link; if (req_need_defer(de->req, de->seq)) break; list_del_init(&de->list); - /* punt-init is done before queueing for defer */ - link = __io_queue_async_work(de->req); - if (link) { - __io_queue_linked_timeout(link); - /* drop submission reference */ - io_put_req_deferred(link, 1); - } + io_req_task_queue(de->req); kfree(de); } while (!list_empty(&ctx->defer_list)); } -- GitLab From 5f46400f7a6a4fad635d5a79e2aa5a04a30ffea1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 26 Jan 2021 17:01:49 +0000 Subject: [PATCH 0721/1084] xen: Fix XenStore initialisation for XS_LOCAL In commit 3499ba8198ca ("xen: Fix event channel callback via INTX/GSI") I reworked the triggering of xenbus_probe(). I tried to simplify things by taking out the workqueue based startup triggered from wake_waiting(); the somewhat poorly named xenbus IRQ handler. I missed the fact that in the XS_LOCAL case (Dom0 starting its own xenstored or xenstore-stubdom, which happens after the kernel is booted completely), that IRQ-based trigger is still actually needed. So... put it back, except more cleanly. By just spawning a xenbus_probe thread which waits on xb_waitq and runs the probe the first time it gets woken, just as the workqueue-based hack did. This is actually a nicer approach for *all* the back ends with different interrupt methods, and we can switch them all over to that without the complex conditions for when to trigger it. But not in -rc6. This is the minimal fix for the regression, although it's a step in the right direction instead of doing a partial revert and actually putting the workqueue back. It's also simpler than the workqueue. Fixes: 3499ba8198ca ("xen: Fix event channel callback via INTX/GSI") Reported-by: Juergen Gross Signed-off-by: David Woodhouse Reviewed-by: Juergen Gross Link: https://lore.kernel.org/r/4c9af052a6e0f6485d1de43f2c38b1461996db99.camel@infradead.org Signed-off-by: Juergen Gross --- drivers/xen/xenbus/xenbus_probe.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index c8f0282bb6497..18ffd0551b542 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -714,6 +714,23 @@ static bool xs_hvm_defer_init_for_callback(void) #endif } +static int xenbus_probe_thread(void *unused) +{ + DEFINE_WAIT(w); + + /* + * We actually just want to wait for *any* trigger of xb_waitq, + * and run xenbus_probe() the moment it occurs. + */ + prepare_to_wait(&xb_waitq, &w, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&xb_waitq, &w); + + DPRINTK("probing"); + xenbus_probe(); + return 0; +} + static int __init xenbus_probe_initcall(void) { /* @@ -725,6 +742,20 @@ static int __init xenbus_probe_initcall(void) !xs_hvm_defer_init_for_callback())) xenbus_probe(); + /* + * For XS_LOCAL, spawn a thread which will wait for xenstored + * or a xenstore-stubdom to be started, then probe. It will be + * triggered when communication starts happening, by waiting + * on xb_waitq. + */ + if (xen_store_domain_type == XS_LOCAL) { + struct task_struct *probe_task; + + probe_task = kthread_run(xenbus_probe_thread, NULL, + "xenbus_probe"); + if (IS_ERR(probe_task)) + return PTR_ERR(probe_task); + } return 0; } device_initcall(xenbus_probe_initcall); -- GitLab From 211e5db19d15a721b2953ea54b8f26c2963720eb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 26 Jan 2021 18:02:11 +0100 Subject: [PATCH 0722/1084] rtc: mc146818: Detect and handle broken RTCs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recent fix for handling the UIP bit unearthed another issue in the RTC code. If the RTC is advertised but the readout is straight 0xFF because it's not available, the old code just proceeded with crappy values, but the new code hangs because it waits for the UIP bit to become low. Add a sanity check in the RTC CMOS probe function which reads the RTC_VALID register (Register D) which should have bit 0-6 cleared. If that's not the case then fail to register the CMOS. Add the same check to mc146818_get_time(), warn once when the condition is true and invalidate the rtc_time data. Reported-by: Mickaël Salaün Signed-off-by: Thomas Gleixner Tested-by: Mickaël Salaün Acked-by: Alexandre Belloni Link: https://lore.kernel.org/r/87tur3fx7w.fsf@nanos.tec.linutronix.de --- drivers/rtc/rtc-cmos.c | 8 ++++++++ drivers/rtc/rtc-mc146818-lib.c | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 51e80bc70d423..68a9ac6f2fe17 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -805,6 +805,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) spin_lock_irq(&rtc_lock); + /* Ensure that the RTC is accessible. Bit 0-6 must be 0! */ + if ((CMOS_READ(RTC_VALID) & 0x7f) != 0) { + spin_unlock_irq(&rtc_lock); + dev_warn(dev, "not accessible\n"); + retval = -ENXIO; + goto cleanup1; + } + if (!(flags & CMOS_RTC_FLAGS_NOFREQ)) { /* force periodic irq to CMOS reset default of 1024Hz; * diff --git a/drivers/rtc/rtc-mc146818-lib.c b/drivers/rtc/rtc-mc146818-lib.c index 972a5b9a629d3..f83c13818af3b 100644 --- a/drivers/rtc/rtc-mc146818-lib.c +++ b/drivers/rtc/rtc-mc146818-lib.c @@ -21,6 +21,13 @@ unsigned int mc146818_get_time(struct rtc_time *time) again: spin_lock_irqsave(&rtc_lock, flags); + /* Ensure that the RTC is accessible. Bit 0-6 must be 0! */ + if (WARN_ON_ONCE((CMOS_READ(RTC_VALID) & 0x7f) != 0)) { + spin_unlock_irqrestore(&rtc_lock, flags); + memset(time, 0xff, sizeof(*time)); + return 0; + } + /* * Check whether there is an update in progress during which the * readout is unspecified. The maximum update time is ~2ms. Poll -- GitLab From b552766c872f5b0d90323b24e4c9e8fa67486dd5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 21 Jan 2021 09:08:05 +0300 Subject: [PATCH 0723/1084] can: dev: prevent potential information leak in can_fill_info() The "bec" struct isn't necessarily always initialized. For example, the mcp251xfd_get_berr_counter() function doesn't initialize anything if the interface is down. Fixes: 52c793f24054 ("can: netlink support for bus-error reporting and counters") Link: https://lore.kernel.org/r/YAkaRdRJncsJO8Ve@mwanda Signed-off-by: Dan Carpenter Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 8b1ae023cb218..c73e2a65c9044 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -1163,7 +1163,7 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); struct can_ctrlmode cm = {.flags = priv->ctrlmode}; - struct can_berr_counter bec; + struct can_berr_counter bec = { }; enum can_state state = priv->state; if (priv->do_get_state) -- GitLab From f21916ec4826766463fe9fb55a5f43d2a365811d Mon Sep 17 00:00:00 2001 From: Tony Krowiak Date: Tue, 22 Dec 2020 20:20:13 -0500 Subject: [PATCH 0724/1084] s390/vfio-ap: clean up vfio_ap resources when KVM pointer invalidated The vfio_ap device driver registers a group notifier with VFIO when the file descriptor for a VFIO mediated device for a KVM guest is opened to receive notification that the KVM pointer is set (VFIO_GROUP_NOTIFY_SET_KVM event). When the KVM pointer is set, the vfio_ap driver takes the following actions: 1. Stashes the KVM pointer in the vfio_ap_mdev struct that holds the state of the mediated device. 2. Calls the kvm_get_kvm() function to increment its reference counter. 3. Sets the function pointer to the function that handles interception of the instruction that enables/disables interrupt processing. 4. Sets the masks in the KVM guest's CRYCB to pass AP resources through to the guest. In order to avoid memory leaks, when the notifier is called to receive notification that the KVM pointer has been set to NULL, the vfio_ap device driver should reverse the actions taken when the KVM pointer was set. Fixes: 258287c994de ("s390: vfio-ap: implement mediated device open callback") Signed-off-by: Tony Krowiak Reviewed-by: Halil Pasic Reviewed-by: Cornelia Huck Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20201223012013.5418-1-akrowiak@linux.ibm.com Signed-off-by: Christian Borntraeger Signed-off-by: Vasily Gorbik --- drivers/s390/crypto/vfio_ap_ops.c | 49 ++++++++++++++++++------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index e0bde85187451..7339043906cf9 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -1037,19 +1037,14 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev, { struct ap_matrix_mdev *m; - mutex_lock(&matrix_dev->lock); - list_for_each_entry(m, &matrix_dev->mdev_list, node) { - if ((m != matrix_mdev) && (m->kvm == kvm)) { - mutex_unlock(&matrix_dev->lock); + if ((m != matrix_mdev) && (m->kvm == kvm)) return -EPERM; - } } matrix_mdev->kvm = kvm; kvm_get_kvm(kvm); kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook; - mutex_unlock(&matrix_dev->lock); return 0; } @@ -1083,35 +1078,52 @@ static int vfio_ap_mdev_iommu_notifier(struct notifier_block *nb, return NOTIFY_DONE; } +static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev) +{ + kvm_arch_crypto_clear_masks(matrix_mdev->kvm); + matrix_mdev->kvm->arch.crypto.pqap_hook = NULL; + vfio_ap_mdev_reset_queues(matrix_mdev->mdev); + kvm_put_kvm(matrix_mdev->kvm); + matrix_mdev->kvm = NULL; +} + static int vfio_ap_mdev_group_notifier(struct notifier_block *nb, unsigned long action, void *data) { - int ret; + int ret, notify_rc = NOTIFY_OK; struct ap_matrix_mdev *matrix_mdev; if (action != VFIO_GROUP_NOTIFY_SET_KVM) return NOTIFY_OK; matrix_mdev = container_of(nb, struct ap_matrix_mdev, group_notifier); + mutex_lock(&matrix_dev->lock); if (!data) { - matrix_mdev->kvm = NULL; - return NOTIFY_OK; + if (matrix_mdev->kvm) + vfio_ap_mdev_unset_kvm(matrix_mdev); + goto notify_done; } ret = vfio_ap_mdev_set_kvm(matrix_mdev, data); - if (ret) - return NOTIFY_DONE; + if (ret) { + notify_rc = NOTIFY_DONE; + goto notify_done; + } /* If there is no CRYCB pointer, then we can't copy the masks */ - if (!matrix_mdev->kvm->arch.crypto.crycbd) - return NOTIFY_DONE; + if (!matrix_mdev->kvm->arch.crypto.crycbd) { + notify_rc = NOTIFY_DONE; + goto notify_done; + } kvm_arch_crypto_set_masks(matrix_mdev->kvm, matrix_mdev->matrix.apm, matrix_mdev->matrix.aqm, matrix_mdev->matrix.adm); - return NOTIFY_OK; +notify_done: + mutex_unlock(&matrix_dev->lock); + return notify_rc; } static void vfio_ap_irq_disable_apqn(int apqn) @@ -1222,13 +1234,8 @@ static void vfio_ap_mdev_release(struct mdev_device *mdev) struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); mutex_lock(&matrix_dev->lock); - if (matrix_mdev->kvm) { - kvm_arch_crypto_clear_masks(matrix_mdev->kvm); - matrix_mdev->kvm->arch.crypto.pqap_hook = NULL; - vfio_ap_mdev_reset_queues(mdev); - kvm_put_kvm(matrix_mdev->kvm); - matrix_mdev->kvm = NULL; - } + if (matrix_mdev->kvm) + vfio_ap_mdev_unset_kvm(matrix_mdev); mutex_unlock(&matrix_dev->lock); vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, -- GitLab From 6c12a6384e0c0b96debd88b24028e58f2ebd417b Mon Sep 17 00:00:00 2001 From: Tony Krowiak Date: Tue, 22 Dec 2020 20:15:53 -0500 Subject: [PATCH 0725/1084] s390/vfio-ap: No need to disable IRQ after queue reset The queues assigned to a matrix mediated device are currently reset when: * The VFIO_DEVICE_RESET ioctl is invoked * The mdev fd is closed by userspace (QEMU) * The mdev is removed from sysfs. Immediately after the reset of a queue, a call is made to disable interrupts for the queue. This is entirely unnecessary because the reset of a queue disables interrupts, so this will be removed. Furthermore, vfio_ap_irq_disable() does an unconditional PQAP/AQIC which can result in a specification exception (when the corresponding facility is not available), so this is actually a bugfix. Signed-off-by: Tony Krowiak [pasic@linux.ibm.com: minor rework before merging] Signed-off-by: Halil Pasic Fixes: ec89b55e3bce ("s390: ap: implement PAPQ AQIC interception in kernel") Cc: Signed-off-by: Vasily Gorbik --- drivers/s390/crypto/vfio_ap_drv.c | 6 +- drivers/s390/crypto/vfio_ap_ops.c | 100 ++++++++++++++++---------- drivers/s390/crypto/vfio_ap_private.h | 12 ++-- 3 files changed, 69 insertions(+), 49 deletions(-) diff --git a/drivers/s390/crypto/vfio_ap_drv.c b/drivers/s390/crypto/vfio_ap_drv.c index be2520cc010be..7dc72cb718b0e 100644 --- a/drivers/s390/crypto/vfio_ap_drv.c +++ b/drivers/s390/crypto/vfio_ap_drv.c @@ -71,15 +71,11 @@ static int vfio_ap_queue_dev_probe(struct ap_device *apdev) static void vfio_ap_queue_dev_remove(struct ap_device *apdev) { struct vfio_ap_queue *q; - int apid, apqi; mutex_lock(&matrix_dev->lock); q = dev_get_drvdata(&apdev->device); + vfio_ap_mdev_reset_queue(q, 1); dev_set_drvdata(&apdev->device, NULL); - apid = AP_QID_CARD(q->apqn); - apqi = AP_QID_QUEUE(q->apqn); - vfio_ap_mdev_reset_queue(apid, apqi, 1); - vfio_ap_irq_disable(q); kfree(q); mutex_unlock(&matrix_dev->lock); } diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 7339043906cf9..41fc2e4135fe1 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -25,6 +25,7 @@ #define VFIO_AP_MDEV_NAME_HWVIRT "VFIO AP Passthrough Device" static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev); +static struct vfio_ap_queue *vfio_ap_find_queue(int apqn); static int match_apqn(struct device *dev, const void *data) { @@ -49,20 +50,15 @@ static struct vfio_ap_queue *vfio_ap_get_queue( int apqn) { struct vfio_ap_queue *q; - struct device *dev; if (!test_bit_inv(AP_QID_CARD(apqn), matrix_mdev->matrix.apm)) return NULL; if (!test_bit_inv(AP_QID_QUEUE(apqn), matrix_mdev->matrix.aqm)) return NULL; - dev = driver_find_device(&matrix_dev->vfio_ap_drv->driver, NULL, - &apqn, match_apqn); - if (!dev) - return NULL; - q = dev_get_drvdata(dev); - q->matrix_mdev = matrix_mdev; - put_device(dev); + q = vfio_ap_find_queue(apqn); + if (q) + q->matrix_mdev = matrix_mdev; return q; } @@ -119,13 +115,18 @@ static void vfio_ap_wait_for_irqclear(int apqn) */ static void vfio_ap_free_aqic_resources(struct vfio_ap_queue *q) { - if (q->saved_isc != VFIO_AP_ISC_INVALID && q->matrix_mdev) + if (!q) + return; + if (q->saved_isc != VFIO_AP_ISC_INVALID && + !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm))) { kvm_s390_gisc_unregister(q->matrix_mdev->kvm, q->saved_isc); - if (q->saved_pfn && q->matrix_mdev) + q->saved_isc = VFIO_AP_ISC_INVALID; + } + if (q->saved_pfn && !WARN_ON(!q->matrix_mdev)) { vfio_unpin_pages(mdev_dev(q->matrix_mdev->mdev), &q->saved_pfn, 1); - q->saved_pfn = 0; - q->saved_isc = VFIO_AP_ISC_INVALID; + q->saved_pfn = 0; + } } /** @@ -144,7 +145,7 @@ static void vfio_ap_free_aqic_resources(struct vfio_ap_queue *q) * Returns if ap_aqic function failed with invalid, deconfigured or * checkstopped AP. */ -struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q) +static struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q) { struct ap_qirq_ctrl aqic_gisa = {}; struct ap_queue_status status; @@ -1126,48 +1127,70 @@ static int vfio_ap_mdev_group_notifier(struct notifier_block *nb, return notify_rc; } -static void vfio_ap_irq_disable_apqn(int apqn) +static struct vfio_ap_queue *vfio_ap_find_queue(int apqn) { struct device *dev; - struct vfio_ap_queue *q; + struct vfio_ap_queue *q = NULL; dev = driver_find_device(&matrix_dev->vfio_ap_drv->driver, NULL, &apqn, match_apqn); if (dev) { q = dev_get_drvdata(dev); - vfio_ap_irq_disable(q); put_device(dev); } + + return q; } -int vfio_ap_mdev_reset_queue(unsigned int apid, unsigned int apqi, +int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q, unsigned int retry) { struct ap_queue_status status; + int ret; int retry2 = 2; - int apqn = AP_MKQID(apid, apqi); - do { - status = ap_zapq(apqn); - switch (status.response_code) { - case AP_RESPONSE_NORMAL: - while (!status.queue_empty && retry2--) { - msleep(20); - status = ap_tapq(apqn, NULL); - } - WARN_ON_ONCE(retry2 <= 0); - return 0; - case AP_RESPONSE_RESET_IN_PROGRESS: - case AP_RESPONSE_BUSY: + if (!q) + return 0; + +retry_zapq: + status = ap_zapq(q->apqn); + switch (status.response_code) { + case AP_RESPONSE_NORMAL: + ret = 0; + break; + case AP_RESPONSE_RESET_IN_PROGRESS: + if (retry--) { msleep(20); - break; - default: - /* things are really broken, give up */ - return -EIO; + goto retry_zapq; } - } while (retry--); + ret = -EBUSY; + break; + case AP_RESPONSE_Q_NOT_AVAIL: + case AP_RESPONSE_DECONFIGURED: + case AP_RESPONSE_CHECKSTOPPED: + WARN_ON_ONCE(status.irq_enabled); + ret = -EBUSY; + goto free_resources; + default: + /* things are really broken, give up */ + WARN(true, "PQAP/ZAPQ completed with invalid rc (%x)\n", + status.response_code); + return -EIO; + } + + /* wait for the reset to take effect */ + while (retry2--) { + if (status.queue_empty && !status.irq_enabled) + break; + msleep(20); + status = ap_tapq(q->apqn, NULL); + } + WARN_ON_ONCE(retry2 <= 0); - return -EBUSY; +free_resources: + vfio_ap_free_aqic_resources(q); + + return ret; } static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev) @@ -1175,13 +1198,15 @@ static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev) int ret; int rc = 0; unsigned long apid, apqi; + struct vfio_ap_queue *q; struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); for_each_set_bit_inv(apid, matrix_mdev->matrix.apm, matrix_mdev->matrix.apm_max + 1) { for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm, matrix_mdev->matrix.aqm_max + 1) { - ret = vfio_ap_mdev_reset_queue(apid, apqi, 1); + q = vfio_ap_find_queue(AP_MKQID(apid, apqi)); + ret = vfio_ap_mdev_reset_queue(q, 1); /* * Regardless whether a queue turns out to be busy, or * is not operational, we need to continue resetting @@ -1189,7 +1214,6 @@ static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev) */ if (ret) rc = ret; - vfio_ap_irq_disable_apqn(AP_MKQID(apid, apqi)); } } diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h index f46dde56b4644..28e9d99897682 100644 --- a/drivers/s390/crypto/vfio_ap_private.h +++ b/drivers/s390/crypto/vfio_ap_private.h @@ -88,11 +88,6 @@ struct ap_matrix_mdev { struct mdev_device *mdev; }; -extern int vfio_ap_mdev_register(void); -extern void vfio_ap_mdev_unregister(void); -int vfio_ap_mdev_reset_queue(unsigned int apid, unsigned int apqi, - unsigned int retry); - struct vfio_ap_queue { struct ap_matrix_mdev *matrix_mdev; unsigned long saved_pfn; @@ -100,5 +95,10 @@ struct vfio_ap_queue { #define VFIO_AP_ISC_INVALID 0xff unsigned char saved_isc; }; -struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q); + +int vfio_ap_mdev_register(void); +void vfio_ap_mdev_unregister(void); +int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q, + unsigned int retry); + #endif /* _VFIO_AP_PRIVATE_H_ */ -- GitLab From e82080e1f456467cc185fe65ee69fe9f9bd0b576 Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Wed, 13 Jan 2021 11:56:26 -0500 Subject: [PATCH 0726/1084] s390: uv: Fix sysfs max number of VCPUs reporting The number reported by the query is N-1 and I think people reading the sysfs file would expect N instead. For users creating VMs there's no actual difference because KVM's limit is currently below the UV's limit. Signed-off-by: Janosch Frank Fixes: a0f60f8431999 ("s390/protvirt: Add sysfs firmware interface for Ultravisor information") Cc: stable@vger.kernel.org Reviewed-by: Claudio Imbrenda Acked-by: Cornelia Huck Signed-off-by: Vasily Gorbik --- arch/s390/boot/uv.c | 2 +- arch/s390/include/asm/uv.h | 4 ++-- arch/s390/kernel/uv.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/s390/boot/uv.c b/arch/s390/boot/uv.c index a15c033f53ca4..87641dd65ccf9 100644 --- a/arch/s390/boot/uv.c +++ b/arch/s390/boot/uv.c @@ -35,7 +35,7 @@ void uv_query_info(void) uv_info.guest_cpu_stor_len = uvcb.cpu_stor_len; uv_info.max_sec_stor_addr = ALIGN(uvcb.max_guest_stor_addr, PAGE_SIZE); uv_info.max_num_sec_conf = uvcb.max_num_sec_conf; - uv_info.max_guest_cpus = uvcb.max_guest_cpus; + uv_info.max_guest_cpu_id = uvcb.max_guest_cpu_id; } #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h index 0325fc0469b7b..7b98d4caee779 100644 --- a/arch/s390/include/asm/uv.h +++ b/arch/s390/include/asm/uv.h @@ -96,7 +96,7 @@ struct uv_cb_qui { u32 max_num_sec_conf; u64 max_guest_stor_addr; u8 reserved88[158 - 136]; - u16 max_guest_cpus; + u16 max_guest_cpu_id; u8 reserveda0[200 - 160]; } __packed __aligned(8); @@ -273,7 +273,7 @@ struct uv_info { unsigned long guest_cpu_stor_len; unsigned long max_sec_stor_addr; unsigned int max_num_sec_conf; - unsigned short max_guest_cpus; + unsigned short max_guest_cpu_id; }; extern struct uv_info uv_info; diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c index 883bfed9f5c2c..b2d2ad1530676 100644 --- a/arch/s390/kernel/uv.c +++ b/arch/s390/kernel/uv.c @@ -368,7 +368,7 @@ static ssize_t uv_query_max_guest_cpus(struct kobject *kobj, struct kobj_attribute *attr, char *page) { return scnprintf(page, PAGE_SIZE, "%d\n", - uv_info.max_guest_cpus); + uv_info.max_guest_cpu_id + 1); } static struct kobj_attribute uv_query_max_guest_cpus_attr = -- GitLab From a1df829ead5877d4a1061e976a50e2e665a16f24 Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Thu, 21 Jan 2021 17:24:19 -0800 Subject: [PATCH 0727/1084] ACPI/IORT: Do not blindly trust DMA masks from firmware Address issue observed on real world system with suboptimal IORT table where DMA masks of PCI devices would get set to 0 as result. iort_dma_setup() would query the root complex'/named component IORT entry for a DMA mask, and use that over the one the device has been configured with earlier. Ideally we want to use the minimum mask of what the IORT contains for the root complex and what the device was configured with. Fixes: 5ac65e8c8941 ("ACPI/IORT: Support address size limit for root complexes") Signed-off-by: Moritz Fischer Reviewed-by: Robin Murphy Acked-by: Lorenzo Pieralisi Link: https://lore.kernel.org/r/20210122012419.95010-1-mdf@kernel.org Signed-off-by: Catalin Marinas --- drivers/acpi/arm64/iort.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index d4eac6d7e9fbc..2494138a6905e 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -1107,6 +1107,11 @@ static int nc_dma_get_range(struct device *dev, u64 *size) ncomp = (struct acpi_iort_named_component *)node->node_data; + if (!ncomp->memory_address_limit) { + pr_warn(FW_BUG "Named component missing memory address limit\n"); + return -EINVAL; + } + *size = ncomp->memory_address_limit >= 64 ? U64_MAX : 1ULL<memory_address_limit; @@ -1126,6 +1131,11 @@ static int rc_dma_get_range(struct device *dev, u64 *size) rc = (struct acpi_iort_root_complex *)node->node_data; + if (!rc->memory_address_limit) { + pr_warn(FW_BUG "Root complex missing memory address limit\n"); + return -EINVAL; + } + *size = rc->memory_address_limit >= 64 ? U64_MAX : 1ULL<memory_address_limit; @@ -1173,8 +1183,8 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) end = dmaaddr + size - 1; mask = DMA_BIT_MASK(ilog2(end) + 1); dev->bus_dma_limit = end; - dev->coherent_dma_mask = mask; - *dev->dma_mask = mask; + dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask); + *dev->dma_mask = min(*dev->dma_mask, mask); } *dma_addr = dmaaddr; -- GitLab From ae07f5c7c5e9ebca5b9d6471bb4b99a9da5c6d88 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 26 Jan 2021 16:47:02 +0100 Subject: [PATCH 0728/1084] ASoC: siu: Fix build error by a wrong const prefix A const prefix was put wrongly in the middle at the code refactoring commit 932eaf7c7904 ("ASoC: sh: siu_pcm: remove snd_pcm_ops"), which leads to a build error as: sound/soc/sh/siu_pcm.c:546:8: error: expected '{' before 'const' Also, another inconsistency is that the declaration of siu_component misses the const prefix. This patch corrects both failures. Fixes: 932eaf7c7904 ("ASoC: sh: siu_pcm: remove snd_pcm_ops") Cc: Signed-off-by: Takashi Iwai Link: https://lore.kernel.org/r/20210126154702.3974-1-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/sh/siu.h | 2 +- sound/soc/sh/siu_pcm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h index 6201840f1bc05..a675c36fc9d95 100644 --- a/sound/soc/sh/siu.h +++ b/sound/soc/sh/siu.h @@ -169,7 +169,7 @@ static inline u32 siu_read32(u32 __iomem *addr) #define SIU_BRGBSEL (0x108 / sizeof(u32)) #define SIU_BRRB (0x10c / sizeof(u32)) -extern struct snd_soc_component_driver siu_component; +extern const struct snd_soc_component_driver siu_component; extern struct siu_info *siu_i2s_data; int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card); diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index 45c4320976ab9..4785886df4f03 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -543,7 +543,7 @@ static void siu_pcm_free(struct snd_soc_component *component, dev_dbg(pcm->card->dev, "%s\n", __func__); } -struct const snd_soc_component_driver siu_component = { +const struct snd_soc_component_driver siu_component = { .name = DRV_NAME, .open = siu_pcm_open, .close = siu_pcm_close, -- GitLab From 7da99ef9757a3dd6e66a9b4854c5e58cd65a0b9a Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Mon, 25 Jan 2021 09:04:58 +0200 Subject: [PATCH 0729/1084] ASoC: SOF: allow soundwire use desc->default_fw_filename The old code always uses sof_fw_filename in struct snd_soc_acpi_mach as the firmware name. However, firmware name should depend on the platform instead of the machine. For example, different machines may use the same soundwire link topology, but they are using the different firmware. In this case, it's hard to determine in struct snd_soc_acpi_mach which firmware it should use. Signed-off-by: Libin Yang Reviewed-by: Bard Liao Reviewed-by: Guennadi Liakhovetski Signed-off-by: Kai Vehmanen Tested-by: Jaroslav Kysela Link: https://lore.kernel.org/r/20210125070500.807474-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 509a9b2564230..b625d852b999c 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1173,7 +1173,10 @@ static int hda_sdw_machine_select(struct snd_sof_dev *sdev) mach->mach_params.links = mach->links; mach->mach_params.link_mask = mach->link_mask; mach->mach_params.platform = dev_name(sdev->dev); - pdata->fw_filename = mach->sof_fw_filename; + if (mach->sof_fw_filename) + pdata->fw_filename = mach->sof_fw_filename; + else + pdata->fw_filename = pdata->desc->default_fw_filename; pdata->tplg_filename = mach->sof_tplg_filename; } else { dev_info(sdev->dev, -- GitLab From 3d14932527ff09517f052e54e7c25d676120b33a Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Mon, 25 Jan 2021 09:04:59 +0200 Subject: [PATCH 0730/1084] ASoC: Intel: tgl: remove sof_fw_filename set for tgl_3_in_1_default tgl_3_in_1_default link topology may be used by both TGL-LP and TGL-H. Let's remove the sof_fw_filename setting in struct snd_soc_acpi_mach and use the default_fw_filename setting in struct sof_dev_desc. Signed-off-by: Libin Yang Reviewed-by: Bard Liao Reviewed-by: Guennadi Liakhovetski Signed-off-by: Kai Vehmanen Tested-by: Jaroslav Kysela Link: https://lore.kernel.org/r/20210125070500.807474-2-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-tgl-match.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c index 98196e9fad62f..711aed06c6ddc 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -358,14 +358,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { .link_mask = 0x7, .links = tgl_sdw_rt711_link1_rt1308_link2_rt715_link0, .drv_name = "sof_sdw", - .sof_fw_filename = "sof-tgl.ri", .sof_tplg_filename = "sof-tgl-rt715-rt711-rt1308-mono.tplg", }, { .link_mask = 0xF, /* 4 active links required */ .links = tgl_3_in_1_default, .drv_name = "sof_sdw", - .sof_fw_filename = "sof-tgl.ri", .sof_tplg_filename = "sof-tgl-rt711-rt1308-rt715.tplg", }, { @@ -377,35 +375,30 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { .link_mask = 0xF, .links = tgl_3_in_1_mono_amp, .drv_name = "sof_sdw", - .sof_fw_filename = "sof-tgl.ri", .sof_tplg_filename = "sof-tgl-rt711-rt1308-mono-rt715.tplg", }, { .link_mask = 0xF, /* 4 active links required */ .links = tgl_3_in_1_sdca, .drv_name = "sof_sdw", - .sof_fw_filename = "sof-tgl.ri", .sof_tplg_filename = "sof-tgl-rt711-rt1316-rt714.tplg", }, { .link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */ .links = tgl_rvp, .drv_name = "sof_sdw", - .sof_fw_filename = "sof-tgl.ri", .sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg", }, { .link_mask = 0x3, /* rt5682 on link0 & 2xmax98373 on link 1 */ .links = tgl_chromebook_base, .drv_name = "sof_sdw", - .sof_fw_filename = "sof-tgl.ri", .sof_tplg_filename = "sof-tgl-sdw-max98373-rt5682.tplg", }, { .link_mask = 0x1, /* this will only enable rt5682 for now */ .links = tgl_chromebook_base, .drv_name = "sof_sdw", - .sof_fw_filename = "sof-tgl.ri", .sof_tplg_filename = "sof-tgl-rt5682.tplg", }, {}, -- GitLab From 89e641ae647a4ebc1d608fd56f331a4f4886da5f Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Wed, 27 Jan 2021 14:23:58 +0200 Subject: [PATCH 0731/1084] ASoC: SOF: add a pointer to download repo in case FW request fails The SOF firmware and topology files are not distributed via linux-firmware. To help debugging cases where correct firmware is not installed, print a pointer to the official upstream repository for Sound Open Firmware releases. BugLink: https://github.com/thesofproject/sof/issues/3665 Reported-by: Bruce Perens Signed-off-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Marc Herbert Reviewed-by: Liam Girdwood Link: https://lore.kernel.org/r/20210127122358.1014458-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/loader.c | 2 ++ sound/soc/sof/topology.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index 08a17abb63ff5..eabeaf7b260e3 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c @@ -731,6 +731,8 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev) if (ret < 0) { dev_err(sdev->dev, "error: request firmware %s failed err: %d\n", fw_filename, ret); + dev_err(sdev->dev, + "you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n"); goto err; } else { dev_dbg(sdev->dev, "request_firmware %s successful\n", diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index b6b32a7a91f87..59f89f3d61a23 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -3740,6 +3740,8 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) if (ret < 0) { dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n", file, ret); + dev_err(scomp->dev, + "you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n"); return ret; } -- GitLab From 89a400bdeb129dbc7e1c8ad2151cc8141a619709 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 26 Jan 2021 18:07:36 -0800 Subject: [PATCH 0732/1084] ASoC: SOF: Intel: hda: enable DMI L1 for D0i3-compatible streams DMI L1 entry is currently disabled whenever any capture stream is opened to prevent xruns during pause/release. But, in order to maximise power savings for the wake-on-voice usecase, DMI L1 entry should be enabled for D0i3-compatible capture streams. Introduce a new field, flags in struct sof_intel_hda_stream that stores whether a stream is dmi_l1_compatible. All playback streams, and D0i3-compatible capture streams are DMI L1 compatible. Reviewed-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Signed-off-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20210127020737.1088960-2-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-compress.c | 2 +- sound/soc/sof/intel/hda-loader.c | 2 +- sound/soc/sof/intel/hda-pcm.c | 16 ++++++++++++- sound/soc/sof/intel/hda-stream.c | 38 +++++++++++++++++------------- sound/soc/sof/intel/hda-trace.c | 3 +-- sound/soc/sof/intel/hda.h | 6 ++++- 6 files changed, 45 insertions(+), 22 deletions(-) diff --git a/sound/soc/sof/intel/hda-compress.c b/sound/soc/sof/intel/hda-compress.c index 53c08034fa221..c6cf7b3139342 100644 --- a/sound/soc/sof/intel/hda-compress.c +++ b/sound/soc/sof/intel/hda-compress.c @@ -25,7 +25,7 @@ int hda_probe_compr_assign(struct snd_sof_dev *sdev, { struct hdac_ext_stream *stream; - stream = hda_dsp_stream_get(sdev, cstream->direction); + stream = hda_dsp_stream_get(sdev, cstream->direction, 0); if (!stream) return -EBUSY; diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index ed773696b4955..365a79fc70811 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -35,7 +35,7 @@ static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsig struct pci_dev *pci = to_pci_dev(sdev->dev); int ret; - dsp_stream = hda_dsp_stream_get(sdev, direction); + dsp_stream = hda_dsp_stream_get(sdev, direction, 0); if (!dsp_stream) { dev_err(sdev->dev, "error: no stream available\n"); diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index 5d35bb18660ae..689934131a682 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -215,11 +215,25 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev, int hda_dsp_pcm_open(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_component *scomp = sdev->component; struct hdac_ext_stream *dsp_stream; + struct snd_sof_pcm *spcm; int direction = substream->stream; + u32 flags = 0; + + spcm = snd_sof_find_spcm_dai(scomp, rtd); + if (!spcm) { + dev_err(sdev->dev, "error: can't find PCM with DAI ID %d\n", rtd->dai_link->id); + return -EINVAL; + } - dsp_stream = hda_dsp_stream_get(sdev, direction); + /* All playback and D0i3 compatible streams are DMI L1 capable */ + if (direction == SNDRV_PCM_STREAM_PLAYBACK || + spcm->stream[substream->stream].d0i3_compatible) + flags |= SOF_HDA_STREAM_DMI_L1_COMPATIBLE; + dsp_stream = hda_dsp_stream_get(sdev, direction, flags); if (!dsp_stream) { dev_err(sdev->dev, "error: no stream available\n"); return -ENODEV; diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 0e09ede922c7a..40a3993ae2cbb 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -155,7 +155,7 @@ int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev, /* get next unused stream */ struct hdac_ext_stream * -hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction) +hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags) { struct hdac_bus *bus = sof_to_bus(sdev); struct sof_intel_hda_stream *hda_stream; @@ -183,18 +183,22 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction) spin_unlock_irq(&bus->reg_lock); /* stream found ? */ - if (!stream) + if (!stream) { dev_err(sdev->dev, "error: no free %s streams\n", direction == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture"); + return stream; + } + + hda_stream->flags = flags; /* - * Disable DMI Link L1 entry when capture stream is opened. + * Prevent DMI Link L1 entry for streams that don't support it. * Workaround to address a known issue with host DMA that results * in xruns during pause/release in capture scenarios. */ if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1)) - if (stream && direction == SNDRV_PCM_STREAM_CAPTURE) + if (stream && !(flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE)) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2, HDA_VS_INTEL_EM2_L1SEN, 0); @@ -206,37 +210,39 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction) int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag) { struct hdac_bus *bus = sof_to_bus(sdev); + struct sof_intel_hda_stream *hda_stream; + struct hdac_ext_stream *stream; struct hdac_stream *s; - bool active_capture_stream = false; + bool dmi_l1_enable = true; bool found = false; spin_lock_irq(&bus->reg_lock); /* - * close stream matching the stream tag - * and check if there are any open capture streams. + * close stream matching the stream tag and check if there are any open streams + * that are DMI L1 incompatible. */ list_for_each_entry(s, &bus->stream_list, list) { + stream = stream_to_hdac_ext_stream(s); + hda_stream = container_of(stream, struct sof_intel_hda_stream, hda_stream); + if (!s->opened) continue; if (s->direction == direction && s->stream_tag == stream_tag) { s->opened = false; found = true; - } else if (s->direction == SNDRV_PCM_STREAM_CAPTURE) { - active_capture_stream = true; + } else if (!(hda_stream->flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE)) { + dmi_l1_enable = false; } } spin_unlock_irq(&bus->reg_lock); - /* Enable DMI L1 entry if there are no capture streams open */ - if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1)) - if (!active_capture_stream) - snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, - HDA_VS_INTEL_EM2, - HDA_VS_INTEL_EM2_L1SEN, - HDA_VS_INTEL_EM2_L1SEN); + /* Enable DMI L1 if permitted */ + if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1) && dmi_l1_enable) + snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2, + HDA_VS_INTEL_EM2_L1SEN, HDA_VS_INTEL_EM2_L1SEN); if (!found) { dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag); diff --git a/sound/soc/sof/intel/hda-trace.c b/sound/soc/sof/intel/hda-trace.c index 1eb746d5adeb5..ca869038e9093 100644 --- a/sound/soc/sof/intel/hda-trace.c +++ b/sound/soc/sof/intel/hda-trace.c @@ -42,8 +42,7 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; int ret; - hda->dtrace_stream = hda_dsp_stream_get(sdev, - SNDRV_PCM_STREAM_CAPTURE); + hda->dtrace_stream = hda_dsp_stream_get(sdev, SNDRV_PCM_STREAM_CAPTURE, 0); if (!hda->dtrace_stream) { dev_err(sdev->dev, diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 9ec8ae0fd6495..8e9b94bf03338 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -402,6 +402,9 @@ struct sof_intel_dsp_bdl { #define SOF_HDA_PLAYBACK 0 #define SOF_HDA_CAPTURE 1 +/* stream flags */ +#define SOF_HDA_STREAM_DMI_L1_COMPATIBLE 1 + /* * Time in ms for opportunistic D0I3 entry delay. * This has been deliberately chosen to be long to avoid race conditions. @@ -471,6 +474,7 @@ struct sof_intel_hda_stream { struct hdac_ext_stream hda_stream; struct sof_intel_stream stream; int host_reserved; /* reserve host DMA channel */ + u32 flags; }; #define hstream_to_sof_hda_stream(hstream) \ @@ -562,7 +566,7 @@ bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev); bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev); struct hdac_ext_stream * - hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction); + hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags); int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag); int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream, -- GitLab From 6e0210763024ac43c5716dc873065ce5069edbf0 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 26 Jan 2021 18:07:37 -0800 Subject: [PATCH 0733/1084] ASoC: SOF: Intel: hda: Enable DMI L1 for trace Enabling DMI L1 for capture streams could result in xruns during pause/release. As pause/release is not a valid scenario for trace, we can safely enable DMI L1 for it. Reviewed-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Signed-off-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20210127020737.1088960-3-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-trace.c b/sound/soc/sof/intel/hda-trace.c index ca869038e9093..81d76d3debc65 100644 --- a/sound/soc/sof/intel/hda-trace.c +++ b/sound/soc/sof/intel/hda-trace.c @@ -42,7 +42,8 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; int ret; - hda->dtrace_stream = hda_dsp_stream_get(sdev, SNDRV_PCM_STREAM_CAPTURE, 0); + hda->dtrace_stream = hda_dsp_stream_get(sdev, SNDRV_PCM_STREAM_CAPTURE, + SOF_HDA_STREAM_DMI_L1_COMPATIBLE); if (!hda->dtrace_stream) { dev_err(sdev->dev, -- GitLab From 1da0b9899abdbc7103d3ec6b1a888efda41dbb59 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 26 Jan 2021 17:17:48 +0000 Subject: [PATCH 0734/1084] ASoC: soc-component: add snd_soc_component_read/write_field() It's often the case that we would write or read a particular field in register. With the current soc_component apis, reading a particular field in register would involve first read the register and then perform shift operations. Ex: to read from a field mask of 0xf0 val = snd_soc_component_read(component, reg); field = ((val & 0xf0) >> 0x4); This is sometimes prone to errors and code become less readable! With this new api we could just do field = snd_soc_component_read_field(component, reg, 0xf0); this makes it bit simple, easy to write and less error prone! This also applies to writing! There are various places in kernel which provides such field interfaces however soc_component seems to be missing this. This patch is inspired by FIELD_GET/FIELD_PREP macros in include/linux/bitfield.h Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210126171749.1863-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- include/sound/soc-component.h | 6 ++++ sound/soc/soc-component.c | 53 +++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 0bce41fefd306..5b47768222b7f 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -353,6 +353,12 @@ int snd_soc_component_test_bits(struct snd_soc_component *component, unsigned int reg, unsigned int mask, unsigned int value); +unsigned int snd_soc_component_read_field(struct snd_soc_component *component, + unsigned int reg, unsigned int mask); +int snd_soc_component_write_field(struct snd_soc_component *component, + unsigned int reg, unsigned int mask, + unsigned int val); + /* component wide operations */ int snd_soc_component_set_sysclk(struct snd_soc_component *component, int clk_id, int source, diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index 760523382f3c5..361a79d655e37 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -34,6 +34,18 @@ static inline int _soc_component_ret(struct snd_soc_component *component, return ret; } +static inline int soc_component_field_shift(struct snd_soc_component *component, + unsigned int mask) +{ + if (!mask) { + dev_err(component->dev, "ASoC: error field mask is zero for %s\n", + component->name); + return 0; + } + + return (__builtin_ffs(mask) - 1); +} + /* * We might want to check substream by using list. * In such case, we can update these macros. @@ -839,6 +851,47 @@ int snd_soc_component_update_bits_async(struct snd_soc_component *component, } EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async); +/** + * snd_soc_component_read_field() - Read register field value + * @component: Component to read from + * @reg: Register to read + * @mask: mask of the register field + * + * Return: read value of register field. + */ +unsigned int snd_soc_component_read_field(struct snd_soc_component *component, + unsigned int reg, unsigned int mask) +{ + unsigned int val; + + val = snd_soc_component_read(component, reg); + + val = (val & mask) >> soc_component_field_shift(component, mask); + + return val; +} +EXPORT_SYMBOL_GPL(snd_soc_component_read_field); + +/** + * snd_soc_component_write_field() - write to register field + * @component: Component to write to + * @reg: Register to write + * @mask: mask of the register field to update + * @val: value of the field to write + * + * Return: 1 for change, otherwise 0. + */ +int snd_soc_component_write_field(struct snd_soc_component *component, + unsigned int reg, unsigned int mask, + unsigned int val) +{ + + val = (val << soc_component_field_shift(component, mask)) & mask; + + return snd_soc_component_update_bits(component, reg, mask, val); +} +EXPORT_SYMBOL_GPL(snd_soc_component_write_field); + /** * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed * @component: Component for which to wait -- GitLab From 7db4c4cd767e5c2418e7892c6b2f06982d34369a Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 26 Jan 2021 17:17:49 +0000 Subject: [PATCH 0735/1084] ASoC: codecs: lpass-wsa-macro: make use of snd_soc_component_read_field() Make use of snd_soc_component_read_field() to make the code more readable! Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210126171749.1863-2-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-wsa-macro.c | 43 ++++++++++++++---------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index 25f1df214ca5d..5ebcd935ba898 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -40,9 +40,11 @@ #define CDC_WSA_TOP_I2S_CLK (0x00A4) #define CDC_WSA_TOP_I2S_RESET (0x00A8) #define CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 (0x0100) -#define CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(5, 3) -#define CDC_WSA_RX_INTX_2_SEL_MASK GENMASK(2, 0) +#define CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK GENMASK(2, 0) +#define CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK GENMASK(5, 3) #define CDC_WSA_RX_INP_MUX_RX_INT0_CFG1 (0x0104) +#define CDC_WSA_RX_INTX_2_SEL_MASK GENMASK(2, 0) +#define CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(5, 3) #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG0 (0x0108) #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG1 (0x010C) #define CDC_WSA_RX_INP_MUX_RX_MIX_CFG0 (0x0110) @@ -229,8 +231,6 @@ #define NUM_INTERPOLATORS 2 #define WSA_NUM_CLKS_MAX 5 #define WSA_MACRO_MCLK_FREQ 19200000 -#define WSA_MACRO_MUX_INP_SHFT 0x3 -#define WSA_MACRO_MUX_INP_MASK1 0x07 #define WSA_MACRO_MUX_INP_MASK2 0x38 #define WSA_MACRO_MUX_CFG_OFFSET 0x8 #define WSA_MACRO_MUX_CFG1_OFFSET 0x4 @@ -843,7 +843,6 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, u32 j, port; u16 int_mux_cfg0, int_mux_cfg1; u16 int_fs_reg; - u8 int_mux_cfg0_val, int_mux_cfg1_val; u8 inp0_sel, inp1_sel, inp2_sel; struct snd_soc_component *component = dai->component; struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); @@ -865,15 +864,13 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, */ for (j = 0; j < NUM_INTERPOLATORS; j++) { int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET; - int_mux_cfg0_val = snd_soc_component_read(component, - int_mux_cfg0); - int_mux_cfg1_val = snd_soc_component_read(component, - int_mux_cfg1); - inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1; - inp1_sel = (int_mux_cfg0_val >> WSA_MACRO_MUX_INP_SHFT) & - WSA_MACRO_MUX_INP_MASK1; - inp2_sel = (int_mux_cfg1_val >> WSA_MACRO_MUX_INP_SHFT) & - WSA_MACRO_MUX_INP_MASK1; + inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK); + inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK); + inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1, + CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK); + if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { @@ -912,9 +909,9 @@ static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1; for (j = 0; j < NUM_INTERPOLATORS; j++) { - int_mux_cfg1_val = snd_soc_component_read(component, - int_mux_cfg1) & - WSA_MACRO_MUX_INP_MASK1; + int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1, + CDC_WSA_RX_INTX_2_SEL_MASK); + if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) { int_fs_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL + WSA_MACRO_RX_PATH_OFFSET * j; @@ -1410,25 +1407,25 @@ static bool wsa_macro_adie_lb(struct snd_soc_component *component, int interp_idx) { u16 int_mux_cfg0, int_mux_cfg1; - u8 int_mux_cfg0_val, int_mux_cfg1_val; u8 int_n_inp0, int_n_inp1, int_n_inp2; int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; int_mux_cfg1 = int_mux_cfg0 + 4; - int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0); - int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1); - int_n_inp0 = int_mux_cfg0_val & 0x0F; + int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK); if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || int_n_inp0 == INTn_1_INP_SEL_DEC1) return true; - int_n_inp1 = int_mux_cfg0_val >> 4; + int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK); if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || int_n_inp1 == INTn_1_INP_SEL_DEC1) return true; - int_n_inp2 = int_mux_cfg1_val >> 4; + int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1, + CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK); if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || int_n_inp2 == INTn_1_INP_SEL_DEC1) return true; -- GitLab From 9fd5599a9b2618b315983d8a097e6dead640f55c Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 26 Jan 2021 15:20:23 -0600 Subject: [PATCH 0736/1084] ASoC: q6asm: fix 'physical' typos Fix misspellings of "physical". Signed-off-by: Bjorn Helgaas Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210126212023.2921168-1-helgaas@kernel.org Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6asm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c index a6618efe22f2b..36bf8bd4edd7c 100644 --- a/sound/soc/qcom/qdsp6/q6asm.c +++ b/sound/soc/qcom/qdsp6/q6asm.c @@ -491,7 +491,7 @@ static int __q6asm_memory_map_regions(struct audio_client *ac, int dir, * * @dir: direction of audio stream * @ac: audio client instanace - * @phys: physcial address that needs mapping. + * @phys: physical address that needs mapping. * @period_sz: audio period size * @periods: number of periods * -- GitLab From 2e92493637a09547734f92c62a2471f6f0cb9a2c Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 25 Jan 2021 14:42:07 +0100 Subject: [PATCH 0737/1084] x86/xen: avoid warning in Xen pv guest with CONFIG_AMD_MEM_ENCRYPT enabled When booting a kernel which has been built with CONFIG_AMD_MEM_ENCRYPT enabled as a Xen pv guest a warning is issued for each processor: [ 5.964347] ------------[ cut here ]------------ [ 5.968314] WARNING: CPU: 0 PID: 1 at /home/gross/linux/head/arch/x86/xen/enlighten_pv.c:660 get_trap_addr+0x59/0x90 [ 5.972321] Modules linked in: [ 5.976313] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G W 5.11.0-rc5-default #75 [ 5.980313] Hardware name: Dell Inc. OptiPlex 9020/0PC5F7, BIOS A05 12/05/2013 [ 5.984313] RIP: e030:get_trap_addr+0x59/0x90 [ 5.988313] Code: 42 10 83 f0 01 85 f6 74 04 84 c0 75 1d b8 01 00 00 00 c3 48 3d 00 80 83 82 72 08 48 3d 20 81 83 82 72 0c b8 01 00 00 00 eb db <0f> 0b 31 c0 c3 48 2d 00 80 83 82 48 ba 72 1c c7 71 1c c7 71 1c 48 [ 5.992313] RSP: e02b:ffffc90040033d38 EFLAGS: 00010202 [ 5.996313] RAX: 0000000000000001 RBX: ffffffff82a141d0 RCX: ffffffff8222ec38 [ 6.000312] RDX: ffffffff8222ec38 RSI: 0000000000000005 RDI: ffffc90040033d40 [ 6.004313] RBP: ffff8881003984a0 R08: 0000000000000007 R09: ffff888100398000 [ 6.008312] R10: 0000000000000007 R11: ffffc90040246000 R12: ffff8884082182a8 [ 6.012313] R13: 0000000000000100 R14: 000000000000001d R15: ffff8881003982d0 [ 6.016316] FS: 0000000000000000(0000) GS:ffff888408200000(0000) knlGS:0000000000000000 [ 6.020313] CS: e030 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 6.024313] CR2: ffffc900020ef000 CR3: 000000000220a000 CR4: 0000000000050660 [ 6.028314] Call Trace: [ 6.032313] cvt_gate_to_trap.part.7+0x3f/0x90 [ 6.036313] ? asm_exc_double_fault+0x30/0x30 [ 6.040313] xen_convert_trap_info+0x87/0xd0 [ 6.044313] xen_pv_cpu_up+0x17a/0x450 [ 6.048313] bringup_cpu+0x2b/0xc0 [ 6.052313] ? cpus_read_trylock+0x50/0x50 [ 6.056313] cpuhp_invoke_callback+0x80/0x4c0 [ 6.060313] _cpu_up+0xa7/0x140 [ 6.064313] cpu_up+0x98/0xd0 [ 6.068313] bringup_nonboot_cpus+0x4f/0x60 [ 6.072313] smp_init+0x26/0x79 [ 6.076313] kernel_init_freeable+0x103/0x258 [ 6.080313] ? rest_init+0xd0/0xd0 [ 6.084313] kernel_init+0xa/0x110 [ 6.088313] ret_from_fork+0x1f/0x30 [ 6.092313] ---[ end trace be9ecf17dceeb4f3 ]--- Reason is that there is no Xen pv trap entry for X86_TRAP_VC. Fix that by adding a generic trap handler for unknown traps and wire all unknown bare metal handlers to this generic handler, which will just crash the system in case such a trap will ever happen. Fixes: 0786138c78e793 ("x86/sev-es: Add a Runtime #VC Exception Handler") Cc: # v5.10 Signed-off-by: Juergen Gross Reviewed-by: Andrew Cooper Signed-off-by: Juergen Gross --- arch/x86/include/asm/idtentry.h | 1 + arch/x86/xen/enlighten_pv.c | 15 ++++++++++++++- arch/x86/xen/xen-asm.S | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h index b2442eb0ac2f8..eb01c2618a9df 100644 --- a/arch/x86/include/asm/idtentry.h +++ b/arch/x86/include/asm/idtentry.h @@ -616,6 +616,7 @@ DECLARE_IDTENTRY_VC(X86_TRAP_VC, exc_vmm_communication); #ifdef CONFIG_XEN_PV DECLARE_IDTENTRY_XENCB(X86_TRAP_OTHER, exc_xen_hypervisor_callback); +DECLARE_IDTENTRY_RAW(X86_TRAP_OTHER, exc_xen_unknown_trap); #endif /* Device interrupts common/spurious */ diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 4409306364dc3..9a5a50cdaab59 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -583,6 +583,13 @@ DEFINE_IDTENTRY_RAW(xenpv_exc_debug) exc_debug(regs); } +DEFINE_IDTENTRY_RAW(exc_xen_unknown_trap) +{ + /* This should never happen and there is no way to handle it. */ + pr_err("Unknown trap in Xen PV mode."); + BUG(); +} + struct trap_array_entry { void (*orig)(void); void (*xen)(void); @@ -631,6 +638,7 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist) { unsigned int nr; bool ist_okay = false; + bool found = false; /* * Replace trap handler addresses by Xen specific ones. @@ -645,6 +653,7 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist) if (*addr == entry->orig) { *addr = entry->xen; ist_okay = entry->ist_okay; + found = true; break; } } @@ -655,9 +664,13 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist) nr = (*addr - (void *)early_idt_handler_array[0]) / EARLY_IDT_HANDLER_SIZE; *addr = (void *)xen_early_idt_handler_array[nr]; + found = true; } - if (WARN_ON(ist != 0 && !ist_okay)) + if (!found) + *addr = (void *)xen_asm_exc_xen_unknown_trap; + + if (WARN_ON(found && ist != 0 && !ist_okay)) return false; return true; diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 1cb0e84b91610..53cf8aa35032d 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S @@ -178,6 +178,7 @@ xen_pv_trap asm_exc_simd_coprocessor_error #ifdef CONFIG_IA32_EMULATION xen_pv_trap entry_INT80_compat #endif +xen_pv_trap asm_exc_xen_unknown_trap xen_pv_trap asm_exc_xen_hypervisor_callback __INIT -- GitLab From 03a58ea5905fdbd93ff9e52e670d802600ba38cd Mon Sep 17 00:00:00 2001 From: Kent Gibson Date: Thu, 21 Jan 2021 22:10:38 +0800 Subject: [PATCH 0738/1084] gpiolib: cdev: clear debounce period if line set to output When set_config changes a line from input to output debounce is implicitly disabled, as debounce makes no sense for outputs, but the debounce period is not being cleared and is still reported in the line info. So clear the debounce period when the debouncer is stopped in edge_detector_stop(). Fixes: 65cff7046406 ("gpiolib: cdev: support setting debounce") Cc: stable@vger.kernel.org Signed-off-by: Kent Gibson Reviewed-by: Linus Walleij Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-cdev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 1a7b51163528b..1631727bf0da1 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -776,6 +776,8 @@ static void edge_detector_stop(struct line *line) cancel_delayed_work_sync(&line->work); WRITE_ONCE(line->sw_debounced, 0); WRITE_ONCE(line->eflags, 0); + if (line->desc) + WRITE_ONCE(line->desc->debounce_period_us, 0); /* do not change line->level - see comment in debounced_value() */ } -- GitLab From ded055eea679139f11bd808795d9697b430d1c7d Mon Sep 17 00:00:00 2001 From: Judy Hsiao Date: Wed, 27 Jan 2021 21:56:20 +0800 Subject: [PATCH 0739/1084] ASoC: max98373: Fixes a typo in max98373_feedback_get The snd_soc_put_volsw in max98373_feedback_get is a typo, change it to snd_soc_get_volsw. Fixes: 349dd23931d1 ("ASoC: max98373: don't access volatile registers in bias level off") Signed-off-by: Judy Hsiao Link: https://lore.kernel.org/r/20210127135620.1143942-1-judyhsiao@chromium.org Signed-off-by: Mark Brown --- sound/soc/codecs/max98373.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c index 31d571d4fac1c..746c829312b87 100644 --- a/sound/soc/codecs/max98373.c +++ b/sound/soc/codecs/max98373.c @@ -190,7 +190,7 @@ static int max98373_feedback_get(struct snd_kcontrol *kcontrol, } } - return snd_soc_put_volsw(kcontrol, ucontrol); + return snd_soc_get_volsw(kcontrol, ucontrol); } static const struct snd_kcontrol_new max98373_snd_controls[] = { -- GitLab From 40fb68c7725aee024ed99ad38504f5d25820c6f0 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 27 Jan 2021 09:50:41 -0600 Subject: [PATCH 0740/1084] Revert "PCI/ASPM: Save/restore L1SS Capability for suspend/resume" This reverts commit 4257f7e008ea394fcecc050f1569c3503b8bcc15. Kenneth reported that after 4257f7e008ea, he sees a torrent of disk I/O errors on his NVMe device after suspend/resume until a reboot. Link: https://lore.kernel.org/linux-pci/20201228040513.GA611645@bjorn-Precision-5520/ Reported-by: Kenneth R. Crudup Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 7 ------- drivers/pci/pci.h | 4 ---- drivers/pci/pcie/aspm.c | 44 ----------------------------------------- 3 files changed, 55 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b9fecc25d2131..790393d1e3189 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1558,7 +1558,6 @@ int pci_save_state(struct pci_dev *dev) return i; pci_save_ltr_state(dev); - pci_save_aspm_l1ss_state(dev); pci_save_dpc_state(dev); pci_save_aer_state(dev); pci_save_ptm_state(dev); @@ -1665,7 +1664,6 @@ void pci_restore_state(struct pci_dev *dev) * LTR itself (in the PCIe capability). */ pci_restore_ltr_state(dev); - pci_restore_aspm_l1ss_state(dev); pci_restore_pcie_state(dev); pci_restore_pasid_state(dev); @@ -3353,11 +3351,6 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev) if (error) pci_err(dev, "unable to allocate suspend buffer for LTR\n"); - error = pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_L1SS, - 2 * sizeof(u32)); - if (error) - pci_err(dev, "unable to allocate suspend buffer for ASPM-L1SS\n"); - pci_allocate_vc_save_buffers(dev); } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 5c59365092fa4..a7bdf0b1d45db 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -582,15 +582,11 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev); void pcie_aspm_exit_link_state(struct pci_dev *pdev); void pcie_aspm_pm_state_change(struct pci_dev *pdev); void pcie_aspm_powersave_config_link(struct pci_dev *pdev); -void pci_save_aspm_l1ss_state(struct pci_dev *dev); -void pci_restore_aspm_l1ss_state(struct pci_dev *dev); #else static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { } static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { } -static inline void pci_save_aspm_l1ss_state(struct pci_dev *dev) { } -static inline void pci_restore_aspm_l1ss_state(struct pci_dev *dev) { } #endif #ifdef CONFIG_PCIE_ECRC diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index a08e7d6dc2488..ac0557a305aff 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -734,50 +734,6 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state) PCI_L1SS_CTL1_L1SS_MASK, val); } -void pci_save_aspm_l1ss_state(struct pci_dev *dev) -{ - int aspm_l1ss; - struct pci_cap_saved_state *save_state; - u32 *cap; - - if (!pci_is_pcie(dev)) - return; - - aspm_l1ss = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_L1SS); - if (!aspm_l1ss) - return; - - save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS); - if (!save_state) - return; - - cap = (u32 *)&save_state->cap.data[0]; - pci_read_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL1, cap++); - pci_read_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL2, cap++); -} - -void pci_restore_aspm_l1ss_state(struct pci_dev *dev) -{ - int aspm_l1ss; - struct pci_cap_saved_state *save_state; - u32 *cap; - - if (!pci_is_pcie(dev)) - return; - - aspm_l1ss = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_L1SS); - if (!aspm_l1ss) - return; - - save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS); - if (!save_state) - return; - - cap = (u32 *)&save_state->cap.data[0]; - pci_write_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL1, *cap++); - pci_write_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL2, *cap++); -} - static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) { pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, -- GitLab From 8dc932d3e8afb65e12eba7495f046c83884c49bf Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 26 Jan 2021 21:59:07 +0200 Subject: [PATCH 0741/1084] Revert "block: simplify set_init_blocksize" to regain lost performance The cited commit introduced a serious regression with SATA write speed, as found by bisecting. This patch reverts this commit, which restores write speed back to the values observed before this commit. The performance tests were done on a Helios4 NAS (2nd batch) with 4 HDDs (WD8003FFBX) using dd (bs=1M count=2000). "Direct" is a test with a single HDD, the rest are different RAID levels built over the first partitions of 4 HDDs. Test results are in MB/s, R is read, W is write. | Direct | RAID0 | RAID10 f2 | RAID10 n2 | RAID6 ----------------+--------+-------+-----------+-----------+-------- 9011495c9466 | R:256 | R:313 | R:276 | R:313 | R:323 (before faulty) | W:254 | W:253 | W:195 | W:204 | W:117 ----------------+--------+-------+-----------+-----------+-------- 5ff9f19231a0 | R:257 | R:398 | R:312 | R:344 | R:391 (faulty commit) | W:154 | W:122 | W:67.7 | W:66.6 | W:67.2 ----------------+--------+-------+-----------+-----------+-------- 5.10.10 | R:256 | R:401 | R:312 | R:356 | R:375 unpatched | W:149 | W:123 | W:64 | W:64.1 | W:61.5 ----------------+--------+-------+-----------+-----------+-------- 5.10.10 | R:255 | R:396 | R:312 | R:340 | R:393 patched | W:247 | W:274 | W:220 | W:225 | W:121 Applying this patch doesn't hurt read performance, while improves the write speed by 1.5x - 3.5x (more impact on RAID tests). The write speed is restored back to the state before the faulty commit, and even a bit higher in RAID tests (which aren't HDD-bound on this device) - that is likely related to other optimizations done between the faulty commit and 5.10.10 which also improved the read speed. Signed-off-by: Maxim Mikityanskiy Fixes: 5ff9f19231a0 ("block: simplify set_init_blocksize") Cc: Christoph Hellwig Cc: Jens Axboe Acked-by: Christoph Hellwig Signed-off-by: Jens Axboe --- fs/block_dev.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 3b8963e228a1b..235b5042672e9 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -130,7 +130,15 @@ EXPORT_SYMBOL(truncate_bdev_range); static void set_init_blocksize(struct block_device *bdev) { - bdev->bd_inode->i_blkbits = blksize_bits(bdev_logical_block_size(bdev)); + unsigned int bsize = bdev_logical_block_size(bdev); + loff_t size = i_size_read(bdev->bd_inode); + + while (bsize < PAGE_SIZE) { + if (size & bsize) + break; + bsize <<= 1; + } + bdev->bd_inode->i_blkbits = blksize_bits(bsize); } int set_blocksize(struct block_device *bdev, int size) -- GitLab From 6195ba09822c87cad09189bbf550d0fbe714687a Mon Sep 17 00:00:00 2001 From: Hao Xu Date: Wed, 27 Jan 2021 15:14:09 +0800 Subject: [PATCH 0742/1084] io_uring: fix flush cqring overflow list while TASK_INTERRUPTIBLE Abaci reported the follow warning: [ 27.073425] do not call blocking ops when !TASK_RUNNING; state=1 set at [] prepare_to_wait_exclusive+0x3a/0xc0 [ 27.075805] WARNING: CPU: 0 PID: 951 at kernel/sched/core.c:7853 __might_sleep+0x80/0xa0 [ 27.077604] Modules linked in: [ 27.078379] CPU: 0 PID: 951 Comm: a.out Not tainted 5.11.0-rc3+ #1 [ 27.079637] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 [ 27.080852] RIP: 0010:__might_sleep+0x80/0xa0 [ 27.081835] Code: 65 48 8b 04 25 80 71 01 00 48 8b 90 c0 15 00 00 48 8b 70 18 48 c7 c7 08 39 95 82 c6 05 f9 5f de 08 01 48 89 d1 e8 00 c6 fa ff 0b eb bf 41 0f b6 f5 48 c7 c7 40 23 c9 82 e8 f3 48 ec 00 eb a7 [ 27.084521] RSP: 0018:ffffc90000fe3ce8 EFLAGS: 00010286 [ 27.085350] RAX: 0000000000000000 RBX: ffffffff82956083 RCX: 0000000000000000 [ 27.086348] RDX: ffff8881057a0000 RSI: ffffffff8118cc9e RDI: ffff88813bc28570 [ 27.087598] RBP: 00000000000003a7 R08: 0000000000000001 R09: 0000000000000001 [ 27.088819] R10: ffffc90000fe3e00 R11: 00000000fffef9f0 R12: 0000000000000000 [ 27.089819] R13: 0000000000000000 R14: ffff88810576eb80 R15: ffff88810576e800 [ 27.091058] FS: 00007f7b144cf740(0000) GS:ffff88813bc00000(0000) knlGS:0000000000000000 [ 27.092775] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 27.093796] CR2: 00000000022da7b8 CR3: 000000010b928002 CR4: 00000000003706f0 [ 27.094778] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 27.095780] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 27.097011] Call Trace: [ 27.097685] __mutex_lock+0x5d/0xa30 [ 27.098565] ? prepare_to_wait_exclusive+0x71/0xc0 [ 27.099412] ? io_cqring_overflow_flush.part.101+0x6d/0x70 [ 27.100441] ? lockdep_hardirqs_on_prepare+0xe9/0x1c0 [ 27.101537] ? _raw_spin_unlock_irqrestore+0x2d/0x40 [ 27.102656] ? trace_hardirqs_on+0x46/0x110 [ 27.103459] ? io_cqring_overflow_flush.part.101+0x6d/0x70 [ 27.104317] io_cqring_overflow_flush.part.101+0x6d/0x70 [ 27.105113] io_cqring_wait+0x36e/0x4d0 [ 27.105770] ? find_held_lock+0x28/0xb0 [ 27.106370] ? io_uring_remove_task_files+0xa0/0xa0 [ 27.107076] __x64_sys_io_uring_enter+0x4fb/0x640 [ 27.107801] ? rcu_read_lock_sched_held+0x59/0xa0 [ 27.108562] ? lockdep_hardirqs_on_prepare+0xe9/0x1c0 [ 27.109684] ? syscall_enter_from_user_mode+0x26/0x70 [ 27.110731] do_syscall_64+0x2d/0x40 [ 27.111296] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 27.112056] RIP: 0033:0x7f7b13dc8239 [ 27.112663] Code: 01 00 48 81 c4 80 00 00 00 e9 f1 fe ff ff 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 3d 01 f0 ff ff 73 01 c3 48 8b 0d 27 ec 2c 00 f7 d8 64 89 01 48 [ 27.115113] RSP: 002b:00007ffd6d7f5c88 EFLAGS: 00000286 ORIG_RAX: 00000000000001aa [ 27.116562] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7b13dc8239 [ 27.117961] RDX: 000000000000478e RSI: 0000000000000000 RDI: 0000000000000003 [ 27.118925] RBP: 00007ffd6d7f5cb0 R08: 0000000020000040 R09: 0000000000000008 [ 27.119773] R10: 0000000000000001 R11: 0000000000000286 R12: 0000000000400480 [ 27.120614] R13: 00007ffd6d7f5d90 R14: 0000000000000000 R15: 0000000000000000 [ 27.121490] irq event stamp: 5635 [ 27.121946] hardirqs last enabled at (5643): [] console_unlock+0x5c4/0x740 [ 27.123476] hardirqs last disabled at (5652): [] console_unlock+0x4e7/0x740 [ 27.125192] softirqs last enabled at (5272): [] __do_softirq+0x3c5/0x5aa [ 27.126430] softirqs last disabled at (5267): [] asm_call_irq_on_stack+0xf/0x20 [ 27.127634] ---[ end trace 289d7e28fa60f928 ]--- This is caused by calling io_cqring_overflow_flush() which may sleep after calling prepare_to_wait_exclusive() which set task state to TASK_INTERRUPTIBLE Reported-by: Abaci Fixes: 6c503150ae33 ("io_uring: patch up IOPOLL overflow_flush sync") Reviewed-by: Pavel Begunkov Signed-off-by: Hao Xu Signed-off-by: Jens Axboe --- fs/io_uring.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index c218deaf73a9f..ae388cc528436 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -7268,14 +7268,18 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, TASK_INTERRUPTIBLE); /* make sure we run task_work before checking for signals */ ret = io_run_task_work_sig(); - if (ret > 0) + if (ret > 0) { + finish_wait(&ctx->wait, &iowq.wq); continue; + } else if (ret < 0) break; if (io_should_wake(&iowq)) break; - if (test_bit(0, &ctx->cq_check_overflow)) + if (test_bit(0, &ctx->cq_check_overflow)) { + finish_wait(&ctx->wait, &iowq.wq); continue; + } if (uts) { timeout = schedule_timeout(timeout); if (timeout == 0) { -- GitLab From d17405d52bacd14fe7fdbb10c0434934ea496914 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 25 Jan 2021 14:13:06 +1300 Subject: [PATCH 0743/1084] dma-mapping: benchmark: fix kernel crash when dma_map_single fails if dma_map_single() fails, kernel will give the below oops since task_struct has been destroyed and we are running into the memory corruption due to use-after-free in kthread_stop(): [ 48.095310] Unable to handle kernel paging request at virtual address 000000c473548040 [ 48.095736] Mem abort info: [ 48.095864] ESR = 0x96000004 [ 48.096025] EC = 0x25: DABT (current EL), IL = 32 bits [ 48.096268] SET = 0, FnV = 0 [ 48.096401] EA = 0, S1PTW = 0 [ 48.096538] Data abort info: [ 48.096659] ISV = 0, ISS = 0x00000004 [ 48.096820] CM = 0, WnR = 0 [ 48.097079] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000104639000 [ 48.098099] [000000c473548040] pgd=0000000000000000, p4d=0000000000000000 [ 48.098832] Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 48.099232] Modules linked in: [ 48.099387] CPU: 0 PID: 2 Comm: kthreadd Tainted: G W [ 48.099887] Hardware name: linux,dummy-virt (DT) [ 48.100078] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--) [ 48.100516] pc : __kmalloc_node+0x214/0x368 [ 48.100944] lr : __kmalloc_node+0x1f4/0x368 [ 48.101458] sp : ffff800011f0bb80 [ 48.101843] x29: ffff800011f0bb80 x28: ffff0000c0098ec0 [ 48.102330] x27: 0000000000000000 x26: 00000000001d4600 [ 48.102648] x25: ffff0000c0098ec0 x24: ffff800011b6a000 [ 48.102988] x23: 00000000ffffffff x22: ffff0000c0098ec0 [ 48.103333] x21: ffff8000101d7a54 x20: 0000000000000dc0 [ 48.103657] x19: ffff0000c0001e00 x18: 0000000000000000 [ 48.104069] x17: 0000000000000000 x16: 0000000000000000 [ 48.105449] x15: 000001aa0304e7b9 x14: 00000000000003b1 [ 48.106401] x13: ffff8000122d5000 x12: ffff80001228d000 [ 48.107296] x11: ffff0000c0154340 x10: 0000000000000000 [ 48.107862] x9 : ffff80000fffffff x8 : ffff0000c473527f [ 48.108326] x7 : ffff800011e62f58 x6 : ffff0000c01c8ed8 [ 48.108778] x5 : ffff0000c0098ec0 x4 : 0000000000000000 [ 48.109223] x3 : 00000000001d4600 x2 : 0000000000000040 [ 48.109656] x1 : 0000000000000001 x0 : ff0000c473548000 [ 48.110104] Call trace: [ 48.110287] __kmalloc_node+0x214/0x368 [ 48.110493] __vmalloc_node_range+0xc4/0x298 [ 48.110805] copy_process+0x2c8/0x15c8 [ 48.111133] kernel_clone+0x5c/0x3c0 [ 48.111373] kernel_thread+0x64/0x90 [ 48.111604] kthreadd+0x158/0x368 [ 48.111810] ret_from_fork+0x10/0x30 [ 48.112336] Code: 17ffffe9 b9402a62 b94008a1 11000421 (f8626802) [ 48.112884] ---[ end trace d4890e21e75419d5 ]--- Signed-off-by: Barry Song Signed-off-by: Christoph Hellwig --- kernel/dma/map_benchmark.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c index b1496e744c687..1b1b8ff875cb3 100644 --- a/kernel/dma/map_benchmark.c +++ b/kernel/dma/map_benchmark.c @@ -147,8 +147,10 @@ static int do_map_benchmark(struct map_benchmark_data *map) atomic64_set(&map->sum_sq_unmap, 0); atomic64_set(&map->loops, 0); - for (i = 0; i < threads; i++) + for (i = 0; i < threads; i++) { + get_task_struct(tsk[i]); wake_up_process(tsk[i]); + } msleep_interruptible(map->bparam.seconds * 1000); @@ -183,6 +185,8 @@ static int do_map_benchmark(struct map_benchmark_data *map) } out: + for (i = 0; i < threads; i++) + put_task_struct(tsk[i]); put_device(map->dev); kfree(tsk); return ret; -- GitLab From e32df142359fb6f4d27977b7652549f0844aa62f Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Mon, 25 Jan 2021 09:05:00 +0200 Subject: [PATCH 0744/1084] ASoC: Intel: adl: remove sof_fw_filename setting in ADL snd_soc_acpi_mach ADL will use sof-adl-s.ri if it is ADL-S platform. So let's use the default_fw_filename in pdata->desc for the ADL FW filename. Signed-off-by: Libin Yang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210125070500.807474-3-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-adl-match.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index 06b233d63b73a..0aca340ebc258 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -44,7 +44,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { .link_mask = 0x1, /* link0 required */ .links = adl_rvp, .drv_name = "sof_sdw", - .sof_fw_filename = "sof-adl.ri", .sof_tplg_filename = "sof-adl-rt711.tplg", }, {}, -- GitLab From daf12bee07b9e2f38216f58aca7ac4e4e66a7146 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 22 Jan 2021 06:52:18 +0100 Subject: [PATCH 0745/1084] arm64: dts: meson: switch TFLASH_VDD_EN pin to open drain on Odroid-C4 For the proper reboot Odroid-C4 board requires to switch TFLASH_VDD_EN pin to the high impedance mode, otherwise the board is stuck in the middle of loading early stages of the bootloader from SD card. This can be achieved by using the OPEN_DRAIN flag instead of the ACTIVE_HIGH, what will leave the pin in input mode to achieve high state (pin has the pull-up) and solve the issue. Suggested-by: Neil Armstrong Fixes: 326e57518b0d ("arm64: dts: meson-sm1: add support for Hardkernel ODROID-C4") Signed-off-by: Marek Szyprowski Acked-by: Martin Blumenstingl Signed-off-by: Kevin Hilman Link: https://lore.kernel.org/r/20210122055218.27241-1-m.szyprowski@samsung.com --- arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts index cf5a98f0e47c8..a712273c905af 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts @@ -52,7 +52,7 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - gpio = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>; + gpio = <&gpio_ao GPIOAO_3 GPIO_OPEN_DRAIN>; enable-active-high; regulator-always-on; }; -- GitLab From 89c7cb1608ac3c7ecc19436469f35ed12da97e1d Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Tue, 19 Jan 2021 18:52:03 +0800 Subject: [PATCH 0746/1084] of/device: Update dma_range_map only when dev has valid dma-ranges The commit e0d072782c73 ("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset") always update dma_range_map even though it was already set, like in the sunxi_mbus driver. the issue is reported at [1]. This patch avoid this(Updating it only when dev has valid dma-ranges). Meanwhile, dma_range_map contains the devices' dma_ranges information, This patch moves dma_range_map before of_iommu_configure. The iommu driver may need to know the dma_address requirements of its iommu consumer devices. [1] https://lore.kernel.org/linux-arm-kernel/5c7946f3-b56e-da00-a750-be097c7ceb32@arm.com/ CC: Frank Rowand Fixes: e0d072782c73 ("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset"), Suggested-by: Robin Murphy Signed-off-by: Yong Wu Signed-off-by: Paul Kocialkowski Reviewed-by: Rob Herring Reviewed-by: Robin Murphy Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20210119105203.15530-1-yong.wu@mediatek.com --- drivers/of/device.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/of/device.c b/drivers/of/device.c index aedfaaafd3e7e..1122daa8e2736 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -162,9 +162,11 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, mask = DMA_BIT_MASK(ilog2(end) + 1); dev->coherent_dma_mask &= mask; *dev->dma_mask &= mask; - /* ...but only set bus limit if we found valid dma-ranges earlier */ - if (!ret) + /* ...but only set bus limit and range map if we found valid dma-ranges earlier */ + if (!ret) { dev->bus_dma_limit = end; + dev->dma_range_map = map; + } coherent = of_dma_is_coherent(np); dev_dbg(dev, "device is%sdma coherent\n", @@ -172,6 +174,9 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, iommu = of_iommu_configure(dev, np, id); if (PTR_ERR(iommu) == -EPROBE_DEFER) { + /* Don't touch range map if it wasn't set from a valid dma-ranges */ + if (!ret) + dev->dma_range_map = NULL; kfree(map); return -EPROBE_DEFER; } @@ -181,7 +186,6 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, arch_setup_dma_ops(dev, dma_start, size, iommu, coherent); - dev->dma_range_map = map; return 0; } EXPORT_SYMBOL_GPL(of_dma_configure_id); -- GitLab From 20776b465c0c249f5e5b5b4fe077cd24ef1cda86 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Mon, 25 Jan 2021 13:41:16 +0100 Subject: [PATCH 0747/1084] net: switchdev: don't set port_obj_info->handled true when -EOPNOTSUPP It's not true that switchdev_port_obj_notify() only inspects the ->handled field of "struct switchdev_notifier_port_obj_info" if call_switchdev_blocking_notifiers() returns 0 - there's a WARN_ON() triggering for a non-zero return combined with ->handled not being true. But the real problem here is that -EOPNOTSUPP is not being properly handled. The wrapper functions switchdev_handle_port_obj_add() et al change a return value of -EOPNOTSUPP to 0, and the treatment of ->handled in switchdev_port_obj_notify() seems to be designed to change that back to -EOPNOTSUPP in case nobody actually acted on the notifier (i.e., everybody returned -EOPNOTSUPP). Currently, as soon as some device down the stack passes the check_cb() check, ->handled gets set to true, which means that switchdev_port_obj_notify() cannot actually ever return -EOPNOTSUPP. This, for example, means that the detection of hardware offload support in the MRP code is broken: switchdev_port_obj_add() used by br_mrp_switchdev_send_ring_test() always returns 0, so since the MRP code thinks the generation of MRP test frames has been offloaded, no such frames are actually put on the wire. Similarly, br_mrp_switchdev_set_ring_role() also always returns 0, causing mrp->ring_role_offloaded to be set to 1. To fix this, continue to set ->handled true if any callback returns success or any error distinct from -EOPNOTSUPP. But if all the callbacks return -EOPNOTSUPP, make sure that ->handled stays false, so the logic in switchdev_port_obj_notify() can propagate that information. Fixes: 9a9f26e8f7ea ("bridge: mrp: Connect MRP API with the switchdev API") Fixes: f30f0601eb93 ("switchdev: Add helpers to aid traversal through lower devices") Reviewed-by: Petr Machata Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20210125124116.102928-1-rasmus.villemoes@prevas.dk Signed-off-by: Jakub Kicinski --- net/switchdev/switchdev.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 23d8685453627..2c1ffc9ba2eb2 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -460,10 +460,11 @@ static int __switchdev_handle_port_obj_add(struct net_device *dev, extack = switchdev_notifier_info_to_extack(&port_obj_info->info); if (check_cb(dev)) { - /* This flag is only checked if the return value is success. */ - port_obj_info->handled = true; - return add_cb(dev, port_obj_info->obj, port_obj_info->trans, - extack); + err = add_cb(dev, port_obj_info->obj, port_obj_info->trans, + extack); + if (err != -EOPNOTSUPP) + port_obj_info->handled = true; + return err; } /* Switch ports might be stacked under e.g. a LAG. Ignore the @@ -515,9 +516,10 @@ static int __switchdev_handle_port_obj_del(struct net_device *dev, int err = -EOPNOTSUPP; if (check_cb(dev)) { - /* This flag is only checked if the return value is success. */ - port_obj_info->handled = true; - return del_cb(dev, port_obj_info->obj); + err = del_cb(dev, port_obj_info->obj); + if (err != -EOPNOTSUPP) + port_obj_info->handled = true; + return err; } /* Switch ports might be stacked under e.g. a LAG. Ignore the @@ -568,9 +570,10 @@ static int __switchdev_handle_port_attr_set(struct net_device *dev, int err = -EOPNOTSUPP; if (check_cb(dev)) { - port_attr_info->handled = true; - return set_cb(dev, port_attr_info->attr, - port_attr_info->trans); + err = set_cb(dev, port_attr_info->attr, port_attr_info->trans); + if (err != -EOPNOTSUPP) + port_attr_info->handled = true; + return err; } /* Switch ports might be stacked under e.g. a LAG. Ignore the -- GitLab From 3f96d644976825986a93b7b9fe6a9900a80f2e11 Mon Sep 17 00:00:00 2001 From: Vadim Fedorenko Date: Tue, 26 Jan 2021 03:02:14 +0300 Subject: [PATCH 0748/1084] net: decnet: fix netdev refcount leaking on error path On building the route there is an assumption that the destination could be local. In this case loopback_dev is used to get the address. If the address is still cannot be retrieved dn_route_output_slow returns EADDRNOTAVAIL with loopback_dev reference taken. Cannot find hash for the fixes tag because this code was introduced long time ago. I don't think that this bug has ever fired but the patch is done just to have a consistent code base. Signed-off-by: Vadim Fedorenko Link: https://lore.kernel.org/r/1611619334-20955-1-git-send-email-vfedorenko@novek.ru Signed-off-by: Jakub Kicinski --- net/decnet/dn_route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 4cac31d22a502..2193ae529e752 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1035,7 +1035,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowidn *o fld.saddr = dnet_select_source(dev_out, 0, RT_SCOPE_HOST); if (!fld.daddr) - goto out; + goto done; } fld.flowidn_oif = LOOPBACK_IFINDEX; res.type = RTN_LOCAL; -- GitLab From b770753c7b08f1f6008d0d364180fc123f7b25e2 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 26 Jan 2021 18:18:44 -0800 Subject: [PATCH 0749/1084] MAINTAINERS: add missing header for bonding include/net/bonding.h is missing from bonding entry. Link: https://lore.kernel.org/r/20210127021844.4071706-1-kuba@kernel.org Signed-off-by: Jakub Kicinski --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1a5facde5a908..964d0c03d4388 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3239,6 +3239,7 @@ L: netdev@vger.kernel.org S: Supported W: http://sourceforge.net/projects/bonding/ F: drivers/net/bonding/ +F: include/net/bonding.h F: include/uapi/linux/if_bonding.h BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER -- GitLab From e41aec79e62fa50f940cf222d1e9577f14e149dc Mon Sep 17 00:00:00 2001 From: Lijun Pan Date: Wed, 27 Jan 2021 19:34:42 -0600 Subject: [PATCH 0750/1084] ibmvnic: Ensure that CRQ entry read are correctly ordered Ensure that received Command-Response Queue (CRQ) entries are properly read in order by the driver. dma_rmb barrier has been added before accessing the CRQ descriptor to ensure the entire descriptor is read before processing. Fixes: 032c5e82847a ("Driver for IBM System i/p VNIC protocol") Signed-off-by: Lijun Pan Link: https://lore.kernel.org/r/20210128013442.88319-1-ljp@linux.ibm.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/ibm/ibmvnic.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 9778c83150f1c..8820c98ea891e 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -5084,6 +5084,12 @@ static void ibmvnic_tasklet(struct tasklet_struct *t) while (!done) { /* Pull all the valid messages off the CRQ */ while ((crq = ibmvnic_next_crq(adapter)) != NULL) { + /* This barrier makes sure ibmvnic_next_crq()'s + * crq->generic.first & IBMVNIC_CRQ_CMD_RSP is loaded + * before ibmvnic_handle_crq()'s + * switch(gen_crq->first) and switch(gen_crq->cmd). + */ + dma_rmb(); ibmvnic_handle_crq(crq, adapter); crq->generic.first = 0; } -- GitLab From 2cea4a7a1885bd0c765089afc14f7ff0eb77864e Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Thu, 22 Nov 2018 16:40:49 +0100 Subject: [PATCH 0751/1084] scripts: use pkg-config to locate libcrypto Otherwise build fails if the headers are not in the default location. While at it also ask pkg-config for the libs, with fallback to the existing value. Signed-off-by: Rolf Eike Beer Cc: stable@vger.kernel.org # 5.6.x Signed-off-by: Masahiro Yamada --- scripts/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile b/scripts/Makefile index b5418ec587fbd..9de3c03b94aa7 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -3,6 +3,9 @@ # scripts contains sources for various helper programs used throughout # the kernel for the build process. +CRYPTO_LIBS = $(shell pkg-config --libs libcrypto 2> /dev/null || echo -lcrypto) +CRYPTO_CFLAGS = $(shell pkg-config --cflags libcrypto 2> /dev/null) + hostprogs-always-$(CONFIG_BUILD_BIN2C) += bin2c hostprogs-always-$(CONFIG_KALLSYMS) += kallsyms hostprogs-always-$(BUILD_C_RECORDMCOUNT) += recordmcount @@ -14,8 +17,9 @@ hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include -HOSTLDLIBS_sign-file = -lcrypto -HOSTLDLIBS_extract-cert = -lcrypto +HOSTLDLIBS_sign-file = $(CRYPTO_LIBS) +HOSTCFLAGS_extract-cert.o = $(CRYPTO_CFLAGS) +HOSTLDLIBS_extract-cert = $(CRYPTO_LIBS) ifdef CONFIG_UNWINDER_ORC ifeq ($(ARCH),x86_64) -- GitLab From ae9162e2be767240065b2f16c3061fc0a3622f61 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 27 Jan 2021 04:15:40 +0900 Subject: [PATCH 0752/1084] Revert "checkpatch: add check for keyword 'boolean' in Kconfig definitions" This reverts commit 327953e9af6c59ad111b28359e59e3ec0cbd71b6. You cannot use 'boolean' since commit b92d804a5179 ("kconfig: drop 'boolean' keyword"). This check is no longer needed. Signed-off-by: Masahiro Yamada Acked-by: Joe Perches --- scripts/checkpatch.pl | 7 ------- 1 file changed, 7 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 92e888ed939f9..1afe3af1cc097 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3390,13 +3390,6 @@ sub process { } } -# discourage the use of boolean for type definition attributes of Kconfig options - if ($realfile =~ /Kconfig/ && - $line =~ /^\+\s*\bboolean\b/) { - WARN("CONFIG_TYPE_BOOLEAN", - "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); - } - if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { my $flag = $1; -- GitLab From 181f494888d5b178ffda41bed965f187d5e5c432 Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Wed, 27 Jan 2021 20:44:51 -0600 Subject: [PATCH 0753/1084] KVM: x86: fix CPUID entries returned by KVM_GET_CPUID2 ioctl Recent commit 255cbecfe0 modified struct kvm_vcpu_arch to make 'cpuid_entries' a pointer to an array of kvm_cpuid_entry2 entries rather than embedding the array in the struct. KVM_SET_CPUID and KVM_SET_CPUID2 were updated accordingly, but KVM_GET_CPUID2 was missed. As a result, KVM_GET_CPUID2 currently returns random fields from struct kvm_vcpu_arch to userspace rather than the expected CPUID values. Fix this by treating 'cpuid_entries' as a pointer when copying its contents to userspace buffer. Fixes: 255cbecfe0c9 ("KVM: x86: allocate vcpu->arch.cpuid_entries dynamically") Cc: Vitaly Kuznetsov Signed-off-by: Michael Roth Message-Id: <20210128024451.1816770-1-michael.roth@amd.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini --- arch/x86/kvm/cpuid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 13036cf0b9124..38172ca627d36 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -321,7 +321,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, if (cpuid->nent < vcpu->arch.cpuid_nent) goto out; r = -EFAULT; - if (copy_to_user(entries, &vcpu->arch.cpuid_entries, + if (copy_to_user(entries, vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2))) goto out; return 0; -- GitLab From e478d6029dca9d8462f426aee0d32896ef64f10f Mon Sep 17 00:00:00 2001 From: Christoph Schemmel Date: Wed, 27 Jan 2021 20:58:46 +0100 Subject: [PATCH 0754/1084] USB: serial: option: Adding support for Cinterion MV31 Adding support for Cinterion device MV31 for enumeration with PID 0x00B3 and 0x00B7. usb-devices output for 0x00B3 T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 6 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=ef(misc ) Sub=02 Prot=01 MxPS= 9 #Cfgs= 1 P: Vendor=1e2d ProdID=00b3 Rev=04.14 S: Manufacturer=Cinterion S: Product=Cinterion PID 0x00B3 USB Mobile Broadband S: SerialNumber=b3246eed C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#=0x0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim I: If#=0x1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x3 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=cdc_wdm I: If#=0x4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option usb-devices output for 0x00B7 T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 5 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=ef(misc ) Sub=02 Prot=01 MxPS= 9 #Cfgs= 1 P: Vendor=1e2d ProdID=00b7 Rev=04.14 S: Manufacturer=Cinterion S: Product=Cinterion PID 0x00B3 USB Mobile Broadband S: SerialNumber=b3246eed C: #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#=0x0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan I: If#=0x1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option Signed-off-by: Christoph Schemmel Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3fe959104311b..2049e66f34a3f 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -425,6 +425,8 @@ static void option_instat_callback(struct urb *urb); #define CINTERION_PRODUCT_AHXX_2RMNET 0x0084 #define CINTERION_PRODUCT_AHXX_AUDIO 0x0085 #define CINTERION_PRODUCT_CLS8 0x00b0 +#define CINTERION_PRODUCT_MV31_MBIM 0x00b3 +#define CINTERION_PRODUCT_MV31_RMNET 0x00b7 /* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c @@ -1914,6 +1916,10 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) }, { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */ { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_MBIM, 0xff), + .driver_info = RSVD(3)}, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff), + .driver_info = RSVD(0)}, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), .driver_info = RSVD(4) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), -- GitLab From 13f445d65955f388499f00851dc9a86280970f7c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 12 Jan 2021 23:35:50 -0800 Subject: [PATCH 0755/1084] libnvdimm/namespace: Fix visibility of namespace resource attribute Legacy pmem namespaces lost support for the "resource" attribute when the code was cleaned up to put the permission visibility in the declaration. Restore this by listing 'resource' in the default attributes. A new ndctl regression test for pfn_to_online_page() corner cases builds on this fix. Fixes: bfd2e9140656 ("libnvdimm: Simplify root read-only definition for the 'resource' attribute") Cc: Vishal Verma Cc: Dave Jiang Cc: Ira Weiny Cc: Link: https://lore.kernel.org/r/161052334995.1805594.12054873528154362921.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- drivers/nvdimm/namespace_devs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index 6da67f4d641a2..2403b71b601e9 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -1635,11 +1635,11 @@ static umode_t namespace_visible(struct kobject *kobj, return a->mode; } - if (a == &dev_attr_nstype.attr || a == &dev_attr_size.attr - || a == &dev_attr_holder.attr - || a == &dev_attr_holder_class.attr - || a == &dev_attr_force_raw.attr - || a == &dev_attr_mode.attr) + /* base is_namespace_io() attributes */ + if (a == &dev_attr_nstype.attr || a == &dev_attr_size.attr || + a == &dev_attr_holder.attr || a == &dev_attr_holder_class.attr || + a == &dev_attr_force_raw.attr || a == &dev_attr_mode.attr || + a == &dev_attr_resource.attr) return a->mode; return 0; -- GitLab From 9a27e109a391c9021147553b97c3fe4356e2261c Mon Sep 17 00:00:00 2001 From: Santosh Sivaraj Date: Tue, 22 Dec 2020 09:52:34 +0530 Subject: [PATCH 0756/1084] testing/nvdimm: Add test module for non-nfit platforms The current test module cannot be used for testing platforms (make check) that do not have support for NFIT. In order to get the ndctl tests working, we need a module which can emulate NVDIMM devices without relying on ACPI/NFIT. The aim of this proposed module is to implement a similar functionality to the existing module but without the ACPI dependencies. This RFC series is split into reviewable and compilable chunks. This patch adds a new driver and registers two nvdimm bus needed for ndctl make check. Signed-off-by: Santosh Sivaraj Link: https://lore.kernel.org/r/20201222042240.2983755-2-santosh@fossix.org Signed-off-by: Dan Williams --- tools/testing/nvdimm/config_check.c | 3 +- tools/testing/nvdimm/test/Kbuild | 6 +- tools/testing/nvdimm/test/ndtest.c | 206 ++++++++++++++++++++++++++++ tools/testing/nvdimm/test/ndtest.h | 16 +++ 4 files changed, 229 insertions(+), 2 deletions(-) create mode 100644 tools/testing/nvdimm/test/ndtest.c create mode 100644 tools/testing/nvdimm/test/ndtest.h diff --git a/tools/testing/nvdimm/config_check.c b/tools/testing/nvdimm/config_check.c index cac891028cd1b..3e3a5f5188640 100644 --- a/tools/testing/nvdimm/config_check.c +++ b/tools/testing/nvdimm/config_check.c @@ -12,7 +12,8 @@ void check(void) BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BTT)); BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_PFN)); BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BLK)); - BUILD_BUG_ON(!IS_MODULE(CONFIG_ACPI_NFIT)); + if (IS_ENABLED(CONFIG_ACPI_NFIT)) + BUILD_BUG_ON(!IS_MODULE(CONFIG_ACPI_NFIT)); BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX)); BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX_PMEM)); } diff --git a/tools/testing/nvdimm/test/Kbuild b/tools/testing/nvdimm/test/Kbuild index 75baebf8f4ba1..197bcb2b7f351 100644 --- a/tools/testing/nvdimm/test/Kbuild +++ b/tools/testing/nvdimm/test/Kbuild @@ -5,5 +5,9 @@ ccflags-y += -I$(srctree)/drivers/acpi/nfit/ obj-m += nfit_test.o obj-m += nfit_test_iomap.o -nfit_test-y := nfit.o +ifeq ($(CONFIG_ACPI_NFIT),m) + nfit_test-y := nfit.o +else + nfit_test-y := ndtest.o +endif nfit_test_iomap-y := iomap.o diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c new file mode 100644 index 0000000000000..f89d74fdcdeec --- /dev/null +++ b/tools/testing/nvdimm/test/ndtest.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../watermark.h" +#include "nfit_test.h" +#include "ndtest.h" + +enum { + DIMM_SIZE = SZ_32M, + LABEL_SIZE = SZ_128K, + NUM_INSTANCES = 2, + NUM_DCR = 4, +}; + +static struct ndtest_priv *instances[NUM_INSTANCES]; +static struct class *ndtest_dimm_class; + +static inline struct ndtest_priv *to_ndtest_priv(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + return container_of(pdev, struct ndtest_priv, pdev); +} + +static int ndtest_ctl(struct nvdimm_bus_descriptor *nd_desc, + struct nvdimm *nvdimm, unsigned int cmd, void *buf, + unsigned int buf_len, int *cmd_rc) +{ + struct ndtest_dimm *dimm; + int _cmd_rc; + + if (!cmd_rc) + cmd_rc = &_cmd_rc; + + *cmd_rc = 0; + + if (!nvdimm) + return -EINVAL; + + dimm = nvdimm_provider_data(nvdimm); + if (!dimm) + return -EINVAL; + + switch (cmd) { + case ND_CMD_GET_CONFIG_SIZE: + case ND_CMD_GET_CONFIG_DATA: + case ND_CMD_SET_CONFIG_DATA: + default: + return -EINVAL; + } + + return 0; +} + +static int ndtest_bus_register(struct ndtest_priv *p) +{ + p->bus_desc.ndctl = ndtest_ctl; + p->bus_desc.module = THIS_MODULE; + p->bus_desc.provider_name = NULL; + + p->bus = nvdimm_bus_register(&p->pdev.dev, &p->bus_desc); + if (!p->bus) { + dev_err(&p->pdev.dev, "Error creating nvdimm bus %pOF\n", p->dn); + return -ENOMEM; + } + + return 0; +} + +static int ndtest_remove(struct platform_device *pdev) +{ + struct ndtest_priv *p = to_ndtest_priv(&pdev->dev); + + nvdimm_bus_unregister(p->bus); + return 0; +} + +static int ndtest_probe(struct platform_device *pdev) +{ + struct ndtest_priv *p; + + p = to_ndtest_priv(&pdev->dev); + if (ndtest_bus_register(p)) + return -ENOMEM; + + platform_set_drvdata(pdev, p); + + return 0; +} + +static const struct platform_device_id ndtest_id[] = { + { KBUILD_MODNAME }, + { }, +}; + +static struct platform_driver ndtest_driver = { + .probe = ndtest_probe, + .remove = ndtest_remove, + .driver = { + .name = KBUILD_MODNAME, + }, + .id_table = ndtest_id, +}; + +static void ndtest_release(struct device *dev) +{ + struct ndtest_priv *p = to_ndtest_priv(dev); + + kfree(p); +} + +static void cleanup_devices(void) +{ + int i; + + for (i = 0; i < NUM_INSTANCES; i++) + if (instances[i]) + platform_device_unregister(&instances[i]->pdev); + + nfit_test_teardown(); + + if (ndtest_dimm_class) + class_destroy(ndtest_dimm_class); +} + +static __init int ndtest_init(void) +{ + int rc, i; + + pmem_test(); + libnvdimm_test(); + device_dax_test(); + dax_pmem_test(); + dax_pmem_core_test(); +#ifdef CONFIG_DEV_DAX_PMEM_COMPAT + dax_pmem_compat_test(); +#endif + + ndtest_dimm_class = class_create(THIS_MODULE, "nfit_test_dimm"); + if (IS_ERR(ndtest_dimm_class)) { + rc = PTR_ERR(ndtest_dimm_class); + goto err_register; + } + + /* Each instance can be taken as a bus, which can have multiple dimms */ + for (i = 0; i < NUM_INSTANCES; i++) { + struct ndtest_priv *priv; + struct platform_device *pdev; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + rc = -ENOMEM; + goto err_register; + } + + INIT_LIST_HEAD(&priv->resources); + pdev = &priv->pdev; + pdev->name = KBUILD_MODNAME; + pdev->id = i; + pdev->dev.release = ndtest_release; + rc = platform_device_register(pdev); + if (rc) { + put_device(&pdev->dev); + goto err_register; + } + get_device(&pdev->dev); + + instances[i] = priv; + } + + rc = platform_driver_register(&ndtest_driver); + if (rc) + goto err_register; + + return 0; + +err_register: + pr_err("Error registering platform device\n"); + cleanup_devices(); + + return rc; +} + +static __exit void ndtest_exit(void) +{ + cleanup_devices(); + platform_driver_unregister(&ndtest_driver); +} + +module_init(ndtest_init); +module_exit(ndtest_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("IBM Corporation"); diff --git a/tools/testing/nvdimm/test/ndtest.h b/tools/testing/nvdimm/test/ndtest.h new file mode 100644 index 0000000000000..831ac5c65f505 --- /dev/null +++ b/tools/testing/nvdimm/test/ndtest.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef NDTEST_H +#define NDTEST_H + +#include +#include + +struct ndtest_priv { + struct platform_device pdev; + struct device_node *dn; + struct list_head resources; + struct nvdimm_bus_descriptor bus_desc; + struct nvdimm_bus *bus; +}; + +#endif /* NDTEST_H */ -- GitLab From 107b04e970cae754100efb99a5312c321208ca03 Mon Sep 17 00:00:00 2001 From: Santosh Sivaraj Date: Tue, 22 Dec 2020 09:52:35 +0530 Subject: [PATCH 0757/1084] ndtest: Add compatability string to treat it as PAPR family Since this module is written to be platform agnostic, the module is made part of the PAPR_FAMILY. ndctl identifies the family using the compatible string inside of_node dir-entry. Signed-off-by: Santosh Sivaraj Link: https://lore.kernel.org/r/20201222042240.2983755-3-santosh@fossix.org Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/ndtest.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c index f89d74fdcdeec..001527b37a239 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -65,11 +65,34 @@ static int ndtest_ctl(struct nvdimm_bus_descriptor *nd_desc, return 0; } +static ssize_t compatible_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "nvdimm_test"); +} +static DEVICE_ATTR_RO(compatible); + +static struct attribute *of_node_attributes[] = { + &dev_attr_compatible.attr, + NULL +}; + +static const struct attribute_group of_node_attribute_group = { + .name = "of_node", + .attrs = of_node_attributes, +}; + +static const struct attribute_group *ndtest_attribute_groups[] = { + &of_node_attribute_group, + NULL, +}; + static int ndtest_bus_register(struct ndtest_priv *p) { p->bus_desc.ndctl = ndtest_ctl; p->bus_desc.module = THIS_MODULE; p->bus_desc.provider_name = NULL; + p->bus_desc.attr_groups = ndtest_attribute_groups; p->bus = nvdimm_bus_register(&p->pdev.dev, &p->bus_desc); if (!p->bus) { -- GitLab From 9399ab61ad82154911563dd8635c585e3f24b16a Mon Sep 17 00:00:00 2001 From: Santosh Sivaraj Date: Tue, 22 Dec 2020 09:52:36 +0530 Subject: [PATCH 0758/1084] ndtest: Add dimms to the two buses A config array is used to hold the dimms for each bus. These dimms are registered with nvdimm, and new nvdimms are created on the buses. Signed-off-by: Santosh Sivaraj Link: https://lore.kernel.org/r/20201222042240.2983755-4-santosh@fossix.org Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/ndtest.c | 258 +++++++++++++++++++++++++++++ tools/testing/nvdimm/test/ndtest.h | 36 ++++ 2 files changed, 294 insertions(+) diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c index 001527b37a239..a82790013f8a9 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -25,8 +25,83 @@ enum { NUM_DCR = 4, }; +#define NDTEST_SCM_DIMM_CMD_MASK \ + ((1ul << ND_CMD_GET_CONFIG_SIZE) | \ + (1ul << ND_CMD_GET_CONFIG_DATA) | \ + (1ul << ND_CMD_SET_CONFIG_DATA) | \ + (1ul << ND_CMD_CALL)) + +#define NFIT_DIMM_HANDLE(node, socket, imc, chan, dimm) \ + (((node & 0xfff) << 16) | ((socket & 0xf) << 12) \ + | ((imc & 0xf) << 8) | ((chan & 0xf) << 4) | (dimm & 0xf)) + +static DEFINE_SPINLOCK(ndtest_lock); static struct ndtest_priv *instances[NUM_INSTANCES]; static struct class *ndtest_dimm_class; +static struct gen_pool *ndtest_pool; + +static struct ndtest_dimm dimm_group1[] = { + { + .size = DIMM_SIZE, + .handle = NFIT_DIMM_HANDLE(0, 0, 0, 0, 0), + .uuid_str = "1e5c75d2-b618-11ea-9aa3-507b9ddc0f72", + .physical_id = 0, + .num_formats = 2, + }, + { + .size = DIMM_SIZE, + .handle = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1), + .uuid_str = "1c4d43ac-b618-11ea-be80-507b9ddc0f72", + .physical_id = 1, + .num_formats = 2, + }, + { + .size = DIMM_SIZE, + .handle = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0), + .uuid_str = "a9f17ffc-b618-11ea-b36d-507b9ddc0f72", + .physical_id = 2, + .num_formats = 2, + }, + { + .size = DIMM_SIZE, + .handle = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1), + .uuid_str = "b6b83b22-b618-11ea-8aae-507b9ddc0f72", + .physical_id = 3, + .num_formats = 2, + }, + { + .size = DIMM_SIZE, + .handle = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0), + .uuid_str = "bf9baaee-b618-11ea-b181-507b9ddc0f72", + .physical_id = 4, + .num_formats = 2, + }, +}; + +static struct ndtest_dimm dimm_group2[] = { + { + .size = DIMM_SIZE, + .handle = NFIT_DIMM_HANDLE(1, 0, 0, 0, 0), + .uuid_str = "ca0817e2-b618-11ea-9db3-507b9ddc0f72", + .physical_id = 0, + .num_formats = 1, + }, +}; + +static struct ndtest_config bus_configs[NUM_INSTANCES] = { + /* bus 1 */ + { + .dimm_start = 0, + .dimm_count = ARRAY_SIZE(dimm_group1), + .dimms = dimm_group1, + }, + /* bus 2 */ + { + .dimm_start = ARRAY_SIZE(dimm_group1), + .dimm_count = ARRAY_SIZE(dimm_group2), + .dimms = dimm_group2, + }, +}; static inline struct ndtest_priv *to_ndtest_priv(struct device *dev) { @@ -65,6 +140,152 @@ static int ndtest_ctl(struct nvdimm_bus_descriptor *nd_desc, return 0; } +static void ndtest_release_resource(void *data) +{ + struct nfit_test_resource *res = data; + + spin_lock(&ndtest_lock); + list_del(&res->list); + spin_unlock(&ndtest_lock); + + if (resource_size(&res->res) >= DIMM_SIZE) + gen_pool_free(ndtest_pool, res->res.start, + resource_size(&res->res)); + vfree(res->buf); + kfree(res); +} + +static void *ndtest_alloc_resource(struct ndtest_priv *p, size_t size, + dma_addr_t *dma) +{ + dma_addr_t __dma; + void *buf; + struct nfit_test_resource *res; + struct genpool_data_align data = { + .align = SZ_128M, + }; + + res = kzalloc(sizeof(*res), GFP_KERNEL); + if (!res) + return NULL; + + buf = vmalloc(size); + if (size >= DIMM_SIZE) + __dma = gen_pool_alloc_algo(ndtest_pool, size, + gen_pool_first_fit_align, &data); + else + __dma = (unsigned long) buf; + + if (!__dma) + goto buf_err; + + INIT_LIST_HEAD(&res->list); + res->dev = &p->pdev.dev; + res->buf = buf; + res->res.start = __dma; + res->res.end = __dma + size - 1; + res->res.name = "NFIT"; + spin_lock_init(&res->lock); + INIT_LIST_HEAD(&res->requests); + spin_lock(&ndtest_lock); + list_add(&res->list, &p->resources); + spin_unlock(&ndtest_lock); + + if (dma) + *dma = __dma; + + if (!devm_add_action(&p->pdev.dev, ndtest_release_resource, res)) + return res->buf; + +buf_err: + if (__dma && size >= DIMM_SIZE) + gen_pool_free(ndtest_pool, __dma, size); + if (buf) + vfree(buf); + kfree(res); + + return NULL; +} + +static void put_dimms(void *data) +{ + struct ndtest_priv *p = data; + int i; + + for (i = 0; i < p->config->dimm_count; i++) + if (p->config->dimms[i].dev) { + device_unregister(p->config->dimms[i].dev); + p->config->dimms[i].dev = NULL; + } +} + +static int ndtest_dimm_register(struct ndtest_priv *priv, + struct ndtest_dimm *dimm, int id) +{ + struct device *dev = &priv->pdev.dev; + unsigned long dimm_flags = dimm->flags; + + if (dimm->num_formats > 1) { + set_bit(NDD_ALIASING, &dimm_flags); + set_bit(NDD_LABELING, &dimm_flags); + } + + dimm->nvdimm = nvdimm_create(priv->bus, dimm, NULL, dimm_flags, + NDTEST_SCM_DIMM_CMD_MASK, 0, NULL); + if (!dimm->nvdimm) { + dev_err(dev, "Error creating DIMM object for %pOF\n", priv->dn); + return -ENXIO; + } + + dimm->dev = device_create_with_groups(ndtest_dimm_class, + &priv->pdev.dev, + 0, dimm, NULL, + "test_dimm%d", id); + if (!dimm->dev) { + pr_err("Could not create dimm device attributes\n"); + return -ENOMEM; + } + + return 0; +} + +static int ndtest_nvdimm_init(struct ndtest_priv *p) +{ + struct ndtest_dimm *d; + void *res; + int i, id; + + for (i = 0; i < p->config->dimm_count; i++) { + d = &p->config->dimms[i]; + d->id = id = p->config->dimm_start + i; + res = ndtest_alloc_resource(p, LABEL_SIZE, NULL); + if (!res) + return -ENOMEM; + + d->label_area = res; + sprintf(d->label_area, "label%d", id); + d->config_size = LABEL_SIZE; + + if (!ndtest_alloc_resource(p, d->size, + &p->dimm_dma[id])) + return -ENOMEM; + + if (!ndtest_alloc_resource(p, LABEL_SIZE, + &p->label_dma[id])) + return -ENOMEM; + + if (!ndtest_alloc_resource(p, LABEL_SIZE, + &p->dcr_dma[id])) + return -ENOMEM; + + d->address = p->dimm_dma[id]; + + ndtest_dimm_register(p, d, id); + } + + return 0; +} + static ssize_t compatible_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -89,6 +310,8 @@ static const struct attribute_group *ndtest_attribute_groups[] = { static int ndtest_bus_register(struct ndtest_priv *p) { + p->config = &bus_configs[p->pdev.id]; + p->bus_desc.ndctl = ndtest_ctl; p->bus_desc.module = THIS_MODULE; p->bus_desc.provider_name = NULL; @@ -114,14 +337,34 @@ static int ndtest_remove(struct platform_device *pdev) static int ndtest_probe(struct platform_device *pdev) { struct ndtest_priv *p; + int rc; p = to_ndtest_priv(&pdev->dev); if (ndtest_bus_register(p)) return -ENOMEM; + p->dcr_dma = devm_kcalloc(&p->pdev.dev, NUM_DCR, + sizeof(dma_addr_t), GFP_KERNEL); + p->label_dma = devm_kcalloc(&p->pdev.dev, NUM_DCR, + sizeof(dma_addr_t), GFP_KERNEL); + p->dimm_dma = devm_kcalloc(&p->pdev.dev, NUM_DCR, + sizeof(dma_addr_t), GFP_KERNEL); + + rc = ndtest_nvdimm_init(p); + if (rc) + goto err; + + rc = devm_add_action_or_reset(&pdev->dev, put_dimms, p); + if (rc) + goto err; + platform_set_drvdata(pdev, p); return 0; + +err: + pr_err("%s:%d Failed nvdimm init\n", __func__, __LINE__); + return rc; } static const struct platform_device_id ndtest_id[] = { @@ -155,6 +398,10 @@ static void cleanup_devices(void) nfit_test_teardown(); + if (ndtest_pool) + gen_pool_destroy(ndtest_pool); + + if (ndtest_dimm_class) class_destroy(ndtest_dimm_class); } @@ -178,6 +425,17 @@ static __init int ndtest_init(void) goto err_register; } + ndtest_pool = gen_pool_create(ilog2(SZ_4M), NUMA_NO_NODE); + if (!ndtest_pool) { + rc = -ENOMEM; + goto err_register; + } + + if (gen_pool_add(ndtest_pool, SZ_4G, SZ_4G, NUMA_NO_NODE)) { + rc = -ENOMEM; + goto err_register; + } + /* Each instance can be taken as a bus, which can have multiple dimms */ for (i = 0; i < NUM_INSTANCES; i++) { struct ndtest_priv *priv; diff --git a/tools/testing/nvdimm/test/ndtest.h b/tools/testing/nvdimm/test/ndtest.h index 831ac5c65f505..e607d72ffed11 100644 --- a/tools/testing/nvdimm/test/ndtest.h +++ b/tools/testing/nvdimm/test/ndtest.h @@ -5,12 +5,48 @@ #include #include +struct ndtest_config; + struct ndtest_priv { struct platform_device pdev; struct device_node *dn; struct list_head resources; struct nvdimm_bus_descriptor bus_desc; struct nvdimm_bus *bus; + struct ndtest_config *config; + + dma_addr_t *dcr_dma; + dma_addr_t *label_dma; + dma_addr_t *dimm_dma; +}; + +struct ndtest_dimm { + struct device *dev; + struct nvdimm *nvdimm; + struct ndtest_blk_mmio *mmio; + struct nd_region *blk_region; + + dma_addr_t address; + unsigned long long flags; + unsigned long config_size; + void *label_area; + char *uuid_str; + + unsigned int size; + unsigned int handle; + unsigned int fail_cmd; + unsigned int physical_id; + unsigned int num_formats; + int id; + int fail_cmd_code; + u8 no_alias; +}; + +struct ndtest_config { + struct ndtest_dimm *dimms; + unsigned int dimm_count; + unsigned int dimm_start; + u8 num_regions; }; #endif /* NDTEST_H */ -- GitLab From 5e41396f723004a4e5710a0bb03259a443be1971 Mon Sep 17 00:00:00 2001 From: Santosh Sivaraj Date: Tue, 22 Dec 2020 09:52:37 +0530 Subject: [PATCH 0759/1084] ndtest: Add dimm attributes This patch adds sysfs attributes for nvdimm and the dimm device. Signed-off-by: Santosh Sivaraj Link: https://lore.kernel.org/r/20201222042240.2983755-5-santosh@fossix.org Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/ndtest.c | 202 ++++++++++++++++++++++++++++- 1 file changed, 200 insertions(+), 2 deletions(-) diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c index a82790013f8a9..f7682e1d3efe6 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -219,6 +219,203 @@ static void put_dimms(void *data) } } +static ssize_t handle_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ndtest_dimm *dimm = dev_get_drvdata(dev); + + return sprintf(buf, "%#x\n", dimm->handle); +} +static DEVICE_ATTR_RO(handle); + +static ssize_t fail_cmd_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ndtest_dimm *dimm = dev_get_drvdata(dev); + + return sprintf(buf, "%#x\n", dimm->fail_cmd); +} + +static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ndtest_dimm *dimm = dev_get_drvdata(dev); + unsigned long val; + ssize_t rc; + + rc = kstrtol(buf, 0, &val); + if (rc) + return rc; + + dimm->fail_cmd = val; + + return size; +} +static DEVICE_ATTR_RW(fail_cmd); + +static ssize_t fail_cmd_code_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ndtest_dimm *dimm = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", dimm->fail_cmd_code); +} + +static ssize_t fail_cmd_code_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ndtest_dimm *dimm = dev_get_drvdata(dev); + unsigned long val; + ssize_t rc; + + rc = kstrtol(buf, 0, &val); + if (rc) + return rc; + + dimm->fail_cmd_code = val; + return size; +} +static DEVICE_ATTR_RW(fail_cmd_code); + +static struct attribute *dimm_attributes[] = { + &dev_attr_handle.attr, + &dev_attr_fail_cmd.attr, + &dev_attr_fail_cmd_code.attr, + NULL, +}; + +static struct attribute_group dimm_attribute_group = { + .attrs = dimm_attributes, +}; + +static const struct attribute_group *dimm_attribute_groups[] = { + &dimm_attribute_group, + NULL, +}; + +static ssize_t phys_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); + + return sprintf(buf, "%#x\n", dimm->physical_id); +} +static DEVICE_ATTR_RO(phys_id); + +static ssize_t vendor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "0x1234567\n"); +} +static DEVICE_ATTR_RO(vendor); + +static ssize_t id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); + + return sprintf(buf, "%04x-%02x-%04x-%08x", 0xabcd, + 0xa, 2016, ~(dimm->handle)); +} +static DEVICE_ATTR_RO(id); + +static ssize_t nvdimm_handle_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); + + return sprintf(buf, "%#x\n", dimm->handle); +} + +static struct device_attribute dev_attr_nvdimm_show_handle = { + .attr = { .name = "handle", .mode = 0444 }, + .show = nvdimm_handle_show, +}; + +static ssize_t subsystem_vendor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "0x%04x\n", 0); +} +static DEVICE_ATTR_RO(subsystem_vendor); + +static ssize_t dirty_shutdown_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", 42); +} +static DEVICE_ATTR_RO(dirty_shutdown); + +static ssize_t formats_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); + + return sprintf(buf, "%d\n", dimm->num_formats); +} +static DEVICE_ATTR_RO(formats); + +static ssize_t format_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); + + if (dimm->num_formats > 1) + return sprintf(buf, "0x201\n"); + + return sprintf(buf, "0x101\n"); +} +static DEVICE_ATTR_RO(format); + +static ssize_t format1_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "0x301\n"); +} +static DEVICE_ATTR_RO(format1); + +static umode_t ndtest_nvdimm_attr_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nvdimm *nvdimm = to_nvdimm(dev); + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); + + if (a == &dev_attr_format1.attr && dimm->num_formats <= 1) + return 0; + + return a->mode; +} + +static struct attribute *ndtest_nvdimm_attributes[] = { + &dev_attr_nvdimm_show_handle.attr, + &dev_attr_vendor.attr, + &dev_attr_id.attr, + &dev_attr_phys_id.attr, + &dev_attr_subsystem_vendor.attr, + &dev_attr_dirty_shutdown.attr, + &dev_attr_formats.attr, + &dev_attr_format.attr, + &dev_attr_format1.attr, + NULL, +}; + +static const struct attribute_group ndtest_nvdimm_attribute_group = { + .name = "papr", + .attrs = ndtest_nvdimm_attributes, + .is_visible = ndtest_nvdimm_attr_visible, +}; + +static const struct attribute_group *ndtest_nvdimm_attribute_groups[] = { + &ndtest_nvdimm_attribute_group, + NULL, +}; + static int ndtest_dimm_register(struct ndtest_priv *priv, struct ndtest_dimm *dimm, int id) { @@ -230,7 +427,8 @@ static int ndtest_dimm_register(struct ndtest_priv *priv, set_bit(NDD_LABELING, &dimm_flags); } - dimm->nvdimm = nvdimm_create(priv->bus, dimm, NULL, dimm_flags, + dimm->nvdimm = nvdimm_create(priv->bus, dimm, + ndtest_nvdimm_attribute_groups, dimm_flags, NDTEST_SCM_DIMM_CMD_MASK, 0, NULL); if (!dimm->nvdimm) { dev_err(dev, "Error creating DIMM object for %pOF\n", priv->dn); @@ -239,7 +437,7 @@ static int ndtest_dimm_register(struct ndtest_priv *priv, dimm->dev = device_create_with_groups(ndtest_dimm_class, &priv->pdev.dev, - 0, dimm, NULL, + 0, dimm, dimm_attribute_groups, "test_dimm%d", id); if (!dimm->dev) { pr_err("Could not create dimm device attributes\n"); -- GitLab From 6fde2d4c8b25cec9589a4a58fd524b9d4e40c4b6 Mon Sep 17 00:00:00 2001 From: Santosh Sivaraj Date: Tue, 22 Dec 2020 09:52:38 +0530 Subject: [PATCH 0760/1084] ndtest: Add regions and mappings to the test buses The bus config array is used to hold the regions and the respective mappings. This config based interface enables to change the dimm/region/namespace layouts easily. Signed-off-by: Santosh Sivaraj Link: https://lore.kernel.org/r/20201222042240.2983755-6-santosh@fossix.org Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/ndtest.c | 352 +++++++++++++++++++++++++++++ tools/testing/nvdimm/test/ndtest.h | 26 +++ 2 files changed, 378 insertions(+) diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c index f7682e1d3efe6..821296b59bdc2 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -23,6 +23,7 @@ enum { LABEL_SIZE = SZ_128K, NUM_INSTANCES = 2, NUM_DCR = 4, + NDTEST_MAX_MAPPING = 6, }; #define NDTEST_SCM_DIMM_CMD_MASK \ @@ -88,18 +89,161 @@ static struct ndtest_dimm dimm_group2[] = { }, }; +static struct ndtest_mapping region0_mapping[] = { + { + .dimm = 0, + .position = 0, + .start = 0, + .size = SZ_16M, + }, + { + .dimm = 1, + .position = 1, + .start = 0, + .size = SZ_16M, + } +}; + +static struct ndtest_mapping region1_mapping[] = { + { + .dimm = 0, + .position = 0, + .start = SZ_16M, + .size = SZ_16M, + }, + { + .dimm = 1, + .position = 1, + .start = SZ_16M, + .size = SZ_16M, + }, + { + .dimm = 2, + .position = 2, + .start = SZ_16M, + .size = SZ_16M, + }, + { + .dimm = 3, + .position = 3, + .start = SZ_16M, + .size = SZ_16M, + }, +}; + +static struct ndtest_mapping region2_mapping[] = { + { + .dimm = 0, + .position = 0, + .start = 0, + .size = DIMM_SIZE, + }, +}; + +static struct ndtest_mapping region3_mapping[] = { + { + .dimm = 1, + .start = 0, + .size = DIMM_SIZE, + } +}; + +static struct ndtest_mapping region4_mapping[] = { + { + .dimm = 2, + .start = 0, + .size = DIMM_SIZE, + } +}; + +static struct ndtest_mapping region5_mapping[] = { + { + .dimm = 3, + .start = 0, + .size = DIMM_SIZE, + } +}; + +static struct ndtest_region bus0_regions[] = { + { + .type = ND_DEVICE_NAMESPACE_PMEM, + .num_mappings = ARRAY_SIZE(region0_mapping), + .mapping = region0_mapping, + .size = DIMM_SIZE, + .range_index = 1, + }, + { + .type = ND_DEVICE_NAMESPACE_PMEM, + .num_mappings = ARRAY_SIZE(region1_mapping), + .mapping = region1_mapping, + .size = DIMM_SIZE * 2, + .range_index = 2, + }, + { + .type = ND_DEVICE_NAMESPACE_BLK, + .num_mappings = ARRAY_SIZE(region2_mapping), + .mapping = region2_mapping, + .size = DIMM_SIZE, + .range_index = 3, + }, + { + .type = ND_DEVICE_NAMESPACE_BLK, + .num_mappings = ARRAY_SIZE(region3_mapping), + .mapping = region3_mapping, + .size = DIMM_SIZE, + .range_index = 4, + }, + { + .type = ND_DEVICE_NAMESPACE_BLK, + .num_mappings = ARRAY_SIZE(region4_mapping), + .mapping = region4_mapping, + .size = DIMM_SIZE, + .range_index = 5, + }, + { + .type = ND_DEVICE_NAMESPACE_BLK, + .num_mappings = ARRAY_SIZE(region5_mapping), + .mapping = region5_mapping, + .size = DIMM_SIZE, + .range_index = 6, + }, +}; + +static struct ndtest_mapping region6_mapping[] = { + { + .dimm = 0, + .position = 0, + .start = 0, + .size = DIMM_SIZE, + }, +}; + +static struct ndtest_region bus1_regions[] = { + { + .type = ND_DEVICE_NAMESPACE_IO, + .num_mappings = ARRAY_SIZE(region6_mapping), + .mapping = region6_mapping, + .size = DIMM_SIZE, + .range_index = 1, + }, +}; + static struct ndtest_config bus_configs[NUM_INSTANCES] = { /* bus 1 */ { .dimm_start = 0, .dimm_count = ARRAY_SIZE(dimm_group1), .dimms = dimm_group1, + .regions = bus0_regions, + .num_regions = ARRAY_SIZE(bus0_regions), }, /* bus 2 */ { .dimm_start = ARRAY_SIZE(dimm_group1), .dimm_count = ARRAY_SIZE(dimm_group2), .dimms = dimm_group2, + .regions = bus1_regions, + .num_regions = ARRAY_SIZE(bus1_regions), }, }; @@ -140,6 +284,95 @@ static int ndtest_ctl(struct nvdimm_bus_descriptor *nd_desc, return 0; } +static int ndtest_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa, + void *iobuf, u64 len, int rw) +{ + struct ndtest_dimm *dimm = ndbr->blk_provider_data; + struct ndtest_blk_mmio *mmio = dimm->mmio; + struct nd_region *nd_region = &ndbr->nd_region; + unsigned int lane; + + if (!mmio) + return -ENOMEM; + + lane = nd_region_acquire_lane(nd_region); + if (rw) + memcpy(mmio->base + dpa, iobuf, len); + else { + memcpy(iobuf, mmio->base + dpa, len); + arch_invalidate_pmem(mmio->base + dpa, len); + } + + nd_region_release_lane(nd_region, lane); + + return 0; +} + +static int ndtest_blk_region_enable(struct nvdimm_bus *nvdimm_bus, + struct device *dev) +{ + struct nd_blk_region *ndbr = to_nd_blk_region(dev); + struct nvdimm *nvdimm; + struct ndtest_dimm *dimm; + struct ndtest_blk_mmio *mmio; + + nvdimm = nd_blk_region_to_dimm(ndbr); + dimm = nvdimm_provider_data(nvdimm); + + nd_blk_region_set_provider_data(ndbr, dimm); + dimm->blk_region = to_nd_region(dev); + + mmio = devm_kzalloc(dev, sizeof(struct ndtest_blk_mmio), GFP_KERNEL); + if (!mmio) + return -ENOMEM; + + mmio->base = (void __iomem *) devm_nvdimm_memremap( + dev, dimm->address, 12, nd_blk_memremap_flags(ndbr)); + if (!mmio->base) { + dev_err(dev, "%s failed to map blk dimm\n", nvdimm_name(nvdimm)); + return -ENOMEM; + } + mmio->size = dimm->size; + mmio->base_offset = 0; + + dimm->mmio = mmio; + + return 0; +} + +static struct nfit_test_resource *ndtest_resource_lookup(resource_size_t addr) +{ + int i; + + for (i = 0; i < NUM_INSTANCES; i++) { + struct nfit_test_resource *n, *nfit_res = NULL; + struct ndtest_priv *t = instances[i]; + + if (!t) + continue; + spin_lock(&ndtest_lock); + list_for_each_entry(n, &t->resources, list) { + if (addr >= n->res.start && (addr < n->res.start + + resource_size(&n->res))) { + nfit_res = n; + break; + } else if (addr >= (unsigned long) n->buf + && (addr < (unsigned long) n->buf + + resource_size(&n->res))) { + nfit_res = n; + break; + } + } + spin_unlock(&ndtest_lock); + if (nfit_res) + return nfit_res; + } + + pr_warn("Failed to get resource\n"); + + return NULL; +} + static void ndtest_release_resource(void *data) { struct nfit_test_resource *res = data; @@ -207,6 +440,119 @@ static void *ndtest_alloc_resource(struct ndtest_priv *p, size_t size, return NULL; } +static ssize_t range_index_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nd_region *nd_region = to_nd_region(dev); + struct ndtest_region *region = nd_region_provider_data(nd_region); + + return sprintf(buf, "%d\n", region->range_index); +} +static DEVICE_ATTR_RO(range_index); + +static struct attribute *ndtest_region_attributes[] = { + &dev_attr_range_index.attr, + NULL, +}; + +static const struct attribute_group ndtest_region_attribute_group = { + .name = "papr", + .attrs = ndtest_region_attributes, +}; + +static const struct attribute_group *ndtest_region_attribute_groups[] = { + &ndtest_region_attribute_group, + NULL, +}; + +static int ndtest_create_region(struct ndtest_priv *p, + struct ndtest_region *region) +{ + struct nd_mapping_desc mappings[NDTEST_MAX_MAPPING]; + struct nd_blk_region_desc ndbr_desc; + struct nd_interleave_set *nd_set; + struct nd_region_desc *ndr_desc; + struct resource res; + int i, ndimm = region->mapping[0].dimm; + u64 uuid[2]; + + memset(&res, 0, sizeof(res)); + memset(&mappings, 0, sizeof(mappings)); + memset(&ndbr_desc, 0, sizeof(ndbr_desc)); + ndr_desc = &ndbr_desc.ndr_desc; + + if (!ndtest_alloc_resource(p, region->size, &res.start)) + return -ENOMEM; + + res.end = res.start + region->size - 1; + ndr_desc->mapping = mappings; + ndr_desc->res = &res; + ndr_desc->provider_data = region; + ndr_desc->attr_groups = ndtest_region_attribute_groups; + + if (uuid_parse(p->config->dimms[ndimm].uuid_str, (uuid_t *)uuid)) { + pr_err("failed to parse UUID\n"); + return -ENXIO; + } + + nd_set = devm_kzalloc(&p->pdev.dev, sizeof(*nd_set), GFP_KERNEL); + if (!nd_set) + return -ENOMEM; + + nd_set->cookie1 = cpu_to_le64(uuid[0]); + nd_set->cookie2 = cpu_to_le64(uuid[1]); + nd_set->altcookie = nd_set->cookie1; + ndr_desc->nd_set = nd_set; + + if (region->type == ND_DEVICE_NAMESPACE_BLK) { + mappings[0].start = 0; + mappings[0].size = DIMM_SIZE; + mappings[0].nvdimm = p->config->dimms[ndimm].nvdimm; + + ndr_desc->mapping = &mappings[0]; + ndr_desc->num_mappings = 1; + ndr_desc->num_lanes = 1; + ndbr_desc.enable = ndtest_blk_region_enable; + ndbr_desc.do_io = ndtest_blk_do_io; + region->region = nvdimm_blk_region_create(p->bus, ndr_desc); + + goto done; + } + + for (i = 0; i < region->num_mappings; i++) { + ndimm = region->mapping[i].dimm; + mappings[i].start = region->mapping[i].start; + mappings[i].size = region->mapping[i].size; + mappings[i].position = region->mapping[i].position; + mappings[i].nvdimm = p->config->dimms[ndimm].nvdimm; + } + + ndr_desc->num_mappings = region->num_mappings; + region->region = nvdimm_pmem_region_create(p->bus, ndr_desc); + +done: + if (!region->region) { + dev_err(&p->pdev.dev, "Error registering region %pR\n", + ndr_desc->res); + return -ENXIO; + } + + return 0; +} + +static int ndtest_init_regions(struct ndtest_priv *p) +{ + int i, ret = 0; + + for (i = 0; i < p->config->num_regions; i++) { + ret = ndtest_create_region(p, &p->config->regions[i]); + if (ret) + return ret; + } + + return 0; +} + static void put_dimms(void *data) { struct ndtest_priv *p = data; @@ -552,6 +898,10 @@ static int ndtest_probe(struct platform_device *pdev) if (rc) goto err; + rc = ndtest_init_regions(p); + if (rc) + goto err; + rc = devm_add_action_or_reset(&pdev->dev, put_dimms, p); if (rc) goto err; @@ -617,6 +967,8 @@ static __init int ndtest_init(void) dax_pmem_compat_test(); #endif + nfit_test_setup(ndtest_resource_lookup, NULL); + ndtest_dimm_class = class_create(THIS_MODULE, "nfit_test_dimm"); if (IS_ERR(ndtest_dimm_class)) { rc = PTR_ERR(ndtest_dimm_class); diff --git a/tools/testing/nvdimm/test/ndtest.h b/tools/testing/nvdimm/test/ndtest.h index e607d72ffed11..8f27ad6f7319f 100644 --- a/tools/testing/nvdimm/test/ndtest.h +++ b/tools/testing/nvdimm/test/ndtest.h @@ -20,6 +20,15 @@ struct ndtest_priv { dma_addr_t *dimm_dma; }; +struct ndtest_blk_mmio { + void __iomem *base; + u64 size; + u64 base_offset; + u32 line_size; + u32 num_lines; + u32 table_size; +}; + struct ndtest_dimm { struct device *dev; struct nvdimm *nvdimm; @@ -42,8 +51,25 @@ struct ndtest_dimm { u8 no_alias; }; +struct ndtest_mapping { + u64 start; + u64 size; + u8 position; + u8 dimm; +}; + +struct ndtest_region { + struct nd_region *region; + struct ndtest_mapping *mapping; + u64 size; + u8 type; + u8 num_mappings; + u8 range_index; +}; + struct ndtest_config { struct ndtest_dimm *dimms; + struct ndtest_region *regions; unsigned int dimm_count; unsigned int dimm_start; u8 num_regions; -- GitLab From 14ccef10e53e4c303570d2ee2d49e45be1118e99 Mon Sep 17 00:00:00 2001 From: Santosh Sivaraj Date: Tue, 22 Dec 2020 09:52:39 +0530 Subject: [PATCH 0761/1084] ndtest: Add nvdimm control functions Add functions to support ND_CMD_GET_CONFIG_SIZE, ND_CMD_SET_CONFIG_DATA and ND_CMD_GET_CONFIG_DATA. Signed-off-by: Santosh Sivaraj Link: https://lore.kernel.org/r/20201222042240.2983755-7-santosh@fossix.org Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/ndtest.c | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c index 821296b59bdc2..dc1e3636616a6 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -254,6 +254,45 @@ static inline struct ndtest_priv *to_ndtest_priv(struct device *dev) return container_of(pdev, struct ndtest_priv, pdev); } +static int ndtest_config_get(struct ndtest_dimm *p, unsigned int buf_len, + struct nd_cmd_get_config_data_hdr *hdr) +{ + unsigned int len; + + if ((hdr->in_offset + hdr->in_length) > LABEL_SIZE) + return -EINVAL; + + hdr->status = 0; + len = min(hdr->in_length, LABEL_SIZE - hdr->in_offset); + memcpy(hdr->out_buf, p->label_area + hdr->in_offset, len); + + return buf_len - len; +} + +static int ndtest_config_set(struct ndtest_dimm *p, unsigned int buf_len, + struct nd_cmd_set_config_hdr *hdr) +{ + unsigned int len; + + if ((hdr->in_offset + hdr->in_length) > LABEL_SIZE) + return -EINVAL; + + len = min(hdr->in_length, LABEL_SIZE - hdr->in_offset); + memcpy(p->label_area + hdr->in_offset, hdr->in_buf, len); + + return buf_len - len; +} + +static int ndtest_get_config_size(struct ndtest_dimm *dimm, unsigned int buf_len, + struct nd_cmd_get_config_size *size) +{ + size->status = 0; + size->max_xfer = 8; + size->config_size = dimm->config_size; + + return 0; +} + static int ndtest_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc) @@ -275,12 +314,24 @@ static int ndtest_ctl(struct nvdimm_bus_descriptor *nd_desc, switch (cmd) { case ND_CMD_GET_CONFIG_SIZE: + *cmd_rc = ndtest_get_config_size(dimm, buf_len, buf); + break; case ND_CMD_GET_CONFIG_DATA: + *cmd_rc = ndtest_config_get(dimm, buf_len, buf); + break; case ND_CMD_SET_CONFIG_DATA: + *cmd_rc = ndtest_config_set(dimm, buf_len, buf); + break; default: return -EINVAL; } + /* Failures for a DIMM can be injected using fail_cmd and + * fail_cmd_code, see the device attributes below + */ + if ((1 << cmd) & dimm->fail_cmd) + return dimm->fail_cmd_code ? dimm->fail_cmd_code : -EIO; + return 0; } -- GitLab From 50f558a5fe16b385cf1427b2a96149f4f68952d9 Mon Sep 17 00:00:00 2001 From: Santosh Sivaraj Date: Tue, 22 Dec 2020 09:52:40 +0530 Subject: [PATCH 0762/1084] ndtest: Add papr health related flags sysfs attibutes to show health related flags are added. Signed-off-by: Santosh Sivaraj Link: https://lore.kernel.org/r/20201222042240.2983755-8-santosh@fossix.org Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/ndtest.c | 41 ++++++++++++++++++++++++++++++ tools/testing/nvdimm/test/ndtest.h | 31 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c index dc1e3636616a6..6862915f1fb0c 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -86,6 +86,9 @@ static struct ndtest_dimm dimm_group2[] = { .uuid_str = "ca0817e2-b618-11ea-9db3-507b9ddc0f72", .physical_id = 0, .num_formats = 1, + .flags = PAPR_PMEM_UNARMED | PAPR_PMEM_EMPTY | + PAPR_PMEM_SAVE_FAILED | PAPR_PMEM_SHUTDOWN_DIRTY | + PAPR_PMEM_HEALTH_FATAL, }, }; @@ -789,6 +792,40 @@ static umode_t ndtest_nvdimm_attr_visible(struct kobject *kobj, return a->mode; } +static ssize_t flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); + struct seq_buf s; + u64 flags; + + flags = dimm->flags; + + seq_buf_init(&s, buf, PAGE_SIZE); + if (flags & PAPR_PMEM_UNARMED_MASK) + seq_buf_printf(&s, "not_armed "); + + if (flags & PAPR_PMEM_BAD_SHUTDOWN_MASK) + seq_buf_printf(&s, "flush_fail "); + + if (flags & PAPR_PMEM_BAD_RESTORE_MASK) + seq_buf_printf(&s, "restore_fail "); + + if (flags & PAPR_PMEM_SAVE_MASK) + seq_buf_printf(&s, "save_fail "); + + if (flags & PAPR_PMEM_SMART_EVENT_MASK) + seq_buf_printf(&s, "smart_notify "); + + + if (seq_buf_used(&s)) + seq_buf_printf(&s, "\n"); + + return seq_buf_used(&s); +} +static DEVICE_ATTR_RO(flags); + static struct attribute *ndtest_nvdimm_attributes[] = { &dev_attr_nvdimm_show_handle.attr, &dev_attr_vendor.attr, @@ -799,6 +836,7 @@ static struct attribute *ndtest_nvdimm_attributes[] = { &dev_attr_formats.attr, &dev_attr_format.attr, &dev_attr_format1.attr, + &dev_attr_flags.attr, NULL, }; @@ -824,6 +862,9 @@ static int ndtest_dimm_register(struct ndtest_priv *priv, set_bit(NDD_LABELING, &dimm_flags); } + if (dimm->flags & PAPR_PMEM_UNARMED_MASK) + set_bit(NDD_UNARMED, &dimm_flags); + dimm->nvdimm = nvdimm_create(priv->bus, dimm, ndtest_nvdimm_attribute_groups, dimm_flags, NDTEST_SCM_DIMM_CMD_MASK, 0, NULL); diff --git a/tools/testing/nvdimm/test/ndtest.h b/tools/testing/nvdimm/test/ndtest.h index 8f27ad6f7319f..2c54c9cbb90c7 100644 --- a/tools/testing/nvdimm/test/ndtest.h +++ b/tools/testing/nvdimm/test/ndtest.h @@ -5,6 +5,37 @@ #include #include +/* SCM device is unable to persist memory contents */ +#define PAPR_PMEM_UNARMED (1ULL << (63 - 0)) +/* SCM device failed to persist memory contents */ +#define PAPR_PMEM_SHUTDOWN_DIRTY (1ULL << (63 - 1)) +/* SCM device contents are not persisted from previous IPL */ +#define PAPR_PMEM_EMPTY (1ULL << (63 - 3)) +#define PAPR_PMEM_HEALTH_CRITICAL (1ULL << (63 - 4)) +/* SCM device will be garded off next IPL due to failure */ +#define PAPR_PMEM_HEALTH_FATAL (1ULL << (63 - 5)) +/* SCM contents cannot persist due to current platform health status */ +#define PAPR_PMEM_HEALTH_UNHEALTHY (1ULL << (63 - 6)) + +/* Bits status indicators for health bitmap indicating unarmed dimm */ +#define PAPR_PMEM_UNARMED_MASK (PAPR_PMEM_UNARMED | \ + PAPR_PMEM_HEALTH_UNHEALTHY) + +#define PAPR_PMEM_SAVE_FAILED (1ULL << (63 - 10)) + +/* Bits status indicators for health bitmap indicating unflushed dimm */ +#define PAPR_PMEM_BAD_SHUTDOWN_MASK (PAPR_PMEM_SHUTDOWN_DIRTY) + +/* Bits status indicators for health bitmap indicating unrestored dimm */ +#define PAPR_PMEM_BAD_RESTORE_MASK (PAPR_PMEM_EMPTY) + +/* Bit status indicators for smart event notification */ +#define PAPR_PMEM_SMART_EVENT_MASK (PAPR_PMEM_HEALTH_CRITICAL | \ + PAPR_PMEM_HEALTH_FATAL | \ + PAPR_PMEM_HEALTH_UNHEALTHY) + +#define PAPR_PMEM_SAVE_MASK (PAPR_PMEM_SAVE_FAILED) + struct ndtest_config; struct ndtest_priv { -- GitLab From 9efb069de4ba748d284f6129e71de239f801053a Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 28 Jan 2021 10:22:48 +0100 Subject: [PATCH 0763/1084] ovl: add warning on user_ns mismatch Currently there's no way to create an overlay filesystem outside of the current user namespace. Make sure that if this assumption changes it doesn't go unnoticed. Reported-by: "Eric W. Biederman" Signed-off-by: Miklos Szeredi --- fs/overlayfs/super.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 2bd570cbe8a45..82cd6d55a5a13 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -1923,6 +1923,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) unsigned int numlower; int err; + err = -EIO; + if (WARN_ON(sb->s_user_ns != current_user_ns())) + goto out; + sb->s_d_op = &ovl_dentry_operations; err = -ENOMEM; -- GitLab From 554677b97257b0b69378bd74e521edb7e94769ff Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 28 Jan 2021 10:22:48 +0100 Subject: [PATCH 0764/1084] ovl: perform vfs_getxattr() with mounter creds The vfs_getxattr() in ovl_xattr_set() is used to check whether an xattr exist on a lower layer file that is to be removed. If the xattr does not exist, then no need to copy up the file. This call of vfs_getxattr() wasn't wrapped in credential override, and this is probably okay. But for consitency wrap this instance as well. Reported-by: "Eric W. Biederman" Signed-off-by: Miklos Szeredi --- fs/overlayfs/inode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index d739e14c6814d..cf41bcb664bc7 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -352,7 +352,9 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, goto out; if (!value && !upperdentry) { + old_cred = ovl_override_creds(dentry->d_sb); err = vfs_getxattr(realdentry, name, NULL, 0); + revert_creds(old_cred); if (err < 0) goto out_drop_write; } -- GitLab From f2b00be488730522d0fb7a8a5de663febdcefe0a Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 28 Jan 2021 10:22:48 +0100 Subject: [PATCH 0765/1084] cap: fix conversions on getxattr If a capability is stored on disk in v2 format cap_inode_getsecurity() will currently return in v2 format unconditionally. This is wrong: v2 cap should be equivalent to a v3 cap with zero rootid, and so the same conversions performed on it. If the rootid cannot be mapped, v3 is returned unconverted. Fix this so that both v2 and v3 return -EOVERFLOW if the rootid (or the owner of the fs user namespace in case of v2) cannot be mapped into the current user namespace. Signed-off-by: Miklos Szeredi Acked-by: "Eric W. Biederman" --- security/commoncap.c | 67 ++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/security/commoncap.c b/security/commoncap.c index bacc1111d871b..26c1cb725dcbe 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -371,10 +371,11 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, { int size, ret; kuid_t kroot; + u32 nsmagic, magic; uid_t root, mappedroot; char *tmpbuf = NULL; struct vfs_cap_data *cap; - struct vfs_ns_cap_data *nscap; + struct vfs_ns_cap_data *nscap = NULL; struct dentry *dentry; struct user_namespace *fs_ns; @@ -396,46 +397,61 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, fs_ns = inode->i_sb->s_user_ns; cap = (struct vfs_cap_data *) tmpbuf; if (is_v2header((size_t) ret, cap)) { - /* If this is sizeof(vfs_cap_data) then we're ok with the - * on-disk value, so return that. */ - if (alloc) - *buffer = tmpbuf; - else - kfree(tmpbuf); - return ret; - } else if (!is_v3header((size_t) ret, cap)) { - kfree(tmpbuf); - return -EINVAL; + root = 0; + } else if (is_v3header((size_t) ret, cap)) { + nscap = (struct vfs_ns_cap_data *) tmpbuf; + root = le32_to_cpu(nscap->rootid); + } else { + size = -EINVAL; + goto out_free; } - nscap = (struct vfs_ns_cap_data *) tmpbuf; - root = le32_to_cpu(nscap->rootid); kroot = make_kuid(fs_ns, root); /* If the root kuid maps to a valid uid in current ns, then return * this as a nscap. */ mappedroot = from_kuid(current_user_ns(), kroot); if (mappedroot != (uid_t)-1 && mappedroot != (uid_t)0) { + size = sizeof(struct vfs_ns_cap_data); if (alloc) { - *buffer = tmpbuf; + if (!nscap) { + /* v2 -> v3 conversion */ + nscap = kzalloc(size, GFP_ATOMIC); + if (!nscap) { + size = -ENOMEM; + goto out_free; + } + nsmagic = VFS_CAP_REVISION_3; + magic = le32_to_cpu(cap->magic_etc); + if (magic & VFS_CAP_FLAGS_EFFECTIVE) + nsmagic |= VFS_CAP_FLAGS_EFFECTIVE; + memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32); + nscap->magic_etc = cpu_to_le32(nsmagic); + } else { + /* use allocated v3 buffer */ + tmpbuf = NULL; + } nscap->rootid = cpu_to_le32(mappedroot); - } else - kfree(tmpbuf); - return size; + *buffer = nscap; + } + goto out_free; } if (!rootid_owns_currentns(kroot)) { - kfree(tmpbuf); - return -EOPNOTSUPP; + size = -EOVERFLOW; + goto out_free; } /* This comes from a parent namespace. Return as a v2 capability */ size = sizeof(struct vfs_cap_data); if (alloc) { - *buffer = kmalloc(size, GFP_ATOMIC); - if (*buffer) { - struct vfs_cap_data *cap = *buffer; - __le32 nsmagic, magic; + if (nscap) { + /* v3 -> v2 conversion */ + cap = kzalloc(size, GFP_ATOMIC); + if (!cap) { + size = -ENOMEM; + goto out_free; + } magic = VFS_CAP_REVISION_2; nsmagic = le32_to_cpu(nscap->magic_etc); if (nsmagic & VFS_CAP_FLAGS_EFFECTIVE) @@ -443,9 +459,12 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, memcpy(&cap->data, &nscap->data, sizeof(__le32) * 2 * VFS_CAP_U32); cap->magic_etc = cpu_to_le32(magic); } else { - size = -ENOMEM; + /* use unconverted v2 */ + tmpbuf = NULL; } + *buffer = cap; } +out_free: kfree(tmpbuf); return size; } -- GitLab From b854cc659dcb80f172cb35dbedc15d39d49c383f Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 5 Jan 2021 08:36:11 +0800 Subject: [PATCH 0766/1084] ovl: avoid deadlock on directory ioctl The function ovl_dir_real_file() currently uses the inode lock to serialize writes to the od->upperfile field. However, this function will get called by ovl_ioctl_set_flags(), which utilizes the inode lock too. In this case ovl_dir_real_file() will try to claim a lock that is owned by a function in its call stack, which won't get released before ovl_dir_real_file() returns. Fix by replacing the open coded compare and exchange by an explicit atomic op. Fixes: 61536bed2149 ("ovl: support [S|G]ETFLAGS and FS[S|G]ETXATTR ioctls for directories") Cc: stable@vger.kernel.org # v5.10 Reported-by: Icenowy Zheng Tested-by: Icenowy Zheng Signed-off-by: Miklos Szeredi --- fs/overlayfs/readdir.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 01620ebae1bd4..60d751f28fea5 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -865,7 +865,7 @@ struct file *ovl_dir_real_file(const struct file *file, bool want_upper) struct ovl_dir_file *od = file->private_data; struct dentry *dentry = file->f_path.dentry; - struct file *realfile = od->realfile; + struct file *old, *realfile = od->realfile; if (!OVL_TYPE_UPPER(ovl_path_type(dentry))) return want_upper ? NULL : realfile; @@ -874,29 +874,20 @@ struct file *ovl_dir_real_file(const struct file *file, bool want_upper) * Need to check if we started out being a lower dir, but got copied up */ if (!od->is_upper) { - struct inode *inode = file_inode(file); - realfile = READ_ONCE(od->upperfile); if (!realfile) { struct path upperpath; ovl_path_upper(dentry, &upperpath); realfile = ovl_dir_open_realfile(file, &upperpath); + if (IS_ERR(realfile)) + return realfile; - inode_lock(inode); - if (!od->upperfile) { - if (IS_ERR(realfile)) { - inode_unlock(inode); - return realfile; - } - smp_store_release(&od->upperfile, realfile); - } else { - /* somebody has beaten us to it */ - if (!IS_ERR(realfile)) - fput(realfile); - realfile = od->upperfile; + old = cmpxchg_release(&od->upperfile, NULL, realfile); + if (old) { + fput(realfile); + realfile = old; } - inode_unlock(inode); } } -- GitLab From e04527fefba6e4e66492f122cf8cc6314f3cf3bf Mon Sep 17 00:00:00 2001 From: Liangyan Date: Tue, 22 Dec 2020 11:06:26 +0800 Subject: [PATCH 0767/1084] ovl: fix dentry leak in ovl_get_redirect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to lock d_parent->d_lock before dget_dlock, or this may have d_lockref updated parallelly like calltrace below which will cause dentry->d_lockref leak and risk a crash. CPU 0 CPU 1 ovl_set_redirect lookup_fast ovl_get_redirect __d_lookup dget_dlock //no lock protection here spin_lock(&dentry->d_lock) dentry->d_lockref.count++ dentry->d_lockref.count++ [   49.799059] PGD 800000061fed7067 P4D 800000061fed7067 PUD 61fec5067 PMD 0 [   49.799689] Oops: 0002 [#1] SMP PTI [   49.800019] CPU: 2 PID: 2332 Comm: node Not tainted 4.19.24-7.20.al7.x86_64 #1 [   49.800678] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS 8a46cfe 04/01/2014 [   49.801380] RIP: 0010:_raw_spin_lock+0xc/0x20 [   49.803470] RSP: 0018:ffffac6fc5417e98 EFLAGS: 00010246 [   49.803949] RAX: 0000000000000000 RBX: ffff93b8da3446c0 RCX: 0000000a00000000 [   49.804600] RDX: 0000000000000001 RSI: 000000000000000a RDI: 0000000000000088 [   49.805252] RBP: 0000000000000000 R08: 0000000000000000 R09: ffffffff993cf040 [   49.805898] R10: ffff93b92292e580 R11: ffffd27f188a4b80 R12: 0000000000000000 [   49.806548] R13: 00000000ffffff9c R14: 00000000fffffffe R15: ffff93b8da3446c0 [   49.807200] FS:  00007ffbedffb700(0000) GS:ffff93b927880000(0000) knlGS:0000000000000000 [   49.807935] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [   49.808461] CR2: 0000000000000088 CR3: 00000005e3f74006 CR4: 00000000003606a0 [   49.809113] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [   49.809758] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [   49.810410] Call Trace: [   49.810653]  d_delete+0x2c/0xb0 [   49.810951]  vfs_rmdir+0xfd/0x120 [   49.811264]  do_rmdir+0x14f/0x1a0 [   49.811573]  do_syscall_64+0x5b/0x190 [   49.811917]  entry_SYSCALL_64_after_hwframe+0x44/0xa9 [   49.812385] RIP: 0033:0x7ffbf505ffd7 [   49.814404] RSP: 002b:00007ffbedffada8 EFLAGS: 00000297 ORIG_RAX: 0000000000000054 [   49.815098] RAX: ffffffffffffffda RBX: 00007ffbedffb640 RCX: 00007ffbf505ffd7 [   49.815744] RDX: 0000000004449700 RSI: 0000000000000000 RDI: 0000000006c8cd50 [   49.816394] RBP: 00007ffbedffaea0 R08: 0000000000000000 R09: 0000000000017d0b [   49.817038] R10: 0000000000000000 R11: 0000000000000297 R12: 0000000000000012 [   49.817687] R13: 00000000072823d8 R14: 00007ffbedffb700 R15: 00000000072823d8 [   49.818338] Modules linked in: pvpanic cirrusfb button qemu_fw_cfg atkbd libps2 i8042 [   49.819052] CR2: 0000000000000088 [   49.819368] ---[ end trace 4e652b8aa299aa2d ]--- [   49.819796] RIP: 0010:_raw_spin_lock+0xc/0x20 [   49.821880] RSP: 0018:ffffac6fc5417e98 EFLAGS: 00010246 [   49.822363] RAX: 0000000000000000 RBX: ffff93b8da3446c0 RCX: 0000000a00000000 [   49.823008] RDX: 0000000000000001 RSI: 000000000000000a RDI: 0000000000000088 [   49.823658] RBP: 0000000000000000 R08: 0000000000000000 R09: ffffffff993cf040 [   49.825404] R10: ffff93b92292e580 R11: ffffd27f188a4b80 R12: 0000000000000000 [   49.827147] R13: 00000000ffffff9c R14: 00000000fffffffe R15: ffff93b8da3446c0 [   49.828890] FS:  00007ffbedffb700(0000) GS:ffff93b927880000(0000) knlGS:0000000000000000 [   49.830725] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [   49.832359] CR2: 0000000000000088 CR3: 00000005e3f74006 CR4: 00000000003606a0 [   49.834085] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [   49.835792] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Cc: Fixes: a6c606551141 ("ovl: redirect on rename-dir") Signed-off-by: Liangyan Reviewed-by: Joseph Qi Suggested-by: Al Viro Signed-off-by: Miklos Szeredi --- fs/overlayfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 28a075b5f5b2e..d1efa3a5a5032 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -992,8 +992,8 @@ static char *ovl_get_redirect(struct dentry *dentry, bool abs_redirect) buflen -= thislen; memcpy(&buf[buflen], name, thislen); - tmp = dget_dlock(d->d_parent); spin_unlock(&d->d_lock); + tmp = dget_parent(d); dput(d); d = tmp; -- GitLab From 03fedf93593c82538b18476d8c4f0e8f8435ea70 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Sat, 19 Dec 2020 12:16:08 +0200 Subject: [PATCH 0768/1084] ovl: skip getxattr of security labels When inode has no listxattr op of its own (e.g. squashfs) vfs_listxattr calls the LSM inode_listsecurity hooks to list the xattrs that LSMs will intercept in inode_getxattr hooks. When selinux LSM is installed but not initialized, it will list the security.selinux xattr in inode_listsecurity, but will not intercept it in inode_getxattr. This results in -ENODATA for a getxattr call for an xattr returned by listxattr. This situation was manifested as overlayfs failure to copy up lower files from squashfs when selinux is built-in but not initialized, because ovl_copy_xattr() iterates the lower inode xattrs by vfs_listxattr() and vfs_getxattr(). ovl_copy_xattr() skips copy up of security labels that are indentified by inode_copy_up_xattr LSM hooks, but it does that after vfs_getxattr(). Since we are not going to copy them, skip vfs_getxattr() of the security labels. Reported-by: Michael Labriola Tested-by: Michael Labriola Link: https://lore.kernel.org/linux-unionfs/2nv9d47zt7.fsf@aldarion.sourceruckus.org/ Signed-off-by: Amir Goldstein Signed-off-by: Miklos Szeredi --- fs/overlayfs/copy_up.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index e5b616c93e11b..0fed532efa68d 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -84,6 +84,14 @@ int ovl_copy_xattr(struct super_block *sb, struct dentry *old, if (ovl_is_private_xattr(sb, name)) continue; + + error = security_inode_copy_up_xattr(name); + if (error < 0 && error != -EOPNOTSUPP) + break; + if (error == 1) { + error = 0; + continue; /* Discard */ + } retry: size = vfs_getxattr(old, name, value, value_size); if (size == -ERANGE) @@ -107,13 +115,6 @@ int ovl_copy_xattr(struct super_block *sb, struct dentry *old, goto retry; } - error = security_inode_copy_up_xattr(name); - if (error < 0 && error != -EOPNOTSUPP) - break; - if (error == 1) { - error = 0; - continue; /* Discard */ - } error = vfs_setxattr(new, name, value, size, 0); if (error) { if (error != -EOPNOTSUPP || ovl_must_copy_xattr(name)) -- GitLab From 335d3fc57941e5c6164c69d439aec1cb7a800876 Mon Sep 17 00:00:00 2001 From: Sargun Dhillon Date: Thu, 7 Jan 2021 16:10:43 -0800 Subject: [PATCH 0769/1084] ovl: implement volatile-specific fsync error behaviour Overlayfs's volatile option allows the user to bypass all forced sync calls to the upperdir filesystem. This comes at the cost of safety. We can never ensure that the user's data is intact, but we can make a best effort to expose whether or not the data is likely to be in a bad state. The best way to handle this in the time being is that if an overlayfs's upperdir experiences an error after a volatile mount occurs, that error will be returned on fsync, fdatasync, sync, and syncfs. This is contradictory to the traditional behaviour of VFS which fails the call once, and only raises an error if a subsequent fsync error has occurred, and been raised by the filesystem. One awkward aspect of the patch is that we have to manually set the superblock's errseq_t after the sync_fs callback as opposed to just returning an error from syncfs. This is because the call chain looks something like this: sys_syncfs -> sync_filesystem -> __sync_filesystem -> /* The return value is ignored here sb->s_op->sync_fs(sb) _sync_blockdev /* Where the VFS fetches the error to raise to userspace */ errseq_check_and_advance Because of this we call errseq_set every time the sync_fs callback occurs. Due to the nature of this seen / unseen dichotomy, if the upperdir is an inconsistent state at the initial mount time, overlayfs will refuse to mount, as overlayfs cannot get a snapshot of the upperdir's errseq that will increment on error until the user calls syncfs. Signed-off-by: Sargun Dhillon Suggested-by: Amir Goldstein Reviewed-by: Amir Goldstein Fixes: c86243b090bc ("ovl: provide a mount option "volatile"") Cc: stable@vger.kernel.org Reviewed-by: Vivek Goyal Reviewed-by: Jeff Layton Signed-off-by: Miklos Szeredi --- Documentation/filesystems/overlayfs.rst | 8 ++++++ fs/overlayfs/file.c | 5 ++-- fs/overlayfs/overlayfs.h | 1 + fs/overlayfs/ovl_entry.h | 2 ++ fs/overlayfs/readdir.c | 5 ++-- fs/overlayfs/super.c | 34 ++++++++++++++++++++----- fs/overlayfs/util.c | 27 ++++++++++++++++++++ 7 files changed, 71 insertions(+), 11 deletions(-) diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst index 587a939739290..78240e29b0bb6 100644 --- a/Documentation/filesystems/overlayfs.rst +++ b/Documentation/filesystems/overlayfs.rst @@ -586,6 +586,14 @@ without significant effort. The advantage of mounting with the "volatile" option is that all forms of sync calls to the upper filesystem are omitted. +In order to avoid a giving a false sense of safety, the syncfs (and fsync) +semantics of volatile mounts are slightly different than that of the rest of +VFS. If any writeback error occurs on the upperdir's filesystem after a +volatile mount takes place, all sync functions will return an error. Once this +condition is reached, the filesystem will not recover, and every subsequent sync +call will return an error, even if the upperdir has not experience a new error +since the last sync call. + When overlay is mounted with "volatile" option, the directory "$workdir/work/incompat/volatile" is created. During next mount, overlay checks for this directory and refuses to mount if present. This is a strong diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index bd9dd38347aed..077d3ad343f68 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -398,8 +398,9 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync) const struct cred *old_cred; int ret; - if (!ovl_should_sync(OVL_FS(file_inode(file)->i_sb))) - return 0; + ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb)); + if (ret <= 0) + return ret; ret = ovl_real_fdget_meta(file, &real, !datasync); if (ret) diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index b487e48c7fd42..cb4e2d60ecf9c 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -324,6 +324,7 @@ int ovl_check_metacopy_xattr(struct ovl_fs *ofs, struct dentry *dentry); bool ovl_is_metacopy_dentry(struct dentry *dentry); char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, int padding); +int ovl_sync_status(struct ovl_fs *ofs); static inline bool ovl_is_impuredir(struct super_block *sb, struct dentry *dentry) diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index fbd5e27ce66bd..63efee554f69a 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -81,6 +81,8 @@ struct ovl_fs { atomic_long_t last_ino; /* Whiteout dentry cache */ struct dentry *whiteout; + /* r/o snapshot of upperdir sb's only taken on volatile mounts */ + errseq_t errseq; }; static inline struct vfsmount *ovl_upper_mnt(struct ovl_fs *ofs) diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 60d751f28fea5..f404a78e6b607 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -900,8 +900,9 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, struct file *realfile; int err; - if (!ovl_should_sync(OVL_FS(file->f_path.dentry->d_sb))) - return 0; + err = ovl_sync_status(OVL_FS(file->f_path.dentry->d_sb)); + if (err <= 0) + return err; realfile = ovl_dir_real_file(file, true); err = PTR_ERR_OR_ZERO(realfile); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 82cd6d55a5a13..d58b8f2bf9d0a 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -264,11 +264,20 @@ static int ovl_sync_fs(struct super_block *sb, int wait) struct super_block *upper_sb; int ret; - if (!ovl_upper_mnt(ofs)) - return 0; + ret = ovl_sync_status(ofs); + /* + * We have to always set the err, because the return value isn't + * checked in syncfs, and instead indirectly return an error via + * the sb's writeback errseq, which VFS inspects after this call. + */ + if (ret < 0) { + errseq_set(&sb->s_wb_err, -EIO); + return -EIO; + } + + if (!ret) + return ret; - if (!ovl_should_sync(ofs)) - return 0; /* * Not called for sync(2) call or an emergency sync (SB_I_SKIP_SYNC). * All the super blocks will be iterated, including upper_sb. @@ -1993,6 +2002,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) sb->s_op = &ovl_super_operations; if (ofs->config.upperdir) { + struct super_block *upper_sb; + if (!ofs->config.workdir) { pr_err("missing 'workdir'\n"); goto out_err; @@ -2002,6 +2013,16 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) if (err) goto out_err; + upper_sb = ovl_upper_mnt(ofs)->mnt_sb; + if (!ovl_should_sync(ofs)) { + ofs->errseq = errseq_sample(&upper_sb->s_wb_err); + if (errseq_check(&upper_sb->s_wb_err, ofs->errseq)) { + err = -EIO; + pr_err("Cannot mount volatile when upperdir has an unseen error. Sync upperdir fs to clear state.\n"); + goto out_err; + } + } + err = ovl_get_workdir(sb, ofs, &upperpath); if (err) goto out_err; @@ -2009,9 +2030,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) if (!ofs->workdir) sb->s_flags |= SB_RDONLY; - sb->s_stack_depth = ovl_upper_mnt(ofs)->mnt_sb->s_stack_depth; - sb->s_time_gran = ovl_upper_mnt(ofs)->mnt_sb->s_time_gran; - + sb->s_stack_depth = upper_sb->s_stack_depth; + sb->s_time_gran = upper_sb->s_time_gran; } oe = ovl_get_lowerstack(sb, splitlower, numlower, ofs, layers); err = PTR_ERR(oe); diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 6569031af3cdd..9826b003f1d27 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -962,3 +962,30 @@ char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, kfree(buf); return ERR_PTR(res); } + +/* + * ovl_sync_status() - Check fs sync status for volatile mounts + * + * Returns 1 if this is not a volatile mount and a real sync is required. + * + * Returns 0 if syncing can be skipped because mount is volatile, and no errors + * have occurred on the upperdir since the mount. + * + * Returns -errno if it is a volatile mount, and the error that occurred since + * the last mount. If the error code changes, it'll return the latest error + * code. + */ + +int ovl_sync_status(struct ovl_fs *ofs) +{ + struct vfsmount *mnt; + + if (ovl_should_sync(ofs)) + return 1; + + mnt = ovl_upper_mnt(ofs); + if (!mnt) + return 0; + + return errseq_check(&mnt->mnt_sb->s_wb_err, ofs->errseq); +} -- GitLab From de96c3943f591018727b862f51953c1b6c55bcc3 Mon Sep 17 00:00:00 2001 From: Qii Wang Date: Sat, 9 Jan 2021 16:29:50 +0800 Subject: [PATCH 0770/1084] i2c: mediatek: Move suspend and resume handling to NOIRQ phase Some i2c device driver indirectly uses I2C driver when it is now being suspended. The i2c devices driver is suspended during the NOIRQ phase and this cannot be changed due to other dependencies. Therefore, we also need to move the suspend handling for the I2C controller driver to the NOIRQ phase as well. Signed-off-by: Qii Wang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 0818d3e507347..2ffd2f354d0ae 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -1275,7 +1275,8 @@ static int mtk_i2c_probe(struct platform_device *pdev) mtk_i2c_clock_disable(i2c); ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, - IRQF_TRIGGER_NONE, I2C_DRV_NAME, i2c); + IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, + I2C_DRV_NAME, i2c); if (ret < 0) { dev_err(&pdev->dev, "Request I2C IRQ %d fail\n", irq); @@ -1302,7 +1303,16 @@ static int mtk_i2c_remove(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP -static int mtk_i2c_resume(struct device *dev) +static int mtk_i2c_suspend_noirq(struct device *dev) +{ + struct mtk_i2c *i2c = dev_get_drvdata(dev); + + i2c_mark_adapter_suspended(&i2c->adap); + + return 0; +} + +static int mtk_i2c_resume_noirq(struct device *dev) { int ret; struct mtk_i2c *i2c = dev_get_drvdata(dev); @@ -1317,12 +1327,15 @@ static int mtk_i2c_resume(struct device *dev) mtk_i2c_clock_disable(i2c); + i2c_mark_adapter_resumed(&i2c->adap); + return 0; } #endif static const struct dev_pm_ops mtk_i2c_pm = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, mtk_i2c_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_i2c_suspend_noirq, + mtk_i2c_resume_noirq) }; static struct platform_driver mtk_i2c_driver = { -- GitLab From 530fe6bf0f9ff91e5156f0423ae8db8d106d0159 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Fri, 15 Jan 2021 18:58:31 +0100 Subject: [PATCH 0771/1084] soc: sunxi: mbus: Remove DE2 display engine compatibles The DE2 display engine hardware takes physical addresses that do not need PHYS_BASE subtracted. As a result, they should not be present on the mbus driver match list. Remove them. This was tested on the A83T, along with the patch allowing the DMA range map to be non-NULL and restores a working display. Fixes: b4bdc4fbf8d0 ("soc: sunxi: Deal with the MBUS DMA offsets in a central place") Signed-off-by: Paul Kocialkowski Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20210115175831.1184260-2-paul.kocialkowski@bootlin.com --- drivers/soc/sunxi/sunxi_mbus.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/soc/sunxi/sunxi_mbus.c b/drivers/soc/sunxi/sunxi_mbus.c index e9925c8487d74..d90e4a264b6f6 100644 --- a/drivers/soc/sunxi/sunxi_mbus.c +++ b/drivers/soc/sunxi/sunxi_mbus.c @@ -23,12 +23,7 @@ static const char * const sunxi_mbus_devices[] = { "allwinner,sun7i-a20-display-engine", "allwinner,sun8i-a23-display-engine", "allwinner,sun8i-a33-display-engine", - "allwinner,sun8i-a83t-display-engine", - "allwinner,sun8i-h3-display-engine", - "allwinner,sun8i-r40-display-engine", - "allwinner,sun8i-v3s-display-engine", "allwinner,sun9i-a80-display-engine", - "allwinner,sun50i-a64-display-engine", /* * And now we have the regular devices connected to the MBUS -- GitLab From 31f190e0ccac8b75d33fdc95a797c526cf9b149e Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Thu, 21 Jan 2021 15:44:02 +0100 Subject: [PATCH 0772/1084] media: rkisp1: uapi: change hist_bins array type from __u16 to __u32 Each entry in the array is a 20 bits value composed of 16 bits unsigned integer and 4 bits fractional part. So the type should change to __u32. In addition add a documentation of how the measurements are done. Signed-off-by: Dafna Hirschfeld Acked-by: Helen Koike Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/rkisp1-config.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h index 6e449e7842605..24f05d6d258f9 100644 --- a/include/uapi/linux/rkisp1-config.h +++ b/include/uapi/linux/rkisp1-config.h @@ -844,13 +844,18 @@ struct rkisp1_cif_isp_af_stat { /** * struct rkisp1_cif_isp_hist_stat - statistics histogram data * - * @hist_bins: measured bin counters + * @hist_bins: measured bin counters. Each bin is a 20 bits unsigned fixed point + * type. Bits 0-4 are the fractional part and bits 5-19 are the + * integer part. * - * Measurement window divided into 25 sub-windows, set - * with ISP_HIST_XXX + * The window of the measurements area is divided to 5x5 sub-windows. The + * histogram is then computed for each sub-window independently and the final + * result is a weighted average of the histogram measurements on all + * sub-windows. The window of the measurements area and the weight of each + * sub-window are configurable using struct @rkisp1_cif_isp_hst_config. */ struct rkisp1_cif_isp_hist_stat { - __u16 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX]; + __u32 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX]; }; /** -- GitLab From a76f8dc8be471028540df24749e99a3ec0ac7c94 Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Thu, 21 Jan 2021 15:44:03 +0100 Subject: [PATCH 0773/1084] media: rkisp1: stats: remove a wrong cast to u8 hist_bins is an array of type __u32. Each entry represent a 20 bit fixed point value as documented inline. The cast to u8 when setting the values is wrong. Remove it. Signed-off-by: Dafna Hirschfeld Reviewed-by: Heiko Stuebner Acked-by: Helen Koike Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c index 3ddab8fa8f2d3..4cdb180fa64d0 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c @@ -235,8 +235,7 @@ static void rkisp1_stats_get_hst_meas(struct rkisp1_stats *stats, pbuf->meas_type |= RKISP1_CIF_ISP_STAT_HIST; for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX; i++) pbuf->params.hist.hist_bins[i] = - (u8)rkisp1_read(rkisp1, - RKISP1_CIF_ISP_HIST_BIN_0 + i * 4); + rkisp1_read(rkisp1, RKISP1_CIF_ISP_HIST_BIN_0 + i * 4); } static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats, -- GitLab From a802a0430b863f03bc01aaea2d2bf6ff464f03e7 Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Thu, 21 Jan 2021 15:44:04 +0100 Subject: [PATCH 0774/1084] media: rkisp1: stats: mask the hist_bins values hist_bins is an array of type __u32. Each entry represents a 20 bit value. So mask out the unused bits. Signed-off-by: Dafna Hirschfeld Acked-by: Helen Koike Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h | 1 + drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h index 8a8d960a679c2..fa33080f51db5 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h @@ -365,6 +365,7 @@ #define RKISP1_CIF_ISP_MAX_HIST_PREDIVIDER 0x0000007F #define RKISP1_CIF_ISP_HIST_ROW_NUM 5 #define RKISP1_CIF_ISP_HIST_COLUMN_NUM 5 +#define RKISP1_CIF_ISP_HIST_GET_BIN(x) ((x) & 0x000FFFFF) /* AUTO FOCUS MEASUREMENT: ISP_AFM_CTRL */ #define RKISP1_ISP_AFM_CTRL_ENABLE BIT(0) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c index 4cdb180fa64d0..3b2783700abc2 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c @@ -233,9 +233,11 @@ static void rkisp1_stats_get_hst_meas(struct rkisp1_stats *stats, unsigned int i; pbuf->meas_type |= RKISP1_CIF_ISP_STAT_HIST; - for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX; i++) - pbuf->params.hist.hist_bins[i] = - rkisp1_read(rkisp1, RKISP1_CIF_ISP_HIST_BIN_0 + i * 4); + for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX; i++) { + u32 reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_HIST_BIN_0 + i * 4); + + pbuf->params.hist.hist_bins[i] = RKISP1_CIF_ISP_HIST_GET_BIN(reg_val); + } } static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats, -- GitLab From 66d81de7ea9d2b0775e5bfd5e770483a1c24b9ca Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 21 Jan 2021 15:44:05 +0100 Subject: [PATCH 0775/1084] media: rockchip: rkisp1: reduce number of histogram grid elements in uapi The uapi right now specifies an array size of 28 but the actual number of elements is only 25 with the last 3 being unused. Reduce the array size to the correct number of elements and change the params code to iterate the array 25 times. Signed-off-by: Heiko Stuebner Signed-off-by: Dafna Hirschfeld Acked-by: Helen Koike Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rockchip/rkisp1/rkisp1-params.c | 3 ++- include/uapi/linux/rkisp1-config.h | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c index 6af4d551ffb54..021939466b241 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c @@ -589,7 +589,6 @@ static void rkisp1_hst_config(struct rkisp1_params *params, RKISP1_CIF_ISP_HIST_WEIGHT_22TO03, RKISP1_CIF_ISP_HIST_WEIGHT_13TO43, RKISP1_CIF_ISP_HIST_WEIGHT_04TO34, - RKISP1_CIF_ISP_HIST_WEIGHT_44, }; const u8 *weight; unsigned int i; @@ -622,6 +621,8 @@ static void rkisp1_hst_config(struct rkisp1_params *params, weight[2], weight[3]), hist_weight_regs[i]); + + rkisp1_write(params->rkisp1, weight[0] & 0x1F, RKISP1_CIF_ISP_HIST_WEIGHT_44); } static void diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h index 24f05d6d258f9..35aa82d5f6dd5 100644 --- a/include/uapi/linux/rkisp1-config.h +++ b/include/uapi/linux/rkisp1-config.h @@ -102,8 +102,7 @@ /* * Histogram calculation */ -/* Last 3 values unused. */ -#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 28 +#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 25 /* * Defect Pixel Cluster Correction -- GitLab From fc672d806bd77eff26117479e90ccdcfd2a8ecb4 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 21 Jan 2021 15:44:06 +0100 Subject: [PATCH 0776/1084] media: rockchip: rkisp1: carry ip version information The IP block evolved from its rk3288/rk3399 base and the vendor designates them with a numerical version. rk3399 for example is designated V10 probably meaning V1.0. There doesn't seem to be an actual version register we could read that information from, so allow the match_data to carry that information for future differentiation. Also carry that information in the hw_revision field of the media- controller API, so that userspace also has access to that. The added versions are: - V10: at least rk3288 + rk3399 - V11: seemingly unused as of now, but probably appeared in some soc - V12: at least rk3326 + px30 - V13: at least rk1808 [fix checkpatch warning don't use multiple blank lines] Signed-off-by: Heiko Stuebner Signed-off-by: Dafna Hirschfeld Reviewed-by: Ezequiel Garcia Acked-by: Helen Koike Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/admin-guide/media/rkisp1.rst | 16 ++++++++++++++ .../platform/rockchip/rkisp1/rkisp1-dev.c | 21 +++++++++++-------- include/uapi/linux/rkisp1-config.h | 15 +++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/Documentation/admin-guide/media/rkisp1.rst b/Documentation/admin-guide/media/rkisp1.rst index 2267e4fb475e5..ccf418713623b 100644 --- a/Documentation/admin-guide/media/rkisp1.rst +++ b/Documentation/admin-guide/media/rkisp1.rst @@ -13,6 +13,22 @@ This file documents the driver for the Rockchip ISP1 that is part of RK3288 and RK3399 SoCs. The driver is located under drivers/staging/media/rkisp1 and uses the Media-Controller API. +Revisions +========= + +There exist multiple smaller revisions to this ISP that got introduced in +later SoCs. Revisions can be found in the enum :c:type:`rkisp1_cif_isp_version` +in the UAPI and the revision of the ISP inside the running SoC can be read +in the field hw_revision of struct media_device_info as returned by +ioctl MEDIA_IOC_DEVICE_INFO. + +Versions in use are: + +- RKISP1_V10: used at least in rk3288 and rk3399 +- RKISP1_V11: declared in the original vendor code, but not used +- RKISP1_V12: used at least in rk3326 and px30 +- RKISP1_V13: used at least in rk1808 + Topology ======== .. _rkisp1_topology_graph: diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index 68da1eed753dc..f7e9fd3055485 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -104,6 +104,7 @@ struct rkisp1_match_data { const char * const *clks; unsigned int size; + enum rkisp1_cif_isp_version isp_ver; }; /* ---------------------------------------------------------------------------- @@ -411,15 +412,16 @@ static const char * const rk3399_isp_clks[] = { "hclk", }; -static const struct rkisp1_match_data rk3399_isp_clk_data = { +static const struct rkisp1_match_data rk3399_isp_match_data = { .clks = rk3399_isp_clks, .size = ARRAY_SIZE(rk3399_isp_clks), + .isp_ver = RKISP1_V10, }; static const struct of_device_id rkisp1_of_match[] = { { .compatible = "rockchip,rk3399-cif-isp", - .data = &rk3399_isp_clk_data, + .data = &rk3399_isp_match_data, }, {}, }; @@ -457,15 +459,15 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1) static int rkisp1_probe(struct platform_device *pdev) { - const struct rkisp1_match_data *clk_data; + const struct rkisp1_match_data *match_data; struct device *dev = &pdev->dev; struct rkisp1_device *rkisp1; struct v4l2_device *v4l2_dev; unsigned int i; int ret, irq; - clk_data = of_device_get_match_data(&pdev->dev); - if (!clk_data) + match_data = of_device_get_match_data(&pdev->dev); + if (!match_data) return -ENODEV; rkisp1 = devm_kzalloc(dev, sizeof(*rkisp1), GFP_KERNEL); @@ -494,15 +496,16 @@ static int rkisp1_probe(struct platform_device *pdev) rkisp1->irq = irq; - for (i = 0; i < clk_data->size; i++) - rkisp1->clks[i].id = clk_data->clks[i]; - ret = devm_clk_bulk_get(dev, clk_data->size, rkisp1->clks); + for (i = 0; i < match_data->size; i++) + rkisp1->clks[i].id = match_data->clks[i]; + ret = devm_clk_bulk_get(dev, match_data->size, rkisp1->clks); if (ret) return ret; - rkisp1->clk_size = clk_data->size; + rkisp1->clk_size = match_data->size; pm_runtime_enable(&pdev->dev); + rkisp1->media_dev.hw_revision = match_data->isp_ver; strscpy(rkisp1->media_dev.model, RKISP1_DRIVER_NAME, sizeof(rkisp1->media_dev.model)); rkisp1->media_dev.dev = &pdev->dev; diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h index 35aa82d5f6dd5..bee4413fe0d35 100644 --- a/include/uapi/linux/rkisp1-config.h +++ b/include/uapi/linux/rkisp1-config.h @@ -123,6 +123,21 @@ #define RKISP1_CIF_ISP_STAT_AFM (1U << 2) #define RKISP1_CIF_ISP_STAT_HIST (1U << 3) +/** + * enum rkisp1_cif_isp_version - ISP variants + * + * @RKISP1_V10: used at least in rk3288 and rk3399 + * @RKISP1_V11: declared in the original vendor code, but not used + * @RKISP1_V12: used at least in rk3326 and px30 + * @RKISP1_V13: used at least in rk1808 + */ +enum rkisp1_cif_isp_version { + RKISP1_V10 = 10, + RKISP1_V11, + RKISP1_V12, + RKISP1_V13, +}; + enum rkisp1_cif_isp_histogram_mode { RKISP1_CIF_ISP_HISTOGRAM_MODE_DISABLE, RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED, -- GitLab From ef357e02b6c420dc2d668ebf3165838c77358acd Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 21 Jan 2021 15:44:07 +0100 Subject: [PATCH 0777/1084] media: rockchip: rkisp1: extend uapi array sizes Later variants of the rkisp1 block use more entries in some arrays: RKISP1_CIF_ISP_AE_MEAN_MAX 25 -> 81 RKISP1_CIF_ISP_HIST_BIN_N_MAX 16 -> 32 RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES 17 -> 34 RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 25 -> 81 and we can still extend the uapi during the 5.11-rc cycle, so do that now to be on the safe side. V10 and V11 only need the smaller sizes, while V12 and V13 needed the larger sizes. When adding the bigger sizes make sure, values filled from hardware values and transmitted to userspace don't leak kernel data by zeroing them beforehand. Signed-off-by: Heiko Stuebner Signed-off-by: Dafna Hirschfeld Reviewed-by: Ezequiel Garcia Acked-by: Helen Koike Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../platform/rockchip/rkisp1/rkisp1-params.c | 2 +- .../platform/rockchip/rkisp1/rkisp1-stats.c | 4 +- include/uapi/linux/rkisp1-config.h | 67 ++++++++++++++++--- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c index 021939466b241..aa5f45749543b 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c @@ -391,7 +391,7 @@ static void rkisp1_goc_config(struct rkisp1_params *params, RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE); - for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES; i++) + for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++) rkisp1_write(params->rkisp1, arg->gamma_y[i], RKISP1_CIF_ISP_GAMMA_OUT_Y_0 + i * 4); } diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c index 3b2783700abc2..c1d07a2e8839f 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c @@ -203,7 +203,7 @@ static void rkisp1_stats_get_aec_meas(struct rkisp1_stats *stats, unsigned int i; pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AUTOEXP; - for (i = 0; i < RKISP1_CIF_ISP_AE_MEAN_MAX; i++) + for (i = 0; i < RKISP1_CIF_ISP_AE_MEAN_MAX_V10; i++) pbuf->params.ae.exp_mean[i] = (u8)rkisp1_read(rkisp1, RKISP1_CIF_ISP_EXP_MEAN_00 + i * 4); @@ -233,7 +233,7 @@ static void rkisp1_stats_get_hst_meas(struct rkisp1_stats *stats, unsigned int i; pbuf->meas_type |= RKISP1_CIF_ISP_STAT_HIST; - for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX; i++) { + for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10; i++) { u32 reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_HIST_BIN_0 + i * 4); pbuf->params.hist.hist_bins[i] = RKISP1_CIF_ISP_HIST_GET_BIN(reg_val); diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h index bee4413fe0d35..36e3efb81b014 100644 --- a/include/uapi/linux/rkisp1-config.h +++ b/include/uapi/linux/rkisp1-config.h @@ -49,8 +49,14 @@ #define RKISP1_CIF_ISP_CTK_COEFF_MAX 0x100 #define RKISP1_CIF_ISP_CTK_OFFSET_MAX 0x800 -#define RKISP1_CIF_ISP_AE_MEAN_MAX 25 -#define RKISP1_CIF_ISP_HIST_BIN_N_MAX 16 +#define RKISP1_CIF_ISP_AE_MEAN_MAX_V10 25 +#define RKISP1_CIF_ISP_AE_MEAN_MAX_V12 81 +#define RKISP1_CIF_ISP_AE_MEAN_MAX RKISP1_CIF_ISP_AE_MEAN_MAX_V12 + +#define RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10 16 +#define RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12 32 +#define RKISP1_CIF_ISP_HIST_BIN_N_MAX RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12 + #define RKISP1_CIF_ISP_AFM_MAX_WINDOWS 3 #define RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE 17 @@ -86,7 +92,9 @@ * Gamma out */ /* Maximum number of color samples supported */ -#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES 17 +#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10 17 +#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 34 +#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 /* * Lens shade correction @@ -102,7 +110,9 @@ /* * Histogram calculation */ -#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 25 +#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10 25 +#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12 81 +#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12 /* * Defect Pixel Cluster Correction @@ -524,6 +534,15 @@ enum rkisp1_cif_isp_goc_mode { * * @mode: goc mode (from enum rkisp1_cif_isp_goc_mode) * @gamma_y: gamma out curve y-axis for all color components + * + * The number of entries of @gamma_y depends on the hardware revision + * as is reported by the hw_revision field of the struct media_device_info + * that is returned by ioctl MEDIA_IOC_DEVICE_INFO. + * + * Versions <= V11 have RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10 + * entries, versions >= V12 have RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 + * entries. RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES is equal to the maximum + * of the two. */ struct rkisp1_cif_isp_goc_config { __u32 mode; @@ -538,6 +557,15 @@ struct rkisp1_cif_isp_goc_config { * skipped * @meas_window: coordinates of the measure window * @hist_weight: weighting factor for sub-windows + * + * The number of entries of @hist_weight depends on the hardware revision + * as is reported by the hw_revision field of the struct media_device_info + * that is returned by ioctl MEDIA_IOC_DEVICE_INFO. + * + * Versions <= V11 have RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10 + * entries, versions >= V12 have RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12 + * entries. RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE is equal to the maximum + * of the two. */ struct rkisp1_cif_isp_hst_config { __u32 mode; @@ -825,7 +853,15 @@ struct rkisp1_cif_isp_bls_meas_val { * @exp_mean: Mean luminance value of block xx * @bls_val: BLS measured values * - * Image is divided into 5x5 blocks. + * The number of entries of @exp_mean depends on the hardware revision + * as is reported by the hw_revision field of the struct media_device_info + * that is returned by ioctl MEDIA_IOC_DEVICE_INFO. + * + * Versions <= V11 have RKISP1_CIF_ISP_AE_MEAN_MAX_V10 entries, + * versions >= V12 have RKISP1_CIF_ISP_AE_MEAN_MAX_V12 entries. + * RKISP1_CIF_ISP_AE_MEAN_MAX is equal to the maximum of the two. + * + * Image is divided into 5x5 blocks on V10 and 9x9 blocks on V12. */ struct rkisp1_cif_isp_ae_stat { __u8 exp_mean[RKISP1_CIF_ISP_AE_MEAN_MAX]; @@ -862,11 +898,22 @@ struct rkisp1_cif_isp_af_stat { * type. Bits 0-4 are the fractional part and bits 5-19 are the * integer part. * - * The window of the measurements area is divided to 5x5 sub-windows. The - * histogram is then computed for each sub-window independently and the final - * result is a weighted average of the histogram measurements on all - * sub-windows. The window of the measurements area and the weight of each - * sub-window are configurable using struct @rkisp1_cif_isp_hst_config. + * The window of the measurements area is divided to 5x5 sub-windows for + * V10/V11 and to 9x9 sub-windows for V12. The histogram is then computed for + * each sub-window independently and the final result is a weighted average of + * the histogram measurements on all sub-windows. The window of the + * measurements area and the weight of each sub-window are configurable using + * struct @rkisp1_cif_isp_hst_config. + * + * The histogram contains 16 bins in V10/V11 and 32 bins in V12/V13. + * + * The number of entries of @hist_bins depends on the hardware revision + * as is reported by the hw_revision field of the struct media_device_info + * that is returned by ioctl MEDIA_IOC_DEVICE_INFO. + * + * Versions <= V11 have RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10 entries, + * versions >= V12 have RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12 entries. + * RKISP1_CIF_ISP_HIST_BIN_N_MAX is equal to the maximum of the two. */ struct rkisp1_cif_isp_hist_stat { __u32 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX]; -- GitLab From 053b1b287ccf734cc3b5a40b3b17a63185758c61 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 22 Jan 2021 02:33:01 +0300 Subject: [PATCH 0778/1084] drm/bridge/lontium-lt9611uxc: fix waiting for EDID to become available - Call wake_up() when EDID ready event is received to wake wait_event_interruptible_timeout() - Increase waiting timeout, reading EDID can take longer than 100ms, so let's be on a safe side. Signed-off-by: Dmitry Baryshkov Fixes: 0cbbd5b1a012 ("drm: bridge: add support for lontium LT9611UXC bridge") Reviewed-by: Bjorn Andersson Reviewed-by: Andrzej Hajda Signed-off-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20210121233303.1221784-2-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 0c98d27f84ac7..a59e811f17057 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -145,8 +145,10 @@ static irqreturn_t lt9611uxc_irq_thread_handler(int irq, void *dev_id) lt9611uxc_unlock(lt9611uxc); - if (irq_status & BIT(0)) + if (irq_status & BIT(0)) { lt9611uxc->edid_read = !!(hpd_status & BIT(0)); + wake_up_all(<9611uxc->wq); + } if (irq_status & BIT(1)) { if (lt9611uxc->connector.dev) @@ -465,7 +467,7 @@ static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *brid static int lt9611uxc_wait_for_edid(struct lt9611uxc *lt9611uxc) { return wait_event_interruptible_timeout(lt9611uxc->wq, lt9611uxc->edid_read, - msecs_to_jiffies(100)); + msecs_to_jiffies(500)); } static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len) -- GitLab From 1bb7ab402da44e09b4bb3f31cfe24695cdb1b7df Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 22 Jan 2021 02:33:02 +0300 Subject: [PATCH 0779/1084] drm/bridge/lontium-lt9611uxc: fix get_edid return code Return NULL pointer from get_edid() callback rather than ERR_PTR() pointer, as DRM code does NULL checks rather than IS_ERR(). Also while we are at it, return NULL if getting EDID timed out. Signed-off-by: Dmitry Baryshkov Fixes: 0cbbd5b1a012 ("drm: bridge: add support for lontium LT9611UXC bridge") Reviewed-by: Bjorn Andersson Reviewed-by: Andrzej Hajda Signed-off-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20210121233303.1221784-3-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index a59e811f17057..b708700e182db 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -505,7 +505,10 @@ static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge, ret = lt9611uxc_wait_for_edid(lt9611uxc); if (ret < 0) { dev_err(lt9611uxc->dev, "wait for EDID failed: %d\n", ret); - return ERR_PTR(ret); + return NULL; + } else if (ret == 0) { + dev_err(lt9611uxc->dev, "wait for EDID timeout\n"); + return NULL; } return drm_do_get_edid(connector, lt9611uxc_get_edid_block, lt9611uxc); -- GitLab From bc6fa8676ebbf9c5285f80d7b831663aeabb90bb Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 22 Jan 2021 02:33:03 +0300 Subject: [PATCH 0780/1084] drm/bridge/lontium-lt9611uxc: move HPD notification out of IRQ handler drm hotplug handling code (drm_client_dev_hotplug()) can wait on mutex, thus delaying further lt9611uxc IRQ events processing. It was observed occasionally during bootups, when drm_client_modeset_probe() was waiting for EDID ready event, which was delayed because IRQ handler was stuck trying to deliver hotplug event. Move hotplug notifications from IRQ handler to separate work to be able to process IRQ events without delays. Signed-off-by: Dmitry Baryshkov Fixes: 0cbbd5b1a012 ("drm: bridge: add support for lontium LT9611UXC bridge") Reviewed-by: Andrzej Hajda Signed-off-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20210121233303.1221784-4-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 46 +++++++++++++++++----- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index b708700e182db..fee27952ec6d1 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -36,6 +37,7 @@ struct lt9611uxc { struct mutex ocm_lock; struct wait_queue_head wq; + struct work_struct work; struct device_node *dsi0_node; struct device_node *dsi1_node; @@ -52,6 +54,8 @@ struct lt9611uxc { bool hpd_supported; bool edid_read; + /* can be accessed from different threads, so protect this with ocm_lock */ + bool hdmi_connected; uint8_t fw_version; }; @@ -143,23 +147,41 @@ static irqreturn_t lt9611uxc_irq_thread_handler(int irq, void *dev_id) if (irq_status) regmap_write(lt9611uxc->regmap, 0xb022, 0); - lt9611uxc_unlock(lt9611uxc); - if (irq_status & BIT(0)) { lt9611uxc->edid_read = !!(hpd_status & BIT(0)); wake_up_all(<9611uxc->wq); } if (irq_status & BIT(1)) { - if (lt9611uxc->connector.dev) - drm_kms_helper_hotplug_event(lt9611uxc->connector.dev); - else - drm_bridge_hpd_notify(<9611uxc->bridge, !!(hpd_status & BIT(1))); + lt9611uxc->hdmi_connected = hpd_status & BIT(1); + schedule_work(<9611uxc->work); } + lt9611uxc_unlock(lt9611uxc); + return IRQ_HANDLED; } +static void lt9611uxc_hpd_work(struct work_struct *work) +{ + struct lt9611uxc *lt9611uxc = container_of(work, struct lt9611uxc, work); + bool connected; + + if (lt9611uxc->connector.dev) + drm_kms_helper_hotplug_event(lt9611uxc->connector.dev); + else { + + mutex_lock(<9611uxc->ocm_lock); + connected = lt9611uxc->hdmi_connected; + mutex_unlock(<9611uxc->ocm_lock); + + drm_bridge_hpd_notify(<9611uxc->bridge, + connected ? + connector_status_connected : + connector_status_disconnected); + } +} + static void lt9611uxc_reset(struct lt9611uxc *lt9611uxc) { gpiod_set_value_cansleep(lt9611uxc->reset_gpio, 1); @@ -447,18 +469,21 @@ static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *brid struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge); unsigned int reg_val = 0; int ret; - int connected = 1; + bool connected = true; + + lt9611uxc_lock(lt9611uxc); if (lt9611uxc->hpd_supported) { - lt9611uxc_lock(lt9611uxc); ret = regmap_read(lt9611uxc->regmap, 0xb023, ®_val); - lt9611uxc_unlock(lt9611uxc); if (ret) dev_err(lt9611uxc->dev, "failed to read hpd status: %d\n", ret); else connected = reg_val & BIT(1); } + lt9611uxc->hdmi_connected = connected; + + lt9611uxc_unlock(lt9611uxc); return connected ? connector_status_connected : connector_status_disconnected; @@ -931,6 +956,8 @@ static int lt9611uxc_probe(struct i2c_client *client, lt9611uxc->fw_version = ret; init_waitqueue_head(<9611uxc->wq); + INIT_WORK(<9611uxc->work, lt9611uxc_hpd_work); + ret = devm_request_threaded_irq(dev, client->irq, NULL, lt9611uxc_irq_thread_handler, IRQF_ONESHOT, "lt9611uxc", lt9611uxc); @@ -967,6 +994,7 @@ static int lt9611uxc_remove(struct i2c_client *client) struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client); disable_irq(client->irq); + flush_scheduled_work(); lt9611uxc_audio_exit(lt9611uxc); drm_bridge_remove(<9611uxc->bridge); -- GitLab From a44092e326d403c7878018ba532369f84d31dbfa Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Wed, 20 Jan 2021 07:50:02 -0600 Subject: [PATCH 0781/1084] iommu/amd: Use IVHD EFR for early initialization of IOMMU features IOMMU Extended Feature Register (EFR) is used to communicate the supported features for each IOMMU to the IOMMU driver. This is normally read from the PCI MMIO register offset 0x30, and used by the iommu_feature() helper function. However, there are certain scenarios where the information is needed prior to PCI initialization, and the iommu_feature() function is used prematurely w/o warning. This has caused incorrect initialization of IOMMU. This is the case for the commit 6d39bdee238f ("iommu/amd: Enforce 4k mapping for certain IOMMU data structures") Since, the EFR is also available in the IVHD header, and is available to the driver prior to PCI initialization. Therefore, default to using the IVHD EFR instead. Fixes: 6d39bdee238f ("iommu/amd: Enforce 4k mapping for certain IOMMU data structures") Signed-off-by: Suravee Suthikulpanit Tested-by: Brijesh Singh Reviewed-by: Robert Richter Link: https://lore.kernel.org/r/20210120135002.2682-1-suravee.suthikulpanit@amd.com Signed-off-by: Joerg Roedel --- drivers/iommu/amd/amd_iommu.h | 7 ++-- drivers/iommu/amd/amd_iommu_types.h | 4 +++ drivers/iommu/amd/init.c | 56 +++++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index 6b8cbdf717140..b4adab6985632 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -84,12 +84,9 @@ static inline bool is_rd890_iommu(struct pci_dev *pdev) (pdev->device == PCI_DEVICE_ID_RD890_IOMMU); } -static inline bool iommu_feature(struct amd_iommu *iommu, u64 f) +static inline bool iommu_feature(struct amd_iommu *iommu, u64 mask) { - if (!(iommu->cap & (1 << IOMMU_CAP_EFR))) - return false; - - return !!(iommu->features & f); + return !!(iommu->features & mask); } static inline u64 iommu_virt_to_phys(void *vaddr) diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h index 5535878277710..1a0495dd5fcbc 100644 --- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -387,6 +387,10 @@ #define IOMMU_CAP_NPCACHE 26 #define IOMMU_CAP_EFR 27 +/* IOMMU IVINFO */ +#define IOMMU_IVINFO_OFFSET 36 +#define IOMMU_IVINFO_EFRSUP BIT(0) + /* IOMMU Feature Reporting Field (for IVHD type 10h */ #define IOMMU_FEAT_GASUP_SHIFT 6 diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index 6a1f7048dacc6..83d8ab2aed9f4 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -257,6 +257,8 @@ static void init_device_table_dma(void); static bool amd_iommu_pre_enabled = true; +static u32 amd_iommu_ivinfo __initdata; + bool translation_pre_enabled(struct amd_iommu *iommu) { return (iommu->flags & AMD_IOMMU_FLAG_TRANS_PRE_ENABLED); @@ -296,6 +298,18 @@ int amd_iommu_get_num_iommus(void) return amd_iommus_present; } +/* + * For IVHD type 0x11/0x40, EFR is also available via IVHD. + * Default to IVHD EFR since it is available sooner + * (i.e. before PCI init). + */ +static void __init early_iommu_features_init(struct amd_iommu *iommu, + struct ivhd_header *h) +{ + if (amd_iommu_ivinfo & IOMMU_IVINFO_EFRSUP) + iommu->features = h->efr_reg; +} + /* Access to l1 and l2 indexed register spaces */ static u32 iommu_read_l1(struct amd_iommu *iommu, u16 l1, u8 address) @@ -1577,6 +1591,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) if (h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT)) amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE; + + early_iommu_features_init(iommu, h); + break; default: return -EINVAL; @@ -1770,6 +1787,35 @@ static const struct attribute_group *amd_iommu_groups[] = { NULL, }; +/* + * Note: IVHD 0x11 and 0x40 also contains exact copy + * of the IOMMU Extended Feature Register [MMIO Offset 0030h]. + * Default to EFR in IVHD since it is available sooner (i.e. before PCI init). + */ +static void __init late_iommu_features_init(struct amd_iommu *iommu) +{ + u64 features; + + if (!(iommu->cap & (1 << IOMMU_CAP_EFR))) + return; + + /* read extended feature bits */ + features = readq(iommu->mmio_base + MMIO_EXT_FEATURES); + + if (!iommu->features) { + iommu->features = features; + return; + } + + /* + * Sanity check and warn if EFR values from + * IVHD and MMIO conflict. + */ + if (features != iommu->features) + pr_warn(FW_WARN "EFR mismatch. Use IVHD EFR (%#llx : %#llx\n).", + features, iommu->features); +} + static int __init iommu_init_pci(struct amd_iommu *iommu) { int cap_ptr = iommu->cap_ptr; @@ -1789,8 +1835,7 @@ static int __init iommu_init_pci(struct amd_iommu *iommu) if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB))) amd_iommu_iotlb_sup = false; - /* read extended feature bits */ - iommu->features = readq(iommu->mmio_base + MMIO_EXT_FEATURES); + late_iommu_features_init(iommu); if (iommu_feature(iommu, FEATURE_GT)) { int glxval; @@ -2607,6 +2652,11 @@ static void __init free_dma_resources(void) free_unity_maps(); } +static void __init ivinfo_init(void *ivrs) +{ + amd_iommu_ivinfo = *((u32 *)(ivrs + IOMMU_IVINFO_OFFSET)); +} + /* * This is the hardware init function for AMD IOMMU in the system. * This function is called either from amd_iommu_init or from the interrupt @@ -2661,6 +2711,8 @@ static int __init early_amd_iommu_init(void) if (ret) goto out; + ivinfo_init(ivrs_base); + amd_iommu_target_ivhd_type = get_highest_supported_ivhd_type(ivrs_base); DUMP_printk("Using IVHD type %#x\n", amd_iommu_target_ivhd_type); -- GitLab From 2b1b3e544f65f40df5eef99753e460a127910479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 28 Jan 2021 10:53:46 +0100 Subject: [PATCH 0782/1084] drm/ttm: Use __GFP_NOWARN for huge pages in ttm_pool_alloc_page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without __GFP_NOWARN, attempts at allocating huge pages can trigger dmesg splats like below (which are essentially noise, since TTM falls back to normal pages if it can't get a huge one). [ 9556.710241] clinfo: page allocation failure: order:9, mode:0x194dc2(GFP_HIGHUSER|__GFP_RETRY_MAYFAIL|__GFP_NORETRY|__GFP_ZERO|__GFP_NOMEMALLOC), nodemask=(null),cpuset=user.slice,mems_allowed=0 [ 9556.710259] CPU: 1 PID: 470821 Comm: clinfo Tainted: G E 5.10.10+ #4 [ 9556.710264] Hardware name: Micro-Star International Co., Ltd. MS-7A34/B350 TOMAHAWK (MS-7A34), BIOS 1.OR 11/29/2019 [ 9556.710268] Call Trace: [ 9556.710281] dump_stack+0x6b/0x83 [ 9556.710288] warn_alloc.cold+0x7b/0xdf [ 9556.710297] ? __alloc_pages_direct_compact+0x137/0x150 [ 9556.710303] __alloc_pages_slowpath.constprop.0+0xc1b/0xc50 [ 9556.710312] __alloc_pages_nodemask+0x2ec/0x320 [ 9556.710325] ttm_pool_alloc+0x2e4/0x5e0 [ttm] [ 9556.710332] ? kvmalloc_node+0x46/0x80 [ 9556.710341] ttm_tt_populate+0x37/0xe0 [ttm] [ 9556.710350] ttm_bo_handle_move_mem+0x142/0x180 [ttm] [ 9556.710359] ttm_bo_validate+0x11d/0x190 [ttm] [ 9556.710391] ? drm_vma_offset_add+0x2f/0x60 [drm] [ 9556.710399] ttm_bo_init_reserved+0x2a7/0x320 [ttm] [ 9556.710529] amdgpu_bo_do_create+0x1b8/0x500 [amdgpu] [ 9556.710657] ? amdgpu_bo_subtract_pin_size+0x60/0x60 [amdgpu] [ 9556.710663] ? get_page_from_freelist+0x11f9/0x1450 [ 9556.710789] amdgpu_bo_create+0x40/0x270 [amdgpu] [ 9556.710797] ? _raw_spin_unlock+0x16/0x30 [ 9556.710927] amdgpu_gem_create_ioctl+0x123/0x310 [amdgpu] [ 9556.711062] ? amdgpu_gem_force_release+0x150/0x150 [amdgpu] [ 9556.711098] drm_ioctl_kernel+0xaa/0xf0 [drm] [ 9556.711133] drm_ioctl+0x20f/0x3a0 [drm] [ 9556.711267] ? amdgpu_gem_force_release+0x150/0x150 [amdgpu] [ 9556.711276] ? preempt_count_sub+0x9b/0xd0 [ 9556.711404] amdgpu_drm_ioctl+0x49/0x80 [amdgpu] [ 9556.711411] __x64_sys_ioctl+0x83/0xb0 [ 9556.711417] do_syscall_64+0x33/0x80 [ 9556.711421] entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: bf9eee249ac2 ("drm/ttm: stop using GFP_TRANSHUGE_LIGHT") Signed-off-by: Michel Dänzer Reviewed-by: Christian König Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/416353/ --- drivers/gpu/drm/ttm/ttm_pool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 11e0313db0ea6..74bf1c84b6374 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -84,7 +84,7 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags, * put_page() on a TTM allocated page is illegal. */ if (order) - gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY | + gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM; if (!pool->use_dma_alloc) { -- GitLab From 494b3688bb11a21af12e92a344a1313486693d47 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Tue, 19 Jan 2021 12:35:00 +0800 Subject: [PATCH 0783/1084] iommu/vt-d: Correctly check addr alignment in qi_flush_dev_iotlb_pasid() An incorrect address mask is being used in the qi_flush_dev_iotlb_pasid() to check the address alignment. This leads to a lot of spurious kernel warnings: [ 485.837093] DMAR: Invalidate non-aligned address 7f76f47f9000, order 0 [ 485.837098] DMAR: Invalidate non-aligned address 7f76f47f9000, order 0 [ 492.494145] qi_flush_dev_iotlb_pasid: 5734 callbacks suppressed [ 492.494147] DMAR: Invalidate non-aligned address 7f7728800000, order 11 [ 492.508965] DMAR: Invalidate non-aligned address 7f7728800000, order 11 Fix it by checking the alignment in right way. Fixes: 288d08e780088 ("iommu/vt-d: Handle non-page aligned address") Reported-and-tested-by: Guo Kaijie Signed-off-by: Lu Baolu Cc: Liu Yi L Link: https://lore.kernel.org/r/20210119043500.1539596-1-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel --- drivers/iommu/intel/dmar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c index 004feaed3c72c..02e7c10a4224b 100644 --- a/drivers/iommu/intel/dmar.c +++ b/drivers/iommu/intel/dmar.c @@ -1496,7 +1496,7 @@ void qi_flush_dev_iotlb_pasid(struct intel_iommu *iommu, u16 sid, u16 pfsid, * Max Invs Pending (MIP) is set to 0 for now until we have DIT in * ECAP. */ - if (addr & GENMASK_ULL(size_order + VTD_PAGE_SHIFT, 0)) + if (!IS_ALIGNED(addr, VTD_PAGE_SIZE << size_order)) pr_warn_ratelimited("Invalidate non-aligned address %llx, order %d\n", addr, size_order); -- GitLab From 4d395c5e74398f664405819330e5a298da37f655 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 26 Oct 2020 19:12:59 +0300 Subject: [PATCH 0784/1084] thunderbolt: Fix possible NULL pointer dereference in tb_acpi_add_link() When we walk up the device hierarchy in tb_acpi_add_link() make sure we break the loop if the device has no parent. Otherwise we may crash the kernel by dereferencing a NULL pointer. Fixes: b2be2b05cf3b ("thunderbolt: Create device links from ACPI description") Cc: stable@vger.kernel.org Signed-off-by: Mario Limonciello Acked-by: Yehezkel Bernat Signed-off-by: Mika Westerberg --- drivers/thunderbolt/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thunderbolt/acpi.c b/drivers/thunderbolt/acpi.c index a5f988a9f9482..b5442f979b4d0 100644 --- a/drivers/thunderbolt/acpi.c +++ b/drivers/thunderbolt/acpi.c @@ -56,7 +56,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data, * managed with the xHCI and the SuperSpeed hub so we create the * link from xHCI instead. */ - while (!dev_is_pci(dev)) + while (dev && !dev_is_pci(dev)) dev = dev->parent; if (!dev) -- GitLab From 41c1a06d1d1544bed9692ba72a5692454eee1945 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Sat, 23 Jan 2021 03:21:32 -0800 Subject: [PATCH 0785/1084] entry: Unbreak single step reporting behaviour The move of TIF_SYSCALL_EMU to SYSCALL_WORK_SYSCALL_EMU broke single step reporting. The original code reported the single step when TIF_SINGLESTEP was set and TIF_SYSCALL_EMU was not set. The SYSCALL_WORK conversion got the logic wrong and now the reporting only happens when both bits are set. Restore the original behaviour. [ tglx: Massaged changelog and dropped the pointless double negation ] Fixes: 64eb35f701f0 ("ptrace: Migrate TIF_SYSCALL_EMU to use SYSCALL_WORK flag") Signed-off-by: Yuxuan Shui Signed-off-by: Thomas Gleixner Reviewed-by: Gabriel Krisman Bertazi Link: https://lore.kernel.org/r/877do3gaq9.fsf@m5Zedd9JOGzJrf0 --- kernel/entry/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/entry/common.c b/kernel/entry/common.c index 378341642f94c..6dd82be60df81 100644 --- a/kernel/entry/common.c +++ b/kernel/entry/common.c @@ -222,7 +222,7 @@ static inline bool report_single_step(unsigned long work) */ static inline bool report_single_step(unsigned long work) { - if (!(work & SYSCALL_WORK_SYSCALL_EMU)) + if (work & SYSCALL_WORK_SYSCALL_EMU) return false; return !!(current_thread_info()->flags & _TIF_SINGLESTEP); -- GitLab From 29b32839725f8c89a41cb6ee054c85f3116ea8b5 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Wed, 27 Jan 2021 09:53:17 -0800 Subject: [PATCH 0786/1084] iommu/vt-d: Do not use flush-queue when caching-mode is on When an Intel IOMMU is virtualized, and a physical device is passed-through to the VM, changes of the virtual IOMMU need to be propagated to the physical IOMMU. The hypervisor therefore needs to monitor PTE mappings in the IOMMU page-tables. Intel specifications provide "caching-mode" capability that a virtual IOMMU uses to report that the IOMMU is virtualized and a TLB flush is needed after mapping to allow the hypervisor to propagate virtual IOMMU mappings to the physical IOMMU. To the best of my knowledge no real physical IOMMU reports "caching-mode" as turned on. Synchronizing the virtual and the physical IOMMU tables is expensive if the hypervisor is unaware which PTEs have changed, as the hypervisor is required to walk all the virtualized tables and look for changes. Consequently, domain flushes are much more expensive than page-specific flushes on virtualized IOMMUs with passthrough devices. The kernel therefore exploited the "caching-mode" indication to avoid domain flushing and use page-specific flushing in virtualized environments. See commit 78d5f0f500e6 ("intel-iommu: Avoid global flushes with caching mode.") This behavior changed after commit 13cf01744608 ("iommu/vt-d: Make use of iova deferred flushing"). Now, when batched TLB flushing is used (the default), full TLB domain flushes are performed frequently, requiring the hypervisor to perform expensive synchronization between the virtual TLB and the physical one. Getting batched TLB flushes to use page-specific invalidations again in such circumstances is not easy, since the TLB invalidation scheme assumes that "full" domain TLB flushes are performed for scalability. Disable batched TLB flushes when caching-mode is on, as the performance benefit from using batched TLB invalidations is likely to be much smaller than the overhead of the virtual-to-physical IOMMU page-tables synchronization. Fixes: 13cf01744608 ("iommu/vt-d: Make use of iova deferred flushing") Signed-off-by: Nadav Amit Cc: David Woodhouse Cc: Lu Baolu Cc: Joerg Roedel Cc: Will Deacon Cc: stable@vger.kernel.org Acked-by: Lu Baolu Link: https://lore.kernel.org/r/20210127175317.1600473-1-namit@vmware.com Signed-off-by: Joerg Roedel --- drivers/iommu/intel/iommu.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index f665322a09919..06b00b5363d86 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -5440,6 +5440,36 @@ intel_iommu_domain_set_attr(struct iommu_domain *domain, return ret; } +static bool domain_use_flush_queue(void) +{ + struct dmar_drhd_unit *drhd; + struct intel_iommu *iommu; + bool r = true; + + if (intel_iommu_strict) + return false; + + /* + * The flush queue implementation does not perform page-selective + * invalidations that are required for efficient TLB flushes in virtual + * environments. The benefit of batching is likely to be much lower than + * the overhead of synchronizing the virtual and physical IOMMU + * page-tables. + */ + rcu_read_lock(); + for_each_active_iommu(iommu, drhd) { + if (!cap_caching_mode(iommu->cap)) + continue; + + pr_warn_once("IOMMU batching is disabled due to virtualization"); + r = false; + break; + } + rcu_read_unlock(); + + return r; +} + static int intel_iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) @@ -5450,7 +5480,7 @@ intel_iommu_domain_get_attr(struct iommu_domain *domain, case IOMMU_DOMAIN_DMA: switch (attr) { case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE: - *(int *)data = !intel_iommu_strict; + *(int *)data = domain_use_flush_queue(); return 0; default: return -ENODEV; -- GitLab From 6c635caef410aa757befbd8857c1eadde5cc22ed Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Thu, 28 Jan 2021 13:58:15 +0800 Subject: [PATCH 0787/1084] blk-cgroup: Use cond_resched() when destroy blkgs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On !PREEMPT kernel, we can get below softlockup when doing stress testing with creating and destroying block cgroup repeatly. The reason is it may take a long time to acquire the queue's lock in the loop of blkcg_destroy_blkgs(), or the system can accumulate a huge number of blkgs in pathological cases. We can add a need_resched() check on each loop and release locks and do cond_resched() if true to avoid this issue, since the blkcg_destroy_blkgs() is not called from atomic contexts. [ 4757.010308] watchdog: BUG: soft lockup - CPU#11 stuck for 94s! [ 4757.010698] Call trace: [ 4757.010700]  blkcg_destroy_blkgs+0x68/0x150 [ 4757.010701]  cgwb_release_workfn+0x104/0x158 [ 4757.010702]  process_one_work+0x1bc/0x3f0 [ 4757.010704]  worker_thread+0x164/0x468 [ 4757.010705]  kthread+0x108/0x138 Suggested-by: Tejun Heo Signed-off-by: Baolin Wang Signed-off-by: Jens Axboe --- block/blk-cgroup.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 031114d454a60..4221a1539391c 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1016,6 +1016,8 @@ static void blkcg_css_offline(struct cgroup_subsys_state *css) */ void blkcg_destroy_blkgs(struct blkcg *blkcg) { + might_sleep(); + spin_lock_irq(&blkcg->lock); while (!hlist_empty(&blkcg->blkg_list)) { @@ -1023,14 +1025,20 @@ void blkcg_destroy_blkgs(struct blkcg *blkcg) struct blkcg_gq, blkcg_node); struct request_queue *q = blkg->q; - if (spin_trylock(&q->queue_lock)) { - blkg_destroy(blkg); - spin_unlock(&q->queue_lock); - } else { + if (need_resched() || !spin_trylock(&q->queue_lock)) { + /* + * Given that the system can accumulate a huge number + * of blkgs in pathological cases, check to see if we + * need to rescheduling to avoid softlockup. + */ spin_unlock_irq(&blkcg->lock); - cpu_relax(); + cond_resched(); spin_lock_irq(&blkcg->lock); + continue; } + + blkg_destroy(blkg); + spin_unlock(&q->queue_lock); } spin_unlock_irq(&blkcg->lock); -- GitLab From 0fe37724f8e70fa4cb72948f60fca553702df768 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Thu, 28 Jan 2021 15:36:19 +0900 Subject: [PATCH 0788/1084] block: fix bd_size_lock use Some block device drivers, e.g. the skd driver, call set_capacity() with IRQ disabled. This results in lockdep ito complain about inconsistent lock states ("inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage") because set_capacity takes a block device bd_size_lock using the functions spin_lock() and spin_unlock(). Ensure a consistent locking state by replacing these calls with spin_lock_irqsave() and spin_lock_irqrestore(). The same applies to bdev_set_nr_sectors(). With this fix, all lockdep complaints are resolved. Signed-off-by: Damien Le Moal Signed-off-by: Jens Axboe --- block/genhd.c | 5 +++-- block/partitions/core.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 419548e92d82f..9e741a4f351be 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -45,10 +45,11 @@ static void disk_release_events(struct gendisk *disk); void set_capacity(struct gendisk *disk, sector_t sectors) { struct block_device *bdev = disk->part0; + unsigned long flags; - spin_lock(&bdev->bd_size_lock); + spin_lock_irqsave(&bdev->bd_size_lock, flags); i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT); - spin_unlock(&bdev->bd_size_lock); + spin_unlock_irqrestore(&bdev->bd_size_lock, flags); } EXPORT_SYMBOL(set_capacity); diff --git a/block/partitions/core.c b/block/partitions/core.c index 23460cee9de50..4601a845cd79e 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -88,9 +88,11 @@ static int (*check_part[])(struct parsed_partitions *) = { static void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors) { - spin_lock(&bdev->bd_size_lock); + unsigned long flags; + + spin_lock_irqsave(&bdev->bd_size_lock, flags); i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT); - spin_unlock(&bdev->bd_size_lock); + spin_unlock_irqrestore(&bdev->bd_size_lock, flags); } static struct parsed_partitions *allocate_partitions(struct gendisk *hd) -- GitLab From 0df28cad06eb41cc36bfea69d9c882fb567fd0d6 Mon Sep 17 00:00:00 2001 From: Coly Li Date: Thu, 28 Jan 2021 18:48:47 +0800 Subject: [PATCH 0789/1084] bcache: only check feature sets when sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES For super block version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES, it doesn't make sense to check the feature sets. This patch checks super block version in bch_has_feature_* routines, if the version doesn't have feature sets yet, returns 0 (false) to the caller. Fixes: 5342fd425502 ("bcache: set bcache device into read-only mode for BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET") Fixes: ffa470327572 ("bcache: add bucket_size_hi into struct cache_sb_disk for large bucket") Cc: stable@vger.kernel.org # 5.9+ Reported-and-tested-by: Bockholdt Arne Signed-off-by: Coly Li Signed-off-by: Jens Axboe --- drivers/md/bcache/features.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/md/bcache/features.h b/drivers/md/bcache/features.h index 84fc2c0f01015..d1c8fd3977fc6 100644 --- a/drivers/md/bcache/features.h +++ b/drivers/md/bcache/features.h @@ -33,6 +33,8 @@ #define BCH_FEATURE_COMPAT_FUNCS(name, flagname) \ static inline int bch_has_feature_##name(struct cache_sb *sb) \ { \ + if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \ + return 0; \ return (((sb)->feature_compat & \ BCH##_FEATURE_COMPAT_##flagname) != 0); \ } \ @@ -50,6 +52,8 @@ static inline void bch_clear_feature_##name(struct cache_sb *sb) \ #define BCH_FEATURE_RO_COMPAT_FUNCS(name, flagname) \ static inline int bch_has_feature_##name(struct cache_sb *sb) \ { \ + if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \ + return 0; \ return (((sb)->feature_ro_compat & \ BCH##_FEATURE_RO_COMPAT_##flagname) != 0); \ } \ @@ -67,6 +71,8 @@ static inline void bch_clear_feature_##name(struct cache_sb *sb) \ #define BCH_FEATURE_INCOMPAT_FUNCS(name, flagname) \ static inline int bch_has_feature_##name(struct cache_sb *sb) \ { \ + if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \ + return 0; \ return (((sb)->feature_incompat & \ BCH##_FEATURE_INCOMPAT_##flagname) != 0); \ } \ -- GitLab From 19d51588125fb7abe258e85b412710486a3d9219 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Wed, 27 Jan 2021 13:44:35 -0800 Subject: [PATCH 0790/1084] cifs: ignore auto and noauto options if given In 24e0a1eff9e2, the noauto and auto options were missed when migrating to the new mount API. As a result, users with noauto in their fstab mount options are now unable to mount cifs filesystems, as they'll receive an "Unknown parameter" error. This restores the old behaviour of ignoring noauto and auto if they're given. Fixes: 24e0a1eff9e2 ("cifs: switch to new mount api") Signed-off-by: Adam Harvey Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/fs_context.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index 076bcadc756a7..62818b142e2e8 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -175,6 +175,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = { fsparam_flag_no("exec", Opt_ignore), fsparam_flag_no("dev", Opt_ignore), fsparam_flag_no("mand", Opt_ignore), + fsparam_flag_no("auto", Opt_ignore), fsparam_string("cred", Opt_ignore), fsparam_string("credentials", Opt_ignore), {} -- GitLab From 757fed1d0898b893d7daa84183947c70f27632f3 Mon Sep 17 00:00:00 2001 From: Wang Hai Date: Thu, 28 Jan 2021 19:32:50 +0800 Subject: [PATCH 0791/1084] Revert "mm/slub: fix a memory leak in sysfs_slab_add()" This reverts commit dde3c6b72a16c2db826f54b2d49bdea26c3534a2. syzbot report a double-free bug. The following case can cause this bug. - mm/slab_common.c: create_cache(): if the __kmem_cache_create() fails, it does: out_free_cache: kmem_cache_free(kmem_cache, s); - but __kmem_cache_create() - at least for slub() - will have done sysfs_slab_add(s) -> sysfs_create_group() .. fails .. -> kobject_del(&s->kobj); .. which frees s ... We can't remove the kmem_cache_free() in create_cache(), because other error cases of __kmem_cache_create() do not free this. So, revert the commit dde3c6b72a16 ("mm/slub: fix a memory leak in sysfs_slab_add()") to fix this. Reported-by: syzbot+d0bd96b4696c1ef67991@syzkaller.appspotmail.com Fixes: dde3c6b72a16 ("mm/slub: fix a memory leak in sysfs_slab_add()") Acked-by: Vlastimil Babka Signed-off-by: Wang Hai Cc: Signed-off-by: Linus Torvalds --- mm/slub.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 69742ab9a21d3..7ecbbbe5bc0c1 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -5625,10 +5625,8 @@ static int sysfs_slab_add(struct kmem_cache *s) s->kobj.kset = kset; err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name); - if (err) { - kobject_put(&s->kobj); + if (err) goto out; - } err = sysfs_create_group(&s->kobj, &slab_attr_group); if (err) -- GitLab From 6c28377b7114d04cf82eedffe9dcc8fa66ecec48 Mon Sep 17 00:00:00 2001 From: Srinivasa Rao Mandadapu Date: Wed, 27 Jan 2021 20:48:24 +0530 Subject: [PATCH 0792/1084] ASoC: qcom: lpass-cpu: Remove bit clock state check No need of BCLK state maintenance from driver side as clock_enable and clk_disable API's maintaing state counter. One of the major issue was spotted when Headset jack inserted while playback continues, due to same PCM device node opens twice for playaback/capture and closes once for capture and playback continues. It can resolve the errors in such scenarios. Fixes: b1824968221c ("ASoC: qcom: Fix enabling BCLK and LRCLK in LPAIF invalid state") Signed-off-by: Srinivasa Rao Mandadapu Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210127151824.8929-1-srivasam@codeaurora.org Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-cpu.c | 22 ++++++++-------------- sound/soc/qcom/lpass-lpaif-reg.h | 3 --- sound/soc/qcom/lpass.h | 1 - 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 66b834312f330..73ca24c0a08b7 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -286,16 +286,12 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, dev_err(dai->dev, "error writing to i2sctl reg: %d\n", ret); - if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_DISABLE) { - ret = clk_enable(drvdata->mi2s_bit_clk[id]); - if (ret) { - dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret); - clk_disable(drvdata->mi2s_osr_clk[id]); - return ret; - } - drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_ENABLE; + ret = clk_enable(drvdata->mi2s_bit_clk[id]); + if (ret) { + dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret); + clk_disable(drvdata->mi2s_osr_clk[id]); + return ret; } - break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: @@ -310,10 +306,9 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, if (ret) dev_err(dai->dev, "error writing to i2sctl reg: %d\n", ret); - if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_ENABLE) { - clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]); - drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_DISABLE; - } + + clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]); + break; } @@ -866,7 +861,6 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); } - drvdata->bit_clk_state[dai_id] = LPAIF_BIT_CLK_DISABLE; } /* Allocation for i2sctl regmap fields */ diff --git a/sound/soc/qcom/lpass-lpaif-reg.h b/sound/soc/qcom/lpass-lpaif-reg.h index baf72f124ea9b..2eb03ad9b7c74 100644 --- a/sound/soc/qcom/lpass-lpaif-reg.h +++ b/sound/soc/qcom/lpass-lpaif-reg.h @@ -60,9 +60,6 @@ #define LPAIF_I2SCTL_BITWIDTH_24 1 #define LPAIF_I2SCTL_BITWIDTH_32 2 -#define LPAIF_BIT_CLK_DISABLE 0 -#define LPAIF_BIT_CLK_ENABLE 1 - #define LPAIF_I2SCTL_RESET_STATE 0x003C0004 #define LPAIF_DMACTL_RESET_STATE 0x00200000 diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h index 2d68af0da34d8..83b2e08ade060 100644 --- a/sound/soc/qcom/lpass.h +++ b/sound/soc/qcom/lpass.h @@ -68,7 +68,6 @@ struct lpass_data { unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; int hdmi_port_enable; - int bit_clk_state[LPASS_MAX_MI2S_PORTS]; /* low-power audio interface (LPAIF) registers */ void __iomem *lpaif; -- GitLab From 0084364d9678e9d722ee620ed916f2f9954abdbf Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 28 Jan 2021 11:23:45 +0200 Subject: [PATCH 0793/1084] ASoC: SOF: Intel: hda: cancel D0i3 work during runtime suspend Cancel the D0i3 work during runtime suspend as no streams are active at this point anyway. Fixes: 63e51fd33fef ("ASoC: SOF: Intel: cnl: Implement feature to support DSP D0i3 in S0") Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128092345.1033085-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 1c5e05b88a90d..1799fc56a3e41 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -802,11 +802,15 @@ int hda_dsp_runtime_idle(struct snd_sof_dev *sdev) int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev) { + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; const struct sof_dsp_power_state target_state = { .state = SOF_DSP_PM_D3, }; int ret; + /* cancel any attempt for DSP D0I3 */ + cancel_delayed_work_sync(&hda->d0i3_work); + /* stop hda controller and power dsp off */ ret = hda_suspend(sdev, true); if (ret < 0) -- GitLab From f6c246eacb62977dea5c9c65ac6fb4921cad5bcd Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:46 +0200 Subject: [PATCH 0794/1084] ASoC: SOF: Intel: hda: use snd_sof_dsp_core_power_up/down API To implement common logic in SOF core, core power up/down flows should use common SOF API and not directly use low-level platform specific helper functions. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-2-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 2 +- sound/soc/sof/intel/hda-loader.c | 2 +- sound/soc/sof/intel/hda.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 2b001151fe376..4fe4175179d4a 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -624,7 +624,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) #endif /* power down DSP */ - ret = hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask); + ret = snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask); if (ret < 0) { dev_err(sdev->dev, "error: failed to power down core during suspend\n"); diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 365a79fc70811..4b2ab351e2cc6 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -183,7 +183,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) flags |= SOF_DBG_DUMP_FORCE_ERR_LEVEL; hda_dsp_dump(sdev, flags); - hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask); + snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask); return ret; } diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 7e703ce22fcd3..d57d484a42d13 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -928,7 +928,7 @@ int hda_dsp_remove(struct snd_sof_dev *sdev) /* disable cores */ if (chip) - hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask); + snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask); /* disable DSP */ snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, -- GitLab From cedd502d18b5b7a913fa13fa18a037cc51b1798d Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:47 +0200 Subject: [PATCH 0795/1084] ASoC: SOF: Intel: hda-loader: keep init cores alive init_core_mask should be the available cores mask after fw boot. So we should keep not core 0 but init cores alive. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-3-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 4b2ab351e2cc6..07b73fe3c5e5d 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -147,8 +147,9 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) chip->ipc_ack_mask, chip->ipc_ack_mask); - /* step 5: power down corex */ - ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & ~(BIT(0))); + /* step 5: power down cores that are no longer needed */ + ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & + ~(chip->init_core_mask)); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, -- GitLab From 42077f08b3f1ba891dca1f8f479810f16b7d6cbd Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:48 +0200 Subject: [PATCH 0796/1084] ASoC: SOF: update dsp core power status in common APIs Only manage enabled_cores_mask in common snd_sof_dsp_core_power_up/down APIs to ensure it stays in sync with actual DSP core state. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-4-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/loader.c | 6 ------ sound/soc/sof/ops.h | 22 ++++++++++++++++------ sound/soc/sof/pm.c | 1 - sound/soc/sof/topology.c | 8 -------- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index 08a17abb63ff5..4ade55bf6d751 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c @@ -811,7 +811,6 @@ EXPORT_SYMBOL(snd_sof_load_firmware); int snd_sof_run_firmware(struct snd_sof_dev *sdev) { int ret; - int init_core_mask; init_waitqueue_head(&sdev->boot_wait); @@ -843,8 +842,6 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev) return ret; } - init_core_mask = ret; - /* * now wait for the DSP to boot. There are 3 possible outcomes: * 1. Boot wait times out indicating FW boot failure. @@ -874,9 +871,6 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev) return ret; } - /* fw boot is complete. Update the active cores mask */ - sdev->enabled_cores_mask = init_core_mask; - return 0; } EXPORT_SYMBOL(snd_sof_run_firmware); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index f0c9ca8820d2a..2e9a8da53d570 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -76,19 +76,29 @@ static inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev) static inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask) { - if (sof_ops(sdev)->core_power_up) - return sof_ops(sdev)->core_power_up(sdev, core_mask); + int ret = 0; - return 0; + if (sof_ops(sdev)->core_power_up) { + ret = sof_ops(sdev)->core_power_up(sdev, core_mask); + if (!ret) + sdev->enabled_cores_mask |= core_mask; + } + + return ret; } static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask) { - if (sof_ops(sdev)->core_power_down) - return sof_ops(sdev)->core_power_down(sdev, core_mask); + int ret = 0; - return 0; + if (sof_ops(sdev)->core_power_down) { + ret = sof_ops(sdev)->core_power_down(sdev, core_mask); + if (!ret) + sdev->enabled_cores_mask &= ~core_mask; + } + + return ret; } /* pre/post fw load */ diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index c83fb62559616..fd265803f7bc7 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -256,7 +256,6 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) /* reset FW state */ sdev->fw_state = SOF_FW_BOOT_NOT_STARTED; - sdev->enabled_cores_mask = 0; return ret; } diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index b6b32a7a91f87..b69f493b5faa9 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1352,10 +1352,6 @@ static int sof_core_enable(struct snd_sof_dev *sdev, int core) core, ret); goto err; } - - /* update enabled cores mask */ - sdev->enabled_cores_mask |= BIT(core); - return ret; err: /* power down core if it is host managed and return the original error if this fails too */ @@ -2603,10 +2599,6 @@ static int sof_widget_unload(struct snd_soc_component *scomp, if (ret < 0) dev_err(scomp->dev, "error: powering down pipeline schedule core %d\n", pipeline->core); - - /* update enabled cores mask */ - sdev->enabled_cores_mask &= ~(1 << pipeline->core); - break; default: break; -- GitLab From 30876e2a06f35b525dc71f94dfc3c6f329e55a28 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:49 +0200 Subject: [PATCH 0797/1084] ASoC: SOF: Filter out unneeded core power up/downs Exclude cores that are already powered on/off correctly. This allows to simplify dsp_power_up/down() implementations and avoid unexpected error. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-5-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ops.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 2e9a8da53d570..5099ad03df72f 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -78,7 +78,8 @@ static inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev, { int ret = 0; - if (sof_ops(sdev)->core_power_up) { + core_mask &= ~sdev->enabled_cores_mask; + if (sof_ops(sdev)->core_power_up && core_mask) { ret = sof_ops(sdev)->core_power_up(sdev, core_mask); if (!ret) sdev->enabled_cores_mask |= core_mask; @@ -92,7 +93,8 @@ static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev, { int ret = 0; - if (sof_ops(sdev)->core_power_down) { + core_mask &= sdev->enabled_cores_mask; + if (sof_ops(sdev)->core_power_down && core_mask) { ret = sof_ops(sdev)->core_power_down(sdev, core_mask); if (!ret) sdev->enabled_cores_mask &= ~core_mask; -- GitLab From 92c6ec606cd12c16091b70442da536bdeddb1f7f Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:50 +0200 Subject: [PATCH 0798/1084] ASoC: SOF: intel: hda-loader: use snd_sof_dsp_core_power_down/up APIs To manage enabled_cores_mask flag, we should always use snd_sof_dsp_ core_power_down/up APIs to power up/down dsp cores. The APIs do a little bit more than the original functions, but it is harmless. Suggested-by: Ranjani Sridharan Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-6-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 07b73fe3c5e5d..d744952f69543 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -93,7 +93,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) int i; /* step 1: power up corex */ - ret = hda_dsp_core_power_up(sdev, chip->host_managed_cores_mask); + ret = snd_sof_dsp_core_power_up(sdev, chip->host_managed_cores_mask); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n"); @@ -148,8 +148,8 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) chip->ipc_ack_mask); /* step 5: power down cores that are no longer needed */ - ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & - ~(chip->init_core_mask)); + ret = snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask & + ~(chip->init_core_mask)); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, -- GitLab From 1fc96dc29c3ba342915c3a935c9d177f8f420d03 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 28 Jan 2021 12:57:51 +0200 Subject: [PATCH 0799/1084] ASoC: Intel: remove duplicate MODULE_LICENSE/DESCRIPTION tags The snd-soc-acpi-intel-match has duplicate module tags for all platforms separately. Remove all but one and save some storage space and cleanup modinfo output. Signed-off-by: Kai Vehmanen Reviewed-by: Rander Wang Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210128105751.1049837-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-bxt-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-byt-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-cfl-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-cht-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-cml-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-cnl-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-ehl-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-glk-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-icl-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-jsl-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-kbl-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-skl-match.c | 3 --- sound/soc/intel/common/soc-acpi-intel-tgl-match.c | 3 --- 14 files changed, 42 deletions(-) diff --git a/sound/soc/intel/common/soc-acpi-intel-bxt-match.c b/sound/soc/intel/common/soc-acpi-intel-bxt-match.c index 32f77e29c2ff5..398cc771c8351 100644 --- a/sound/soc/intel/common/soc-acpi-intel-bxt-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-bxt-match.c @@ -85,6 +85,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_bxt_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c index c348607b49a59..31e60df131c37 100644 --- a/sound/soc/intel/common/soc-acpi-intel-byt-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-byt-match.c @@ -233,6 +233,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_baytrail_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-cfl-match.c b/sound/soc/intel/common/soc-acpi-intel-cfl-match.c index 27b4b73d94d48..1733dfb23e797 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cfl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cfl-match.c @@ -18,6 +18,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_sdw_machines[] = { {} }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cfl_sdw_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c index 2752dc9557334..227424236fd57 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c @@ -196,6 +196,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cherrytrail_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-cml-match.c b/sound/soc/intel/common/soc-acpi-intel-cml-match.c index adddc91918dfe..2161b3b85b4a1 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c @@ -309,6 +309,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[] = { {} }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_sdw_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c index b80f032a8b76d..ec77a57a07ba0 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c @@ -63,6 +63,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[] = { {} }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cnl_sdw_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c index 5c7a1214403d3..6222708a98e70 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c @@ -20,6 +20,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ehl_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-glk-match.c b/sound/soc/intel/common/soc-acpi-intel-glk-match.c index 26cb3b16cdd34..6ceaab19ccb63 100644 --- a/sound/soc/intel/common/soc-acpi-intel-glk-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-glk-match.c @@ -43,6 +43,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_glk_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c b/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c index 35958553652ec..fe343a95b5ff7 100644 --- a/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c @@ -53,6 +53,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[] = { {} }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_broadwell_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c index 9a529a7852885..d38ff7d187c4d 100644 --- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c @@ -185,6 +185,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_sdw_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_sdw_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c index 34f5fcad5701f..52238db0bcb53 100644 --- a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c @@ -63,6 +63,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_jsl_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-kbl-match.c b/sound/soc/intel/common/soc-acpi-intel-kbl-match.c index a4fbe6707ca76..47dadc9d5d2a0 100644 --- a/sound/soc/intel/common/soc-acpi-intel-kbl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-kbl-match.c @@ -128,6 +128,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_kbl_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-skl-match.c b/sound/soc/intel/common/soc-acpi-intel-skl-match.c index 26f9ce1465230..961df8d6b5e40 100644 --- a/sound/soc/intel/common/soc-acpi-intel-skl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-skl-match.c @@ -42,6 +42,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_skl_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_skl_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c index 4933184df5f50..ee25451dfdd0a 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -411,6 +411,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_sdw_machines); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel Common ACPI Match module"); -- GitLab From c9b8cd6a39c48b2827c0925b648b221b5f8ef25d Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 28 Jan 2021 11:20:22 -0600 Subject: [PATCH 0800/1084] cifs: fix mounts to subdirectories of target The "prefixpath" mount option needs to be ignored which was missed in the recent conversion to the new mount API (prefixpath would be set by the mount helper if mounting a subdirectory of the root of a share e.g. //server/share/subdir) Fixes: 24e0a1eff9e2 ("cifs: switch to new mount api") Suggested-by: Ronnie Sahlberg Signed-off-by: Steve French Reviewed-by: Ronnie Sahlberg --- fs/cifs/fs_context.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index 62818b142e2e8..818c413db82d2 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -178,6 +178,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = { fsparam_flag_no("auto", Opt_ignore), fsparam_string("cred", Opt_ignore), fsparam_string("credentials", Opt_ignore), + fsparam_string("prefixpath", Opt_ignore), {} }; -- GitLab From ae000861b95cc4521c498430eb9c61ad62cea51c Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Thu, 28 Jan 2021 23:47:47 +0800 Subject: [PATCH 0801/1084] KVM: Documentation: Fix documentation for nested. Nested VMX was enabled by default in commit 1e58e5e59148 ("KVM: VMX: enable nested virtualization by default"), which was merged in Linux 4.20. This patch is to fix the documentation accordingly. Signed-off-by: Yu Zhang Message-Id: <20210128154747.4242-1-yu.c.zhang@linux.intel.com> Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/nested-vmx.rst | 6 ++++-- Documentation/virt/kvm/running-nested-guests.rst | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/virt/kvm/nested-vmx.rst b/Documentation/virt/kvm/nested-vmx.rst index 6ab4e35cee233..ac2095d41f020 100644 --- a/Documentation/virt/kvm/nested-vmx.rst +++ b/Documentation/virt/kvm/nested-vmx.rst @@ -37,8 +37,10 @@ call L2. Running nested VMX ------------------ -The nested VMX feature is disabled by default. It can be enabled by giving -the "nested=1" option to the kvm-intel module. +The nested VMX feature is enabled by default since Linux kernel v4.20. For +older Linux kernel, it can be enabled by giving the "nested=1" option to the +kvm-intel module. + No modifications are required to user space (qemu). However, qemu's default emulated CPU type (qemu64) does not list the "VMX" CPU feature, so it must be diff --git a/Documentation/virt/kvm/running-nested-guests.rst b/Documentation/virt/kvm/running-nested-guests.rst index d0a1fc754c84f..bd70c69468aeb 100644 --- a/Documentation/virt/kvm/running-nested-guests.rst +++ b/Documentation/virt/kvm/running-nested-guests.rst @@ -74,7 +74,7 @@ few: Enabling "nested" (x86) ----------------------- -From Linux kernel v4.19 onwards, the ``nested`` KVM parameter is enabled +From Linux kernel v4.20 onwards, the ``nested`` KVM parameter is enabled by default for Intel and AMD. (Though your Linux distribution might override this default.) -- GitLab From 19a23da53932bc8011220bd8c410cb76012de004 Mon Sep 17 00:00:00 2001 From: Peter Gonda Date: Wed, 27 Jan 2021 08:15:24 -0800 Subject: [PATCH 0802/1084] Fix unsynchronized access to sev members through svm_register_enc_region Grab kvm->lock before pinning memory when registering an encrypted region; sev_pin_memory() relies on kvm->lock being held to ensure correctness when checking and updating the number of pinned pages. Add a lockdep assertion to help prevent future regressions. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Paolo Bonzini Cc: Joerg Roedel Cc: Tom Lendacky Cc: Brijesh Singh Cc: Sean Christopherson Cc: x86@kernel.org Cc: kvm@vger.kernel.org Cc: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org Fixes: 1e80fdc09d12 ("KVM: SVM: Pin guest memory when SEV is active") Signed-off-by: Peter Gonda V2 - Fix up patch description - Correct file paths svm.c -> sev.c - Add unlock of kvm->lock on sev_pin_memory error V1 - https://lore.kernel.org/kvm/20210126185431.1824530-1-pgonda@google.com/ Message-Id: <20210127161524.2832400-1-pgonda@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/sev.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index ac652bc476ae7..48017fef1cd9c 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -342,6 +342,8 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr, unsigned long first, last; int ret; + lockdep_assert_held(&kvm->lock); + if (ulen == 0 || uaddr + ulen < uaddr) return ERR_PTR(-EINVAL); @@ -1119,12 +1121,20 @@ int svm_register_enc_region(struct kvm *kvm, if (!region) return -ENOMEM; + mutex_lock(&kvm->lock); region->pages = sev_pin_memory(kvm, range->addr, range->size, ®ion->npages, 1); if (IS_ERR(region->pages)) { ret = PTR_ERR(region->pages); + mutex_unlock(&kvm->lock); goto e_free; } + region->uaddr = range->addr; + region->size = range->size; + + list_add_tail(®ion->list, &sev->regions_list); + mutex_unlock(&kvm->lock); + /* * The guest may change the memory encryption attribute from C=0 -> C=1 * or vice versa for this memory range. Lets make sure caches are @@ -1133,13 +1143,6 @@ int svm_register_enc_region(struct kvm *kvm, */ sev_clflush_pages(region->pages, region->npages); - region->uaddr = range->addr; - region->size = range->size; - - mutex_lock(&kvm->lock); - list_add_tail(®ion->list, &sev->regions_list); - mutex_unlock(&kvm->lock); - return ret; e_free: -- GitLab From 899199292b14b7c735808a37517de4dd2160c300 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Mon, 25 Jan 2021 21:19:16 -0800 Subject: [PATCH 0803/1084] nvme-pci: add the DISABLE_WRITE_ZEROES quirk for a SPCC device This adds a quirk for SPCC 256GB NVMe 1.3 drive which fixes timeouts and I/O errors due to the fact that the controller does not properly handle the Write Zeroes command: [ 2745.659527] CPU: 2 PID: 0 Comm: swapper/2 Tainted: G E 5.10.6-BET #1 [ 2745.659528] Hardware name: System manufacturer System Product Name/PRIME X570-P, BIOS 3001 12/04/2020 [ 2776.138874] nvme nvme1: I/O 414 QID 3 timeout, aborting [ 2776.138886] nvme nvme1: I/O 415 QID 3 timeout, aborting [ 2776.138891] nvme nvme1: I/O 416 QID 3 timeout, aborting [ 2776.138895] nvme nvme1: I/O 417 QID 3 timeout, aborting [ 2776.138912] nvme nvme1: Abort status: 0x0 [ 2776.138921] nvme nvme1: I/O 428 QID 3 timeout, aborting [ 2776.138922] nvme nvme1: Abort status: 0x0 [ 2776.138925] nvme nvme1: Abort status: 0x0 [ 2776.138974] nvme nvme1: Abort status: 0x0 [ 2776.138977] nvme nvme1: Abort status: 0x0 [ 2806.346792] nvme nvme1: I/O 414 QID 3 timeout, reset controller [ 2806.363566] nvme nvme1: 15/0/0 default/read/poll queues [ 2836.554298] nvme nvme1: I/O 415 QID 3 timeout, disable controller [ 2836.672064] blk_update_request: I/O error, dev nvme1n1, sector 16350 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672072] blk_update_request: I/O error, dev nvme1n1, sector 16093 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672074] blk_update_request: I/O error, dev nvme1n1, sector 15836 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672076] blk_update_request: I/O error, dev nvme1n1, sector 15579 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672078] blk_update_request: I/O error, dev nvme1n1, sector 15322 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672080] blk_update_request: I/O error, dev nvme1n1, sector 15065 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672082] blk_update_request: I/O error, dev nvme1n1, sector 14808 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672083] blk_update_request: I/O error, dev nvme1n1, sector 14551 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672085] blk_update_request: I/O error, dev nvme1n1, sector 14294 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672087] blk_update_request: I/O error, dev nvme1n1, sector 14037 op 0x9:(WRITE_ZEROES) flags 0x0 phys_seg 0 prio class 0 [ 2836.672121] nvme nvme1: failed to mark controller live state [ 2836.672123] nvme nvme1: Removing after probe failure status: -19 [ 2836.689016] Aborting journal on device dm-0-8. [ 2836.689024] Buffer I/O error on dev dm-0, logical block 25198592, lost sync page write [ 2836.689027] JBD2: Error -5 detected when updating journal superblock for dm-0-8. Reported-by: Bradley Chapman Signed-off-by: Chaitanya Kulkarni Tested-by: Bradley Chapman Reviewed-by: Keith Busch Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 856aa31931c14..81e6389b20420 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3257,6 +3257,8 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, { PCI_DEVICE(0x15b7, 0x2001), /* Sandisk Skyhawk */ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x1d97, 0x2263), /* SPCC */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001), .driver_data = NVME_QUIRK_SINGLE_VECTOR }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) }, -- GitLab From d1bcf006a9d3d63c1bcb65a993cb13756954cd9c Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 27 Jan 2021 11:30:33 +0100 Subject: [PATCH 0804/1084] nvme-multipath: Early exit if no path is available nvme_round_robin_path() should test if the return ns pointer is valid. nvme_next_ns() will return a NULL pointer if there is no path left. Fixes: 75c10e732724 ("nvme-multipath: round-robin I/O policy") Signed-off-by: Daniel Wagner Reviewed-by: Hannes Reinecke Signed-off-by: Christoph Hellwig --- drivers/nvme/host/multipath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 9ac762b288112..282b7a4ea9a9a 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -221,7 +221,7 @@ static struct nvme_ns *nvme_round_robin_path(struct nvme_ns_head *head, } for (ns = nvme_next_ns(head, old); - ns != old; + ns && ns != old; ns = nvme_next_ns(head, ns)) { if (nvme_path_is_disabled(ns)) continue; -- GitLab From 772ea326a4a00b6b4b2c8f3606ad10c31f46c511 Mon Sep 17 00:00:00 2001 From: Chao Leng Date: Thu, 28 Jan 2021 11:33:51 +0800 Subject: [PATCH 0805/1084] nvme-core: use list_add_tail_rcu instead of list_add_tail for nvme_init_ns_head The "list" of nvme_ns_head is used as rcu list, now in nvme_init_ns_head list_add_tail is used to add ns->siblings to the rcu list. It is not safe. Should use list_add_tail_rcu instead of list_add_tail. Signed-off-by: Chao Leng Signed-off-by: Christoph Hellwig --- drivers/nvme/host/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 8caf9b34734dc..f13eb4ded95fa 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3829,7 +3829,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid, } } - list_add_tail(&ns->siblings, &head->list); + list_add_tail_rcu(&ns->siblings, &head->list); ns->head = head; mutex_unlock(&ctrl->subsys->lock); return 0; -- GitLab From a119f87b86bcdf14a18ce39a899e97a1e9160f7f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Jan 2021 13:28:59 -0500 Subject: [PATCH 0806/1084] Revert "drm/amdgpu/swsmu: drop set_fan_speed_percent (v2)" On some boards the rpm interface apparently does not work at all leading to the fan not spinning or spinning at strange speeds. Revert this for now to fix 5.10, 5.11. The follow on patch fixes this properly for 5.12. This reverts commit 8d6e65adc25e23fabbc5293b6cd320195c708dca. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1408 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h | 1 + drivers/gpu/drm/amd/pm/inc/smu_v11_0.h | 3 ++ drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 9 ++---- .../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 1 + .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 1 + .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 1 + .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 31 ++++++++++++++++++- 7 files changed, 39 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h index 4bdbcce7092d1..0d797fa9f5cc6 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h @@ -553,6 +553,7 @@ struct pptable_funcs { *clock_req); uint32_t (*get_fan_control_mode)(struct smu_context *smu); int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode); + int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed); int (*set_fan_speed_rpm)(struct smu_context *smu, uint32_t speed); int (*set_xgmi_pstate)(struct smu_context *smu, uint32_t pstate); int (*gfx_off_control)(struct smu_context *smu, bool enable); diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h index 13de692a42136..5d0b29653ffa1 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h @@ -203,6 +203,9 @@ int smu_v11_0_set_fan_control_mode(struct smu_context *smu, uint32_t mode); +int +smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed); + int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed); diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 8b867a6d52b57..e84c737e39673 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -2151,19 +2151,14 @@ int smu_get_fan_speed_percent(struct smu_context *smu, uint32_t *speed) int smu_set_fan_speed_percent(struct smu_context *smu, uint32_t speed) { int ret = 0; - uint32_t rpm; if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) return -EOPNOTSUPP; mutex_lock(&smu->mutex); - if (smu->ppt_funcs->set_fan_speed_rpm) { - if (speed > 100) - speed = 100; - rpm = speed * smu->fan_max_rpm / 100; - ret = smu->ppt_funcs->set_fan_speed_rpm(smu, rpm); - } + if (smu->ppt_funcs->set_fan_speed_percent) + ret = smu->ppt_funcs->set_fan_speed_percent(smu, speed); mutex_unlock(&smu->mutex); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index cd7b411457ffa..16db0b506b0de 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -2326,6 +2326,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, .get_fan_control_mode = smu_v11_0_get_fan_control_mode, .set_fan_control_mode = smu_v11_0_set_fan_control_mode, + .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm, .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate, .gfx_off_control = smu_v11_0_gfx_off_control, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index 51e83123f72a1..cd7efa923195e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -2456,6 +2456,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, .get_fan_control_mode = smu_v11_0_get_fan_control_mode, .set_fan_control_mode = smu_v11_0_set_fan_control_mode, + .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm, .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate, .gfx_off_control = smu_v11_0_gfx_off_control, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 12b36eb0ff6a5..d68d3dfee51d4 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -2802,6 +2802,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = { .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, .get_fan_control_mode = smu_v11_0_get_fan_control_mode, .set_fan_control_mode = smu_v11_0_set_fan_control_mode, + .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm, .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate, .gfx_off_control = smu_v11_0_gfx_off_control, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index b279dbbbce6ba..5aeb5f5a04478 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -1173,6 +1173,35 @@ smu_v11_0_set_fan_static_mode(struct smu_context *smu, uint32_t mode) return 0; } +int +smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed) +{ + struct amdgpu_device *adev = smu->adev; + uint32_t duty100, duty; + uint64_t tmp64; + + if (speed > 100) + speed = 100; + + if (smu_v11_0_auto_fan_control(smu, 0)) + return -EINVAL; + + duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), + CG_FDO_CTRL1, FMAX_DUTY100); + if (!duty100) + return -EINVAL; + + tmp64 = (uint64_t)speed * duty100; + do_div(tmp64, 100); + duty = (uint32_t)tmp64; + + WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0, + REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0), + CG_FDO_CTRL0, FDO_STATIC_DUTY, duty)); + + return smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC); +} + int smu_v11_0_set_fan_control_mode(struct smu_context *smu, uint32_t mode) @@ -1181,7 +1210,7 @@ smu_v11_0_set_fan_control_mode(struct smu_context *smu, switch (mode) { case AMD_FAN_CTRL_NONE: - ret = smu_v11_0_set_fan_speed_rpm(smu, smu->fan_max_rpm); + ret = smu_v11_0_set_fan_speed_percent(smu, 100); break; case AMD_FAN_CTRL_MANUAL: ret = smu_v11_0_auto_fan_control(smu, 0); -- GitLab From 00190bc087e795290502dc51c5d32de85cb2c2b8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 25 Jan 2021 13:23:20 +0100 Subject: [PATCH 0807/1084] amdgpu: fix clang build warning clang warns about the -mhard-float command line arguments on architectures that do not support this: clang: error: argument unused during compilation: '-mhard-float' [-Werror,-Wunused-command-line-argument] Move this into the gcc-specific arguments. Fixes: e77165bf7b02 ("drm/amd/display: Add DCN3 blocks to Makefile") Signed-off-by: Arnd Bergmann Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/Makefile | 6 ++++-- drivers/gpu/drm/amd/display/dc/dcn301/Makefile | 3 ++- drivers/gpu/drm/amd/display/dc/dcn302/Makefile | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile index c20331eb62e01..dfd77b3cc84d8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile @@ -32,8 +32,8 @@ DCN30 = dcn30_init.o dcn30_hubbub.o dcn30_hubp.o dcn30_dpp.o dcn30_optc.o \ ifdef CONFIG_X86 -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mhard-float -msse -CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -msse +CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -msse +CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -msse endif ifdef CONFIG_PPC64 @@ -45,6 +45,8 @@ ifdef CONFIG_CC_IS_GCC ifeq ($(call cc-ifversion, -lt, 0701, y), y) IS_OLD_GCC = 1 endif +CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -mhard-float +CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -mhard-float endif ifdef CONFIG_X86 diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile index 3ca7d911d25c4..09264716d1dc9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile @@ -14,7 +14,7 @@ DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \ dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o ifdef CONFIG_X86 -CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -msse +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -msse endif ifdef CONFIG_PPC64 @@ -25,6 +25,7 @@ ifdef CONFIG_CC_IS_GCC ifeq ($(call cc-ifversion, -lt, 0701, y), y) IS_OLD_GCC = 1 endif +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mhard-float endif ifdef CONFIG_X86 diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/Makefile b/drivers/gpu/drm/amd/display/dc/dcn302/Makefile index 8d4924b7dc221..101620a8867aa 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn302/Makefile @@ -13,7 +13,7 @@ DCN3_02 = dcn302_init.o dcn302_hwseq.o dcn302_resource.o ifdef CONFIG_X86 -CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -msse +CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -msse endif ifdef CONFIG_PPC64 @@ -24,6 +24,7 @@ ifdef CONFIG_CC_IS_GCC ifeq ($(call cc-ifversion, -lt, 0701, y), y) IS_OLD_GCC = 1 endif +CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o += -mhard-float endif ifdef CONFIG_X86 -- GitLab From f609cbb8911e40e15f9055e8f945f926ac906924 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Thu, 28 Jan 2021 18:39:24 +0000 Subject: [PATCH 0808/1084] io_uring: fix list corruption for splice file_get kernel BUG at lib/list_debug.c:29! Call Trace: __list_add include/linux/list.h:67 [inline] list_add include/linux/list.h:86 [inline] io_file_get+0x8cc/0xdb0 fs/io_uring.c:6466 __io_splice_prep+0x1bc/0x530 fs/io_uring.c:3866 io_splice_prep fs/io_uring.c:3920 [inline] io_req_prep+0x3546/0x4e80 fs/io_uring.c:6081 io_queue_sqe+0x609/0x10d0 fs/io_uring.c:6628 io_submit_sqe fs/io_uring.c:6705 [inline] io_submit_sqes+0x1495/0x2720 fs/io_uring.c:6953 __do_sys_io_uring_enter+0x107d/0x1f30 fs/io_uring.c:9353 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xa9 io_file_get() may be called from splice, and so REQ_F_INFLIGHT may already be set. Fixes: 02a13674fa0e8 ("io_uring: account io_uring internal files as REQ_F_INFLIGHT") Cc: stable@vger.kernel.org # 5.9+ Reported-by: syzbot+6879187cf57845801267@syzkaller.appspotmail.com Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index ae388cc528436..39ae1f821cef8 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -6460,7 +6460,8 @@ static struct file *io_file_get(struct io_submit_state *state, file = __io_file_get(state, fd); } - if (file && file->f_op == &io_uring_fops) { + if (file && file->f_op == &io_uring_fops && + !(req->flags & REQ_F_INFLIGHT)) { io_req_init_async(req); req->flags |= REQ_F_INFLIGHT; -- GitLab From 70b2c60d3797bffe182dddb9bb55975b9be5889a Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Thu, 28 Jan 2021 18:39:25 +0000 Subject: [PATCH 0809/1084] io_uring: fix sqo ownership false positive warning WARNING: CPU: 0 PID: 21359 at fs/io_uring.c:9042 io_uring_cancel_task_requests+0xe55/0x10c0 fs/io_uring.c:9042 Call Trace: io_uring_flush+0x47b/0x6e0 fs/io_uring.c:9227 filp_close+0xb4/0x170 fs/open.c:1295 close_files fs/file.c:403 [inline] put_files_struct fs/file.c:418 [inline] put_files_struct+0x1cc/0x350 fs/file.c:415 exit_files+0x7e/0xa0 fs/file.c:435 do_exit+0xc22/0x2ae0 kernel/exit.c:820 do_group_exit+0x125/0x310 kernel/exit.c:922 get_signal+0x427/0x20f0 kernel/signal.c:2773 arch_do_signal_or_restart+0x2a8/0x1eb0 arch/x86/kernel/signal.c:811 handle_signal_work kernel/entry/common.c:147 [inline] exit_to_user_mode_loop kernel/entry/common.c:171 [inline] exit_to_user_mode_prepare+0x148/0x250 kernel/entry/common.c:201 __syscall_exit_to_user_mode_work kernel/entry/common.c:291 [inline] syscall_exit_to_user_mode+0x19/0x50 kernel/entry/common.c:302 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Now io_uring_cancel_task_requests() can be called not through file notes but directly, remove a WARN_ONCE() there that give us false positives. That check is not very important and we catch it in other places. Fixes: 84965ff8a84f0 ("io_uring: if we see flush on exit, cancel related tasks") Cc: stable@vger.kernel.org # 5.9+ Reported-by: syzbot+3e3d9bd0c6ce9efbc3ef@syzkaller.appspotmail.com Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 39ae1f821cef8..12bf7180c0f10 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -8967,8 +8967,6 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx, struct task_struct *task = current; if ((ctx->flags & IORING_SETUP_SQPOLL) && ctx->sq_data) { - /* for SQPOLL only sqo_task has task notes */ - WARN_ON_ONCE(ctx->sqo_task != current); io_disable_sqo_submit(ctx); task = ctx->sq_data->thread; atomic_inc(&task->io_uring->in_idle); -- GitLab From dad3a72f5eec966dbd714c1a657894ffd2a6f471 Mon Sep 17 00:00:00 2001 From: Giacinto Cifelli Date: Tue, 26 Jan 2021 05:42:45 +0100 Subject: [PATCH 0810/1084] net: usb: cdc_ether: added support for Thales Cinterion PLSx3 modem family. lsusb -v for this device: Bus 003 Device 007: ID 1e2d:0069 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 239 Miscellaneous Device bDeviceSubClass 2 ? bDeviceProtocol 1 Interface Association bMaxPacketSize0 64 idVendor 0x1e2d idProduct 0x0069 bcdDevice 0.00 iManufacturer 4 Cinterion Wireless Modules iProduct 3 PLSx3 iSerial 5 fa3c1419 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 352 bNumInterfaces 10 bConfigurationValue 1 iConfiguration 2 Cinterion Configuration bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 500mA Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 0 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 2 Abstract (modem) bFunctionProtocol 1 AT-commands (v.25ter) iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 1.10 CDC ACM: bmCapabilities 0x02 line coding and serial state CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 1 CDC Union: bMasterInterface 0 bSlaveInterface 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 2 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 2 Abstract (modem) bFunctionProtocol 1 AT-commands (v.25ter) iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 1.10 CDC ACM: bmCapabilities 0x02 line coding and serial state CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 3 CDC Union: bMasterInterface 2 bSlaveInterface 3 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 3 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 4 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 2 Abstract (modem) bFunctionProtocol 1 AT-commands (v.25ter) iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 4 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 1.10 CDC ACM: bmCapabilities 0x02 line coding and serial state CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 5 CDC Union: bMasterInterface 4 bSlaveInterface 5 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x85 EP 5 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 5 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x86 EP 6 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 6 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 2 Abstract (modem) bFunctionProtocol 1 AT-commands (v.25ter) iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 6 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 1.10 CDC ACM: bmCapabilities 0x02 line coding and serial state CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 7 CDC Union: bMasterInterface 6 bSlaveInterface 7 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x87 EP 7 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 7 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x88 EP 8 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x04 EP 4 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 8 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 0 bFunctionProtocol 0 iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 8 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 6 Ethernet Networking bInterfaceProtocol 0 iInterface 0 CDC Header: bcdCDC 1.10 CDC Ethernet: iMacAddress 1 00A0C6C14190 bmEthernetStatistics 0x00000000 wMaxSegmentSize 16384 wNumberMCFilters 0x0001 bNumberPowerFilters 0 CDC Union: bMasterInterface 8 bSlaveInterface 9 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x89 EP 9 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 9 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 9 bAlternateSetting 1 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x8a EP 10 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x05 EP 5 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 239 Miscellaneous Device bDeviceSubClass 2 ? bDeviceProtocol 1 Interface Association bMaxPacketSize0 64 bNumConfigurations 1 Device Status: 0x0000 (Bus Powered) Signed-off-by: Giacinto Cifelli Link: https://lore.kernel.org/r/20210126044245.8455-1-gciofono@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/usb/cdc_ether.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 6aaa0675c28a3..a9b5510286595 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -968,6 +968,12 @@ static const struct usb_device_id products[] = { USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (unsigned long)&wwan_info, +}, { + /* Cinterion PLS83/PLS63 modem by GEMALTO/THALES */ + USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0069, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&wwan_info, }, { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- GitLab From 7cfc4486e7ea25bd405df162d9c131ee5d4c6c93 Mon Sep 17 00:00:00 2001 From: Voon Weifeng Date: Tue, 26 Jan 2021 18:08:44 +0800 Subject: [PATCH 0811/1084] stmmac: intel: Configure EHL PSE0 GbE and PSE1 GbE to 32 bits DMA addressing Fix an issue where dump stack is printed and Reset Adapter occurs when PSE0 GbE or/and PSE1 GbE is/are enabled. EHL PSE0 GbE and PSE1 GbE use 32 bits DMA addressing whereas EHL PCH GbE uses 64 bits DMA addressing. [ 25.535095] ------------[ cut here ]------------ [ 25.540276] NETDEV WATCHDOG: enp0s29f2 (intel-eth-pci): transmit queue 2 timed out [ 25.548749] WARNING: CPU: 2 PID: 0 at net/sched/sch_generic.c:443 dev_watchdog+0x259/0x260 [ 25.558004] Modules linked in: 8021q bnep bluetooth ecryptfs snd_hda_codec_hdmi intel_gpy marvell intel_ishtp_loader intel_ishtp_hid iTCO_wdt mei_hdcp iTCO_vendor_support x86_pkg_temp_thermal kvm_intel dwmac_intel stmmac kvm igb pcs_xpcs irqbypass phylink snd_hda_intel intel_rapl_msr pcspkr dca snd_hda_codec i915 i2c_i801 i2c_smbus libphy intel_ish_ipc snd_hda_core mei_me intel_ishtp mei spi_dw_pci 8250_lpss spi_dw thermal dw_dmac_core parport_pc tpm_crb tpm_tis parport tpm_tis_core tpm intel_pmc_core sch_fq_codel uhid fuse configfs snd_sof_pci snd_sof_intel_byt snd_sof_intel_ipc snd_sof_intel_hda_common snd_sof_xtensa_dsp snd_sof snd_soc_acpi_intel_match snd_soc_acpi snd_intel_dspcfg ledtrig_audio snd_soc_core snd_compress ac97_bus snd_pcm snd_timer snd soundcore [ 25.633795] CPU: 2 PID: 0 Comm: swapper/2 Tainted: G U 5.11.0-rc4-intel-lts-MISMAIL5+ #5 [ 25.644306] Hardware name: Intel Corporation Elkhart Lake Embedded Platform/ElkhartLake LPDDR4x T4 RVP1, BIOS EHLSFWI1.R00.2434.A00.2010231402 10/23/2020 [ 25.659674] RIP: 0010:dev_watchdog+0x259/0x260 [ 25.664650] Code: e8 3b 6b 60 ff eb 98 4c 89 ef c6 05 ec e7 bf 00 01 e8 fb e5 fa ff 89 d9 4c 89 ee 48 c7 c7 78 31 d2 9e 48 89 c2 e8 79 1b 18 00 <0f> 0b e9 77 ff ff ff 0f 1f 44 00 00 48 c7 47 08 00 00 00 00 48 c7 [ 25.685647] RSP: 0018:ffffb7ca80160eb8 EFLAGS: 00010286 [ 25.691498] RAX: 0000000000000000 RBX: 0000000000000002 RCX: 0000000000000103 [ 25.699483] RDX: 0000000080000103 RSI: 00000000000000f6 RDI: 00000000ffffffff [ 25.707465] RBP: ffff985709ce0440 R08: 0000000000000000 R09: c0000000ffffefff [ 25.715455] R10: ffffb7ca80160cf0 R11: ffffb7ca80160ce8 R12: ffff985709ce039c [ 25.723438] R13: ffff985709ce0000 R14: 0000000000000008 R15: ffff9857068af940 [ 25.731425] FS: 0000000000000000(0000) GS:ffff985864300000(0000) knlGS:0000000000000000 [ 25.740481] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 25.746913] CR2: 00005567f8bb76b8 CR3: 00000001f8e0a000 CR4: 0000000000350ee0 [ 25.754900] Call Trace: [ 25.757631] [ 25.759891] ? qdisc_put_unlocked+0x30/0x30 [ 25.764565] ? qdisc_put_unlocked+0x30/0x30 [ 25.769245] call_timer_fn+0x2e/0x140 [ 25.773346] run_timer_softirq+0x1f3/0x430 [ 25.777932] ? __hrtimer_run_queues+0x12c/0x2c0 [ 25.783005] ? ktime_get+0x3e/0xa0 [ 25.786812] __do_softirq+0xa6/0x2ef [ 25.790816] asm_call_irq_on_stack+0xf/0x20 [ 25.795501] [ 25.797852] do_softirq_own_stack+0x5d/0x80 [ 25.802538] irq_exit_rcu+0x94/0xb0 [ 25.806475] sysvec_apic_timer_interrupt+0x42/0xc0 [ 25.811836] asm_sysvec_apic_timer_interrupt+0x12/0x20 [ 25.817586] RIP: 0010:cpuidle_enter_state+0xd9/0x370 [ 25.823142] Code: 85 c0 0f 8f 0a 02 00 00 31 ff e8 22 d5 7e ff 45 84 ff 74 12 9c 58 f6 c4 02 0f 85 47 02 00 00 31 ff e8 7b a0 84 ff fb 45 85 f6 <0f> 88 ab 00 00 00 49 63 ce 48 2b 2c 24 48 89 c8 48 6b d1 68 48 c1 [ 25.844140] RSP: 0018:ffffb7ca800f7e80 EFLAGS: 00000206 [ 25.849996] RAX: ffff985864300000 RBX: 0000000000000003 RCX: 000000000000001f [ 25.857975] RDX: 00000005f2028ea8 RSI: ffffffff9ec5907f RDI: ffffffff9ec62a5d [ 25.865961] RBP: 00000005f2028ea8 R08: 0000000000000000 R09: 0000000000029d00 [ 25.873947] R10: 000000137b0e0508 R11: ffff9858643294e4 R12: ffff9858643336d0 [ 25.881935] R13: ffffffff9ef74b00 R14: 0000000000000003 R15: 0000000000000000 [ 25.889918] cpuidle_enter+0x29/0x40 [ 25.893922] do_idle+0x24a/0x290 [ 25.897536] cpu_startup_entry+0x19/0x20 [ 25.901930] start_secondary+0x128/0x160 [ 25.906326] secondary_startup_64_no_verify+0xb0/0xbb [ 25.911983] ---[ end trace b4c0c8195d0ba61f ]--- [ 25.917193] intel-eth-pci 0000:00:1d.2 enp0s29f2: Reset adapter. Fixes: 67c08ac4140a ("net: stmmac: add EHL PSE0 & PSE1 1Gbps PCI info and PCI ID") Signed-off-by: Voon Weifeng Co-developed-by: Mohammad Athari Bin Ismail Signed-off-by: Mohammad Athari Bin Ismail Link: https://lore.kernel.org/r/20210126100844.30326-1-mohammad.athari.ismail@intel.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c index 9a6a519426a08..103d2448e9e0d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c @@ -375,6 +375,7 @@ static int ehl_pse0_common_data(struct pci_dev *pdev, struct plat_stmmacenet_data *plat) { plat->bus_id = 2; + plat->addr64 = 32; return ehl_common_data(pdev, plat); } @@ -406,6 +407,7 @@ static int ehl_pse1_common_data(struct pci_dev *pdev, struct plat_stmmacenet_data *plat) { plat->bus_id = 3; + plat->addr64 = 32; return ehl_common_data(pdev, plat); } -- GitLab From 11df27f7fdf02cc2bb354358ad482e1fdd690589 Mon Sep 17 00:00:00 2001 From: Danielle Ratson Date: Thu, 28 Jan 2021 16:48:19 +0200 Subject: [PATCH 0812/1084] selftests: forwarding: Specify interface when invoking mausezahn Specify the interface through which packets should be transmitted so that the test will pass regardless of the libnet version against which mausezahn is linked. Fixes: cab14d1087d9 ("selftests: Add version of router_multipath.sh using nexthop objects") Fixes: 3d578d879517 ("selftests: forwarding: Test IPv4 weighted nexthops") Signed-off-by: Danielle Ratson Signed-off-by: Ido Schimmel Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/forwarding/router_mpath_nh.sh | 2 +- tools/testing/selftests/net/forwarding/router_multipath.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/forwarding/router_mpath_nh.sh b/tools/testing/selftests/net/forwarding/router_mpath_nh.sh index 388e4492b81be..76efb1f8375e3 100755 --- a/tools/testing/selftests/net/forwarding/router_mpath_nh.sh +++ b/tools/testing/selftests/net/forwarding/router_mpath_nh.sh @@ -203,7 +203,7 @@ multipath4_test() t0_rp12=$(link_stats_tx_packets_get $rp12) t0_rp13=$(link_stats_tx_packets_get $rp13) - ip vrf exec vrf-h1 $MZ -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \ + ip vrf exec vrf-h1 $MZ $h1 -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \ -d 1msec -t udp "sp=1024,dp=0-32768" t1_rp12=$(link_stats_tx_packets_get $rp12) diff --git a/tools/testing/selftests/net/forwarding/router_multipath.sh b/tools/testing/selftests/net/forwarding/router_multipath.sh index 79a2099279621..464821c587a5e 100755 --- a/tools/testing/selftests/net/forwarding/router_multipath.sh +++ b/tools/testing/selftests/net/forwarding/router_multipath.sh @@ -178,7 +178,7 @@ multipath4_test() t0_rp12=$(link_stats_tx_packets_get $rp12) t0_rp13=$(link_stats_tx_packets_get $rp13) - ip vrf exec vrf-h1 $MZ -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \ + ip vrf exec vrf-h1 $MZ $h1 -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \ -d 1msec -t udp "sp=1024,dp=0-32768" t1_rp12=$(link_stats_tx_packets_get $rp12) -- GitLab From b6f6881aaf2344bf35a4221810737abe5fd210af Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Thu, 28 Jan 2021 16:48:20 +0200 Subject: [PATCH 0813/1084] mlxsw: spectrum_span: Do not overwrite policer configuration The purpose of the delayed work in the SPAN module is to potentially update the destination port and various encapsulation parameters of SPAN agents that point to a VLAN device or a GRE tap. The destination port can change following the insertion of a new route, for example. SPAN agents that point to a physical port or the CPU port are static and never change throughout the lifetime of the SPAN agent. Therefore, skip over them in the delayed work. This fixes an issue where the delayed work overwrites the policer that was set on a SPAN agent pointing to the CPU. Modifying the delayed work to inherit the original policer configuration is error-prone, as the same will be needed for any new parameter. Fixes: 4039504e6a0c ("mlxsw: spectrum_span: Allow setting policer on a SPAN agent") Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c | 6 ++++++ drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c index c6c5826aba41e..1892cea05ee7c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c @@ -157,6 +157,7 @@ mlxsw_sp1_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry) static const struct mlxsw_sp_span_entry_ops mlxsw_sp1_span_entry_ops_cpu = { + .is_static = true, .can_handle = mlxsw_sp1_span_cpu_can_handle, .parms_set = mlxsw_sp1_span_entry_cpu_parms, .configure = mlxsw_sp1_span_entry_cpu_configure, @@ -214,6 +215,7 @@ mlxsw_sp_span_entry_phys_deconfigure(struct mlxsw_sp_span_entry *span_entry) static const struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_phys = { + .is_static = true, .can_handle = mlxsw_sp_port_dev_check, .parms_set = mlxsw_sp_span_entry_phys_parms, .configure = mlxsw_sp_span_entry_phys_configure, @@ -721,6 +723,7 @@ mlxsw_sp2_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry) static const struct mlxsw_sp_span_entry_ops mlxsw_sp2_span_entry_ops_cpu = { + .is_static = true, .can_handle = mlxsw_sp2_span_cpu_can_handle, .parms_set = mlxsw_sp2_span_entry_cpu_parms, .configure = mlxsw_sp2_span_entry_cpu_configure, @@ -1036,6 +1039,9 @@ static void mlxsw_sp_span_respin_work(struct work_struct *work) if (!refcount_read(&curr->ref_count)) continue; + if (curr->ops->is_static) + continue; + err = curr->ops->parms_set(mlxsw_sp, curr->to_dev, &sparms); if (err) continue; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h index d907718bc8c58..aa1cd409c0e2e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h @@ -60,6 +60,7 @@ struct mlxsw_sp_span_entry { }; struct mlxsw_sp_span_entry_ops { + bool is_static; bool (*can_handle)(const struct net_device *to_dev); int (*parms_set)(struct mlxsw_sp *mlxsw_sp, const struct net_device *to_dev, -- GitLab From b8323f7288abd71794cd7b11a4c0a38b8637c8b5 Mon Sep 17 00:00:00 2001 From: Takeshi Misawa Date: Thu, 28 Jan 2021 10:48:36 +0000 Subject: [PATCH 0814/1084] rxrpc: Fix memory leak in rxrpc_lookup_local Commit 9ebeddef58c4 ("rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record") Then release ref in __rxrpc_put_peer and rxrpc_put_peer_locked. struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp) - peer->local = local; + peer->local = rxrpc_get_local(local); rxrpc_discard_prealloc also need ref release in discarding. syzbot report: BUG: memory leak unreferenced object 0xffff8881080ddc00 (size 256): comm "syz-executor339", pid 8462, jiffies 4294942238 (age 12.350s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 0a 00 00 00 00 c0 00 08 81 88 ff ff ................ backtrace: [<000000002b6e495f>] kmalloc include/linux/slab.h:552 [inline] [<000000002b6e495f>] kzalloc include/linux/slab.h:682 [inline] [<000000002b6e495f>] rxrpc_alloc_local net/rxrpc/local_object.c:79 [inline] [<000000002b6e495f>] rxrpc_lookup_local+0x1c1/0x760 net/rxrpc/local_object.c:244 [<000000006b43a77b>] rxrpc_bind+0x174/0x240 net/rxrpc/af_rxrpc.c:149 [<00000000fd447a55>] afs_open_socket+0xdb/0x200 fs/afs/rxrpc.c:64 [<000000007fd8867c>] afs_net_init+0x2b4/0x340 fs/afs/main.c:126 [<0000000063d80ec1>] ops_init+0x4e/0x190 net/core/net_namespace.c:152 [<00000000073c5efa>] setup_net+0xde/0x2d0 net/core/net_namespace.c:342 [<00000000a6744d5b>] copy_net_ns+0x19f/0x3e0 net/core/net_namespace.c:483 [<0000000017d3aec3>] create_new_namespaces+0x199/0x4f0 kernel/nsproxy.c:110 [<00000000186271ef>] unshare_nsproxy_namespaces+0x9b/0x120 kernel/nsproxy.c:226 [<000000002de7bac4>] ksys_unshare+0x2fe/0x5c0 kernel/fork.c:2957 [<00000000349b12ba>] __do_sys_unshare kernel/fork.c:3025 [inline] [<00000000349b12ba>] __se_sys_unshare kernel/fork.c:3023 [inline] [<00000000349b12ba>] __x64_sys_unshare+0x12/0x20 kernel/fork.c:3023 [<000000006d178ef7>] do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 [<00000000637076d4>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: 9ebeddef58c4 ("rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record") Signed-off-by: Takeshi Misawa Reported-and-tested-by: syzbot+305326672fed51b205f7@syzkaller.appspotmail.com Signed-off-by: David Howells Link: https://lore.kernel.org/r/161183091692.3506637.3206605651502458810.stgit@warthog.procyon.org.uk Signed-off-by: Jakub Kicinski --- net/rxrpc/call_accept.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c index 382add72c66f6..1ae90fb979362 100644 --- a/net/rxrpc/call_accept.c +++ b/net/rxrpc/call_accept.c @@ -197,6 +197,7 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx) tail = b->peer_backlog_tail; while (CIRC_CNT(head, tail, size) > 0) { struct rxrpc_peer *peer = b->peer_backlog[tail]; + rxrpc_put_local(peer->local); kfree(peer); tail = (tail + 1) & (size - 1); } -- GitLab From bd2f0b43c1c864fa653342c5c074bfcd29f10934 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 28 Jan 2021 16:43:03 -0600 Subject: [PATCH 0815/1084] cifs: returning mount parm processing errors correctly During additional testing of the updated cifs.ko with the new mount API support, we found a few additional cases where we were logging errors, but not returning them to the user. For example: a) invalid security mechanisms b) invalid cache options c) unsupported rdma d) invalid smb dialect requested Fixes: 24e0a1eff9e2 ("cifs: switch to new mount api") Acked-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/fs_context.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index 818c413db82d2..27354417e9889 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -533,7 +533,7 @@ static int smb3_fs_context_validate(struct fs_context *fc) if (ctx->rdma && ctx->vals->protocol_id < SMB30_PROT_ID) { cifs_dbg(VFS, "SMB Direct requires Version >=3.0\n"); - return -1; + return -EOPNOTSUPP; } #ifndef CONFIG_KEYS @@ -556,7 +556,7 @@ static int smb3_fs_context_validate(struct fs_context *fc) /* make sure UNC has a share name */ if (strlen(ctx->UNC) < 3 || !strchr(ctx->UNC + 3, '\\')) { cifs_dbg(VFS, "Malformed UNC. Unable to find share name.\n"); - return -1; + return -ENOENT; } if (!ctx->got_ip) { @@ -570,7 +570,7 @@ static int smb3_fs_context_validate(struct fs_context *fc) if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr, &ctx->UNC[2], len)) { pr_err("Unable to determine destination address\n"); - return -1; + return -EHOSTUNREACH; } } @@ -1265,7 +1265,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, return 0; cifs_parse_mount_err: - return 1; + return -EINVAL; } int smb3_init_fs_context(struct fs_context *fc) -- GitLab From 3a7efd1ad269ccaf9c1423364d97c9661ba6dafa Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Thu, 28 Jan 2021 23:23:42 +0000 Subject: [PATCH 0816/1084] io_uring: reinforce cancel on flush during exit What 84965ff8a84f0 ("io_uring: if we see flush on exit, cancel related tasks") really wants is to cancel all relevant REQ_F_INFLIGHT requests reliably. That can be achieved by io_uring_cancel_files(), but we'll miss it calling io_uring_cancel_task_requests(files=NULL) from io_uring_flush(), because it will go through __io_uring_cancel_task_requests(). Just always call io_uring_cancel_files() during cancel, it's good enough for now. Cc: stable@vger.kernel.org # 5.9+ Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 12bf7180c0f10..38c6cbe1ab387 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -8976,10 +8976,9 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx, io_cancel_defer_files(ctx, task, files); io_cqring_overflow_flush(ctx, true, task, files); + io_uring_cancel_files(ctx, task, files); if (!files) __io_uring_cancel_task_requests(ctx, task); - else - io_uring_cancel_files(ctx, task, files); if ((ctx->flags & IORING_SETUP_SQPOLL) && ctx->sq_data) { atomic_dec(&task->io_uring->in_idle); -- GitLab From fd55b61ebd31449549e14c33574825d64de2b29b Mon Sep 17 00:00:00 2001 From: Bastian Beranek Date: Thu, 21 Jan 2021 15:27:36 +0100 Subject: [PATCH 0817/1084] drm/nouveau/dispnv50: Restore pushing of all data. Commit f844eb485eb056ad3b67e49f95cbc6c685a73db4 introduced a regression for NV50, which lead to visual artifacts, tearing and eventual crashes. In the changes of f844eb485eb056ad3b67e49f95cbc6c685a73db4 only the first line was correctly translated to the new NVIDIA header macros: - PUSH_NVSQ(push, NV827C, 0x0110, 0, - 0x0114, 0); + PUSH_MTHD(push, NV827C, SET_PROCESSING, + NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE)); The lower part ("0x0114, 0") was probably omitted by accident. This patch restores the push of the missing data and fixes the regression. Signed-off-by: Bastian Beranek Fixes: f844eb485eb05 ("drm/nouveau/kms/nv50-: use NVIDIA's headers for wndw image_set()") Link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/14 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/base507c.c | 6 +++++- drivers/gpu/drm/nouveau/dispnv50/base827c.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index 302d4e6fc52f1..788db043a3429 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -88,7 +88,11 @@ base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) NVVAL(NV507C, SET_CONVERSION, OFS, 0x64)); } else { PUSH_MTHD(push, NV507C, SET_PROCESSING, - NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE)); + NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE), + + SET_CONVERSION, + NVVAL(NV507C, SET_CONVERSION, GAIN, 0) | + NVVAL(NV507C, SET_CONVERSION, OFS, 0)); } PUSH_MTHD(push, NV507C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8); diff --git a/drivers/gpu/drm/nouveau/dispnv50/base827c.c b/drivers/gpu/drm/nouveau/dispnv50/base827c.c index 18d34096f1258..093d4ba6910ec 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base827c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base827c.c @@ -49,7 +49,11 @@ base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) NVVAL(NV827C, SET_CONVERSION, OFS, 0x64)); } else { PUSH_MTHD(push, NV827C, SET_PROCESSING, - NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE)); + NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE), + + SET_CONVERSION, + NVVAL(NV827C, SET_CONVERSION, GAIN, 0) | + NVVAL(NV827C, SET_CONVERSION, OFS, 0)); } PUSH_MTHD(push, NV827C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8, -- GitLab From dcd602cc5fe2803bf532d407cde24ba0b7808ff3 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Mon, 18 Jan 2021 18:16:06 +0100 Subject: [PATCH 0818/1084] drm/nouveau/svm: fail NOUVEAU_SVM_INIT ioctl on unsupported devices Fixes a crash when trying to create a channel on e.g. Turing GPUs when NOUVEAU_SVM_INIT was called before. Fixes: eeaf06ac1a558 ("drm/nouveau/svm: initial support for shared virtual memory") Signed-off-by: Karol Herbst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_svm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index 4f69e4c3dafde..1c3f890377d2c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -315,6 +315,10 @@ nouveau_svmm_init(struct drm_device *dev, void *data, struct drm_nouveau_svm_init *args = data; int ret; + /* We need to fail if svm is disabled */ + if (!cli->drm->svm) + return -ENOSYS; + /* Allocate tracking for SVM-enabled VMM. */ if (!(svmm = kzalloc(sizeof(*svmm), GFP_KERNEL))) return -ENOMEM; -- GitLab From 7c6d659868c77da9b518f32348160340dcdfa008 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 18 Jan 2021 20:54:12 -0500 Subject: [PATCH 0819/1084] drivers/nouveau/kms/nv50-: Reject format modifiers for cursor planes Nvidia hardware doesn't actually support using tiling formats with the cursor plane, only linear is allowed. In the future, we should write a testcase for this. Fixes: c586f30bf74c ("drm/nouveau/kms: Add format mod prop to base/ovly/nvdisp") Cc: James Jones Cc: Martin Peres Cc: Jeremy Cline Cc: Simon Ser Cc: # v5.8+ Signed-off-by: Lyude Paul Reviewed-by: Simon Ser Reviewed-by: James Jones Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index ce451242f79eb..271de3a63f21c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -702,6 +702,11 @@ nv50_wndw_init(struct nv50_wndw *wndw) nvif_notify_get(&wndw->notify); } +static const u64 nv50_cursor_format_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID, +}; + int nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, enum drm_plane_type type, const char *name, int index, @@ -713,6 +718,7 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, struct nvif_mmu *mmu = &drm->client.mmu; struct nv50_disp *disp = nv50_disp(dev); struct nv50_wndw *wndw; + const u64 *format_modifiers; int nformat; int ret; @@ -728,10 +734,13 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, for (nformat = 0; format[nformat]; nformat++); - ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, - format, nformat, - nouveau_display(dev)->format_modifiers, - type, "%s-%d", name, index); + if (type == DRM_PLANE_TYPE_CURSOR) + format_modifiers = nv50_cursor_format_modifiers; + else + format_modifiers = nouveau_display(dev)->format_modifiers; + + ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, format, nformat, + format_modifiers, type, "%s-%d", name, index); if (ret) { kfree(*pwndw); *pwndw = NULL; -- GitLab From d3b2f0f7921c75b5f0de50e618e4bd165fded3e1 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 18 Jan 2021 20:54:13 -0500 Subject: [PATCH 0820/1084] drm/nouveau/kms/nv50-: Report max cursor size to userspace Cc: Martin Peres Cc: Jeremy Cline Cc: Simon Ser Signed-off-by: Lyude Paul Tested-by: Simon Ser Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index c6367035970eb..5f4f09a601d4c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -2663,6 +2663,14 @@ nv50_display_create(struct drm_device *dev) else nouveau_display(dev)->format_modifiers = disp50xx_modifiers; + if (disp->disp->object.oclass >= GK104_DISP) { + dev->mode_config.cursor_width = 256; + dev->mode_config.cursor_height = 256; + } else { + dev->mode_config.cursor_width = 64; + dev->mode_config.cursor_height = 64; + } + /* create crtc objects to represent the hw heads */ if (disp->disp->object.oclass >= GV100_DISP) crtcs = nvif_rd32(&device->object, 0x610060) & 0xff; -- GitLab From ba839b7598440a5d78550a115bac21b08d57cc32 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 18 Jan 2021 20:54:14 -0500 Subject: [PATCH 0821/1084] drm/nouveau/kms/gk104-gp1xx: Fix > 64x64 cursors While we do handle the additional cursor sizes introduced in NVE4, it looks like we accidentally broke this when converting over to use Nvidia's display headers. Since we now use NVVAL in dispnv50/head907d.c in order to format the value for the cursor layout and NVD9 only had one byte reserved vs. the 2 bytes reserved in later generations, we end up accidentally stripping the second bit in the cursor layout format parameter - causing us to set the wrong cursor size. This fixes that by adding our own curs_set hook for 917d which uses the NV917D headers. Cc: Martin Peres Cc: Jeremy Cline Cc: Simon Ser Cc: # v5.9+ Signed-off-by: Lyude Paul Fixes: ed0b86a90bf9 ("drm/nouveau/kms/nv50-: use NVIDIA's headers for core head_curs_set()") Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/head917d.c | 28 ++++++++++++++++++- .../drm/nouveau/include/nvhw/class/cl917d.h | 4 +++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/head917d.c b/drivers/gpu/drm/nouveau/dispnv50/head917d.c index a5d8274036609..ea9f8667305ec 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head917d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head917d.c @@ -22,6 +22,7 @@ #include "head.h" #include "core.h" +#include "nvif/push.h" #include #include @@ -73,6 +74,31 @@ head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh) return 0; } +static int +head917d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 5); + if (ret) + return ret; + + PUSH_MTHD(push, NV917D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NV917D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) | + NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) | + NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) | + NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) | + NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) | + NVDEF(NV917D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND), + + HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8); + + PUSH_MTHD(push, NV917D, HEAD_SET_CONTEXT_DMA_CURSOR(i), asyh->curs.handle); + return 0; +} + int head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) @@ -101,7 +127,7 @@ head917d = { .core_clr = head907d_core_clr, .curs_layout = head917d_curs_layout, .curs_format = head507d_curs_format, - .curs_set = head907d_curs_set, + .curs_set = head917d_curs_set, .curs_clr = head907d_curs_clr, .base = head917d_base, .ovly = head907d_ovly, diff --git a/drivers/gpu/drm/nouveau/include/nvhw/class/cl917d.h b/drivers/gpu/drm/nouveau/include/nvhw/class/cl917d.h index 2a2612d6e1e0e..fb223723a38ad 100644 --- a/drivers/gpu/drm/nouveau/include/nvhw/class/cl917d.h +++ b/drivers/gpu/drm/nouveau/include/nvhw/class/cl917d.h @@ -66,6 +66,10 @@ #define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_ALPHA_BLEND (0x00000000) #define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_PREMULT_ALPHA_BLEND (0x00000001) #define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_XOR (0x00000002) +#define NV917D_HEAD_SET_OFFSET_CURSOR(a) (0x00000484 + (a)*0x00000300) +#define NV917D_HEAD_SET_OFFSET_CURSOR_ORIGIN 31:0 +#define NV917D_HEAD_SET_CONTEXT_DMA_CURSOR(a) (0x0000048C + (a)*0x00000300) +#define NV917D_HEAD_SET_CONTEXT_DMA_CURSOR_HANDLE 31:0 #define NV917D_HEAD_SET_DITHER_CONTROL(a) (0x000004A0 + (a)*0x00000300) #define NV917D_HEAD_SET_DITHER_CONTROL_ENABLE 0:0 #define NV917D_HEAD_SET_DITHER_CONTROL_ENABLE_DISABLE (0x00000000) -- GitLab From 0d4873f9aa4ff8fc1d63a5755395b794d32ce046 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Thu, 28 Jan 2021 21:35:10 -0600 Subject: [PATCH 0822/1084] cifs: fix dfs domain referrals The new mount API requires additional changes to how DFS is handled. Additional testing of DFS uncovered problems with domain based DFS referrals (a follow on patch addresses DFS links) which this patch addresses. Signed-off-by: Ronnie Sahlberg Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/cifs_dfs_ref.c | 12 ++++++++---- fs/cifs/cifsfs.c | 2 +- fs/cifs/cifsproto.h | 6 ++++-- fs/cifs/connect.c | 32 ++++++++++++++++++++++++++------ fs/cifs/dfs_cache.c | 8 +++++--- fs/cifs/fs_context.c | 31 +++++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 16 deletions(-) diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index e4c6ae47a7961..6b1ce4efb591c 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -133,8 +133,9 @@ cifs_build_devname(char *nodename, const char *prepath) * Caller is responsible for freeing returned value if it is not error. */ char *cifs_compose_mount_options(const char *sb_mountdata, - const char *fullpath, - const struct dfs_info3_param *ref) + const char *fullpath, + const struct dfs_info3_param *ref, + char **devname) { int rc; char *name; @@ -231,7 +232,10 @@ char *cifs_compose_mount_options(const char *sb_mountdata, strcat(mountdata, "ip="); strcat(mountdata, srvIP); - kfree(name); + if (devname) + *devname = name; + else + kfree(name); /*cifs_dbg(FYI, "%s: parent mountdata: %s\n", __func__, sb_mountdata);*/ /*cifs_dbg(FYI, "%s: submount mountdata: %s\n", __func__, mountdata );*/ @@ -278,7 +282,7 @@ static struct vfsmount *cifs_dfs_do_mount(struct dentry *mntpt, /* strip first '\' from fullpath */ mountdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options, - fullpath + 1, NULL); + fullpath + 1, NULL, NULL); if (IS_ERR(mountdata)) { kfree(devname); return (struct vfsmount *)mountdata; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index ce0d0037fd0af..e46da536ed339 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -822,7 +822,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, goto out; } - rc = cifs_setup_volume_info(cifs_sb->ctx); + rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, old_ctx->UNC); if (rc) { root = ERR_PTR(rc); goto out; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 340ff81ee87bf..32f7a013402ee 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -78,7 +78,8 @@ extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx, int add_treename); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern char *cifs_compose_mount_options(const char *sb_mountdata, - const char *fullpath, const struct dfs_info3_param *ref); + const char *fullpath, const struct dfs_info3_param *ref, + char **devname); /* extern void renew_parental_timestamps(struct dentry *direntry);*/ extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server); @@ -89,6 +90,7 @@ extern void cifs_wake_up_task(struct mid_q_entry *mid); extern int cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid); extern int smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx); +extern int smb3_parse_opt(const char *options, const char *key, char **val); extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs); extern int cifs_discard_remaining_data(struct TCP_Server_Info *server); extern int cifs_call_async(struct TCP_Server_Info *server, @@ -549,7 +551,7 @@ extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); extern int -cifs_setup_volume_info(struct smb3_fs_context *ctx); +cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname); extern struct TCP_Server_Info * cifs_find_tcp_session(struct smb3_fs_context *ctx); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c8ef24bac94fc..10fe6d6d2dee4 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2972,17 +2972,20 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses, rc = dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), ref_path, &referral, NULL); if (!rc) { + char *fake_devname = NULL; + mdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options, - full_path + 1, &referral); + full_path + 1, &referral, + &fake_devname); free_dfs_info_param(&referral); if (IS_ERR(mdata)) { rc = PTR_ERR(mdata); mdata = NULL; } else { - smb3_cleanup_fs_context_contents(ctx); - rc = cifs_setup_volume_info(ctx); + rc = cifs_setup_volume_info(ctx, mdata, fake_devname); } + kfree(fake_devname); kfree(cifs_sb->ctx->mount_options); cifs_sb->ctx->mount_options = mdata; } @@ -3036,6 +3039,7 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path, struct dfs_info3_param ref = {0}; char *mdata = NULL; struct smb3_fs_context fake_ctx = {NULL}; + char *fake_devname = NULL; cifs_dbg(FYI, "%s: dfs path: %s\n", __func__, path); @@ -3044,16 +3048,18 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path, return rc; mdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options, - full_path + 1, &ref); + full_path + 1, &ref, + &fake_devname); free_dfs_info_param(&ref); if (IS_ERR(mdata)) { rc = PTR_ERR(mdata); mdata = NULL; } else - rc = cifs_setup_volume_info(&fake_ctx); + rc = cifs_setup_volume_info(&fake_ctx, mdata, fake_devname); kfree(mdata); + kfree(fake_devname); if (!rc) { /* @@ -3122,10 +3128,24 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_ * we should pass a clone of the original context? */ int -cifs_setup_volume_info(struct smb3_fs_context *ctx) +cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname) { int rc = 0; + smb3_parse_devname(devname, ctx); + + if (mntopts) { + char *ip; + + cifs_dbg(FYI, "%s: mntopts=%s\n", __func__, mntopts); + rc = smb3_parse_opt(mntopts, "ip", &ip); + if (!rc && !cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip, + strlen(ip))) { + cifs_dbg(VFS, "%s: failed to convert ip address\n", __func__); + return -EINVAL; + } + } + if (ctx->nullauth) { cifs_dbg(FYI, "Anonymous login\n"); kfree(ctx->username); diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index 0fdb0de7ff861..4950ab0486aee 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -1417,7 +1417,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi, int rc; struct cache_entry *ce; struct dfs_info3_param ref = {0}; - char *mdata = NULL; + char *mdata = NULL, *devname = NULL; struct TCP_Server_Info *server; struct cifs_ses *ses; struct smb3_fs_context ctx = {NULL}; @@ -1444,7 +1444,8 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi, up_read(&htable_rw_lock); - mdata = cifs_compose_mount_options(vi->mntdata, rpath, &ref); + mdata = cifs_compose_mount_options(vi->mntdata, rpath, &ref, + &devname); free_dfs_info_param(&ref); if (IS_ERR(mdata)) { @@ -1453,7 +1454,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi, goto out; } - rc = cifs_setup_volume_info(&ctx); + rc = cifs_setup_volume_info(&ctx, NULL, devname); if (rc) { ses = ERR_PTR(rc); @@ -1472,6 +1473,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi, smb3_cleanup_fs_context_contents(&ctx); kfree(mdata); kfree(rpath); + kfree(devname); return ses; } diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index 27354417e9889..5111aadfdb6b6 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -401,6 +401,37 @@ cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3) return 0; } +int smb3_parse_opt(const char *options, const char *key, char **val) +{ + int rc = -ENOENT; + char *opts, *orig, *p; + + orig = opts = kstrdup(options, GFP_KERNEL); + if (!opts) + return -ENOMEM; + + while ((p = strsep(&opts, ","))) { + char *nval; + + if (!*p) + continue; + if (strncasecmp(p, key, strlen(key))) + continue; + nval = strchr(p, '='); + if (nval) { + if (nval == p) + continue; + *nval++ = 0; + *val = kstrndup(nval, strlen(nval), GFP_KERNEL); + rc = !*val ? -ENOMEM : 0; + goto out; + } + } +out: + kfree(orig); + return rc; +} + /* * Parse a devname into substrings and populate the ctx->UNC and ctx->prepath * fields with the result. Returns 0 on success and an error otherwise -- GitLab From 39d3454c3513840eb123b3913fda6903e45ce671 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Oct 2020 09:39:21 +0100 Subject: [PATCH 0823/1084] ARM: footbridge: fix dc21285 PCI configuration accessors Building with gcc 4.9.2 reveals a latent bug in the PCI accessors for Footbridge platforms, which causes a fatal alignment fault while accessing IO memory. Fix this by making the assembly volatile. Cc: stable@vger.kernel.org Signed-off-by: Russell King --- arch/arm/mach-footbridge/dc21285.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 416462e3f5d63..f9713dc561cf7 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -65,15 +65,15 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, if (addr) switch (size) { case 1: - asm("ldrb %0, [%1, %2]" + asm volatile("ldrb %0, [%1, %2]" : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; case 2: - asm("ldrh %0, [%1, %2]" + asm volatile("ldrh %0, [%1, %2]" : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; case 4: - asm("ldr %0, [%1, %2]" + asm volatile("ldr %0, [%1, %2]" : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; } @@ -99,17 +99,17 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, if (addr) switch (size) { case 1: - asm("strb %0, [%1, %2]" + asm volatile("strb %0, [%1, %2]" : : "r" (value), "r" (addr), "r" (where) : "cc"); break; case 2: - asm("strh %0, [%1, %2]" + asm volatile("strh %0, [%1, %2]" : : "r" (value), "r" (addr), "r" (where) : "cc"); break; case 4: - asm("str %0, [%1, %2]" + asm volatile("str %0, [%1, %2]" : : "r" (value), "r" (addr), "r" (where) : "cc"); break; -- GitLab From 538eea5362a1179dfa7770dd2b6607dc30cc50c6 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Tue, 15 Dec 2020 16:16:44 +0100 Subject: [PATCH 0824/1084] ARM: 9043/1: tegra: Fix misplaced tegra_uart_config in decompressor The tegra_uart_config of the DEBUG_LL code is now placed right at the start of the .text section after commit which enabled debug output in the decompressor. Tegra devices are not booting anymore if DEBUG_LL is enabled since tegra_uart_config data is executes as a code. Fix the misplaced tegra_uart_config storage by embedding it into the code. Cc: stable@vger.kernel.org Fixes: 2596a72d3384 ("ARM: 9009/1: uncompress: Enable debug in head.S") Reviewed-by: Linus Walleij Signed-off-by: Dmitry Osipenko Signed-off-by: Russell King --- arch/arm/include/debug/tegra.S | 54 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/arch/arm/include/debug/tegra.S b/arch/arm/include/debug/tegra.S index 98daa7f483148..7454480d084b2 100644 --- a/arch/arm/include/debug/tegra.S +++ b/arch/arm/include/debug/tegra.S @@ -149,7 +149,34 @@ .align 99: .word . +#if defined(ZIMAGE) + .word . + 4 +/* + * Storage for the state maintained by the macro. + * + * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c. + * That's because this header is included from multiple files, and we only + * want a single copy of the data. In particular, the UART probing code above + * assumes it's running using physical addresses. This is true when this file + * is included from head.o, but not when included from debug.o. So we need + * to share the probe results between the two copies, rather than having + * to re-run the probing again later. + * + * In the decompressor, we put the storage right here, since common.c + * isn't included in the decompressor build. This storage data gets put in + * .text even though it's really data, since .data is discarded from the + * decompressor. Luckily, .text is writeable in the decompressor, unless + * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug. + */ + /* Debug UART initialization required */ + .word 1 + /* Debug UART physical address */ + .word 0 + /* Debug UART virtual address */ + .word 0 +#else .word tegra_uart_config +#endif .ltorg /* Load previously selected UART address */ @@ -189,30 +216,3 @@ .macro waituarttxrdy,rd,rx .endm - -/* - * Storage for the state maintained by the macros above. - * - * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c. - * That's because this header is included from multiple files, and we only - * want a single copy of the data. In particular, the UART probing code above - * assumes it's running using physical addresses. This is true when this file - * is included from head.o, but not when included from debug.o. So we need - * to share the probe results between the two copies, rather than having - * to re-run the probing again later. - * - * In the decompressor, we put the symbol/storage right here, since common.c - * isn't included in the decompressor build. This symbol gets put in .text - * even though it's really data, since .data is discarded from the - * decompressor. Luckily, .text is writeable in the decompressor, unless - * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug. - */ -#if defined(ZIMAGE) -tegra_uart_config: - /* Debug UART initialization required */ - .word 1 - /* Debug UART physical address */ - .word 0 - /* Debug UART virtual address */ - .word 0 -#endif -- GitLab From 8ac9e476b86851c94e0f33bea758e0a00e3f875e Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 29 Jan 2021 10:05:39 +0000 Subject: [PATCH 0825/1084] ASoC: soc-component: fix undefined reference to __ffssi2 microblaze-linux-gcc (GCC) 9.3.0 complains about missing __ffssi2 symbol while using __builtin_ffs at runtime. This is because arch/h8300 is compiled with -fno-builtin option. so fallback and use kernel ffs() instead to all the arch builds happy! Fixes: 1da0b9899abd ("ASoC: soc-component: add snd_soc_component_read/write_field()") Reported-by: kernel test robot Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210129100539.23459-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/soc-component.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index 361a79d655e37..159bf88b9f8cd 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -11,6 +11,7 @@ #include #include #include +#include #define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret) static inline int _soc_component_ret(struct snd_soc_component *component, @@ -43,7 +44,7 @@ static inline int soc_component_field_shift(struct snd_soc_component *component, return 0; } - return (__builtin_ffs(mask) - 1); + return (ffs(mask) - 1); } /* -- GitLab From c351bb64cbe67029c68dea3adbec1b9508c6ff0f Mon Sep 17 00:00:00 2001 From: Quanyang Wang Date: Fri, 29 Jan 2021 16:19:17 +0800 Subject: [PATCH 0826/1084] gpiolib: free device name on error path to fix kmemleak In gpiochip_add_data_with_key, we should check the return value of dev_set_name to ensure that device name is allocated successfully and then add a label on the error path to free device name to fix kmemleak as below: unreferenced object 0xc2d6fc40 (size 64): comm "kworker/0:1", pid 16, jiffies 4294937425 (age 65.120s) hex dump (first 32 bytes): 67 70 69 6f 63 68 69 70 30 00 1a c0 54 63 1a c0 gpiochip0...Tc.. 0c ed 84 c0 48 ed 84 c0 3c ee 84 c0 10 00 00 00 ....H...<....... backtrace: [<962810f7>] kobject_set_name_vargs+0x2c/0xa0 [] dev_set_name+0x2c/0x5c [<94abbca9>] gpiochip_add_data_with_key+0xfc/0xce8 [<5c4193e0>] omap_gpio_probe+0x33c/0x68c [<3402f137>] platform_probe+0x58/0xb8 [<7421e210>] really_probe+0xec/0x3b4 [<000f8ada>] driver_probe_device+0x58/0xb4 [<67e0f7f7>] bus_for_each_drv+0x80/0xd0 [<4de545dc>] __device_attach+0xe8/0x15c [<2e4431e7>] bus_probe_device+0x84/0x8c [] device_add+0x384/0x7c0 [<5aff2995>] of_platform_device_create_pdata+0x8c/0xb8 [<061c3483>] of_platform_bus_create+0x198/0x230 [<5ee6d42a>] of_platform_populate+0x60/0xb8 [<2647300f>] sysc_probe+0xd18/0x135c [<3402f137>] platform_probe+0x58/0xb8 Signed-off-by: Quanyang Wang Cc: stable@vger.kernel.org Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index b78a634cca240..3ba9c981f0b9d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -603,7 +603,11 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ret = gdev->id; goto err_free_gdev; } - dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id); + + ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id); + if (ret) + goto err_free_ida; + device_initialize(&gdev->dev); dev_set_drvdata(&gdev->dev, gdev); if (gc->parent && gc->parent->driver) @@ -617,7 +621,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, gdev->descs = kcalloc(gc->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL); if (!gdev->descs) { ret = -ENOMEM; - goto err_free_ida; + goto err_free_dev_name; } if (gc->ngpio == 0) { @@ -768,6 +772,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, kfree_const(gdev->label); err_free_descs: kfree(gdev->descs); +err_free_dev_name: + kfree(dev_name(&gdev->dev)); err_free_ida: ida_free(&gpio_ida, gdev->id); err_free_gdev: -- GitLab From 1074f8ec288f537f3b8462d09997a69b40f87e38 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Fri, 29 Jan 2021 15:00:23 +0100 Subject: [PATCH 0827/1084] clang-format: Update with the latest for_each macro list Re-run the shell fragment that generated the original list. Signed-off-by: Miguel Ojeda --- .clang-format | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.clang-format b/.clang-format index 10dc5a9a61b3e..01a341ceec6c0 100644 --- a/.clang-format +++ b/.clang-format @@ -122,6 +122,7 @@ ForEachMacros: - 'drm_for_each_bridge_in_chain' - 'drm_for_each_connector_iter' - 'drm_for_each_crtc' + - 'drm_for_each_crtc_reverse' - 'drm_for_each_encoder' - 'drm_for_each_encoder_mask' - 'drm_for_each_fb' @@ -203,14 +204,13 @@ ForEachMacros: - 'for_each_matching_node' - 'for_each_matching_node_and_match' - 'for_each_member' - - 'for_each_mem_region' - - 'for_each_memblock_type' - 'for_each_memcg_cache_index' - 'for_each_mem_pfn_range' - '__for_each_mem_range' - 'for_each_mem_range' - '__for_each_mem_range_rev' - 'for_each_mem_range_rev' + - 'for_each_mem_region' - 'for_each_migratetype_order' - 'for_each_msi_entry' - 'for_each_msi_entry_safe' @@ -276,10 +276,8 @@ ForEachMacros: - 'for_each_reserved_mem_range' - 'for_each_reserved_mem_region' - 'for_each_rtd_codec_dais' - - 'for_each_rtd_codec_dais_rollback' - 'for_each_rtd_components' - 'for_each_rtd_cpu_dais' - - 'for_each_rtd_cpu_dais_rollback' - 'for_each_rtd_dais' - 'for_each_set_bit' - 'for_each_set_bit_from' @@ -298,6 +296,7 @@ ForEachMacros: - '__for_each_thread' - 'for_each_thread' - 'for_each_unicast_dest_pgid' + - 'for_each_vsi' - 'for_each_wakeup_source' - 'for_each_zone' - 'for_each_zone_zonelist' @@ -330,6 +329,7 @@ ForEachMacros: - 'hlist_for_each_entry_rcu_bh' - 'hlist_for_each_entry_rcu_notrace' - 'hlist_for_each_entry_safe' + - 'hlist_for_each_entry_srcu' - '__hlist_for_each_rcu' - 'hlist_for_each_safe' - 'hlist_nulls_for_each_entry' @@ -378,6 +378,7 @@ ForEachMacros: - 'list_for_each_entry_safe_continue' - 'list_for_each_entry_safe_from' - 'list_for_each_entry_safe_reverse' + - 'list_for_each_entry_srcu' - 'list_for_each_prev' - 'list_for_each_prev_safe' - 'list_for_each_safe' @@ -411,6 +412,8 @@ ForEachMacros: - 'of_property_for_each_string' - 'of_property_for_each_u32' - 'pci_bus_for_each_resource' + - 'pcl_for_each_chunk' + - 'pcl_for_each_segment' - 'pcm_for_each_format' - 'ping_portaddr_for_each_entry' - 'plist_for_each' -- GitLab From cd92cdb9c8bcfc27a8f28bcbf7c414a0ea79e5ec Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Fri, 29 Jan 2021 23:47:25 +0900 Subject: [PATCH 0828/1084] null_blk: cleanup zoned mode initialization To avoid potential compilation problems, replaced the badly written MB_TO_SECTS() macro (missing parenthesis around the argument use) with the inline function mb_to_sects(). And while at it, simplify the calculation of the total number of zones of the device using the round_up() macro. Signed-off-by: Damien Le Moal Signed-off-by: Jens Axboe --- drivers/block/null_blk/zoned.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c index 148b871f263ba..fce0a54df0e5f 100644 --- a/drivers/block/null_blk/zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -6,7 +6,10 @@ #define CREATE_TRACE_POINTS #include "trace.h" -#define MB_TO_SECTS(mb) (((sector_t)mb * SZ_1M) >> SECTOR_SHIFT) +static inline sector_t mb_to_sects(unsigned long mb) +{ + return ((sector_t)mb * SZ_1M) >> SECTOR_SHIFT; +} static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect) { @@ -77,12 +80,11 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q) return -EINVAL; } - zone_capacity_sects = MB_TO_SECTS(dev->zone_capacity); - dev_capacity_sects = MB_TO_SECTS(dev->size); - dev->zone_size_sects = MB_TO_SECTS(dev->zone_size); - dev->nr_zones = dev_capacity_sects >> ilog2(dev->zone_size_sects); - if (dev_capacity_sects & (dev->zone_size_sects - 1)) - dev->nr_zones++; + zone_capacity_sects = mb_to_sects(dev->zone_capacity); + dev_capacity_sects = mb_to_sects(dev->size); + dev->zone_size_sects = mb_to_sects(dev->zone_size); + dev->nr_zones = round_up(dev_capacity_sects, dev->zone_size_sects) + >> ilog2(dev->zone_size_sects); dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct nullb_zone), GFP_KERNEL | __GFP_ZERO); -- GitLab From 20bf2b378729c4a0366a53e2018a0b70ace94bcd Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 28 Jan 2021 15:52:19 -0600 Subject: [PATCH 0829/1084] x86/build: Disable CET instrumentation in the kernel With retpolines disabled, some configurations of GCC, and specifically the GCC versions 9 and 10 in Ubuntu will add Intel CET instrumentation to the kernel by default. That breaks certain tracing scenarios by adding a superfluous ENDBR64 instruction before the fentry call, for functions which can be called indirectly. CET instrumentation isn't currently necessary in the kernel, as CET is only supported in user space. Disable it unconditionally and move it into the x86's Makefile as CET/CFI... enablement should be a per-arch decision anyway. [ bp: Massage and extend commit message. ] Fixes: 29be86d7f9cb ("kbuild: add -fcf-protection=none when using retpoline flags") Reported-by: Nikolay Borisov Signed-off-by: Josh Poimboeuf Signed-off-by: Borislav Petkov Reviewed-by: Nikolay Borisov Tested-by: Nikolay Borisov Cc: Cc: Seth Forshee Cc: Masahiro Yamada Link: https://lkml.kernel.org/r/20210128215219.6kct3h2eiustncws@treble --- Makefile | 6 ------ arch/x86/Makefile | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index e0af7a4a55985..51c2bf34142de 100644 --- a/Makefile +++ b/Makefile @@ -948,12 +948,6 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) # change __FILE__ to the relative path from the srctree KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=) -# ensure -fcf-protection is disabled when using retpoline as it is -# incompatible with -mindirect-branch=thunk-extern -ifdef CONFIG_RETPOLINE -KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) -endif - # include additional Makefiles when needed include-y := scripts/Makefile.extrawarn include-$(CONFIG_KASAN) += scripts/Makefile.kasan diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 7116da3980be4..5857917f83eee 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -120,6 +120,9 @@ else KBUILD_CFLAGS += -mno-red-zone KBUILD_CFLAGS += -mcmodel=kernel + + # Intel CET isn't enabled in the kernel + KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) endif ifdef CONFIG_X86_X32 -- GitLab From 8c65830ae1629b03e5d65e9aafae7e2cf5f8b743 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 27 Jan 2021 14:16:01 -0800 Subject: [PATCH 0830/1084] scsi: lpfc: Fix EEH encountering oops with NVMe traffic In testing, in a configuration with Redfish and native NVMe multipath when an EEH is injected, a kernel oops is being encountered: (unreliable) lpfc_nvme_ls_req+0x328/0x720 [lpfc] __nvme_fc_send_ls_req.constprop.13+0x1d8/0x3d0 [nvme_fc] nvme_fc_create_association+0x224/0xd10 [nvme_fc] nvme_fc_reset_ctrl_work+0x110/0x154 [nvme_fc] process_one_work+0x304/0x5d the NBMe transport is issuing a Disconnect LS request, which the driver receives and tries to post but the work queue used by the driver is already being torn down by the eeh. Fix by validating the validity of the work queue before proceeding with the LS transmit. Link: https://lore.kernel.org/r/20210127221601.84878-1-jsmart2021@gmail.com Reviewed-by: Ewan D. Milne Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nvme.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 1cb82fa6a60e4..39d147e251bf4 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -559,6 +559,9 @@ __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return -ENODEV; } + if (!vport->phba->sli4_hba.nvmels_wq) + return -ENOMEM; + /* * there are two dma buf in the request, actually there is one and * the second one is just the start address + cmd size. -- GitLab From 7e0a9220467dbcfdc5bc62825724f3e52e50ab31 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Fri, 29 Jan 2021 10:13:53 -0500 Subject: [PATCH 0831/1084] fgraph: Initialize tracing_graph_pause at task creation On some archs, the idle task can call into cpu_suspend(). The cpu_suspend() will disable or pause function graph tracing, as there's some paths in bringing down the CPU that can have issues with its return address being modified. The task_struct structure has a "tracing_graph_pause" atomic counter, that when set to something other than zero, the function graph tracer will not modify the return address. The problem is that the tracing_graph_pause counter is initialized when the function graph tracer is enabled. This can corrupt the counter for the idle task if it is suspended in these architectures. CPU 1 CPU 2 ----- ----- do_idle() cpu_suspend() pause_graph_tracing() task_struct->tracing_graph_pause++ (0 -> 1) start_graph_tracing() for_each_online_cpu(cpu) { ftrace_graph_init_idle_task(cpu) task-struct->tracing_graph_pause = 0 (1 -> 0) unpause_graph_tracing() task_struct->tracing_graph_pause-- (0 -> -1) The above should have gone from 1 to zero, and enabled function graph tracing again. But instead, it is set to -1, which keeps it disabled. There's no reason that the field tracing_graph_pause on the task_struct can not be initialized at boot up. Cc: stable@vger.kernel.org Fixes: 380c4b1411ccd ("tracing/function-graph-tracer: append the tracing_graph_flag") Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=211339 Reported-by: pierre.gondois@arm.com Signed-off-by: Steven Rostedt (VMware) --- init/init_task.c | 3 ++- kernel/trace/fgraph.c | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/init/init_task.c b/init/init_task.c index 8a992d73e6fb7..3711cdaafed2f 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -198,7 +198,8 @@ struct task_struct init_task .lockdep_recursion = 0, #endif #ifdef CONFIG_FUNCTION_GRAPH_TRACER - .ret_stack = NULL, + .ret_stack = NULL, + .tracing_graph_pause = ATOMIC_INIT(0), #endif #if defined(CONFIG_TRACING) && defined(CONFIG_PREEMPTION) .trace_recursion = 0, diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c index 73edb9e4f3548..29a6ebeebc9e1 100644 --- a/kernel/trace/fgraph.c +++ b/kernel/trace/fgraph.c @@ -394,7 +394,6 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) } if (t->ret_stack == NULL) { - atomic_set(&t->tracing_graph_pause, 0); atomic_set(&t->trace_overrun, 0); t->curr_ret_stack = -1; t->curr_ret_depth = -1; @@ -489,7 +488,6 @@ static DEFINE_PER_CPU(struct ftrace_ret_stack *, idle_ret_stack); static void graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack) { - atomic_set(&t->tracing_graph_pause, 0); atomic_set(&t->trace_overrun, 0); t->ftrace_timestamp = 0; /* make curr_ret_stack visible before we add the ret_stack */ -- GitLab From da7f84cdf02fd5f66864041f45018b328911b722 Mon Sep 17 00:00:00 2001 From: Viktor Rosendahl Date: Tue, 19 Jan 2021 17:43:43 +0100 Subject: [PATCH 0832/1084] tracing: Use pause-on-trace with the latency tracers Eaerlier, tracing was disabled when reading the trace file. This behavior was changed with: commit 06e0a548bad0 ("tracing: Do not disable tracing when reading the trace file"). This doesn't seem to work with the latency tracers. The above mentioned commit dit not only change the behavior but also added an option to emulate the old behavior. The idea with this patch is to enable this pause-on-trace option when the latency tracers are used. Link: https://lkml.kernel.org/r/20210119164344.37500-2-Viktor.Rosendahl@bmw.de Cc: stable@vger.kernel.org Fixes: 06e0a548bad0 ("tracing: Do not disable tracing when reading the trace file") Signed-off-by: Viktor Rosendahl Signed-off-by: Steven Rostedt (VMware) --- kernel/trace/trace_irqsoff.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index d06aab4dcbb8f..6756379b661fe 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -562,6 +562,8 @@ static int __irqsoff_tracer_init(struct trace_array *tr) /* non overwrite screws up the latency tracers */ set_tracer_flag(tr, TRACE_ITER_OVERWRITE, 1); set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, 1); + /* without pause, we will produce garbage if another latency occurs */ + set_tracer_flag(tr, TRACE_ITER_PAUSE_ON_TRACE, 1); tr->max_latency = 0; irqsoff_trace = tr; @@ -583,11 +585,13 @@ static void __irqsoff_tracer_reset(struct trace_array *tr) { int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT; int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE; + int pause_flag = save_flags & TRACE_ITER_PAUSE_ON_TRACE; stop_irqsoff_tracer(tr, is_graph(tr)); set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, lat_flag); set_tracer_flag(tr, TRACE_ITER_OVERWRITE, overwrite_flag); + set_tracer_flag(tr, TRACE_ITER_PAUSE_ON_TRACE, pause_flag); ftrace_reset_array_ops(tr); irqsoff_busy = false; -- GitLab From 97c753e62e6c31a404183898d950d8c08d752dbd Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 28 Jan 2021 00:37:51 +0900 Subject: [PATCH 0833/1084] tracing/kprobe: Fix to support kretprobe events on unloaded modules Fix kprobe_on_func_entry() returns error code instead of false so that register_kretprobe() can return an appropriate error code. append_trace_kprobe() expects the kprobe registration returns -ENOENT when the target symbol is not found, and it checks whether the target module is unloaded or not. If the target module doesn't exist, it defers to probe the target symbol until the module is loaded. However, since register_kretprobe() returns -EINVAL instead of -ENOENT in that case, it always fail on putting the kretprobe event on unloaded modules. e.g. Kprobe event: /sys/kernel/debug/tracing # echo p xfs:xfs_end_io >> kprobe_events [ 16.515574] trace_kprobe: This probe might be able to register after target module is loaded. Continue. Kretprobe event: (p -> r) /sys/kernel/debug/tracing # echo r xfs:xfs_end_io >> kprobe_events sh: write error: Invalid argument /sys/kernel/debug/tracing # cat error_log [ 41.122514] trace_kprobe: error: Failed to register probe event Command: r xfs:xfs_end_io ^ To fix this bug, change kprobe_on_func_entry() to detect symbol lookup failure and return -ENOENT in that case. Otherwise it returns -EINVAL or 0 (succeeded, given address is on the entry). Link: https://lkml.kernel.org/r/161176187132.1067016.8118042342894378981.stgit@devnote2 Cc: stable@vger.kernel.org Fixes: 59158ec4aef7 ("tracing/kprobes: Check the probe on unloaded module correctly") Reported-by: Jianlin Lv Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt (VMware) --- include/linux/kprobes.h | 2 +- kernel/kprobes.c | 34 +++++++++++++++++++++++++--------- kernel/trace/trace_kprobe.c | 10 ++++++---- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index b3a36b0cfc81a..1883a4a9f16a7 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -266,7 +266,7 @@ extern void kprobes_inc_nmissed_count(struct kprobe *p); extern bool arch_within_kprobe_blacklist(unsigned long addr); extern int arch_populate_kprobe_blacklist(void); extern bool arch_kprobe_on_func_entry(unsigned long offset); -extern bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset); +extern int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset); extern bool within_kprobe_blacklist(unsigned long addr); extern int kprobe_add_ksym_blacklist(unsigned long entry); diff --git a/kernel/kprobes.c b/kernel/kprobes.c index f7fb5d135930f..1a5bc321e0a5e 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1954,29 +1954,45 @@ bool __weak arch_kprobe_on_func_entry(unsigned long offset) return !offset; } -bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset) +/** + * kprobe_on_func_entry() -- check whether given address is function entry + * @addr: Target address + * @sym: Target symbol name + * @offset: The offset from the symbol or the address + * + * This checks whether the given @addr+@offset or @sym+@offset is on the + * function entry address or not. + * This returns 0 if it is the function entry, or -EINVAL if it is not. + * And also it returns -ENOENT if it fails the symbol or address lookup. + * Caller must pass @addr or @sym (either one must be NULL), or this + * returns -EINVAL. + */ +int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset) { kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset); if (IS_ERR(kp_addr)) - return false; + return PTR_ERR(kp_addr); - if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset) || - !arch_kprobe_on_func_entry(offset)) - return false; + if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset)) + return -ENOENT; - return true; + if (!arch_kprobe_on_func_entry(offset)) + return -EINVAL; + + return 0; } int register_kretprobe(struct kretprobe *rp) { - int ret = 0; + int ret; struct kretprobe_instance *inst; int i; void *addr; - if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset)) - return -EINVAL; + ret = kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset); + if (ret) + return ret; if (kretprobe_blacklist_size) { addr = kprobe_addr(&rp->kp); diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index e6fba1798771b..56c7fbff7bd7f 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -221,9 +221,9 @@ bool trace_kprobe_on_func_entry(struct trace_event_call *call) { struct trace_kprobe *tk = trace_kprobe_primary_from_call(call); - return tk ? kprobe_on_func_entry(tk->rp.kp.addr, + return tk ? (kprobe_on_func_entry(tk->rp.kp.addr, tk->rp.kp.addr ? NULL : tk->rp.kp.symbol_name, - tk->rp.kp.addr ? 0 : tk->rp.kp.offset) : false; + tk->rp.kp.addr ? 0 : tk->rp.kp.offset) == 0) : false; } bool trace_kprobe_error_injectable(struct trace_event_call *call) @@ -828,9 +828,11 @@ static int trace_kprobe_create(int argc, const char *argv[]) } if (is_return) flags |= TPARG_FL_RETURN; - if (kprobe_on_func_entry(NULL, symbol, offset)) + ret = kprobe_on_func_entry(NULL, symbol, offset); + if (ret == 0) flags |= TPARG_FL_FENTRY; - if (offset && is_return && !(flags & TPARG_FL_FENTRY)) { + /* Defer the ENOENT case until register kprobe */ + if (ret == -EINVAL && is_return) { trace_probe_log_err(0, BAD_RETPROBE); goto parse_error; } -- GitLab From ed4e9e615b7ec4992a4eba1643e62ec2d9d979db Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 13 Jan 2021 17:34:47 -0700 Subject: [PATCH 0834/1084] Documentation/llvm: Add a section about supported architectures The most common question around building the Linux kernel with clang is "does it work?" and the answer has always been "it depends on your architecture, configuration, and LLVM version" with no hard answers for users wanting to experiment. LLVM support has significantly improved over the past couple of years, resulting in more architectures and configurations supported, and continuous integration has made it easier to see what works and what does not. Add a section that goes over what architectures are supported in the current kernel version, how they should be built (with just clang or the LLVM utilities as well), and the level of support they receive. This will make it easier for people to try out building their kernel with LLVM and reporting issues that come about from it. Suggested-by: Miguel Ojeda Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- Documentation/kbuild/llvm.rst | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/Documentation/kbuild/llvm.rst b/Documentation/kbuild/llvm.rst index 21c847890d03c..b18401d2ba820 100644 --- a/Documentation/kbuild/llvm.rst +++ b/Documentation/kbuild/llvm.rst @@ -63,6 +63,50 @@ They can be enabled individually. The full list of the parameters: :: Currently, the integrated assembler is disabled by default. You can pass ``LLVM_IAS=1`` to enable it. +Supported Architectures +----------------------- + +LLVM does not target all of the architectures that Linux supports and +just because a target is supported in LLVM does not mean that the kernel +will build or work without any issues. Below is a general summary of +architectures that currently work with ``CC=clang`` or ``LLVM=1``. Level +of support corresponds to "S" values in the MAINTAINERS files. If an +architecture is not present, it either means that LLVM does not target +it or there are known issues. Using the latest stable version of LLVM or +even the development tree will generally yield the best results. +An architecture's ``defconfig`` is generally expected to work well, +certain configurations may have problems that have not been uncovered +yet. Bug reports are always welcome at the issue tracker below! + +.. list-table:: + :widths: 10 10 10 + :header-rows: 1 + + * - Architecture + - Level of support + - ``make`` command + * - arm + - Supported + - ``LLVM=1`` + * - arm64 + - Supported + - ``LLVM=1`` + * - mips + - Maintained + - ``CC=clang`` + * - powerpc + - Maintained + - ``CC=clang`` + * - riscv + - Maintained + - ``CC=clang`` + * - s390 + - Maintained + - ``CC=clang`` + * - x86 + - Supported + - ``LLVM=1`` + Getting Help ------------ -- GitLab From a9cbbb80e3e7dd38ceac166e0698f161862a18ae Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 29 Jan 2021 12:28:20 -0800 Subject: [PATCH 0835/1084] tty: avoid using vfs_iocb_iter_write() for redirected console writes It turns out that the vfs_iocb_iter_{read,write}() functions are entirely broken, and don't actually use the passed-in file pointer for IO - only for the preparatory work (permission checking and for the write_iter function lookup). That worked fine for overlayfs, which always builds the new iocb with the same file pointer that it passes in, but in the general case it ends up doing nonsensical things (and could cause an iterator call that doesn't even match the passed-in file pointer). This subtly broke the tty conversion to write_iter in commit 9bb48c82aced ("tty: implement write_iter"), because the console redirection didn't actually end up redirecting anything, since the passed-in file pointer was basically ignored, and the actual write was done with the original non-redirected console tty after all. The main visible effect of this is that the console messages were no longer logged to /var/log/boot.log during graphical boot. Fix the issue by simply not using the vfs write "helper" function at all, and just redirecting the write entirely internally to the tty layer. Do the target writability permission checks when actually registering the target tty with TIOCCONS instead of at write time. Fixes: 9bb48c82aced ("tty: implement write_iter") Reported-and-tested-by: Hans de Goede Cc: Greg Kroah-Hartman Cc: stable@kernel.org Signed-off-by: Linus Torvalds --- drivers/tty/tty_io.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 48de20916ca78..816e709afa561 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1026,9 +1026,8 @@ void tty_write_message(struct tty_struct *tty, char *msg) * write method will not be invoked in parallel for each device. */ -static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from) +static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_iter *from) { - struct file *file = iocb->ki_filp; struct tty_struct *tty = file_tty(file); struct tty_ldisc *ld; ssize_t ret; @@ -1051,6 +1050,11 @@ static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from) return ret; } +static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from) +{ + return file_tty_write(iocb->ki_filp, iocb, from); +} + ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) { struct file *p = NULL; @@ -1060,9 +1064,13 @@ ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) p = get_file(redirect); spin_unlock(&redirect_lock); + /* + * We know the redirected tty is just another tty, we can can + * call file_tty_write() directly with that file pointer. + */ if (p) { ssize_t res; - res = vfs_iocb_iter_write(p, iocb, iter); + res = file_tty_write(p, iocb, iter); fput(p); return res; } @@ -2308,6 +2316,12 @@ static int tioccons(struct file *file) fput(f); return 0; } + if (file->f_op->write_iter != tty_write) + return -ENOTTY; + if (!(file->f_mode & FMODE_WRITE)) + return -EBADF; + if (!(file->f_mode & FMODE_CAN_WRITE)) + return -EINVAL; spin_lock(&redirect_lock); if (redirect) { spin_unlock(&redirect_lock); -- GitLab From 1bea2a937dadd188de70198b0cf3915e05a506e4 Mon Sep 17 00:00:00 2001 From: David Gow Date: Tue, 26 Jan 2021 19:36:04 -0800 Subject: [PATCH 0836/1084] soc: litex: Properly depend on HAS_IOMEM The LiteX SOC controller driver makes use of IOMEM functions like devm_platform_ioremap_resource(), which are only available if CONFIG_HAS_IOMEM is defined. This causes the driver to be enable under make ARCH=um allyesconfig, even though it won't build. By adding a dependency on HAS_IOMEM, the driver will not be enabled on architectures which don't support it. Fixes: 22447a99c97e ("drivers/soc/litex: add LiteX SoC Controller driver") Signed-off-by: David Gow [shorne@gmail.com: Fix typo in commit message pointed out in review] Signed-off-by: Stafford Horne --- drivers/soc/litex/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/litex/Kconfig b/drivers/soc/litex/Kconfig index 7c6b009b6f6cf..7a7c38282e114 100644 --- a/drivers/soc/litex/Kconfig +++ b/drivers/soc/litex/Kconfig @@ -8,6 +8,7 @@ config LITEX config LITEX_SOC_CONTROLLER tristate "Enable LiteX SoC Controller driver" depends on OF || COMPILE_TEST + depends on HAS_IOMEM select LITEX help This option enables the SoC Controller Driver which verifies -- GitLab From 0188b87899ffc4a1d36a0badbe77d56c92fd91dc Mon Sep 17 00:00:00 2001 From: Wang ShaoBo Date: Thu, 28 Jan 2021 20:44:27 +0800 Subject: [PATCH 0837/1084] kretprobe: Avoid re-registration of the same kretprobe earlier Our system encountered a re-init error when re-registering same kretprobe, where the kretprobe_instance in rp->free_instances is illegally accessed after re-init. Implementation to avoid re-registration has been introduced for kprobe before, but lags for register_kretprobe(). We must check if kprobe has been re-registered before re-initializing kretprobe, otherwise it will destroy the data struct of kretprobe registered, which can lead to memory leak, system crash, also some unexpected behaviors. We use check_kprobe_rereg() to check if kprobe has been re-registered before running register_kretprobe()'s body, for giving a warning message and terminate registration process. Link: https://lkml.kernel.org/r/20210128124427.2031088-1-bobo.shaobowang@huawei.com Cc: stable@vger.kernel.org Fixes: 1f0ab40976460 ("kprobes: Prevent re-registration of the same kprobe") [ The above commit should have been done for kretprobes too ] Acked-by: Naveen N. Rao Acked-by: Ananth N Mavinakayanahalli Acked-by: Masami Hiramatsu Signed-off-by: Wang ShaoBo Signed-off-by: Cheng Jian Signed-off-by: Steven Rostedt (VMware) --- kernel/kprobes.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 1a5bc321e0a5e..d5a3eb74a6574 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1994,6 +1994,10 @@ int register_kretprobe(struct kretprobe *rp) if (ret) return ret; + /* If only rp->kp.addr is specified, check reregistering kprobes */ + if (rp->kp.addr && check_kprobe_rereg(&rp->kp)) + return -EINVAL; + if (kretprobe_blacklist_size) { addr = kprobe_addr(&rp->kp); if (IS_ERR(addr)) -- GitLab From 32ada6b0980d86133d080d62371a5787ea2ec5ed Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 28 Jan 2021 13:45:15 -0600 Subject: [PATCH 0838/1084] dt-bindings: Cleanup standard unit properties Properties with standard unit suffixes already have a type and don't need type definitions. They also default to a single entry, so 'maxItems: 1' can be dropped. adi,ad5758 is an oddball which defined an enum of arrays. While a valid schema, it is simpler as a whole to only define scalar constraints. Cc: Jean Delvare Cc: Lars-Peter Clausen Cc: Dmitry Torokhov Cc: Ulf Hansson Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Serge Semin Cc: linux-hwmon@vger.kernel.org Cc: linux-i2c@vger.kernel.org Cc: linux-iio@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-input@vger.kernel.org Cc: linux-mmc@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-pm@vger.kernel.org Cc: linux-rtc@vger.kernel.org Cc: linux-serial@vger.kernel.org Cc: alsa-devel@alsa-project.org Cc: linux-watchdog@vger.kernel.org Signed-off-by: Rob Herring Acked-by: Guenter Roeck Acked-by: Mark Brown Acked-by: Wolfram Sang # for I2C Acked-by: Alexandre Belloni Acked-by: Greg Kroah-Hartman Acked-by: Sebastian Reichel # for power-supply Acked-by: Jonathan Cameron #for-iio Acked-by: Alexandre TORGUE Link: https://lore.kernel.org/r/20210128194515.743252-1-robh@kernel.org --- .../devicetree/bindings/arm/cpus.yaml | 1 - .../bindings/extcon/wlf,arizona.yaml | 1 - .../bindings/hwmon/adi,ltc2947.yaml | 1 - .../bindings/hwmon/baikal,bt1-pvt.yaml | 8 ++-- .../devicetree/bindings/hwmon/ti,tmp513.yaml | 1 - .../devicetree/bindings/i2c/i2c-gpio.yaml | 2 - .../bindings/i2c/snps,designware-i2c.yaml | 3 -- .../bindings/iio/adc/maxim,max9611.yaml | 1 - .../bindings/iio/adc/st,stm32-adc.yaml | 1 - .../bindings/iio/adc/ti,palmas-gpadc.yaml | 2 - .../bindings/iio/dac/adi,ad5758.yaml | 41 ++++++++++++------- .../bindings/iio/health/maxim,max30100.yaml | 1 - .../input/touchscreen/touchscreen.yaml | 2 - .../bindings/mmc/mmc-controller.yaml | 1 - .../bindings/mmc/mmc-pwrseq-simple.yaml | 2 - .../bindings/net/ethernet-controller.yaml | 2 - .../devicetree/bindings/net/snps,dwmac.yaml | 1 - .../bindings/power/supply/battery.yaml | 3 -- .../bindings/power/supply/bq2515x.yaml | 1 - .../bindings/regulator/dlg,da9121.yaml | 1 - .../bindings/regulator/fixed-regulator.yaml | 2 - .../devicetree/bindings/rtc/rtc.yaml | 2 - .../devicetree/bindings/serial/pl011.yaml | 2 - .../devicetree/bindings/sound/sgtl5000.yaml | 2 - .../bindings/watchdog/watchdog.yaml | 1 - 25 files changed, 29 insertions(+), 56 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml index 14cd727d3c4b7..f02fd10de604b 100644 --- a/Documentation/devicetree/bindings/arm/cpus.yaml +++ b/Documentation/devicetree/bindings/arm/cpus.yaml @@ -232,7 +232,6 @@ properties: by this cpu (see ./idle-states.yaml). capacity-dmips-mhz: - $ref: '/schemas/types.yaml#/definitions/uint32' description: u32 value representing CPU capacity (see ./cpu-capacity.txt) in DMIPS/MHz, relative to highest capacity-dmips-mhz diff --git a/Documentation/devicetree/bindings/extcon/wlf,arizona.yaml b/Documentation/devicetree/bindings/extcon/wlf,arizona.yaml index 5fe784f487c5e..efdf59abb2e18 100644 --- a/Documentation/devicetree/bindings/extcon/wlf,arizona.yaml +++ b/Documentation/devicetree/bindings/extcon/wlf,arizona.yaml @@ -85,7 +85,6 @@ properties: wlf,micd-timeout-ms: description: Timeout for microphone detection, specified in milliseconds. - $ref: "/schemas/types.yaml#/definitions/uint32" wlf,micd-force-micbias: description: diff --git a/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml b/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml index eef614962b103..bf04151b63d2b 100644 --- a/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml +++ b/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml @@ -49,7 +49,6 @@ properties: description: This property controls the Accumulation Dead band which allows to set the level of current below which no accumulation takes place. - $ref: /schemas/types.yaml#/definitions/uint32 maximum: 255 default: 0 diff --git a/Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml b/Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml index 00a6511354e6c..5d3ce641fcdeb 100644 --- a/Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml +++ b/Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml @@ -73,11 +73,9 @@ properties: description: | Temperature sensor trimming factor. It can be used to manually adjust the temperature measurements within 7.130 degrees Celsius. - maxItems: 1 - items: - default: 0 - minimum: 0 - maximum: 7130 + default: 0 + minimum: 0 + maximum: 7130 additionalProperties: false diff --git a/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml b/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml index 8020d739a078e..1502b22c77ccb 100644 --- a/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml +++ b/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml @@ -52,7 +52,6 @@ properties: ti,bus-range-microvolt: description: | This is the operating range of the bus voltage in microvolt - $ref: /schemas/types.yaml#/definitions/uint32 enum: [16000000, 32000000] default: 32000000 diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.yaml b/Documentation/devicetree/bindings/i2c/i2c-gpio.yaml index cc3aa2a5e70bf..ff99344788ab8 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-gpio.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.yaml @@ -39,11 +39,9 @@ properties: i2c-gpio,delay-us: description: delay between GPIO operations (may depend on each platform) - $ref: /schemas/types.yaml#/definitions/uint32 i2c-gpio,timeout-ms: description: timeout to get data - $ref: /schemas/types.yaml#/definitions/uint32 # Deprecated properties, do not use in new device tree sources: gpios: diff --git a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml index c22b66b6219ea..d9293c57f573c 100644 --- a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml @@ -66,21 +66,18 @@ properties: default: 400000 i2c-sda-hold-time-ns: - maxItems: 1 description: | The property should contain the SDA hold time in nanoseconds. This option is only supported in hardware blocks version 1.11a or newer or on Microsemi SoCs. i2c-scl-falling-time-ns: - maxItems: 1 description: | The property should contain the SCL falling time in nanoseconds. This value is used to compute the tLOW period. default: 300 i2c-sda-falling-time-ns: - maxItems: 1 description: | The property should contain the SDA falling time in nanoseconds. This value is used to compute the tHIGH period. diff --git a/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml b/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml index 9475a9e6e9207..95774a55629df 100644 --- a/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml +++ b/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml @@ -23,7 +23,6 @@ properties: maxItems: 1 shunt-resistor-micro-ohms: - $ref: /schemas/types.yaml#/definitions/uint32 description: | Value in micro Ohms of the shunt resistor connected between the RS+ and RS- inputs, across which the current is measured. Value needed to compute diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml index 28417b31b5589..517e32976c304 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml @@ -246,7 +246,6 @@ patternProperties: Resolution (bits) to use for conversions: - can be 6, 8, 10 or 12 on stm32f4 - can be 8, 10, 12, 14 or 16 on stm32h7 and stm32mp1 - $ref: /schemas/types.yaml#/definitions/uint32 st,adc-channels: description: | diff --git a/Documentation/devicetree/bindings/iio/adc/ti,palmas-gpadc.yaml b/Documentation/devicetree/bindings/iio/adc/ti,palmas-gpadc.yaml index 692dacd0fee5f..7b895784e0085 100644 --- a/Documentation/devicetree/bindings/iio/adc/ti,palmas-gpadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/ti,palmas-gpadc.yaml @@ -42,7 +42,6 @@ properties: const: 1 ti,channel0-current-microamp: - $ref: /schemas/types.yaml#/definitions/uint32 description: Channel 0 current in uA. enum: - 0 @@ -51,7 +50,6 @@ properties: - 20 ti,channel3-current-microamp: - $ref: /schemas/types.yaml#/definitions/uint32 description: Channel 3 current in uA. enum: - 0 diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml index 626ccb6fe21e1..fd4edca34a285 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml @@ -46,31 +46,42 @@ properties: two properties must be present: adi,range-microvolt: - $ref: /schemas/types.yaml#/definitions/int32-array description: | Voltage output range specified as - enum: - - [[0, 5000000]] - - [[0, 10000000]] - - [[-5000000, 5000000]] - - [[-10000000, 10000000]] + oneOf: + - items: + - const: 0 + - enum: [5000000, 10000000] + - items: + - const: -5000000 + - const: 5000000 + - items: + - const: -10000000 + - const: 10000000 adi,range-microamp: - $ref: /schemas/types.yaml#/definitions/int32-array description: | Current output range specified as - enum: - - [[0, 20000]] - - [[0, 24000]] - - [[4, 24000]] - - [[-20000, 20000]] - - [[-24000, 24000]] - - [[-1000, 22000]] + oneOf: + - items: + - const: 0 + - enum: [20000, 24000] + - items: + - const: 4 + - const: 24000 + - items: + - const: -20000 + - const: 20000 + - items: + - const: -24000 + - const: 24000 + - items: + - const: -1000 + - const: 22000 reset-gpios: true adi,dc-dc-ilim-microamp: - $ref: /schemas/types.yaml#/definitions/uint32 enum: [150000, 200000, 250000, 300000, 350000, 400000] description: | The dc-to-dc converter current limit. diff --git a/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml b/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml index 64b8626370393..967778fb0ce89 100644 --- a/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml +++ b/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml @@ -21,7 +21,6 @@ properties: description: Connected to ADC_RDY pin. maxim,led-current-microamp: - $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 2 maxItems: 2 description: | diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml index a771a15f053fa..046ace461cc9d 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml @@ -70,11 +70,9 @@ properties: touchscreen-x-mm: description: horizontal length in mm of the touchscreen - $ref: /schemas/types.yaml#/definitions/uint32 touchscreen-y-mm: description: vertical length in mm of the touchscreen - $ref: /schemas/types.yaml#/definitions/uint32 dependencies: touchscreen-size-x: [ touchscreen-size-y ] diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml index 186f04ba93579..e674bba52ee97 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml +++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml @@ -259,7 +259,6 @@ properties: waiting for I/O signalling and card power supply to be stable, regardless of whether pwrseq-simple is used. Default to 10ms if no available. - $ref: /schemas/types.yaml#/definitions/uint32 default: 10 supports-cqe: diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml index 6cd57863c1dbd..226fb191913d2 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml @@ -41,13 +41,11 @@ properties: description: Delay in ms after powering the card and de-asserting the reset-gpios (if any). - $ref: /schemas/types.yaml#/definitions/uint32 power-off-delay-us: description: Delay in us after asserting the reset-gpios (if any) during power off of the card. - $ref: /schemas/types.yaml#/definitions/uint32 required: - compatible diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml index 0965f6515f9ec..dac4aadb6e2e7 100644 --- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml +++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml @@ -122,7 +122,6 @@ properties: such as flow control thresholds. rx-internal-delay-ps: - $ref: /schemas/types.yaml#/definitions/uint32 description: | RGMII Receive Clock Delay defined in pico seconds. This is used for controllers that have configurable RX internal delays. @@ -140,7 +139,6 @@ properties: is used for components that can have configurable fifo sizes. tx-internal-delay-ps: - $ref: /schemas/types.yaml#/definitions/uint32 description: | RGMII Transmit Clock Delay defined in pico seconds. This is used for controllers that have configurable TX internal delays. diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml index b2f6083f556af..9ac77b8cb7670 100644 --- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml +++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml @@ -208,7 +208,6 @@ properties: Triplet of delays. The 1st cell is reset pre-delay in micro seconds. The 2nd cell is reset pulse in micro seconds. The 3rd cell is reset post-delay in micro seconds. - $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 3 maxItems: 3 diff --git a/Documentation/devicetree/bindings/power/supply/battery.yaml b/Documentation/devicetree/bindings/power/supply/battery.yaml index 0c7e2e44793ba..c3b4b75435918 100644 --- a/Documentation/devicetree/bindings/power/supply/battery.yaml +++ b/Documentation/devicetree/bindings/power/supply/battery.yaml @@ -83,21 +83,18 @@ properties: for each of the battery capacity lookup table. operating-range-celsius: - $ref: /schemas/types.yaml#/definitions/uint32-array description: operating temperature range of a battery items: - description: minimum temperature at which battery can operate - description: maximum temperature at which battery can operate ambient-celsius: - $ref: /schemas/types.yaml#/definitions/uint32-array description: safe range of ambient temperature items: - description: alert when ambient temperature is lower than this value - description: alert when ambient temperature is higher than this value alert-celsius: - $ref: /schemas/types.yaml#/definitions/uint32-array description: safe range of battery temperature items: - description: alert when battery temperature is lower than this value diff --git a/Documentation/devicetree/bindings/power/supply/bq2515x.yaml b/Documentation/devicetree/bindings/power/supply/bq2515x.yaml index 75a56773be4a0..813d6afde6069 100644 --- a/Documentation/devicetree/bindings/power/supply/bq2515x.yaml +++ b/Documentation/devicetree/bindings/power/supply/bq2515x.yaml @@ -50,7 +50,6 @@ properties: maxItems: 1 input-current-limit-microamp: - $ref: /schemas/types.yaml#/definitions/uint32 description: Maximum input current in micro Amps. minimum: 50000 maximum: 500000 diff --git a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml index 6f2164f7bc577..228018c87bea8 100644 --- a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml +++ b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml @@ -62,7 +62,6 @@ properties: description: IRQ line information. dlg,irq-polling-delay-passive-ms: - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 1000 maximum: 10000 description: | diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml index d3d0dc13dd8b8..8850c01bd4706 100644 --- a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml @@ -72,11 +72,9 @@ properties: startup-delay-us: description: startup time in microseconds - $ref: /schemas/types.yaml#/definitions/uint32 off-on-delay-us: description: off delay time in microseconds - $ref: /schemas/types.yaml#/definitions/uint32 enable-active-high: description: diff --git a/Documentation/devicetree/bindings/rtc/rtc.yaml b/Documentation/devicetree/bindings/rtc/rtc.yaml index d30dc045aac64..0ec3551f12dd3 100644 --- a/Documentation/devicetree/bindings/rtc/rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/rtc.yaml @@ -27,7 +27,6 @@ properties: 1: chargeable quartz-load-femtofarads: - $ref: /schemas/types.yaml#/definitions/uint32 description: The capacitive load of the quartz(x-tal), expressed in femto Farad (fF). The default value shall be listed (if optional), @@ -47,7 +46,6 @@ properties: deprecated: true trickle-resistor-ohms: - $ref: /schemas/types.yaml#/definitions/uint32 description: Selected resistor for trickle charger. Should be given if trickle charger should be enabled. diff --git a/Documentation/devicetree/bindings/serial/pl011.yaml b/Documentation/devicetree/bindings/serial/pl011.yaml index c23c93b400f06..07fa6d26f2b43 100644 --- a/Documentation/devicetree/bindings/serial/pl011.yaml +++ b/Documentation/devicetree/bindings/serial/pl011.yaml @@ -88,14 +88,12 @@ properties: description: Rate at which poll occurs when auto-poll is set. default 100ms. - $ref: /schemas/types.yaml#/definitions/uint32 default: 100 poll-timeout-ms: description: Poll timeout when auto-poll is set, default 3000ms. - $ref: /schemas/types.yaml#/definitions/uint32 default: 3000 required: diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.yaml b/Documentation/devicetree/bindings/sound/sgtl5000.yaml index d116c174b545f..70b4a88310732 100644 --- a/Documentation/devicetree/bindings/sound/sgtl5000.yaml +++ b/Documentation/devicetree/bindings/sound/sgtl5000.yaml @@ -41,14 +41,12 @@ properties: values of 2k, 4k or 8k. If set to 0 it will be off. If this node is not mentioned or if the value is unknown, then micbias resistor is set to 4k. - $ref: "/schemas/types.yaml#/definitions/uint32" enum: [ 0, 2, 4, 8 ] micbias-voltage-m-volts: description: The bias voltage to be used in mVolts. The voltage can take values from 1.25V to 3V by 250mV steps. If this node is not mentioned or the value is unknown, then the value is set to 1.25V. - $ref: "/schemas/types.yaml#/definitions/uint32" enum: [ 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000 ] lrclk-strength: diff --git a/Documentation/devicetree/bindings/watchdog/watchdog.yaml b/Documentation/devicetree/bindings/watchdog/watchdog.yaml index 4e2c26cd981d9..e3dfb02f0ca52 100644 --- a/Documentation/devicetree/bindings/watchdog/watchdog.yaml +++ b/Documentation/devicetree/bindings/watchdog/watchdog.yaml @@ -19,7 +19,6 @@ properties: pattern: "^watchdog(@.*|-[0-9a-f])?$" timeout-sec: - $ref: /schemas/types.yaml#/definitions/uint32 description: Contains the watchdog timeout in seconds. -- GitLab From 4c457e8cb75eda91906a4f89fc39bde3f9a43922 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 23 Jan 2021 12:27:59 +0000 Subject: [PATCH 0839/1084] genirq/msi: Activate Multi-MSI early when MSI_FLAG_ACTIVATE_EARLY is set When MSI_FLAG_ACTIVATE_EARLY is set (which is the case for PCI), __msi_domain_alloc_irqs() performs the activation of the interrupt (which in the case of PCI results in the endpoint being programmed) as soon as the interrupt is allocated. But it appears that this is only done for the first vector, introducing an inconsistent behaviour for PCI Multi-MSI. Fix it by iterating over the number of vectors allocated to each MSI descriptor. This is easily achieved by introducing a new "for_each_msi_vector" iterator, together with a tiny bit of refactoring. Fixes: f3b0946d629c ("genirq/msi: Make sure PCI MSIs are activated early") Reported-by: Shameer Kolothum Signed-off-by: Marc Zyngier Signed-off-by: Thomas Gleixner Tested-by: Shameer Kolothum Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210123122759.1781359-1-maz@kernel.org --- include/linux/msi.h | 6 ++++++ kernel/irq/msi.c | 44 ++++++++++++++++++++------------------------ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/include/linux/msi.h b/include/linux/msi.h index 360a0a7e73415..aef35fd1cf116 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -178,6 +178,12 @@ struct msi_desc { list_for_each_entry((desc), dev_to_msi_list((dev)), list) #define for_each_msi_entry_safe(desc, tmp, dev) \ list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list) +#define for_each_msi_vector(desc, __irq, dev) \ + for_each_msi_entry((desc), (dev)) \ + if ((desc)->irq) \ + for (__irq = (desc)->irq; \ + __irq < ((desc)->irq + (desc)->nvec_used); \ + __irq++) #ifdef CONFIG_IRQ_MSI_IOMMU static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc) diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index dc0e2d7fbdfd9..b338d622f26e3 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -436,22 +436,22 @@ int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, can_reserve = msi_check_reservation_mode(domain, info, dev); - for_each_msi_entry(desc, dev) { - virq = desc->irq; - if (desc->nvec_used == 1) - dev_dbg(dev, "irq %d for MSI\n", virq); - else + /* + * This flag is set by the PCI layer as we need to activate + * the MSI entries before the PCI layer enables MSI in the + * card. Otherwise the card latches a random msi message. + */ + if (!(info->flags & MSI_FLAG_ACTIVATE_EARLY)) + goto skip_activate; + + for_each_msi_vector(desc, i, dev) { + if (desc->irq == i) { + virq = desc->irq; dev_dbg(dev, "irq [%d-%d] for MSI\n", virq, virq + desc->nvec_used - 1); - /* - * This flag is set by the PCI layer as we need to activate - * the MSI entries before the PCI layer enables MSI in the - * card. Otherwise the card latches a random msi message. - */ - if (!(info->flags & MSI_FLAG_ACTIVATE_EARLY)) - continue; + } - irq_data = irq_domain_get_irq_data(domain, desc->irq); + irq_data = irq_domain_get_irq_data(domain, i); if (!can_reserve) { irqd_clr_can_reserve(irq_data); if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK) @@ -462,28 +462,24 @@ int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, goto cleanup; } +skip_activate: /* * If these interrupts use reservation mode, clear the activated bit * so request_irq() will assign the final vector. */ if (can_reserve) { - for_each_msi_entry(desc, dev) { - irq_data = irq_domain_get_irq_data(domain, desc->irq); + for_each_msi_vector(desc, i, dev) { + irq_data = irq_domain_get_irq_data(domain, i); irqd_clr_activated(irq_data); } } return 0; cleanup: - for_each_msi_entry(desc, dev) { - struct irq_data *irqd; - - if (desc->irq == virq) - break; - - irqd = irq_domain_get_irq_data(domain, desc->irq); - if (irqd_is_activated(irqd)) - irq_domain_deactivate_irq(irqd); + for_each_msi_vector(desc, i, dev) { + irq_data = irq_domain_get_irq_data(domain, i); + if (irqd_is_activated(irq_data)) + irq_domain_deactivate_irq(irq_data); } msi_domain_free_irqs(domain, dev); return ret; -- GitLab From 01365633bd1c836240f9bbf86bbeee749795480a Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Thu, 28 Jan 2021 20:48:02 +0100 Subject: [PATCH 0840/1084] net: arcnet: Fix RESET flag handling The main arcnet interrupt handler calls arcnet_close() then arcnet_open(), if the RESET status flag is encountered. This is invalid: 1) In general, interrupt handlers should never call ->ndo_stop() and ->ndo_open() functions. They are usually full of blocking calls and other methods that are expected to be called only from drivers init and exit code paths. 2) arcnet_close() contains a del_timer_sync(). If the irq handler interrupts the to-be-deleted timer, del_timer_sync() will just loop forever. 3) arcnet_close() also calls tasklet_kill(), which has a warning if called from irq context. 4) For device reset, the sequence "arcnet_close(); arcnet_open();" is not complete. Some children arcnet drivers have special init/exit code sequences, which then embed a call to arcnet_open() and arcnet_close() accordingly. Check drivers/net/arcnet/com20020.c. Run the device RESET sequence from a scheduled workqueue instead. Signed-off-by: Ahmed S. Darwish Signed-off-by: Sebastian Andrzej Siewior Link: https://lore.kernel.org/r/20210128194802.727770-1-a.darwish@linutronix.de Signed-off-by: Jakub Kicinski --- drivers/net/arcnet/arc-rimi.c | 4 +- drivers/net/arcnet/arcdevice.h | 6 +++ drivers/net/arcnet/arcnet.c | 66 +++++++++++++++++++++++++++++-- drivers/net/arcnet/com20020-isa.c | 4 +- drivers/net/arcnet/com20020-pci.c | 2 +- drivers/net/arcnet/com20020_cs.c | 2 +- drivers/net/arcnet/com90io.c | 4 +- drivers/net/arcnet/com90xx.c | 4 +- 8 files changed, 78 insertions(+), 14 deletions(-) diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 98df38fe553ce..12d085405bd05 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -332,7 +332,7 @@ static int __init arc_rimi_init(void) dev->irq = 9; if (arcrimi_probe(dev)) { - free_netdev(dev); + free_arcdev(dev); return -EIO; } @@ -349,7 +349,7 @@ static void __exit arc_rimi_exit(void) iounmap(lp->mem_start); release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); free_irq(dev->irq, dev); - free_netdev(dev); + free_arcdev(dev); } #ifndef MODULE diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h index 22a49c6d7ae6e..5d4a4c7efbbff 100644 --- a/drivers/net/arcnet/arcdevice.h +++ b/drivers/net/arcnet/arcdevice.h @@ -298,6 +298,10 @@ struct arcnet_local { int excnak_pending; /* We just got an excesive nak interrupt */ + /* RESET flag handling */ + int reset_in_progress; + struct work_struct reset_work; + struct { uint16_t sequence; /* sequence number (incs with each packet) */ __be16 aborted_seq; @@ -350,7 +354,9 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc) void arcnet_unregister_proto(struct ArcProto *proto); irqreturn_t arcnet_interrupt(int irq, void *dev_id); + struct net_device *alloc_arcdev(const char *name); +void free_arcdev(struct net_device *dev); int arcnet_open(struct net_device *dev); int arcnet_close(struct net_device *dev); diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index e04efc0a5c977..d76dd7d14299e 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -387,10 +387,44 @@ static void arcnet_timer(struct timer_list *t) struct arcnet_local *lp = from_timer(lp, t, timer); struct net_device *dev = lp->dev; - if (!netif_carrier_ok(dev)) { + spin_lock_irq(&lp->lock); + + if (!lp->reset_in_progress && !netif_carrier_ok(dev)) { netif_carrier_on(dev); netdev_info(dev, "link up\n"); } + + spin_unlock_irq(&lp->lock); +} + +static void reset_device_work(struct work_struct *work) +{ + struct arcnet_local *lp; + struct net_device *dev; + + lp = container_of(work, struct arcnet_local, reset_work); + dev = lp->dev; + + /* Do not bring the network interface back up if an ifdown + * was already done. + */ + if (!netif_running(dev) || !lp->reset_in_progress) + return; + + rtnl_lock(); + + /* Do another check, in case of an ifdown that was triggered in + * the small race window between the exit condition above and + * acquiring RTNL. + */ + if (!netif_running(dev) || !lp->reset_in_progress) + goto out; + + dev_close(dev); + dev_open(dev, NULL); + +out: + rtnl_unlock(); } static void arcnet_reply_tasklet(unsigned long data) @@ -452,12 +486,25 @@ struct net_device *alloc_arcdev(const char *name) lp->dev = dev; spin_lock_init(&lp->lock); timer_setup(&lp->timer, arcnet_timer, 0); + INIT_WORK(&lp->reset_work, reset_device_work); } return dev; } EXPORT_SYMBOL(alloc_arcdev); +void free_arcdev(struct net_device *dev) +{ + struct arcnet_local *lp = netdev_priv(dev); + + /* Do not cancel this at ->ndo_close(), as the workqueue itself + * indirectly calls the ifdown path through dev_close(). + */ + cancel_work_sync(&lp->reset_work); + free_netdev(dev); +} +EXPORT_SYMBOL(free_arcdev); + /* Open/initialize the board. This is called sometime after booting when * the 'ifconfig' program is run. * @@ -587,6 +634,10 @@ int arcnet_close(struct net_device *dev) /* shut down the card */ lp->hw.close(dev); + + /* reset counters */ + lp->reset_in_progress = 0; + module_put(lp->hw.owner); return 0; } @@ -820,6 +871,9 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) spin_lock_irqsave(&lp->lock, flags); + if (lp->reset_in_progress) + goto out; + /* RESET flag was enabled - if device is not running, we must * clear it right away (but nothing else). */ @@ -852,11 +906,14 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) if (status & RESETflag) { arc_printk(D_NORMAL, dev, "spurious reset (status=%Xh)\n", status); - arcnet_close(dev); - arcnet_open(dev); + + lp->reset_in_progress = 1; + netif_stop_queue(dev); + netif_carrier_off(dev); + schedule_work(&lp->reset_work); /* get out of the interrupt handler! */ - break; + goto out; } /* RX is inhibited - we must have received something. * Prepare to receive into the next buffer. @@ -1052,6 +1109,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) udelay(1); lp->hw.intmask(dev, lp->intmask); +out: spin_unlock_irqrestore(&lp->lock, flags); return retval; } diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c index f983c4ce6b07f..be618e4b9ed5e 100644 --- a/drivers/net/arcnet/com20020-isa.c +++ b/drivers/net/arcnet/com20020-isa.c @@ -169,7 +169,7 @@ static int __init com20020_init(void) dev->irq = 9; if (com20020isa_probe(dev)) { - free_netdev(dev); + free_arcdev(dev); return -EIO; } @@ -182,7 +182,7 @@ static void __exit com20020_exit(void) unregister_netdev(my_dev); free_irq(my_dev->irq, my_dev); release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE); - free_netdev(my_dev); + free_arcdev(my_dev); } #ifndef MODULE diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index eb7f76753c9c0..8bdc44b7e09a1 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -291,7 +291,7 @@ static void com20020pci_remove(struct pci_dev *pdev) unregister_netdev(dev); free_irq(dev->irq, dev); - free_netdev(dev); + free_arcdev(dev); } } diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c index cf607ffcf358e..9cc5eb6a8e905 100644 --- a/drivers/net/arcnet/com20020_cs.c +++ b/drivers/net/arcnet/com20020_cs.c @@ -177,7 +177,7 @@ static void com20020_detach(struct pcmcia_device *link) dev = info->dev; if (dev) { dev_dbg(&link->dev, "kfree...\n"); - free_netdev(dev); + free_arcdev(dev); } dev_dbg(&link->dev, "kfree2...\n"); kfree(info); diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c index cf214b7306715..3856b447d38ed 100644 --- a/drivers/net/arcnet/com90io.c +++ b/drivers/net/arcnet/com90io.c @@ -396,7 +396,7 @@ static int __init com90io_init(void) err = com90io_probe(dev); if (err) { - free_netdev(dev); + free_arcdev(dev); return err; } @@ -419,7 +419,7 @@ static void __exit com90io_exit(void) free_irq(dev->irq, dev); release_region(dev->base_addr, ARCNET_TOTAL_SIZE); - free_netdev(dev); + free_arcdev(dev); } module_init(com90io_init) diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c index 3dc3d533cb19a..d8dfb9ea0de89 100644 --- a/drivers/net/arcnet/com90xx.c +++ b/drivers/net/arcnet/com90xx.c @@ -554,7 +554,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, err_release_mem: release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); err_free_dev: - free_netdev(dev); + free_arcdev(dev); return -EIO; } @@ -672,7 +672,7 @@ static void __exit com90xx_exit(void) release_region(dev->base_addr, ARCNET_TOTAL_SIZE); release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); - free_netdev(dev); + free_arcdev(dev); } } -- GitLab From 8d520b4de3edca4f4fb242b5ddc659b6a9b9e65e Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 28 Jan 2021 23:01:54 +0100 Subject: [PATCH 0841/1084] r8169: work around RTL8125 UDP hw bug It was reported that on RTL8125 network breaks under heavy UDP load, e.g. torrent traffic ([0], from comment 27). Realtek confirmed a hw bug and provided me with a test version of the r8125 driver including a workaround. Tests confirmed that the workaround fixes the issue. I modified the original version of the workaround to meet mainline code style. [0] https://bugzilla.kernel.org/show_bug.cgi?id=209839 v2: - rebased to net v3: - make rtl_skb_is_udp() more robust and use skb_header_pointer() to access the ip(v6) header v4: - remove dependency on ptp_classify.h - replace magic number with offsetof(struct udphdr, len) Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125") Tested-by: xplo Signed-off-by: Heiner Kallweit Acked-by: Willem de Bruijn Link: https://lore.kernel.org/r/6e453d49-1801-e6de-d5f7-d7e6c7526c8f@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/realtek/r8169_main.c | 71 +++++++++++++++++++++-- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index a569abe7f5ef2..f2269c9f5f055 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -4046,17 +4046,72 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, return -EIO; } -static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp) +static bool rtl_skb_is_udp(struct sk_buff *skb) +{ + int no = skb_network_offset(skb); + struct ipv6hdr *i6h, _i6h; + struct iphdr *ih, _ih; + + switch (vlan_get_protocol(skb)) { + case htons(ETH_P_IP): + ih = skb_header_pointer(skb, no, sizeof(_ih), &_ih); + return ih && ih->protocol == IPPROTO_UDP; + case htons(ETH_P_IPV6): + i6h = skb_header_pointer(skb, no, sizeof(_i6h), &_i6h); + return i6h && i6h->nexthdr == IPPROTO_UDP; + default: + return false; + } +} + +#define RTL_MIN_PATCH_LEN 47 + +/* see rtl8125_get_patch_pad_len() in r8125 vendor driver */ +static unsigned int rtl8125_quirk_udp_padto(struct rtl8169_private *tp, + struct sk_buff *skb) { + unsigned int padto = 0, len = skb->len; + + if (rtl_is_8125(tp) && len < 128 + RTL_MIN_PATCH_LEN && + rtl_skb_is_udp(skb) && skb_transport_header_was_set(skb)) { + unsigned int trans_data_len = skb_tail_pointer(skb) - + skb_transport_header(skb); + + if (trans_data_len >= offsetof(struct udphdr, len) && + trans_data_len < RTL_MIN_PATCH_LEN) { + u16 dest = ntohs(udp_hdr(skb)->dest); + + /* dest is a standard PTP port */ + if (dest == 319 || dest == 320) + padto = len + RTL_MIN_PATCH_LEN - trans_data_len; + } + + if (trans_data_len < sizeof(struct udphdr)) + padto = max_t(unsigned int, padto, + len + sizeof(struct udphdr) - trans_data_len); + } + + return padto; +} + +static unsigned int rtl_quirk_packet_padto(struct rtl8169_private *tp, + struct sk_buff *skb) +{ + unsigned int padto; + + padto = rtl8125_quirk_udp_padto(tp, skb); + switch (tp->mac_version) { case RTL_GIGA_MAC_VER_34: case RTL_GIGA_MAC_VER_60: case RTL_GIGA_MAC_VER_61: case RTL_GIGA_MAC_VER_63: - return true; + padto = max_t(unsigned int, padto, ETH_ZLEN); default: - return false; + break; } + + return padto; } static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts) @@ -4128,9 +4183,10 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, opts[1] |= transport_offset << TCPHO_SHIFT; } else { - if (unlikely(skb->len < ETH_ZLEN && rtl_test_hw_pad_bug(tp))) - /* eth_skb_pad would free the skb on error */ - return !__skb_put_padto(skb, ETH_ZLEN, false); + unsigned int padto = rtl_quirk_packet_padto(tp, skb); + + /* skb_padto would free the skb on error */ + return !__skb_put_padto(skb, padto, false); } return true; @@ -4307,6 +4363,9 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb, if (skb->len < ETH_ZLEN) features &= ~NETIF_F_CSUM_MASK; + if (rtl_quirk_packet_padto(tp, skb)) + features &= ~NETIF_F_CSUM_MASK; + if (transport_offset > TCPHO_MAX && rtl_chip_supports_csum_v2(tp)) features &= ~NETIF_F_CSUM_MASK; -- GitLab From 5399d52233c47905bbf97dcbaa2d7a9cc31670ba Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 29 Jan 2021 23:53:50 +0000 Subject: [PATCH 0842/1084] rxrpc: Fix deadlock around release of dst cached on udp tunnel AF_RXRPC sockets use UDP ports in encap mode. This causes socket and dst from an incoming packet to get stolen and attached to the UDP socket from whence it is leaked when that socket is closed. When a network namespace is removed, the wait for dst records to be cleaned up happens before the cleanup of the rxrpc and UDP socket, meaning that the wait never finishes. Fix this by moving the rxrpc (and, by dependence, the afs) private per-network namespace registrations to the device group rather than subsys group. This allows cached rxrpc local endpoints to be cleared and their UDP sockets closed before we try waiting for the dst records. The symptom is that lines looking like the following: unregister_netdevice: waiting for lo to become free get emitted at regular intervals after running something like the referenced syzbot test. Thanks to Vadim for tracking this down and work out the fix. Reported-by: syzbot+df400f2f24a1677cd7e0@syzkaller.appspotmail.com Reported-by: Vadim Fedorenko Fixes: 5271953cad31 ("rxrpc: Use the UDP encap_rcv hook") Signed-off-by: David Howells Acked-by: Vadim Fedorenko Link: https://lore.kernel.org/r/161196443016.3868642.5577440140646403533.stgit@warthog.procyon.org.uk Signed-off-by: Jakub Kicinski --- fs/afs/main.c | 6 +++--- net/rxrpc/af_rxrpc.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/afs/main.c b/fs/afs/main.c index accdd8970e7c0..b2975256dadbd 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c @@ -193,7 +193,7 @@ static int __init afs_init(void) goto error_cache; #endif - ret = register_pernet_subsys(&afs_net_ops); + ret = register_pernet_device(&afs_net_ops); if (ret < 0) goto error_net; @@ -213,7 +213,7 @@ static int __init afs_init(void) error_proc: afs_fs_exit(); error_fs: - unregister_pernet_subsys(&afs_net_ops); + unregister_pernet_device(&afs_net_ops); error_net: #ifdef CONFIG_AFS_FSCACHE fscache_unregister_netfs(&afs_cache_netfs); @@ -244,7 +244,7 @@ static void __exit afs_exit(void) proc_remove(afs_proc_symlink); afs_fs_exit(); - unregister_pernet_subsys(&afs_net_ops); + unregister_pernet_device(&afs_net_ops); #ifdef CONFIG_AFS_FSCACHE fscache_unregister_netfs(&afs_cache_netfs); #endif diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 0a2f4817ec6cf..41671af6b33f9 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -990,7 +990,7 @@ static int __init af_rxrpc_init(void) goto error_security; } - ret = register_pernet_subsys(&rxrpc_net_ops); + ret = register_pernet_device(&rxrpc_net_ops); if (ret) goto error_pernet; @@ -1035,7 +1035,7 @@ static int __init af_rxrpc_init(void) error_sock: proto_unregister(&rxrpc_proto); error_proto: - unregister_pernet_subsys(&rxrpc_net_ops); + unregister_pernet_device(&rxrpc_net_ops); error_pernet: rxrpc_exit_security(); error_security: @@ -1057,7 +1057,7 @@ static void __exit af_rxrpc_exit(void) unregister_key_type(&key_type_rxrpc); sock_unregister(PF_RXRPC); proto_unregister(&rxrpc_proto); - unregister_pernet_subsys(&rxrpc_net_ops); + unregister_pernet_device(&rxrpc_net_ops); ASSERTCMP(atomic_read(&rxrpc_n_tx_skbs), ==, 0); ASSERTCMP(atomic_read(&rxrpc_n_rx_skbs), ==, 0); -- GitLab From 344717a14cd7272f88346022a77742323346299e Mon Sep 17 00:00:00 2001 From: Ravi Bangoria Date: Fri, 29 Jan 2021 12:47:45 +0530 Subject: [PATCH 0843/1084] powerpc/sstep: Fix array out of bound warning Compiling kernel with -Warray-bounds throws below warning: In function 'emulate_vsx_store': warning: array subscript is above array bounds [-Warray-bounds] buf.d[2] = byterev_8(reg->d[1]); ~~~~~^~~ buf.d[3] = byterev_8(reg->d[0]); ~~~~~^~~ Fix it by using temporary array variable 'union vsx_reg buf32[]' in that code block. Also, with element_size = 32, 'union vsx_reg *reg' is an array of size 2. So, use 'reg' as an array instead of pointer in the same code block. Fixes: af99da74333b ("powerpc/sstep: Support VSX vector paired storage access instructions") Suggested-by: Naveen N. Rao Signed-off-by: Ravi Bangoria Tested-by: Naveen N. Rao Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210129071745.111466-1-ravi.bangoria@linux.ibm.com --- arch/powerpc/lib/sstep.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index bf7a7d62ae8b5..ede093e962347 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -818,13 +818,15 @@ void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, break; if (rev) { /* reverse 32 bytes */ - buf.d[0] = byterev_8(reg->d[3]); - buf.d[1] = byterev_8(reg->d[2]); - buf.d[2] = byterev_8(reg->d[1]); - buf.d[3] = byterev_8(reg->d[0]); - reg = &buf; + union vsx_reg buf32[2]; + buf32[0].d[0] = byterev_8(reg[1].d[1]); + buf32[0].d[1] = byterev_8(reg[1].d[0]); + buf32[1].d[0] = byterev_8(reg[0].d[1]); + buf32[1].d[1] = byterev_8(reg[0].d[0]); + memcpy(mem, buf32, size); + } else { + memcpy(mem, reg, size); } - memcpy(mem, reg, size); break; case 16: /* stxv, stxvx, stxvl, stxvll */ -- GitLab From bce74491c3008e27dd6e8f79a83b4faa77a08f7e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Dec 2020 02:11:41 +0900 Subject: [PATCH 0844/1084] powerpc/vdso: fix unnecessary rebuilds of vgettimeofday.o vgettimeofday.o is unnecessarily rebuilt. Adding it to 'targets' is not enough to fix the issue. Kbuild is correctly rebuilding it because the command line is changed. PowerPC builds each vdso directory twice; first in vdso_prepare to generate vdso{32,64}-offsets.h, second as part of the ordinary build process to embed vdso{32,64}.so.dbg into the kernel. The problem shows up when CONFIG_PPC_WERROR=y due to the following line in arch/powerpc/Kbuild: subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror In the preparation stage, Kbuild directly visits the vdso directories, hence it does not inherit subdir-ccflags-y. In the second descend, Kbuild adds -Werror, which results in the command line flipping with/without -Werror. It implies a potential danger; if a more critical flag that would impact the resulted vdso, the offsets recorded in the headers might be different from real offsets in the embedded vdso images. Removing the unneeded second descend solves the problem. Reported-by: Michael Ellerman Signed-off-by: Masahiro Yamada Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/linuxppc-dev/87tuslxhry.fsf@mpe.ellerman.id.au/ Link: https://lore.kernel.org/r/20201223171142.707053-1-masahiroy@kernel.org --- arch/powerpc/kernel/Makefile | 4 ++-- arch/powerpc/kernel/vdso32/Makefile | 5 +---- arch/powerpc/kernel/{vdso32 => }/vdso32_wrapper.S | 0 arch/powerpc/kernel/vdso64/Makefile | 6 +----- arch/powerpc/kernel/{vdso64 => }/vdso64_wrapper.S | 0 5 files changed, 4 insertions(+), 11 deletions(-) rename arch/powerpc/kernel/{vdso32 => }/vdso32_wrapper.S (100%) rename arch/powerpc/kernel/{vdso64 => }/vdso64_wrapper.S (100%) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index fe2ef598e2ead..79ee7750937db 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -51,7 +51,7 @@ obj-y += ptrace/ obj-$(CONFIG_PPC64) += setup_64.o \ paca.o nvram_64.o note.o syscall_64.o obj-$(CONFIG_COMPAT) += sys_ppc32.o signal_32.o -obj-$(CONFIG_VDSO32) += vdso32/ +obj-$(CONFIG_VDSO32) += vdso32_wrapper.o obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_PPC_DAWR) += dawr.o @@ -60,7 +60,7 @@ obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o obj-$(CONFIG_PPC_BARRIER_NOSPEC) += security.o -obj-$(CONFIG_PPC64) += vdso64/ +obj-$(CONFIG_PPC64) += vdso64_wrapper.o obj-$(CONFIG_ALTIVEC) += vecemu.o obj-$(CONFIG_PPC_BOOK3S_IDLE) += idle_book3s.o procfs-y := proc_powerpc.o diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index 9cb6f524854b9..7d9a6fee0e3dc 100644 --- a/arch/powerpc/kernel/vdso32/Makefile +++ b/arch/powerpc/kernel/vdso32/Makefile @@ -30,7 +30,7 @@ CC32FLAGS += -m32 KBUILD_CFLAGS := $(filter-out -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc,$(KBUILD_CFLAGS)) endif -targets := $(obj-vdso32) vdso32.so.dbg +targets := $(obj-vdso32) vdso32.so.dbg vgettimeofday.o obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) GCOV_PROFILE := n @@ -46,9 +46,6 @@ obj-y += vdso32_wrapper.o targets += vdso32.lds CPPFLAGS_vdso32.lds += -P -C -Upowerpc -# Force dependency (incbin is bad) -$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so.dbg - # link rule for the .so file, .lds has to be first $(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday.o FORCE $(call if_changed,vdso32ld_and_check) diff --git a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S b/arch/powerpc/kernel/vdso32_wrapper.S similarity index 100% rename from arch/powerpc/kernel/vdso32/vdso32_wrapper.S rename to arch/powerpc/kernel/vdso32_wrapper.S diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile index bf363ff371521..a06fb9b461fc7 100644 --- a/arch/powerpc/kernel/vdso64/Makefile +++ b/arch/powerpc/kernel/vdso64/Makefile @@ -17,7 +17,7 @@ endif # Build rules -targets := $(obj-vdso64) vdso64.so.dbg +targets := $(obj-vdso64) vdso64.so.dbg vgettimeofday.o obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64)) GCOV_PROFILE := n @@ -29,15 +29,11 @@ ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ -Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both asflags-y := -D__VDSO64__ -s -obj-y += vdso64_wrapper.o targets += vdso64.lds CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) $(obj)/vgettimeofday.o: %.o: %.c FORCE -# Force dependency (incbin is bad) -$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so.dbg - # link rule for the .so file, .lds has to be first $(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday.o FORCE $(call if_changed,vdso64ld_and_check) diff --git a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S b/arch/powerpc/kernel/vdso64_wrapper.S similarity index 100% rename from arch/powerpc/kernel/vdso64/vdso64_wrapper.S rename to arch/powerpc/kernel/vdso64_wrapper.S -- GitLab From 66f0a9e058fad50e569ad752be72e52701991fd5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 24 Dec 2020 02:11:42 +0900 Subject: [PATCH 0845/1084] powerpc/vdso64: remove meaningless vgettimeofday.o build rule VDSO64 is only built for the 64-bit kernel, hence vgettimeofday.o is built by the generic rule in scripts/Makefile.build. This line does not provide anything useful. Signed-off-by: Masahiro Yamada Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20201223171142.707053-2-masahiroy@kernel.org --- arch/powerpc/kernel/vdso64/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile index a06fb9b461fc7..2813e3f98db65 100644 --- a/arch/powerpc/kernel/vdso64/Makefile +++ b/arch/powerpc/kernel/vdso64/Makefile @@ -32,8 +32,6 @@ asflags-y := -D__VDSO64__ -s targets += vdso64.lds CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) -$(obj)/vgettimeofday.o: %.o: %.c FORCE - # link rule for the .so file, .lds has to be first $(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday.o FORCE $(call if_changed,vdso64ld_and_check) -- GitLab From aa880c6f3ee6dbd0d5ab02026a514ff8ea0a3328 Mon Sep 17 00:00:00 2001 From: Zyta Szpak Date: Thu, 21 Jan 2021 16:52:37 +0100 Subject: [PATCH 0846/1084] arm64: dts: ls1046a: fix dcfg address range Dcfg was overlapping with clockgen address space which resulted in failure in memory allocation for dcfg. According regs description dcfg size should not be bigger than 4KB. Signed-off-by: Zyta Szpak Fixes: 8126d88162a5 ("arm64: dts: add QorIQ LS1046A SoC support") Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index 025e1f5876627..565934cbfa280 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -385,7 +385,7 @@ dcfg: dcfg@1ee0000 { compatible = "fsl,ls1046a-dcfg", "syscon"; - reg = <0x0 0x1ee0000 0x0 0x10000>; + reg = <0x0 0x1ee0000 0x0 0x1000>; big-endian; }; -- GitLab From eb4e8fac00d1e01ada5e57c05d24739156086677 Mon Sep 17 00:00:00 2001 From: Chinmay Agarwal Date: Wed, 27 Jan 2021 22:24:54 +0530 Subject: [PATCH 0847/1084] neighbour: Prevent a dead entry from updating gc_list Following race condition was detected: - neigh_flush_dev() is under execution and calls neigh_mark_dead(n) marking the neighbour entry 'n' as dead. - Executing: __netif_receive_skb() -> __netif_receive_skb_core() -> arp_rcv() -> arp_process().arp_process() calls __neigh_lookup() which takes a reference on neighbour entry 'n'. - Moves further along neigh_flush_dev() and calls neigh_cleanup_and_release(n), but since reference count increased in t2, 'n' couldn't be destroyed. - Moves further along, arp_process() and calls neigh_update()-> __neigh_update() -> neigh_update_gc_list(), which adds the neighbour entry back in gc_list(neigh_mark_dead(), removed it earlier in t0 from gc_list) - arp_process() finally calls neigh_release(n), destroying the neighbour entry. This leads to 'n' still being part of gc_list, but the actual neighbour structure has been freed. The situation can be prevented from happening if we disallow a dead entry to have any possibility of updating gc_list. This is what the patch intends to achieve. Fixes: 9c29a2f55ec0 ("neighbor: Fix locking order for gc_list changes") Signed-off-by: Chinmay Agarwal Reviewed-by: Cong Wang Reviewed-by: David Ahern Link: https://lore.kernel.org/r/20210127165453.GA20514@chinagar-linux.qualcomm.com Signed-off-by: Jakub Kicinski --- net/core/neighbour.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 277ed854aef1c..6d2d557442dc6 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1245,13 +1245,14 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr, old = neigh->nud_state; err = -EPERM; - if (!(flags & NEIGH_UPDATE_F_ADMIN) && - (old & (NUD_NOARP | NUD_PERMANENT))) - goto out; if (neigh->dead) { NL_SET_ERR_MSG(extack, "Neighbor entry is now dead"); + new = old; goto out; } + if (!(flags & NEIGH_UPDATE_F_ADMIN) && + (old & (NUD_NOARP | NUD_PERMANENT))) + goto out; ext_learn_change = neigh_update_ext_learned(neigh, flags, ¬ify); -- GitLab From 4e04b11800194f2ec756b5f3e9f2e559df5a0b1e Mon Sep 17 00:00:00 2001 From: Zheng Yongjun Date: Wed, 16 Dec 2020 21:16:53 +0800 Subject: [PATCH 0848/1084] leds: leds-lm3533: convert comma to semicolon Replace a comma between expression statements by a semicolon. Signed-off-by: Zheng Yongjun Signed-off-by: Pavel Machek --- drivers/leds/leds-lm3533.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c index b3edee7031931..9dd205870525c 100644 --- a/drivers/leds/leds-lm3533.c +++ b/drivers/leds/leds-lm3533.c @@ -679,7 +679,7 @@ static int lm3533_led_probe(struct platform_device *pdev) led->cdev.brightness_get = lm3533_led_get; led->cdev.blink_set = lm3533_led_blink_set; led->cdev.brightness = LED_OFF; - led->cdev.groups = lm3533_led_attribute_groups, + led->cdev.groups = lm3533_led_attribute_groups; led->id = pdev->id; mutex_init(&led->mutex); -- GitLab From 47854d2d2ba8f100c419557a7d9d8f155c0a1064 Mon Sep 17 00:00:00 2001 From: Zheng Yongjun Date: Mon, 14 Dec 2020 21:45:45 +0800 Subject: [PATCH 0849/1084] leds: leds-ariel: convert comma to semicolon Replace a comma between expression statements by a semicolon. Signed-off-by: Zheng Yongjun Reviewed-by: Alexander Dahl Signed-off-by: Pavel Machek --- drivers/leds/leds-ariel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/leds/leds-ariel.c b/drivers/leds/leds-ariel.c index bb68ba23a7d44..49e1bddaa15e0 100644 --- a/drivers/leds/leds-ariel.c +++ b/drivers/leds/leds-ariel.c @@ -96,14 +96,14 @@ static int ariel_led_probe(struct platform_device *pdev) return -ENOMEM; leds[0].ec_index = EC_BLUE_LED; - leds[0].led_cdev.name = "blue:power", + leds[0].led_cdev.name = "blue:power"; leds[0].led_cdev.default_trigger = "default-on"; leds[1].ec_index = EC_AMBER_LED; - leds[1].led_cdev.name = "amber:status", + leds[1].led_cdev.name = "amber:status"; leds[2].ec_index = EC_GREEN_LED; - leds[2].led_cdev.name = "green:status", + leds[2].led_cdev.name = "green:status"; leds[2].led_cdev.default_trigger = "default-on"; for (i = 0; i < NLEDS; i++) { -- GitLab From 27af8e2c90fba242460b01fa020e6e19ed68c495 Mon Sep 17 00:00:00 2001 From: Andrea Righi Date: Wed, 25 Nov 2020 16:18:22 +0100 Subject: [PATCH 0850/1084] leds: trigger: fix potential deadlock with libata We have the following potential deadlock condition: ======================================================== WARNING: possible irq lock inversion dependency detected 5.10.0-rc2+ #25 Not tainted -------------------------------------------------------- swapper/3/0 just changed the state of lock: ffff8880063bd618 (&host->lock){-...}-{2:2}, at: ata_bmdma_interrupt+0x27/0x200 but this lock took another, HARDIRQ-READ-unsafe lock in the past: (&trig->leddev_list_lock){.+.?}-{2:2} and interrupts could create inverse lock ordering between them. other info that might help us debug this: Possible interrupt unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&trig->leddev_list_lock); local_irq_disable(); lock(&host->lock); lock(&trig->leddev_list_lock); lock(&host->lock); *** DEADLOCK *** no locks held by swapper/3/0. the shortest dependencies between 2nd lock and 1st lock: -> (&trig->leddev_list_lock){.+.?}-{2:2} ops: 46 { HARDIRQ-ON-R at: lock_acquire+0x15f/0x420 _raw_read_lock+0x42/0x90 led_trigger_event+0x2b/0x70 rfkill_global_led_trigger_worker+0x94/0xb0 process_one_work+0x240/0x560 worker_thread+0x58/0x3d0 kthread+0x151/0x170 ret_from_fork+0x1f/0x30 IN-SOFTIRQ-R at: lock_acquire+0x15f/0x420 _raw_read_lock+0x42/0x90 led_trigger_event+0x2b/0x70 kbd_bh+0x9e/0xc0 tasklet_action_common.constprop.0+0xe9/0x100 tasklet_action+0x22/0x30 __do_softirq+0xcc/0x46d run_ksoftirqd+0x3f/0x70 smpboot_thread_fn+0x116/0x1f0 kthread+0x151/0x170 ret_from_fork+0x1f/0x30 SOFTIRQ-ON-R at: lock_acquire+0x15f/0x420 _raw_read_lock+0x42/0x90 led_trigger_event+0x2b/0x70 rfkill_global_led_trigger_worker+0x94/0xb0 process_one_work+0x240/0x560 worker_thread+0x58/0x3d0 kthread+0x151/0x170 ret_from_fork+0x1f/0x30 INITIAL READ USE at: lock_acquire+0x15f/0x420 _raw_read_lock+0x42/0x90 led_trigger_event+0x2b/0x70 rfkill_global_led_trigger_worker+0x94/0xb0 process_one_work+0x240/0x560 worker_thread+0x58/0x3d0 kthread+0x151/0x170 ret_from_fork+0x1f/0x30 } ... key at: [] __key.0+0x0/0x10 ... acquired at: _raw_read_lock+0x42/0x90 led_trigger_blink_oneshot+0x3b/0x90 ledtrig_disk_activity+0x3c/0xa0 ata_qc_complete+0x26/0x450 ata_do_link_abort+0xa3/0xe0 ata_port_freeze+0x2e/0x40 ata_hsm_qc_complete+0x94/0xa0 ata_sff_hsm_move+0x177/0x7a0 ata_sff_pio_task+0xc7/0x1b0 process_one_work+0x240/0x560 worker_thread+0x58/0x3d0 kthread+0x151/0x170 ret_from_fork+0x1f/0x30 -> (&host->lock){-...}-{2:2} ops: 69 { IN-HARDIRQ-W at: lock_acquire+0x15f/0x420 _raw_spin_lock_irqsave+0x52/0xa0 ata_bmdma_interrupt+0x27/0x200 __handle_irq_event_percpu+0xd5/0x2b0 handle_irq_event+0x57/0xb0 handle_edge_irq+0x8c/0x230 asm_call_irq_on_stack+0xf/0x20 common_interrupt+0x100/0x1c0 asm_common_interrupt+0x1e/0x40 native_safe_halt+0xe/0x10 arch_cpu_idle+0x15/0x20 default_idle_call+0x59/0x1c0 do_idle+0x22c/0x2c0 cpu_startup_entry+0x20/0x30 start_secondary+0x11d/0x150 secondary_startup_64_no_verify+0xa6/0xab INITIAL USE at: lock_acquire+0x15f/0x420 _raw_spin_lock_irqsave+0x52/0xa0 ata_dev_init+0x54/0xe0 ata_link_init+0x8b/0xd0 ata_port_alloc+0x1f1/0x210 ata_host_alloc+0xf1/0x130 ata_host_alloc_pinfo+0x14/0xb0 ata_pci_sff_prepare_host+0x41/0xa0 ata_pci_bmdma_prepare_host+0x14/0x30 piix_init_one+0x21f/0x600 local_pci_probe+0x48/0x80 pci_device_probe+0x105/0x1c0 really_probe+0x221/0x490 driver_probe_device+0xe9/0x160 device_driver_attach+0xb2/0xc0 __driver_attach+0x91/0x150 bus_for_each_dev+0x81/0xc0 driver_attach+0x1e/0x20 bus_add_driver+0x138/0x1f0 driver_register+0x91/0xf0 __pci_register_driver+0x73/0x80 piix_init+0x1e/0x2e do_one_initcall+0x5f/0x2d0 kernel_init_freeable+0x26f/0x2cf kernel_init+0xe/0x113 ret_from_fork+0x1f/0x30 } ... key at: [] __key.6+0x0/0x10 ... acquired at: __lock_acquire+0x9da/0x2370 lock_acquire+0x15f/0x420 _raw_spin_lock_irqsave+0x52/0xa0 ata_bmdma_interrupt+0x27/0x200 __handle_irq_event_percpu+0xd5/0x2b0 handle_irq_event+0x57/0xb0 handle_edge_irq+0x8c/0x230 asm_call_irq_on_stack+0xf/0x20 common_interrupt+0x100/0x1c0 asm_common_interrupt+0x1e/0x40 native_safe_halt+0xe/0x10 arch_cpu_idle+0x15/0x20 default_idle_call+0x59/0x1c0 do_idle+0x22c/0x2c0 cpu_startup_entry+0x20/0x30 start_secondary+0x11d/0x150 secondary_startup_64_no_verify+0xa6/0xab This lockdep splat is reported after: commit e918188611f0 ("locking: More accurate annotations for read_lock()") To clarify: - read-locks are recursive only in interrupt context (when in_interrupt() returns true) - after acquiring host->lock in CPU1, another cpu (i.e. CPU2) may call write_lock(&trig->leddev_list_lock) that would be blocked by CPU0 that holds trig->leddev_list_lock in read-mode - when CPU1 (ata_ac_complete()) tries to read-lock trig->leddev_list_lock, it would be blocked by the write-lock waiter on CPU2 (because we are not in interrupt context, so the read-lock is not recursive) - at this point if an interrupt happens on CPU0 and ata_bmdma_interrupt() is executed it will try to acquire host->lock, that is held by CPU1, that is currently blocked by CPU2, so: * CPU0 blocked by CPU1 * CPU1 blocked by CPU2 * CPU2 blocked by CPU0 *** DEADLOCK *** The deadlock scenario is better represented by the following schema (thanks to Boqun Feng for the schema and the detailed explanation of the deadlock condition): CPU 0: CPU 1: CPU 2: ----- ----- ----- led_trigger_event(): read_lock(&trig->leddev_list_lock); ata_hsm_qc_complete(): spin_lock_irqsave(&host->lock); write_lock(&trig->leddev_list_lock); ata_port_freeze(): ata_do_link_abort(): ata_qc_complete(): ledtrig_disk_activity(): led_trigger_blink_oneshot(): read_lock(&trig->leddev_list_lock); // ^ not in in_interrupt() context, so could get blocked by CPU 2 ata_bmdma_interrupt(): spin_lock_irqsave(&host->lock); Fix by using read_lock_irqsave/irqrestore() in led_trigger_event(), so that no interrupt can happen in between, preventing the deadlock condition. Apply the same change to led_trigger_blink_setup() as well, since the same deadlock scenario can also happen in power_supply_update_bat_leds() -> led_trigger_blink() -> led_trigger_blink_setup() (workqueue context), and potentially prevent other similar usages. Link: https://lore.kernel.org/lkml/20201101092614.GB3989@xps-13-7390/ Fixes: eb25cb9956cc ("leds: convert IDE trigger to common disk trigger") Signed-off-by: Andrea Righi Signed-off-by: Pavel Machek --- drivers/leds/led-triggers.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 91da90cfb11d9..4e7b78a84149b 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -378,14 +378,15 @@ void led_trigger_event(struct led_trigger *trig, enum led_brightness brightness) { struct led_classdev *led_cdev; + unsigned long flags; if (!trig) return; - read_lock(&trig->leddev_list_lock); + read_lock_irqsave(&trig->leddev_list_lock, flags); list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) led_set_brightness(led_cdev, brightness); - read_unlock(&trig->leddev_list_lock); + read_unlock_irqrestore(&trig->leddev_list_lock, flags); } EXPORT_SYMBOL_GPL(led_trigger_event); @@ -396,11 +397,12 @@ static void led_trigger_blink_setup(struct led_trigger *trig, int invert) { struct led_classdev *led_cdev; + unsigned long flags; if (!trig) return; - read_lock(&trig->leddev_list_lock); + read_lock_irqsave(&trig->leddev_list_lock, flags); list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) { if (oneshot) led_blink_set_oneshot(led_cdev, delay_on, delay_off, @@ -408,7 +410,7 @@ static void led_trigger_blink_setup(struct led_trigger *trig, else led_blink_set(led_cdev, delay_on, delay_off); } - read_unlock(&trig->leddev_list_lock); + read_unlock_irqrestore(&trig->leddev_list_lock, flags); } void led_trigger_blink(struct led_trigger *trig, -- GitLab From c8283eb79d879ef898f4224ba30e554f83904b0a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 3 Jan 2021 00:15:09 +0100 Subject: [PATCH 0851/1084] dt-bindings: leds: Add DT binding for Richtek RT8515 Add a YAML devicetree binding for the Richtek RT8515 dual channel flash/torch LED driver. Cc: Sakari Ailus Cc: newbytee@protonmail.com Cc: Stephan Gerhold Cc: phone-devel@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: devicetree@vger.kernel.org Reviewed-by: Rob Herring Reviewed-by: Sakari Ailus Signed-off-by: Linus Walleij Signed-off-by: Pavel Machek --- .../bindings/leds/richtek,rt8515.yaml | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/richtek,rt8515.yaml diff --git a/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml b/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml new file mode 100644 index 0000000000000..68c328eec03be --- /dev/null +++ b/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml @@ -0,0 +1,111 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/richtek,rt8515.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Richtek RT8515 1.5A dual channel LED driver + +maintainers: + - Linus Walleij + +description: | + The Richtek RT8515 is a dual channel (two mode) LED driver that + supports driving a white LED in flash or torch mode. The maximum + current for each mode is defined in hardware using two resistors + RFS and RTS. + +properties: + compatible: + const: richtek,rt8515 + + enf-gpios: + maxItems: 1 + description: A connection to the 'ENF' (enable flash) pin. + + ent-gpios: + maxItems: 1 + description: A connection to the 'ENT' (enable torch) pin. + + richtek,rfs-ohms: + minimum: 7680 + maximum: 367000 + description: The resistance value of the RFS resistor. This + resistors limits the maximum flash current. This must be set + for the property flash-max-microamp to work, the RFS resistor + defines the range of the dimmer setting (brightness) of the + flash LED. + + richtek,rts-ohms: + minimum: 7680 + maximum: 367000 + description: The resistance value of the RTS resistor. This + resistors limits the maximum torch current. This must be set + for the property torch-max-microamp to work, the RTS resistor + defines the range of the dimmer setting (brightness) of the + torch LED. + + led: + type: object + $ref: common.yaml# + properties: + function: true + color: true + flash-max-timeout-us: true + + flash-max-microamp: + maximum: 700000 + description: The maximum current for flash mode + is hardwired to the component using the RFS resistor to + ground. The maximum hardware current setting is calculated + according to the formula Imax = 5500 / RFS. The lowest + allowed resistance value is 7.86 kOhm giving an absolute + maximum current of 700mA. By setting this attribute in + the device tree, you can further restrict the maximum + current below the hardware limit. This requires the RFS + to be defined as it defines the maximum range. + + led-max-microamp: + maximum: 700000 + description: The maximum current for torch mode + is hardwired to the component using the RTS resistor to + ground. The maximum hardware current setting is calculated + according to the formula Imax = 5500 / RTS. The lowest + allowed resistance value is 7.86 kOhm giving an absolute + maximum current of 700mA. By setting this attribute in + the device tree, you can further restrict the maximum + current below the hardware limit. This requires the RTS + to be defined as it defines the maximum range. + + additionalProperties: false + +required: + - compatible + - ent-gpios + - enf-gpios + - led + +additionalProperties: false + +examples: + - | + #include + #include + + led-controller { + compatible = "richtek,rt8515"; + enf-gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>; + ent-gpios = <&gpio4 13 GPIO_ACTIVE_HIGH>; + richtek,rfs-ohms = <16000>; + richtek,rts-ohms = <100000>; + + led { + function = LED_FUNCTION_FLASH; + color = ; + flash-max-timeout-us = <250000>; + flash-max-microamp = <150000>; + led-max-microamp = <25000>; + }; + }; + +... -- GitLab From e1c6edcbea13de025c3406645b4cce4ac3baf973 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 3 Jan 2021 00:15:10 +0100 Subject: [PATCH 0852/1084] leds: rt8515: Add Richtek RT8515 LED driver This adds a driver for the Richtek RT8515 dual channel torch/flash white LED driver. This LED driver is found in some mobile phones from Samsung such as the GT-S7710 and GT-I8190. A V4L interface is added. We do not have a proper datasheet for the RT8515 but it turns out that RT9387A has a public datasheet and is essentially the same chip. We designed the driver in accordance with this datasheet. The day someone needs to drive a RT9387A this driver can probably easily be augmented to handle that chip too. Sakari Ailus, Pavel Machek and Andy Shevchenko helped significantly in getting this driver right. Cc: Sakari Ailus Cc: newbytee@protonmail.com Cc: Stephan Gerhold Cc: linux-media@vger.kernel.org Cc: phone-devel@vger.kernel.org Reviewed-by: Sakari Ailus Signed-off-by: Linus Walleij Signed-off-by: Pavel Machek --- drivers/leds/Kconfig | 3 + drivers/leds/Makefile | 3 + drivers/leds/flash/Kconfig | 15 ++ drivers/leds/flash/Makefile | 3 + drivers/leds/flash/leds-rt8515.c | 397 +++++++++++++++++++++++++++++++ 5 files changed, 421 insertions(+) create mode 100644 drivers/leds/flash/Kconfig create mode 100644 drivers/leds/flash/Makefile create mode 100644 drivers/leds/flash/leds-rt8515.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 849d3c5f908e4..6c1d8b69a465a 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -928,6 +928,9 @@ config LEDS_ACER_A500 This option enables support for the Power Button LED of Acer Iconia Tab A500. +comment "Flash and Torch LED drivers" +source "drivers/leds/flash/Kconfig" + comment "LED Triggers" source "drivers/leds/trigger/Kconfig" diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 73e603e1727e7..156c0b4e60d95 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -103,5 +103,8 @@ obj-$(CONFIG_LEDS_SPI_BYTE) += leds-spi-byte.o # LED Userspace Drivers obj-$(CONFIG_LEDS_USER) += uleds.o +# Flash and Torch LED Drivers +obj-$(CONFIG_LEDS_CLASS_FLASH) += flash/ + # LED Triggers obj-$(CONFIG_LEDS_TRIGGERS) += trigger/ diff --git a/drivers/leds/flash/Kconfig b/drivers/leds/flash/Kconfig new file mode 100644 index 0000000000000..d21d273ef3da2 --- /dev/null +++ b/drivers/leds/flash/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 + +if LEDS_CLASS_FLASH + +config LEDS_RT8515 + tristate "LED support for Richtek RT8515 flash/torch LED" + depends on GPIOLIB + help + This option enables support for the Richtek RT8515 flash + and torch LEDs found on some mobile phones. + + To compile this driver as a module, choose M here: the module + will be called leds-rt8515. + +endif # LEDS_CLASS_FLASH diff --git a/drivers/leds/flash/Makefile b/drivers/leds/flash/Makefile new file mode 100644 index 0000000000000..e990e257f4d75 --- /dev/null +++ b/drivers/leds/flash/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_LEDS_RT8515) += leds-rt8515.o diff --git a/drivers/leds/flash/leds-rt8515.c b/drivers/leds/flash/leds-rt8515.c new file mode 100644 index 0000000000000..590bfa180d104 --- /dev/null +++ b/drivers/leds/flash/leds-rt8515.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * LED driver for Richtek RT8515 flash/torch white LEDs + * found on some Samsung mobile phones. + * + * This is a 1.5A Boost dual channel driver produced around 2011. + * + * The component lacks a datasheet, but in the schematic picture + * from the LG P970 service manual you can see the connections + * from the RT8515 to the LED, with two resistors connected + * from the pins "RFS" and "RTS" to ground. + * + * On the LG P970: + * RFS (resistance flash setting?) is 20 kOhm + * RTS (resistance torch setting?) is 39 kOhm + * + * Some sleuthing finds us the RT9387A which we have a datasheet for: + * https://static5.arrow.com/pdfs/2014/7/27/8/21/12/794/rtt_/manual/94download_ds.jspprt9387a.jspprt9387a.pdf + * This apparently works the same way so in theory this driver + * should cover RT9387A as well. This has not been tested, please + * update the compatibles if you add RT9387A support. + * + * Linus Walleij + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* We can provide 15-700 mA out to the LED */ +#define RT8515_MIN_IOUT_MA 15 +#define RT8515_MAX_IOUT_MA 700 +/* The maximum intensity is 1-16 for flash and 1-100 for torch */ +#define RT8515_FLASH_MAX 16 +#define RT8515_TORCH_MAX 100 + +#define RT8515_TIMEOUT_US 250000U +#define RT8515_MAX_TIMEOUT_US 300000U + +struct rt8515 { + struct led_classdev_flash fled; + struct device *dev; + struct v4l2_flash *v4l2_flash; + struct mutex lock; + struct regulator *reg; + struct gpio_desc *enable_torch; + struct gpio_desc *enable_flash; + struct timer_list powerdown_timer; + u32 max_timeout; /* Flash max timeout */ + int flash_max_intensity; + int torch_max_intensity; +}; + +static struct rt8515 *to_rt8515(struct led_classdev_flash *fled) +{ + return container_of(fled, struct rt8515, fled); +} + +static void rt8515_gpio_led_off(struct rt8515 *rt) +{ + gpiod_set_value(rt->enable_flash, 0); + gpiod_set_value(rt->enable_torch, 0); +} + +static void rt8515_gpio_brightness_commit(struct gpio_desc *gpiod, + int brightness) +{ + int i; + + /* + * Toggling a GPIO line with a small delay increases the + * brightness one step at a time. + */ + for (i = 0; i < brightness; i++) { + gpiod_set_value(gpiod, 0); + udelay(1); + gpiod_set_value(gpiod, 1); + udelay(1); + } +} + +/* This is setting the torch light level */ +static int rt8515_led_brightness_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct led_classdev_flash *fled = lcdev_to_flcdev(led); + struct rt8515 *rt = to_rt8515(fled); + + mutex_lock(&rt->lock); + + if (brightness == LED_OFF) { + /* Off */ + rt8515_gpio_led_off(rt); + } else if (brightness < RT8515_TORCH_MAX) { + /* Step it up to movie mode brightness using the flash pin */ + rt8515_gpio_brightness_commit(rt->enable_torch, brightness); + } else { + /* Max torch brightness requested */ + gpiod_set_value(rt->enable_torch, 1); + } + + mutex_unlock(&rt->lock); + + return 0; +} + +static int rt8515_led_flash_strobe_set(struct led_classdev_flash *fled, + bool state) +{ + struct rt8515 *rt = to_rt8515(fled); + struct led_flash_setting *timeout = &fled->timeout; + int brightness = rt->flash_max_intensity; + + mutex_lock(&rt->lock); + + if (state) { + /* Enable LED flash mode and set brightness */ + rt8515_gpio_brightness_commit(rt->enable_flash, brightness); + /* Set timeout */ + mod_timer(&rt->powerdown_timer, + jiffies + usecs_to_jiffies(timeout->val)); + } else { + del_timer_sync(&rt->powerdown_timer); + /* Turn the LED off */ + rt8515_gpio_led_off(rt); + } + + fled->led_cdev.brightness = LED_OFF; + /* After this the torch LED will be disabled */ + + mutex_unlock(&rt->lock); + + return 0; +} + +static int rt8515_led_flash_strobe_get(struct led_classdev_flash *fled, + bool *state) +{ + struct rt8515 *rt = to_rt8515(fled); + + *state = timer_pending(&rt->powerdown_timer); + + return 0; +} + +static int rt8515_led_flash_timeout_set(struct led_classdev_flash *fled, + u32 timeout) +{ + /* The timeout is stored in the led-class-flash core */ + return 0; +} + +static const struct led_flash_ops rt8515_flash_ops = { + .strobe_set = rt8515_led_flash_strobe_set, + .strobe_get = rt8515_led_flash_strobe_get, + .timeout_set = rt8515_led_flash_timeout_set, +}; + +static void rt8515_powerdown_timer(struct timer_list *t) +{ + struct rt8515 *rt = from_timer(rt, t, powerdown_timer); + + /* Turn the LED off */ + rt8515_gpio_led_off(rt); +} + +static void rt8515_init_flash_timeout(struct rt8515 *rt) +{ + struct led_classdev_flash *fled = &rt->fled; + struct led_flash_setting *s; + + /* Init flash timeout setting */ + s = &fled->timeout; + s->min = 1; + s->max = rt->max_timeout; + s->step = 1; + /* + * Set default timeout to RT8515_TIMEOUT_US except if + * max_timeout from DT is lower. + */ + s->val = min(rt->max_timeout, RT8515_TIMEOUT_US); +} + +#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS) +/* Configure the V2L2 flash subdevice */ +static void rt8515_init_v4l2_flash_config(struct rt8515 *rt, + struct v4l2_flash_config *v4l2_sd_cfg) +{ + struct led_classdev *led = &rt->fled.led_cdev; + struct led_flash_setting *s; + + strscpy(v4l2_sd_cfg->dev_name, led->dev->kobj.name, + sizeof(v4l2_sd_cfg->dev_name)); + + /* + * Init flash intensity setting: this is a linear scale + * capped from the device tree max intensity setting + * 1..flash_max_intensity + */ + s = &v4l2_sd_cfg->intensity; + s->min = 1; + s->max = rt->flash_max_intensity; + s->step = 1; + s->val = s->max; +} + +static void rt8515_v4l2_flash_release(struct rt8515 *rt) +{ + v4l2_flash_release(rt->v4l2_flash); +} + +#else +static void rt8515_init_v4l2_flash_config(struct rt8515 *rt, + struct v4l2_flash_config *v4l2_sd_cfg) +{ +} + +static void rt8515_v4l2_flash_release(struct rt8515 *rt) +{ +} +#endif + +static void rt8515_determine_max_intensity(struct rt8515 *rt, + struct fwnode_handle *led, + const char *resistance, + const char *max_ua_prop, int hw_max, + int *max_intensity_setting) +{ + u32 res = 0; /* Can't be 0 so 0 is undefined */ + u32 ua; + u32 max_ma; + int max_intensity; + int ret; + + fwnode_property_read_u32(rt->dev->fwnode, resistance, &res); + ret = fwnode_property_read_u32(led, max_ua_prop, &ua); + + /* Missing info in DT, OK go with hardware maxima */ + if (ret || res == 0) { + dev_err(rt->dev, + "either %s or %s missing from DT, using HW max\n", + resistance, max_ua_prop); + max_ma = RT8515_MAX_IOUT_MA; + max_intensity = hw_max; + goto out_assign_max; + } + + /* + * Formula from the datasheet, this is the maximum current + * defined by the hardware. + */ + max_ma = (5500 * 1000) / res; + /* + * Calculate max intensity (linear scaling) + * Formula is ((ua / 1000) / max_ma) * 100, then simplified + */ + max_intensity = (ua / 10) / max_ma; + + dev_info(rt->dev, + "current restricted from %u to %u mA, max intensity %d/100\n", + max_ma, (ua / 1000), max_intensity); + +out_assign_max: + dev_info(rt->dev, "max intensity %d/%d = %d mA\n", + max_intensity, hw_max, max_ma); + *max_intensity_setting = max_intensity; +} + +static int rt8515_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct fwnode_handle *child; + struct rt8515 *rt; + struct led_classdev *led; + struct led_classdev_flash *fled; + struct led_init_data init_data = {}; + struct v4l2_flash_config v4l2_sd_cfg = {}; + int ret; + + rt = devm_kzalloc(dev, sizeof(*rt), GFP_KERNEL); + if (!rt) + return -ENOMEM; + + rt->dev = dev; + fled = &rt->fled; + led = &fled->led_cdev; + + /* ENF - Enable Flash line */ + rt->enable_flash = devm_gpiod_get(dev, "enf", GPIOD_OUT_LOW); + if (IS_ERR(rt->enable_flash)) + return dev_err_probe(dev, PTR_ERR(rt->enable_flash), + "cannot get ENF (enable flash) GPIO\n"); + + /* ENT - Enable Torch line */ + rt->enable_torch = devm_gpiod_get(dev, "ent", GPIOD_OUT_LOW); + if (IS_ERR(rt->enable_torch)) + return dev_err_probe(dev, PTR_ERR(rt->enable_torch), + "cannot get ENT (enable torch) GPIO\n"); + + child = fwnode_get_next_available_child_node(dev->fwnode, NULL); + if (!child) { + dev_err(dev, + "No fwnode child node found for connected LED.\n"); + return -EINVAL; + } + init_data.fwnode = child; + + rt8515_determine_max_intensity(rt, child, "richtek,rfs-ohms", + "flash-max-microamp", + RT8515_FLASH_MAX, + &rt->flash_max_intensity); + rt8515_determine_max_intensity(rt, child, "richtek,rts-ohms", + "led-max-microamp", + RT8515_TORCH_MAX, + &rt->torch_max_intensity); + + ret = fwnode_property_read_u32(child, "flash-max-timeout-us", + &rt->max_timeout); + if (ret) { + rt->max_timeout = RT8515_MAX_TIMEOUT_US; + dev_warn(dev, + "flash-max-timeout-us property missing\n"); + } + timer_setup(&rt->powerdown_timer, rt8515_powerdown_timer, 0); + rt8515_init_flash_timeout(rt); + + fled->ops = &rt8515_flash_ops; + + led->max_brightness = rt->torch_max_intensity; + led->brightness_set_blocking = rt8515_led_brightness_set; + led->flags |= LED_CORE_SUSPENDRESUME | LED_DEV_CAP_FLASH; + + mutex_init(&rt->lock); + + platform_set_drvdata(pdev, rt); + + ret = devm_led_classdev_flash_register_ext(dev, fled, &init_data); + if (ret) { + dev_err(dev, "can't register LED %s\n", led->name); + mutex_destroy(&rt->lock); + return ret; + } + + rt8515_init_v4l2_flash_config(rt, &v4l2_sd_cfg); + + /* Create a V4L2 Flash device if V4L2 flash is enabled */ + rt->v4l2_flash = v4l2_flash_init(dev, child, fled, NULL, &v4l2_sd_cfg); + if (IS_ERR(rt->v4l2_flash)) { + ret = PTR_ERR(rt->v4l2_flash); + dev_err(dev, "failed to register V4L2 flash device (%d)\n", + ret); + /* + * Continue without the V4L2 flash + * (we still have the classdev) + */ + } + + return 0; +} + +static int rt8515_remove(struct platform_device *pdev) +{ + struct rt8515 *rt = platform_get_drvdata(pdev); + + rt8515_v4l2_flash_release(rt); + del_timer_sync(&rt->powerdown_timer); + mutex_destroy(&rt->lock); + + return 0; +} + +static const struct of_device_id rt8515_match[] = { + { .compatible = "richtek,rt8515", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rt8515_match); + +static struct platform_driver rt8515_driver = { + .driver = { + .name = "rt8515", + .of_match_table = rt8515_match, + }, + .probe = rt8515_probe, + .remove = rt8515_remove, +}; +module_platform_driver(rt8515_driver); + +MODULE_AUTHOR("Linus Walleij "); +MODULE_DESCRIPTION("Richtek RT8515 LED driver"); +MODULE_LICENSE("GPL"); -- GitLab From 3e1f4a2e1184ae6ad7f4caf682ced9554141a0f4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 28 Jan 2021 12:33:42 +0300 Subject: [PATCH 0853/1084] USB: gadget: legacy: fix an error code in eth_bind() This code should return -ENOMEM if the allocation fails but it currently returns success. Fixes: 9b95236eebdb ("usb: gadget: ether: allocate and init otg descriptor by otg capabilities") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/YBKE9rqVuJEOUWpW@mwanda Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/ether.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/ether.c b/drivers/usb/gadget/legacy/ether.c index 30313b233680d..99c7fc0d1d597 100644 --- a/drivers/usb/gadget/legacy/ether.c +++ b/drivers/usb/gadget/legacy/ether.c @@ -403,8 +403,10 @@ static int eth_bind(struct usb_composite_dev *cdev) struct usb_descriptor_header *usb_desc; usb_desc = usb_otg_descriptor_alloc(gadget); - if (!usb_desc) + if (!usb_desc) { + status = -ENOMEM; goto fail1; + } usb_otg_descriptor_init(gadget, usb_desc); otg_desc[0] = usb_desc; otg_desc[1] = NULL; -- GitLab From 215164bfb7144c5890dd8021ff06e486939862d4 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 29 Jan 2021 11:26:54 -0600 Subject: [PATCH 0854/1084] platform/x86: dell-wmi-sysman: fix a NULL pointer dereference An upcoming Dell platform is causing a NULL pointer dereference in dell-wmi-sysman initialization. Validate that the input from BIOS matches correct ACPI types and abort module initialization if it fails. Signed-off-by: Mario Limonciello Tested-by: Perry Yuan Link: https://lore.kernel.org/r/20210129172654.2326751-1-mario.limonciello@dell.com [hdegoede@redhat.com: Drop redundant release_attributes_data() call] Signed-off-by: Hans de Goede --- drivers/platform/x86/dell-wmi-sysman/sysman.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell-wmi-sysman/sysman.c index dc6dd531c9964..cb81010ba1a21 100644 --- a/drivers/platform/x86/dell-wmi-sysman/sysman.c +++ b/drivers/platform/x86/dell-wmi-sysman/sysman.c @@ -419,13 +419,17 @@ static int init_bios_attributes(int attr_type, const char *guid) return retval; /* need to use specific instance_id and guid combination to get right data */ obj = get_wmiobj_pointer(instance_id, guid); - if (!obj) + if (!obj || obj->type != ACPI_TYPE_PACKAGE) return -ENODEV; elements = obj->package.elements; mutex_lock(&wmi_priv.mutex); while (elements) { /* sanity checking */ + if (elements[ATTR_NAME].type != ACPI_TYPE_STRING) { + pr_debug("incorrect element type\n"); + goto nextobj; + } if (strlen(elements[ATTR_NAME].string.pointer) == 0) { pr_debug("empty attribute found\n"); goto nextobj; -- GitLab From 1048ba83fb1c00cd24172e23e8263972f6b5d9ac Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 31 Jan 2021 13:50:09 -0800 Subject: [PATCH 0855/1084] Linux 5.11-rc6 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e0af7a4a55985..f5842126e89d4 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 11 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Kleptomaniac Octopus # *DOCUMENTATION* -- GitLab From d8d2d38275c1b2d3936c0d809e0559e88912fbb5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Feb 2021 10:00:24 +0900 Subject: [PATCH 0856/1084] kbuild: remove PYTHON variable Python retired in 2020, and some distributions do not provide the 'python' command any more. As in commit 51839e29cb59 ("scripts: switch explicitly to Python 3"), we need to use more specific 'python3' to invoke scripts even if they are written in a way compatible with both Python 2 and 3. This commit removes the variable 'PYTHON', and switches the existing users to 'PYTHON3'. BTW, PEP 394 (https://www.python.org/dev/peps/pep-0394/) is a helpful material. Signed-off-by: Masahiro Yamada --- Documentation/Makefile | 2 +- Documentation/kbuild/makefiles.rst | 2 +- Makefile | 3 +-- arch/ia64/Makefile | 2 +- arch/ia64/scripts/unwcheck.py | 2 +- scripts/jobserver-exec | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Documentation/Makefile b/Documentation/Makefile index 61a7310b49e0c..9c42dde97671f 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -75,7 +75,7 @@ quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4) cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media $2 && \ PYTHONDONTWRITEBYTECODE=1 \ BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \ - $(PYTHON) $(srctree)/scripts/jobserver-exec \ + $(PYTHON3) $(srctree)/scripts/jobserver-exec \ $(SHELL) $(srctree)/Documentation/sphinx/parallel-wrapper.sh \ $(SPHINXBUILD) \ -b $2 \ diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 9f6a118819513..300d8edcb994e 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -755,7 +755,7 @@ more details, with real examples. bits on the scripts nonetheless. Kbuild provides variables $(CONFIG_SHELL), $(AWK), $(PERL), - $(PYTHON) and $(PYTHON3) to refer to interpreters for the respective + and $(PYTHON3) to refer to interpreters for the respective scripts. Example:: diff --git a/Makefile b/Makefile index b0e4767735dca..89217e4e68c63 100644 --- a/Makefile +++ b/Makefile @@ -452,7 +452,6 @@ AWK = awk INSTALLKERNEL := installkernel DEPMOD = depmod PERL = perl -PYTHON = python PYTHON3 = python3 CHECK = sparse BASH = bash @@ -508,7 +507,7 @@ CLANG_FLAGS := export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL -export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX +export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 703b1c4f6d123..45d5368d6a99c 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -69,7 +69,7 @@ vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) unwcheck: vmlinux - -$(Q)READELF=$(READELF) $(PYTHON) $(srctree)/arch/ia64/scripts/unwcheck.py $< + -$(Q)READELF=$(READELF) $(PYTHON3) $(srctree)/arch/ia64/scripts/unwcheck.py $< archclean: diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py index bfd1b671e35fc..9581742f0db23 100644 --- a/arch/ia64/scripts/unwcheck.py +++ b/arch/ia64/scripts/unwcheck.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 # # Usage: unwcheck.py FILE diff --git a/scripts/jobserver-exec b/scripts/jobserver-exec index 0fdb31a790a81..48d141e3ec56f 100755 --- a/scripts/jobserver-exec +++ b/scripts/jobserver-exec @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # # This determines how many parallel tasks "make" is expecting, as it is -- GitLab From f92e04f764b86e55e522988e6f4b6082d19a2721 Mon Sep 17 00:00:00 2001 From: Fengnan Chang Date: Sat, 23 Jan 2021 11:32:31 +0800 Subject: [PATCH 0857/1084] mmc: core: Limit retries when analyse of SDIO tuples fails When analysing tuples fails we may loop indefinitely to retry. Let's avoid this by using a 10s timeout and bail if not completed earlier. Signed-off-by: Fengnan Chang Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210123033230.36442-1-fengnanchang@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/sdio_cis.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index 44bea5e4aeda1..b23773583179d 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c @@ -20,6 +20,8 @@ #include "sdio_cis.h" #include "sdio_ops.h" +#define SDIO_READ_CIS_TIMEOUT_MS (10 * 1000) /* 10s */ + static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func, const unsigned char *buf, unsigned size) { @@ -274,6 +276,8 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) do { unsigned char tpl_code, tpl_link; + unsigned long timeout = jiffies + + msecs_to_jiffies(SDIO_READ_CIS_TIMEOUT_MS); ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code); if (ret) @@ -326,6 +330,8 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) prev = &this->next; if (ret == -ENOENT) { + if (time_after(jiffies, timeout)) + break; /* warn about unknown tuples */ pr_warn_ratelimited("%s: queuing unknown" " CIS tuple 0x%02x (%u bytes)\n", -- GitLab From d7fb9c24209556478e65211d7a1f056f2d43cceb Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 26 Jan 2021 10:43:13 +0100 Subject: [PATCH 0858/1084] mmc: sdhci-pltfm: Fix linking err for sdhci-brcmstb The implementation of sdhci_pltfm_suspend() is only available when CONFIG_PM_SLEEP is set, which triggers a linking error: "undefined symbol: sdhci_pltfm_suspend" when building sdhci-brcmstb.c. Fix this by implementing the missing stubs when CONFIG_PM_SLEEP is unset. Reported-by: Arnd Bergmann Suggested-by: Florian Fainelli Fixes: 5b191dcba719 ("mmc: sdhci-brcmstb: Fix mmc timeout errors on S5 suspend") Cc: stable@vger.kernel.org Tested-By: Nicolas Schichan Acked-by: Arnd Bergmann Acked-by: Florian Fainelli Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-pltfm.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h index 6301b81cf5731..9bd717ff784be 100644 --- a/drivers/mmc/host/sdhci-pltfm.h +++ b/drivers/mmc/host/sdhci-pltfm.h @@ -111,8 +111,13 @@ static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host) return host->private; } +extern const struct dev_pm_ops sdhci_pltfm_pmops; +#ifdef CONFIG_PM_SLEEP int sdhci_pltfm_suspend(struct device *dev); int sdhci_pltfm_resume(struct device *dev); -extern const struct dev_pm_ops sdhci_pltfm_pmops; +#else +static inline int sdhci_pltfm_suspend(struct device *dev) { return 0; } +static inline int sdhci_pltfm_resume(struct device *dev) { return 0; } +#endif #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */ -- GitLab From c07ea8d0b170c0cf6592a53981841c7973e142ea Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 5 Jan 2021 11:59:14 +0100 Subject: [PATCH 0859/1084] gpio: gpiolib: remove shadowed variable After refactoring, we had two variables for the same thing. Remove the second declaration, one is enough here. Found by cppcheck. drivers/gpio/gpiolib.c:2551:17: warning: Local variable 'ret' shadows outer variable [shadowVariable] Fixes: d377f56f34f5 ("gpio: gpiolib: Normalize return code variable name") Signed-off-by: Wolfram Sang Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 3ba9c981f0b9d..97eec8d8dbdc4 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2557,7 +2557,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep, struct gpio_chip *gc = desc_array[i]->gdev->chip; unsigned long fastpath[2 * BITS_TO_LONGS(FASTPATH_NGPIO)]; unsigned long *mask, *bits; - int first, j, ret; + int first, j; if (likely(gc->ngpio <= FASTPATH_NGPIO)) { mask = fastpath; -- GitLab From 9917f0e3cdba7b9f1a23f70e3f70b1a106be54a8 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 1 Feb 2021 21:47:20 +0900 Subject: [PATCH 0860/1084] usb: renesas_usbhs: Clear pipe running flag in usbhs_pkt_pop() Should clear the pipe running flag in usbhs_pkt_pop(). Otherwise, we cannot use this pipe after dequeue was called while the pipe was running. Fixes: 8355b2b3082d ("usb: renesas_usbhs: fix the behavior of some usbhs_pkt_handle") Reported-by: Tho Vu Signed-off-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/1612183640-8898-1-git-send-email-yoshihiro.shimoda.uh@renesas.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/renesas_usbhs/fifo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index ac9a81ae82164..e6fa137018082 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -126,6 +126,7 @@ struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) } usbhs_pipe_clear_without_sequence(pipe, 0, 0); + usbhs_pipe_running(pipe, 0); __usbhsf_pkt_del(pkt); } -- GitLab From 54f6a8af372213a254af6609758d99f7c0b6b5ad Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Mon, 1 Feb 2021 13:57:44 +0800 Subject: [PATCH 0861/1084] usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints For those unchecked endpoints, we don't allocate bandwidth for them, so no need free the bandwidth, otherwise will decrease the allocated bandwidth. Meanwhile use xhci_dbg() instead of dev_dbg() to print logs and rename bw_ep_list_new as bw_ep_chk_list. Fixes: 1d69f9d901ef ("usb: xhci-mtk: fix unreleased bandwidth data") Cc: stable Reviewed-and-tested-by: Ikjoon Jang Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1612159064-28413-1-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mtk-sch.c | 61 ++++++++++++++++++--------------- drivers/usb/host/xhci-mtk.h | 4 ++- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index a313e75ff1c6b..dee8a329076d1 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -200,6 +200,7 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, sch_ep->sch_tt = tt; sch_ep->ep = ep; + INIT_LIST_HEAD(&sch_ep->endpoint); INIT_LIST_HEAD(&sch_ep->tt_endpoint); return sch_ep; @@ -374,6 +375,7 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, sch_ep->bw_budget_table[j]; } } + sch_ep->allocated = used; } static int check_sch_tt(struct usb_device *udev, @@ -542,6 +544,22 @@ static int check_sch_bw(struct usb_device *udev, return 0; } +static void destroy_sch_ep(struct usb_device *udev, + struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) +{ + /* only release ep bw check passed by check_sch_bw() */ + if (sch_ep->allocated) + update_bus_bw(sch_bw, sch_ep, 0); + + list_del(&sch_ep->endpoint); + + if (sch_ep->sch_tt) { + list_del(&sch_ep->tt_endpoint); + drop_tt(udev); + } + kfree(sch_ep); +} + static bool need_bw_sch(struct usb_host_endpoint *ep, enum usb_device_speed speed, int has_tt) { @@ -584,7 +602,7 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) mtk->sch_array = sch_array; - INIT_LIST_HEAD(&mtk->bw_ep_list_new); + INIT_LIST_HEAD(&mtk->bw_ep_chk_list); return 0; } @@ -636,29 +654,12 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, setup_sch_info(udev, ep_ctx, sch_ep); - list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_list_new); + list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list); return 0; } EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); -static void xhci_mtk_drop_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, - struct mu3h_sch_ep_info *sch_ep) -{ - struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); - int bw_index = get_bw_index(xhci, udev, sch_ep->ep); - struct mu3h_sch_bw_info *sch_bw = &mtk->sch_array[bw_index]; - - update_bus_bw(sch_bw, sch_ep, 0); - list_del(&sch_ep->endpoint); - - if (sch_ep->sch_tt) { - list_del(&sch_ep->tt_endpoint); - drop_tt(udev); - } - kfree(sch_ep); -} - void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep) { @@ -688,9 +689,8 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, sch_bw = &sch_array[bw_index]; list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { - if (sch_ep->ep == ep) { - xhci_mtk_drop_ep(mtk, udev, sch_ep); - } + if (sch_ep->ep == ep) + destroy_sch_ep(udev, sch_bw, sch_ep); } } EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk); @@ -704,9 +704,9 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) struct mu3h_sch_ep_info *sch_ep, *tmp; int bw_index, ret; - dev_dbg(&udev->dev, "%s\n", __func__); + xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); - list_for_each_entry(sch_ep, &mtk->bw_ep_list_new, endpoint) { + list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) { bw_index = get_bw_index(xhci, udev, sch_ep->ep); sch_bw = &mtk->sch_array[bw_index]; @@ -717,7 +717,7 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) } } - list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { + list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { struct xhci_ep_ctx *ep_ctx; struct usb_host_endpoint *ep = sch_ep->ep; unsigned int ep_index = xhci_get_endpoint_index(&ep->desc); @@ -746,12 +746,17 @@ EXPORT_SYMBOL_GPL(xhci_mtk_check_bandwidth); void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) { struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct mu3h_sch_bw_info *sch_bw; struct mu3h_sch_ep_info *sch_ep, *tmp; + int bw_index; - dev_dbg(&udev->dev, "%s\n", __func__); + xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); - list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { - xhci_mtk_drop_ep(mtk, udev, sch_ep); + list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { + bw_index = get_bw_index(xhci, udev, sch_ep->ep); + sch_bw = &mtk->sch_array[bw_index]; + destroy_sch_ep(udev, sch_bw, sch_ep); } xhci_reset_bandwidth(hcd, udev); diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index 577f431c5c93c..cbb09dfea62e0 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -59,6 +59,7 @@ struct mu3h_sch_bw_info { * @ep_type: endpoint type * @maxpkt: max packet size of endpoint * @ep: address of usb_host_endpoint struct + * @allocated: the bandwidth is aready allocated from bus_bw * @offset: which uframe of the interval that transfer should be * scheduled first time within the interval * @repeat: the time gap between two uframes that transfers are @@ -86,6 +87,7 @@ struct mu3h_sch_ep_info { u32 ep_type; u32 maxpkt; void *ep; + bool allocated; /* * mtk xHCI scheduling information put into reserved DWs * in ep context @@ -130,8 +132,8 @@ struct mu3c_ippc_regs { struct xhci_hcd_mtk { struct device *dev; struct usb_hcd *hcd; - struct list_head bw_ep_list_new; struct mu3h_sch_bw_info *sch_array; + struct list_head bw_ep_chk_list; struct mu3c_ippc_regs __iomem *ippc_regs; bool has_ippc; int num_u2_ports; -- GitLab From 941d3f0d7e9ffcbee1efeb6f07fa5fc5ef8347ff Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Mon, 1 Feb 2021 11:31:28 +0200 Subject: [PATCH 0862/1084] ASoC: SOF: topology: Prevent NULL pointer dereference with no TLV When there is no TLV data in topology, extracting the TLV data could result in a NULL pointer exception. Prevent this by making sure that the TLV data exists before extracting it. Signed-off-by: Ranjani Sridharan Reviewed-by: Guennadi Liakhovetski Reviewed-by: Paul Olaru Reviewed-by: Bard Liao Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210201093128.1226603-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 59f89f3d61a23..480cf75a7575e 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1073,7 +1073,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp, scontrol->cmd = SOF_CTRL_CMD_VOLUME; /* extract tlv data */ - if (get_tlv_data(kc->tlv.p, tlv) < 0) { + if (!kc->tlv.p || get_tlv_data(kc->tlv.p, tlv) < 0) { dev_err(scomp->dev, "error: invalid TLV data\n"); ret = -EINVAL; goto out_free; -- GitLab From 6bbb859012e905736c852b518be16c653e451967 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 29 Jan 2021 23:57:38 +0530 Subject: [PATCH 0863/1084] ASoC: dt-bindings: rt5659: Update binding doc Update following in rt5659.txt binding doc - Add JD source for Intel HDA header: Commit 041e74b71491 ("ASoC: rt5659: Add the support of Intel HDA Header") added driver support. Add missing info here. - sound-name-prefix: Used to prefix component widgets/kcontrols with given prefix. - ports: Helps to use the Codec with audio graph card Signed-off-by: Sameer Pujar Reported-by: Jon Hunter Cc: Oder Chiou Cc: Bard Liao Link: https://lore.kernel.org/r/1611944866-29373-2-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/rt5659.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/rt5659.txt b/Documentation/devicetree/bindings/sound/rt5659.txt index 56788f50b6cf4..c473df5c878c6 100644 --- a/Documentation/devicetree/bindings/sound/rt5659.txt +++ b/Documentation/devicetree/bindings/sound/rt5659.txt @@ -37,10 +37,21 @@ Optional properties: - realtek,jd-src 0: No JD is used 1: using JD3 as JD source + 2: JD source for Intel HDA header - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. - realtek,reset-gpios : The GPIO that controls the CODEC's RESET pin. +- sound-name-prefix: Please refer to name-prefix.txt + +- ports: A Codec may have a single or multiple I2S interfaces. These + interfaces on Codec side can be described under 'ports' or 'port'. + When the SoC or host device is connected to multiple interfaces of + the Codec, the connectivity can be described using 'ports' property. + If a single interface is used, then 'port' can be used. The usage + depends on the platform or board design. + Please refer to Documentation/devicetree/bindings/graph.txt + Pins on the device (for linking into audio routes) for RT5659/RT5658: * DMIC L1 -- GitLab From 70f0bc65f6cf757fa4cca2d6fcb84f613bc0d8cc Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 29 Jan 2021 23:57:39 +0530 Subject: [PATCH 0864/1084] ASoC: dt-bindings: tegra: Add iommus property to Tegra graph card Document 'iommus' property for APE (Audio Processing Engine) sound card. Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1611944866-29373-3-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- .../bindings/sound/nvidia,tegra-audio-graph-card.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml index fc271f644aafb..249970952202b 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml @@ -45,6 +45,9 @@ properties: minItems: 1 maxItems: 3 + iommus: + maxItems: 1 + required: - clocks - clock-names -- GitLab From 531e5b7abbde3c190aeff5b13c17f7ef3e0f3543 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 29 Jan 2021 23:57:40 +0530 Subject: [PATCH 0865/1084] ASoC: audio-graph-card: Add clocks property to endpoint node Add optional 'clocks' property to audio port 'endpoint' node. One such example is where SoC supplies a clock to external audio codec component. Signed-off-by: Sameer Pujar Cc: Kuninori Morimoto Reviewed-by: Jon Hunter Link: https://lore.kernel.org/r/1611944866-29373-4-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/audio-graph-port.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml index 766e9109b2f77..08ed8f52c9623 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml +++ b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml @@ -33,6 +33,9 @@ properties: properties: remote-endpoint: maxItems: 1 + clocks: + maxItems: 1 + description: Describes the clock used by audio component. mclk-fs: description: | Multiplication factor between stream rate and codec mclk. -- GitLab From 563c2681d4313f55b9b1d9a8f635946cd4972170 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 29 Jan 2021 23:57:41 +0530 Subject: [PATCH 0866/1084] ASoC: rt5659: Add Kconfig prompt Add tristate prompt to allow codec selection. Cc: Oder Chiou Cc: Bard Liao Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1611944866-29373-5-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 9bf6bfdaf11e4..df34b3b3bb143 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1162,7 +1162,7 @@ config SND_SOC_RT5651 depends on I2C config SND_SOC_RT5659 - tristate + tristate "Realtek RT5658/RT5659 Codec" depends on I2C config SND_SOC_RT5660 -- GitLab From e86caa011c80507783e5975bca1458f28c1d2b8c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2021 13:59:15 +0100 Subject: [PATCH 0867/1084] ASoC: tegra: SND_SOC_TEGRA_AUDIO_GRAPH_CARD should depend on SND_SOC_TEGRA Audio Graph Card based Tegra driver is only useful on NVIDIA Tegra SoCs. Hence add a dependency on SND_SOC_TEGRA, to prevent asking the user about this driver when configuring a kernel without Tegra sound support. Wrap all Tegra sound config options inside a big if/endif block, instead of just adding the dependency to the single config option that does not have it yet, to preventing similar future mistakes. Fixes: 202e2f7745437aa5 ("ASoC: tegra: Add audio graph based card driver") Signed-off-by: Geert Uytterhoeven Acked-by: Sameer Pujar Link: https://lore.kernel.org/r/20210129125915.2652952-1-geert+renesas@glider.be Signed-off-by: Mark Brown --- sound/soc/tegra/Kconfig | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 6dc83ad8607a1..a4e6760944d02 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -9,9 +9,10 @@ config SND_SOC_TEGRA help Say Y or M here if you want support for SoC audio on Tegra. +if SND_SOC_TEGRA + config SND_SOC_TEGRA20_AC97 tristate "Tegra20 AC97 interface" - depends on SND_SOC_TEGRA select SND_SOC_AC97_BUS select SND_SOC_TEGRA20_DAS help @@ -21,7 +22,6 @@ config SND_SOC_TEGRA20_AC97 config SND_SOC_TEGRA20_DAS tristate "Tegra20 DAS module" - depends on SND_SOC_TEGRA help Say Y or M if you want to add support for the Tegra20 DAS module. You will also need to select the individual machine drivers to @@ -29,7 +29,6 @@ config SND_SOC_TEGRA20_DAS config SND_SOC_TEGRA20_I2S tristate "Tegra20 I2S interface" - depends on SND_SOC_TEGRA select SND_SOC_TEGRA20_DAS help Say Y or M if you want to add support for codecs attached to the @@ -38,7 +37,6 @@ config SND_SOC_TEGRA20_I2S config SND_SOC_TEGRA20_SPDIF tristate "Tegra20 SPDIF interface" - depends on SND_SOC_TEGRA help Say Y or M if you want to add support for the Tegra20 SPDIF interface. You will also need to select the individual machine drivers to support @@ -46,7 +44,6 @@ config SND_SOC_TEGRA20_SPDIF config SND_SOC_TEGRA30_AHUB tristate "Tegra30 AHUB module" - depends on SND_SOC_TEGRA help Say Y or M if you want to add support for the Tegra30 AHUB module. You will also need to select the individual machine drivers to @@ -54,7 +51,6 @@ config SND_SOC_TEGRA30_AHUB config SND_SOC_TEGRA30_I2S tristate "Tegra30 I2S interface" - depends on SND_SOC_TEGRA select SND_SOC_TEGRA30_AHUB help Say Y or M if you want to add support for codecs attached to the @@ -63,7 +59,6 @@ config SND_SOC_TEGRA30_I2S config SND_SOC_TEGRA210_AHUB tristate "Tegra210 AHUB module" - depends on SND_SOC_TEGRA help Config to enable Audio Hub (AHUB) module, which comprises of a switch called Audio Crossbar (AXBAR) used to configure or modify @@ -73,7 +68,6 @@ config SND_SOC_TEGRA210_AHUB config SND_SOC_TEGRA210_DMIC tristate "Tegra210 DMIC module" - depends on SND_SOC_TEGRA help Config to enable the Digital MIC (DMIC) controller which is used to interface with Pulse Density Modulation (PDM) input devices. @@ -84,7 +78,6 @@ config SND_SOC_TEGRA210_DMIC config SND_SOC_TEGRA210_I2S tristate "Tegra210 I2S module" - depends on SND_SOC_TEGRA help Config to enable the Inter-IC Sound (I2S) Controller which implements full-duplex and bidirectional and single direction @@ -94,7 +87,6 @@ config SND_SOC_TEGRA210_I2S config SND_SOC_TEGRA186_DSPK tristate "Tegra186 DSPK module" - depends on SND_SOC_TEGRA help Config to enable the Digital Speaker Controller (DSPK) which converts the multi-bit Pulse Code Modulation (PCM) audio input to @@ -107,7 +99,6 @@ config SND_SOC_TEGRA186_DSPK config SND_SOC_TEGRA210_ADMAIF tristate "Tegra210 ADMAIF module" - depends on SND_SOC_TEGRA help Config to enable ADMAIF which is the interface between ADMA and Audio Hub (AHUB). Each ADMA channel that sends/receives data to/ @@ -128,7 +119,7 @@ config SND_SOC_TEGRA_AUDIO_GRAPH_CARD config SND_SOC_TEGRA_RT5640 tristate "SoC Audio support for Tegra boards using an RT5640 codec" - depends on SND_SOC_TEGRA && I2C && GPIOLIB + depends on I2C && GPIOLIB select SND_SOC_RT5640 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -136,7 +127,7 @@ config SND_SOC_TEGRA_RT5640 config SND_SOC_TEGRA_WM8753 tristate "SoC Audio support for Tegra boards using a WM8753 codec" - depends on SND_SOC_TEGRA && I2C && GPIOLIB + depends on I2C && GPIOLIB select SND_SOC_WM8753 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -144,7 +135,7 @@ config SND_SOC_TEGRA_WM8753 config SND_SOC_TEGRA_WM8903 tristate "SoC Audio support for Tegra boards using a WM8903 codec" - depends on SND_SOC_TEGRA && I2C && GPIOLIB + depends on I2C && GPIOLIB select SND_SOC_WM8903 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -153,7 +144,7 @@ config SND_SOC_TEGRA_WM8903 config SND_SOC_TEGRA_WM9712 tristate "SoC Audio support for Tegra boards using a WM9712 codec" - depends on SND_SOC_TEGRA && GPIOLIB + depends on GPIOLIB select SND_SOC_TEGRA20_AC97 select SND_SOC_WM9712 help @@ -162,7 +153,7 @@ config SND_SOC_TEGRA_WM9712 config SND_SOC_TEGRA_TRIMSLICE tristate "SoC Audio support for TrimSlice board" - depends on SND_SOC_TEGRA && I2C + depends on I2C select SND_SOC_TLV320AIC23_I2C help Say Y or M here if you want to add support for SoC audio on the @@ -170,7 +161,7 @@ config SND_SOC_TEGRA_TRIMSLICE config SND_SOC_TEGRA_ALC5632 tristate "SoC Audio support for Tegra boards using an ALC5632 codec" - depends on SND_SOC_TEGRA && I2C && GPIOLIB + depends on I2C && GPIOLIB select SND_SOC_ALC5632 help Say Y or M here if you want to add support for SoC audio on the @@ -178,7 +169,7 @@ config SND_SOC_TEGRA_ALC5632 config SND_SOC_TEGRA_MAX98090 tristate "SoC Audio support for Tegra boards using a MAX98090 codec" - depends on SND_SOC_TEGRA && I2C && GPIOLIB + depends on I2C && GPIOLIB select SND_SOC_MAX98090 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -186,7 +177,7 @@ config SND_SOC_TEGRA_MAX98090 config SND_SOC_TEGRA_RT5677 tristate "SoC Audio support for Tegra boards using a RT5677 codec" - depends on SND_SOC_TEGRA && I2C && GPIOLIB + depends on I2C && GPIOLIB select SND_SOC_RT5677 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -194,9 +185,11 @@ config SND_SOC_TEGRA_RT5677 config SND_SOC_TEGRA_SGTL5000 tristate "SoC Audio support for Tegra boards using a SGTL5000 codec" - depends on SND_SOC_TEGRA && I2C && GPIOLIB + depends on I2C && GPIOLIB select SND_SOC_SGTL5000 help Say Y or M here if you want to add support for SoC audio on Tegra boards using the SGTL5000 codec, such as Apalis T30, Apalis TK1 or Colibri T30. + +endif -- GitLab From 18fe0fae61252b5ae6e26553e2676b5fac555951 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 1 Feb 2021 09:33:24 +0100 Subject: [PATCH 0868/1084] mac80211: fix station rate table updates on assoc If the driver uses .sta_add, station entries are only uploaded after the sta is in assoc state. Fix early station rate table updates by deferring them until the sta has been uploaded. Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20210201083324.3134-1-nbd@nbd.name [use rcu_access_pointer() instead since we won't dereference here] Signed-off-by: Johannes Berg --- net/mac80211/driver-ops.c | 5 ++++- net/mac80211/rate.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c index c9a8a2433e8ac..48322e45e7ddb 100644 --- a/net/mac80211/driver-ops.c +++ b/net/mac80211/driver-ops.c @@ -125,8 +125,11 @@ int drv_sta_state(struct ieee80211_local *local, } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC) { ret = drv_sta_add(local, sdata, &sta->sta); - if (ret == 0) + if (ret == 0) { sta->uploaded = true; + if (rcu_access_pointer(sta->sta.rates)) + drv_sta_rate_tbl_update(local, sdata, &sta->sta); + } } else if (old_state == IEEE80211_STA_ASSOC && new_state == IEEE80211_STA_AUTH) { drv_sta_remove(local, sdata, &sta->sta); diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 45927202c71c6..63652c39c8e07 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -960,7 +960,8 @@ int rate_control_set_rates(struct ieee80211_hw *hw, if (old) kfree_rcu(old, rcu_head); - drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta); + if (sta->uploaded) + drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta); ieee80211_sta_set_expected_throughput(pubsta, sta_get_expected_throughput(sta)); -- GitLab From 9ad22e165994ccb64d85b68499eaef97342c175b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 28 Jan 2021 22:16:27 +0100 Subject: [PATCH 0869/1084] x86/debug: Fix DR6 handling Tom reported that one of the GDB test-cases failed, and Boris bisected it to commit: d53d9bc0cf78 ("x86/debug: Change thread.debugreg6 to thread.virtual_dr6") The debugging session led us to commit: 6c0aca288e72 ("x86: Ignore trap bits on single step exceptions") It turns out that TF and data breakpoints are both traps and will be merged, while instruction breakpoints are faults and will not be merged. This means 6c0aca288e72 is wrong, only TF and instruction breakpoints need to be excluded while TF and data breakpoints can be merged. [ bp: Massage commit message. ] Fixes: d53d9bc0cf78 ("x86/debug: Change thread.debugreg6 to thread.virtual_dr6") Fixes: 6c0aca288e72 ("x86: Ignore trap bits on single step exceptions") Reported-by: Tom de Vries Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Borislav Petkov Cc: Link: https://lkml.kernel.org/r/YBMAbQGACujjfz%2Bi@hirez.programming.kicks-ass.net Link: https://lkml.kernel.org/r/20210128211627.GB4348@worktop.programming.kicks-ass.net --- arch/x86/kernel/hw_breakpoint.c | 39 +++++++++++++++------------------ 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 03aa33b581658..6694c0f8e6c16 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -491,15 +491,12 @@ static int hw_breakpoint_handler(struct die_args *args) struct perf_event *bp; unsigned long *dr6_p; unsigned long dr6; + bool bpx; /* The DR6 value is pointed by args->err */ dr6_p = (unsigned long *)ERR_PTR(args->err); dr6 = *dr6_p; - /* If it's a single step, TRAP bits are random */ - if (dr6 & DR_STEP) - return NOTIFY_DONE; - /* Do an early return if no trap bits are set in DR6 */ if ((dr6 & DR_TRAP_BITS) == 0) return NOTIFY_DONE; @@ -509,28 +506,29 @@ static int hw_breakpoint_handler(struct die_args *args) if (likely(!(dr6 & (DR_TRAP0 << i)))) continue; + bp = this_cpu_read(bp_per_reg[i]); + if (!bp) + continue; + + bpx = bp->hw.info.type == X86_BREAKPOINT_EXECUTE; + /* - * The counter may be concurrently released but that can only - * occur from a call_rcu() path. We can then safely fetch - * the breakpoint, use its callback, touch its counter - * while we are in an rcu_read_lock() path. + * TF and data breakpoints are traps and can be merged, however + * instruction breakpoints are faults and will be raised + * separately. + * + * However DR6 can indicate both TF and instruction + * breakpoints. In that case take TF as that has precedence and + * delay the instruction breakpoint for the next exception. */ - rcu_read_lock(); + if (bpx && (dr6 & DR_STEP)) + continue; - bp = this_cpu_read(bp_per_reg[i]); /* * Reset the 'i'th TRAP bit in dr6 to denote completion of * exception handling */ (*dr6_p) &= ~(DR_TRAP0 << i); - /* - * bp can be NULL due to lazy debug register switching - * or due to concurrent perf counter removing. - */ - if (!bp) { - rcu_read_unlock(); - break; - } perf_bp_event(bp, args->regs); @@ -538,11 +536,10 @@ static int hw_breakpoint_handler(struct die_args *args) * Set up resume flag to avoid breakpoint recursion when * returning back to origin. */ - if (bp->hw.info.type == X86_BREAKPOINT_EXECUTE) + if (bpx) args->regs->flags |= X86_EFLAGS_RF; - - rcu_read_unlock(); } + /* * Further processing in do_debug() is needed for a) user-space * breakpoints (to generate signals) and b) when the system has -- GitLab From bad4c6eb5eaa8300e065bd4426727db5141d687d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sun, 31 Jan 2021 16:16:23 -0500 Subject: [PATCH 0870/1084] SUNRPC: Fix NFS READs that start at non-page-aligned offsets Anj Duvnjak reports that the Kodi.tv NFS client is not able to read video files from a v5.10.11 Linux NFS server. The new sendpage-based TCP sendto logic was not attentive to non- zero page_base values. nfsd_splice_read() sets that field when a READ payload starts in the middle of a page. The Linux NFS client rarely emits an NFS READ that is not page- aligned. All of my testing so far has been with Linux clients, so I missed this one. Reported-by: A. Duvnjak BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=211471 Fixes: 4a85a6a3320b ("SUNRPC: Handle TCP socket sends with kernel_sendpage() again") Signed-off-by: Chuck Lever Tested-by: A. Duvnjak --- net/sunrpc/svcsock.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index c9766d07eb81a..5a809c64dc7b9 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1113,14 +1113,15 @@ static int svc_tcp_sendmsg(struct socket *sock, struct msghdr *msg, unsigned int offset, len, remaining; struct bio_vec *bvec; - bvec = xdr->bvec; - offset = xdr->page_base; + bvec = xdr->bvec + (xdr->page_base >> PAGE_SHIFT); + offset = offset_in_page(xdr->page_base); remaining = xdr->page_len; flags = MSG_MORE | MSG_SENDPAGE_NOTLAST; while (remaining > 0) { if (remaining <= PAGE_SIZE && tail->iov_len == 0) flags = 0; - len = min(remaining, bvec->bv_len); + + len = min(remaining, bvec->bv_len - offset); ret = kernel_sendpage(sock, bvec->bv_page, bvec->bv_offset + offset, len, flags); -- GitLab From de5bfae2fd962a9da99f56382305ec7966a604b9 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Sat, 23 Jan 2021 18:29:45 +0100 Subject: [PATCH 0871/1084] ASoC: cpcap: fix microphone timeslot mask The correct mask is 0x1f8 (Bit 3-8), but due to missing BIT() 0xf (Bit 0-3) was set instead. This means setting of CPCAP_BIT_MIC1_RX_TIMESLOT0 (Bit 3) still worked (part of both masks). On the other hand the code does not properly clear the other MIC timeslot bits. I think this is not a problem, since they are probably initialized to 0 and not touched by the driver anywhere else. But the mask also contains some wrong bits, that will be cleared. Bit 0 (CPCAP_BIT_SMB_CDC) should be safe, since the driver enforces it to be 0 anyways. Bit 1-2 are CPCAP_BIT_FS_INV and CPCAP_BIT_CLK_INV. This means enabling audio recording forces the codec into SND_SOC_DAIFMT_NB_NF mode, which is obviously bad. The bug probably remained undetected, because there are not many use cases for routing microphone to the CPU on platforms using cpcap and user base is small. I do remember having some issues with bad sound quality when testing voice recording back when I wrote the driver. It probably was this bug. Fixes: f6cdf2d3445d ("ASoC: cpcap: new codec") Reported-by: Dan Carpenter Signed-off-by: Sebastian Reichel Reviewed-by: Tony Lindgren Link: https://lore.kernel.org/r/20210123172945.3958622-1-sre@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/cpcap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c index f046987ee4cdb..c0425e3707d9c 100644 --- a/sound/soc/codecs/cpcap.c +++ b/sound/soc/codecs/cpcap.c @@ -1264,12 +1264,12 @@ static int cpcap_voice_hw_params(struct snd_pcm_substream *substream, if (direction == SNDRV_PCM_STREAM_CAPTURE) { mask = 0x0000; - mask |= CPCAP_BIT_MIC1_RX_TIMESLOT0; - mask |= CPCAP_BIT_MIC1_RX_TIMESLOT1; - mask |= CPCAP_BIT_MIC1_RX_TIMESLOT2; - mask |= CPCAP_BIT_MIC2_TIMESLOT0; - mask |= CPCAP_BIT_MIC2_TIMESLOT1; - mask |= CPCAP_BIT_MIC2_TIMESLOT2; + mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0); + mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT1); + mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT2); + mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT0); + mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT1); + mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT2); val = 0x0000; if (channels >= 2) val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0); -- GitLab From e8820dbddbcad7e91daacf7d42a49d1d04a4e489 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 1 Feb 2021 16:14:29 +0000 Subject: [PATCH 0872/1084] ASoC: codecs: add missing max_register in regmap config For some reason setting max_register was missed from regmap_config. Without this cat /sys/kernel/debug/regmap/sdw:0:217:2010:0:1/range actually throws below Warning. WARNING: CPU: 7 PID: 540 at drivers/base/regmap/regmap-debugfs.c:160 regmap_debugfs_get_dump_start.part.10+0x1e0/0x220 ... Call trace: regmap_debugfs_get_dump_start.part.10+0x1e0/0x220 regmap_reg_ranges_read_file+0xc0/0x2e0 full_proxy_read+0x64/0x98 vfs_read+0xa8/0x1e0 ksys_read+0x6c/0x100 __arm64_sys_read+0x1c/0x28 el0_svc_common.constprop.3+0x6c/0x190 do_el0_svc+0x24/0x90 el0_svc+0x14/0x20 el0_sync_handler+0x90/0xb8 el0_sync+0x158/0x180 ... Fixes: a0aab9e1404a ("ASoC: codecs: add wsa881x amplifier support") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210201161429.28060-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa881x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index 4530b74f5921b..db87e07b11c94 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -640,6 +640,7 @@ static struct regmap_config wsa881x_regmap_config = { .val_bits = 8, .cache_type = REGCACHE_RBTREE, .reg_defaults = wsa881x_defaults, + .max_register = WSA881X_SPKR_STATUS3, .num_reg_defaults = ARRAY_SIZE(wsa881x_defaults), .volatile_reg = wsa881x_volatile_register, .readable_reg = wsa881x_readable_register, -- GitLab From 7131636e7ea5b50ca910f8953f6365ef2d1f741c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 28 Jan 2021 11:45:00 -0500 Subject: [PATCH 0873/1084] KVM: x86: Allow guests to see MSR_IA32_TSX_CTRL even if tsx=off Userspace that does not know about KVM_GET_MSR_FEATURE_INDEX_LIST will generally use the default value for MSR_IA32_ARCH_CAPABILITIES. When this happens and the host has tsx=on, it is possible to end up with virtual machines that have HLE and RTM disabled, but TSX_CTRL available. If the fleet is then switched to tsx=off, kvm_get_arch_capabilities() will clear the ARCH_CAP_TSX_CTRL_MSR bit and it will not be possible to use the tsx=off hosts as migration destinations, even though the guests do not have TSX enabled. To allow this migration, allow guests to write to their TSX_CTRL MSR, while keeping the host MSR unchanged for the entire life of the guests. This ensures that TSX remains disabled and also saves MSR reads and writes, and it's okay to do because with tsx=off we know that guests will not have the HLE and RTM features in their CPUID. (If userspace sets bogus CPUID data, we do not expect HLE and RTM to work in guests anyway). Cc: stable@vger.kernel.org Fixes: cbbaa2727aa3 ("KVM: x86: fix presentation of TSX feature in ARCH_CAPABILITIES") Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 17 +++++++++++++---- arch/x86/kvm/x86.c | 26 +++++++++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index cc60b1fc3ee71..eb69fef57485d 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6860,11 +6860,20 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) switch (index) { case MSR_IA32_TSX_CTRL: /* - * No need to pass TSX_CTRL_CPUID_CLEAR through, so - * let's avoid changing CPUID bits under the host - * kernel's feet. + * TSX_CTRL_CPUID_CLEAR is handled in the CPUID + * interception. Keep the host value unchanged to avoid + * changing CPUID bits under the host kernel's feet. + * + * hle=0, rtm=0, tsx_ctrl=1 can be found with some + * combinations of new kernel and old userspace. If + * those guests run on a tsx=off host, do allow guests + * to use TSX_CTRL, but do not change the value on the + * host so that TSX remains always disabled. */ - vmx->guest_uret_msrs[j].mask = ~(u64)TSX_CTRL_CPUID_CLEAR; + if (boot_cpu_has(X86_FEATURE_RTM)) + vmx->guest_uret_msrs[j].mask = ~(u64)TSX_CTRL_CPUID_CLEAR; + else + vmx->guest_uret_msrs[j].mask = 0; break; default: vmx->guest_uret_msrs[j].mask = -1ull; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 76bce832cade2..b05a1fe9dae96 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1394,16 +1394,24 @@ static u64 kvm_get_arch_capabilities(void) if (!boot_cpu_has_bug(X86_BUG_MDS)) data |= ARCH_CAP_MDS_NO; - /* - * On TAA affected systems: - * - nothing to do if TSX is disabled on the host. - * - we emulate TSX_CTRL if present on the host. - * This lets the guest use VERW to clear CPU buffers. - */ - if (!boot_cpu_has(X86_FEATURE_RTM)) - data &= ~(ARCH_CAP_TAA_NO | ARCH_CAP_TSX_CTRL_MSR); - else if (!boot_cpu_has_bug(X86_BUG_TAA)) + if (!boot_cpu_has(X86_FEATURE_RTM)) { + /* + * If RTM=0 because the kernel has disabled TSX, the host might + * have TAA_NO or TSX_CTRL. Clear TAA_NO (the guest sees RTM=0 + * and therefore knows that there cannot be TAA) but keep + * TSX_CTRL: some buggy userspaces leave it set on tsx=on hosts, + * and we want to allow migrating those guests to tsx=off hosts. + */ + data &= ~ARCH_CAP_TAA_NO; + } else if (!boot_cpu_has_bug(X86_BUG_TAA)) { data |= ARCH_CAP_TAA_NO; + } else { + /* + * Nothing to do here; we emulate TSX_CTRL if present on the + * host so the guest can choose between disabling TSX or + * using VERW to clear CPU buffers. + */ + } return data; } -- GitLab From b66f9bab1279c281c83dea077c5e808527e3ef69 Mon Sep 17 00:00:00 2001 From: Zheng Zhan Liang Date: Mon, 1 Feb 2021 13:53:10 +0800 Subject: [PATCH 0874/1084] KVM/x86: assign hva with the right value to vm_munmap the pages Cc: Paolo Bonzini Cc: Wanpeng Li Cc: kvm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Zheng Zhan Liang Message-Id: <20210201055310.267029-1-zhengzhanliang@huorong.cn> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b05a1fe9dae96..42b28d0f0311b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10502,7 +10502,7 @@ void __user * __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, return 0; old_npages = slot->npages; - hva = 0; + hva = slot->userspace_addr; } for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { -- GitLab From 4683d758f48e6ae87d3d3493ffa00aceb955ee16 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 1 Feb 2021 15:28:43 +0100 Subject: [PATCH 0875/1084] KVM: x86: Supplement __cr4_reserved_bits() with X86_FEATURE_PCID check Commit 7a873e455567 ("KVM: selftests: Verify supported CR4 bits can be set before KVM_SET_CPUID2") reveals that KVM allows to set X86_CR4_PCIDE even when PCID support is missing: ==== Test Assertion Failure ==== x86_64/set_sregs_test.c:41: rc pid=6956 tid=6956 - Invalid argument 1 0x000000000040177d: test_cr4_feature_bit at set_sregs_test.c:41 2 0x00000000004014fc: main at set_sregs_test.c:119 3 0x00007f2d9346d041: ?? ??:0 4 0x000000000040164d: _start at ??:? KVM allowed unsupported CR4 bit (0x20000) Add X86_FEATURE_PCID feature check to __cr4_reserved_bits() to make kvm_is_valid_cr4() fail. Signed-off-by: Vitaly Kuznetsov Message-Id: <20210201142843.108190-1-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index c5ee0f5ce0f13..0f727b50bd3d2 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -425,6 +425,8 @@ bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type); __reserved_bits |= X86_CR4_UMIP; \ if (!__cpu_has(__c, X86_FEATURE_VMX)) \ __reserved_bits |= X86_CR4_VMXE; \ + if (!__cpu_has(__c, X86_FEATURE_PCID)) \ + __reserved_bits |= X86_CR4_PCIDE; \ __reserved_bits; \ }) -- GitLab From 0f347aa07f15b346a001e557f4a0a45069f7fa3d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 1 Feb 2021 17:34:19 +0100 Subject: [PATCH 0876/1084] ACPI: scan: Fix battery devices sometimes never binding With the new 2 step scanning process, which defers instantiating some ACPI-devices based on their _DEP to the second step, the following may happen: 1. During the first acpi_walk_namespace(acpi_bus_check_add) call acpi_scan_check_dep() gets called on the Battery ACPI dev handle and adds one or more deps for this handle to the acpi_dep_list 2. During the first acpi_bus_attach() call one or more of the suppliers of these deps get their driver attached and acpi_walk_dep_device_list(supplier_handle) gets called. At this point acpi_bus_get_device(dep->consumer) get called, but since the battery has DEPs it has not been instantiated during the first acpi_walk_namespace(acpi_bus_check_add), so the acpi_bus_get_device(dep->consumer) call fails. Before this commit, acpi_walk_dep_device_list() would now continue *without* removing the acpi_dep_data entry for this supplier,consumer pair from the acpi_dep_list. 3. During the second acpi_walk_namespace(acpi_bus_check_add) call an acpi_device gets instantiated for the battery and acpi_scan_dep_init() gets called to initialize its dep_unmet val. Before this commit, the dep_unmet count would include DEPs for suppliers for which acpi_walk_dep_device_list(supplier_handle) has already been called, so it will never become 0 and the ACPI battery driver will never get attached / bind. Fix the ACPI battery driver never binding in this scenario by making acpi_walk_dep_device_list() always remove matching acpi_dep_data entries independent of the acpi_bus_get_device(dep->consumer) call succeeding or not. Fixes: 71da201f38df ("ACPI: scan: Defer enumeration of devices with _DEP lists") Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 1db063b02f63e..22566b4b3150a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2123,12 +2123,12 @@ void acpi_walk_dep_device_list(acpi_handle handle) list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) { if (dep->supplier == handle) { acpi_bus_get_device(dep->consumer, &adev); - if (!adev) - continue; - adev->dep_unmet--; - if (!adev->dep_unmet) - acpi_bus_attach(adev, true); + if (adev) { + adev->dep_unmet--; + if (!adev->dep_unmet) + acpi_bus_attach(adev, true); + } list_del(&dep->node); kfree(dep); -- GitLab From 2e99dedc73f004f650b197c9b269c15c7e01ad15 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Wed, 2 Dec 2020 15:50:17 +0800 Subject: [PATCH 0877/1084] igc: Report speed and duplex as unknown when device is runtime suspended Similar to commit 165ae7a8feb5 ("igb: Report speed and duplex as unknown when device is runtime suspended"), if we try to read speed and duplex sysfs while the device is runtime suspended, igc will complain and stops working: [ 123.449883] igc 0000:03:00.0 enp3s0: PCIe link lost, device now detached [ 123.450052] BUG: kernel NULL pointer dereference, address: 0000000000000008 [ 123.450056] #PF: supervisor read access in kernel mode [ 123.450058] #PF: error_code(0x0000) - not-present page [ 123.450059] PGD 0 P4D 0 [ 123.450064] Oops: 0000 [#1] SMP NOPTI [ 123.450068] CPU: 0 PID: 2525 Comm: udevadm Tainted: G U W OE 5.10.0-1002-oem #2+rkl2-Ubuntu [ 123.450078] RIP: 0010:igc_rd32+0x1c/0x90 [igc] [ 123.450080] Code: c0 5d c3 b8 fd ff ff ff c3 0f 1f 44 00 00 0f 1f 44 00 00 55 89 f0 48 89 e5 41 56 41 55 41 54 49 89 c4 53 48 8b 57 08 48 01 d0 <44> 8b 28 41 83 fd ff 74 0c 5b 44 89 e8 41 5c 41 5d 4 [ 123.450083] RSP: 0018:ffffb0d100d6fcc0 EFLAGS: 00010202 [ 123.450085] RAX: 0000000000000008 RBX: ffffb0d100d6fd30 RCX: 0000000000000000 [ 123.450087] RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffff945a12716c10 [ 123.450089] RBP: ffffb0d100d6fce0 R08: ffff945a12716550 R09: ffff945a09874000 [ 123.450090] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000008 [ 123.450092] R13: ffff945a12716000 R14: ffff945a037da280 R15: ffff945a037da290 [ 123.450094] FS: 00007f3b34c868c0(0000) GS:ffff945b89200000(0000) knlGS:0000000000000000 [ 123.450096] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 123.450098] CR2: 0000000000000008 CR3: 00000001144de006 CR4: 0000000000770ef0 [ 123.450100] PKRU: 55555554 [ 123.450101] Call Trace: [ 123.450111] igc_ethtool_get_link_ksettings+0xd6/0x1b0 [igc] [ 123.450118] __ethtool_get_link_ksettings+0x71/0xb0 [ 123.450123] duplex_show+0x74/0xc0 [ 123.450129] dev_attr_show+0x1d/0x40 [ 123.450134] sysfs_kf_seq_show+0xa1/0x100 [ 123.450137] kernfs_seq_show+0x27/0x30 [ 123.450142] seq_read+0xb7/0x400 [ 123.450148] ? common_file_perm+0x72/0x170 [ 123.450151] kernfs_fop_read+0x35/0x1b0 [ 123.450155] vfs_read+0xb5/0x1b0 [ 123.450157] ksys_read+0x67/0xe0 [ 123.450160] __x64_sys_read+0x1a/0x20 [ 123.450164] do_syscall_64+0x38/0x90 [ 123.450168] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 123.450170] RIP: 0033:0x7f3b351fe142 [ 123.450173] Code: c0 e9 c2 fe ff ff 50 48 8d 3d 3a ca 0a 00 e8 f5 19 02 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24 [ 123.450174] RSP: 002b:00007fffef2ec138 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 [ 123.450177] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f3b351fe142 [ 123.450179] RDX: 0000000000001001 RSI: 00005644c047f070 RDI: 0000000000000003 [ 123.450180] RBP: 00007fffef2ec340 R08: 00005644c047f070 R09: 00007f3b352d9320 [ 123.450182] R10: 00005644c047c010 R11: 0000000000000246 R12: 00005644c047cbf0 [ 123.450184] R13: 00005644c047e6d0 R14: 0000000000000003 R15: 00007fffef2ec140 [ 123.450189] Modules linked in: rfcomm ccm cmac algif_hash algif_skcipher af_alg bnep toshiba_acpi industrialio toshiba_haps hp_accel lis3lv02d btusb btrtl btbcm btintel bluetooth ecdh_generic ecc joydev input_leds nls_iso8859_1 snd_sof_pci snd_sof_intel_byt snd_sof_intel_ipc snd_sof_intel_hda_common snd_soc_hdac_hda snd_hda_codec_hdmi snd_sof_xtensa_dsp snd_sof_intel_hda snd_sof snd_hda_ext_core snd_soc_acpi_intel_match snd_soc_acpi snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_dspcfg soundwire_intel soundwire_generic_allocation soundwire_cadence snd_hda_codec snd_hda_core ath10k_pci snd_hwdep intel_rapl_msr intel_rapl_common ath10k_core soundwire_bus snd_soc_core x86_pkg_temp_thermal ath intel_powerclamp snd_compress ac97_bus snd_pcm_dmaengine mac80211 snd_pcm coretemp snd_seq_midi snd_seq_midi_event snd_rawmidi kvm_intel cfg80211 snd_seq snd_seq_device snd_timer mei_hdcp kvm libarc4 snd crct10dif_pclmul ghash_clmulni_intel aesni_intel mei_me dell_wmi [ 123.450266] dell_smbios soundcore sparse_keymap dcdbas crypto_simd cryptd mei dell_uart_backlight glue_helper ee1004 wmi_bmof intel_wmi_thunderbolt dell_wmi_descriptor mac_hid efi_pstore acpi_pad acpi_tad intel_cstate sch_fq_codel parport_pc ppdev lp parport ip_tables x_tables autofs4 btrfs blake2b_generic raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid1 raid0 multipath linear dm_mirror dm_region_hash dm_log hid_generic usbhid hid i915 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec crc32_pclmul rc_core drm intel_lpss_pci i2c_i801 ahci igc intel_lpss i2c_smbus idma64 xhci_pci libahci virt_dma xhci_pci_renesas wmi video pinctrl_tigerlake [ 123.450335] CR2: 0000000000000008 [ 123.450338] ---[ end trace 9f731e38b53c35cc ]--- The more generic approach will be wrap get_link_ksettings() with begin() and complete() callbacks, and calls runtime resume and runtime suspend routine respectively. However, igc is like igb, runtime resume routine uses rtnl_lock() which upper ethtool layer also uses. So to prevent a deadlock on rtnl, take a different approach, use pm_runtime_suspended() to avoid reading register while device is runtime suspended. Fixes: 8c5ad0dae93c ("igc: Add ethtool support") Signed-off-by: Kai-Heng Feng Acked-by: Sasha Neftin Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/igc/igc_ethtool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index 831f2f09de5fb..ec8cd69d49928 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -1714,7 +1714,8 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev, Asym_Pause); } - status = rd32(IGC_STATUS); + status = pm_runtime_suspended(&adapter->pdev->dev) ? + 0 : rd32(IGC_STATUS); if (status & IGC_STATUS_LU) { if (status & IGC_STATUS_SPEED_1000) { -- GitLab From ebc8d125062e7dccb7922b2190b097c20d88ad96 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Sun, 20 Dec 2020 22:18:19 +0800 Subject: [PATCH 0878/1084] igc: set the default return value to -IGC_ERR_NVM in igc_write_nvm_srwr This patch sets the default return value to -IGC_ERR_NVM in igc_write_nvm_srwr. Without this change it wouldn't lead to a shadow RAM write EEWR timeout. Fixes: ab4056126813 ("igc: Add NVM support") Signed-off-by: Kevin Lo Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/igc/igc_i225.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igc/igc_i225.c b/drivers/net/ethernet/intel/igc/igc_i225.c index 8b67d9b49a83a..7ec04e48860c6 100644 --- a/drivers/net/ethernet/intel/igc/igc_i225.c +++ b/drivers/net/ethernet/intel/igc/igc_i225.c @@ -219,9 +219,9 @@ static s32 igc_write_nvm_srwr(struct igc_hw *hw, u16 offset, u16 words, u16 *data) { struct igc_nvm_info *nvm = &hw->nvm; + s32 ret_val = -IGC_ERR_NVM; u32 attempts = 100000; u32 i, k, eewr = 0; - s32 ret_val = 0; /* A check for invalid values: offset too large, too many words, * too many words for the offset, and not enough words. @@ -229,7 +229,6 @@ static s32 igc_write_nvm_srwr(struct igc_hw *hw, u16 offset, u16 words, if (offset >= nvm->word_size || (words > (nvm->word_size - offset)) || words == 0) { hw_dbg("nvm parameter(s) out of bounds\n"); - ret_val = -IGC_ERR_NVM; goto out; } -- GitLab From b881145642ce0bbe2be521e0882e72a5cebe93b8 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Thu, 7 Jan 2021 14:10:38 +0800 Subject: [PATCH 0879/1084] igc: check return value of ret_val in igc_config_fc_after_link_up Check return value from ret_val to make error check actually work. Fixes: 4eb8080143a9 ("igc: Add setup link functionality") Signed-off-by: Kevin Lo Acked-by: Sasha Neftin Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/igc/igc_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/igc/igc_mac.c b/drivers/net/ethernet/intel/igc/igc_mac.c index 09cd0ec7ee87d..67b8ffd21d8af 100644 --- a/drivers/net/ethernet/intel/igc/igc_mac.c +++ b/drivers/net/ethernet/intel/igc/igc_mac.c @@ -638,7 +638,7 @@ s32 igc_config_fc_after_link_up(struct igc_hw *hw) } out: - return 0; + return ret_val; } /** -- GitLab From 50af06d43eab6b09afc37aa7c8bbf69b14a3b2f7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 1 Feb 2021 16:29:56 +0100 Subject: [PATCH 0880/1084] staging: rtl8723bs: Move wiphy setup to after reading the regulatory settings from the chip Commit 81f153faacd0 ("staging: rtl8723bs: fix wireless regulatory API misuse") moved the wiphy_apply_custom_regulatory() call to earlier in the driver's init-sequence, so that it gets called before wiphy_register(). But at this point in time the eFuses which code the regulatory-settings for the chip have not been read by the driver yet, causing _rtw_reg_apply_flags() to set the IEEE80211_CHAN_DISABLED flag on *all* channels. On the device where I initially tested the fix, a Jumper EZpad 7 tablet, this does not cause any problems because shortly after init the rtw_reg_notifier() gets called fixing things up. I guess this happens into response to receiving a (broadcast) packet with regulatory info from the access-point ? But on another device with a RTL8723BS wifi chip, an Acer Switch 10E (SW3-016), the rtw_reg_notifier() never gets called. I assume that some fuse has been set on this device to ignore regulatory info received from access-points. This means that on the Acer the driver is stuck in a state with all channels disabled, leading to non working Wifi. We cannot move the wiphy_apply_custom_regulatory() call back, because that call must be made before the wiphy_register() call. Instead move the entire rtw_wdev_alloc() call to after the Efuses have been read, fixing all channels being disabled in the initial channel-map. Fixes: 81f153faacd0 ("staging: rtl8723bs: fix wireless regulatory API misuse") Cc: Johannes Berg Signed-off-by: Hans de Goede Acked-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20210201152956.370186-2-hdegoede@redhat.com Signed-off-by: Johannes Berg --- drivers/staging/rtl8723bs/os_dep/sdio_intf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c index b2208e5f190ad..301ffff12e82b 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c @@ -339,8 +339,6 @@ static struct adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj, const struct padapter = rtw_netdev_priv(pnetdev); - rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj)); - /* 3 3. init driver special setting, interface, OS and hardware relative */ /* 4 3.1 set hardware operation functions */ @@ -378,6 +376,8 @@ static struct adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj, const struct goto free_hal_data; } + rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj)); + /* 3 8. get WLan MAC address */ /* set mac addr */ rtw_macaddr_cfg(&psdio->func->dev, padapter->eeprompriv.mac_addr); -- GitLab From 8acf417805a5f5c69e9ff66f14cab022c2755161 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Mon, 1 Feb 2021 19:00:07 +0000 Subject: [PATCH 0881/1084] x86/split_lock: Enable the split lock feature on another Alder Lake CPU Add Alder Lake mobile processor to CPU list to enumerate and enable the split lock feature. Signed-off-by: Fenghua Yu Signed-off-by: Borislav Petkov Reviewed-by: Tony Luck Link: https://lkml.kernel.org/r/20210201190007.4031869-1-fenghua.yu@intel.com --- arch/x86/kernel/cpu/intel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 59a1e3ce3f145..816fdbec795a4 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -1159,6 +1159,7 @@ static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = { X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, 1), X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, 1), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, 1), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, 1), {} }; -- GitLab From f559a356043a55bab25a4c00505ea65c50a956fb Mon Sep 17 00:00:00 2001 From: Aleksandr Loktionov Date: Sat, 23 Jan 2021 00:22:23 +0000 Subject: [PATCH 0882/1084] i40e: Revert "i40e: don't report link up for a VF who hasn't enabled queues" This reverts commit 2ad1274fa35ace5c6360762ba48d33b63da2396c VF queues were not brought up when PF was brought up after being downed if the VF driver disabled VFs queues during PF down. This could happen in some older or external VF driver implementations. The problem was that PF driver used vf->queues_enabled as a condition to decide what link-state it would send out which caused the issue. Remove the check for vf->queues_enabled in the VF link notify. Now VF will always be notified of the current link status. Also remove the queues_enabled member from i40e_vf structure as it is not used anymore. Otherwise VNF implementation was broken and caused a link flap. The original commit was a workaround to avoid breaking existing VFs though it's really a fault of the VF code not the PF. The commit should be safe to revert as all of the VFs we know of have been fixed. Also, since we now know there is a related bug in the workaround, removing it is preferred. Fixes: 2ad1274fa35a ("i40e: don't report link up for a VF who hasn't enabled") Signed-off-by: Aleksandr Loktionov Signed-off-by: Arkadiusz Kubalewski Tested-by: Konrad Jankowski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 13 +------------ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h | 1 - 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 7efc61aacb0a5..1b6ec9be155a6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -55,12 +55,7 @@ static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf) pfe.event = VIRTCHNL_EVENT_LINK_CHANGE; pfe.severity = PF_EVENT_SEVERITY_INFO; - - /* Always report link is down if the VF queues aren't enabled */ - if (!vf->queues_enabled) { - pfe.event_data.link_event.link_status = false; - pfe.event_data.link_event.link_speed = 0; - } else if (vf->link_forced) { + if (vf->link_forced) { pfe.event_data.link_event.link_status = vf->link_up; pfe.event_data.link_event.link_speed = (vf->link_up ? i40e_virtchnl_link_speed(ls->link_speed) : 0); @@ -70,7 +65,6 @@ static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf) pfe.event_data.link_event.link_speed = i40e_virtchnl_link_speed(ls->link_speed); } - i40e_aq_send_msg_to_vf(hw, abs_vf_id, VIRTCHNL_OP_EVENT, 0, (u8 *)&pfe, sizeof(pfe), NULL); } @@ -2443,8 +2437,6 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg) } } - vf->queues_enabled = true; - error_param: /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_ENABLE_QUEUES, @@ -2466,9 +2458,6 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg) struct i40e_pf *pf = vf->pf; i40e_status aq_ret = 0; - /* Immediately mark queues as disabled */ - vf->queues_enabled = false; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { aq_ret = I40E_ERR_PARAM; goto error_param; diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h index 5491215d81deb..091e32c1bb46f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h @@ -98,7 +98,6 @@ struct i40e_vf { unsigned int tx_rate; /* Tx bandwidth limit in Mbps */ bool link_forced; bool link_up; /* only valid if VF link is forced */ - bool queues_enabled; /* true if the VF queues are enabled */ bool spoofchk; u16 num_vlan; -- GitLab From 7018c897c2f243d4b5f1b94bc6b4831a7eab80fb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 1 Feb 2021 16:20:40 -0800 Subject: [PATCH 0883/1084] libnvdimm/dimm: Avoid race between probe and available_slots_show() Richard reports that the following test: (while true; do cat /sys/bus/nd/devices/nmem*/available_slots 2>&1 > /dev/null done) & while true; do for i in $(seq 0 4); do echo nmem$i > /sys/bus/nd/drivers/nvdimm/bind done for i in $(seq 0 4); do echo nmem$i > /sys/bus/nd/drivers/nvdimm/unbind done done ...fails with a crash signature like: divide error: 0000 [#1] SMP KASAN PTI RIP: 0010:nd_label_nfree+0x134/0x1a0 [libnvdimm] [..] Call Trace: available_slots_show+0x4e/0x120 [libnvdimm] dev_attr_show+0x42/0x80 ? memset+0x20/0x40 sysfs_kf_seq_show+0x218/0x410 The root cause is that available_slots_show() consults driver-data, but fails to synchronize against device-unbind setting up a TOCTOU race to access uninitialized memory. Validate driver-data under the device-lock. Fixes: 4d88a97aa9e8 ("libnvdimm, nvdimm: dimm driver and base libnvdimm device-driver infrastructure") Cc: Cc: Vishal Verma Cc: Dave Jiang Cc: Ira Weiny Cc: Coly Li Reported-by: Richard Palethorpe Acked-by: Richard Palethorpe Signed-off-by: Dan Williams --- drivers/nvdimm/dimm_devs.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index b59032e0859b7..9d208570d059a 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -335,16 +335,16 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(state); -static ssize_t available_slots_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t __available_slots_show(struct nvdimm_drvdata *ndd, char *buf) { - struct nvdimm_drvdata *ndd = dev_get_drvdata(dev); + struct device *dev; ssize_t rc; u32 nfree; if (!ndd) return -ENXIO; + dev = ndd->dev; nvdimm_bus_lock(dev); nfree = nd_label_nfree(ndd); if (nfree - 1 > nfree) { @@ -356,6 +356,18 @@ static ssize_t available_slots_show(struct device *dev, nvdimm_bus_unlock(dev); return rc; } + +static ssize_t available_slots_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t rc; + + nd_device_lock(dev); + rc = __available_slots_show(dev_get_drvdata(dev), buf); + nd_device_unlock(dev); + + return rc; +} static DEVICE_ATTR_RO(available_slots); __weak ssize_t security_show(struct device *dev, -- GitLab From f72f2fb8fb6be095b98af5d740ac50cffd0b0cae Mon Sep 17 00:00:00 2001 From: DENG Qingfang Date: Sat, 30 Jan 2021 21:43:34 +0800 Subject: [PATCH 0884/1084] net: dsa: mv88e6xxx: override existent unicast portvec in port_fdb_add Having multiple destination ports for a unicast address does not make sense. Make port_db_load_purge override existent unicast portvec instead of adding a new port bit. Fixes: 884729399260 ("net: dsa: mv88e6xxx: handle multiple ports in ATU") Signed-off-by: DENG Qingfang Reviewed-by: Vladimir Oltean Link: https://lore.kernel.org/r/20210130134334.10243-1-dqfext@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/mv88e6xxx/chip.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index eafe6bedc692e..54aa942eedaa6 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -1676,7 +1676,11 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, if (!entry.portvec) entry.state = 0; } else { - entry.portvec |= BIT(port); + if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC) + entry.portvec = BIT(port); + else + entry.portvec |= BIT(port); + entry.state = state; } -- GitLab From 5e9eff5dfa460cd1a74b7c1fde4fced7c04383af Mon Sep 17 00:00:00 2001 From: Lijun Pan Date: Thu, 28 Jan 2021 22:34:01 -0600 Subject: [PATCH 0885/1084] ibmvnic: device remove has higher precedence over reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returning -EBUSY in ibmvnic_remove() does not actually hold the removal procedure since driver core doesn't care for the return value (see __device_release_driver() in drivers/base/dd.c calling dev->bus->remove()) though vio_bus_remove (in arch/powerpc/platforms/pseries/vio.c) records the return value and passes it on. [1] During the device removal precedure, checking for resetting bit is dropped so that we can continue executing all the cleanup calls in the rest of the remove function. Otherwise, it can cause latent memory leaks and kernel crashes. [1] https://lore.kernel.org/linuxppc-dev/20210117101242.dpwayq6wdgfdzirl@pengutronix.de/T/#m48f5befd96bc9842ece2a3ad14f4c27747206a53 Reported-by: Uwe Kleine-König Fixes: 7d7195a026ba ("ibmvnic: Do not process device remove during device reset") Signed-off-by: Lijun Pan Link: https://lore.kernel.org/r/20210129043402.95744-1-ljp@linux.ibm.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/ibm/ibmvnic.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 8820c98ea891e..f79034c786c84 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -5444,11 +5444,6 @@ static int ibmvnic_remove(struct vio_dev *dev) unsigned long flags; spin_lock_irqsave(&adapter->state_lock, flags); - if (test_bit(0, &adapter->resetting)) { - spin_unlock_irqrestore(&adapter->state_lock, flags); - return -EBUSY; - } - adapter->state = VNIC_REMOVING; spin_unlock_irqrestore(&adapter->state_lock, flags); -- GitLab From 938e0fcd3253efdef8924714158911286d08cfe1 Mon Sep 17 00:00:00 2001 From: Alexander Ovechkin Date: Mon, 1 Feb 2021 23:00:49 +0300 Subject: [PATCH 0886/1084] net: sched: replaced invalid qdisc tree flush helper in qdisc_replace Commit e5f0e8f8e456 ("net: sched: introduce and use qdisc tree flush/purge helpers") introduced qdisc tree flush/purge helpers, but erroneously used flush helper instead of purge helper in qdisc_replace function. This issue was found in our CI, that tests various qdisc setups by configuring qdisc and sending data through it. Call of invalid helper sporadically leads to corruption of vt_tree/cf_tree of hfsc_class that causes kernel oops: Oops: 0000 [#1] SMP PTI CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.11.0-8f6859df #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.10.2-0-g5f4c7b1-prebuilt.qemu-project.org 04/01/2014 RIP: 0010:rb_insert_color+0x18/0x190 Code: c3 31 c0 c3 0f 1f 40 00 66 2e 0f 1f 84 00 00 00 00 00 48 8b 07 48 85 c0 0f 84 05 01 00 00 48 8b 10 f6 c2 01 0f 85 34 01 00 00 <48> 8b 4a 08 49 89 d0 48 39 c1 74 7d 48 85 c9 74 32 f6 01 01 75 2d RSP: 0018:ffffc900000b8bb0 EFLAGS: 00010246 RAX: ffff8881ef4c38b0 RBX: ffff8881d956e400 RCX: ffff8881ef4c38b0 RDX: 0000000000000000 RSI: ffff8881d956f0a8 RDI: ffff8881d956e4b0 RBP: 0000000000000000 R08: 000000d5c4e249da R09: 1600000000000000 R10: ffffc900000b8be0 R11: ffffc900000b8b28 R12: 0000000000000001 R13: 000000000000005a R14: ffff8881f0905000 R15: ffff8881f0387d00 FS: 0000000000000000(0000) GS:ffff8881f8b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 00000001f4796004 CR4: 0000000000060ee0 Call Trace: init_vf.isra.19+0xec/0x250 [sch_hfsc] hfsc_enqueue+0x245/0x300 [sch_hfsc] ? fib_rules_lookup+0x12a/0x1d0 ? __dev_queue_xmit+0x4b6/0x930 ? hfsc_delete_class+0x250/0x250 [sch_hfsc] __dev_queue_xmit+0x4b6/0x930 ? ip6_finish_output2+0x24d/0x590 ip6_finish_output2+0x24d/0x590 ? ip6_output+0x6c/0x130 ip6_output+0x6c/0x130 ? __ip6_finish_output+0x110/0x110 mld_sendpack+0x224/0x230 mld_ifc_timer_expire+0x186/0x2c0 ? igmp6_group_dropped+0x200/0x200 call_timer_fn+0x2d/0x150 run_timer_softirq+0x20c/0x480 ? tick_sched_do_timer+0x60/0x60 ? tick_sched_timer+0x37/0x70 __do_softirq+0xf7/0x2cb irq_exit+0xa0/0xb0 smp_apic_timer_interrupt+0x74/0x150 apic_timer_interrupt+0xf/0x20 Fixes: e5f0e8f8e456 ("net: sched: introduce and use qdisc tree flush/purge helpers") Signed-off-by: Alexander Ovechkin Reported-by: Alexander Kuznetsov Acked-by: Dmitry Monakhov Acked-by: Dmitry Yakunin Acked-by: Cong Wang Link: https://lore.kernel.org/r/20210201200049.299153-1-ovov@yandex-team.ru Signed-off-by: Jakub Kicinski --- include/net/sch_generic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 639e465a108f4..5b490b5591df5 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -1143,7 +1143,7 @@ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new, old = *pold; *pold = new; if (old != NULL) - qdisc_tree_flush_backlog(old); + qdisc_purge_queue(old); sch_tree_unlock(sch); return old; -- GitLab From c518adafa39f37858697ac9309c6cf1805581446 Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Mon, 1 Feb 2021 11:47:19 +0300 Subject: [PATCH 0887/1084] vsock: fix the race conditions in multi-transport support There are multiple similar bugs implicitly introduced by the commit c0cfa2d8a788fcf4 ("vsock: add multi-transports support") and commit 6a2c0962105ae8ce ("vsock: prevent transport modules unloading"). The bug pattern: [1] vsock_sock.transport pointer is copied to a local variable, [2] lock_sock() is called, [3] the local variable is used. VSOCK multi-transport support introduced the race condition: vsock_sock.transport value may change between [1] and [2]. Let's copy vsock_sock.transport pointer to local variables after the lock_sock() call. Fixes: c0cfa2d8a788fcf4 ("vsock: add multi-transports support") Signed-off-by: Alexander Popov Reviewed-by: Stefano Garzarella Reviewed-by: Jorgen Hansen Link: https://lore.kernel.org/r/20210201084719.2257066-1-alex.popov@linux.com Signed-off-by: Jakub Kicinski --- net/vmw_vsock/af_vsock.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index b12d3a3222428..6894f21dc1475 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1014,9 +1014,12 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock, mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND; } else if (sock->type == SOCK_STREAM) { - const struct vsock_transport *transport = vsk->transport; + const struct vsock_transport *transport; + lock_sock(sk); + transport = vsk->transport; + /* Listening sockets that have connections in their accept * queue can be read. */ @@ -1099,10 +1102,11 @@ static int vsock_dgram_sendmsg(struct socket *sock, struct msghdr *msg, err = 0; sk = sock->sk; vsk = vsock_sk(sk); - transport = vsk->transport; lock_sock(sk); + transport = vsk->transport; + err = vsock_auto_bind(vsk); if (err) goto out; @@ -1561,10 +1565,11 @@ static int vsock_stream_setsockopt(struct socket *sock, err = 0; sk = sock->sk; vsk = vsock_sk(sk); - transport = vsk->transport; lock_sock(sk); + transport = vsk->transport; + switch (optname) { case SO_VM_SOCKETS_BUFFER_SIZE: COPY_IN(val); @@ -1697,7 +1702,6 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg, sk = sock->sk; vsk = vsock_sk(sk); - transport = vsk->transport; total_written = 0; err = 0; @@ -1706,6 +1710,8 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg, lock_sock(sk); + transport = vsk->transport; + /* Callers should not provide a destination with stream sockets. */ if (msg->msg_namelen) { err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; @@ -1840,11 +1846,12 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, sk = sock->sk; vsk = vsock_sk(sk); - transport = vsk->transport; err = 0; lock_sock(sk); + transport = vsk->transport; + if (!transport || sk->sk_state != TCP_ESTABLISHED) { /* Recvmsg is supposed to return 0 if a peer performs an * orderly shutdown. Differentiate between that case and when a -- GitLab From 28e104d00281ade30250b24e098bf50887671ea4 Mon Sep 17 00:00:00 2001 From: Vadim Fedorenko Date: Sat, 30 Jan 2021 01:27:47 +0300 Subject: [PATCH 0888/1084] net: ip_tunnel: fix mtu calculation dev->hard_header_len for tunnel interface is set only when header_ops are set too and already contains full overhead of any tunnel encapsulation. That's why there is not need to use this overhead twice in mtu calc. Fixes: fdafed459998 ("ip_gre: set dev->hard_header_len and dev->needed_headroom properly") Reported-by: Slava Bacherikov Signed-off-by: Vadim Fedorenko Link: https://lore.kernel.org/r/1611959267-20536-1-git-send-email-vfedorenko@novek.ru Signed-off-by: Jakub Kicinski --- net/ipv4/ip_tunnel.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 64594aa755f05..76a420c76f16e 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -317,7 +317,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev) } dev->needed_headroom = t_hlen + hlen; - mtu -= (dev->hard_header_len + t_hlen); + mtu -= t_hlen; if (mtu < IPV4_MIN_MTU) mtu = IPV4_MIN_MTU; @@ -347,7 +347,7 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net, nt = netdev_priv(dev); t_hlen = nt->hlen + sizeof(struct iphdr); dev->min_mtu = ETH_MIN_MTU; - dev->max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen; + dev->max_mtu = IP_MAX_MTU - t_hlen; ip_tunnel_add(itn, nt); return nt; @@ -488,11 +488,10 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, int mtu; tunnel_hlen = md ? tunnel_hlen : tunnel->hlen; - pkt_size = skb->len - tunnel_hlen - dev->hard_header_len; + pkt_size = skb->len - tunnel_hlen; if (df) - mtu = dst_mtu(&rt->dst) - dev->hard_header_len - - sizeof(struct iphdr) - tunnel_hlen; + mtu = dst_mtu(&rt->dst) - (sizeof(struct iphdr) + tunnel_hlen); else mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; @@ -972,7 +971,7 @@ int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict) { struct ip_tunnel *tunnel = netdev_priv(dev); int t_hlen = tunnel->hlen + sizeof(struct iphdr); - int max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen; + int max_mtu = IP_MAX_MTU - t_hlen; if (new_mtu < ETH_MIN_MTU) return -EINVAL; @@ -1149,10 +1148,9 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[], mtu = ip_tunnel_bind_dev(dev); if (tb[IFLA_MTU]) { - unsigned int max = IP_MAX_MTU - dev->hard_header_len - nt->hlen; + unsigned int max = IP_MAX_MTU - (nt->hlen + sizeof(struct iphdr)); - mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU, - (unsigned int)(max - sizeof(struct iphdr))); + mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU, max); } err = dev_set_mtu(dev, mtu); -- GitLab From c3df39ac9b0e3747bf8233ea9ce4ed5ceb3199d3 Mon Sep 17 00:00:00 2001 From: Dongseok Yi Date: Sat, 30 Jan 2021 08:13:27 +0900 Subject: [PATCH 0889/1084] udp: ipv4: manipulate network header of NATed UDP GRO fraglist UDP/IP header of UDP GROed frag_skbs are not updated even after NAT forwarding. Only the header of head_skb from ip_finish_output_gso -> skb_gso_segment is updated but following frag_skbs are not updated. A call path skb_mac_gso_segment -> inet_gso_segment -> udp4_ufo_fragment -> __udp_gso_segment -> __udp_gso_segment_list does not try to update UDP/IP header of the segment list but copy only the MAC header. Update port, addr and check of each skb of the segment list in __udp_gso_segment_list. It covers both SNAT and DNAT. Fixes: 9fd1ff5d2ac7 (udp: Support UDP fraglist GRO/GSO.) Signed-off-by: Dongseok Yi Acked-by: Steffen Klassert Link: https://lore.kernel.org/r/1611962007-80092-1-git-send-email-dseok.yi@samsung.com Signed-off-by: Jakub Kicinski --- include/net/udp.h | 2 +- net/ipv4/udp_offload.c | 69 +++++++++++++++++++++++++++++++++++++++--- net/ipv6/udp_offload.c | 2 +- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/include/net/udp.h b/include/net/udp.h index 877832bed4713..01351ba25b874 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -178,7 +178,7 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, int udp_gro_complete(struct sk_buff *skb, int nhoff, udp_lookup_t lookup); struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, - netdev_features_t features); + netdev_features_t features, bool is_ipv6); static inline struct udphdr *udp_gro_udphdr(struct sk_buff *skb) { diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index ff39e94781bfb..cfc872689b997 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -187,8 +187,67 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, } EXPORT_SYMBOL(skb_udp_tunnel_segment); +static void __udpv4_gso_segment_csum(struct sk_buff *seg, + __be32 *oldip, __be32 *newip, + __be16 *oldport, __be16 *newport) +{ + struct udphdr *uh; + struct iphdr *iph; + + if (*oldip == *newip && *oldport == *newport) + return; + + uh = udp_hdr(seg); + iph = ip_hdr(seg); + + if (uh->check) { + inet_proto_csum_replace4(&uh->check, seg, *oldip, *newip, + true); + inet_proto_csum_replace2(&uh->check, seg, *oldport, *newport, + false); + if (!uh->check) + uh->check = CSUM_MANGLED_0; + } + *oldport = *newport; + + csum_replace4(&iph->check, *oldip, *newip); + *oldip = *newip; +} + +static struct sk_buff *__udpv4_gso_segment_list_csum(struct sk_buff *segs) +{ + struct sk_buff *seg; + struct udphdr *uh, *uh2; + struct iphdr *iph, *iph2; + + seg = segs; + uh = udp_hdr(seg); + iph = ip_hdr(seg); + + if ((udp_hdr(seg)->dest == udp_hdr(seg->next)->dest) && + (udp_hdr(seg)->source == udp_hdr(seg->next)->source) && + (ip_hdr(seg)->daddr == ip_hdr(seg->next)->daddr) && + (ip_hdr(seg)->saddr == ip_hdr(seg->next)->saddr)) + return segs; + + while ((seg = seg->next)) { + uh2 = udp_hdr(seg); + iph2 = ip_hdr(seg); + + __udpv4_gso_segment_csum(seg, + &iph2->saddr, &iph->saddr, + &uh2->source, &uh->source); + __udpv4_gso_segment_csum(seg, + &iph2->daddr, &iph->daddr, + &uh2->dest, &uh->dest); + } + + return segs; +} + static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb, - netdev_features_t features) + netdev_features_t features, + bool is_ipv6) { unsigned int mss = skb_shinfo(skb)->gso_size; @@ -198,11 +257,11 @@ static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb, udp_hdr(skb)->len = htons(sizeof(struct udphdr) + mss); - return skb; + return is_ipv6 ? skb : __udpv4_gso_segment_list_csum(skb); } struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, - netdev_features_t features) + netdev_features_t features, bool is_ipv6) { struct sock *sk = gso_skb->sk; unsigned int sum_truesize = 0; @@ -214,7 +273,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, __be16 newlen; if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) - return __udp_gso_segment_list(gso_skb, features); + return __udp_gso_segment_list(gso_skb, features, is_ipv6); mss = skb_shinfo(gso_skb)->gso_size; if (gso_skb->len <= sizeof(*uh) + mss) @@ -328,7 +387,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, goto out; if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) - return __udp_gso_segment(skb, features); + return __udp_gso_segment(skb, features, false); mss = skb_shinfo(skb)->gso_size; if (unlikely(skb->len <= mss)) diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index c7bd7b1a04c13..faa823c242923 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c @@ -42,7 +42,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, goto out; if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) - return __udp_gso_segment(skb, features); + return __udp_gso_segment(skb, features, true); mss = skb_shinfo(skb)->gso_size; if (unlikely(skb->len <= mss)) -- GitLab From 31628201545548e1ef167f2c55eb6fd7d3562f12 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Sat, 30 Jan 2021 20:05:18 +0100 Subject: [PATCH 0890/1084] docs: networking: swap words in icmp_errors_use_inbound_ifaddr doc Signed-off-by: Vincent Bernat Link: https://lore.kernel.org/r/20210130190518.854806-1-vincent@bernat.ch Signed-off-by: Jakub Kicinski --- Documentation/networking/ip-sysctl.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index c7b775da95542..fa544e9037b99 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -1196,7 +1196,7 @@ icmp_errors_use_inbound_ifaddr - BOOLEAN If non-zero, the message will be sent with the primary address of the interface that received the packet that caused the icmp error. - This is the behaviour network many administrators will expect from + This is the behaviour many network administrators will expect from a router. And it can make debugging complicated network layouts much easier. -- GitLab From 8d8d1dbefc423d42d626cf5b81aac214870ebaab Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 1 Feb 2021 20:36:54 -0600 Subject: [PATCH 0891/1084] smb3: Fix out-of-bounds bug in SMB2_negotiate() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While addressing some warnings generated by -Warray-bounds, I found this bug that was introduced back in 2017: CC [M] fs/cifs/smb2pdu.o fs/cifs/smb2pdu.c: In function ‘SMB2_negotiate’: fs/cifs/smb2pdu.c:822:16: warning: array subscript 1 is above array bounds of ‘__le16[1]’ {aka ‘short unsigned int[1]’} [-Warray-bounds] 822 | req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); | ~~~~~~~~~~~~~^~~ fs/cifs/smb2pdu.c:823:16: warning: array subscript 2 is above array bounds of ‘__le16[1]’ {aka ‘short unsigned int[1]’} [-Warray-bounds] 823 | req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); | ~~~~~~~~~~~~~^~~ fs/cifs/smb2pdu.c:824:16: warning: array subscript 3 is above array bounds of ‘__le16[1]’ {aka ‘short unsigned int[1]’} [-Warray-bounds] 824 | req->Dialects[3] = cpu_to_le16(SMB311_PROT_ID); | ~~~~~~~~~~~~~^~~ fs/cifs/smb2pdu.c:816:16: warning: array subscript 1 is above array bounds of ‘__le16[1]’ {aka ‘short unsigned int[1]’} [-Warray-bounds] 816 | req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); | ~~~~~~~~~~~~~^~~ At the time, the size of array _Dialects_ was changed from 1 to 3 in struct validate_negotiate_info_req, and then in 2019 it was changed from 3 to 4, but those changes were never made in struct smb2_negotiate_req, which has led to a 3 and a half years old out-of-bounds bug in function SMB2_negotiate() (fs/cifs/smb2pdu.c). Fix this by increasing the size of array _Dialects_ in struct smb2_negotiate_req to 4. Fixes: 9764c02fcbad ("SMB3: Add support for multidialect negotiate (SMB2.1 and later)") Fixes: d5c7076b772a ("smb3: add smb3.1.1 to default dialect list") Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva Signed-off-by: Steve French --- fs/cifs/smb2pdu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index d85edf5d14294..a5a9e33c0d739 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -286,7 +286,7 @@ struct smb2_negotiate_req { __le32 NegotiateContextOffset; /* SMB3.1.1 only. MBZ earlier */ __le16 NegotiateContextCount; /* SMB3.1.1 only. MBZ earlier */ __le16 Reserved2; - __le16 Dialects[1]; /* One dialect (vers=) at a time for now */ + __le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */ } __packed; /* Dialects */ -- GitLab From ed5e83a3c02948dad9dc4e68fb4e535baa5da630 Mon Sep 17 00:00:00 2001 From: Daniel Jurgens Date: Mon, 1 Feb 2021 18:11:10 +0200 Subject: [PATCH 0892/1084] net/mlx5: Fix function calculation for page trees The function calculation always results in a value of 0. This works generally, but when the release all pages feature is enabled it will result in crashes. Fixes: 0aa128475d33 ("net/mlx5: Maintain separate page trees for ECPF and PF functions") Signed-off-by: Daniel Jurgens Reported-by: Colin Ian King Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c index eaa8958e24d79..c0656d4782e1c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c @@ -76,7 +76,7 @@ enum { static u32 get_function(u16 func_id, bool ec_function) { - return func_id & (ec_function << 16); + return (u32)func_id | (ec_function << 16); } static struct rb_root *page_root_per_function(struct mlx5_core_dev *dev, u32 function) -- GitLab From a5bfe6b4675e0eefbd9418055b5cc6e89af27eb4 Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Wed, 20 Jan 2021 17:41:18 +0200 Subject: [PATCH 0893/1084] net/mlx5: Fix leak upon failure of rule creation When creation of a new rule that requires allocation of an FTE fails, need to call to tree_put_node on the FTE in order to release its' resource. Fixes: cefc23554fc2 ("net/mlx5: Fix FTE cleanup") Signed-off-by: Maor Gottlieb Reviewed-by: Alaa Hleihel Reviewed-by: Mark Bloch Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 0fcee702b808b..ee4d86c1f4360 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1760,6 +1760,7 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft, if (!fte_tmp) continue; rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte_tmp); + /* No error check needed here, because insert_fte() is not called */ up_write_ref_node(&fte_tmp->node, false); tree_put_node(&fte_tmp->node, false); kmem_cache_free(steering->ftes_cache, fte); @@ -1812,6 +1813,8 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft, up_write_ref_node(&g->node, false); rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte); up_write_ref_node(&fte->node, false); + if (IS_ERR(rule)) + tree_put_node(&fte->node, false); return rule; } rule = ERR_PTR(-ENOENT); @@ -1910,6 +1913,8 @@ _mlx5_add_flow_rules(struct mlx5_flow_table *ft, up_write_ref_node(&g->node, false); rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte); up_write_ref_node(&fte->node, false); + if (IS_ERR(rule)) + tree_put_node(&fte->node, false); tree_put_node(&g->node, false); return rule; -- GitLab From 5a2ba25a55c4dc0f143567c99aede768b6628ebd Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Thu, 28 Jan 2021 14:37:59 +0200 Subject: [PATCH 0894/1084] net/mlx5e: Update max_opened_tc also when channels are closed max_opened_tc is used for stats, so that potentially non-zero stats won't disappear when num_tc decreases. However, mlx5e_setup_tc_mqprio fails to update it in the flow where channels are closed. This commit fixes it. The new value of priv->channels.params.num_tc is always checked on exit. In case of errors it will just be the old value, and in case of success it will be the updated value. Fixes: 05909babce53 ("net/mlx5e: Avoid reset netdev stats on configuration changes") Signed-off-by: Maxim Mikityanskiy Reviewed-by: Tariq Toukan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index a9d824a9cb05a..3fc7d18ac868b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3627,12 +3627,10 @@ static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv, err = mlx5e_safe_switch_channels(priv, &new_channels, mlx5e_num_channels_changed_ctx, NULL); - if (err) - goto out; - priv->max_opened_tc = max_t(u8, priv->max_opened_tc, - new_channels.params.num_tc); out: + priv->max_opened_tc = max_t(u8, priv->max_opened_tc, + priv->channels.params.num_tc); mutex_unlock(&priv->state_lock); return err; } -- GitLab From a34ffec8af8ff1c730697a99e09ec7b74a3423b6 Mon Sep 17 00:00:00 2001 From: Maor Dickman Date: Sun, 31 Jan 2021 18:47:15 +0200 Subject: [PATCH 0895/1084] net/mlx5e: Release skb in case of failure in tc update skb In case of failure in tc update skb the packet is dropped without freeing the skb. Fixed by freeing the skb in case failure in tc update skb. Fixes: d6d27782864f ("net/mlx5: E-Switch, Restore chain id on miss") Fixes: c75690972228 ("net/mlx5e: Add tc chains offload support for nic flows") Signed-off-by: Maor Dickman Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 7f5851c612181..ca4b55839a8a7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -1262,8 +1262,10 @@ static void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe) mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb); if (mlx5e_cqe_regb_chain(cqe)) - if (!mlx5e_tc_update_skb(cqe, skb)) + if (!mlx5e_tc_update_skb(cqe, skb)) { + dev_kfree_skb_any(skb); goto free_wqe; + } napi_gro_receive(rq->cq.napi, skb); @@ -1316,8 +1318,10 @@ static void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe) if (rep->vlan && skb_vlan_tag_present(skb)) skb_vlan_pop(skb); - if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) + if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) { + dev_kfree_skb_any(skb); goto free_wqe; + } napi_gro_receive(rq->cq.napi, skb); @@ -1371,8 +1375,10 @@ static void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb); - if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) + if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) { + dev_kfree_skb_any(skb); goto mpwrq_cqe_out; + } napi_gro_receive(rq->cq.napi, skb); @@ -1528,8 +1534,10 @@ static void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cq mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb); if (mlx5e_cqe_regb_chain(cqe)) - if (!mlx5e_tc_update_skb(cqe, skb)) + if (!mlx5e_tc_update_skb(cqe, skb)) { + dev_kfree_skb_any(skb); goto mpwrq_cqe_out; + } napi_gro_receive(rq->cq.napi, skb); -- GitLab From eaf5bfe37db871031232d2bf2535b6ca92afbad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 28 Jan 2021 17:59:44 +0200 Subject: [PATCH 0896/1084] drm/i915: Skip vswing programming for TBT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In thunderbolt mode the PHY is owned by the thunderbolt controller. We are not supposed to touch it. So skip the vswing programming as well (we already skipped the other steps not applicable to TBT). Touching this stuff could supposedly interfere with the PHY programming done by the thunderbolt controller. Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210128155948.13678-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit f8c6b615b921d8a1bcd74870f9105e62b0bceff3) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index bf17365857caf..e1e3ac12f9790 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2754,6 +2754,9 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int n_entries, ln; u32 val; + if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT) + return; + ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries); if (level >= n_entries) { drm_dbg_kms(&dev_priv->drm, @@ -2890,6 +2893,9 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32 val, dpcnt_mask, dpcnt_val; int n_entries, ln; + if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT) + return; + ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries); if (level >= n_entries) -- GitLab From 425cbd1fce10d4d68188123404d1a302a6939e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 28 Jan 2021 17:59:45 +0200 Subject: [PATCH 0897/1084] drm/i915: Extract intel_ddi_power_up_lanes() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce the copypasta by pulling the combo PHY lane power up stuff into a helper. We'll have a third user soon. Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210128155948.13678-2-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit 5cdf706fb91a6e4e6af799bb957c4d598e6a067b) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 35 +++++++++++++----------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index e1e3ac12f9790..e39ef68a480e7 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3537,6 +3537,23 @@ static void intel_ddi_disable_fec_state(struct intel_encoder *encoder, intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); } +static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + enum phy phy = intel_port_to_phy(i915, encoder->port); + + if (intel_phy_is_combo(i915, phy)) { + bool lane_reversal = + dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; + + intel_combo_phy_power_up_lanes(i915, phy, false, + crtc_state->lane_count, + lane_reversal); + } +} + static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, @@ -3626,14 +3643,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up * the used lanes of the DDI. */ - if (intel_phy_is_combo(dev_priv, phy)) { - bool lane_reversal = - dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; - - intel_combo_phy_power_up_lanes(dev_priv, phy, false, - crtc_state->lane_count, - lane_reversal); - } + intel_ddi_power_up_lanes(encoder, crtc_state); /* * 7.g Configure and enable DDI_BUF_CTL @@ -3718,14 +3728,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, else intel_prepare_dp_ddi_buffers(encoder, crtc_state); - if (intel_phy_is_combo(dev_priv, phy)) { - bool lane_reversal = - dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; - - intel_combo_phy_power_up_lanes(dev_priv, phy, false, - crtc_state->lane_count, - lane_reversal); - } + intel_ddi_power_up_lanes(encoder, crtc_state); intel_ddi_init_dp_buf_reg(encoder, crtc_state); if (!is_mst) -- GitLab From fad9bae9ee5d578afbe6380c82e4715efaddf118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 28 Jan 2021 17:59:46 +0200 Subject: [PATCH 0898/1084] drm/i915: Power up combo PHY lanes for for HDMI as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we only explicitly power up the combo PHY lanes for DP. The spec says we should do it for HDMI as well. Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210128155948.13678-3-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit 1e0cb7bef35f0d1aed383bf69a209df218b807c9) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index e39ef68a480e7..dc13d1814d95d 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4214,6 +4214,8 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, intel_de_write(dev_priv, reg, val); } + intel_ddi_power_up_lanes(encoder, crtc_state); + /* In HDMI/DVI mode, the port width, and swing/emphasis values * are ignored so nothing special needs to be done besides * enabling the port. -- GitLab From 538e4a8c571efdf131834431e0c14808bcfb1004 Mon Sep 17 00:00:00 2001 From: Thorsten Leemhuis Date: Fri, 29 Jan 2021 06:24:42 +0100 Subject: [PATCH 0899/1084] nvme-pci: avoid the deepest sleep state on Kingston A2000 SSDs Some Kingston A2000 NVMe SSDs sooner or later get confused and stop working when they use the deepest APST sleep while running Linux. The system then crashes and one has to cold boot it to get the SSD working again. Kingston seems to known about this since at least mid-September 2020: https://bbs.archlinux.org/viewtopic.php?pid=1926994#p1926994 Someone working for a German company representing Kingston to the German press confirmed to me Kingston engineering is aware of the issue and investigating; the person stated that to their current knowledge only the deepest APST sleep state causes trouble. Therefore, make Linux avoid it for now by applying the NVME_QUIRK_NO_DEEPEST_PS to this SSD. I have two such SSDs, but it seems the problem doesn't occur with them. I hence couldn't verify if this patch really fixes the problem, but all the data in front of me suggests it should. This patch can easily be reverted or improved upon if a better solution surfaces. FWIW, there are many reports about the issue scattered around the web; most of the users disabled APST completely to make things work, some just made Linux avoid the deepest sleep state: https://bugzilla.kernel.org/show_bug.cgi?id=195039#c65 https://bugzilla.kernel.org/show_bug.cgi?id=195039#c73 https://bugzilla.kernel.org/show_bug.cgi?id=195039#c74 https://bugzilla.kernel.org/show_bug.cgi?id=195039#c78 https://bugzilla.kernel.org/show_bug.cgi?id=195039#c79 https://bugzilla.kernel.org/show_bug.cgi?id=195039#c80 https://askubuntu.com/questions/1222049/nvmekingston-a2000-sometimes-stops-giving-response-in-ubuntu-18-04dell-inspir https://community.acer.com/en/discussion/604326/m-2-nvme-ssd-aspire-517-51g-issue-compatibility-kingston-a2000-linux-ubuntu For the record, some data from 'nvme id-ctrl /dev/nvme0' NVME Identify Controller: vid : 0x2646 ssvid : 0x2646 mn : KINGSTON SA2000M81000G fr : S5Z42105 [...] ps 0 : mp:9.00W operational enlat:0 exlat:0 rrt:0 rrl:0 rwt:0 rwl:0 idle_power:- active_power:- ps 1 : mp:4.60W operational enlat:0 exlat:0 rrt:1 rrl:1 rwt:1 rwl:1 idle_power:- active_power:- ps 2 : mp:3.80W operational enlat:0 exlat:0 rrt:2 rrl:2 rwt:2 rwl:2 idle_power:- active_power:- ps 3 : mp:0.0450W non-operational enlat:2000 exlat:2000 rrt:3 rrl:3 rwt:3 rwl:3 idle_power:- active_power:- ps 4 : mp:0.0040W non-operational enlat:15000 exlat:15000 rrt:4 rrl:4 rwt:4 rwl:4 idle_power:- active_power:- Cc: stable@vger.kernel.org # 4.14+ Signed-off-by: Thorsten Leemhuis Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 81e6389b20420..7aa33bb3692f5 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3259,6 +3259,8 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, { PCI_DEVICE(0x1d97, 0x2263), /* SPCC */ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001), .driver_data = NVME_QUIRK_SINGLE_VECTOR }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) }, -- GitLab From c9e95c39280530200cdd0bbd2670e6334a81970b Mon Sep 17 00:00:00 2001 From: Claus Stovgaard Date: Mon, 1 Feb 2021 22:08:22 +0100 Subject: [PATCH 0900/1084] nvme-pci: ignore the subsysem NQN on Phison E16 Tested both with Corsairs firmware 11.3 and 13.0 for the Corsairs MP600 and both have the issue as reported by the kernel. nvme nvme0: missing or invalid SUBNQN field. Signed-off-by: Claus Stovgaard Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 7aa33bb3692f5..6bad4d4dcdf07 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3242,6 +3242,8 @@ static const struct pci_device_id nvme_id_table[] = { { PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */ .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ + .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, { PCI_DEVICE(0x1d1d, 0x1f1f), /* LighNVM qemu device */ .driver_data = NVME_QUIRK_LIGHTNVM, }, { PCI_DEVICE(0x1d1d, 0x2807), /* CNEX WL */ -- GitLab From 46121fa7c2dc55bcbb729b6a2ab323aa1e8986cf Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 1 Feb 2021 11:48:44 -0800 Subject: [PATCH 0901/1084] update the email address for Keith Bush Redirect my older email addresses that are in the git logs. Signed-off-by: Keith Busch Signed-off-by: Christoph Hellwig --- .mailmap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mailmap b/.mailmap index 632700cee55cd..c52c6ca7aa954 100644 --- a/.mailmap +++ b/.mailmap @@ -180,6 +180,8 @@ Kees Cook Kees Cook Kees Cook Kees Cook +Keith Busch +Keith Busch Kenneth W Chen Konstantin Khlebnikov Konstantin Khlebnikov -- GitLab From 00f9a08fbc3c703b71842a5425c1eb82053c8a70 Mon Sep 17 00:00:00 2001 From: Andres Calderon Jaramillo Date: Tue, 2 Feb 2021 10:45:53 +0200 Subject: [PATCH 0902/1084] drm/i915/display: Prevent double YUV range correction on HDR planes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent the ICL HDR plane pipeline from performing YUV color range correction twice when the input is in limited range. This is done by removing the limited-range code from icl_program_input_csc(). Before this patch the following could happen: user space gives us a YUV buffer in limited range; per the pipeline in [1], the plane would first go through a "YUV Range correct" stage that expands the range; the plane would then go through the "Input CSC" stage which would also expand the range because icl_program_input_csc() would use a matrix and an offset that assume limited-range input; this would ultimately cause dark and light colors to appear darker and lighter than they should respectively. This is an issue because if a buffer switches between being scanned out and being composited with the GPU, the user will see a color difference. If this switching happens quickly and frequently, the user will perceive this as a flickering. [1] https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-icllp-vol12-displayengine_0.pdf#page=281 Cc: stable@vger.kernel.org Signed-off-by: Andres Calderon Jaramillo Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201215224219.3896256-1-andrescj@google.com (cherry picked from commit fed387572040e84ead53852a7820e30a30e515d0) Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210202084553.30691-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 + drivers/gpu/drm/i915/display/intel_sprite.c | 65 +++----------------- 2 files changed, 12 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 53a00cf3fa325..39396248f3888 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4807,6 +4807,8 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE; } else if (fb->format->is_yuv) { plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE; + if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) + plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE; } return plane_color_ctl; diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index 019a2d6d807a6..3da2544fa1c0b 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -618,13 +618,19 @@ skl_program_scaler(struct intel_plane *plane, /* Preoffset values for YUV to RGB Conversion */ #define PREOFF_YUV_TO_RGB_HI 0x1800 -#define PREOFF_YUV_TO_RGB_ME 0x1F00 +#define PREOFF_YUV_TO_RGB_ME 0x0000 #define PREOFF_YUV_TO_RGB_LO 0x1800 #define ROFF(x) (((x) & 0xffff) << 16) #define GOFF(x) (((x) & 0xffff) << 0) #define BOFF(x) (((x) & 0xffff) << 16) +/* + * Programs the input color space conversion stage for ICL HDR planes. + * Note that it is assumed that this stage always happens after YUV + * range correction. Thus, the input to this stage is assumed to be + * in full-range YCbCr. + */ static void icl_program_input_csc(struct intel_plane *plane, const struct intel_crtc_state *crtc_state, @@ -672,52 +678,7 @@ icl_program_input_csc(struct intel_plane *plane, 0x0, 0x7800, 0x7F10, }, }; - - /* Matrix for Limited Range to Full Range Conversion */ - static const u16 input_csc_matrix_lr[][9] = { - /* - * BT.601 Limted range YCbCr -> full range RGB - * The matrix required is : - * [1.164384, 0.000, 1.596027, - * 1.164384, -0.39175, -0.812813, - * 1.164384, 2.017232, 0.0000] - */ - [DRM_COLOR_YCBCR_BT601] = { - 0x7CC8, 0x7950, 0x0, - 0x8D00, 0x7950, 0x9C88, - 0x0, 0x7950, 0x6810, - }, - /* - * BT.709 Limited range YCbCr -> full range RGB - * The matrix required is : - * [1.164384, 0.000, 1.792741, - * 1.164384, -0.213249, -0.532909, - * 1.164384, 2.112402, 0.0000] - */ - [DRM_COLOR_YCBCR_BT709] = { - 0x7E58, 0x7950, 0x0, - 0x8888, 0x7950, 0xADA8, - 0x0, 0x7950, 0x6870, - }, - /* - * BT.2020 Limited range YCbCr -> full range RGB - * The matrix required is : - * [1.164, 0.000, 1.678, - * 1.164, -0.1873, -0.6504, - * 1.164, 2.1417, 0.0000] - */ - [DRM_COLOR_YCBCR_BT2020] = { - 0x7D70, 0x7950, 0x0, - 0x8A68, 0x7950, 0xAC00, - 0x0, 0x7950, 0x6890, - }, - }; - const u16 *csc; - - if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) - csc = input_csc_matrix[plane_state->hw.color_encoding]; - else - csc = input_csc_matrix_lr[plane_state->hw.color_encoding]; + const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding]; intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), ROFF(csc[0]) | GOFF(csc[1])); @@ -734,14 +695,8 @@ icl_program_input_csc(struct intel_plane *plane, intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0), PREOFF_YUV_TO_RGB_HI); - if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) - intel_de_write_fw(dev_priv, - PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), - 0); - else - intel_de_write_fw(dev_priv, - PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), - PREOFF_YUV_TO_RGB_ME); + intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), + PREOFF_YUV_TO_RGB_ME); intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2), PREOFF_YUV_TO_RGB_LO); intel_de_write_fw(dev_priv, -- GitLab From 24321ac668e452a4942598533d267805f291fdc9 Mon Sep 17 00:00:00 2001 From: Raoni Fassina Firmino Date: Mon, 1 Feb 2021 17:05:05 -0300 Subject: [PATCH 0903/1084] powerpc/64/signal: Fix regression in __kernel_sigtramp_rt64() semantics Commit 0138ba5783ae ("powerpc/64/signal: Balance return predictor stack in signal trampoline") changed __kernel_sigtramp_rt64() VDSO and trampoline code, and introduced a regression in the way glibc's backtrace()[1] detects the signal-handler stack frame. Apart from the practical implications, __kernel_sigtramp_rt64() was a VDSO function with the semantics that it is a function you can call from userspace to end a signal handling. Now this semantics are no longer valid. I believe the aforementioned change affects all releases since 5.9. This patch tries to fix both the semantics and practical aspect of __kernel_sigtramp_rt64() returning it to the previous code, whilst keeping the intended behaviour of 0138ba5783ae by adding a new symbol to serve as the jump target from the kernel to the trampoline. Now the trampoline has two parts, a new entry point and the old return point. [1] https://lists.ozlabs.org/pipermail/linuxppc-dev/2021-January/223194.html Fixes: 0138ba5783ae ("powerpc/64/signal: Balance return predictor stack in signal trampoline") Cc: stable@vger.kernel.org # v5.9+ Signed-off-by: Raoni Fassina Firmino Acked-by: Nicholas Piggin [mpe: Minor tweaks to change log formatting, add stable tag] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210201200505.iz46ubcizipnkcxe@work-tp --- arch/powerpc/kernel/vdso64/sigtramp.S | 11 ++++++++++- arch/powerpc/kernel/vdso64/vdso64.lds.S | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S index bbf68cd01088b..2d4067561293e 100644 --- a/arch/powerpc/kernel/vdso64/sigtramp.S +++ b/arch/powerpc/kernel/vdso64/sigtramp.S @@ -15,11 +15,20 @@ .text +/* + * __kernel_start_sigtramp_rt64 and __kernel_sigtramp_rt64 together + * are one function split in two parts. The kernel jumps to the former + * and the signal handler indirectly (by blr) returns to the latter. + * __kernel_sigtramp_rt64 needs to point to the return address so + * glibc can correctly identify the trampoline stack frame. + */ .balign 8 .balign IFETCH_ALIGN_BYTES -V_FUNCTION_BEGIN(__kernel_sigtramp_rt64) +V_FUNCTION_BEGIN(__kernel_start_sigtramp_rt64) .Lsigrt_start: bctrl /* call the handler */ +V_FUNCTION_END(__kernel_start_sigtramp_rt64) +V_FUNCTION_BEGIN(__kernel_sigtramp_rt64) addi r1, r1, __SIGNAL_FRAMESIZE li r0,__NR_rt_sigreturn sc diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 6164d1a1ba11b..2f3c359cacd3a 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -131,4 +131,4 @@ VERSION /* * Make the sigreturn code visible to the kernel. */ -VDSO_sigtramp_rt64 = __kernel_sigtramp_rt64; +VDSO_sigtramp_rt64 = __kernel_start_sigtramp_rt64; -- GitLab From 9f5dc9974298aea9690c7a0f7007f1af37198230 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 26 Nov 2020 14:04:07 +0000 Subject: [PATCH 0904/1084] drm/i915/gt: Move the breadcrumb to the signaler if completed upon cancel If while we are cancelling the breadcrumb signaling, we find that the request is already completed, move it to the irq signaler and let it be signaled. v2: Tweak reference counting so that we only acquire a new reference on adding to a signal list, as opposed to a hidden i915_request_put of the caller's reference. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201126140407.31952-5-chris@chris-wilson.co.uk (cherry picked from commit 85cc2917a3965a3a747a6407d6e3028cfeb1534e) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 41 +++++++++++---------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index 0625cbb3b4312..484c74d717397 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -187,18 +187,6 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl) intel_engine_add_retire(b->irq_engine, tl); } -static bool __signal_request(struct i915_request *rq) -{ - GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)); - - if (!__dma_fence_signal(&rq->fence)) { - i915_request_put(rq); - return false; - } - - return true; -} - static struct llist_node * slist_add(struct llist_node *node, struct llist_node *head) { @@ -269,9 +257,11 @@ static void signal_irq_work(struct irq_work *work) release = remove_signaling_context(b, ce); spin_unlock(&ce->signal_lock); - if (__signal_request(rq)) + if (__dma_fence_signal(&rq->fence)) /* We own signal_node now, xfer to local list */ signal = slist_add(&rq->signal_node, signal); + else + i915_request_put(rq); if (release) { add_retire(b, ce->timeline); @@ -358,6 +348,17 @@ void intel_breadcrumbs_free(struct intel_breadcrumbs *b) kfree(b); } +static void irq_signal_request(struct i915_request *rq, + struct intel_breadcrumbs *b) +{ + if (!__dma_fence_signal(&rq->fence)) + return; + + i915_request_get(rq); + if (llist_add(&rq->signal_node, &b->signaled_requests)) + irq_work_queue(&b->irq_work); +} + static void insert_breadcrumb(struct i915_request *rq) { struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs; @@ -367,17 +368,13 @@ static void insert_breadcrumb(struct i915_request *rq) if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) return; - i915_request_get(rq); - /* * If the request is already completed, we can transfer it * straight onto a signaled list, and queue the irq worker for * its signal completion. */ if (__i915_request_is_complete(rq)) { - if (__signal_request(rq) && - llist_add(&rq->signal_node, &b->signaled_requests)) - irq_work_queue(&b->irq_work); + irq_signal_request(rq, b); return; } @@ -408,6 +405,8 @@ static void insert_breadcrumb(struct i915_request *rq) break; } } + + i915_request_get(rq); list_add_rcu(&rq->signal_link, pos); GEM_BUG_ON(!check_signal_order(ce, rq)); GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags)); @@ -448,6 +447,7 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq) void i915_request_cancel_breadcrumb(struct i915_request *rq) { + struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs; struct intel_context *ce = rq->context; bool release; @@ -456,11 +456,14 @@ void i915_request_cancel_breadcrumb(struct i915_request *rq) spin_lock(&ce->signal_lock); list_del_rcu(&rq->signal_link); - release = remove_signaling_context(rq->engine->breadcrumbs, ce); + release = remove_signaling_context(b, ce); spin_unlock(&ce->signal_lock); if (release) intel_context_put(ce); + if (__i915_request_is_complete(rq)) + irq_signal_request(rq, b); + i915_request_put(rq); } -- GitLab From e4747cb3ec3c232d65c84cbe77633abd5871fda3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 19 Jan 2021 16:20:57 +0000 Subject: [PATCH 0905/1084] drm/i915/gt: Close race between enable_breadcrumbs and cancel_breadcrumbs If we enable_breadcrumbs for a request while that request is being removed from HW; we may see that the request is active as we take the ce->signal_lock and proceed to attach the request to ce->signals. However, during unsubmission after marking the request as inactive, we see that the request has not yet been added to ce->signals and so skip the removal. Pull the check during cancel_breadcrumbs under the same spinlock as enabling so that we the two tests are consistent in enable/cancel. Otherwise, we may insert a request onto ce->signals that we expect should not be there: intel_context_remove_breadcrumbs:488 GEM_BUG_ON(!__i915_request_is_complete(rq)) While updating, we can note that we are always called with irqs-disabled, due to the engine->active.lock being held at the single caller, and so remove the irqsave/restore making it symmetric to enable_breadcrumbs. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2931 Fixes: c18636f76344 ("drm/i915: Remove requirement for holding i915_request.lock for breadcrumbs") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Andi Shyti Cc: # v5.10+ Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20210119162057.31097-1-chris@chris-wilson.co.uk (cherry picked from commit e7004ea4f5f528f5a5018f0b70cab36d25315498) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index 484c74d717397..1d1757584f490 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -451,10 +451,12 @@ void i915_request_cancel_breadcrumb(struct i915_request *rq) struct intel_context *ce = rq->context; bool release; - if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) + spin_lock(&ce->signal_lock); + if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) { + spin_unlock(&ce->signal_lock); return; + } - spin_lock(&ce->signal_lock); list_del_rcu(&rq->signal_link); release = remove_signaling_context(b, ce); spin_unlock(&ce->signal_lock); -- GitLab From 761c70a52586a9214b29026d384d2c01b73661a8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 Jan 2021 13:21:58 +0000 Subject: [PATCH 0906/1084] drm/i915/gem: Drop lru bumping on display unpinning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify the frontbuffer unpin by removing the lock requirement. The LRU bumping was primarily to protect the GTT from being evicted and from frontbuffers being eagerly shrunk. Now we protect frontbuffers from the shrinker, and we avoid accidentally evicting from the GTT, so the benefit from bumping LRU is no more, and we can save more time by not. Reported-and-tested-by: Matti Hämäläinen Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2905 Fixes: c1793ba86a41 ("drm/i915: Add ww locking to pin_to_display_plane, v2.") Signed-off-by: Chris Wilson Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20210119214336.1463-6-chris@chris-wilson.co.uk (cherry picked from commit 14ca83eece9565a2d2177291ceb122982dc38420) Cc: Joonas Lahtinen Cc: Jani Nikula Cc: # v5.10+ Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 7 +-- drivers/gpu/drm/i915/display/intel_overlay.c | 4 +- drivers/gpu/drm/i915/gem/i915_gem_domain.c | 45 -------------------- drivers/gpu/drm/i915/gem/i915_gem_object.h | 1 - 4 files changed, 4 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 39396248f3888..61be6bed91629 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2309,7 +2309,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, */ ret = i915_vma_pin_fence(vma); if (ret != 0 && INTEL_GEN(dev_priv) < 4) { - i915_gem_object_unpin_from_display_plane(vma); + i915_vma_unpin(vma); vma = ERR_PTR(ret); goto err; } @@ -2327,12 +2327,9 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) { - i915_gem_object_lock(vma->obj, NULL); if (flags & PLANE_HAS_FENCE) i915_vma_unpin_fence(vma); - i915_gem_object_unpin_from_display_plane(vma); - i915_gem_object_unlock(vma->obj); - + i915_vma_unpin(vma); i915_vma_put(vma); } diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 52b4f6193b4ce..0095c8cac9b40 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -359,7 +359,7 @@ static void intel_overlay_release_old_vma(struct intel_overlay *overlay) intel_frontbuffer_flip_complete(overlay->i915, INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe)); - i915_gem_object_unpin_from_display_plane(vma); + i915_vma_unpin(vma); i915_vma_put(vma); } @@ -860,7 +860,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, return 0; out_unpin: - i915_gem_object_unpin_from_display_plane(vma); + i915_vma_unpin(vma); out_pin_section: atomic_dec(&dev_priv->gpu_error.pending_fb_pin); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index fcce6909f2017..3d435bfff7649 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -387,48 +387,6 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, return vma; } -static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj) -{ - struct drm_i915_private *i915 = to_i915(obj->base.dev); - struct i915_vma *vma; - - if (list_empty(&obj->vma.list)) - return; - - mutex_lock(&i915->ggtt.vm.mutex); - spin_lock(&obj->vma.lock); - for_each_ggtt_vma(vma, obj) { - if (!drm_mm_node_allocated(&vma->node)) - continue; - - GEM_BUG_ON(vma->vm != &i915->ggtt.vm); - list_move_tail(&vma->vm_link, &vma->vm->bound_list); - } - spin_unlock(&obj->vma.lock); - mutex_unlock(&i915->ggtt.vm.mutex); - - if (i915_gem_object_is_shrinkable(obj)) { - unsigned long flags; - - spin_lock_irqsave(&i915->mm.obj_lock, flags); - - if (obj->mm.madv == I915_MADV_WILLNEED && - !atomic_read(&obj->mm.shrink_pin)) - list_move_tail(&obj->mm.link, &i915->mm.shrink_list); - - spin_unlock_irqrestore(&i915->mm.obj_lock, flags); - } -} - -void -i915_gem_object_unpin_from_display_plane(struct i915_vma *vma) -{ - /* Bump the LRU to try and avoid premature eviction whilst flipping */ - i915_gem_object_bump_inactive_ggtt(vma->obj); - - i915_vma_unpin(vma); -} - /** * Moves a single object to the CPU read, and possibly write domain. * @obj: object to act on @@ -569,9 +527,6 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, else err = i915_gem_object_set_to_cpu_domain(obj, write_domain); - /* And bump the LRU for this access */ - i915_gem_object_bump_inactive_ggtt(obj); - i915_gem_object_unlock(obj); if (write_domain) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index be14486f63a7a..4556afe18f16d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -486,7 +486,6 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, u32 alignment, const struct i915_ggtt_view *view, unsigned int flags); -void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma); void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj); void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj); -- GitLab From e1711b1f9dfb712aa72ea25e03e0a3f6ef16c4fb Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Mon, 1 Feb 2021 11:23:45 +0200 Subject: [PATCH 0907/1084] ASoC: SOF: add be_hw_params_fixup() for ALH Fixup BE DAI links channel count to match topology settings. Normally the channel count of BE is equal to FE's so we don't have any issue. For some cases like DSM with 2-channel FE and 4-channel BE the mismatch of BE and topology will result in audio issues. Signed-off-by: Rander Wang Reviewed-by: Keyon Jie Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210201092345.1214232-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/pcm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 0dc39fbcd81de..61c3fe17342d9 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -707,7 +707,12 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa } break; case SOF_DAI_INTEL_ALH: - /* do nothing for ALH dai_link */ + /* + * Dai could run with different channel count compared with + * front end, so get dai channel count from topology + */ + channels->min = dai->dai_config->alh.channels; + channels->max = dai->dai_config->alh.channels; break; case SOF_DAI_IMX_ESAI: rate->min = dai->dai_config->esai.fsync_rate; -- GitLab From 1ecebae4733d8971059f0c514741868ce19f5d24 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Tue, 2 Feb 2021 11:35:57 +0800 Subject: [PATCH 0908/1084] ASoC: mt6359: reduce log verbosity for optional DT properties DT properties "dmic-mode" and "mic-type-X" are optional. Reduces the log verbosity and changes the message a bit to avoid misleading. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210202033557.1621029-1-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/codecs/mt6359.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/mt6359.c b/sound/soc/codecs/mt6359.c index 6de0d744fa9eb..6f4b1da52082d 100644 --- a/sound/soc/codecs/mt6359.c +++ b/sound/soc/codecs/mt6359.c @@ -2754,7 +2754,8 @@ static int mt6359_parse_dt(struct mt6359_priv *priv) ret = of_property_read_u32(np, "mediatek,dmic-mode", &priv->dmic_one_wire_mode); if (ret) { - dev_warn(priv->dev, "%s() failed to read dmic-mode\n", + dev_info(priv->dev, + "%s() failed to read dmic-mode, use default (0)\n", __func__); priv->dmic_one_wire_mode = 0; } @@ -2762,24 +2763,27 @@ static int mt6359_parse_dt(struct mt6359_priv *priv) ret = of_property_read_u32(np, "mediatek,mic-type-0", &priv->mux_select[MUX_MIC_TYPE_0]); if (ret) { - dev_warn(priv->dev, "%s() failed to read mic-type-0\n", - __func__); + dev_info(priv->dev, + "%s() failed to read mic-type-0, use default (%d)\n", + __func__, MIC_TYPE_MUX_IDLE); priv->mux_select[MUX_MIC_TYPE_0] = MIC_TYPE_MUX_IDLE; } ret = of_property_read_u32(np, "mediatek,mic-type-1", &priv->mux_select[MUX_MIC_TYPE_1]); if (ret) { - dev_warn(priv->dev, "%s() failed to read mic-type-1\n", - __func__); + dev_info(priv->dev, + "%s() failed to read mic-type-1, use default (%d)\n", + __func__, MIC_TYPE_MUX_IDLE); priv->mux_select[MUX_MIC_TYPE_1] = MIC_TYPE_MUX_IDLE; } ret = of_property_read_u32(np, "mediatek,mic-type-2", &priv->mux_select[MUX_MIC_TYPE_2]); if (ret) { - dev_warn(priv->dev, "%s() failed to read mic-type-2\n", - __func__); + dev_info(priv->dev, + "%s() failed to read mic-type-2, use default (%d)\n", + __func__, MIC_TYPE_MUX_IDLE); priv->mux_select[MUX_MIC_TYPE_2] = MIC_TYPE_MUX_IDLE; } -- GitLab From c8b186a8d54d7e12d28e9f9686cb00ff18fc2ab2 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Tue, 2 Feb 2021 18:23:26 +1100 Subject: [PATCH 0909/1084] tracepoint: Fix race between tracing and removing tracepoint When executing a tracepoint, the tracepoint's func is dereferenced twice - in __DO_TRACE() (where the returned pointer is checked) and later on in __traceiter_##_name where the returned pointer is dereferenced without checking which leads to races against tracepoint_removal_sync() and crashes. This adds a check before referencing the pointer in tracepoint_ptr_deref. Link: https://lkml.kernel.org/r/20210202072326.120557-1-aik@ozlabs.ru Cc: stable@vger.kernel.org Fixes: d25e37d89dd2f ("tracepoint: Optimize using static_call()") Acked-by: Peter Zijlstra (Intel) Signed-off-by: Alexey Kardashevskiy Signed-off-by: Steven Rostedt (VMware) --- include/linux/tracepoint.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 0f21617f1a668..966ed89803274 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -307,11 +307,13 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) \ it_func_ptr = \ rcu_dereference_raw((&__tracepoint_##_name)->funcs); \ - do { \ - it_func = (it_func_ptr)->func; \ - __data = (it_func_ptr)->data; \ - ((void(*)(void *, proto))(it_func))(__data, args); \ - } while ((++it_func_ptr)->func); \ + if (it_func_ptr) { \ + do { \ + it_func = (it_func_ptr)->func; \ + __data = (it_func_ptr)->data; \ + ((void(*)(void *, proto))(it_func))(__data, args); \ + } while ((++it_func_ptr)->func); \ + } \ return 0; \ } \ DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name); -- GitLab From 4c9fb5d9140802db4db9f66c23887f43174e113c Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Tue, 2 Feb 2021 15:54:19 +0100 Subject: [PATCH 0910/1084] iommu: Check dev->iommu in dev_iommu_priv_get() before dereferencing it The dev_iommu_priv_get() needs a similar check to dev_iommu_fwspec_get() to make sure no NULL-ptr is dereferenced. Fixes: 05a0542b456e1 ("iommu/amd: Store dev_data as device iommu private data") Cc: stable@vger.kernel.org # v5.8+ Link: https://lore.kernel.org/r/20210202145419.29143-1-joro@8bytes.org Reference: https://bugzilla.kernel.org/show_bug.cgi?id=211241 Signed-off-by: Joerg Roedel --- include/linux/iommu.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index b3f0e2018c623..efa96263b81b3 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -616,7 +616,10 @@ static inline void dev_iommu_fwspec_set(struct device *dev, static inline void *dev_iommu_priv_get(struct device *dev) { - return dev->iommu->priv; + if (dev->iommu) + return dev->iommu->priv; + else + return NULL; } static inline void dev_iommu_priv_set(struct device *dev, void *priv) -- GitLab From 83404d581471775f37f85e5261ec0d09407d8bed Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 25 Jan 2021 19:36:35 +0200 Subject: [PATCH 0911/1084] drm/dp/mst: Export drm_dp_get_vc_payload_bw() This function will be needed by the next patch where the driver calculates the BW based on driver specific parameters, so export it. At the same time sanitize the function params, passing the more natural link rate instead of the encoding of the same rate. v2: - Fix function documentation. (Lyude) Cc: Lyude Paul Cc: Ville Syrjala Cc: Cc: dri-devel@lists.freedesktop.org Signed-off-by: Imre Deak Reviewed-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210125173636.1733812-1-imre.deak@intel.com (cherry picked from commit a321fc2b4e60fc1b39517d26c8104351636a6062) Signed-off-by: Jani Nikula --- drivers/gpu/drm/drm_dp_mst_topology.c | 24 ++++++++++++++++++------ include/drm/drm_dp_mst_helper.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 0401b2f475002..8781deefeae3e 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3629,14 +3629,26 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr, return 0; } -static int drm_dp_get_vc_payload_bw(u8 dp_link_bw, u8 dp_link_count) +/** + * drm_dp_get_vc_payload_bw - get the VC payload BW for an MST link + * @link_rate: link rate in 10kbits/s units + * @link_lane_count: lane count + * + * Calculate the total bandwidth of a MultiStream Transport link. The returned + * value is in units of PBNs/(timeslots/1 MTP). This value can be used to + * convert the number of PBNs required for a given stream to the number of + * timeslots this stream requires in each MTP. + */ +int drm_dp_get_vc_payload_bw(int link_rate, int link_lane_count) { - if (dp_link_bw == 0 || dp_link_count == 0) - DRM_DEBUG_KMS("invalid link bandwidth in DPCD: %x (link count: %d)\n", - dp_link_bw, dp_link_count); + if (link_rate == 0 || link_lane_count == 0) + DRM_DEBUG_KMS("invalid link rate/lane count: (%d / %d)\n", + link_rate, link_lane_count); - return dp_link_bw * dp_link_count / 2; + /* See DP v2.0 2.6.4.2, VCPayload_Bandwidth_for_OneTimeSlotPer_MTP_Allocation */ + return link_rate * link_lane_count / 54000; } +EXPORT_SYMBOL(drm_dp_get_vc_payload_bw); /** * drm_dp_read_mst_cap() - check whether or not a sink supports MST @@ -3692,7 +3704,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms goto out_unlock; } - mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr->dpcd[1], + mgr->pbn_div = drm_dp_get_vc_payload_bw(drm_dp_bw_code_to_link_rate(mgr->dpcd[1]), mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK); if (mgr->pbn_div == 0) { ret = -EINVAL; diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index f5e92fe9151c3..bd1c39907b924 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -783,6 +783,7 @@ drm_dp_mst_detect_port(struct drm_connector *connector, struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); +int drm_dp_get_vc_payload_bw(int link_rate, int link_lane_count); int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc); -- GitLab From 882554042d138dbc6fb1a43017d0b9c3b38ee5f5 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 25 Jan 2021 19:36:36 +0200 Subject: [PATCH 0912/1084] drm/i915: Fix the MST PBN divider calculation Atm the driver will calculate a wrong MST timeslots/MTP (aka time unit) value for MST streams if the link parameters (link rate or lane count) are limited in a way independent of the sink capabilities (reported by DPCD). One example of such a limitation is when a MUX between the sink and source connects only a limited number of lanes to the display and connects the rest of the lanes to other peripherals (USB). Another issue is that atm MST core calculates the divider based on the backwards compatible DPCD (at address 0x0000) vs. the extended capability info (at address 0x2200). This can result in leaving some part of the MST BW unused (For instance in case of the WD19TB dock). Fix the above two issues by calculating the PBN divider value based on the rate and lane count link parameters that the driver uses for all other computation. Bugzilla: https://gitlab.freedesktop.org/drm/intel/-/issues/2977 Cc: Lyude Paul Cc: Ville Syrjala Cc: Signed-off-by: Imre Deak Reviewed-by: Ville Syrjala Link: https://patchwork.freedesktop.org/patch/msgid/20210125173636.1733812-2-imre.deak@intel.com (cherry picked from commit b59c27cab257cfbff939615a87b72bce83925710) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 27f04aed8764a..3286b232be0b8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -69,7 +69,9 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr, connector->port, - crtc_state->pbn, 0); + crtc_state->pbn, + drm_dp_get_vc_payload_bw(crtc_state->port_clock, + crtc_state->lane_count)); if (slots == -EDEADLK) return slots; if (slots >= 0) -- GitLab From 2051c890caa50f9d8658335cb9d39bfcb5680a7e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 29 Dec 2020 19:22:00 +0200 Subject: [PATCH 0913/1084] drm/i915/dp: Move intel_dp_set_signal_levels() to intel_dp_link_training.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_dp_set_signal_levels() is needed for link training, so move it to intel_dp_link_training.c. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201229172201.4155327-1-imre.deak@intel.com (cherry picked from commit 1c6e527d6947ea77bebabe15bbeaa765a87b70ca) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 18 ------------------ drivers/gpu/drm/i915/display/intel_dp.h | 3 --- .../drm/i915/display/intel_dp_link_training.c | 18 ++++++++++++++++++ .../drm/i915/display/intel_dp_link_training.h | 2 ++ 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 09123e8625c49..f6eec5c206d8c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4637,24 +4637,6 @@ ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp, intel_de_posting_read(dev_priv, intel_dp->output_reg); } -void intel_dp_set_signal_levels(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u8 train_set = intel_dp->train_set[0]; - - drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s\n", - train_set & DP_TRAIN_VOLTAGE_SWING_MASK, - train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : ""); - drm_dbg_kms(&dev_priv->drm, "Using pre-emphasis level %d%s\n", - (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >> - DP_TRAIN_PRE_EMPHASIS_SHIFT, - train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ? - " (max)" : ""); - - intel_dp->set_signal_levels(intel_dp, crtc_state); -} - void intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 05f7ddf7a7952..6620f9efdcbba 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -96,9 +96,6 @@ void intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, u8 dp_train_pat); -void -intel_dp_set_signal_levels(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, u8 *link_bw, u8 *rate_select); bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 91d3979902d03..7876e781f6989 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -334,6 +334,24 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, return drm_dp_dpcd_write(&intel_dp->aux, reg, buf, len) == len; } +void intel_dp_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + u8 train_set = intel_dp->train_set[0]; + + drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s\n", + train_set & DP_TRAIN_VOLTAGE_SWING_MASK, + train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : ""); + drm_dbg_kms(&dev_priv->drm, "Using pre-emphasis level %d%s\n", + (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >> + DP_TRAIN_PRE_EMPHASIS_SHIFT, + train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ? + " (max)" : ""); + + intel_dp->set_signal_levels(intel_dp, crtc_state); +} + static bool intel_dp_reset_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h index 86905aa24db76..c3110c032bc2e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h @@ -17,6 +17,8 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, enum drm_dp_phy dp_phy, const u8 link_status[DP_LINK_STATUS_SIZE]); +void intel_dp_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); void intel_dp_start_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); void intel_dp_stop_link_train(struct intel_dp *intel_dp, -- GitLab From 88ebe1f572e284ecfe088648e0ae93803a75a459 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 29 Dec 2020 19:22:01 +0200 Subject: [PATCH 0914/1084] drm/i915/dp: Fix LTTPR vswing/pre-emp setting in non-transparent mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DP PHY vswing/pre-emphasis level programming the driver does is related to the DPTX -> first LTTPR link segment only. Accordingly it should be only programmed when link training the first LTTPR and kept as-is when training subsequent LTTPRs and the DPRX. For these latter PHYs the vs/pe levels will be set in response to writing the DP_TRAINING_LANEx_SET_PHY_REPEATERy DPCD registers (by an upstream LTTPR TX PHY snooping this write access of its downstream LTTPR/DPRX RX PHY). The above is also described in DP Standard v2.0 under 3.6.6.1. While at it simplify and add the LTTPR that is link trained to the debug message in intel_dp_set_signal_levels(). Fixes: b30edfd8d0b4 ("drm/i915: Switch to LTTPR non-transparent mode link training") Cc: Ville Syrjälä Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201229172201.4155327-2-imre.deak@intel.com (cherry picked from commit 67fba3f1c73b83569d171ae1fa463a537bbfe0a8) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- .../drm/i915/display/intel_dp_link_training.c | 19 +++++++++++-------- .../drm/i915/display/intel_dp_link_training.h | 3 ++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f6eec5c206d8c..8a26307c48960 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5685,7 +5685,7 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp, intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state); - intel_dp_set_signal_levels(intel_dp, crtc_state); + intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX); intel_dp_phy_pattern_update(intel_dp, crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 7876e781f6989..d8c6d7054d11d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -335,21 +335,24 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, } void intel_dp_set_signal_levels(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u8 train_set = intel_dp->train_set[0]; + char phy_name[10]; - drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s\n", + drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s, pre-emphasis level %d%s, at %s\n", train_set & DP_TRAIN_VOLTAGE_SWING_MASK, - train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : ""); - drm_dbg_kms(&dev_priv->drm, "Using pre-emphasis level %d%s\n", + train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : "", (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT, train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ? - " (max)" : ""); + " (max)" : "", + intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name))); - intel_dp->set_signal_levels(intel_dp, crtc_state); + if (intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy)) + intel_dp->set_signal_levels(intel_dp, crtc_state); } static bool @@ -359,7 +362,7 @@ intel_dp_reset_link_train(struct intel_dp *intel_dp, u8 dp_train_pat) { memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); - intel_dp_set_signal_levels(intel_dp, crtc_state); + intel_dp_set_signal_levels(intel_dp, crtc_state, dp_phy); return intel_dp_set_link_train(intel_dp, crtc_state, dp_phy, dp_train_pat); } @@ -373,7 +376,7 @@ intel_dp_update_link_train(struct intel_dp *intel_dp, DP_TRAINING_LANE0_SET_PHY_REPEATER(dp_phy); int ret; - intel_dp_set_signal_levels(intel_dp, crtc_state); + intel_dp_set_signal_levels(intel_dp, crtc_state, dp_phy); ret = drm_dp_dpcd_write(&intel_dp->aux, reg, intel_dp->train_set, crtc_state->lane_count); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h index c3110c032bc2e..6a1f76bd8c758 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h @@ -18,7 +18,8 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp, enum drm_dp_phy dp_phy, const u8 link_status[DP_LINK_STATUS_SIZE]); void intel_dp_set_signal_levels(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy); void intel_dp_start_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); void intel_dp_stop_link_train(struct intel_dp *intel_dp, -- GitLab From 88c7a9fd9bdd3e453f04018920964c6f848a591a Mon Sep 17 00:00:00 2001 From: Xie He Date: Sun, 31 Jan 2021 21:57:06 -0800 Subject: [PATCH 0915/1084] net: lapb: Copy the skb before sending a packet When sending a packet, we will prepend it with an LAPB header. This modifies the shared parts of a cloned skb, so we should copy the skb rather than just clone it, before we prepend the header. In "Documentation/networking/driver.rst" (the 2nd point), it states that drivers shouldn't modify the shared parts of a cloned skb when transmitting. The "dev_queue_xmit_nit" function in "net/core/dev.c", which is called when an skb is being sent, clones the skb and sents the clone to AF_PACKET sockets. Because the LAPB drivers first remove a 1-byte pseudo-header before handing over the skb to us, if we don't copy the skb before prepending the LAPB header, the first byte of the packets received on AF_PACKET sockets can be corrupted. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Xie He Acked-by: Martin Schiller Link: https://lore.kernel.org/r/20210201055706.415842-1-xie.he.0141@gmail.com Signed-off-by: Jakub Kicinski --- net/lapb/lapb_out.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/lapb/lapb_out.c b/net/lapb/lapb_out.c index 7a4d0715d1c32..a966d29c772d9 100644 --- a/net/lapb/lapb_out.c +++ b/net/lapb/lapb_out.c @@ -82,7 +82,8 @@ void lapb_kick(struct lapb_cb *lapb) skb = skb_dequeue(&lapb->write_queue); do { - if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { + skbn = skb_copy(skb, GFP_ATOMIC); + if (!skbn) { skb_queue_head(&lapb->write_queue, skb); break; } -- GitLab From 43f4a20a1266d393840ce010f547486d14cc0071 Mon Sep 17 00:00:00 2001 From: Stefan Chulski Date: Mon, 1 Feb 2021 11:35:39 +0200 Subject: [PATCH 0916/1084] net: mvpp2: TCAM entry enable should be written after SRAM data Last TCAM data contains TCAM enable bit. It should be written after SRAM data before entry enabled. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Stefan Chulski Link: https://lore.kernel.org/r/1612172139-28343-1-git-send-email-stefanc@marvell.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c index a30eb90ba3d28..dd590086fe6a5 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c @@ -29,16 +29,16 @@ static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe) /* Clear entry invalidation bit */ pe->tcam[MVPP2_PRS_TCAM_INV_WORD] &= ~MVPP2_PRS_TCAM_INV_MASK; - /* Write tcam index - indirect access */ - mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index); - for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++) - mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam[i]); - /* Write sram index - indirect access */ mvpp2_write(priv, MVPP2_PRS_SRAM_IDX_REG, pe->index); for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++) mvpp2_write(priv, MVPP2_PRS_SRAM_DATA_REG(i), pe->sram[i]); + /* Write tcam index - indirect access */ + mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index); + for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++) + mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam[i]); + return 0; } -- GitLab From a11148e6fcce2ae53f47f0a442d098d860b4f7db Mon Sep 17 00:00:00 2001 From: Sabyrzhan Tasbolatov Date: Tue, 2 Feb 2021 02:32:33 +0600 Subject: [PATCH 0917/1084] net/rds: restrict iovecs length for RDS_CMSG_RDMA_ARGS syzbot found WARNING in rds_rdma_extra_size [1] when RDS_CMSG_RDMA_ARGS control message is passed with user-controlled 0x40001 bytes of args->nr_local, causing order >= MAX_ORDER condition. The exact value 0x40001 can be checked with UIO_MAXIOV which is 0x400. So for kcalloc() 0x400 iovecs with sizeof(struct rds_iovec) = 0x10 is the closest limit, with 0x10 leftover. Same condition is currently done in rds_cmsg_rdma_args(). [1] WARNING: mm/page_alloc.c:5011 [..] Call Trace: alloc_pages_current+0x18c/0x2a0 mm/mempolicy.c:2267 alloc_pages include/linux/gfp.h:547 [inline] kmalloc_order+0x2e/0xb0 mm/slab_common.c:837 kmalloc_order_trace+0x14/0x120 mm/slab_common.c:853 kmalloc_array include/linux/slab.h:592 [inline] kcalloc include/linux/slab.h:621 [inline] rds_rdma_extra_size+0xb2/0x3b0 net/rds/rdma.c:568 rds_rm_size net/rds/send.c:928 [inline] Reported-by: syzbot+1bd2b07f93745fa38425@syzkaller.appspotmail.com Signed-off-by: Sabyrzhan Tasbolatov Acked-by: Santosh Shilimkar Link: https://lore.kernel.org/r/20210201203233.1324704-1-snovitoll@gmail.com Signed-off-by: Jakub Kicinski --- net/rds/rdma.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 1d0afb1dd77b5..6f1a50d50d06d 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -565,6 +565,9 @@ int rds_rdma_extra_size(struct rds_rdma_args *args, if (args->nr_local == 0) return -EINVAL; + if (args->nr_local > UIO_MAXIOV) + return -EMSGSIZE; + iov->iov = kcalloc(args->nr_local, sizeof(struct rds_iovec), GFP_KERNEL); -- GitLab From cc9f07a838c4988ed244d0907cb71d54b85482a5 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 1 Feb 2021 21:50:56 +0100 Subject: [PATCH 0918/1084] r8169: fix WoL on shutdown if CONFIG_DEBUG_SHIRQ is set So far phy_disconnect() is called before free_irq(). If CONFIG_DEBUG_SHIRQ is set and interrupt is shared, then free_irq() creates an "artificial" interrupt by calling the interrupt handler. The "link change" flag is set in the interrupt status register, causing phylib to eventually call phy_suspend(). Because the net_device is detached from the PHY already, the PHY driver can't recognize that WoL is configured and powers down the PHY. Fixes: f1e911d5d0df ("r8169: add basic phylib support") Signed-off-by: Heiner Kallweit Link: https://lore.kernel.org/r/fe732c2c-a473-9088-3974-df83cfbd6efd@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/realtek/r8169_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index f2269c9f5f055..0d78408b4e269 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -4704,10 +4704,10 @@ static int rtl8169_close(struct net_device *dev) cancel_work_sync(&tp->wk.work); - phy_disconnect(tp->phydev); - free_irq(pci_irq_vector(pdev, 0), tp); + phy_disconnect(tp->phydev); + dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, tp->RxPhyAddr); dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, -- GitLab From 4ace7a6e287b7e3b33276cd9fe870c326f880480 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Feb 2021 08:55:25 +0300 Subject: [PATCH 0919/1084] net: ipa: pass correct dma_handle to dma_free_coherent() The "ring->addr = addr;" assignment is done a few lines later so we can't use "ring->addr" yet. The correct dma_handle is "addr". Fixes: 650d1603825d ("soc: qcom: ipa: the generic software interface") Signed-off-by: Dan Carpenter Reviewed-by: Alex Elder Link: https://lore.kernel.org/r/YBjpTU2oejkNIULT@mwanda Signed-off-by: Jakub Kicinski --- drivers/net/ipa/gsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c index 14d9a791924bf..b8f39e48a0093 100644 --- a/drivers/net/ipa/gsi.c +++ b/drivers/net/ipa/gsi.c @@ -1373,7 +1373,7 @@ static int gsi_ring_alloc(struct gsi *gsi, struct gsi_ring *ring, u32 count) /* Hardware requires a 2^n ring size, with alignment equal to size */ ring->virt = dma_alloc_coherent(dev, size, &addr, GFP_KERNEL); if (ring->virt && addr % size) { - dma_free_coherent(dev, size, ring->virt, ring->addr); + dma_free_coherent(dev, size, ring->virt, addr); dev_err(dev, "unable to alloc 0x%zx-aligned ring buffer\n", size); return -EINVAL; /* Not a good error value, but distinct */ -- GitLab From e6cdd6d80baedadb96d7060a509f51769e53021d Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 1 Feb 2021 17:26:06 -0600 Subject: [PATCH 0920/1084] net: ipa: add a missing __iomem attribute The virt local variable in gsi_channel_state() does not have an __iomem attribute but should. Fix this. Signed-off-by: Alex Elder Reviewed-by: Amy Parker Signed-off-by: Jakub Kicinski --- drivers/net/ipa/gsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c index b8f39e48a0093..34e5f2155d620 100644 --- a/drivers/net/ipa/gsi.c +++ b/drivers/net/ipa/gsi.c @@ -440,7 +440,7 @@ static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id) static enum gsi_channel_state gsi_channel_state(struct gsi_channel *channel) { u32 channel_id = gsi_channel_id(channel); - void *virt = channel->gsi->virt; + void __iomem *virt = channel->gsi->virt; u32 val; val = ioread32(virt + GSI_CH_C_CNTXT_0_OFFSET(channel_id)); -- GitLab From 088f8a2396d813e7ee49272a1a59b55139c81e64 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 1 Feb 2021 17:26:07 -0600 Subject: [PATCH 0921/1084] net: ipa: be explicit about endianness Sparse warns that the assignment of the metadata mask for a QMAP endpoint in ipa_endpoint_init_hdr_metadata_mask() is a bad assignment. We know we want the mask value to be big endian, even though the value we write is in host byte order. Use a __force tag to indicate we really mean it. Signed-off-by: Alex Elder Signed-off-by: Jakub Kicinski --- drivers/net/ipa/ipa_endpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c index 9f4be9812a1f3..448d89da1e456 100644 --- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@ -588,7 +588,7 @@ static void ipa_endpoint_init_hdr_metadata_mask(struct ipa_endpoint *endpoint) /* Note that HDR_ENDIANNESS indicates big endian header fields */ if (endpoint->data->qmap) - val = cpu_to_be32(IPA_ENDPOINT_QMAP_METADATA_MASK); + val = (__force u32)cpu_to_be32(IPA_ENDPOINT_QMAP_METADATA_MASK); iowrite32(val, endpoint->ipa->reg_virt + offset); } -- GitLab From c13899f187285eaa5bfc30f8692888ba2e7765cb Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 1 Feb 2021 17:26:08 -0600 Subject: [PATCH 0922/1084] net: ipa: use the right accessor in ipa_endpoint_status_skip() When extracting the destination endpoint ID from the status in ipa_endpoint_status_skip(), u32_get_bits() is used. This happens to work, but it's wrong: the structure field is only 8 bits wide instead of 32. Fix this by using u8_get_bits() to get the destination endpoint ID. Signed-off-by: Alex Elder Signed-off-by: Jakub Kicinski --- drivers/net/ipa/ipa_endpoint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c index 448d89da1e456..612afece303f3 100644 --- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@ -1164,8 +1164,8 @@ static bool ipa_endpoint_status_skip(struct ipa_endpoint *endpoint, return true; if (!status->pkt_len) return true; - endpoint_id = u32_get_bits(status->endp_dst_idx, - IPA_STATUS_DST_IDX_FMASK); + endpoint_id = u8_get_bits(status->endp_dst_idx, + IPA_STATUS_DST_IDX_FMASK); if (endpoint_id != endpoint->endpoint_id) return true; -- GitLab From 113b6ea09ccd46157d8d37fa9fabf1ca2315e503 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 1 Feb 2021 17:26:09 -0600 Subject: [PATCH 0923/1084] net: ipa: fix two format specifier errors Fix two format specifiers that used %lu for a size_t in "ipa_mem.c". Signed-off-by: Alex Elder Signed-off-by: Jakub Kicinski --- drivers/net/ipa/ipa_mem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c index 0cc3a3374caa2..f25029b9ec857 100644 --- a/drivers/net/ipa/ipa_mem.c +++ b/drivers/net/ipa/ipa_mem.c @@ -336,7 +336,7 @@ static void ipa_imem_exit(struct ipa *ipa) size = iommu_unmap(domain, ipa->imem_iova, ipa->imem_size); if (size != ipa->imem_size) - dev_warn(dev, "unmapped %zu IMEM bytes, expected %lu\n", + dev_warn(dev, "unmapped %zu IMEM bytes, expected %zu\n", size, ipa->imem_size); } else { dev_err(dev, "couldn't get IPA IOMMU domain for IMEM\n"); @@ -440,7 +440,7 @@ static void ipa_smem_exit(struct ipa *ipa) size = iommu_unmap(domain, ipa->smem_iova, ipa->smem_size); if (size != ipa->smem_size) - dev_warn(dev, "unmapped %zu SMEM bytes, expected %lu\n", + dev_warn(dev, "unmapped %zu SMEM bytes, expected %zu\n", size, ipa->smem_size); } else { -- GitLab From 6c9f18f294c4a1a6d8b1097e39c325481664ee1c Mon Sep 17 00:00:00 2001 From: Andreas Oetken Date: Tue, 2 Feb 2021 10:03:04 +0100 Subject: [PATCH 0924/1084] net: hsr: align sup_multicast_addr in struct hsr_priv to u16 boundary sup_multicast_addr is passed to ether_addr_equal for address comparison which casts the address inputs to u16 leading to an unaligned access. Aligning the sup_multicast_addr to u16 boundary fixes the issue. Signed-off-by: Andreas Oetken Link: https://lore.kernel.org/r/20210202090304.2740471-1-ennoerlangen@gmail.com Signed-off-by: Jakub Kicinski --- net/hsr/hsr_main.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h index 7dc92ce5a1340..a9c30a608e35d 100644 --- a/net/hsr/hsr_main.h +++ b/net/hsr/hsr_main.h @@ -217,7 +217,10 @@ struct hsr_priv { u8 net_id; /* for PRP, it occupies most significant 3 bits * of lan_id */ - unsigned char sup_multicast_addr[ETH_ALEN]; + unsigned char sup_multicast_addr[ETH_ALEN] __aligned(sizeof(u16)); + /* Align to u16 boundary to avoid unaligned access + * in ether_addr_equal + */ #ifdef CONFIG_DEBUG_FS struct dentry *node_tbl_root; #endif -- GitLab From 943dea8af21bd896e0d6c30ea221203fb3cd3265 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 2 Feb 2021 08:55:46 -0800 Subject: [PATCH 0925/1084] KVM: x86: Update emulator context mode if SYSENTER xfers to 64-bit mode Set the emulator context to PROT64 if SYSENTER transitions from 32-bit userspace (compat mode) to a 64-bit kernel, otherwise the RIP update at the end of x86_emulate_insn() will incorrectly truncate the new RIP. Note, this bug is mostly limited to running an Intel virtual CPU model on an AMD physical CPU, as other combinations of virtual and physical CPUs do not trigger full emulation. On Intel CPUs, SYSENTER in compatibility mode is legal, and unconditionally transitions to 64-bit mode. On AMD CPUs, SYSENTER is illegal in compatibility mode and #UDs. If the vCPU is AMD, KVM injects a #UD on SYSENTER in compat mode. If the pCPU is Intel, SYSENTER will execute natively and not trigger #UD->VM-Exit (ignoring guest TLB shenanigans). Fixes: fede8076aab4 ("KVM: x86: handle wrap around 32-bit address space") Cc: stable@vger.kernel.org Signed-off-by: Jonny Barker [sean: wrote changelog] Signed-off-by: Sean Christopherson Message-Id: <20210202165546.2390296-1-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 56cae1ff9e3fe..66a08322988f2 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2879,6 +2879,8 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) ops->get_msr(ctxt, MSR_IA32_SYSENTER_ESP, &msr_data); *reg_write(ctxt, VCPU_REGS_RSP) = (efer & EFER_LMA) ? msr_data : (u32)msr_data; + if (efer & EFER_LMA) + ctxt->mode = X86EMUL_MODE_PROT64; return X86EMUL_CONTINUE; } -- GitLab From 68be8ed6a4622d4eb6cf7632bc7cb78464c83c78 Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Thu, 28 Jan 2021 19:27:14 +0800 Subject: [PATCH 0926/1084] ASoC: fsl_spdif: Utilize the defined parameter to clear code Utilize the defined parameter 'dev' to make the code cleaner. Signed-off-by: Tang Bin Acked-by: Shengjiu Wang Link: https://lore.kernel.org/r/20210128112714.16324-1-tangbin@cmss.chinamobile.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index b4d3b04694bff..174e558224d8c 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1255,7 +1255,7 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, for (i = 0; i < STC_TXCLK_SRC_MAX; i++) { sprintf(tmp, "rxtx%d", i); - clk = devm_clk_get(&pdev->dev, tmp); + clk = devm_clk_get(dev, tmp); if (IS_ERR(clk)) { dev_err(dev, "no rxtx%d clock in devicetree\n", i); return PTR_ERR(clk); @@ -1277,14 +1277,14 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, break; } - dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n", + dev_dbg(dev, "use rxtx%d as tx clock source for %dHz sample rate\n", spdif_priv->txclk_src[index], rate[index]); - dev_dbg(&pdev->dev, "use txclk df %d for %dHz sample rate\n", + dev_dbg(dev, "use txclk df %d for %dHz sample rate\n", spdif_priv->txclk_df[index], rate[index]); if (clk_is_match(spdif_priv->txclk[index], spdif_priv->sysclk)) - dev_dbg(&pdev->dev, "use sysclk df %d for %dHz sample rate\n", + dev_dbg(dev, "use sysclk df %d for %dHz sample rate\n", spdif_priv->sysclk_df[index], rate[index]); - dev_dbg(&pdev->dev, "the best rate for %dHz sample rate is %dHz\n", + dev_dbg(dev, "the best rate for %dHz sample rate is %dHz\n", rate[index], spdif_priv->txrate[index]); return 0; -- GitLab From be6be67e135e59fb176b1e2e9d47a7436fb161d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Tue, 2 Feb 2021 17:31:23 +0100 Subject: [PATCH 0927/1084] ASoC: topology: KUnit: Convert from cpu to data format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When creating topology templates and overriding data in specific test cases it should be done with cpu_to_le32 macro, so we operate on correct data on all architectures, as topology parser use le32_to_cpu to parse data from structures. Reported-by: kernel test robot Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20210202163123.3942040-1-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology-test.c | 66 +++++++++++++++++------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/sound/soc/soc-topology-test.c b/sound/soc/soc-topology-test.c index 36e2a3486dbfb..ae3968161509c 100644 --- a/sound/soc/soc-topology-test.c +++ b/sound/soc/soc-topology-test.c @@ -121,19 +121,19 @@ struct tplg_tmpl_001 { static struct tplg_tmpl_001 tplg_tmpl_empty = { .header = { - .magic = SND_SOC_TPLG_MAGIC, - .abi = 5, + .magic = cpu_to_le32(SND_SOC_TPLG_MAGIC), + .abi = cpu_to_le32(5), .version = 0, - .type = SND_SOC_TPLG_TYPE_MANIFEST, - .size = sizeof(struct snd_soc_tplg_hdr), + .type = cpu_to_le32(SND_SOC_TPLG_TYPE_MANIFEST), + .size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)), .vendor_type = 0, - .payload_size = sizeof(struct snd_soc_tplg_manifest), + .payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)), .index = 0, - .count = 1, + .count = cpu_to_le32(1), }, .manifest = { - .size = sizeof(struct snd_soc_tplg_manifest), + .size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)), /* rest of fields is 0 */ }, }; @@ -149,60 +149,60 @@ struct tplg_tmpl_002 { static struct tplg_tmpl_002 tplg_tmpl_with_pcm = { .header = { - .magic = SND_SOC_TPLG_MAGIC, - .abi = 5, + .magic = cpu_to_le32(SND_SOC_TPLG_MAGIC), + .abi = cpu_to_le32(5), .version = 0, - .type = SND_SOC_TPLG_TYPE_MANIFEST, - .size = sizeof(struct snd_soc_tplg_hdr), + .type = cpu_to_le32(SND_SOC_TPLG_TYPE_MANIFEST), + .size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)), .vendor_type = 0, - .payload_size = sizeof(struct snd_soc_tplg_manifest), + .payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)), .index = 0, - .count = 1, + .count = cpu_to_le32(1), }, .manifest = { - .size = sizeof(struct snd_soc_tplg_manifest), - .pcm_elems = 1, + .size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)), + .pcm_elems = cpu_to_le32(1), /* rest of fields is 0 */ }, .pcm_header = { - .magic = SND_SOC_TPLG_MAGIC, - .abi = 5, + .magic = cpu_to_le32(SND_SOC_TPLG_MAGIC), + .abi = cpu_to_le32(5), .version = 0, - .type = SND_SOC_TPLG_TYPE_PCM, - .size = sizeof(struct snd_soc_tplg_hdr), + .type = cpu_to_le32(SND_SOC_TPLG_TYPE_PCM), + .size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)), .vendor_type = 0, - .payload_size = sizeof(struct snd_soc_tplg_pcm), + .payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_pcm)), .index = 0, - .count = 1, + .count = cpu_to_le32(1), }, .pcm = { - .size = sizeof(struct snd_soc_tplg_pcm), + .size = cpu_to_le32(sizeof(struct snd_soc_tplg_pcm)), .pcm_name = "KUNIT Audio", .dai_name = "kunit-audio-dai", .pcm_id = 0, .dai_id = 0, - .playback = 1, - .capture = 1, + .playback = cpu_to_le32(1), + .capture = cpu_to_le32(1), .compress = 0, .stream = { [0] = { - .channels = 2, + .channels = cpu_to_le32(2), }, [1] = { - .channels = 2, + .channels = cpu_to_le32(2), }, }, .num_streams = 0, .caps = { [0] = { .name = "kunit-audio-playback", - .channels_min = 2, - .channels_max = 2, + .channels_min = cpu_to_le32(2), + .channels_max = cpu_to_le32(2), }, [1] = { .name = "kunit-audio-capture", - .channels_min = 2, - .channels_max = 2, + .channels_min = cpu_to_le32(2), + .channels_max = cpu_to_le32(2), }, }, .flag_mask = 0, @@ -460,7 +460,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test) * override abi * any value != magic number is wrong */ - data->header.magic = SND_SOC_TPLG_MAGIC + 1; + data->header.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC + 1); kunit_comp->fw.data = (u8 *)data; kunit_comp->fw.size = size; @@ -516,7 +516,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test) * override abi * any value != accepted range is wrong */ - data->header.abi = SND_SOC_TPLG_ABI_VERSION + 1; + data->header.abi = cpu_to_le32(SND_SOC_TPLG_ABI_VERSION + 1); kunit_comp->fw.data = (u8 *)data; kunit_comp->fw.size = size; @@ -572,7 +572,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test) * override size * any value != struct size is wrong */ - data->header.size = sizeof(struct snd_soc_tplg_hdr) + 1; + data->header.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr) + 1); kunit_comp->fw.data = (u8 *)data; kunit_comp->fw.size = size; -- GitLab From e681b1a6d706b4e54c3847bb822531b4660234f3 Mon Sep 17 00:00:00 2001 From: Srinivasa Rao Mandadapu Date: Tue, 2 Feb 2021 11:57:27 +0530 Subject: [PATCH 0928/1084] ASoC: qcom: Fix typo error in HDMI regmap config callbacks Had a typo in lpass platform driver that resulted in crash during suspend/resume with an HDMI dongle connected. The regmap read/write/volatile regesters validation callbacks in lpass-cpu were using MI2S rdma_channels count instead of hdmi_rdma_channels. This typo error causing to read registers from the regmap beyond the length of the mapping created by ioremap(). This fix avoids the need for reducing number hdmi_rdma_channels, which is done in commit 7dfe20ee92f6 ("ASoC: qcom: Fix number of HDMI RDMA channels on sc7180"). So reverting the same. Fixes: 7cb37b7bd0d3c ("ASoC: qcom: Add support for lpass hdmi driver") Signed-off-by: Srinivasa Rao Mandadapu Link: https://lore.kernel.org/r/20210202062727.22469-1-srivasam@codeaurora.org Reviewed-by: Stephen Boyd Tested-by: Stephen Boyd Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-cpu.c | 8 ++++---- sound/soc/qcom/lpass-sc7180.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 73ca24c0a08b7..8e5415c9234f1 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -594,7 +594,7 @@ static bool lpass_hdmi_regmap_writeable(struct device *dev, unsigned int reg) return true; } - for (i = 0; i < v->rdma_channels; ++i) { + for (i = 0; i < v->hdmi_rdma_channels; ++i) { if (reg == LPAIF_HDMI_RDMACTL_REG(v, i)) return true; if (reg == LPAIF_HDMI_RDMABASE_REG(v, i)) @@ -640,7 +640,7 @@ static bool lpass_hdmi_regmap_readable(struct device *dev, unsigned int reg) if (reg == LPASS_HDMITX_APP_IRQSTAT_REG(v)) return true; - for (i = 0; i < v->rdma_channels; ++i) { + for (i = 0; i < v->hdmi_rdma_channels; ++i) { if (reg == LPAIF_HDMI_RDMACTL_REG(v, i)) return true; if (reg == LPAIF_HDMI_RDMABASE_REG(v, i)) @@ -667,7 +667,7 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg) if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v)) return true; - for (i = 0; i < v->rdma_channels; ++i) { + for (i = 0; i < v->hdmi_rdma_channels; ++i) { if (reg == LPAIF_HDMI_RDMACURR_REG(v, i)) return true; } @@ -817,7 +817,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) } lpass_hdmi_regmap_config.max_register = LPAIF_HDMI_RDMAPER_REG(variant, - variant->hdmi_rdma_channels); + variant->hdmi_rdma_channels - 1); drvdata->hdmiif_map = devm_regmap_init_mmio(dev, drvdata->hdmiif, &lpass_hdmi_regmap_config); if (IS_ERR(drvdata->hdmiif_map)) { diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c index 735c9dac28f26..8c168d3c589e9 100644 --- a/sound/soc/qcom/lpass-sc7180.c +++ b/sound/soc/qcom/lpass-sc7180.c @@ -171,7 +171,7 @@ static struct lpass_variant sc7180_data = { .rdma_channels = 5, .hdmi_rdma_reg_base = 0x64000, .hdmi_rdma_reg_stride = 0x1000, - .hdmi_rdma_channels = 3, + .hdmi_rdma_channels = 4, .dmactl_audif_start = 1, .wrdma_reg_base = 0x18000, .wrdma_reg_stride = 0x1000, -- GitLab From 91cb2c8b072e00632adf463b78b44f123d46a0fa Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 1 Feb 2021 19:06:33 +0000 Subject: [PATCH 0929/1084] arm64: Do not pass tagged addresses to __is_lm_address() Commit 519ea6f1c82f ("arm64: Fix kernel address detection of __is_lm_address()") fixed the incorrect validation of addresses below PAGE_OFFSET. However, it no longer allowed tagged addresses to be passed to virt_addr_valid(). Fix this by explicitly resetting the pointer tag prior to invoking __is_lm_address(). This is consistent with the __lm_to_phys() macro. Fixes: 519ea6f1c82f ("arm64: Fix kernel address detection of __is_lm_address()") Signed-off-by: Catalin Marinas Acked-by: Ard Biesheuvel Cc: # 5.4.x Cc: Will Deacon Cc: Vincenzo Frascino Cc: Mark Rutland Link: https://lore.kernel.org/r/20210201190634.22942-2-catalin.marinas@arm.com --- arch/arm64/include/asm/memory.h | 2 +- arch/arm64/mm/physaddr.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 99d7e1494aaa6..3c1aaa522cbdd 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -332,7 +332,7 @@ static inline void *phys_to_virt(phys_addr_t x) #endif /* !CONFIG_SPARSEMEM_VMEMMAP || CONFIG_DEBUG_VIRTUAL */ #define virt_addr_valid(addr) ({ \ - __typeof__(addr) __addr = addr; \ + __typeof__(addr) __addr = __tag_reset(addr); \ __is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr)); \ }) diff --git a/arch/arm64/mm/physaddr.c b/arch/arm64/mm/physaddr.c index 67a9ba9eaa96b..cde44c13dda1b 100644 --- a/arch/arm64/mm/physaddr.c +++ b/arch/arm64/mm/physaddr.c @@ -9,7 +9,7 @@ phys_addr_t __virt_to_phys(unsigned long x) { - WARN(!__is_lm_address(x), + WARN(!__is_lm_address(__tag_reset(x)), "virt_to_phys used for non-linear address: %pK (%pS)\n", (void *)x, (void *)x); -- GitLab From 22cd5edb2d9c6d68b6ac0fc9584104d88710fa57 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 1 Feb 2021 19:06:34 +0000 Subject: [PATCH 0930/1084] arm64: Use simpler arithmetics for the linear map macros Because of the tagged addresses, the __is_lm_address() and __lm_to_phys() macros grew to some harder to understand bitwise operations using PAGE_OFFSET. Since these macros only accept untagged addresses, use a simple subtract operation. Signed-off-by: Catalin Marinas Acked-by: Ard Biesheuvel Cc: Will Deacon Cc: Mark Rutland Link: https://lore.kernel.org/r/20210201190634.22942-3-catalin.marinas@arm.com --- arch/arm64/include/asm/memory.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 3c1aaa522cbdd..ff4732785c32f 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -251,9 +251,9 @@ static inline const void *__tag_set(const void *addr, u8 tag) * lives in the [PAGE_OFFSET, PAGE_END) interval at the bottom of the * kernel's TTBR1 address range. */ -#define __is_lm_address(addr) (((u64)(addr) ^ PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET)) +#define __is_lm_address(addr) (((u64)(addr) - PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET)) -#define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET) +#define __lm_to_phys(addr) (((addr) - PAGE_OFFSET) + PHYS_OFFSET) #define __kimg_to_phys(addr) ((addr) - kimage_voffset) #define __virt_to_phys_nodebug(x) ({ \ -- GitLab From a50ea34d6dd00a12c9cd29cf7b0fa72816bffbcb Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Tue, 2 Feb 2021 16:38:24 +0800 Subject: [PATCH 0931/1084] usb: xhci-mtk: break loop when find the endpoint to drop No need to check the following endpoints after finding the endpoint wanted to drop. Fixes: 54f6a8af3722 ("usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints") Cc: stable Reported-by: Ikjoon Jang Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1612255104-5363-1-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mtk-sch.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index dee8a329076d1..b45e5bf089979 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -689,8 +689,10 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, sch_bw = &sch_array[bw_index]; list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { - if (sch_ep->ep == ep) + if (sch_ep->ep == ep) { destroy_sch_ep(udev, sch_bw, sch_ep); + break; + } } } EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk); -- GitLab From ebb22a05943666155e6da04407cc6e913974c78c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 1 Feb 2021 20:24:17 +0100 Subject: [PATCH 0932/1084] rtc: mc146818: Dont test for bit 0-5 in Register D The recent change to validate the RTC turned out to be overly tight. While it cures the problem on the reporters machine it breaks machines with Intel chipsets which use bit 0-5 of the D register. So check only for bit 6 being 0 which is the case on these Intel machines as well. Fixes: 211e5db19d15 ("rtc: mc146818: Detect and handle broken RTCs") Reported-by: Serge Belyshev Reported-by: Dirk Gouders Reported-by: Borislav Petkov Signed-off-by: Thomas Gleixner Tested-by: Dirk Gouders Tested-by: Len Brown Tested-by: Borislav Petkov Acked-by: Alexandre Belloni Link: https://lore.kernel.org/r/87zh0nbnha.fsf@nanos.tec.linutronix.de --- drivers/rtc/rtc-cmos.c | 4 ++-- drivers/rtc/rtc-mc146818-lib.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 68a9ac6f2fe17..a701dae653c4a 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -805,8 +805,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) spin_lock_irq(&rtc_lock); - /* Ensure that the RTC is accessible. Bit 0-6 must be 0! */ - if ((CMOS_READ(RTC_VALID) & 0x7f) != 0) { + /* Ensure that the RTC is accessible. Bit 6 must be 0! */ + if ((CMOS_READ(RTC_VALID) & 0x40) != 0) { spin_unlock_irq(&rtc_lock); dev_warn(dev, "not accessible\n"); retval = -ENXIO; diff --git a/drivers/rtc/rtc-mc146818-lib.c b/drivers/rtc/rtc-mc146818-lib.c index f83c13818af3b..dcfaf09946ee3 100644 --- a/drivers/rtc/rtc-mc146818-lib.c +++ b/drivers/rtc/rtc-mc146818-lib.c @@ -21,8 +21,8 @@ unsigned int mc146818_get_time(struct rtc_time *time) again: spin_lock_irqsave(&rtc_lock, flags); - /* Ensure that the RTC is accessible. Bit 0-6 must be 0! */ - if (WARN_ON_ONCE((CMOS_READ(RTC_VALID) & 0x7f) != 0)) { + /* Ensure that the RTC is accessible. Bit 6 must be 0! */ + if (WARN_ON_ONCE((CMOS_READ(RTC_VALID) & 0x40) != 0)) { spin_unlock_irqrestore(&rtc_lock, flags); memset(time, 0xff, sizeof(*time)); return 0; -- GitLab From 89fa15ecdca7eb46a711476b961f70a74765bbe4 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Sat, 30 Jan 2021 17:14:30 +0800 Subject: [PATCH 0933/1084] drm/amdgpu: fix the issue that retry constantly once the buffer is oversize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We cannot modify initial_domain every time while the retry starts. That will cause the busy waiting that unable to switch to GTT while the vram is not enough. Fixes: f8aab60422c3 ("drm/amdgpu: Initialise drm_gem_object_funcs for imported BOs") Signed-off-by: Huang Rui Reviewed-by: Alex Deucher Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index d0a1fee1f5f6f..174a73eb23f08 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -269,8 +269,8 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, resv = vm->root.base.bo->tbo.base.resv; } -retry: initial_domain = (u32)(0xffffffff & args->in.domains); +retry: r = amdgpu_gem_object_create(adev, size, args->in.alignment, initial_domain, flags, ttm_bo_type_device, resv, &gobj); -- GitLab From b99a8c8f239d76820bbed33c1a42c381cc1f16db Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Mon, 1 Feb 2021 18:39:16 +0800 Subject: [PATCH 0934/1084] drm/amdkfd: fix null pointer panic while free buffer in kfd In drm_gem_object_free, it will call funcs of drm buffer obj. So kfd_alloc should use amdgpu_gem_object_create instead of amdgpu_bo_create to initialize the funcs as amdgpu_gem_object_funcs. [ 396.231390] amdgpu: Release VA 0x7f76b4ada000 - 0x7f76b4add000 [ 396.231394] amdgpu: remove VA 0x7f76b4ada000 - 0x7f76b4add000 in entry 0000000085c24a47 [ 396.231408] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 396.231445] #PF: supervisor read access in kernel mode [ 396.231466] #PF: error_code(0x0000) - not-present page [ 396.231484] PGD 0 P4D 0 [ 396.231495] Oops: 0000 [#1] SMP NOPTI [ 396.231509] CPU: 7 PID: 1352 Comm: clinfo Tainted: G OE 5.11.0-rc2-custom #1 [ 396.231537] Hardware name: AMD Celadon-RN/Celadon-RN, BIOS WCD0401N_Weekly_20_04_0 04/01/2020 [ 396.231563] RIP: 0010:drm_gem_object_free+0xc/0x22 [drm] [ 396.231606] Code: eb ec 48 89 c3 eb e7 0f 1f 44 00 00 55 48 89 e5 48 8b bf 00 06 00 00 e8 72 0d 01 00 5d c3 0f 1f 44 00 00 48 8b 87 40 01 00 00 <48> 8b 00 48 85 c0 74 0b 55 48 89 e5 e8 54 37 7c db 5d c3 0f 0b c3 [ 396.231666] RSP: 0018:ffffb4704177fcf8 EFLAGS: 00010246 [ 396.231686] RAX: 0000000000000000 RBX: ffff993a0d0cc400 RCX: 0000000000003113 [ 396.231711] RDX: 0000000000000001 RSI: e9cda7a5d0791c6d RDI: ffff993a333a9058 [ 396.231736] RBP: ffffb4704177fdd0 R08: ffff993a03855858 R09: 0000000000000000 [ 396.231761] R10: ffff993a0d1f7158 R11: 0000000000000001 R12: 0000000000000000 [ 396.231785] R13: ffff993a0d0cc428 R14: 0000000000003000 R15: ffffb4704177fde0 [ 396.231811] FS: 00007f76b5730740(0000) GS:ffff993b275c0000(0000) knlGS:0000000000000000 [ 396.231840] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 396.231860] CR2: 0000000000000000 CR3: 000000016d2e2000 CR4: 0000000000350ee0 [ 396.231885] Call Trace: [ 396.231897] ? amdgpu_amdkfd_gpuvm_free_memory_of_gpu+0x24c/0x25f [amdgpu] [ 396.232056] ? __dynamic_dev_dbg+0xcd/0x100 [ 396.232076] kfd_ioctl_free_memory_of_gpu+0x91/0x102 [amdgpu] [ 396.232214] kfd_ioctl+0x211/0x35b [amdgpu] [ 396.232341] ? kfd_ioctl_get_queue_wave_state+0x52/0x52 [amdgpu] Fixes: 246cb7e49a70 ("drm/amdgpu: Introduce GEM object functions") Reviewed-by: Felix Kuehling Tested-by: Changfeng Signed-off-by: Huang Rui Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 2d991da2cead7..d1ed4f8df2b76 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -26,6 +26,7 @@ #include #include "amdgpu_object.h" +#include "amdgpu_gem.h" #include "amdgpu_vm.h" #include "amdgpu_amdkfd.h" #include "amdgpu_dma_buf.h" @@ -1152,7 +1153,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( struct sg_table *sg = NULL; uint64_t user_addr = 0; struct amdgpu_bo *bo; - struct amdgpu_bo_param bp; + struct drm_gem_object *gobj; u32 domain, alloc_domain; u64 alloc_flags; int ret; @@ -1220,19 +1221,14 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( pr_debug("\tcreate BO VA 0x%llx size 0x%llx domain %s\n", va, size, domain_string(alloc_domain)); - memset(&bp, 0, sizeof(bp)); - bp.size = size; - bp.byte_align = 1; - bp.domain = alloc_domain; - bp.flags = alloc_flags; - bp.type = bo_type; - bp.resv = NULL; - ret = amdgpu_bo_create(adev, &bp, &bo); + ret = amdgpu_gem_object_create(adev, size, 1, alloc_domain, alloc_flags, + bo_type, NULL, &gobj); if (ret) { pr_debug("Failed to create BO on domain %s. ret %d\n", - domain_string(alloc_domain), ret); + domain_string(alloc_domain), ret); goto err_bo_create; } + bo = gem_to_amdgpu_bo(gobj); if (bo_type == ttm_bo_type_sg) { bo->tbo.sg = sg; bo->tbo.ttm->sg = sg; -- GitLab From ea41bd232f167d6fd6505d54485826148b52e54a Mon Sep 17 00:00:00 2001 From: chen gong Date: Fri, 29 Jan 2021 15:37:45 +0800 Subject: [PATCH 0935/1084] drm/amdgpu/gfx10: update CGTS_TCC_DISABLE and CGTS_USER_TCC_DISABLE register offsets for VGH For Vangogh: The offset of the CGTS_TCC_DISABLE is 0x5006 by calculation. The offset of the CGTS_USER_TCC_DISABLE is 0x5007 by calculation. Signed-off-by: chen gong Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 346963e3cf731..d86b42a365601 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -99,6 +99,10 @@ #define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580 #define mmGCR_GENERAL_CNTL_Sienna_Cichlid_BASE_IDX 0 +#define mmCGTS_TCC_DISABLE_Vangogh 0x5006 +#define mmCGTS_TCC_DISABLE_Vangogh_BASE_IDX 1 +#define mmCGTS_USER_TCC_DISABLE_Vangogh 0x5007 +#define mmCGTS_USER_TCC_DISABLE_Vangogh_BASE_IDX 1 #define mmGOLDEN_TSC_COUNT_UPPER_Vangogh 0x0025 #define mmGOLDEN_TSC_COUNT_UPPER_Vangogh_BASE_IDX 1 #define mmGOLDEN_TSC_COUNT_LOWER_Vangogh 0x0026 @@ -4936,8 +4940,18 @@ static void gfx_v10_0_tcp_harvest(struct amdgpu_device *adev) static void gfx_v10_0_get_tcc_info(struct amdgpu_device *adev) { /* TCCs are global (not instanced). */ - uint32_t tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE) | - RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE); + uint32_t tcc_disable; + + switch (adev->asic_type) { + case CHIP_VANGOGH: + tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE_Vangogh) | + RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE_Vangogh); + break; + default: + tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE) | + RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE); + break; + } adev->gfx.config.tcc_disabled_mask = REG_GET_FIELD(tcc_disable, CGTS_TCC_DISABLE, TCC_DISABLE) | -- GitLab From 53a5a2729470ac7a7f77a64be4ae87dc4aa80d39 Mon Sep 17 00:00:00 2001 From: Xiaojian Du Date: Mon, 1 Feb 2021 16:20:38 +0800 Subject: [PATCH 0936/1084] drm/amd/pm: fill in the data member of v2 gpu metrics table for vangogh This patch is to fill in the data member of v2 gpu metrics table for vangogh. Signed-off-by: Xiaojian Du Reviewed-by: Kevin Wang Reviewed-by: Huang Rui Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index 5c1482d4ca43e..92ad2cdbae107 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -591,14 +591,17 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, gpu_metrics->average_socket_power = metrics.CurrentSocketPower; gpu_metrics->average_cpu_power = metrics.Power[0]; gpu_metrics->average_soc_power = metrics.Power[1]; + gpu_metrics->average_gfx_power = metrics.Power[2]; memcpy(&gpu_metrics->average_core_power[0], &metrics.CorePower[0], sizeof(uint16_t) * 8); gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency; gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency; + gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency; gpu_metrics->average_fclk_frequency = metrics.MemclkFrequency; gpu_metrics->average_vclk_frequency = metrics.VclkFrequency; + gpu_metrics->average_dclk_frequency = metrics.DclkFrequency; memcpy(&gpu_metrics->current_coreclk[0], &metrics.CoreFrequency[0], -- GitLab From cd9b0159beb7787bec38eb339ed7bc167d83b4ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 27 Jan 2021 13:20:40 +0100 Subject: [PATCH 0937/1084] drm/amdgpu: enable freesync for A+A configs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some newer APUs can scanout directly from GTT, that saves us from allocating another bounce buffer in VRAM and enables freesync in such configurations. Without this patch creating a framebuffer from the imported BO will fail and userspace will fall back to a copy. Signed-off-by: Christian König Reviewed-by: Shashank Sharma Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 8 ++++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index f764803c53a4b..48cb33e5b3826 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -926,8 +926,10 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) { - struct drm_gem_object *obj; struct amdgpu_framebuffer *amdgpu_fb; + struct drm_gem_object *obj; + struct amdgpu_bo *bo; + uint32_t domains; int ret; obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); @@ -938,7 +940,9 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, } /* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */ - if (obj->import_attach) { + bo = gem_to_amdgpu_bo(obj); + domains = amdgpu_display_supported_domains(drm_to_adev(dev), bo->flags); + if (obj->import_attach && !(domains & AMDGPU_GEM_DOMAIN_GTT)) { drm_dbg_kms(dev, "Cannot create framebuffer from imported dma_buf\n"); return ERR_PTR(-EINVAL); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 25ec4d57333f6..b4c8e5d5c763c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -897,7 +897,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, return -EINVAL; /* A shared bo cannot be migrated to VRAM */ - if (bo->prime_shared_count) { + if (bo->prime_shared_count || bo->tbo.base.import_attach) { if (domain & AMDGPU_GEM_DOMAIN_GTT) domain = AMDGPU_GEM_DOMAIN_GTT; else -- GitLab From 2b6b7ab4b1cabfbee1af5d818efcab5d51d62c7e Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 22 Dec 2020 14:05:41 -0500 Subject: [PATCH 0938/1084] drm/amd/display: Fix DPCD translation for LTTPR AUX_RD_INTERVAL [Why] The translation between the DPCD value and the specified AUX_RD_INTERVAL in the DP spec do not match. [How] Update values to match the spec. Signed-off-by: George Shen Reviewed-by: Wenjing Liu Acked-by: Anson Jacob Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index f95bade596242..1e4794e2825ca 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -892,13 +892,13 @@ static uint32_t translate_training_aux_read_interval(uint32_t dpcd_aux_read_inte switch (dpcd_aux_read_interval) { case 0x01: - aux_rd_interval_us = 400; + aux_rd_interval_us = 4000; break; case 0x02: - aux_rd_interval_us = 4000; + aux_rd_interval_us = 8000; break; case 0x03: - aux_rd_interval_us = 8000; + aux_rd_interval_us = 12000; break; case 0x04: aux_rd_interval_us = 16000; -- GitLab From 8866a67ab86cc0812e65c04f1ef02bcc41e24d68 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Wed, 6 Jan 2021 11:23:05 -0500 Subject: [PATCH 0939/1084] drm/amd/display: reuse current context instead of recreating one [Why] Currently we discard the current context and recreate it. The current context is what is applied to the HW so we should be re-using this rather than creating a new context. Recreating the context can lead to mismatch between new context and the current context For example: gsl groups get changed when we create a new context this can cause issues in a multi display config (with flip immediate) because we don't align the existing gsl groups in the new and current context. If we reuse the current context the gsl group assignment stays the same. [How] Instead of discarding the current context, we instead just copy the current state and add/remove planes and streams. Signed-off-by: Bhawanpreet Lakha Reviewed-by: Nicholas Kazlauskas Acked-by: Anson Jacob Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 +++++++--------- drivers/gpu/drm/amd/display/dc/core/dc.c | 27 +++++++++++++------ drivers/gpu/drm/amd/display/dc/dc_stream.h | 3 +-- 3 files changed, 30 insertions(+), 23 deletions(-) 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 c6da89df055de..0757328e3085a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1934,7 +1934,7 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, dc_commit_updates_for_stream( dm->dc, bundle->surface_updates, dc_state->stream_status->plane_count, - dc_state->streams[k], &bundle->stream_update, dc_state); + dc_state->streams[k], &bundle->stream_update); } cleanup: @@ -1965,8 +1965,7 @@ static void dm_set_dpms_off(struct dc_link *link) stream_update.stream = stream_state; dc_commit_updates_for_stream(stream_state->ctx->dc, NULL, 0, - stream_state, &stream_update, - stream_state->ctx->dc->current_state); + stream_state, &stream_update); mutex_unlock(&adev->dm.dc_lock); } @@ -7549,7 +7548,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct drm_crtc *pcrtc, bool wait_for_vblank) { - uint32_t i; + int i; uint64_t timestamp_ns; struct drm_plane *plane; struct drm_plane_state *old_plane_state, *new_plane_state; @@ -7590,7 +7589,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, amdgpu_dm_commit_cursors(state); /* update planes when needed */ - for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { + for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { struct drm_crtc *crtc = new_plane_state->crtc; struct drm_crtc_state *new_crtc_state; struct drm_framebuffer *fb = new_plane_state->fb; @@ -7813,8 +7812,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->surface_updates, planes_count, acrtc_state->stream, - &bundle->stream_update, - dc_state); + &bundle->stream_update); /** * Enable or disable the interrupts on the backend. @@ -8150,13 +8148,13 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state); struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); - struct dc_surface_update dummy_updates[MAX_SURFACES]; + struct dc_surface_update surface_updates[MAX_SURFACES]; struct dc_stream_update stream_update; struct dc_info_packet hdr_packet; struct dc_stream_status *status = NULL; bool abm_changed, hdr_changed, scaling_changed; - memset(&dummy_updates, 0, sizeof(dummy_updates)); + memset(&surface_updates, 0, sizeof(surface_updates)); memset(&stream_update, 0, sizeof(stream_update)); if (acrtc) { @@ -8213,16 +8211,15 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) * To fix this, DC should permit updating only stream properties. */ for (j = 0; j < status->plane_count; j++) - dummy_updates[j].surface = status->plane_states[0]; + surface_updates[j].surface = status->plane_states[j]; mutex_lock(&dm->dc_lock); dc_commit_updates_for_stream(dm->dc, - dummy_updates, + surface_updates, status->plane_count, dm_new_crtc_state->stream, - &stream_update, - dc_state); + &stream_update); mutex_unlock(&dm->dc_lock); } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 58eb0d69873a6..6cf1a5a2a5ecc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2679,8 +2679,7 @@ void dc_commit_updates_for_stream(struct dc *dc, struct dc_surface_update *srf_updates, int surface_count, struct dc_stream_state *stream, - struct dc_stream_update *stream_update, - struct dc_state *state) + struct dc_stream_update *stream_update) { const struct dc_stream_status *stream_status; enum surface_update_type update_type; @@ -2699,6 +2698,12 @@ void dc_commit_updates_for_stream(struct dc *dc, if (update_type >= UPDATE_TYPE_FULL) { + struct dc_plane_state *new_planes[MAX_SURFACES]; + + memset(new_planes, 0, sizeof(new_planes)); + + for (i = 0; i < surface_count; i++) + new_planes[i] = srf_updates[i].surface; /* initialize scratch memory for building context */ context = dc_create_state(dc); @@ -2707,15 +2712,21 @@ void dc_commit_updates_for_stream(struct dc *dc, return; } - dc_resource_state_copy_construct(state, context); + dc_resource_state_copy_construct( + dc->current_state, context); - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; - struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + /*remove old surfaces from context */ + if (!dc_rem_all_planes_for_stream(dc, stream, context)) { + DC_ERROR("Failed to remove streams for new validate context!\n"); + return; + } - if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) - new_pipe->plane_state->force_full_update = true; + /* add surface to context */ + if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) { + DC_ERROR("Failed to add streams for new validate context!\n"); + return; } + } diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index b7910976b81a7..e243c01b9672e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -283,8 +283,7 @@ void dc_commit_updates_for_stream(struct dc *dc, struct dc_surface_update *srf_updates, int surface_count, struct dc_stream_state *stream, - struct dc_stream_update *stream_update, - struct dc_state *state); + struct dc_stream_update *stream_update); /* * Log the current stream state. */ -- GitLab From 1622711beebe887e4f0f8237fea1f09bb48e9a51 Mon Sep 17 00:00:00 2001 From: Sung Lee Date: Fri, 15 Jan 2021 13:53:15 -0500 Subject: [PATCH 0940/1084] drm/amd/display: Add more Clock Sources to DCN2.1 [WHY] When enabling HDMI on ComboPHY, there are not enough clock sources to complete display detection. [HOW] Initialize more clock sources. Signed-off-by: Sung Lee Reviewed-by: Tony Cheng Acked-by: Anson Jacob Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index b000b43a820d4..6743764289167 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -906,6 +906,8 @@ enum dcn20_clk_src_array_id { DCN20_CLK_SRC_PLL0, DCN20_CLK_SRC_PLL1, DCN20_CLK_SRC_PLL2, + DCN20_CLK_SRC_PLL3, + DCN20_CLK_SRC_PLL4, DCN20_CLK_SRC_TOTAL_DCN21 }; @@ -2030,6 +2032,14 @@ static bool dcn21_resource_construct( dcn21_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL2, &clk_src_regs[2], false); + pool->base.clock_sources[DCN20_CLK_SRC_PLL3] = + dcn21_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL3, + &clk_src_regs[3], false); + pool->base.clock_sources[DCN20_CLK_SRC_PLL4] = + dcn21_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL4, + &clk_src_regs[4], false); pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21; -- GitLab From 1a10e5244778169a5a53a527d7830cf0438132a1 Mon Sep 17 00:00:00 2001 From: Stylon Wang Date: Tue, 5 Jan 2021 11:29:34 +0800 Subject: [PATCH 0941/1084] drm/amd/display: Revert "Fix EDID parsing after resume from suspend" This reverts commit b24bdc37d03a0478189e20a50286092840f414fa. It caused memory leak after S3 on 4K HDMI displays. Signed-off-by: Stylon Wang Reviewed-by: Rodrigo Siqueira Acked-by: Anson Jacob Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 -- 1 file changed, 2 deletions(-) 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 0757328e3085a..8d496fe36dd2d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2346,8 +2346,6 @@ void amdgpu_dm_update_connector_after_detect( drm_connector_update_edid_property(connector, aconnector->edid); - drm_add_edid_modes(connector, aconnector->edid); - if (aconnector->dc_link->aux_mode) drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, aconnector->edid); -- GitLab From 58180a0cc0c57fe62a799a112f95b60f6935bd96 Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Thu, 14 Jan 2021 11:48:57 -0500 Subject: [PATCH 0942/1084] drm/amd/display: Release DSC before acquiring [why] Need to unassign DSC from pipes that are not using it so other pipes can acquire it. That is needed for asic's that have unmatching number of DSC engines from the number of pipes. [how] Before acquiring dsc to stream resources, first remove it. Signed-off-by: Mikita Lipski Reviewed-by: Eryk Brol Acked-by: Anson Jacob Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 8ab0b9060d2bb..f2d8cf34be46e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -833,6 +833,9 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, if (computed_streams[i]) continue; + if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK) + return false; + mutex_lock(&aconnector->mst_mgr.lock); if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link)) { mutex_unlock(&aconnector->mst_mgr.lock); @@ -850,7 +853,8 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, stream = dc_state->streams[i]; if (stream->timing.flags.DSC == 1) - dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream); + if (dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream) != DC_OK) + return false; } return true; -- GitLab From 3ddc818d9bb877c64f5c649beab97af86c403702 Mon Sep 17 00:00:00 2001 From: Victor Lu Date: Thu, 14 Jan 2021 22:24:14 -0500 Subject: [PATCH 0943/1084] drm/amd/display: Fix dc_sink kref count in emulated_link_detect [why] prev_sink is not used anywhere else in the function and the reference to it from dc_link is replaced with a new dc_sink. [how] Change dc_sink_retain(prev_sink) to dc_sink_release(prev_sink). Signed-off-by: Victor Lu Reviewed-by: Nicholas Kazlauskas Acked-by: Anson Jacob Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 8d496fe36dd2d..ee1aa91bd2375 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1833,8 +1833,8 @@ static void emulated_link_detect(struct dc_link *link) link->type = dc_connection_none; prev_sink = link->local_sink; - if (prev_sink != NULL) - dc_sink_retain(prev_sink); + if (prev_sink) + dc_sink_release(prev_sink); switch (link->connector_signal) { case SIGNAL_TYPE_HDMI_TYPE_A: { -- GitLab From 2abaa323d744011982b20b8f3886184d56d23946 Mon Sep 17 00:00:00 2001 From: Victor Lu Date: Thu, 14 Jan 2021 16:27:07 -0500 Subject: [PATCH 0944/1084] drm/amd/display: Free atomic state after drm_atomic_commit [why] drm_atomic_commit was changed so that the caller must free their drm_atomic_state reference on successes. [how] Add drm_atomic_commit_put after drm_atomic_commit call in dm_force_atomic_commit. Signed-off-by: Victor Lu Reviewed-by: Roman Li Acked-by: Anson Jacob Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) 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 ee1aa91bd2375..6761c612beae1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8354,14 +8354,14 @@ static int dm_force_atomic_commit(struct drm_connector *connector) ret = PTR_ERR_OR_ZERO(conn_state); if (ret) - goto err; + goto out; /* Attach crtc to drm_atomic_state*/ crtc_state = drm_atomic_get_crtc_state(state, &disconnected_acrtc->base); ret = PTR_ERR_OR_ZERO(crtc_state); if (ret) - goto err; + goto out; /* force a restore */ crtc_state->mode_changed = true; @@ -8371,17 +8371,15 @@ static int dm_force_atomic_commit(struct drm_connector *connector) ret = PTR_ERR_OR_ZERO(plane_state); if (ret) - goto err; - + goto out; /* Call commit internally with the state we just constructed */ ret = drm_atomic_commit(state); - if (!ret) - return 0; -err: - DRM_ERROR("Restoring old state failed with %i\n", ret); +out: drm_atomic_state_put(state); + if (ret) + DRM_ERROR("Restoring old state failed with %i\n", ret); return ret; } -- GitLab From 8e92bb0fa75bca9a57e4aba2e36f67d8016a3053 Mon Sep 17 00:00:00 2001 From: Victor Lu Date: Fri, 15 Jan 2021 11:02:48 -0500 Subject: [PATCH 0945/1084] drm/amd/display: Decrement refcount of dc_sink before reassignment [why] An old dc_sink state is causing a memory leak because it is missing a dc_sink_release before a new dc_sink is assigned back to aconnector->dc_sink. [how] Decrement the dc_sink refcount before reassigning it to a new dc_sink. Signed-off-by: Victor Lu Reviewed-by: Rodrigo Siqueira Acked-by: Anson Jacob Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 6761c612beae1..961abf1cf040c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2329,8 +2329,10 @@ void amdgpu_dm_update_connector_after_detect( * TODO: check if we still need the S3 mode update workaround. * If yes, put it here. */ - if (aconnector->dc_sink) + if (aconnector->dc_sink) { amdgpu_dm_update_freesync_caps(connector, NULL); + dc_sink_release(aconnector->dc_sink); + } aconnector->dc_sink = sink; dc_sink_retain(aconnector->dc_sink); -- GitLab From 074075aea2ff72dade5231b4ee9f2ab9a055f1ec Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 2 Feb 2021 15:06:04 +0900 Subject: [PATCH 0946/1084] scripts/clang-tools: switch explicitly to Python 3 For the same reason as commit 51839e29cb59 ("scripts: switch explicitly to Python 3"), switch some more scripts, which I tested and confirmed working on Python 3. Signed-off-by: Masahiro Yamada Acked-by: Nathan Chancellor --- scripts/clang-tools/gen_compile_commands.py | 2 +- scripts/clang-tools/run-clang-tools.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/clang-tools/gen_compile_commands.py b/scripts/clang-tools/gen_compile_commands.py index 19963708bcf87..8ddb5d099029f 100755 --- a/scripts/clang-tools/gen_compile_commands.py +++ b/scripts/clang-tools/gen_compile_commands.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 # # Copyright (C) Google LLC, 2018 diff --git a/scripts/clang-tools/run-clang-tools.py b/scripts/clang-tools/run-clang-tools.py index fa7655c7cec0e..f754415af398b 100755 --- a/scripts/clang-tools/run-clang-tools.py +++ b/scripts/clang-tools/run-clang-tools.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 # # Copyright (C) Google LLC, 2020 -- GitLab From 2ab543823322b564f205cb15d0f0302803c87d11 Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Fri, 29 Jan 2021 12:31:05 -0500 Subject: [PATCH 0947/1084] riscv: virt_addr_valid must check the address belongs to linear mapping virt_addr_valid macro checks that a virtual address is valid, ie that the address belongs to the linear mapping and that the corresponding physical page exists. Add the missing check that ensures the virtual address belongs to the linear mapping, otherwise __virt_to_phys, when compiled with CONFIG_DEBUG_VIRTUAL enabled, raises a WARN that is interpreted as a kernel bug by syzbot. Signed-off-by: Alexandre Ghiti Reviewed-by: Atish Patra Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/page.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h index 2d50f76efe481..64a675c5c30ac 100644 --- a/arch/riscv/include/asm/page.h +++ b/arch/riscv/include/asm/page.h @@ -135,7 +135,10 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x); #endif /* __ASSEMBLY__ */ -#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr))) +#define virt_addr_valid(vaddr) ({ \ + unsigned long _addr = (unsigned long)vaddr; \ + (unsigned long)(_addr) >= PAGE_OFFSET && pfn_valid(virt_to_pfn(_addr)); \ +}) #define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC -- GitLab From f105ea9890f42137344f8c08548c895dc9294bd8 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Fri, 29 Jan 2021 11:00:36 -0800 Subject: [PATCH 0948/1084] RISC-V: Fix .init section permission update .init section permission should only updated to non-execute if STRICT_KERNEL_RWX is enabled. Otherwise, this will lead to a kernel hang. Fixes: 19a00869028f ("RISC-V: Protect all kernel sections including init early") Cc: stable@vger.kernel.org Suggested-by: Geert Uytterhoeven Reported-by: Geert Uytterhoeven Signed-off-by: Atish Patra Reviewed-by: Atish Patra Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/setup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 3fa3f26dde856..c7c0655dd45b0 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -293,6 +293,8 @@ void free_initmem(void) unsigned long init_begin = (unsigned long)__init_begin; unsigned long init_end = (unsigned long)__init_end; - set_memory_rw_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT); + if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) + set_memory_rw_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT); + free_initmem_default(POISON_FREE_INITMEM); } -- GitLab From eefb5f3ab2e8e0b3ef5eba5c5a9f33457741300d Mon Sep 17 00:00:00 2001 From: Sebastien Van Cauwenberghe Date: Fri, 29 Jan 2021 11:00:37 -0800 Subject: [PATCH 0949/1084] riscv: Align on L1_CACHE_BYTES when STRICT_KERNEL_RWX Allows the sections to be aligned on smaller boundaries and therefore results in a smaller kernel image size. Signed-off-by: Sebastien Van Cauwenberghe Reviewed-by: Atish Patra Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/set_memory.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h index 211eb8244a454..8b80c80c7f1ac 100644 --- a/arch/riscv/include/asm/set_memory.h +++ b/arch/riscv/include/asm/set_memory.h @@ -32,14 +32,14 @@ bool kernel_page_present(struct page *page); #endif /* __ASSEMBLY__ */ -#ifdef CONFIG_ARCH_HAS_STRICT_KERNEL_RWX +#ifdef CONFIG_STRICT_KERNEL_RWX #ifdef CONFIG_64BIT #define SECTION_ALIGN (1 << 21) #else #define SECTION_ALIGN (1 << 22) #endif -#else /* !CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */ +#else /* !CONFIG_STRICT_KERNEL_RWX */ #define SECTION_ALIGN L1_CACHE_BYTES -#endif /* CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */ +#endif /* CONFIG_STRICT_KERNEL_RWX */ #endif /* _ASM_RISCV_SET_MEMORY_H */ -- GitLab From de5f4b8f634beacf667e6eff334522601dd03b59 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Fri, 29 Jan 2021 11:00:38 -0800 Subject: [PATCH 0950/1084] RISC-V: Define MAXPHYSMEM_1GB only for RV32 MAXPHYSMEM_1GB option was added for RV32 because RV32 only supports 1GB of maximum physical memory. This lead to few compilation errors reported by kernel test robot which created the following configuration combination which are not useful but can be configured. 1. MAXPHYSMEM_1GB & RV64 2, MAXPHYSMEM_2GB & RV32 Fix this by restricting MAXPHYSMEM_1GB for RV32 and MAXPHYSMEM_2GB only for RV64. Fixes: e557793799c5 ("RISC-V: Fix maximum allowed phsyical memory for RV32") Cc: stable@vger.kernel.org Reported-by: Randy Dunlap Acked-by: Randy Dunlap Tested-by: Geert Uytterhoeven Signed-off-by: Atish Patra Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index e9e2c1f0a6905..e0a34eb5ed3b3 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -252,8 +252,10 @@ choice default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY config MAXPHYSMEM_1GB + depends on 32BIT bool "1GiB" config MAXPHYSMEM_2GB + depends on 64BIT && CMODEL_MEDLOW bool "2GiB" config MAXPHYSMEM_128GB depends on 64BIT && CMODEL_MEDANY -- GitLab From 388c705b95f23f317fa43e6abf9ff07b583b721a Mon Sep 17 00:00:00 2001 From: Lin Feng Date: Tue, 2 Feb 2021 07:18:23 -0700 Subject: [PATCH 0951/1084] bfq-iosched: Revert "bfq: Fix computation of shallow depth" This reverts commit 6d4d273588378c65915acaf7b2ee74e9dd9c130a. bfq.limit_depth passes word_depths[] as shallow_depth down to sbitmap core sbitmap_get_shallow, which uses just the number to limit the scan depth of each bitmap word, formula: scan_percentage_for_each_word = shallow_depth / (1 << sbimap->shift) * 100% That means the comments's percentiles 50%, 75%, 18%, 37% of bfq are correct. But after commit patch 'bfq: Fix computation of shallow depth', we use sbitmap.depth instead, as a example in following case: sbitmap.depth = 256, map_nr = 4, shift = 6; sbitmap_word.depth = 64. The resulsts of computed bfqd->word_depths[] are {128, 192, 48, 96}, and three of the numbers exceed core dirver's 'sbitmap_word.depth=64' limit nothing. Signed-off-by: Lin Feng Reviewed-by: Jan Kara Signed-off-by: Jens Axboe --- block/bfq-iosched.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 9e4eb0fc1c16e..9e81d1052091f 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -6332,13 +6332,13 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd, * limit 'something'. */ /* no more than 50% of tags for async I/O */ - bfqd->word_depths[0][0] = max(bt->sb.depth >> 1, 1U); + bfqd->word_depths[0][0] = max((1U << bt->sb.shift) >> 1, 1U); /* * no more than 75% of tags for sync writes (25% extra tags * w.r.t. async I/O, to prevent async I/O from starving sync * writes) */ - bfqd->word_depths[0][1] = max((bt->sb.depth * 3) >> 2, 1U); + bfqd->word_depths[0][1] = max(((1U << bt->sb.shift) * 3) >> 2, 1U); /* * In-word depths in case some bfq_queue is being weight- @@ -6348,9 +6348,9 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd, * shortage. */ /* no more than ~18% of tags for async I/O */ - bfqd->word_depths[1][0] = max((bt->sb.depth * 3) >> 4, 1U); + bfqd->word_depths[1][0] = max(((1U << bt->sb.shift) * 3) >> 4, 1U); /* no more than ~37% of tags for sync writes (~20% extra tags) */ - bfqd->word_depths[1][1] = max((bt->sb.depth * 6) >> 4, 1U); + bfqd->word_depths[1][1] = max(((1U << bt->sb.shift) * 6) >> 4, 1U); for (i = 0; i < 2; i++) for (j = 0; j < 2; j++) -- GitLab From ccd85d90ce092bdb047a7f6580f3955393833b22 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 2 Feb 2021 13:20:17 -0800 Subject: [PATCH 0952/1084] KVM: SVM: Treat SVM as unsupported when running as an SEV guest Don't let KVM load when running as an SEV guest, regardless of what CPUID says. Memory is encrypted with a key that is not accessible to the host (L0), thus it's impossible for L0 to emulate SVM, e.g. it'll see garbage when reading the VMCB. Technically, KVM could decrypt all memory that needs to be accessible to the L0 and use shadow paging so that L0 does not need to shadow NPT, but exposing such information to L0 largely defeats the purpose of running as an SEV guest. This can always be revisited if someone comes up with a use case for running VMs inside SEV guests. Note, VMLOAD, VMRUN, etc... will also #GP on GPAs with C-bit set, i.e. KVM is doomed even if the SEV guest is debuggable and the hypervisor is willing to decrypt the VMCB. This may or may not be fixed on CPUs that have the SVME_ADDR_CHK fix. Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Message-Id: <20210202212017.2486595-1-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 5 +++++ arch/x86/mm/mem_encrypt.c | 1 + 2 files changed, 6 insertions(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index f923e14e87df2..3442d44ca53b8 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -454,6 +454,11 @@ static int has_svm(void) return 0; } + if (sev_active()) { + pr_info("KVM is unsupported when running as an SEV guest\n"); + return 0; + } + return 1; } diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c index c79e5736ab2b7..c3d5f0236f353 100644 --- a/arch/x86/mm/mem_encrypt.c +++ b/arch/x86/mm/mem_encrypt.c @@ -382,6 +382,7 @@ bool sev_active(void) { return sev_status & MSR_AMD64_SEV_ENABLED; } +EXPORT_SYMBOL_GPL(sev_active); /* Needs to be called from non-instrumentable code */ bool noinstr sev_es_active(void) -- GitLab From c1c35cf78bfab31b8cb455259524395c9e4c7cd6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 13 Nov 2020 08:30:38 -0500 Subject: [PATCH 0953/1084] KVM: x86: cleanup CR3 reserved bits checks If not in long mode, the low bits of CR3 are reserved but not enforced to be zero, so remove those checks. If in long mode, however, the MBZ bits extend down to the highest physical address bit of the guest, excluding the encryption bit. Make the checks consistent with the above, and match them between nested_vmcb_checks and KVM_SET_SREGS. Cc: stable@vger.kernel.org Fixes: 761e41693465 ("KVM: nSVM: Check that MBZ bits in CR3 and CR4 are not set on vmrun of nested guests") Fixes: a780a3ea6282 ("KVM: X86: Fix reserved bits check for MOV to CR3") Reviewed-by: Sean Christopherson Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/nested.c | 13 +++---------- arch/x86/kvm/svm/svm.h | 3 --- arch/x86/kvm/x86.c | 2 ++ 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 7a605ad8254db..db30670dd8c4a 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -231,6 +231,7 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control) static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) { + struct kvm_vcpu *vcpu = &svm->vcpu; bool vmcb12_lma; if ((vmcb12->save.efer & EFER_SVME) == 0) @@ -244,18 +245,10 @@ static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) vmcb12_lma = (vmcb12->save.efer & EFER_LME) && (vmcb12->save.cr0 & X86_CR0_PG); - if (!vmcb12_lma) { - if (vmcb12->save.cr4 & X86_CR4_PAE) { - if (vmcb12->save.cr3 & MSR_CR3_LEGACY_PAE_RESERVED_MASK) - return false; - } else { - if (vmcb12->save.cr3 & MSR_CR3_LEGACY_RESERVED_MASK) - return false; - } - } else { + if (vmcb12_lma) { if (!(vmcb12->save.cr4 & X86_CR4_PAE) || !(vmcb12->save.cr0 & X86_CR0_PE) || - (vmcb12->save.cr3 & MSR_CR3_LONG_MBZ_MASK)) + (vmcb12->save.cr3 & vcpu->arch.cr3_lm_rsvd_bits)) return false; } if (!kvm_is_valid_cr4(&svm->vcpu, vmcb12->save.cr4)) diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 0fe874ae54982..6e7d070f8b86d 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -403,9 +403,6 @@ static inline bool gif_set(struct vcpu_svm *svm) } /* svm.c */ -#define MSR_CR3_LEGACY_RESERVED_MASK 0xfe7U -#define MSR_CR3_LEGACY_PAE_RESERVED_MASK 0x7U -#define MSR_CR3_LONG_MBZ_MASK 0xfff0000000000000U #define MSR_INVALID 0xffffffffU extern int sev; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 42b28d0f0311b..c1650e26715b3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9624,6 +9624,8 @@ static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) */ if (!(sregs->cr4 & X86_CR4_PAE) || !(sregs->efer & EFER_LMA)) return false; + if (sregs->cr3 & vcpu->arch.cr3_lm_rsvd_bits) + return false; } else { /* * Not in 64-bit mode: EFER.LMA is clear and the code -- GitLab From a900cac3750b9f0b8f5ed0503d9c6359532f644d Mon Sep 17 00:00:00 2001 From: Hermann Lauer Date: Thu, 28 Jan 2021 12:18:42 +0100 Subject: [PATCH 0954/1084] ARM: dts: sun7i: a20: bananapro: Fix ethernet phy-mode BPi Pro needs TX and RX delay for Gbit to work reliable and avoid high packet loss rates. The realtek phy driver overrides the settings of the pull ups for the delays, so fix this for BananaPro. Fix the phy-mode description to correctly reflect this so that the implementation doesn't reconfigure the delays incorrectly. This happened with commit bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay config"). Fixes: 10662a33dcd9 ("ARM: dts: sun7i: Add dts file for Bananapro board") Signed-off-by: Hermann Lauer Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20210128111842.GA11919@lemon.iwr.uni-heidelberg.de --- arch/arm/boot/dts/sun7i-a20-bananapro.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sun7i-a20-bananapro.dts b/arch/arm/boot/dts/sun7i-a20-bananapro.dts index 01ccff756996d..5740f9442705c 100644 --- a/arch/arm/boot/dts/sun7i-a20-bananapro.dts +++ b/arch/arm/boot/dts/sun7i-a20-bananapro.dts @@ -110,7 +110,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-supply = <®_gmac_3v3>; status = "okay"; }; -- GitLab From 5638159f6d93b99ec9743ac7f65563fca3cf413d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 3 Feb 2021 10:03:20 +0100 Subject: [PATCH 0955/1084] ARM: dts: lpc32xx: Revert set default clock rate of HCLK PLL This reverts commit c17e9377aa81664d94b4f2102559fcf2a01ec8e7. The lpc32xx clock driver is not able to actually change the PLL rate as this would require reparenting ARM_CLK, DDRAM_CLK, PERIPH_CLK to SYSCLK, then stop the PLL, update the register, restart the PLL and wait for the PLL to lock and finally reparent ARM_CLK, DDRAM_CLK, PERIPH_CLK to HCLK PLL. Currently, the HCLK driver simply updates the registers but this has no real effect and all the clock rate calculation end up being wrong. This is especially annoying for the peripheral (e.g. UARTs, I2C, SPI). Signed-off-by: Alexandre Belloni Tested-by: Gregory CLEMENT Link: https://lore.kernel.org/r/20210203090320.GA3760268@piout.net' Signed-off-by: Arnd Bergmann --- arch/arm/boot/dts/lpc32xx.dtsi | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index 3a5cfb0ddb20a..c87066d6c9950 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -326,9 +326,6 @@ clocks = <&xtal_32k>, <&xtal>; clock-names = "xtal_32k", "xtal"; - - assigned-clocks = <&clk LPC32XX_CLK_HCLK_PLL>; - assigned-clock-rates = <208000000>; }; }; -- GitLab From 3241929b67d28c83945d3191c6816a3271fd6b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 1 Feb 2021 16:08:03 +0100 Subject: [PATCH 0956/1084] usb: host: xhci: mvebu: make USB 3.0 PHY optional for Armada 3720 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Older ATF does not provide SMC call for USB 3.0 phy power on functionality and therefore initialization of xhci-hcd is failing when older version of ATF is used. In this case phy_power_on() function returns -EOPNOTSUPP. [ 3.108467] mvebu-a3700-comphy d0018300.phy: unsupported SMC call, try updating your firmware [ 3.117250] phy phy-d0018300.phy.0: phy poweron failed --> -95 [ 3.123465] xhci-hcd: probe of d0058000.usb failed with error -95 This patch introduces a new plat_setup callback for xhci platform drivers which is called prior calling usb_add_hcd() function. This function at its beginning skips PHY init if hcd->skip_phy_initialization is set. Current init_quirk callback for xhci platform drivers is called from xhci_plat_setup() function which is called after chip reset completes. It happens in the middle of the usb_add_hcd() function and therefore this callback cannot be used for setting if PHY init should be skipped or not. For Armada 3720 this patch introduce a new xhci_mvebu_a3700_plat_setup() function configured as a xhci platform plat_setup callback. This new function calls phy_power_on() and in case it returns -EOPNOTSUPP then XHCI_SKIP_PHY_INIT quirk is set to instruct xhci-plat to skip PHY initialization. This patch fixes above failure by ignoring 'not supported' error in xhci-hcd driver. In this case it is expected that phy is already power on. It fixes initialization of xhci-hcd on Espressobin boards where is older Marvell's Arm Trusted Firmware without SMC call for USB 3.0 phy power. This is regression introduced in commit bd3d25b07342 ("arm64: dts: marvell: armada-37xx: link USB hosts with their PHYs") where USB 3.0 phy was defined and therefore xhci-hcd on Espressobin with older ATF started failing. Fixes: bd3d25b07342 ("arm64: dts: marvell: armada-37xx: link USB hosts with their PHYs") Cc: # 5.1+: ea17a0f153af: phy: marvell: comphy: Convert internal SMCC firmware return codes to errno Cc: # 5.1+: f768e718911e: usb: host: xhci-plat: add priv quirk for skip PHY initialization Tested-by: Tomasz Maciej Nowak Tested-by: Yoshihiro Shimoda # On R-Car Reviewed-by: Yoshihiro Shimoda # xhci-plat Acked-by: Mathias Nyman Signed-off-by: Pali Rohár Link: https://lore.kernel.org/r/20210201150803.7305-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mvebu.c | 42 +++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci-mvebu.h | 6 +++++ drivers/usb/host/xhci-plat.c | 20 ++++++++++++++++- drivers/usb/host/xhci-plat.h | 1 + 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c index 60651a50770f9..8ca1a235d1645 100644 --- a/drivers/usb/host/xhci-mvebu.c +++ b/drivers/usb/host/xhci-mvebu.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -74,6 +75,47 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) return 0; } +int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct device *dev = hcd->self.controller; + struct phy *phy; + int ret; + + /* Old bindings miss the PHY handle */ + phy = of_phy_get(dev->of_node, "usb3-phy"); + if (IS_ERR(phy) && PTR_ERR(phy) == -EPROBE_DEFER) + return -EPROBE_DEFER; + else if (IS_ERR(phy)) + goto phy_out; + + ret = phy_init(phy); + if (ret) + goto phy_put; + + ret = phy_set_mode(phy, PHY_MODE_USB_HOST_SS); + if (ret) + goto phy_exit; + + ret = phy_power_on(phy); + if (ret == -EOPNOTSUPP) { + /* Skip initializatin of XHCI PHY when it is unsupported by firmware */ + dev_warn(dev, "PHY unsupported by firmware\n"); + xhci->quirks |= XHCI_SKIP_PHY_INIT; + } + if (ret) + goto phy_exit; + + phy_power_off(phy); +phy_exit: + phy_exit(phy); +phy_put: + of_phy_put(phy); +phy_out: + + return 0; +} + int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h index 3be021793cc8b..01bf3fcb3eca5 100644 --- a/drivers/usb/host/xhci-mvebu.h +++ b/drivers/usb/host/xhci-mvebu.h @@ -12,6 +12,7 @@ struct usb_hcd; #if IS_ENABLED(CONFIG_USB_XHCI_MVEBU) int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd); +int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd); int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd); #else static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) @@ -19,6 +20,11 @@ static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) return 0; } +static inline int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd) +{ + return 0; +} + static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) { return 0; diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 4d34f6005381e..c1edcc9b13cec 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -44,6 +44,16 @@ static void xhci_priv_plat_start(struct usb_hcd *hcd) priv->plat_start(hcd); } +static int xhci_priv_plat_setup(struct usb_hcd *hcd) +{ + struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); + + if (!priv->plat_setup) + return 0; + + return priv->plat_setup(hcd); +} + static int xhci_priv_init_quirk(struct usb_hcd *hcd) { struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); @@ -111,6 +121,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = { }; static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = { + .plat_setup = xhci_mvebu_a3700_plat_setup, .init_quirk = xhci_mvebu_a3700_init_quirk, }; @@ -330,7 +341,14 @@ static int xhci_plat_probe(struct platform_device *pdev) hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node); xhci->shared_hcd->tpl_support = hcd->tpl_support; - if (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)) + + if (priv) { + ret = xhci_priv_plat_setup(hcd); + if (ret) + goto disable_usb_phy; + } + + if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT))) hcd->skip_phy_initialization = 1; if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK)) diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h index 1fb149d1fbcea..561d0b7bce098 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h @@ -13,6 +13,7 @@ struct xhci_plat_priv { const char *firmware_name; unsigned long long quirks; + int (*plat_setup)(struct usb_hcd *); void (*plat_start)(struct usb_hcd *); int (*init_quirk)(struct usb_hcd *); int (*suspend_quirk)(struct usb_hcd *); -- GitLab From 7f1b11ba3564a391169420d98162987a12d0795d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 28 Jan 2021 20:28:56 +0100 Subject: [PATCH 0957/1084] tools/power/turbostat: Fallback to an MSR read for EPB Commit 6d6501d912a9 ("tools/power/turbostat: Read energy_perf_bias from sysfs") converted turbostat to read the energy_perf_bias value from sysfs. However, older kernels which do not have that file yet, would fail. For those, fall back to the MSR reading. Fixes: 6d6501d912a9 ("tools/power/turbostat: Read energy_perf_bias from sysfs") Reported-by: Artem Bityutskiy Signed-off-by: Borislav Petkov Tested-by: Artem Bityutskiy Link: https://lkml.kernel.org/r/20210127132444.981120-1-dedekind1@gmail.com --- tools/power/x86/turbostat/turbostat.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 389ea5209a83d..a7c4f0772e534 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -1834,12 +1834,15 @@ int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp) int get_epb(int cpu) { char path[128 + PATH_BYTES]; + unsigned long long msr; int ret, epb = -1; FILE *fp; sprintf(path, "/sys/devices/system/cpu/cpu%d/power/energy_perf_bias", cpu); - fp = fopen_or_die(path, "r"); + fp = fopen(path, "r"); + if (!fp) + goto msr_fallback; ret = fscanf(fp, "%d", &epb); if (ret != 1) @@ -1848,6 +1851,11 @@ int get_epb(int cpu) fclose(fp); return epb; + +msr_fallback: + get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr); + + return msr & 0xf; } void get_apic_id(struct thread_data *t) -- GitLab From d4a610635400ccc382792f6be69427078541c678 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 3 Feb 2021 13:37:02 +0200 Subject: [PATCH 0958/1084] xhci: fix bounce buffer usage for non-sg list case xhci driver may in some special cases need to copy small amounts of payload data to a bounce buffer in order to meet the boundary and alignment restrictions set by the xHCI specification. In the majority of these cases the data is in a sg list, and driver incorrectly assumed data is always in urb->sg when using the bounce buffer. If data instead is contiguous, and in urb->transfer_buffer, we may still need to bounce buffer a small part if data starts very close (less than packet size) to a 64k boundary. Check if sg list is used before copying data to/from it. Fixes: f9c589e142d0 ("xhci: TD-fragment, align the unsplittable case with a bounce buffer") Cc: stable@vger.kernel.org Reported-by: Andreas Hartmann Tested-by: Andreas Hartmann Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20210203113702.436762-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index cf0c93a90200f..89c3be9917f66 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -699,11 +699,16 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci, dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len, DMA_FROM_DEVICE); /* for in tranfers we need to copy the data from bounce to sg */ - len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf, - seg->bounce_len, seg->bounce_offs); - if (len != seg->bounce_len) - xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n", - len, seg->bounce_len); + if (urb->num_sgs) { + len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf, + seg->bounce_len, seg->bounce_offs); + if (len != seg->bounce_len) + xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n", + len, seg->bounce_len); + } else { + memcpy(urb->transfer_buffer + seg->bounce_offs, seg->bounce_buf, + seg->bounce_len); + } seg->bounce_len = 0; seg->bounce_offs = 0; } @@ -3277,12 +3282,16 @@ static int xhci_align_td(struct xhci_hcd *xhci, struct urb *urb, u32 enqd_len, /* create a max max_pkt sized bounce buffer pointed to by last trb */ if (usb_urb_dir_out(urb)) { - len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs, - seg->bounce_buf, new_buff_len, enqd_len); - if (len != new_buff_len) - xhci_warn(xhci, - "WARN Wrong bounce buffer write length: %zu != %d\n", - len, new_buff_len); + if (urb->num_sgs) { + len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs, + seg->bounce_buf, new_buff_len, enqd_len); + if (len != new_buff_len) + xhci_warn(xhci, "WARN Wrong bounce buffer write length: %zu != %d\n", + len, new_buff_len); + } else { + memcpy(seg->bounce_buf, urb->transfer_buffer + enqd_len, new_buff_len); + } + seg->bounce_dma = dma_map_single(dev, seg->bounce_buf, max_pkt, DMA_TO_DEVICE); } else { -- GitLab From cb8563f5c735a042ea2dd7df1ad55ae06d63ffeb Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Wed, 3 Feb 2021 01:20:25 -0800 Subject: [PATCH 0959/1084] nvmet-tcp: fix out-of-bounds access when receiving multiple h2cdata PDUs When the host sends multiple h2cdata PDUs, we keep track on the receive progress and calculate the scatterlist index and offsets. The issue is that sg_offset should only be kept for the first iov entry we map in the iovec as this is the difference between our cursor and the sg entry offset itself. In addition, the sg index was calculated wrong because we should not round up when dividing the command byte offset with PAG_SIZE. Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver") Reported-by: Narayan Ayalasomayajula Tested-by: Narayan Ayalasomayajula Signed-off-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/nvme/target/tcp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index dc1f0f6471896..aacf06f0b4312 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -305,7 +305,7 @@ static void nvmet_tcp_map_pdu_iovec(struct nvmet_tcp_cmd *cmd) length = cmd->pdu_len; cmd->nr_mapped = DIV_ROUND_UP(length, PAGE_SIZE); offset = cmd->rbytes_done; - cmd->sg_idx = DIV_ROUND_UP(offset, PAGE_SIZE); + cmd->sg_idx = offset / PAGE_SIZE; sg_offset = offset % PAGE_SIZE; sg = &cmd->req.sg[cmd->sg_idx]; @@ -318,6 +318,7 @@ static void nvmet_tcp_map_pdu_iovec(struct nvmet_tcp_cmd *cmd) length -= iov_len; sg = sg_next(sg); iov++; + sg_offset = 0; } iov_iter_kvec(&cmd->recv_msg.msg_iter, READ, cmd->iov, -- GitLab From e01a03db74a88084fb91a4ff18bb8d47a1e12f62 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Mon, 1 Feb 2021 16:01:21 +0800 Subject: [PATCH 0960/1084] ASoC: Intel: catpt: remove unneeded semicolon Eliminate the following coccicheck warning: ./sound/soc/intel/catpt/pcm.c:355:2-3: Unneeded semicolon Reported-by: Abaci Robot Signed-off-by: Yang Li Acked-by: Cezary Rojewski Link: https://lore.kernel.org/r/1612166481-121376-1-git-send-email-yang.lee@linux.alibaba.com Signed-off-by: Mark Brown --- sound/soc/intel/catpt/pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c index 9d304b3a817fa..ebb27daeb1c77 100644 --- a/sound/soc/intel/catpt/pcm.c +++ b/sound/soc/intel/catpt/pcm.c @@ -352,7 +352,7 @@ static int catpt_dai_apply_usettings(struct snd_soc_dai *dai, break; default: return 0; - }; + } list_for_each_entry(pos, &component->card->snd_card->controls, list) { if (pos->private_data == component && -- GitLab From e04e7b8ccd4912e6c823bf7e66f302a53396fb77 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 22 Jan 2021 10:13:32 +0900 Subject: [PATCH 0961/1084] ASoC: soc-pcm: tidyup pcm setting Current soc_new_pcm() setups pcm randomly. This patch tidyup it. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/878s8laigt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 7079a301ec31d..d5f1f653ec9b9 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2760,8 +2760,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) else rtd->close_delayed_work_func = snd_soc_close_delayed_work; - pcm->nonatomic = rtd->dai_link->nonatomic; rtd->pcm = pcm; + pcm->nonatomic = rtd->dai_link->nonatomic; pcm->private_data = rtd; if (rtd->dai_link->no_pcm || rtd->dai_link->params) { -- GitLab From 7fc6bebd5831a788a74e019e39c43c014a96a110 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 22 Jan 2021 10:13:38 +0900 Subject: [PATCH 0962/1084] ASoC: soc-pcm: add soc_get_playback_capture() and simplify soc_new_pcm() soc_new_pcm() implementation is very long / verbose / complex, thus, it is very difficult to read. If we read it carefully, we can notice that it is consisted by int soc_new_pcm(...) { (1) judging playback/caputre part (2) creating the PCM part (3) setup pcm/rtd part } This patch adds new soc_get_playback_capture() for (1) part and offload it from soc_new_pcm(). Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/877do5aign.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index d5f1f653ec9b9..46818b3319f6e 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2631,15 +2631,11 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) return ret; } -/* create a new pcm */ -int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) +static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd, + int *playback, int *capture) { struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; - struct snd_soc_component *component; - struct snd_pcm *pcm; - char new_name[64]; - int ret = 0, playback = 0, capture = 0; int stream; int i; @@ -2655,12 +2651,11 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) for_each_rtd_cpu_dais(rtd, i, cpu_dai) { if (snd_soc_dai_stream_valid(cpu_dai, stream)) { - playback = 1; + *playback = 1; break; } } - - if (!playback) { + if (!*playback) { dev_err(rtd->card->dev, "No CPU DAIs support playback for stream %s\n", rtd->dai_link->stream_name); @@ -2672,12 +2667,12 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) for_each_rtd_cpu_dais(rtd, i, cpu_dai) { if (snd_soc_dai_stream_valid(cpu_dai, stream)) { - capture = 1; + *capture = 1; break; } } - if (!capture) { + if (!*capture) { dev_err(rtd->card->dev, "No CPU DAIs support capture for stream %s\n", rtd->dai_link->stream_name); @@ -2704,23 +2699,39 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) && snd_soc_dai_stream_valid(cpu_dai, cpu_playback)) - playback = 1; + *playback = 1; if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) && snd_soc_dai_stream_valid(cpu_dai, cpu_capture)) - capture = 1; + *capture = 1; } } if (rtd->dai_link->playback_only) { - playback = 1; - capture = 0; + *playback = 1; + *capture = 0; } if (rtd->dai_link->capture_only) { - playback = 0; - capture = 1; + *playback = 0; + *capture = 1; } + return 0; +} + +/* create a new pcm */ +int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) +{ + struct snd_soc_component *component; + struct snd_pcm *pcm; + char new_name[64]; + int ret = 0, playback = 0, capture = 0; + int i; + + ret = soc_get_playback_capture(rtd, &playback, &capture); + if (ret < 0) + return ret; + /* create the PCM */ if (rtd->dai_link->params) { snprintf(new_name, sizeof(new_name), "codec2codec(%s)", -- GitLab From 2b39123b134e10a3817156bd9b157c9b8f950d6f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 22 Jan 2021 10:13:43 +0900 Subject: [PATCH 0963/1084] ASoC: soc-pcm: add soc_create_pcm() and simplify soc_new_pcm() soc_new_pcm() implementation is very long / verbose / complex, thus, it is very difficult to read. If we read it carefully, we can notice that it is consisted by int soc_new_pcm(...) { (1) judging playback/caputre part (2) creating the PCM part (3) setup pcm/rtd part } This patch adds new soc_create_pcm() for (2) part and offload it from snd_pcm_new(). Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/875z3paigi.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 46818b3319f6e..10c5e0beecd80 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2719,18 +2719,12 @@ static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd, return 0; } -/* create a new pcm */ -int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) +static int soc_create_pcm(struct snd_pcm **pcm, + struct snd_soc_pcm_runtime *rtd, + int playback, int capture, int num) { - struct snd_soc_component *component; - struct snd_pcm *pcm; char new_name[64]; - int ret = 0, playback = 0, capture = 0; - int i; - - ret = soc_get_playback_capture(rtd, &playback, &capture); - if (ret < 0) - return ret; + int ret; /* create the PCM */ if (rtd->dai_link->params) { @@ -2738,13 +2732,13 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) rtd->dai_link->stream_name); ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, - playback, capture, &pcm); + playback, capture, pcm); } else if (rtd->dai_link->no_pcm) { snprintf(new_name, sizeof(new_name), "(%s)", rtd->dai_link->stream_name); ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, - playback, capture, &pcm); + playback, capture, pcm); } else { if (rtd->dai_link->dynamic) snprintf(new_name, sizeof(new_name), "%s (*)", @@ -2756,7 +2750,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) "multicodec" : asoc_rtd_to_codec(rtd, 0)->name, num); ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback, - capture, &pcm); + capture, pcm); } if (ret < 0) { dev_err(rtd->card->dev, "ASoC: can't create pcm %s for dailink %s: %d\n", @@ -2765,6 +2759,25 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) } dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name); + return 0; +} + +/* create a new pcm */ +int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) +{ + struct snd_soc_component *component; + struct snd_pcm *pcm; + int ret = 0, playback = 0, capture = 0; + int i; + + ret = soc_get_playback_capture(rtd, &playback, &capture); + if (ret < 0) + return ret; + + ret = soc_create_pcm(&pcm, rtd, playback, capture, num); + if (ret < 0) + return ret; + /* DAPM dai link stream work */ if (rtd->dai_link->params) rtd->close_delayed_work_func = codec2codec_close_delayed_work; @@ -2825,8 +2838,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) ret = snd_soc_pcm_component_new(rtd); if (ret < 0) { - dev_err(rtd->dev, "ASoC: pcm %s constructor failed for dailink %s: %d\n", - new_name, rtd->dai_link->name, ret); + dev_err(rtd->dev, "ASoC: pcm constructor failed for dailink %s: %d\n", + rtd->dai_link->name, ret); return ret; } -- GitLab From 4b260f425497b105acc2baa9d97ef781ef0c667d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 22 Jan 2021 10:13:48 +0900 Subject: [PATCH 0964/1084] ASoC: soc-pcm: use snd_pcm_hardware at dpcm_runtime_merge_xxx() soc-pcm has dpcm_runtime_merge_xxx() functions, but uses parameters are very verbose. dpcm_runtime_merge_format(..., &runtime->hw.formats); dpcm_runtime_merge_chan(..., &runtime->hw.channels_min, &runtime->hw.channels_max); dpcm_runtime_merge_rate(..., &runtime->hw.rates, &runtime->hw.rate_min, &runtime->hw.rate_max); We want to replace it into dpcm_runtime_merge_format(..., runtime); dpcm_runtime_merge_chan(..., runtime); dpcm_runtime_merge_rate(..., runtime); This patch do it. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/874kj9aigd.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 10c5e0beecd80..2a625ce0bacbc 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1526,9 +1526,10 @@ static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, } static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, - u64 *formats) + struct snd_pcm_runtime *runtime) { struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); + struct snd_pcm_hardware *hw = &runtime->hw; struct snd_soc_dpcm *dpcm; struct snd_soc_dai *dai; int stream = substream->stream; @@ -1556,16 +1557,16 @@ static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, codec_stream = snd_soc_dai_get_pcm_stream(dai, stream); - *formats &= codec_stream->formats; + hw->formats &= codec_stream->formats; } } } static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, - unsigned int *channels_min, - unsigned int *channels_max) + struct snd_pcm_runtime *runtime) { struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); + struct snd_pcm_hardware *hw = &runtime->hw; struct snd_soc_dpcm *dpcm; int stream = substream->stream; @@ -1594,10 +1595,10 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream); - *channels_min = max(*channels_min, - cpu_stream->channels_min); - *channels_max = min(*channels_max, - cpu_stream->channels_max); + hw->channels_min = max(hw->channels_min, + cpu_stream->channels_min); + hw->channels_max = min(hw->channels_max, + cpu_stream->channels_max); } /* @@ -1607,20 +1608,19 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, if (be->num_codecs == 1) { codec_stream = snd_soc_dai_get_pcm_stream(asoc_rtd_to_codec(be, 0), stream); - *channels_min = max(*channels_min, - codec_stream->channels_min); - *channels_max = min(*channels_max, - codec_stream->channels_max); + hw->channels_min = max(hw->channels_min, + codec_stream->channels_min); + hw->channels_max = min(hw->channels_max, + codec_stream->channels_max); } } } static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, - unsigned int *rates, - unsigned int *rate_min, - unsigned int *rate_max) + struct snd_pcm_runtime *runtime) { struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); + struct snd_pcm_hardware *hw = &runtime->hw; struct snd_soc_dpcm *dpcm; int stream = substream->stream; @@ -1648,9 +1648,9 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, pcm = snd_soc_dai_get_pcm_stream(dai, stream); - *rate_min = max(*rate_min, pcm->rate_min); - *rate_max = min_not_zero(*rate_max, pcm->rate_max); - *rates = snd_pcm_rate_mask_intersect(*rates, pcm->rates); + hw->rate_min = max(hw->rate_min, pcm->rate_min); + hw->rate_max = min_not_zero(hw->rate_max, pcm->rate_max); + hw->rates = snd_pcm_rate_mask_intersect(hw->rates, pcm->rates); } } } @@ -1675,11 +1675,9 @@ static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) substream->stream)); } - dpcm_runtime_merge_format(substream, &runtime->hw.formats); - dpcm_runtime_merge_chan(substream, &runtime->hw.channels_min, - &runtime->hw.channels_max); - dpcm_runtime_merge_rate(substream, &runtime->hw.rates, - &runtime->hw.rate_min, &runtime->hw.rate_max); + dpcm_runtime_merge_format(substream, runtime); + dpcm_runtime_merge_chan(substream, runtime); + dpcm_runtime_merge_rate(substream, runtime); } static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream, -- GitLab From dd5abc7834ffae1ca6c399583353e00886817181 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 22 Jan 2021 10:13:53 +0900 Subject: [PATCH 0965/1084] ASoC: soc-pcm: fixup snd_pcm_limit_hw_rates() timing soc-pcm has snd_pcm_limit_hw_rates() which determine rate_min/rate_max. It updates runtime->hw.rate_min/max (A) based on hw->rates (B). int snd_pcm_limit_hw_rates(...) { int i; for (...) { (B) if (runtime->hw.rates & (1 << i)) { (A) runtime->hw.rate_min = ... break; } } for (...) { (B) if (runtime->hw.rates & (1 << i)) { (A) runtime->hw.rate_max = ... break; } } return 0; } This means, setup order is 1) set hw->rates 2) call snd_pcm_limit_hw_rates() 3) update hw->rate_min/max soc_pcm_init_runtime_hw() is calling it in good order static void soc_pcm_init_runtime_hw(xxx) { ... 1) hw->rates = snd_pcm_rate_mask_intersect(...); 2) snd_pcm_limit_hw_rates(...); 3) hw->rate_min = max(...); hw->rate_min = max(...); hw->rate_max = min_not_zero(...); hw->rate_max = min_not_zero(...); } But, dpcm_fe_dai_startup() is not. static int dpcm_fe_dai_startup(xxx) { ... 1) 3) dpcm_set_fe_runtime(...); 2) snd_pcm_limit_hw_rates(...); ... } More detail of dpcm_set_fe_runtime() is static void dpcm_set_fe_runtime() { ... for_each_rtd_cpu_dais(rtd, i, cpu_dai) { ... 3) 1) dpcm_init_runtime_hw(...); } ... 3) 1) dpcm_runtime_merge_rate(...); } This patch fixup these into static void dpcm_set_fe_runtime() { ... for_each_rtd_cpu_dais(rtd, i, cpu_dai) { ... 1) 2) 3) dpcm_init_runtime_hw(...); } ... 1) 2) 3) dpcm_runtime_merge_rate(...); } static int dpcm_fe_dai_startup(xxx) { ... dpcm_set_fe_runtime(...); - snd_pcm_limit_hw_rates(...); ... } Link: https://lore.kernel.org/r/87k15l7ewd.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/8735ytaig8.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 2a625ce0bacbc..b79f064887d43 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1514,6 +1514,10 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, struct snd_soc_pcm_stream *stream) { + runtime->hw.rates = stream->rates; + + snd_pcm_limit_hw_rates(runtime); + runtime->hw.rate_min = stream->rate_min; runtime->hw.rate_max = min_not_zero(stream->rate_max, UINT_MAX); runtime->hw.channels_min = stream->channels_min; @@ -1522,7 +1526,6 @@ static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, runtime->hw.formats &= stream->formats; else runtime->hw.formats = stream->formats; - runtime->hw.rates = stream->rates; } static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, @@ -1648,9 +1651,12 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, pcm = snd_soc_dai_get_pcm_stream(dai, stream); + hw->rates = snd_pcm_rate_mask_intersect(hw->rates, pcm->rates); + + snd_pcm_limit_hw_rates(runtime); + hw->rate_min = max(hw->rate_min, pcm->rate_min); hw->rate_max = min_not_zero(hw->rate_max, pcm->rate_max); - hw->rates = snd_pcm_rate_mask_intersect(hw->rates, pcm->rates); } } } @@ -1738,7 +1744,6 @@ static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream, static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) { struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(fe_substream); - struct snd_pcm_runtime *runtime = fe_substream->runtime; int stream = fe_substream->stream, ret = 0; dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); @@ -1761,7 +1766,6 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; dpcm_set_fe_runtime(fe_substream); - snd_pcm_limit_hw_rates(runtime); ret = dpcm_apply_symmetry(fe_substream, stream); if (ret < 0) -- GitLab From f295c8cfec833c2707ff1512da10d65386dde7af Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 1 Feb 2021 10:56:32 +1000 Subject: [PATCH 0966/1084] drm/nouveau: fix dma syncing warning with debugging on. Since I wrote the below patch if you run a debug kernel you can a dma debug warning like: nouveau 0000:1f:00.0: DMA-API: device driver tries to sync DMA memory it has not allocated [device address=0x000000016e012000] [size=4096 bytes] The old nouveau code wasn't consolidate the pages like the ttm code, but the dma-debug expects the sync code to give it the same base/range pairs as the allocator. Fix the nouveau sync code to consolidate pages before calling the sync code. Fixes: bd549d35b4be0 ("nouveau: use ttm populate mapping functions. (v2)") Reported-by: Lyude Paul Reviewed-by: Ben Skeggs Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/417588/ --- drivers/gpu/drm/nouveau/nouveau_bo.c | 35 +++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index c85b1af06b7bf..7ea367a5444dd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -547,7 +547,7 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) { struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm; - int i; + int i, j; if (!ttm_dma) return; @@ -556,10 +556,21 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) if (nvbo->force_coherent) return; - for (i = 0; i < ttm_dma->num_pages; i++) + for (i = 0; i < ttm_dma->num_pages; ++i) { + struct page *p = ttm_dma->pages[i]; + size_t num_pages = 1; + + for (j = i + 1; j < ttm_dma->num_pages; ++j) { + if (++p != ttm_dma->pages[j]) + break; + + ++num_pages; + } dma_sync_single_for_device(drm->dev->dev, ttm_dma->dma_address[i], - PAGE_SIZE, DMA_TO_DEVICE); + num_pages * PAGE_SIZE, DMA_TO_DEVICE); + i += num_pages; + } } void @@ -567,7 +578,7 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) { struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm; - int i; + int i, j; if (!ttm_dma) return; @@ -576,9 +587,21 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) if (nvbo->force_coherent) return; - for (i = 0; i < ttm_dma->num_pages; i++) + for (i = 0; i < ttm_dma->num_pages; ++i) { + struct page *p = ttm_dma->pages[i]; + size_t num_pages = 1; + + for (j = i + 1; j < ttm_dma->num_pages; ++j) { + if (++p != ttm_dma->pages[j]) + break; + + ++num_pages; + } + dma_sync_single_for_cpu(drm->dev->dev, ttm_dma->dma_address[i], - PAGE_SIZE, DMA_FROM_DEVICE); + num_pages * PAGE_SIZE, DMA_FROM_DEVICE); + i += num_pages; + } } void nouveau_bo_add_io_reserve_lru(struct ttm_buffer_object *bo) -- GitLab From 87aa9ec939ec7277b730786e19c161c9194cc8ca Mon Sep 17 00:00:00 2001 From: Ben Gardon Date: Tue, 2 Feb 2021 10:57:16 -0800 Subject: [PATCH 0967/1084] KVM: x86/mmu: Fix TDP MMU zap collapsible SPTEs There is a bug in the TDP MMU function to zap SPTEs which could be replaced with a larger mapping which prevents the function from doing anything. Fix this by correctly zapping the last level SPTEs. Cc: stable@vger.kernel.org Fixes: 14881998566d ("kvm: x86/mmu: Support disabling dirty logging for the tdp MMU") Signed-off-by: Ben Gardon Message-Id: <20210202185734.1680553-11-bgardon@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/tdp_mmu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 2ef8615f9dba8..b56d604809b8a 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1049,8 +1049,8 @@ bool kvm_tdp_mmu_slot_set_dirty(struct kvm *kvm, struct kvm_memory_slot *slot) } /* - * Clear non-leaf entries (and free associated page tables) which could - * be replaced by large mappings, for GFNs within the slot. + * Clear leaf entries which could be replaced by large mappings, for + * GFNs within the slot. */ static void zap_collapsible_spte_range(struct kvm *kvm, struct kvm_mmu_page *root, @@ -1062,7 +1062,7 @@ static void zap_collapsible_spte_range(struct kvm *kvm, tdp_root_for_each_pte(iter, root, start, end) { if (!is_shadow_present_pte(iter.old_spte) || - is_last_spte(iter.old_spte, iter.level)) + !is_last_spte(iter.old_spte, iter.level)) continue; pfn = spte_to_pfn(iter.old_spte); -- GitLab From 06e577b45db37e8a96ce04e7daa64480492b4ace Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 20 Jan 2021 22:49:53 +0100 Subject: [PATCH 0968/1084] mfd: arizona: Add MODULE_SOFTDEP("pre: arizona_ldo1") The (shared) probing code of the arizona-i2c and arizona-spi modules takes the following steps during init: 1. Call mfd_add_devices() for a set of early child-devices, this includes the arizona_ldo1 device which provides one of the core-regulators. 2. Bulk enable the core-regulators. 3. Read the device id. 4. Call mfd_add_devices() for the other child-devices. This sequence depends on 1. leading to not only the child-device being created, but also the driver for the child-device binding to it and registering its regulator. This requires the arizona_ldo1 driver to be loaded before the shared probing code runs. Add a softdep for this to both modules to ensure that this requirement is met. Note this mirrors the existing MODULE_SOFTDEP("pre: wm8994_regulator") in the wm8994 code, which has a similar init sequence. Reviewed-by: Andy Shevchenko Acked-by: Charles Keepax Signed-off-by: Hans de Goede Signed-off-by: Lee Jones --- drivers/mfd/arizona-i2c.c | 1 + drivers/mfd/arizona-spi.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c index 4b58e3ad6eb6f..2a4a3a164d0a9 100644 --- a/drivers/mfd/arizona-i2c.c +++ b/drivers/mfd/arizona-i2c.c @@ -115,6 +115,7 @@ static struct i2c_driver arizona_i2c_driver = { module_i2c_driver(arizona_i2c_driver); +MODULE_SOFTDEP("pre: arizona_ldo1"); MODULE_DESCRIPTION("Arizona I2C bus interface"); MODULE_AUTHOR("Mark Brown "); MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index 2633e147b76c2..704f214d26148 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c @@ -110,6 +110,7 @@ static struct spi_driver arizona_spi_driver = { module_spi_driver(arizona_spi_driver); +MODULE_SOFTDEP("pre: arizona_ldo1"); MODULE_DESCRIPTION("Arizona SPI bus interface"); MODULE_AUTHOR("Mark Brown "); MODULE_LICENSE("GPL"); -- GitLab From 039da225d644e523a3bbec78ee258b25fe0676f9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 20 Jan 2021 22:49:54 +0100 Subject: [PATCH 0969/1084] mfd: arizona: Replace arizona_of_get_type() with device_get_match_data() Replace the custom arizona_of_get_type() function with the generic device_get_match_data() helper. Besides being a nice cleanup this also makes it easier to add support for binding to ACPI enumerated devices. While at it also fix a possible NULL pointer deref of the id argument to the probe functions (this could happen on e.g. manual driver binding through sysfs). Suggested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Acked-by: Charles Keepax Signed-off-by: Hans de Goede Signed-off-by: Lee Jones --- drivers/mfd/arizona-core.c | 11 ----------- drivers/mfd/arizona-i2c.c | 10 ++++++---- drivers/mfd/arizona-spi.c | 10 ++++++---- drivers/mfd/arizona.h | 9 --------- 4 files changed, 12 insertions(+), 28 deletions(-) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 000cb82023e35..75f1bc671d59e 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -797,17 +797,6 @@ const struct dev_pm_ops arizona_pm_ops = { EXPORT_SYMBOL_GPL(arizona_pm_ops); #ifdef CONFIG_OF -unsigned long arizona_of_get_type(struct device *dev) -{ - const struct of_device_id *id = of_match_device(arizona_of_match, dev); - - if (id) - return (unsigned long)id->data; - else - return 0; -} -EXPORT_SYMBOL_GPL(arizona_of_get_type); - static int arizona_of_get_core_pdata(struct arizona *arizona) { struct arizona_pdata *pdata = &arizona->pdata; diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c index 2a4a3a164d0a9..5e83b730c4ced 100644 --- a/drivers/mfd/arizona-i2c.c +++ b/drivers/mfd/arizona-i2c.c @@ -23,14 +23,16 @@ static int arizona_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + const void *match_data; struct arizona *arizona; const struct regmap_config *regmap_config = NULL; - unsigned long type; + unsigned long type = 0; int ret; - if (i2c->dev.of_node) - type = arizona_of_get_type(&i2c->dev); - else + match_data = device_get_match_data(&i2c->dev); + if (match_data) + type = (unsigned long)match_data; + else if (id) type = id->driver_data; switch (type) { diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index 704f214d26148..798b88295c774 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c @@ -23,14 +23,16 @@ static int arizona_spi_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); + const void *match_data; struct arizona *arizona; const struct regmap_config *regmap_config = NULL; - unsigned long type; + unsigned long type = 0; int ret; - if (spi->dev.of_node) - type = arizona_of_get_type(&spi->dev); - else + match_data = device_get_match_data(&spi->dev); + if (match_data) + type = (unsigned long)match_data; + else if (id) type = id->driver_data; switch (type) { diff --git a/drivers/mfd/arizona.h b/drivers/mfd/arizona.h index 995efc6d7f32a..801cbbcd71cb5 100644 --- a/drivers/mfd/arizona.h +++ b/drivers/mfd/arizona.h @@ -50,13 +50,4 @@ int arizona_dev_exit(struct arizona *arizona); int arizona_irq_init(struct arizona *arizona); int arizona_irq_exit(struct arizona *arizona); -#ifdef CONFIG_OF -unsigned long arizona_of_get_type(struct device *dev); -#else -static inline unsigned long arizona_of_get_type(struct device *dev) -{ - return 0; -} -#endif - #endif -- GitLab From e933836744a2606e6cd42a6a83e5e43da2a60788 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 20 Jan 2021 22:49:55 +0100 Subject: [PATCH 0970/1084] mfd: arizona: Add support for ACPI enumeration of WM5102 connected over SPI The Intel Bay Trail (x86/ACPI) based Lenovo Yoga Tablet 2 series use a WM5102 codec connected over SPI. Add support for ACPI enumeration to arizona-spi so that arizona-spi can bind to the codec on these tablets. This is loosely based on an earlier attempt (for Android-x86) at this by Christian Hartmann, combined with insights in things like the speaker GPIO from the android-x86 android port for the Lenovo Yoga Tablet 2 1051F/L [1]. [1] https://github.com/Kitsune2222/Android_Yoga_Tablet_2-1051F_Kernel Cc: Christian Hartmann Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/arizona-spi.c | 127 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index 798b88295c774..24a2c75d691a4 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c @@ -7,7 +7,10 @@ * Author: Mark Brown */ +#include #include +#include +#include #include #include #include @@ -15,11 +18,128 @@ #include #include #include +#include #include #include "arizona.h" +#ifdef CONFIG_ACPI +const struct acpi_gpio_params reset_gpios = { 1, 0, false }; +const struct acpi_gpio_params ldoena_gpios = { 2, 0, false }; + +static const struct acpi_gpio_mapping arizona_acpi_gpios[] = { + { "reset-gpios", &reset_gpios, 1, }, + { "wlf,ldoena-gpios", &ldoena_gpios, 1 }, + { } +}; + +/* + * The ACPI resources for the device only describe external GPIO-s. They do + * not provide mappings for the GPIO-s coming from the Arizona codec itself. + */ +static const struct gpiod_lookup arizona_soc_gpios[] = { + { "arizona", 2, "wlf,spkvdd-ena", 0, GPIO_ACTIVE_HIGH }, + { "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW }, +}; + +/* + * The AOSP 3.5 mm Headset: Accessory Specification gives the following values: + * Function A Play/Pause: 0 ohm + * Function D Voice assistant: 135 ohm + * Function B Volume Up 240 ohm + * Function C Volume Down 470 ohm + * Minimum Mic DC resistance 1000 ohm + * Minimum Ear speaker impedance 16 ohm + * Note the first max value below must be less then the min. speaker impedance, + * to allow CTIA/OMTP detection to work. The other max values are the closest + * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances. + */ +static const struct arizona_micd_range arizona_micd_aosp_ranges[] = { + { .max = 11, .key = KEY_PLAYPAUSE }, + { .max = 186, .key = KEY_VOICECOMMAND }, + { .max = 348, .key = KEY_VOLUMEUP }, + { .max = 752, .key = KEY_VOLUMEDOWN }, +}; + +static void arizona_spi_acpi_remove_lookup(void *lookup) +{ + gpiod_remove_lookup_table(lookup); +} + +static int arizona_spi_acpi_probe(struct arizona *arizona) +{ + struct gpiod_lookup_table *lookup; + acpi_status status; + int ret; + + /* Add mappings for the 2 ACPI declared GPIOs used for reset and ldo-ena */ + devm_acpi_dev_add_driver_gpios(arizona->dev, arizona_acpi_gpios); + + /* Add lookups for the SoCs own GPIOs used for micdet-polarity and spkVDD-enable */ + lookup = devm_kzalloc(arizona->dev, + struct_size(lookup, table, ARRAY_SIZE(arizona_soc_gpios) + 1), + GFP_KERNEL); + if (!lookup) + return -ENOMEM; + + lookup->dev_id = dev_name(arizona->dev); + memcpy(lookup->table, arizona_soc_gpios, sizeof(arizona_soc_gpios)); + + gpiod_add_lookup_table(lookup); + ret = devm_add_action_or_reset(arizona->dev, arizona_spi_acpi_remove_lookup, lookup); + if (ret) + return ret; + + /* Enable 32KHz clock from SoC to codec for jack-detect */ + status = acpi_evaluate_object(ACPI_HANDLE(arizona->dev), "CLKE", NULL, NULL); + if (ACPI_FAILURE(status)) + dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status); + + /* + * Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING + * The IRQ line will stay low when a new IRQ event happens between reading + * the IRQ status flags and acknowledging them. When the IRQ line stays + * low like this the IRQ will never trigger again when its type is set + * to IRQF_TRIGGER_FALLING. Correct the IRQ trigger-type to fix this. + * + * Note theoretically it is possible that some boards are not capable + * of handling active low level interrupts. In that case setting the + * flag to IRQF_TRIGGER_FALLING would not be a bug (and we would need + * to work around this) but so far all known usages of IRQF_TRIGGER_FALLING + * are a bug in the board's DSDT. + */ + arizona->pdata.irq_flags = IRQF_TRIGGER_LOW; + + /* Wait 200 ms after jack insertion */ + arizona->pdata.micd_detect_debounce = 200; + + /* Use standard AOSP values for headset-button mappings */ + arizona->pdata.micd_ranges = arizona_micd_aosp_ranges; + arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges); + + return 0; +} + +static const struct acpi_device_id arizona_acpi_match[] = { + { + .id = "WM510204", + .driver_data = WM5102, + }, + { + .id = "WM510205", + .driver_data = WM5102, + }, + { } +}; +MODULE_DEVICE_TABLE(acpi, arizona_acpi_match); +#else +static int arizona_spi_acpi_probe(struct arizona *arizona) +{ + return -ENODEV; +} +#endif + static int arizona_spi_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); @@ -77,6 +197,12 @@ static int arizona_spi_probe(struct spi_device *spi) arizona->dev = &spi->dev; arizona->irq = spi->irq; + if (has_acpi_companion(&spi->dev)) { + ret = arizona_spi_acpi_probe(arizona); + if (ret) + return ret; + } + return arizona_dev_init(arizona); } @@ -104,6 +230,7 @@ static struct spi_driver arizona_spi_driver = { .name = "arizona", .pm = &arizona_pm_ops, .of_match_table = of_match_ptr(arizona_of_match), + .acpi_match_table = ACPI_PTR(arizona_acpi_match), }, .probe = arizona_spi_probe, .remove = arizona_spi_remove, -- GitLab From d7e10d47691d1702db1cd1edcc689d3031eefc67 Mon Sep 17 00:00:00 2001 From: Xiaoguang Wang Date: Thu, 4 Feb 2021 17:20:56 +0800 Subject: [PATCH 0971/1084] io_uring: don't modify identity's files uncess identity is cowed Abaci Robot reported following panic: BUG: kernel NULL pointer dereference, address: 0000000000000000 PGD 800000010ef3f067 P4D 800000010ef3f067 PUD 10d9df067 PMD 0 Oops: 0002 [#1] SMP PTI CPU: 0 PID: 1869 Comm: io_wqe_worker-0 Not tainted 5.11.0-rc3+ #1 Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 RIP: 0010:put_files_struct+0x1b/0x120 Code: 24 18 c7 00 f4 ff ff ff e9 4d fd ff ff 66 90 0f 1f 44 00 00 41 57 41 56 49 89 fe 41 55 41 54 55 53 48 83 ec 08 e8 b5 6b db ff 41 ff 0e 74 13 48 83 c4 08 5b 5d 41 5c 41 5d 41 5e 41 5f e9 9c RSP: 0000:ffffc90002147d48 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffff88810d9a5300 RCX: 0000000000000000 RDX: ffff88810d87c280 RSI: ffffffff8144ba6b RDI: 0000000000000000 RBP: 0000000000000080 R08: 0000000000000001 R09: ffffffff81431500 R10: ffff8881001be000 R11: 0000000000000000 R12: ffff88810ac2f800 R13: ffff88810af38a00 R14: 0000000000000000 R15: ffff8881057130c0 FS: 0000000000000000(0000) GS:ffff88813bc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000010dbaa002 CR4: 00000000003706f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: __io_clean_op+0x10c/0x2a0 io_dismantle_req+0x3c7/0x600 __io_free_req+0x34/0x280 io_put_req+0x63/0xb0 io_worker_handle_work+0x60e/0x830 ? io_wqe_worker+0x135/0x520 io_wqe_worker+0x158/0x520 ? __kthread_parkme+0x96/0xc0 ? io_worker_handle_work+0x830/0x830 kthread+0x134/0x180 ? kthread_create_worker_on_cpu+0x90/0x90 ret_from_fork+0x1f/0x30 Modules linked in: CR2: 0000000000000000 ---[ end trace c358ca86af95b1e7 ]--- I guess case below can trigger above panic: there're two threads which operates different io_uring ctxs and share same sqthread identity, and later one thread exits, io_uring_cancel_task_requests() will clear task->io_uring->identity->files to be NULL in sqpoll mode, then another ctx that uses same identity will panic. Indeed we don't need to clear task->io_uring->identity->files here, io_grab_identity() should handle identity->files changes well, if task->io_uring->identity->files is not equal to current->files, io_cow_identity() should handle this changes well. Cc: stable@vger.kernel.org # 5.5+ Reported-by: Abaci Robot Signed-off-by: Xiaoguang Wang Reviewed-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 38c6cbe1ab387..5d3348d66f068 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -8982,12 +8982,6 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx, if ((ctx->flags & IORING_SETUP_SQPOLL) && ctx->sq_data) { atomic_dec(&task->io_uring->in_idle); - /* - * If the files that are going away are the ones in the thread - * identity, clear them out. - */ - if (task->io_uring->identity->files == files) - task->io_uring->identity->files = NULL; io_sq_thread_unpark(ctx->sq_data); } } -- GitLab From 031b91a5fe6f1ce61b7617614ddde9ed61e252be Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 3 Feb 2021 16:01:06 -0800 Subject: [PATCH 0972/1084] KVM: x86: Set so called 'reserved CR3 bits in LM mask' at vCPU reset Set cr3_lm_rsvd_bits, which is effectively an invalid GPA mask, at vCPU reset. The reserved bits check needs to be done even if userspace never configures the guest's CPUID model. Cc: stable@vger.kernel.org Fixes: 0107973a80ad ("KVM: x86: Introduce cr3_lm_rsvd_bits in kvm_vcpu_arch") Signed-off-by: Sean Christopherson Message-Id: <20210204000117.3303214-2-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c1650e26715b3..1b404e4d7dd8e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10003,6 +10003,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) fx_init(vcpu); vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); + vcpu->arch.cr3_lm_rsvd_bits = rsvd_bits(cpuid_maxphyaddr(vcpu), 63); vcpu->arch.pat = MSR_IA32_CR_PAT_DEFAULT; -- GitLab From 5c279c4cf206e03995e04fd3404fa95ffd243a97 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Thu, 4 Feb 2021 20:12:37 +0200 Subject: [PATCH 0973/1084] Revert "x86/setup: don't remove E820_TYPE_RAM for pfn 0" This reverts commit bde9cfa3afe4324ec251e4af80ebf9b7afaf7afe. Changing the first memory page type from E820_TYPE_RESERVED to E820_TYPE_RAM makes it a part of "System RAM" resource rather than a reserved resource and this in turn causes devmem_is_allowed() to treat is as area that can be accessed but it is filled with zeroes instead of the actual data as previously. The change in /dev/mem output causes lilo to fail as was reported at slakware users forum, and probably other legacy applications will experience similar problems. Link: https://www.linuxquestions.org/questions/slackware-14/slackware-current-lilo-vesa-warnings-after-recent-updates-4175689617/#post6214439 Signed-off-by: Mike Rapoport Cc: stable@kernel.org Signed-off-by: Linus Torvalds --- arch/x86/kernel/setup.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 3412c4595efd8..740f3bdb3f619 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -660,6 +660,17 @@ static void __init trim_platform_memory_ranges(void) static void __init trim_bios_range(void) { + /* + * A special case is the first 4Kb of memory; + * This is a BIOS owned area, not kernel ram, but generally + * not listed as such in the E820 table. + * + * This typically reserves additional memory (64KiB by default) + * since some BIOSes are known to corrupt low memory. See the + * Kconfig help text for X86_RESERVE_LOW. + */ + e820__range_update(0, PAGE_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); + /* * special case: Some BIOSes report the PC BIOS * area (640Kb -> 1Mb) as RAM even though it is not. @@ -717,15 +728,6 @@ early_param("reservelow", parse_reservelow); static void __init trim_low_memory_range(void) { - /* - * A special case is the first 4Kb of memory; - * This is a BIOS owned area, not kernel ram, but generally - * not listed as such in the E820 table. - * - * This typically reserves additional memory (64KiB by default) - * since some BIOSes are known to corrupt low memory. See the - * Kconfig help text for X86_RESERVE_LOW. - */ memblock_reserve(0, ALIGN(reserve_low, PAGE_SIZE)); } -- GitLab From 25a068b8e9a4eb193d755d58efcb3c98928636e0 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 5 Mar 2020 09:47:08 -0800 Subject: [PATCH 0974/1084] x86/apic: Add extra serialization for non-serializing MSRs Jan Kiszka reported that the x2apic_wrmsr_fence() function uses a plain MFENCE while the Intel SDM (10.12.3 MSR Access in x2APIC Mode) calls for MFENCE; LFENCE. Short summary: we have special MSRs that have weaker ordering than all the rest. Add fencing consistent with current SDM recommendations. This is not known to cause any issues in practice, only in theory. Longer story below: The reason the kernel uses a different semantic is that the SDM changed (roughly in late 2017). The SDM changed because folks at Intel were auditing all of the recommended fences in the SDM and realized that the x2apic fences were insufficient. Why was the pain MFENCE judged insufficient? WRMSR itself is normally a serializing instruction. No fences are needed because the instruction itself serializes everything. But, there are explicit exceptions for this serializing behavior written into the WRMSR instruction documentation for two classes of MSRs: IA32_TSC_DEADLINE and the X2APIC MSRs. Back to x2apic: WRMSR is *not* serializing in this specific case. But why is MFENCE insufficient? MFENCE makes writes visible, but only affects load/store instructions. WRMSR is unfortunately not a load/store instruction and is unaffected by MFENCE. This means that a non-serializing WRMSR could be reordered by the CPU to execute before the writes made visible by the MFENCE have even occurred in the first place. This means that an x2apic IPI could theoretically be triggered before there is any (visible) data to process. Does this affect anything in practice? I honestly don't know. It seems quite possible that by the time an interrupt gets to consume the (not yet) MFENCE'd data, it has become visible, mostly by accident. To be safe, add the SDM-recommended fences for all x2apic WRMSRs. This also leaves open the question of the _other_ weakly-ordered WRMSR: MSR_IA32_TSC_DEADLINE. While it has the same ordering architecture as the x2APIC MSRs, it seems substantially less likely to be a problem in practice. While writes to the in-memory Local Vector Table (LVT) might theoretically be reordered with respect to a weakly-ordered WRMSR like TSC_DEADLINE, the SDM has this to say: In x2APIC mode, the WRMSR instruction is used to write to the LVT entry. The processor ensures the ordering of this write and any subsequent WRMSR to the deadline; no fencing is required. But, that might still leave xAPIC exposed. The safest thing to do for now is to add the extra, recommended LFENCE. [ bp: Massage commit message, fix typos, drop accidentally added newline to tools/arch/x86/include/asm/barrier.h. ] Reported-by: Jan Kiszka Signed-off-by: Dave Hansen Signed-off-by: Borislav Petkov Acked-by: Peter Zijlstra (Intel) Acked-by: Thomas Gleixner Cc: Link: https://lkml.kernel.org/r/20200305174708.F77040DD@viggo.jf.intel.com --- arch/x86/include/asm/apic.h | 10 ---------- arch/x86/include/asm/barrier.h | 18 ++++++++++++++++++ arch/x86/kernel/apic/apic.c | 4 ++++ arch/x86/kernel/apic/x2apic_cluster.c | 6 ++++-- arch/x86/kernel/apic/x2apic_phys.c | 9 ++++++--- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 34cb3c159481b..412b51e059c80 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -197,16 +197,6 @@ static inline bool apic_needs_pit(void) { return true; } #endif /* !CONFIG_X86_LOCAL_APIC */ #ifdef CONFIG_X86_X2APIC -/* - * Make previous memory operations globally visible before - * sending the IPI through x2apic wrmsr. We need a serializing instruction or - * mfence for this. - */ -static inline void x2apic_wrmsr_fence(void) -{ - asm volatile("mfence" : : : "memory"); -} - static inline void native_apic_msr_write(u32 reg, u32 v) { if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR || diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h index 7f828fe497978..4819d5e5a3353 100644 --- a/arch/x86/include/asm/barrier.h +++ b/arch/x86/include/asm/barrier.h @@ -84,4 +84,22 @@ do { \ #include +/* + * Make previous memory operations globally visible before + * a WRMSR. + * + * MFENCE makes writes visible, but only affects load/store + * instructions. WRMSR is unfortunately not a load/store + * instruction and is unaffected by MFENCE. The LFENCE ensures + * that the WRMSR is not reordered. + * + * Most WRMSRs are full serializing instructions themselves and + * do not require this barrier. This is only required for the + * IA32_TSC_DEADLINE and X2APIC MSRs. + */ +static inline void weak_wrmsr_fence(void) +{ + asm volatile("mfence; lfence" : : : "memory"); +} + #endif /* _ASM_X86_BARRIER_H */ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 6bd20c0de8bc6..7f4c081f59f0c 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -477,6 +478,9 @@ static int lapic_next_deadline(unsigned long delta, { u64 tsc; + /* This MSR is special and need a special fence: */ + weak_wrmsr_fence(); + tsc = rdtsc(); wrmsrl(MSR_IA32_TSC_DEADLINE, tsc + (((u64) delta) * TSC_DIVISOR)); return 0; diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index df6adc5674c98..f4da9bb69a885 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -29,7 +29,8 @@ static void x2apic_send_IPI(int cpu, int vector) { u32 dest = per_cpu(x86_cpu_to_logical_apicid, cpu); - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); __x2apic_send_IPI_dest(dest, vector, APIC_DEST_LOGICAL); } @@ -41,7 +42,8 @@ __x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest) unsigned long flags; u32 dest; - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); local_irq_save(flags); tmpmsk = this_cpu_cpumask_var_ptr(ipi_mask); diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index 0e4e81971567b..6bde05a86b4ed 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -43,7 +43,8 @@ static void x2apic_send_IPI(int cpu, int vector) { u32 dest = per_cpu(x86_cpu_to_apicid, cpu); - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); __x2apic_send_IPI_dest(dest, vector, APIC_DEST_PHYSICAL); } @@ -54,7 +55,8 @@ __x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest) unsigned long this_cpu; unsigned long flags; - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); local_irq_save(flags); @@ -125,7 +127,8 @@ void __x2apic_send_IPI_shorthand(int vector, u32 which) { unsigned long cfg = __prepare_ICR(which, vector, 0); - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); native_x2apic_icr_write(cfg, 0); } -- GitLab From 8e59cf943fa7402f008de4b444beb0c5280317bc Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 3 Feb 2021 11:21:59 +0800 Subject: [PATCH 0975/1084] ASoC: mediatek: mt8192-mt6359: use asoc_substream_to_rtd() Uses asoc_substream_to_rtd() helper. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210203032201.2882158-2-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index cc0fc72305d22..f5c1c10408c99 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -39,7 +39,7 @@ struct mt8192_mt6359_priv { static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); struct snd_soc_dai *codec_dai; @@ -74,7 +74,7 @@ static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, static int mt8192_rt5682_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); @@ -362,7 +362,7 @@ static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static int mt8192_mt6359_rt1015_rt5682_cap1_startup(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); -- GitLab From 0840706d6c61658e51f42762c5b4f211b7596535 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 3 Feb 2021 11:22:00 +0800 Subject: [PATCH 0976/1084] ASoC: mediatek: mt8192: use asoc_substream_to_rtd() Uses asoc_substream_to_rtd() helper. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210203032201.2882158-3-tzungbi@google.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8192/mt8192-afe-pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c index e7fec2d75e3d4..7a1724f5ff4c6 100644 --- a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c +++ b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c @@ -42,7 +42,7 @@ static const struct snd_pcm_hardware mt8192_afe_hardware = { static int mt8192_memif_fs(struct snd_pcm_substream *substream, unsigned int rate) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); @@ -59,7 +59,7 @@ static int mt8192_get_dai_fs(struct mtk_base_afe *afe, static int mt8192_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); -- GitLab From 4cceb42f4f401463b70d9e69c4771212707c51a8 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 3 Feb 2021 11:22:01 +0800 Subject: [PATCH 0977/1084] ASoC: mediatek: mt8192-mt6359: simplify ops for Capture1 DAI link 1. Uses rtd->dev to get the device. 2. Generalizes the variable name. Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210203032201.2882158-4-tzungbi@google.com Signed-off-by: Mark Brown --- .../mt8192/mt8192-mt6359-rt1015-rt5682.c | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index f5c1c10408c99..f4b09672af8f7 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -360,14 +360,8 @@ static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, } static int -mt8192_mt6359_rt1015_rt5682_cap1_startup(struct snd_pcm_substream *substream) +mt8192_mt6359_cap1_startup(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_component *component = - snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); - struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); - int ret; - static const unsigned int channels[] = { 1, 2, 4 }; @@ -385,13 +379,15 @@ mt8192_mt6359_rt1015_rt5682_cap1_startup(struct snd_pcm_substream *substream) .mask = 0, }; + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_pcm_runtime *runtime = substream->runtime; + int ret; ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &constraints_channels); if (ret < 0) { - dev_err(afe->dev, "hw_constraint_list channels failed\n"); + dev_err(rtd->dev, "hw_constraint_list channels failed\n"); return ret; } @@ -399,15 +395,15 @@ mt8192_mt6359_rt1015_rt5682_cap1_startup(struct snd_pcm_substream *substream) SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); if (ret < 0) { - dev_err(afe->dev, "hw_constraint_list rate failed\n"); + dev_err(rtd->dev, "hw_constraint_list rate failed\n"); return ret; } return 0; } -static const struct snd_soc_ops mt8192_mt6359_rt1015_rt5682_capture1_ops = { - .startup = mt8192_mt6359_rt1015_rt5682_cap1_startup, +static const struct snd_soc_ops mt8192_mt6359_capture1_ops = { + .startup = mt8192_mt6359_cap1_startup, }; /* FE */ @@ -720,7 +716,7 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = { SND_SOC_DPCM_TRIGGER_PRE}, .dynamic = 1, .dpcm_capture = 1, - .ops = &mt8192_mt6359_rt1015_rt5682_capture1_ops, + .ops = &mt8192_mt6359_capture1_ops, SND_SOC_DAILINK_REG(capture1), }, { -- GitLab From 0dd4d3e8c3a8ab63e9368e01d7839afad7b804c7 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 2 Feb 2021 11:20:16 -0800 Subject: [PATCH 0978/1084] ASoC: da7218: Drop CONFIG_OF ifdef This reverts commit a06cd8cf97a3 ("ASoC: da7218: skip of_device_id table when !CONFIG_OF") because we want to make of_match_device() stop using of_match_ptr() internally, confusing compilers and causing ifdef pollution. Reported-by: kernel test robot Cc: Geert Uytterhoeven Acked-by: Arnd Bergmann Cc: Mark Brown Signed-off-by: Stephen Boyd Link: https://lore.kernel.org/r/20210202192016.49028-1-swboyd@chromium.org Signed-off-by: Mark Brown --- sound/soc/codecs/da7218.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index 0e5b91eb420b8..ea426d986d4ca 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -2278,14 +2278,12 @@ static irqreturn_t da7218_irq_thread(int irq, void *data) * DT */ -#ifdef CONFIG_OF static const struct of_device_id da7218_of_match[] = { { .compatible = "dlg,da7217", .data = (void *) DA7217_DEV_ID }, { .compatible = "dlg,da7218", .data = (void *) DA7218_DEV_ID }, { } }; MODULE_DEVICE_TABLE(of, da7218_of_match); -#endif static inline int da7218_of_get_id(struct device *dev) { @@ -3311,7 +3309,7 @@ MODULE_DEVICE_TABLE(i2c, da7218_i2c_id); static struct i2c_driver da7218_i2c_driver = { .driver = { .name = "da7218", - .of_match_table = of_match_ptr(da7218_of_match), + .of_match_table = da7218_of_match, }, .probe = da7218_i2c_probe, .id_table = da7218_i2c_id, -- GitLab From aec18a57edad562d620f7d19016de1fc0cc2208c Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Thu, 4 Feb 2021 19:22:46 +0000 Subject: [PATCH 0979/1084] io_uring: drop mm/files between task_work_submit Since SQPOLL task can be shared and so task_work entries can be a mix of them, we need to drop mm and files before trying to issue next request. Cc: stable@vger.kernel.org # 5.10+ Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index 5d3348d66f068..1f68105a41ed9 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2205,6 +2205,9 @@ static void __io_req_task_submit(struct io_kiocb *req) else __io_req_task_cancel(req, -EFAULT); mutex_unlock(&ctx->uring_lock); + + if (ctx->flags & IORING_SETUP_SQPOLL) + io_sq_thread_drop_mm_files(); } static void io_req_task_submit(struct callback_head *cb) -- GitLab From 315da87c0f99a4741a639782d59dae44878199f5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 3 Feb 2021 16:52:39 +0900 Subject: [PATCH 0980/1084] kbuild: fix duplicated flags in DEBUG_CFLAGS Sedat Dilek noticed duplicated flags in DEBUG_CFLAGS when building deb-pkg with CONFIG_DEBUG_INFO. For example, 'make CC=clang bindeb-pkg' reproduces the issue. Kbuild recurses to the top Makefile for some targets such as package builds. With commit 121c5d08d53c ("kbuild: Only add -fno-var-tracking-assignments for old GCC versions") applied, DEBUG_CFLAGS is now reset only when CONFIG_CC_IS_GCC=y. Fix it to reset DEBUG_CFLAGS all the time. Fixes: 121c5d08d53c ("kbuild: Only add -fno-var-tracking-assignments for old GCC versions") Reported-by: Sedat Dilek Signed-off-by: Masahiro Yamada Tested-by: Sedat Dilek Reviewed-by: Mark Wielaard Reviewed-by: Nathan Chancellor --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 89217e4e68c63..97c781cf042bc 100644 --- a/Makefile +++ b/Makefile @@ -811,10 +811,12 @@ KBUILD_CFLAGS += -ftrivial-auto-var-init=zero KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang endif +DEBUG_CFLAGS := + # Workaround for GCC versions < 5.0 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61801 ifdef CONFIG_CC_IS_GCC -DEBUG_CFLAGS := $(call cc-ifversion, -lt, 0500, $(call cc-option, -fno-var-tracking-assignments)) +DEBUG_CFLAGS += $(call cc-ifversion, -lt, 0500, $(call cc-option, -fno-var-tracking-assignments)) endif ifdef CONFIG_DEBUG_INFO -- GitLab From efe6e3068067212b85c2d0474b5ee3b2d0c7adab Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 4 Feb 2021 16:29:47 +0100 Subject: [PATCH 0981/1084] kallsyms: fix nonconverging kallsyms table with lld ARM randconfig builds with lld sometimes show a build failure from kallsyms: Inconsistent kallsyms data Try make KALLSYMS_EXTRA_PASS=1 as a workaround The problem is the veneers/thunks getting added by the linker extend the symbol table, which in turn leads to more veneers being needed, so it may take a few extra iterations to converge. This bug has been fixed multiple times before, but comes back every time a new symbol name is used. lld uses a different set of identifiers from ld.bfd, so the additional ones need to be added as well. I looked through the sources and found that arm64 and mips define similar prefixes, so I'm adding those as well, aside from the ones I observed. I'm not sure about powerpc64, which seems to already be handled through a section match, but if it comes back, the "__long_branch_" and "__plt_" prefixes would have to get added as well. Signed-off-by: Arnd Bergmann Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 7ecd2ccba531b..54ad86d137849 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -112,6 +112,12 @@ static bool is_ignored_symbol(const char *name, char type) "__crc_", /* modversions */ "__efistub_", /* arm64 EFI stub namespace */ "__kvm_nvhe_", /* arm64 non-VHE KVM namespace */ + "__AArch64ADRPThunk_", /* arm64 lld */ + "__ARMV5PILongThunk_", /* arm lld */ + "__ARMV7PILongThunk_", + "__ThumbV7PILongThunk_", + "__LA25Thunk_", /* mips lld */ + "__microLA25Thunk_", NULL }; -- GitLab From 0e5a3c8284a30f4c43fd81d7285528ece74563b5 Mon Sep 17 00:00:00 2001 From: Gary Bisson Date: Mon, 25 Jan 2021 17:19:34 +0100 Subject: [PATCH 0982/1084] usb: dwc3: fix clock issue during resume in OTG mode Commit fe8abf332b8f ("usb: dwc3: support clocks and resets for DWC3 core") introduced clock support and a new function named dwc3_core_init_for_resume() which enables the clock before calling dwc3_core_init() during resume as clocks get disabled during suspend. Unfortunately in this commit the DWC3_GCTL_PRTCAP_OTG case was forgotten and therefore during resume, a platform could call dwc3_core_init() without re-enabling the clocks first, preventing to resume properly. So update the resume path to call dwc3_core_init_for_resume() as it should. Fixes: fe8abf332b8f ("usb: dwc3: support clocks and resets for DWC3 core") Cc: stable@vger.kernel.org Signed-off-by: Gary Bisson Link: https://lore.kernel.org/r/20210125161934.527820-1-gary.bisson@boundarydevices.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 841daec70b6ef..3101f0dcf6ae8 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1758,7 +1758,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) if (PMSG_IS_AUTO(msg)) break; - ret = dwc3_core_init(dwc); + ret = dwc3_core_init_for_resume(dwc); if (ret) return ret; -- GitLab From f670e9f9c8cac716c3506c6bac9e997b27ad441a Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 27 Jan 2021 11:39:19 +0100 Subject: [PATCH 0983/1084] usb: dwc2: Fix endpoint direction check in ep_from_windex dwc2_hsotg_process_req_status uses ep_from_windex() to retrieve the endpoint for the index provided in the wIndex request param. In a test-case with a rndis gadget running and sending a malformed packet to it like: dev.ctrl_transfer( 0x82, # bmRequestType 0x00, # bRequest 0x0000, # wValue 0x0001, # wIndex 0x00 # wLength ) it is possible to cause a crash: [ 217.533022] dwc2 ff300000.usb: dwc2_hsotg_process_req_status: USB_REQ_GET_STATUS [ 217.559003] Unable to handle kernel read from unreadable memory at virtual address 0000000000000088 ... [ 218.313189] Call trace: [ 218.330217] ep_from_windex+0x3c/0x54 [ 218.348565] usb_gadget_giveback_request+0x10/0x20 [ 218.368056] dwc2_hsotg_complete_request+0x144/0x184 This happens because ep_from_windex wants to compare the endpoint direction even if index_to_ep() didn't return an endpoint due to the direction not matching. The fix is easy insofar that the actual direction check is already happening when calling index_to_ep() which will return NULL if there is no endpoint for the targeted direction, so the offending check can go away completely. Fixes: c6f5c050e2a7 ("usb: dwc2: gadget: add bi-directional endpoint support") Cc: stable@vger.kernel.org Reported-by: Gerhard Klostermeier Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20210127103919.58215-1-heiko@sntech.de Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc2/gadget.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 0a0d11151cfb8..ad4c94366dadf 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1543,7 +1543,6 @@ static void dwc2_hsotg_complete_oursetup(struct usb_ep *ep, static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, u32 windex) { - struct dwc2_hsotg_ep *ep; int dir = (windex & USB_DIR_IN) ? 1 : 0; int idx = windex & 0x7F; @@ -1553,12 +1552,7 @@ static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, if (idx > hsotg->num_of_eps) return NULL; - ep = index_to_ep(hsotg, idx, dir); - - if (idx && ep->dir_in != dir) - return NULL; - - return ep; + return index_to_ep(hsotg, idx, dir); } /** -- GitLab From 9c698bff66ab4914bb3d71da7dc6112519bde23e Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 29 Jan 2021 10:19:07 +0000 Subject: [PATCH 0984/1084] ARM: ensure the signal page contains defined contents Ensure that the signal page contains our poison instruction to increase the protection against ROP attacks and also contains well defined contents. Acked-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/signal.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 9d2e916121be4..a3a38d0a4c853 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -693,18 +693,20 @@ struct page *get_signal_page(void) addr = page_address(page); + /* Poison the entire page */ + memset32(addr, __opcode_to_mem_arm(0xe7fddef1), + PAGE_SIZE / sizeof(u32)); + /* Give the signal return code some randomness */ offset = 0x200 + (get_random_int() & 0x7fc); signal_return_offset = offset; - /* - * Copy signal return handlers into the vector page, and - * set sigreturn to be a pointer to these. - */ + /* Copy signal return handlers into the page */ memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes)); - ptr = (unsigned long)addr + offset; - flush_icache_range(ptr, ptr + sizeof(sigreturn_codes)); + /* Flush out all instructions in this page */ + ptr = (unsigned long)addr; + flush_icache_range(ptr, ptr + PAGE_SIZE); return page; } -- GitLab From 4d62e81b60d4025e2dfcd5ea531cc1394ce9226f Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 1 Feb 2021 19:40:01 +0000 Subject: [PATCH 0985/1084] ARM: kexec: fix oops after TLB are invalidated Giancarlo Ferrari reports the following oops while trying to use kexec: Unable to handle kernel paging request at virtual address 80112f38 pgd = fd7ef03e [80112f38] *pgd=0001141e(bad) Internal error: Oops: 80d [#1] PREEMPT SMP ARM ... This is caused by machine_kexec() trying to set the kernel text to be read/write, so it can poke values into the relocation code before copying it - and an interrupt occuring which changes the page tables. The subsequent writes then hit read-only sections that trigger a data abort resulting in the above oops. Fix this by copying the relocation code, and then writing the variables into the destination, thereby avoiding the need to make the kernel text read/write. Reported-by: Giancarlo Ferrari Tested-by: Giancarlo Ferrari Signed-off-by: Russell King --- arch/arm/include/asm/kexec-internal.h | 12 +++++++++ arch/arm/kernel/asm-offsets.c | 5 ++++ arch/arm/kernel/machine_kexec.c | 20 ++++++-------- arch/arm/kernel/relocate_kernel.S | 38 ++++++++------------------- 4 files changed, 36 insertions(+), 39 deletions(-) create mode 100644 arch/arm/include/asm/kexec-internal.h diff --git a/arch/arm/include/asm/kexec-internal.h b/arch/arm/include/asm/kexec-internal.h new file mode 100644 index 0000000000000..ecc2322db7aa1 --- /dev/null +++ b/arch/arm/include/asm/kexec-internal.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ARM_KEXEC_INTERNAL_H +#define _ARM_KEXEC_INTERNAL_H + +struct kexec_relocate_data { + unsigned long kexec_start_address; + unsigned long kexec_indirection_page; + unsigned long kexec_mach_type; + unsigned long kexec_r2; +}; + +#endif diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index a1570c8bab25a..be8050b0c3dfb 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -170,5 +171,9 @@ int main(void) DEFINE(MPU_RGN_PRBAR, offsetof(struct mpu_rgn, prbar)); DEFINE(MPU_RGN_PRLAR, offsetof(struct mpu_rgn, prlar)); #endif + DEFINE(KEXEC_START_ADDR, offsetof(struct kexec_relocate_data, kexec_start_address)); + DEFINE(KEXEC_INDIR_PAGE, offsetof(struct kexec_relocate_data, kexec_indirection_page)); + DEFINE(KEXEC_MACH_TYPE, offsetof(struct kexec_relocate_data, kexec_mach_type)); + DEFINE(KEXEC_R2, offsetof(struct kexec_relocate_data, kexec_r2)); return 0; } diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 5d84ad333f050..2b09dad7935eb 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -22,11 +23,6 @@ extern void relocate_new_kernel(void); extern const unsigned int relocate_new_kernel_size; -extern unsigned long kexec_start_address; -extern unsigned long kexec_indirection_page; -extern unsigned long kexec_mach_type; -extern unsigned long kexec_boot_atags; - static atomic_t waiting_for_crash_ipi; /* @@ -159,6 +155,7 @@ void (*kexec_reinit)(void); void machine_kexec(struct kimage *image) { unsigned long page_list, reboot_entry_phys; + struct kexec_relocate_data *data; void (*reboot_entry)(void); void *reboot_code_buffer; @@ -174,18 +171,17 @@ void machine_kexec(struct kimage *image) reboot_code_buffer = page_address(image->control_code_page); - /* Prepare parameters for reboot_code_buffer*/ - set_kernel_text_rw(); - kexec_start_address = image->start; - kexec_indirection_page = page_list; - kexec_mach_type = machine_arch_type; - kexec_boot_atags = image->arch.kernel_r2; - /* copy our kernel relocation code to the control code page */ reboot_entry = fncpy(reboot_code_buffer, &relocate_new_kernel, relocate_new_kernel_size); + data = reboot_code_buffer + relocate_new_kernel_size; + data->kexec_start_address = image->start; + data->kexec_indirection_page = page_list; + data->kexec_mach_type = machine_arch_type; + data->kexec_r2 = image->arch.kernel_r2; + /* get the identity mapping physical address for the reboot code */ reboot_entry_phys = virt_to_idmap(reboot_entry); diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index 72a08786e16eb..218d524360fcd 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S @@ -5,14 +5,16 @@ #include #include +#include #include .align 3 /* not needed for this code, but keeps fncpy() happy */ ENTRY(relocate_new_kernel) - ldr r0,kexec_indirection_page - ldr r1,kexec_start_address + adr r7, relocate_new_kernel_end + ldr r0, [r7, #KEXEC_INDIR_PAGE] + ldr r1, [r7, #KEXEC_START_ADDR] /* * If there is no indirection page (we are doing crashdumps) @@ -57,34 +59,16 @@ ENTRY(relocate_new_kernel) 2: /* Jump to relocated kernel */ - mov lr,r1 - mov r0,#0 - ldr r1,kexec_mach_type - ldr r2,kexec_boot_atags - ARM( ret lr ) - THUMB( bx lr ) - - .align - - .globl kexec_start_address -kexec_start_address: - .long 0x0 - - .globl kexec_indirection_page -kexec_indirection_page: - .long 0x0 - - .globl kexec_mach_type -kexec_mach_type: - .long 0x0 - - /* phy addr of the atags for the new kernel */ - .globl kexec_boot_atags -kexec_boot_atags: - .long 0x0 + mov lr, r1 + mov r0, #0 + ldr r1, [r7, #KEXEC_MACH_TYPE] + ldr r2, [r7, #KEXEC_R2] + ARM( ret lr ) + THUMB( bx lr ) ENDPROC(relocate_new_kernel) + .align 3 relocate_new_kernel_end: .globl relocate_new_kernel_size -- GitLab From 9f5f8ec50165630cfc49897410b30997d4d677b5 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Sat, 6 Feb 2021 00:33:24 +1300 Subject: [PATCH 0986/1084] dma-mapping: benchmark: use u8 for reserved field in uAPI structure The original code put five u32 before a u64 expansion[10] array. Five is odd, this will cause trouble in the extension of the structure by adding new features. This patch moves to use u8 for reserved field to avoid future alignment risk. Meanwhile, it also clears the memory of struct map_benchmark in tools, otherwise, if users use old version to run on newer kernel, the random expansion value will cause side effect on newer kernel. Signed-off-by: Barry Song Signed-off-by: Christoph Hellwig --- kernel/dma/map_benchmark.c | 2 +- tools/testing/selftests/dma/dma_map_benchmark.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c index 1b1b8ff875cb3..da95df3814833 100644 --- a/kernel/dma/map_benchmark.c +++ b/kernel/dma/map_benchmark.c @@ -36,7 +36,7 @@ struct map_benchmark { __s32 node; /* which numa node this benchmark will run on */ __u32 dma_bits; /* DMA addressing capability */ __u32 dma_dir; /* DMA data direction */ - __u64 expansion[10]; /* For future use */ + __u8 expansion[84]; /* For future use */ }; struct map_benchmark_data { diff --git a/tools/testing/selftests/dma/dma_map_benchmark.c b/tools/testing/selftests/dma/dma_map_benchmark.c index 7065163a83880..537d65968c48b 100644 --- a/tools/testing/selftests/dma/dma_map_benchmark.c +++ b/tools/testing/selftests/dma/dma_map_benchmark.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -35,7 +36,7 @@ struct map_benchmark { __s32 node; /* which numa node this benchmark will run on */ __u32 dma_bits; /* DMA addressing capability */ __u32 dma_dir; /* DMA data direction */ - __u64 expansion[10]; /* For future use */ + __u8 expansion[84]; /* For future use */ }; int main(int argc, char **argv) @@ -102,6 +103,7 @@ int main(int argc, char **argv) exit(1); } + memset(&map, 0, sizeof(map)); map.seconds = seconds; map.threads = threads; map.node = node; -- GitLab From f12bbc50f3b14c9b8ed902c6d1da980dd5addcce Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 4 Feb 2021 14:33:00 -0600 Subject: [PATCH 0987/1084] ASoC: Intel: sof_sdw: add missing TGL_HDMI quirk for Dell SKU 0A5E We missed adding the TGL_HDMI quirk which is very much needed to expose the 4 display pipelines and will be required on TGL topologies. Fixes: 9ad9bc59dde10 ('ASoC: Intel: sof_sdw: set proper flags for Dell TGL-H SKU 0A5E') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210204203312.27112-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 6d0d6ef711e0f..29b6bba3d4257 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -73,7 +73,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") }, - .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | SOF_RT715_DAI_ID_FIX | SOF_SDW_FOUR_SPK), }, -- GitLab From 45c92ec32b43c6cb42341ebf07577eefed9d87ec Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 4 Feb 2021 14:33:01 -0600 Subject: [PATCH 0988/1084] ASoC: Intel: sof_sdw: add missing TGL_HDMI quirk for Dell SKU 0A32 We missed adding the TGL_HDMI quirk which is very much needed to expose the 4 display pipelines and will be required on TGL topologies. Fixes: 488cdbd8931fe ('ASoC: Intel: sof_sdw: add quirk for new TigerLake-SDCA device') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210204203312.27112-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 29b6bba3d4257..afdc336ec9bf5 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -54,7 +54,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") }, - .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | SOF_RT715_DAI_ID_FIX | SOF_SDW_FOUR_SPK), }, -- GitLab From 5ab3ff4d66960be766a544886667e7c002f17fd6 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 4 Feb 2021 14:32:59 -0600 Subject: [PATCH 0989/1084] ASoC: Intel: sof_sdw: add missing TGL_HDMI quirk for Dell SKU 0A3E We missed adding the TGL_HDMI quirk which is very much needed to expose the 4 display pipelines and will be required on TGL topologies. Fixes: e787f5b5b1406 ('ASoC: Intel: add support for new SoundWire hardware layout on TGL') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210204203312.27112-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index afdc336ec9bf5..152ea166eeaef 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -65,7 +65,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") }, - .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | SOF_RT715_DAI_ID_FIX), }, { -- GitLab From 737ee8bdf682cedb3c42b713d20ffa5c899591fb Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 4 Feb 2021 14:17:36 -0600 Subject: [PATCH 0990/1084] ASoC: rt700-sdw: use cancel_work_sync() in .remove as well as .suspend Make sure the workqueues are not running after the .remove() callback, which can lead to timeout errors. A previous fix to use cancel_work_sync was applied for the suspend case but the remove case is missing Fixes: 5f2df2a4583b ('ASoC: rt700: wait for the delayed work to finish when the system suspends') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Rander Wang Link: https://lore.kernel.org/r/20210204201739.25206-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt700-sdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c index fb77e77a4ebd5..45488325b6359 100644 --- a/sound/soc/codecs/rt700-sdw.c +++ b/sound/soc/codecs/rt700-sdw.c @@ -462,8 +462,8 @@ static int rt700_sdw_remove(struct sdw_slave *slave) struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); if (rt700 && rt700->hw_init) { - cancel_delayed_work(&rt700->jack_detect_work); - cancel_delayed_work(&rt700->jack_btn_check_work); + cancel_delayed_work_sync(&rt700->jack_detect_work); + cancel_delayed_work_sync(&rt700->jack_btn_check_work); } return 0; -- GitLab From 121871a75ae4032cf5e506ba5159761805709def Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 4 Feb 2021 14:17:37 -0600 Subject: [PATCH 0991/1084] ASoC: rt711-sdw: use cancel_work_sync() for .remove Make sure the workqueues are not running after the .remove() callback, which can lead to timeout errors. A previous fix to use cancel_work_sync was applied for the suspend case but the remove case is missing Fixes: 501ef013390b ('ASoC: rt711: wait for the delayed work to finish when the system suspends') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Rander Wang Link: https://lore.kernel.org/r/20210204201739.25206-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt711-sdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index fc7df79c3b918..308e625648412 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -463,8 +463,8 @@ static int rt711_sdw_remove(struct sdw_slave *slave) struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev); if (rt711 && rt711->hw_init) { - cancel_delayed_work(&rt711->jack_detect_work); - cancel_delayed_work(&rt711->jack_btn_check_work); + cancel_delayed_work_sync(&rt711->jack_detect_work); + cancel_delayed_work_sync(&rt711->jack_btn_check_work); cancel_work_sync(&rt711->calibration_work); } -- GitLab From c792c3690b82c8d26c01494a51ebf66d9cae7e72 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 4 Feb 2021 14:17:38 -0600 Subject: [PATCH 0992/1084] ASoC: rt5682-sdw: cancel_work_sync() in .remove and .suspend Follow pattern from other drivers and use cancel_work_sync() for both .remove() and .suspend(). Fixes: 03f6fc6de919 ('ASoC: rt5682: Add the soundwire support') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Rander Wang Link: https://lore.kernel.org/r/20210204201739.25206-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682-sdw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index 4d707e854875b..35c9d2be9eeb3 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -703,7 +703,7 @@ static int rt5682_sdw_remove(struct sdw_slave *slave) struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); if (rt5682 && rt5682->hw_init) - cancel_delayed_work(&rt5682->jack_detect_work); + cancel_delayed_work_sync(&rt5682->jack_detect_work); return 0; } @@ -721,6 +721,8 @@ static int __maybe_unused rt5682_dev_suspend(struct device *dev) if (!rt5682->hw_init) return 0; + cancel_delayed_work_sync(&rt5682->jack_detect_work); + regcache_cache_only(rt5682->regmap, true); regcache_mark_dirty(rt5682->regmap); -- GitLab From 30fd8f65af78d0ac0859cf436beed14834b39802 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 4 Feb 2021 14:17:39 -0600 Subject: [PATCH 0993/1084] ASoC: rt5682: do nothing in rt5682_suspend/resume in sdw mode regcache sync will be done in sdw device suspend/resume functions. And we have different jack detection mechanism for SoundWire. Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210204201739.25206-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 4d865edadd7eb..fde5c4945e179 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -2906,6 +2906,9 @@ static int rt5682_suspend(struct snd_soc_component *component) { struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); + if (rt5682->is_sdw) + return 0; + regcache_cache_only(rt5682->regmap, true); regcache_mark_dirty(rt5682->regmap); return 0; @@ -2915,6 +2918,9 @@ static int rt5682_resume(struct snd_soc_component *component) { struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); + if (rt5682->is_sdw) + return 0; + regcache_cache_only(rt5682->regmap, false); regcache_sync(rt5682->regmap); -- GitLab From 91792bb8089b63b7b780251eb83939348ac58a64 Mon Sep 17 00:00:00 2001 From: Pavel Shilovsky Date: Tue, 2 Feb 2021 22:34:32 -0600 Subject: [PATCH 0994/1084] smb3: fix crediting for compounding when only one request in flight Currently we try to guess if a compound request is going to succeed waiting for credits or not based on the number of requests in flight. This approach doesn't work correctly all the time because there may be only one request in flight which is going to bring multiple credits satisfying the compound request. Change the behavior to fail a request only if there are no requests in flight at all and proceed waiting for credits otherwise. Cc: # 5.1+ Signed-off-by: Pavel Shilovsky Reviewed-by: Tom Talpey Reviewed-by: Shyam Prasad N Signed-off-by: Steve French --- fs/cifs/transport.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 95ef26b555b91..4a2b836eb0177 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -666,10 +666,22 @@ wait_for_compound_request(struct TCP_Server_Info *server, int num, if (*credits < num) { /* - * Return immediately if not too many requests in flight since - * we will likely be stuck on waiting for credits. + * If the server is tight on resources or just gives us less + * credits for other reasons (e.g. requests are coming out of + * order and the server delays granting more credits until it + * processes a missing mid) and we exhausted most available + * credits there may be situations when we try to send + * a compound request but we don't have enough credits. At this + * point the client needs to decide if it should wait for + * additional credits or fail the request. If at least one + * request is in flight there is a high probability that the + * server will return enough credits to satisfy this compound + * request. + * + * Return immediately if no requests in flight since we will be + * stuck on waiting for credits. */ - if (server->in_flight < num - *credits) { + if (server->in_flight == 0) { spin_unlock(&server->req_lock); trace_smb3_insufficient_credits(server->CurrentMid, server->hostname, scredits, sin_flight); -- GitLab From df91785a22e2505d2ac668f1d3e6b6e6d8ba627a Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Fri, 5 Feb 2021 11:44:03 +0100 Subject: [PATCH 0995/1084] ASoC: dt-bindings: add mclk provider support to stm32 i2s Add master clock provider support to STM32 I2S. Reviewed-by: Rob Herring Signed-off-by: Olivier Moysan Link: https://lore.kernel.org/r/20210205104404.18786-2-olivier.moysan@foss.st.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml b/Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml index f32410890589f..6feb5a09c184e 100644 --- a/Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml @@ -54,6 +54,10 @@ properties: resets: maxItems: 1 + "#clock-cells": + description: Configure the I2S device as MCLK clock provider. + const: 0 + required: - compatible - "#sound-dai-cells" -- GitLab From 8a262e614ef8675cfde924c6ddf873a95db0be6a Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Fri, 5 Feb 2021 11:44:04 +0100 Subject: [PATCH 0996/1084] ASoC: stm32: i2s: add master clock provider Add master clock generation support in STM32 I2S driver. The master clock provided by I2S can be used to feed a codec. Signed-off-by: Olivier Moysan Link: https://lore.kernel.org/r/20210205104404.18786-3-olivier.moysan@foss.st.com Signed-off-by: Mark Brown --- sound/soc/stm/stm32_i2s.c | 310 ++++++++++++++++++++++++++++++++------ 1 file changed, 266 insertions(+), 44 deletions(-) diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 7c4d63c33f15b..7d1672cf78cc5 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -196,6 +197,9 @@ enum i2s_datlen { #define STM32_I2S_IS_MASTER(x) ((x)->ms_flg == I2S_MS_MASTER) #define STM32_I2S_IS_SLAVE(x) ((x)->ms_flg == I2S_MS_SLAVE) +#define STM32_I2S_NAME_LEN 32 +#define STM32_I2S_RATE_11K 11025 + /** * struct stm32_i2s_data - private data of I2S * @regmap_conf: I2S register map configuration pointer @@ -206,6 +210,7 @@ enum i2s_datlen { * @dma_data_rx: dma configuration data for tx channel * @substream: PCM substream data pointer * @i2sclk: kernel clock feeding the I2S clock generator + * @i2smclk: master clock from I2S mclk provider * @pclk: peripheral clock driving bus interface * @x8kclk: I2S parent clock for sampling frequencies multiple of 8kHz * @x11kclk: I2S parent clock for sampling frequencies multiple of 11kHz @@ -215,6 +220,9 @@ enum i2s_datlen { * @irq_lock: prevent race condition with IRQ * @mclk_rate: master clock frequency (Hz) * @fmt: DAI protocol + * @divider: prescaler division ratio + * @div: prescaler div field + * @odd: prescaler odd field * @refcount: keep count of opened streams on I2S * @ms_flg: master mode flag. */ @@ -227,6 +235,7 @@ struct stm32_i2s_data { struct snd_dmaengine_dai_dma_data dma_data_rx; struct snd_pcm_substream *substream; struct clk *i2sclk; + struct clk *i2smclk; struct clk *pclk; struct clk *x8kclk; struct clk *x11kclk; @@ -236,10 +245,210 @@ struct stm32_i2s_data { spinlock_t irq_lock; /* used to prevent race condition with IRQ */ unsigned int mclk_rate; unsigned int fmt; + unsigned int divider; + unsigned int div; + bool odd; int refcount; int ms_flg; }; +struct stm32_i2smclk_data { + struct clk_hw hw; + unsigned long freq; + struct stm32_i2s_data *i2s_data; +}; + +#define to_mclk_data(_hw) container_of(_hw, struct stm32_i2smclk_data, hw) + +static int stm32_i2s_calc_clk_div(struct stm32_i2s_data *i2s, + unsigned long input_rate, + unsigned long output_rate) +{ + unsigned int ratio, div, divider = 1; + bool odd; + + ratio = DIV_ROUND_CLOSEST(input_rate, output_rate); + + /* Check the parity of the divider */ + odd = ratio & 0x1; + + /* Compute the div prescaler */ + div = ratio >> 1; + + /* If div is 0 actual divider is 1 */ + if (div) { + divider = ((2 * div) + odd); + dev_dbg(&i2s->pdev->dev, "Divider: 2*%d(div)+%d(odd) = %d\n", + div, odd, divider); + } + + /* Division by three is not allowed by I2S prescaler */ + if ((div == 1 && odd) || div > I2S_CGFR_I2SDIV_MAX) { + dev_err(&i2s->pdev->dev, "Wrong divider setting\n"); + return -EINVAL; + } + + if (input_rate % divider) + dev_dbg(&i2s->pdev->dev, + "Rate not accurate. requested (%ld), actual (%ld)\n", + output_rate, input_rate / divider); + + i2s->div = div; + i2s->odd = odd; + i2s->divider = divider; + + return 0; +} + +static int stm32_i2s_set_clk_div(struct stm32_i2s_data *i2s) +{ + u32 cgfr, cgfr_mask; + + cgfr = I2S_CGFR_I2SDIV_SET(i2s->div) | (i2s->odd << I2S_CGFR_ODD_SHIFT); + cgfr_mask = I2S_CGFR_I2SDIV_MASK | I2S_CGFR_ODD; + + return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, + cgfr_mask, cgfr); +} + +static int stm32_i2s_set_parent_clock(struct stm32_i2s_data *i2s, + unsigned int rate) +{ + struct platform_device *pdev = i2s->pdev; + struct clk *parent_clk; + int ret; + + if (!(rate % STM32_I2S_RATE_11K)) + parent_clk = i2s->x11kclk; + else + parent_clk = i2s->x8kclk; + + ret = clk_set_parent(i2s->i2sclk, parent_clk); + if (ret) + dev_err(&pdev->dev, + "Error %d setting i2sclk parent clock\n", ret); + + return ret; +} + +static long stm32_i2smclk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct stm32_i2smclk_data *mclk = to_mclk_data(hw); + struct stm32_i2s_data *i2s = mclk->i2s_data; + int ret; + + ret = stm32_i2s_calc_clk_div(i2s, *prate, rate); + if (ret) + return ret; + + mclk->freq = *prate / i2s->divider; + + return mclk->freq; +} + +static unsigned long stm32_i2smclk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct stm32_i2smclk_data *mclk = to_mclk_data(hw); + + return mclk->freq; +} + +static int stm32_i2smclk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct stm32_i2smclk_data *mclk = to_mclk_data(hw); + struct stm32_i2s_data *i2s = mclk->i2s_data; + int ret; + + ret = stm32_i2s_calc_clk_div(i2s, parent_rate, rate); + if (ret) + return ret; + + ret = stm32_i2s_set_clk_div(i2s); + if (ret) + return ret; + + mclk->freq = rate; + + return 0; +} + +static int stm32_i2smclk_enable(struct clk_hw *hw) +{ + struct stm32_i2smclk_data *mclk = to_mclk_data(hw); + struct stm32_i2s_data *i2s = mclk->i2s_data; + + dev_dbg(&i2s->pdev->dev, "Enable master clock\n"); + + return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, + I2S_CGFR_MCKOE, I2S_CGFR_MCKOE); +} + +static void stm32_i2smclk_disable(struct clk_hw *hw) +{ + struct stm32_i2smclk_data *mclk = to_mclk_data(hw); + struct stm32_i2s_data *i2s = mclk->i2s_data; + + dev_dbg(&i2s->pdev->dev, "Disable master clock\n"); + + regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, I2S_CGFR_MCKOE, 0); +} + +static const struct clk_ops mclk_ops = { + .enable = stm32_i2smclk_enable, + .disable = stm32_i2smclk_disable, + .recalc_rate = stm32_i2smclk_recalc_rate, + .round_rate = stm32_i2smclk_round_rate, + .set_rate = stm32_i2smclk_set_rate, +}; + +static int stm32_i2s_add_mclk_provider(struct stm32_i2s_data *i2s) +{ + struct clk_hw *hw; + struct stm32_i2smclk_data *mclk; + struct device *dev = &i2s->pdev->dev; + const char *pname = __clk_get_name(i2s->i2sclk); + char *mclk_name, *p, *s = (char *)pname; + int ret, i = 0; + + mclk = devm_kzalloc(dev, sizeof(*mclk), GFP_KERNEL); + if (!mclk) + return -ENOMEM; + + mclk_name = devm_kcalloc(dev, sizeof(char), + STM32_I2S_NAME_LEN, GFP_KERNEL); + if (!mclk_name) + return -ENOMEM; + + /* + * Forge mclk clock name from parent clock name and suffix. + * String after "_" char is stripped in parent name. + */ + p = mclk_name; + while (*s && *s != '_' && (i < (STM32_I2S_NAME_LEN - 7))) { + *p++ = *s++; + i++; + } + strcat(p, "_mclk"); + + mclk->hw.init = CLK_HW_INIT(mclk_name, pname, &mclk_ops, 0); + mclk->i2s_data = i2s; + hw = &mclk->hw; + + dev_dbg(dev, "Register master clock %s\n", mclk_name); + ret = devm_clk_hw_register(&i2s->pdev->dev, hw); + if (ret) { + dev_err(dev, "mclk register fails with error %d\n", ret); + return ret; + } + i2s->i2smclk = hw->clk; + + /* register mclk provider */ + return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw); +} + static irqreturn_t stm32_i2s_isr(int irq, void *devid) { struct stm32_i2s_data *i2s = (struct stm32_i2s_data *)devid; @@ -405,18 +614,46 @@ static int stm32_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); + int ret = 0; - dev_dbg(cpu_dai->dev, "I2S MCLK frequency is %uHz\n", freq); + dev_dbg(cpu_dai->dev, "I2S MCLK frequency is %uHz. mode: %s, dir: %s\n", + freq, STM32_I2S_IS_MASTER(i2s) ? "master" : "slave", + dir ? "output" : "input"); - if ((dir == SND_SOC_CLOCK_OUT) && STM32_I2S_IS_MASTER(i2s)) { - i2s->mclk_rate = freq; + /* MCLK generation is available only in master mode */ + if (dir == SND_SOC_CLOCK_OUT && STM32_I2S_IS_MASTER(i2s)) { + if (!i2s->i2smclk) { + dev_dbg(cpu_dai->dev, "No MCLK registered\n"); + return 0; + } - /* Enable master clock if master mode and mclk-fs are set */ - return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, - I2S_CGFR_MCKOE, I2S_CGFR_MCKOE); + /* Assume shutdown if requested frequency is 0Hz */ + if (!freq) { + /* Release mclk rate only if rate was actually set */ + if (i2s->mclk_rate) { + clk_rate_exclusive_put(i2s->i2smclk); + i2s->mclk_rate = 0; + } + return regmap_update_bits(i2s->regmap, + STM32_I2S_CGFR_REG, + I2S_CGFR_MCKOE, 0); + } + /* If master clock is used, set parent clock now */ + ret = stm32_i2s_set_parent_clock(i2s, freq); + if (ret) + return ret; + ret = clk_set_rate_exclusive(i2s->i2smclk, freq); + if (ret) { + dev_err(cpu_dai->dev, "Could not set mclk rate\n"); + return ret; + } + ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, + I2S_CGFR_MCKOE, I2S_CGFR_MCKOE); + if (!ret) + i2s->mclk_rate = freq; } - return 0; + return ret; } static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai, @@ -424,11 +661,10 @@ static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai, { struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); unsigned long i2s_clock_rate; - unsigned int tmp, div, real_div, nb_bits, frame_len; + unsigned int nb_bits, frame_len; unsigned int rate = params_rate(params); + u32 cgfr; int ret; - u32 cgfr, cgfr_mask; - bool odd; if (!(rate % 11025)) clk_set_parent(i2s->i2sclk, i2s->x11kclk); @@ -449,7 +685,10 @@ static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai, * dsp mode : div = i2s_clk / (nb_bits x ws) */ if (i2s->mclk_rate) { - tmp = DIV_ROUND_CLOSEST(i2s_clock_rate, i2s->mclk_rate); + ret = stm32_i2s_calc_clk_div(i2s, i2s_clock_rate, + i2s->mclk_rate); + if (ret) + return ret; } else { frame_len = 32; if ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == @@ -462,34 +701,13 @@ static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai, return ret; nb_bits = frame_len * ((cgfr & I2S_CGFR_CHLEN) + 1); - tmp = DIV_ROUND_CLOSEST(i2s_clock_rate, (nb_bits * rate)); - } - - /* Check the parity of the divider */ - odd = tmp & 0x1; - - /* Compute the div prescaler */ - div = tmp >> 1; - - cgfr = I2S_CGFR_I2SDIV_SET(div) | (odd << I2S_CGFR_ODD_SHIFT); - cgfr_mask = I2S_CGFR_I2SDIV_MASK | I2S_CGFR_ODD; - - real_div = ((2 * div) + odd); - dev_dbg(cpu_dai->dev, "I2S clk: %ld, SCLK: %d\n", - i2s_clock_rate, rate); - dev_dbg(cpu_dai->dev, "Divider: 2*%d(div)+%d(odd) = %d\n", - div, odd, real_div); - - if (((div == 1) && odd) || (div > I2S_CGFR_I2SDIV_MAX)) { - dev_err(cpu_dai->dev, "Wrong divider setting\n"); - return -EINVAL; + ret = stm32_i2s_calc_clk_div(i2s, i2s_clock_rate, + (nb_bits * rate)); + if (ret) + return ret; } - if (!div && !odd) - dev_warn(cpu_dai->dev, "real divider forced to 1\n"); - - ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, - cgfr_mask, cgfr); + ret = stm32_i2s_set_clk_div(i2s); if (ret < 0) return ret; @@ -694,9 +912,6 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream, struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); unsigned long flags; - regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, - I2S_CGFR_MCKOE, (unsigned int)~I2S_CGFR_MCKOE); - clk_disable_unprepare(i2s->i2sclk); spin_lock_irqsave(&i2s->irq_lock, flags); @@ -861,6 +1076,13 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev, return PTR_ERR(i2s->x11kclk); } + /* Register mclk provider if requested */ + if (of_find_property(np, "#clock-cells", NULL)) { + ret = stm32_i2s_add_mclk_provider(i2s); + if (ret < 0) + return ret; + } + /* Get irqs */ irq = platform_get_irq(pdev, 0); if (irq < 0) @@ -906,16 +1128,16 @@ static int stm32_i2s_probe(struct platform_device *pdev) if (!i2s) return -ENOMEM; - ret = stm32_i2s_parse_dt(pdev, i2s); - if (ret) - return ret; - i2s->pdev = pdev; i2s->ms_flg = I2S_MS_NOT_SET; spin_lock_init(&i2s->lock_fd); spin_lock_init(&i2s->irq_lock); platform_set_drvdata(pdev, i2s); + ret = stm32_i2s_parse_dt(pdev, i2s); + if (ret) + return ret; + ret = stm32_i2s_dais_init(pdev, i2s); if (ret) return ret; -- GitLab From 19657a609b68f37afede259a762765b77914557f Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Fri, 5 Feb 2021 16:16:52 +0800 Subject: [PATCH 0997/1084] ASoC: mediatek: mt8183-mt6358: set playback and capture constraints Sets playback and capture constraints to S16_LE, stereo, 48kHz. Signed-off-by: Jiaxin Yu Link: https://lore.kernel.org/r/1612513012-27688-1-git-send-email-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- .../mt8183/mt8183-mt6358-ts3a227-max98357.c | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c index 3cf8aeab042c5..271413e719e30 100644 --- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c +++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c @@ -117,6 +117,45 @@ static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int +mt8183_mt6358_startup(struct snd_pcm_substream *substream) +{ + static const unsigned int rates[] = { + 48000, + }; + static const struct snd_pcm_hw_constraint_list constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, + }; + static const unsigned int channels[] = { + 2, + }; + static const struct snd_pcm_hw_constraint_list constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, + }; + + struct snd_pcm_runtime *runtime = substream->runtime; + + snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); + runtime->hw.channels_max = 2; + snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); + + runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; + snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); + + return 0; +} + +static const struct snd_soc_ops mt8183_mt6358_ops = { + .startup = mt8183_mt6358_startup, +}; + static int mt8183_mt6358_ts3a227_max98357_bt_sco_startup( struct snd_pcm_substream *substream) @@ -356,6 +395,7 @@ static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = { SND_SOC_DPCM_TRIGGER_PRE}, .dynamic = 1, .dpcm_playback = 1, + .ops = &mt8183_mt6358_ops, SND_SOC_DAILINK_REG(playback1), }, { @@ -403,6 +443,7 @@ static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = { SND_SOC_DPCM_TRIGGER_PRE}, .dynamic = 1, .dpcm_capture = 1, + .ops = &mt8183_mt6358_ops, SND_SOC_DAILINK_REG(capture3), }, { -- GitLab From b35ccebe3ef76168aa2edaa35809c0232cb3578e Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Thu, 4 Feb 2021 09:36:18 +0200 Subject: [PATCH 0998/1084] vdpa/mlx5: Restore the hardware used index after change map When a change of memory map occurs, the hardware resources are destroyed and then re-created again with the new memory map. In such case, we need to restore the hardware available and used indices. The driver failed to restore the used index which is added here. Also, since the driver also fails to reset the available and used indices upon device reset, fix this here to avoid regression caused by the fact that used index may not be zero upon device reset. Fixes: 1a86b377aa21 ("vdpa/mlx5: Add VDPA driver for supported mlx5 devices") Signed-off-by: Eli Cohen Link: https://lore.kernel.org/r/20210204073618.36336-1-elic@nvidia.com Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang --- drivers/vdpa/mlx5/net/mlx5_vnet.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index 88dde3455bfd9..b5fe6d2ad22f5 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -87,6 +87,7 @@ struct mlx5_vq_restore_info { u64 device_addr; u64 driver_addr; u16 avail_index; + u16 used_index; bool ready; struct vdpa_callback cb; bool restore; @@ -121,6 +122,7 @@ struct mlx5_vdpa_virtqueue { u32 virtq_id; struct mlx5_vdpa_net *ndev; u16 avail_idx; + u16 used_idx; int fw_state; /* keep last in the struct */ @@ -804,6 +806,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque obj_context = MLX5_ADDR_OF(create_virtio_net_q_in, in, obj_context); MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx); + MLX5_SET(virtio_net_q_object, obj_context, hw_used_index, mvq->used_idx); MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_12_3, get_features_12_3(ndev->mvdev.actual_features)); vq_ctx = MLX5_ADDR_OF(virtio_net_q_object, obj_context, virtio_q_context); @@ -1022,6 +1025,7 @@ static int connect_qps(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *m struct mlx5_virtq_attr { u8 state; u16 available_index; + u16 used_index; }; static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, @@ -1052,6 +1056,7 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu memset(attr, 0, sizeof(*attr)); attr->state = MLX5_GET(virtio_net_q_object, obj_context, state); attr->available_index = MLX5_GET(virtio_net_q_object, obj_context, hw_available_index); + attr->used_index = MLX5_GET(virtio_net_q_object, obj_context, hw_used_index); kfree(out); return 0; @@ -1535,6 +1540,16 @@ static void teardown_virtqueues(struct mlx5_vdpa_net *ndev) } } +static void clear_virtqueues(struct mlx5_vdpa_net *ndev) +{ + int i; + + for (i = ndev->mvdev.max_vqs - 1; i >= 0; i--) { + ndev->vqs[i].avail_idx = 0; + ndev->vqs[i].used_idx = 0; + } +} + /* TODO: cross-endian support */ static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev) { @@ -1610,6 +1625,7 @@ static int save_channel_info(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqu return err; ri->avail_index = attr.available_index; + ri->used_index = attr.used_index; ri->ready = mvq->ready; ri->num_ent = mvq->num_ent; ri->desc_addr = mvq->desc_addr; @@ -1654,6 +1670,7 @@ static void restore_channels_info(struct mlx5_vdpa_net *ndev) continue; mvq->avail_idx = ri->avail_index; + mvq->used_idx = ri->used_index; mvq->ready = ri->ready; mvq->num_ent = ri->num_ent; mvq->desc_addr = ri->desc_addr; @@ -1768,6 +1785,7 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status) if (!status) { mlx5_vdpa_info(mvdev, "performing device reset\n"); teardown_driver(ndev); + clear_virtqueues(ndev); mlx5_vdpa_destroy_mr(&ndev->mvdev); ndev->mvdev.status = 0; ndev->mvdev.mlx_features = 0; -- GitLab From 24c242ec7abb3d21fa0b1da6bb251521dc1717b5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 25 Jan 2021 15:30:39 +0100 Subject: [PATCH 0999/1084] ntp: Use freezable workqueue for RTC synchronization The bug fixed by commit e3fab2f3de081e98 ("ntp: Fix RTC synchronization on 32-bit platforms") revealed an underlying issue: RTC synchronization may happen anytime, even while the system is partially suspended. On systems where the RTC is connected to an I2C bus, the I2C bus controller may already or still be suspended, triggering a WARNING during suspend or resume from s2ram: WARNING: CPU: 0 PID: 124 at drivers/i2c/i2c-core.h:54 __i2c_transfer+0x634/0x680 i2c i2c-6: Transfer while suspended [...] Workqueue: events_power_efficient sync_hw_clock [...] (__i2c_transfer) (i2c_transfer) (regmap_i2c_read) ... (da9063_rtc_set_time) (rtc_set_time) (sync_hw_clock) (process_one_work) Fix this race condition by using the freezable instead of the normal power-efficient workqueue. Signed-off-by: Geert Uytterhoeven Signed-off-by: Thomas Gleixner Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20210125143039.1051912-1-geert+renesas@glider.be --- kernel/time/ntp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 87389b9e21aba..5247afd7f3455 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -502,7 +502,7 @@ static struct hrtimer sync_hrtimer; static enum hrtimer_restart sync_timer_callback(struct hrtimer *timer) { - queue_work(system_power_efficient_wq, &sync_work); + queue_work(system_freezable_power_efficient_wq, &sync_work); return HRTIMER_NORESTART; } @@ -668,7 +668,7 @@ void ntp_notify_cmos_timer(void) * just a pointless work scheduled. */ if (ntp_synced() && !hrtimer_is_queued(&sync_hrtimer)) - queue_work(system_power_efficient_wq, &sync_work); + queue_work(system_freezable_power_efficient_wq, &sync_work); } static void __init ntp_init_cmos_sync(void) -- GitLab From 5e3277ab3baff6db96ae44adf6f85d6f0f6502cc Mon Sep 17 00:00:00 2001 From: Jun Nie Date: Mon, 1 Feb 2021 21:29:41 +0800 Subject: [PATCH 1000/1084] ASoC: qcom: lpass: Fix i2s ctl register bit map Fix bitwidth mapping in i2s ctl register per APQ8016 document. Fixes: b5022a36d28f ("ASoC: qcom: lpass: Use regmap_field for i2sctl and dmactl registers") Reviewed-by: Srinivas Kandagatla Reviewed-by: Stephan Gerhold Signed-off-by: Jun Nie Link: https://lore.kernel.org/r/20210201132941.460360-1-jun.nie@linaro.org Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-apq8016.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/qcom/lpass-apq8016.c b/sound/soc/qcom/lpass-apq8016.c index 8507ef8f6679b..3efa133d1c641 100644 --- a/sound/soc/qcom/lpass-apq8016.c +++ b/sound/soc/qcom/lpass-apq8016.c @@ -250,7 +250,7 @@ static struct lpass_variant apq8016_data = { .micmode = REG_FIELD_ID(0x1000, 4, 7, 4, 0x1000), .micmono = REG_FIELD_ID(0x1000, 3, 3, 4, 0x1000), .wssrc = REG_FIELD_ID(0x1000, 2, 2, 4, 0x1000), - .bitwidth = REG_FIELD_ID(0x1000, 0, 0, 4, 0x1000), + .bitwidth = REG_FIELD_ID(0x1000, 0, 1, 4, 0x1000), .rdma_dyncclk = REG_FIELD_ID(0x8400, 12, 12, 2, 0x1000), .rdma_bursten = REG_FIELD_ID(0x8400, 11, 11, 2, 0x1000), -- GitLab From 500c9f8c58a7c8cd5d9c1483569c046cfcfc47a4 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 5 Feb 2021 15:26:25 +0800 Subject: [PATCH 1001/1084] ASoC: dmaengine_pcm: add peripheral configuration The commit e7bbb7acabf4 ("dmaengine: add peripheral configuration") adds peripheral configuration for dma_slave_config. This configuration is useful for some audio peripherals, for example, the peripheral supports multi fifos, we can let the DMA know which fifos are selected. So also add this configuration for snd_dmaengine_dai_dma_data. Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1612509985-11063-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- include/sound/dmaengine_pcm.h | 5 +++++ sound/core/pcm_dmaengine.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index 8c5e38180fb04..96666efddb396 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -66,6 +66,9 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) * @chan_name: Custom channel name to use when requesting DMA channel. * @fifo_size: FIFO size of the DAI controller in bytes * @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now + * @peripheral_config: peripheral configuration for programming peripheral + * for dmaengine transfer + * @peripheral_size: peripheral configuration buffer size */ struct snd_dmaengine_dai_dma_data { dma_addr_t addr; @@ -76,6 +79,8 @@ struct snd_dmaengine_dai_dma_data { const char *chan_name; unsigned int fifo_size; unsigned int flags; + void *peripheral_config; + size_t peripheral_size; }; void snd_dmaengine_pcm_set_config_from_dai_data( diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 4d0e8fe535a1e..1fc2fa0775744 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -125,6 +125,8 @@ void snd_dmaengine_pcm_set_config_from_dai_data( } slave_config->slave_id = dma_data->slave_id; + slave_config->peripheral_config = dma_data->peripheral_config; + slave_config->peripheral_size = dma_data->peripheral_size; } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); -- GitLab From f08c74a3b52d126d053c741b906ee1ca2a4f3568 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 4 Feb 2021 14:00:22 +0100 Subject: [PATCH 1002/1084] ASoC: dt-bindings: renesas, rsnd: Group tuples in playback/capture properties To improve human readability and enable automatic validation, the tuples in "playback" and "capture" properties in sound device nodes should be grouped using angle brackets. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20210204130022.1646427-1-geert+renesas@glider.be Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/renesas,rsnd.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml index 0fd37aa84947a..2e1046513603e 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml @@ -404,7 +404,7 @@ examples: /* DAI base */ rcar_sound,dai { dai0 { - playback = <&ssi5 &src5>; + playback = <&ssi5>, <&src5>; capture = <&ssi6>; }; dai1 { @@ -430,8 +430,8 @@ examples: bitclock-master = <&rsnd_endpoint0>; frame-master = <&rsnd_endpoint0>; - playback = <&ssi0 &src0 &dvc0>; - capture = <&ssi1 &src1 &dvc1>; + playback = <&ssi0>, <&src0>, <&dvc0>; + capture = <&ssi1>, <&src1>, <&dvc1>; }; }; }; -- GitLab From 585fc0d2871c9318c949fbf45b1f081edd489e96 Mon Sep 17 00:00:00 2001 From: Muchun Song Date: Thu, 4 Feb 2021 18:32:03 -0800 Subject: [PATCH 1003/1084] mm: hugetlbfs: fix cannot migrate the fallocated HugeTLB page If a new hugetlb page is allocated during fallocate it will not be marked as active (set_page_huge_active) which will result in a later isolate_huge_page failure when the page migration code would like to move that page. Such a failure would be unexpected and wrong. Only export set_page_huge_active, just leave clear_page_huge_active as static. Because there are no external users. Link: https://lkml.kernel.org/r/20210115124942.46403-3-songmuchun@bytedance.com Fixes: 70c3547e36f5 (hugetlbfs: add hugetlbfs_fallocate()) Signed-off-by: Muchun Song Acked-by: Michal Hocko Reviewed-by: Mike Kravetz Reviewed-by: Oscar Salvador Cc: David Hildenbrand Cc: Yang Shi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/hugetlbfs/inode.c | 3 ++- include/linux/hugetlb.h | 2 ++ mm/hugetlb.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index b5c109703daaf..21c20fd5f9ee7 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -735,9 +735,10 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, mutex_unlock(&hugetlb_fault_mutex_table[hash]); + set_page_huge_active(page); /* * unlock_page because locked by add_to_page_cache() - * page_put due to reference from alloc_huge_page() + * put_page() due to reference from alloc_huge_page() */ unlock_page(page); put_page(page); diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index ebca2ef022127..b5807f23caf80 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -770,6 +770,8 @@ static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, } #endif +void set_page_huge_active(struct page *page); + #else /* CONFIG_HUGETLB_PAGE */ struct hstate {}; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 18f6ee3179002..6f0e242d38ca1 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1349,7 +1349,7 @@ bool page_huge_active(struct page *page) } /* never called for tail page */ -static void set_page_huge_active(struct page *page) +void set_page_huge_active(struct page *page) { VM_BUG_ON_PAGE(!PageHeadHuge(page), page); SetPagePrivate(&page[1]); -- GitLab From 7ffddd499ba6122b1a07828f023d1d67629aa017 Mon Sep 17 00:00:00 2001 From: Muchun Song Date: Thu, 4 Feb 2021 18:32:06 -0800 Subject: [PATCH 1004/1084] mm: hugetlb: fix a race between freeing and dissolving the page There is a race condition between __free_huge_page() and dissolve_free_huge_page(). CPU0: CPU1: // page_count(page) == 1 put_page(page) __free_huge_page(page) dissolve_free_huge_page(page) spin_lock(&hugetlb_lock) // PageHuge(page) && !page_count(page) update_and_free_page(page) // page is freed to the buddy spin_unlock(&hugetlb_lock) spin_lock(&hugetlb_lock) clear_page_huge_active(page) enqueue_huge_page(page) // It is wrong, the page is already freed spin_unlock(&hugetlb_lock) The race window is between put_page() and dissolve_free_huge_page(). We should make sure that the page is already on the free list when it is dissolved. As a result __free_huge_page would corrupt page(s) already in the buddy allocator. Link: https://lkml.kernel.org/r/20210115124942.46403-4-songmuchun@bytedance.com Fixes: c8721bbbdd36 ("mm: memory-hotplug: enable memory hotplug to handle hugepage") Signed-off-by: Muchun Song Reviewed-by: Mike Kravetz Reviewed-by: Oscar Salvador Acked-by: Michal Hocko Cc: David Hildenbrand Cc: Yang Shi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/hugetlb.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 6f0e242d38ca1..c6ee3c28a04ef 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -79,6 +79,21 @@ DEFINE_SPINLOCK(hugetlb_lock); static int num_fault_mutexes; struct mutex *hugetlb_fault_mutex_table ____cacheline_aligned_in_smp; +static inline bool PageHugeFreed(struct page *head) +{ + return page_private(head + 4) == -1UL; +} + +static inline void SetPageHugeFreed(struct page *head) +{ + set_page_private(head + 4, -1UL); +} + +static inline void ClearPageHugeFreed(struct page *head) +{ + set_page_private(head + 4, 0); +} + /* Forward declaration */ static int hugetlb_acct_memory(struct hstate *h, long delta); @@ -1028,6 +1043,7 @@ static void enqueue_huge_page(struct hstate *h, struct page *page) list_move(&page->lru, &h->hugepage_freelists[nid]); h->free_huge_pages++; h->free_huge_pages_node[nid]++; + SetPageHugeFreed(page); } static struct page *dequeue_huge_page_node_exact(struct hstate *h, int nid) @@ -1044,6 +1060,7 @@ static struct page *dequeue_huge_page_node_exact(struct hstate *h, int nid) list_move(&page->lru, &h->hugepage_activelist); set_page_refcounted(page); + ClearPageHugeFreed(page); h->free_huge_pages--; h->free_huge_pages_node[nid]--; return page; @@ -1505,6 +1522,7 @@ static void prep_new_huge_page(struct hstate *h, struct page *page, int nid) spin_lock(&hugetlb_lock); h->nr_huge_pages++; h->nr_huge_pages_node[nid]++; + ClearPageHugeFreed(page); spin_unlock(&hugetlb_lock); } @@ -1755,6 +1773,7 @@ int dissolve_free_huge_page(struct page *page) { int rc = -EBUSY; +retry: /* Not to disrupt normal path by vainly holding hugetlb_lock */ if (!PageHuge(page)) return 0; @@ -1771,6 +1790,26 @@ int dissolve_free_huge_page(struct page *page) int nid = page_to_nid(head); if (h->free_huge_pages - h->resv_huge_pages == 0) goto out; + + /* + * We should make sure that the page is already on the free list + * when it is dissolved. + */ + if (unlikely(!PageHugeFreed(head))) { + spin_unlock(&hugetlb_lock); + cond_resched(); + + /* + * Theoretically, we should return -EBUSY when we + * encounter this race. In fact, we have a chance + * to successfully dissolve the page if we do a + * retry. Because the race window is quite small. + * If we seize this opportunity, it is an optimization + * for increasing the success rate of dissolving page. + */ + goto retry; + } + /* * Move PageHWPoison flag from head page to the raw error page, * which makes any subpages rather than the error page reusable. -- GitLab From 0eb2df2b5629794020f75e94655e1994af63f0d4 Mon Sep 17 00:00:00 2001 From: Muchun Song Date: Thu, 4 Feb 2021 18:32:10 -0800 Subject: [PATCH 1005/1084] mm: hugetlb: fix a race between isolating and freeing page There is a race between isolate_huge_page() and __free_huge_page(). CPU0: CPU1: if (PageHuge(page)) put_page(page) __free_huge_page(page) spin_lock(&hugetlb_lock) update_and_free_page(page) set_compound_page_dtor(page, NULL_COMPOUND_DTOR) spin_unlock(&hugetlb_lock) isolate_huge_page(page) // trigger BUG_ON VM_BUG_ON_PAGE(!PageHead(page), page) spin_lock(&hugetlb_lock) page_huge_active(page) // trigger BUG_ON VM_BUG_ON_PAGE(!PageHuge(page), page) spin_unlock(&hugetlb_lock) When we isolate a HugeTLB page on CPU0. Meanwhile, we free it to the buddy allocator on CPU1. Then, we can trigger a BUG_ON on CPU0, because it is already freed to the buddy allocator. Link: https://lkml.kernel.org/r/20210115124942.46403-5-songmuchun@bytedance.com Fixes: c8721bbbdd36 ("mm: memory-hotplug: enable memory hotplug to handle hugepage") Signed-off-by: Muchun Song Reviewed-by: Mike Kravetz Acked-by: Michal Hocko Reviewed-by: Oscar Salvador Cc: David Hildenbrand Cc: Yang Shi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/hugetlb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index c6ee3c28a04ef..90e03c3000c51 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -5594,9 +5594,9 @@ bool isolate_huge_page(struct page *page, struct list_head *list) { bool ret = true; - VM_BUG_ON_PAGE(!PageHead(page), page); spin_lock(&hugetlb_lock); - if (!page_huge_active(page) || !get_page_unless_zero(page)) { + if (!PageHeadHuge(page) || !page_huge_active(page) || + !get_page_unless_zero(page)) { ret = false; goto unlock; } -- GitLab From ecbf4724e6061b4b01be20f6d797d64d462b2bc8 Mon Sep 17 00:00:00 2001 From: Muchun Song Date: Thu, 4 Feb 2021 18:32:13 -0800 Subject: [PATCH 1006/1084] mm: hugetlb: remove VM_BUG_ON_PAGE from page_huge_active The page_huge_active() can be called from scan_movable_pages() which do not hold a reference count to the HugeTLB page. So when we call page_huge_active() from scan_movable_pages(), the HugeTLB page can be freed parallel. Then we will trigger a BUG_ON which is in the page_huge_active() when CONFIG_DEBUG_VM is enabled. Just remove the VM_BUG_ON_PAGE. Link: https://lkml.kernel.org/r/20210115124942.46403-6-songmuchun@bytedance.com Fixes: 7e1f049efb86 ("mm: hugetlb: cleanup using paeg_huge_active()") Signed-off-by: Muchun Song Reviewed-by: Mike Kravetz Acked-by: Michal Hocko Reviewed-by: Oscar Salvador Cc: David Hildenbrand Cc: Yang Shi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/hugetlb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 90e03c3000c51..d78111f0fa2cb 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1361,8 +1361,7 @@ struct hstate *size_to_hstate(unsigned long size) */ bool page_huge_active(struct page *page) { - VM_BUG_ON_PAGE(!PageHuge(page), page); - return PageHead(page) && PagePrivate(&page[1]); + return PageHeadHuge(page) && PagePrivate(&page[1]); } /* never called for tail page */ -- GitLab From 71a64f618be9594cd0645105c0989855c0f86d90 Mon Sep 17 00:00:00 2001 From: Muchun Song Date: Thu, 4 Feb 2021 18:32:17 -0800 Subject: [PATCH 1007/1084] mm: migrate: do not migrate HugeTLB page whose refcount is one All pages isolated for the migration have an elevated reference count and therefore seeing a reference count equal to 1 means that the last user of the page has dropped the reference and the page has became unused and there doesn't make much sense to migrate it anymore. This has been done for regular pages and this patch does the same for hugetlb pages. Although the likelihood of the race is rather small for hugetlb pages it makes sense the two code paths in sync. Link: https://lkml.kernel.org/r/20210115124942.46403-2-songmuchun@bytedance.com Signed-off-by: Muchun Song Reviewed-by: Mike Kravetz Acked-by: Yang Shi Acked-by: Michal Hocko Reviewed-by: David Hildenbrand Reviewed-by: Oscar Salvador Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/migrate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/migrate.c b/mm/migrate.c index c0efe921bca5c..20ca887ea7694 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1280,6 +1280,12 @@ static int unmap_and_move_huge_page(new_page_t get_new_page, return -ENOSYS; } + if (page_count(hpage) == 1) { + /* page was freed from under us. So we are done. */ + putback_active_hugepage(hpage); + return MIGRATEPAGE_SUCCESS; + } + new_hpage = get_new_page(hpage, private); if (!new_hpage) return -ENOMEM; -- GitLab From 74e21484e40bb8ce0f9828bbfe1c9fc9b04249c6 Mon Sep 17 00:00:00 2001 From: Rokudo Yan Date: Thu, 4 Feb 2021 18:32:20 -0800 Subject: [PATCH 1008/1084] mm, compaction: move high_pfn to the for loop scope In fast_isolate_freepages, high_pfn will be used if a prefered one (ie PFN >= low_fn) not found. But the high_pfn is not reset before searching an free area, so when it was used as freepage, it may from another free area searched before. As a result move_freelist_head(freelist, freepage) will have unexpected behavior (eg corrupt the MOVABLE freelist) Unable to handle kernel paging request at virtual address dead000000000200 Mem abort info: ESR = 0x96000044 Exception class = DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 Data abort info: ISV = 0, ISS = 0x00000044 CM = 0, WnR = 1 [dead000000000200] address between user and kernel address ranges -000|list_cut_before(inline) -000|move_freelist_head(inline) -000|fast_isolate_freepages(inline) -000|isolate_freepages(inline) -000|compaction_alloc(?, ?) -001|unmap_and_move(inline) -001|migrate_pages([NSD:0xFFFFFF80088CBBD0] from = 0xFFFFFF80088CBD88, [NSD:0xFFFFFF80088CBBC8] get_new_p -002|__read_once_size(inline) -002|static_key_count(inline) -002|static_key_false(inline) -002|trace_mm_compaction_migratepages(inline) -002|compact_zone(?, [NSD:0xFFFFFF80088CBCB0] capc = 0x0) -003|kcompactd_do_work(inline) -003|kcompactd([X19] p = 0xFFFFFF93227FBC40) -004|kthread([X20] _create = 0xFFFFFFE1AFB26380) -005|ret_from_fork(asm) The issue was reported on an smart phone product with 6GB ram and 3GB zram as swap device. This patch fixes the issue by reset high_pfn before searching each free area, which ensure freepage and freelist match when call move_freelist_head in fast_isolate_freepages(). Link: http://lkml.kernel.org/r/20190118175136.31341-12-mgorman@techsingularity.net Link: https://lkml.kernel.org/r/20210112094720.1238444-1-wu-yan@tcl.com Fixes: 5a811889de10f1eb ("mm, compaction: use free lists to quickly locate a migration target") Signed-off-by: Rokudo Yan Acked-by: Mel Gorman Acked-by: Vlastimil Babka Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/compaction.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/compaction.c b/mm/compaction.c index e5acb97144363..190ccdaa6c192 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -1342,7 +1342,7 @@ fast_isolate_freepages(struct compact_control *cc) { unsigned int limit = min(1U, freelist_scan_limit(cc) >> 1); unsigned int nr_scanned = 0; - unsigned long low_pfn, min_pfn, high_pfn = 0, highest = 0; + unsigned long low_pfn, min_pfn, highest = 0; unsigned long nr_isolated = 0; unsigned long distance; struct page *page = NULL; @@ -1387,6 +1387,7 @@ fast_isolate_freepages(struct compact_control *cc) struct page *freepage; unsigned long flags; unsigned int order_scanned = 0; + unsigned long high_pfn = 0; if (!area->nr_free) continue; -- GitLab From 4f6ec8602341e97b364e4e0d41a1ed08148f5e98 Mon Sep 17 00:00:00 2001 From: Rick Edgecombe Date: Thu, 4 Feb 2021 18:32:24 -0800 Subject: [PATCH 1009/1084] mm/vmalloc: separate put pages and flush VM flags When VM_MAP_PUT_PAGES was added, it was defined with the same value as VM_FLUSH_RESET_PERMS. This doesn't seem like it will cause any big functional problems other than some excess flushing for VM_MAP_PUT_PAGES allocations. Redefine VM_MAP_PUT_PAGES to have its own value. Also, rearrange things so flags are less likely to be missed in the future. Link: https://lkml.kernel.org/r/20210122233706.9304-1-rick.p.edgecombe@intel.com Fixes: b944afc9d64d ("mm: add a VM_MAP_PUT_PAGES flag for vmap") Signed-off-by: Rick Edgecombe Suggested-by: Matthew Wilcox Cc: Miaohe Lin Cc: Christoph Hellwig Cc: Daniel Axtens Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmalloc.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 80c0181c411df..cedcda6593f61 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -24,7 +24,8 @@ struct notifier_block; /* in notifier.h */ #define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ #define VM_NO_GUARD 0x00000040 /* don't add guard page */ #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ -#define VM_MAP_PUT_PAGES 0x00000100 /* put pages and free array in vfree */ +#define VM_FLUSH_RESET_PERMS 0x00000100 /* reset direct map and flush TLB on unmap, can't be freed in atomic context */ +#define VM_MAP_PUT_PAGES 0x00000200 /* put pages and free array in vfree */ /* * VM_KASAN is used slighly differently depending on CONFIG_KASAN_VMALLOC. @@ -37,12 +38,6 @@ struct notifier_block; /* in notifier.h */ * determine which allocations need the module shadow freed. */ -/* - * Memory with VM_FLUSH_RESET_PERMS cannot be freed in an interrupt or with - * vfree_atomic(). - */ -#define VM_FLUSH_RESET_PERMS 0x00000100 /* Reset direct map and flush TLB on unmap */ - /* bits [20..32] reserved for arch specific ioremap internals */ /* -- GitLab From 55b6f763d8bcb5546997933105d66d3e6b080e6a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 4 Feb 2021 18:32:28 -0800 Subject: [PATCH 1010/1084] init/gcov: allow CONFIG_CONSTRUCTORS on UML to fix module gcov On ARCH=um, loading a module doesn't result in its constructors getting called, which breaks module gcov since the debugfs files are never registered. On the other hand, in-kernel constructors have already been called by the dynamic linker, so we can't call them again. Get out of this conundrum by allowing CONFIG_CONSTRUCTORS to be selected, but avoiding the in-kernel constructor calls. Also remove the "if !UML" from GCOV selecting CONSTRUCTORS now, since we really do want CONSTRUCTORS, just not kernel binary ones. Link: https://lkml.kernel.org/r/20210120172041.c246a2cac2fb.I1358f584b76f1898373adfed77f4462c8705b736@changeid Signed-off-by: Johannes Berg Reviewed-by: Peter Oberparleiter Cc: Arnd Bergmann Cc: Jessica Yu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/Kconfig | 1 - init/main.c | 8 +++++++- kernel/gcov/Kconfig | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index b77c60f8b963d..29ad683250288 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -76,7 +76,6 @@ config CC_HAS_ASM_INLINE config CONSTRUCTORS bool - depends on !UML config IRQ_WORK bool diff --git a/init/main.c b/init/main.c index c68d784376ca1..a626e78dbf061 100644 --- a/init/main.c +++ b/init/main.c @@ -1066,7 +1066,13 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) /* Call all constructor functions linked into the kernel. */ static void __init do_ctors(void) { -#ifdef CONFIG_CONSTRUCTORS +/* + * For UML, the constructors have already been called by the + * normal setup code as it's just a normal ELF binary, so we + * cannot do it again - but we do need CONFIG_CONSTRUCTORS + * even on UML for modules. + */ +#if defined(CONFIG_CONSTRUCTORS) && !defined(CONFIG_UML) ctor_fn_t *fn = (ctor_fn_t *) __ctors_start; for (; fn < (ctor_fn_t *) __ctors_end; fn++) diff --git a/kernel/gcov/Kconfig b/kernel/gcov/Kconfig index 3110c77230c7f..f62de2dea8a31 100644 --- a/kernel/gcov/Kconfig +++ b/kernel/gcov/Kconfig @@ -4,7 +4,7 @@ menu "GCOV-based kernel profiling" config GCOV_KERNEL bool "Enable gcov-based kernel profiling" depends on DEBUG_FS - select CONSTRUCTORS if !UML + select CONSTRUCTORS default n help This option enables gcov-based code profiling (e.g. for code coverage -- GitLab From 1c2f67308af4c102b4e1e6cd6f69819ae59408e0 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Thu, 4 Feb 2021 18:32:31 -0800 Subject: [PATCH 1011/1084] mm: thp: fix MADV_REMOVE deadlock on shmem THP Sergey reported deadlock between kswapd correctly doing its usual lock_page(page) followed by down_read(page->mapping->i_mmap_rwsem), and madvise(MADV_REMOVE) on an madvise(MADV_HUGEPAGE) area doing down_write(page->mapping->i_mmap_rwsem) followed by lock_page(page). This happened when shmem_fallocate(punch hole)'s unmap_mapping_range() reaches zap_pmd_range()'s call to __split_huge_pmd(). The same deadlock could occur when partially truncating a mapped huge tmpfs file, or using fallocate(FALLOC_FL_PUNCH_HOLE) on it. __split_huge_pmd()'s page lock was added in 5.8, to make sure that any concurrent use of reuse_swap_page() (holding page lock) could not catch the anon THP's mapcounts and swapcounts while they were being split. Fortunately, reuse_swap_page() is never applied to a shmem or file THP (not even by khugepaged, which checks PageSwapCache before calling), and anonymous THPs are never created in shmem or file areas: so that __split_huge_pmd()'s page lock can only be necessary for anonymous THPs, on which there is no risk of deadlock with i_mmap_rwsem. Link: https://lkml.kernel.org/r/alpine.LSU.2.11.2101161409470.2022@eggly.anvils Fixes: c444eb564fb1 ("mm: thp: make the THP mapcount atomic against __split_huge_pmd_locked()") Signed-off-by: Hugh Dickins Reported-by: Sergey Senozhatsky Reviewed-by: Andrea Arcangeli Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/huge_memory.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 9237976abe72b..91ca9b103ee52 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2202,7 +2202,7 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, { spinlock_t *ptl; struct mmu_notifier_range range; - bool was_locked = false; + bool do_unlock_page = false; pmd_t _pmd; mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, vma->vm_mm, @@ -2218,7 +2218,6 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, VM_BUG_ON(freeze && !page); if (page) { VM_WARN_ON_ONCE(!PageLocked(page)); - was_locked = true; if (page != pmd_page(*pmd)) goto out; } @@ -2227,19 +2226,29 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, if (pmd_trans_huge(*pmd)) { if (!page) { page = pmd_page(*pmd); - if (unlikely(!trylock_page(page))) { - get_page(page); - _pmd = *pmd; - spin_unlock(ptl); - lock_page(page); - spin_lock(ptl); - if (unlikely(!pmd_same(*pmd, _pmd))) { - unlock_page(page); + /* + * An anonymous page must be locked, to ensure that a + * concurrent reuse_swap_page() sees stable mapcount; + * but reuse_swap_page() is not used on shmem or file, + * and page lock must not be taken when zap_pmd_range() + * calls __split_huge_pmd() while i_mmap_lock is held. + */ + if (PageAnon(page)) { + if (unlikely(!trylock_page(page))) { + get_page(page); + _pmd = *pmd; + spin_unlock(ptl); + lock_page(page); + spin_lock(ptl); + if (unlikely(!pmd_same(*pmd, _pmd))) { + unlock_page(page); + put_page(page); + page = NULL; + goto repeat; + } put_page(page); - page = NULL; - goto repeat; } - put_page(page); + do_unlock_page = true; } } if (PageMlocked(page)) @@ -2249,7 +2258,7 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, __split_huge_pmd_locked(vma, pmd, range.start, freeze); out: spin_unlock(ptl); - if (!was_locked && page) + if (do_unlock_page) unlock_page(page); /* * No need to double call mmu_notifier->invalidate_range() callback. -- GitLab From 2dcb3964544177c51853a210b6ad400de78ef17d Mon Sep 17 00:00:00 2001 From: Roman Gushchin Date: Thu, 4 Feb 2021 18:32:36 -0800 Subject: [PATCH 1012/1084] memblock: do not start bottom-up allocations with kernel_end With kaslr the kernel image is placed at a random place, so starting the bottom-up allocation with the kernel_end can result in an allocation failure and a warning like this one: hugetlb_cma: reserve 2048 MiB, up to 2048 MiB per node ------------[ cut here ]------------ memblock: bottom-up allocation failed, memory hotremove may be affected WARNING: CPU: 0 PID: 0 at mm/memblock.c:332 memblock_find_in_range_node+0x178/0x25a Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 5.10.0+ #1169 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014 RIP: 0010:memblock_find_in_range_node+0x178/0x25a Code: e9 6d ff ff ff 48 85 c0 0f 85 da 00 00 00 80 3d 9b 35 df 00 00 75 15 48 c7 c7 c0 75 59 88 c6 05 8b 35 df 00 01 e8 25 8a fa ff <0f> 0b 48 c7 44 24 20 ff ff ff ff 44 89 e6 44 89 ea 48 c7 c1 70 5c RSP: 0000:ffffffff88803d18 EFLAGS: 00010086 ORIG_RAX: 0000000000000000 RAX: 0000000000000000 RBX: 0000000240000000 RCX: 00000000ffffdfff RDX: 00000000ffffdfff RSI: 00000000ffffffea RDI: 0000000000000046 RBP: 0000000100000000 R08: ffffffff88922788 R09: 0000000000009ffb R10: 00000000ffffe000 R11: 3fffffffffffffff R12: 0000000000000000 R13: 0000000000000000 R14: 0000000080000000 R15: 00000001fb42c000 FS: 0000000000000000(0000) GS:ffffffff88f71000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffa080fb401000 CR3: 00000001fa80a000 CR4: 00000000000406b0 Call Trace: memblock_alloc_range_nid+0x8d/0x11e cma_declare_contiguous_nid+0x2c4/0x38c hugetlb_cma_reserve+0xdc/0x128 flush_tlb_one_kernel+0xc/0x20 native_set_fixmap+0x82/0xd0 flat_get_apic_id+0x5/0x10 register_lapic_address+0x8e/0x97 setup_arch+0x8a5/0xc3f start_kernel+0x66/0x547 load_ucode_bsp+0x4c/0xcd secondary_startup_64_no_verify+0xb0/0xbb random: get_random_bytes called from __warn+0xab/0x110 with crng_init=0 ---[ end trace f151227d0b39be70 ]--- At the same time, the kernel image is protected with memblock_reserve(), so we can just start searching at PAGE_SIZE. In this case the bottom-up allocation has the same chances to success as a top-down allocation, so there is no reason to fallback in the case of a failure. All together it simplifies the logic. Link: https://lkml.kernel.org/r/20201217201214.3414100-2-guro@fb.com Fixes: 8fabc623238e ("powerpc: Ensure that swiotlb buffer is allocated from low memory") Signed-off-by: Roman Gushchin Reviewed-by: Mike Rapoport Cc: Joonsoo Kim Cc: Michal Hocko Cc: Rik van Riel Cc: Wonhyuk Yang Cc: Thiago Jung Bauermann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memblock.c | 49 ++++++------------------------------------------- 1 file changed, 6 insertions(+), 43 deletions(-) diff --git a/mm/memblock.c b/mm/memblock.c index 1eaaec1e7687c..8d9b5f1e70409 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -275,14 +275,6 @@ __memblock_find_range_top_down(phys_addr_t start, phys_addr_t end, * * Find @size free area aligned to @align in the specified range and node. * - * When allocation direction is bottom-up, the @start should be greater - * than the end of the kernel image. Otherwise, it will be trimmed. The - * reason is that we want the bottom-up allocation just near the kernel - * image so it is highly likely that the allocated memory and the kernel - * will reside in the same node. - * - * If bottom-up allocation failed, will try to allocate memory top-down. - * * Return: * Found address on success, 0 on failure. */ @@ -291,8 +283,6 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size, phys_addr_t end, int nid, enum memblock_flags flags) { - phys_addr_t kernel_end, ret; - /* pump up @end */ if (end == MEMBLOCK_ALLOC_ACCESSIBLE || end == MEMBLOCK_ALLOC_KASAN) @@ -301,40 +291,13 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size, /* avoid allocating the first page */ start = max_t(phys_addr_t, start, PAGE_SIZE); end = max(start, end); - kernel_end = __pa_symbol(_end); - - /* - * try bottom-up allocation only when bottom-up mode - * is set and @end is above the kernel image. - */ - if (memblock_bottom_up() && end > kernel_end) { - phys_addr_t bottom_up_start; - - /* make sure we will allocate above the kernel */ - bottom_up_start = max(start, kernel_end); - /* ok, try bottom-up allocation first */ - ret = __memblock_find_range_bottom_up(bottom_up_start, end, - size, align, nid, flags); - if (ret) - return ret; - - /* - * we always limit bottom-up allocation above the kernel, - * but top-down allocation doesn't have the limit, so - * retrying top-down allocation may succeed when bottom-up - * allocation failed. - * - * bottom-up allocation is expected to be fail very rarely, - * so we use WARN_ONCE() here to see the stack trace if - * fail happens. - */ - WARN_ONCE(IS_ENABLED(CONFIG_MEMORY_HOTREMOVE), - "memblock: bottom-up allocation failed, memory hotremove may be affected\n"); - } - - return __memblock_find_range_top_down(start, end, size, align, nid, - flags); + if (memblock_bottom_up()) + return __memblock_find_range_bottom_up(start, end, size, align, + nid, flags); + else + return __memblock_find_range_top_down(start, end, size, align, + nid, flags); } /** -- GitLab From 4c415b9a710b6ebce6517f6d4cdc5c4c31cfd7d9 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 4 Feb 2021 18:32:39 -0800 Subject: [PATCH 1013/1084] mailmap: fix name/email for Viresh Kumar For some of the patches the email id was misspelled to linaro.com instead of linaro.org and for others Viresh Kumar was written as "viresh kumar" (all small). Fix both with help of mailmap entries. Link: https://lkml.kernel.org/r/d6b80b210d7fe0ddc1d4d0b22eff9708c72ef8b3.1612178938.git.viresh.kumar@linaro.org Signed-off-by: Viresh Kumar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- .mailmap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mailmap b/.mailmap index cc4e91d3075e8..d6580d267a1bd 100644 --- a/.mailmap +++ b/.mailmap @@ -334,6 +334,8 @@ Vinod Koul Viresh Kumar Viresh Kumar Viresh Kumar +Viresh Kumar +Viresh Kumar Vivien Didelot Vlad Dogaru Vladimir Davydov -- GitLab From 9c41e526a56f2cf25816e58284f4a5f9c12ccef7 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 4 Feb 2021 18:32:42 -0800 Subject: [PATCH 1014/1084] mailmap: add entries for Manivannan Sadhasivam Map my personal and work addresses to korg mail address. Link: https://lkml.kernel.org/r/20210201104640.108556-1-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- .mailmap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mailmap b/.mailmap index d6580d267a1bd..4105b5f80f4c6 100644 --- a/.mailmap +++ b/.mailmap @@ -199,6 +199,8 @@ Li Yang Li Yang Lukasz Luba Maciej W. Rozycki +Manivannan Sadhasivam +Manivannan Sadhasivam Marcin Nowakowski Marc Zyngier Mark Brown -- GitLab From da74240eb3fcd806edb1643874363e954d9e948b Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Thu, 4 Feb 2021 18:32:45 -0800 Subject: [PATCH 1015/1084] mm/filemap: add missing mem_cgroup_uncharge() to __add_to_page_cache_locked() Commit 3fea5a499d57 ("mm: memcontrol: convert page cache to a new mem_cgroup_charge() API") introduced a bug in __add_to_page_cache_locked() causing the following splat: page dumped because: VM_BUG_ON_PAGE(page_memcg(page)) pages's memcg:ffff8889a4116000 ------------[ cut here ]------------ kernel BUG at mm/memcontrol.c:2924! invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 35 PID: 12345 Comm: cat Tainted: G S W I 5.11.0-rc4-debug+ #1 Hardware name: HP HP Z8 G4 Workstation/81C7, BIOS P60 v01.25 12/06/2017 RIP: commit_charge+0xf4/0x130 Call Trace: mem_cgroup_charge+0x175/0x770 __add_to_page_cache_locked+0x712/0xad0 add_to_page_cache_lru+0xc5/0x1f0 cachefiles_read_or_alloc_pages+0x895/0x2e10 [cachefiles] __fscache_read_or_alloc_pages+0x6c0/0xa00 [fscache] __nfs_readpages_from_fscache+0x16d/0x630 [nfs] nfs_readpages+0x24e/0x540 [nfs] read_pages+0x5b1/0xc40 page_cache_ra_unbounded+0x460/0x750 generic_file_buffered_read_get_pages+0x290/0x1710 generic_file_buffered_read+0x2a9/0xc30 nfs_file_read+0x13f/0x230 [nfs] new_sync_read+0x3af/0x610 vfs_read+0x339/0x4b0 ksys_read+0xf1/0x1c0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Before that commit, there was a try_charge() and commit_charge() in __add_to_page_cache_locked(). These two separated charge functions were replaced by a single mem_cgroup_charge(). However, it forgot to add a matching mem_cgroup_uncharge() when the xarray insertion failed with the page released back to the pool. Fix this by adding a mem_cgroup_uncharge() call when insertion error happens. Link: https://lkml.kernel.org/r/20210125042441.20030-1-longman@redhat.com Fixes: 3fea5a499d57 ("mm: memcontrol: convert page cache to a new mem_cgroup_charge() API") Signed-off-by: Waiman Long Reviewed-by: Alex Shi Acked-by: Johannes Weiner Cc: Matthew Wilcox Cc: Miaohe Lin Cc: Muchun Song Cc: Michal Hocko Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/filemap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mm/filemap.c b/mm/filemap.c index 5c9d564317a5c..aa0e0fb046700 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -835,6 +835,7 @@ noinline int __add_to_page_cache_locked(struct page *page, XA_STATE(xas, &mapping->i_pages, offset); int huge = PageHuge(page); int error; + bool charged = false; VM_BUG_ON_PAGE(!PageLocked(page), page); VM_BUG_ON_PAGE(PageSwapBacked(page), page); @@ -848,6 +849,7 @@ noinline int __add_to_page_cache_locked(struct page *page, error = mem_cgroup_charge(page, current->mm, gfp); if (error) goto error; + charged = true; } gfp &= GFP_RECLAIM_MASK; @@ -896,6 +898,8 @@ noinline int __add_to_page_cache_locked(struct page *page, if (xas_error(&xas)) { error = xas_error(&xas); + if (charged) + mem_cgroup_uncharge(page); goto error; } -- GitLab From 49c6631d3b4f61a7b5bb0453a885a12bfa06ffd8 Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Thu, 4 Feb 2021 18:32:49 -0800 Subject: [PATCH 1016/1084] kasan: add explicit preconditions to kasan_report() Patch series "kasan: Fix metadata detection for KASAN_HW_TAGS", v5. With the introduction of KASAN_HW_TAGS, kasan_report() currently assumes that every location in memory has valid metadata associated. This is due to the fact that addr_has_metadata() returns always true. As a consequence of this, an invalid address (e.g. NULL pointer address) passed to kasan_report() when KASAN_HW_TAGS is enabled, leads to a kernel panic. Example below, based on arm64: BUG: KASAN: invalid-access in 0x0 Read at addr 0000000000000000 by task swapper/0/1 Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 Mem abort info: ESR = 0x96000004 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 Data abort info: ISV = 0, ISS = 0x00000004 CM = 0, WnR = 0 ... Call trace: mte_get_mem_tag+0x24/0x40 kasan_report+0x1a4/0x410 alsa_sound_last_init+0x8c/0xa4 do_one_initcall+0x50/0x1b0 kernel_init_freeable+0x1d4/0x23c kernel_init+0x14/0x118 ret_from_fork+0x10/0x34 Code: d65f03c0 9000f021 f9428021 b6cfff61 (d9600000) ---[ end trace 377c8bb45bdd3a1a ]--- hrtimer: interrupt took 48694256 ns note: swapper/0[1] exited with preempt_count 1 Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b SMP: stopping secondary CPUs Kernel Offset: 0x35abaf140000 from 0xffff800010000000 PHYS_OFFSET: 0x40000000 CPU features: 0x0a7e0152,61c0a030 Memory Limit: none ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]--- This series fixes the behavior of addr_has_metadata() that now returns true only when the address is valid. This patch (of 2): With the introduction of KASAN_HW_TAGS, kasan_report() accesses the metadata only when addr_has_metadata() succeeds. Add a comment to make sure that the preconditions to the function are explicitly clarified. Link: https://lkml.kernel.org/r/20210126134409.47894-1-vincenzo.frascino@arm.com Link: https://lkml.kernel.org/r/20210126134409.47894-2-vincenzo.frascino@arm.com Signed-off-by: Vincenzo Frascino Reviewed-by: Andrey Konovalov Cc: Andrey Ryabinin Cc: Alexander Potapenko Cc: Dmitry Vyukov Cc: Leon Romanovsky Cc: Andrey Konovalov Cc: Catalin Marinas Cc: Will Deacon Cc: Mark Rutland Cc: "Paul E . McKenney" Cc: Naresh Kamboju Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kasan.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/kasan.h b/include/linux/kasan.h index fe1ae73ff8b57..0aea9e2a2a01d 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -333,6 +333,13 @@ static inline void *kasan_reset_tag(const void *addr) return (void *)arch_kasan_reset_tag(addr); } +/** + * kasan_report - print a report about a bad memory access detected by KASAN + * @addr: address of the bad access + * @size: size of the bad access + * @is_write: whether the bad access is a write or a read + * @ip: instruction pointer for the accessibility check or the bad access itself + */ bool kasan_report(unsigned long addr, size_t size, bool is_write, unsigned long ip); -- GitLab From b99acdcbfe3c8394ddd8b8d89d9bae2bbba4a459 Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Thu, 4 Feb 2021 18:32:53 -0800 Subject: [PATCH 1017/1084] kasan: make addr_has_metadata() return true for valid addresses Currently, addr_has_metadata() returns true for every address. An invalid address (e.g. NULL) passed to the function when, KASAN_HW_TAGS is enabled, leads to a kernel panic. Make addr_has_metadata() return true for valid addresses only. Note: KASAN_HW_TAGS support for vmalloc will be added with a future patch. Link: https://lkml.kernel.org/r/20210126134409.47894-3-vincenzo.frascino@arm.com Fixes: 2e903b91479782b7 ("kasan, arm64: implement HW_TAGS runtime") Signed-off-by: Vincenzo Frascino Reviewed-by: Andrey Konovalov Cc: Andrey Ryabinin Cc: Alexander Potapenko Cc: Dmitry Vyukov Cc: Leon Romanovsky Cc: Catalin Marinas Cc: Mark Rutland Cc: Naresh Kamboju Cc: "Paul E . McKenney" Cc: Will Deacon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/kasan/kasan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index cc4d9e1d49b1d..8c706e7652f2b 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -209,7 +209,7 @@ bool check_memory_region(unsigned long addr, size_t size, bool write, static inline bool addr_has_metadata(const void *addr) { - return true; + return (is_vmalloc_addr(addr) || virt_addr_valid(addr)); } #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ -- GitLab From 28abcc963149e06d956d95a18a85f4ba26af746f Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 4 Feb 2021 18:32:57 -0800 Subject: [PATCH 1018/1084] ubsan: implement __ubsan_handle_alignment_assumption When building ARCH=mips 32r2el_defconfig with CONFIG_UBSAN_ALIGNMENT: ld.lld: error: undefined symbol: __ubsan_handle_alignment_assumption referenced by slab.h:557 (include/linux/slab.h:557) main.o:(do_initcalls) in archive init/built-in.a referenced by slab.h:448 (include/linux/slab.h:448) do_mounts_rd.o:(rd_load_image) in archive init/built-in.a referenced by slab.h:448 (include/linux/slab.h:448) do_mounts_rd.o:(identify_ramdisk_image) in archive init/built-in.a referenced 1579 more times Implement this for the kernel based on LLVM's handleAlignmentAssumptionImpl because the kernel is not linked against the compiler runtime. Link: https://github.com/ClangBuiltLinux/linux/issues/1245 Link: https://github.com/llvm/llvm-project/blob/llvmorg-11.0.1/compiler-rt/lib/ubsan/ubsan_handlers.cpp#L151-L190 Link: https://lkml.kernel.org/r/20210127224451.2587372-1-nathan@kernel.org Signed-off-by: Nathan Chancellor Acked-by: Kees Cook Reviewed-by: Nick Desaulniers Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/ubsan.c | 31 +++++++++++++++++++++++++++++++ lib/ubsan.h | 6 ++++++ 2 files changed, 37 insertions(+) diff --git a/lib/ubsan.c b/lib/ubsan.c index 3e3352f3d0da7..bec38c64d6a62 100644 --- a/lib/ubsan.c +++ b/lib/ubsan.c @@ -427,3 +427,34 @@ void __ubsan_handle_load_invalid_value(void *_data, void *val) ubsan_epilogue(); } EXPORT_SYMBOL(__ubsan_handle_load_invalid_value); + +void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr, + unsigned long align, + unsigned long offset); +void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr, + unsigned long align, + unsigned long offset) +{ + struct alignment_assumption_data *data = _data; + unsigned long real_ptr; + + if (suppress_report(&data->location)) + return; + + ubsan_prologue(&data->location, "alignment-assumption"); + + if (offset) + pr_err("assumption of %lu byte alignment (with offset of %lu byte) for pointer of type %s failed", + align, offset, data->type->type_name); + else + pr_err("assumption of %lu byte alignment for pointer of type %s failed", + align, data->type->type_name); + + real_ptr = ptr - offset; + pr_err("%saddress is %lu aligned, misalignment offset is %lu bytes", + offset ? "offset " : "", BIT(real_ptr ? __ffs(real_ptr) : 0), + real_ptr & (align - 1)); + + ubsan_epilogue(); +} +EXPORT_SYMBOL(__ubsan_handle_alignment_assumption); diff --git a/lib/ubsan.h b/lib/ubsan.h index 7b56c09473a98..9a0b71c5ff9fb 100644 --- a/lib/ubsan.h +++ b/lib/ubsan.h @@ -78,6 +78,12 @@ struct invalid_value_data { struct type_descriptor *type; }; +struct alignment_assumption_data { + struct source_location location; + struct source_location assumption_location; + struct type_descriptor *type; +}; + #if defined(CONFIG_ARCH_SUPPORTS_INT128) typedef __int128 s_max; typedef unsigned __int128 u_max; -- GitLab From e558464be982af2546229dcbef746d24e942abaa Mon Sep 17 00:00:00 2001 From: Muchun Song Date: Thu, 4 Feb 2021 18:33:00 -0800 Subject: [PATCH 1019/1084] mm: hugetlb: fix missing put_page in gather_surplus_pages() The VM_BUG_ON_PAGE avoids the generation of any code, even if that expression has side-effects when !CONFIG_DEBUG_VM. Link: https://lkml.kernel.org/r/20210126031009.96266-1-songmuchun@bytedance.com Fixes: e5dfacebe4a4 ("mm/hugetlb.c: just use put_page_testzero() instead of page_count()") Signed-off-by: Muchun Song Reviewed-by: Mike Kravetz Reviewed-by: Miaohe Lin Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/hugetlb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index d78111f0fa2cb..4bdb58ab14cbb 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2047,13 +2047,16 @@ static int gather_surplus_pages(struct hstate *h, long delta) /* Free the needed pages to the hugetlb pool */ list_for_each_entry_safe(page, tmp, &surplus_list, lru) { + int zeroed; + if ((--needed) < 0) break; /* * This page is now managed by the hugetlb allocator and has * no users -- drop the buddy allocator's reference. */ - VM_BUG_ON_PAGE(!put_page_testzero(page), page); + zeroed = put_page_testzero(page); + VM_BUG_ON_PAGE(!zeroed, page); enqueue_huge_page(h, page); } free: -- GitLab From 654eb3f2a009af1fc64b10442e559e0d1e50904a Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 4 Feb 2021 18:33:03 -0800 Subject: [PATCH 1020/1084] MAINTAINERS/.mailmap: use my @kernel.org address Use my @kernel.org for all points of contact so that I am always accessible. Link: https://lkml.kernel.org/r/20210126212730.2097108-1-nathan@kernel.org Signed-off-by: Nathan Chancellor Acked-by: Nick Desaulniers Acked-by: Miguel Ojeda Cc: Sedat Dilek Cc: Lukas Bulwahn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- .mailmap | 1 + MAINTAINERS | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 4105b5f80f4c6..a90952727bc8d 100644 --- a/.mailmap +++ b/.mailmap @@ -246,6 +246,7 @@ Morten Welinder Morten Welinder Morten Welinder Mythri P K +Nathan Chancellor Nguyen Anh Quynh Nicolas Ferre Nicolas Pitre diff --git a/MAINTAINERS b/MAINTAINERS index 2a0737dfca89b..667d03852191f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4304,7 +4304,7 @@ S: Maintained F: .clang-format CLANG/LLVM BUILD SUPPORT -M: Nathan Chancellor +M: Nathan Chancellor M: Nick Desaulniers L: clang-built-linux@googlegroups.com S: Supported -- GitLab From c4bed4b96918ff1d062ee81fdae4d207da4fa9b0 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 4 Feb 2021 23:27:06 +0800 Subject: [PATCH 1021/1084] x86/debug: Prevent data breakpoints on __per_cpu_offset When FSGSBASE is enabled, paranoid_entry() fetches the per-CPU GSBASE value via __per_cpu_offset or pcpu_unit_offsets. When a data breakpoint is set on __per_cpu_offset[cpu] (read-write operation), the specific CPU will be stuck in an infinite #DB loop. RCU will try to send an NMI to the specific CPU, but it is not working either since NMI also relies on paranoid_entry(). Which means it's undebuggable. Fixes: eaad981291ee3("x86/entry/64: Introduce the FIND_PERCPU_BASE macro") Signed-off-by: Lai Jiangshan Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210204152708.21308-1-jiangshanlai@gmail.com --- arch/x86/kernel/hw_breakpoint.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 6694c0f8e6c16..012ed82e5bd32 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -269,6 +269,20 @@ static inline bool within_cpu_entry(unsigned long addr, unsigned long end) CPU_ENTRY_AREA_TOTAL_SIZE)) return true; + /* + * When FSGSBASE is enabled, paranoid_entry() fetches the per-CPU + * GSBASE value via __per_cpu_offset or pcpu_unit_offsets. + */ +#ifdef CONFIG_SMP + if (within_area(addr, end, (unsigned long)__per_cpu_offset, + sizeof(unsigned long) * nr_cpu_ids)) + return true; +#else + if (within_area(addr, end, (unsigned long)&pcpu_unit_offsets, + sizeof(pcpu_unit_offsets))) + return true; +#endif + for_each_possible_cpu(cpu) { /* The original rw GDT is being used after load_direct_gdt() */ if (within_area(addr, end, (unsigned long)get_cpu_gdt_rw(cpu), -- GitLab From 3943abf2dbfae9ea4d2da05c1db569a0603f76da Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 4 Feb 2021 23:27:07 +0800 Subject: [PATCH 1022/1084] x86/debug: Prevent data breakpoints on cpu_dr7 local_db_save() is called at the start of exc_debug_kernel(), reads DR7 and disables breakpoints to prevent recursion. When running in a guest (X86_FEATURE_HYPERVISOR), local_db_save() reads the per-cpu variable cpu_dr7 to check whether a breakpoint is active or not before it accesses DR7. A data breakpoint on cpu_dr7 therefore results in infinite #DB recursion. Disallow data breakpoints on cpu_dr7 to prevent that. Fixes: 84b6a3491567a("x86/entry: Optimize local_db_save() for virt") Signed-off-by: Lai Jiangshan Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210204152708.21308-2-jiangshanlai@gmail.com --- arch/x86/kernel/hw_breakpoint.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 012ed82e5bd32..668a4a6533d92 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -307,6 +307,14 @@ static inline bool within_cpu_entry(unsigned long addr, unsigned long end) (unsigned long)&per_cpu(cpu_tlbstate, cpu), sizeof(struct tlb_state))) return true; + + /* + * When in guest (X86_FEATURE_HYPERVISOR), local_db_save() + * will read per-cpu cpu_dr7 before clear dr7 register. + */ + if (within_area(addr, end, (unsigned long)&per_cpu(cpu_dr7, cpu), + sizeof(cpu_dr7))) + return true; } return false; -- GitLab From 21b200d091826a83aafc95d847139b2b0582f6d1 Mon Sep 17 00:00:00 2001 From: Aurelien Aptel Date: Fri, 5 Feb 2021 15:42:48 +0100 Subject: [PATCH 1023/1084] cifs: report error instead of invalid when revalidating a dentry fails Assuming - //HOST/a is mounted on /mnt - //HOST/b is mounted on /mnt/b On a slow connection, running 'df' and killing it while it's processing /mnt/b can make cifs_get_inode_info() returns -ERESTARTSYS. This triggers the following chain of events: => the dentry revalidation fail => dentry is put and released => superblock associated with the dentry is put => /mnt/b is unmounted This patch makes cifs_d_revalidate() return the error instead of 0 (invalid) when cifs_revalidate_dentry() fails, except for ENOENT (file deleted) and ESTALE (file recreated). Signed-off-by: Aurelien Aptel Suggested-by: Shyam Prasad N Reviewed-by: Shyam Prasad N CC: stable@vger.kernel.org Signed-off-by: Steve French --- fs/cifs/dir.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 68900f1629bff..97ac363b5df16 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -737,6 +737,7 @@ static int cifs_d_revalidate(struct dentry *direntry, unsigned int flags) { struct inode *inode; + int rc; if (flags & LOOKUP_RCU) return -ECHILD; @@ -746,8 +747,25 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags) if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode))) CIFS_I(inode)->time = 0; /* force reval */ - if (cifs_revalidate_dentry(direntry)) - return 0; + rc = cifs_revalidate_dentry(direntry); + if (rc) { + cifs_dbg(FYI, "cifs_revalidate_dentry failed with rc=%d", rc); + switch (rc) { + case -ENOENT: + case -ESTALE: + /* + * Those errors mean the dentry is invalid + * (file was deleted or recreated) + */ + return 0; + default: + /* + * Otherwise some unexpected error happened + * report it as-is to VFS layer + */ + return rc; + } + } else { /* * If the inode wasn't known to be a dfs entry when -- GitLab From 4c7bcb51ae25f79e3733982e5d0cd8ce8640ddfc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 21 Dec 2020 19:56:47 +0100 Subject: [PATCH 1024/1084] genirq: Prevent [devm_]irq_alloc_desc from returning irq 0 Since commit a85a6c86c25b ("driver core: platform: Clarify that IRQ 0 is invalid"), having a linux-irq with number 0 will trigger a WARN() when calling platform_get_irq*() to retrieve that linux-irq. Since [devm_]irq_alloc_desc allocs a single irq and since irq 0 is not used on some systems, it can return 0, triggering that WARN(). This happens e.g. on Intel Bay Trail and Cherry Trail devices using the LPE audio engine for HDMI audio: 0 is an invalid IRQ number WARNING: CPU: 3 PID: 472 at drivers/base/platform.c:238 platform_get_irq_optional+0x108/0x180 Modules linked in: snd_hdmi_lpe_audio(+) ... Call Trace: platform_get_irq+0x17/0x30 hdmi_lpe_audio_probe+0x4a/0x6c0 [snd_hdmi_lpe_audio] ---[ end trace ceece38854223a0b ]--- Change the 'from' parameter passed to __[devm_]irq_alloc_descs() by the [devm_]irq_alloc_desc macros from 0 to 1, so that these macros will no longer return 0. Fixes: a85a6c86c25b ("driver core: platform: Clarify that IRQ 0 is invalid") Signed-off-by: Hans de Goede Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20201221185647.226146-1-hdegoede@redhat.com --- include/linux/irq.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/irq.h b/include/linux/irq.h index 4aeb1c4c7e07b..2efde6a79b7ee 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -928,7 +928,7 @@ int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from, __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE, NULL) #define irq_alloc_desc(node) \ - irq_alloc_descs(-1, 0, 1, node) + irq_alloc_descs(-1, 1, 1, node) #define irq_alloc_desc_at(at, node) \ irq_alloc_descs(at, at, 1, node) @@ -943,7 +943,7 @@ int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from, __devm_irq_alloc_descs(dev, irq, from, cnt, node, THIS_MODULE, NULL) #define devm_irq_alloc_desc(dev, node) \ - devm_irq_alloc_descs(dev, -1, 0, 1, node) + devm_irq_alloc_descs(dev, -1, 1, 1, node) #define devm_irq_alloc_desc_at(dev, at, node) \ devm_irq_alloc_descs(dev, at, at, 1, node) -- GitLab From 2452483d9546de1c540f330469dc4042ff089731 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 5 Feb 2021 23:28:29 +0100 Subject: [PATCH 1025/1084] Revert "lib: Restrict cpumask_local_spread to houskeeping CPUs" This reverts commit 1abdfe706a579a702799fce465bceb9fb01d407c. This change is broken and not solving any problem it claims to solve. Robin reported that cpumask_local_spread() now returns any cpu out of cpu_possible_mask in case that NOHZ_FULL is disabled (runtime or compile time). It can also return any offline or not-present CPU in the housekeeping mask. Before that it was returning a CPU out of online_cpu_mask. While the function is racy against CPU hotplug if the caller does not protect against it, the actual use cases are not caring much about it as they use it mostly as hint for: - the user space affinity hint which is unused by the kernel - memory node selection which is just suboptimal - network queue affinity which might fail but is handled gracefully But the occasional fail vs. hotplug is very different from returning anything from possible_cpu_mask which can have a large amount of offline CPUs obviously. The changelog of the commit claims: "The current implementation of cpumask_local_spread() does not respect the isolated CPUs, i.e., even if a CPU has been isolated for Real-Time task, it will return it to the caller for pinning of its IRQ threads. Having these unwanted IRQ threads on an isolated CPU adds up to a latency overhead." The only correct part of this changelog is: "The current implementation of cpumask_local_spread() does not respect the isolated CPUs." Everything else is just disjunct from reality. Reported-by: Robin Murphy Signed-off-by: Thomas Gleixner Cc: Nitesh Narayan Lal Cc: Marcelo Tosatti Cc: abelits@marvell.com Cc: davem@davemloft.net Link: https://lore.kernel.org/r/87y2g26tnt.fsf@nanos.tec.linutronix.de --- lib/cpumask.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/cpumask.c b/lib/cpumask.c index 35924025097b9..c3c76b8333846 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c @@ -6,7 +6,6 @@ #include #include #include -#include /** * cpumask_next - get the next cpu in a cpumask @@ -206,27 +205,22 @@ void __init free_bootmem_cpumask_var(cpumask_var_t mask) */ unsigned int cpumask_local_spread(unsigned int i, int node) { - int cpu, hk_flags; - const struct cpumask *mask; + int cpu; - hk_flags = HK_FLAG_DOMAIN | HK_FLAG_MANAGED_IRQ; - mask = housekeeping_cpumask(hk_flags); /* Wrap: we always want a cpu. */ - i %= cpumask_weight(mask); + i %= num_online_cpus(); if (node == NUMA_NO_NODE) { - for_each_cpu(cpu, mask) { + for_each_cpu(cpu, cpu_online_mask) if (i-- == 0) return cpu; - } } else { /* NUMA first. */ - for_each_cpu_and(cpu, cpumask_of_node(node), mask) { + for_each_cpu_and(cpu, cpumask_of_node(node), cpu_online_mask) if (i-- == 0) return cpu; - } - for_each_cpu(cpu, mask) { + for_each_cpu(cpu, cpu_online_mask) { /* Skip NUMA nodes, done above. */ if (cpumask_test_cpu(cpu, cpumask_of_node(node))) continue; -- GitLab From 6342adcaa683c2b705c24ed201dc11b35854c88d Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Wed, 3 Feb 2021 13:00:48 -0500 Subject: [PATCH 1026/1084] entry: Ensure trap after single-step on system call return Commit 299155244770 ("entry: Drop usage of TIF flags in the generic syscall code") introduced a bug on architectures using the generic syscall entry code, in which processes stopped by PTRACE_SYSCALL do not trap on syscall return after receiving a TIF_SINGLESTEP. The reason is that the meaning of TIF_SINGLESTEP flag is overloaded to cause the trap after a system call is executed, but since the above commit, the syscall call handler only checks for the SYSCALL_WORK flags on the exit work. Split the meaning of TIF_SINGLESTEP such that it only means single-step mode, and create a new type of SYSCALL_WORK to request a trap immediately after a syscall in single-step mode. In the current implementation, the SYSCALL_WORK flag shadows the TIF_SINGLESTEP flag for simplicity. Update x86 to flip this bit when a tracer enables single stepping. Fixes: 299155244770 ("entry: Drop usage of TIF flags in the generic syscall code") Suggested-by: Linus Torvalds Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Thomas Gleixner Tested-by: Kyle Huey Link: https://lore.kernel.org/r/87h7mtc9pr.fsf_-_@collabora.com --- arch/x86/include/asm/entry-common.h | 2 -- arch/x86/kernel/step.c | 10 ++++++++-- include/linux/entry-common.h | 1 + include/linux/thread_info.h | 2 ++ kernel/entry/common.c | 12 ++---------- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/asm/entry-common.h b/arch/x86/include/asm/entry-common.h index 6fe54b2813c13..2b87b191b3b84 100644 --- a/arch/x86/include/asm/entry-common.h +++ b/arch/x86/include/asm/entry-common.h @@ -43,8 +43,6 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs) } #define arch_check_user_regs arch_check_user_regs -#define ARCH_SYSCALL_EXIT_WORK (_TIF_SINGLESTEP) - static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, unsigned long ti_work) { diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index 60d2c3798ba28..0f3c307b37b3a 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c @@ -127,12 +127,17 @@ static int enable_single_step(struct task_struct *child) regs->flags |= X86_EFLAGS_TF; /* - * Always set TIF_SINGLESTEP - this guarantees that - * we single-step system calls etc.. This will also + * Always set TIF_SINGLESTEP. This will also * cause us to set TF when returning to user mode. */ set_tsk_thread_flag(child, TIF_SINGLESTEP); + /* + * Ensure that a trap is triggered once stepping out of a system + * call prior to executing any user instruction. + */ + set_task_syscall_work(child, SYSCALL_EXIT_TRAP); + oflags = regs->flags; /* Set TF on the kernel stack.. */ @@ -230,6 +235,7 @@ void user_disable_single_step(struct task_struct *child) /* Always clear TIF_SINGLESTEP... */ clear_tsk_thread_flag(child, TIF_SINGLESTEP); + clear_task_syscall_work(child, SYSCALL_EXIT_TRAP); /* But touch TF only if it was set by us.. */ if (test_and_clear_tsk_thread_flag(child, TIF_FORCED_TF)) diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h index ca86a00abe862..a104b298019ae 100644 --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h @@ -46,6 +46,7 @@ SYSCALL_WORK_SYSCALL_TRACE | \ SYSCALL_WORK_SYSCALL_AUDIT | \ SYSCALL_WORK_SYSCALL_USER_DISPATCH | \ + SYSCALL_WORK_SYSCALL_EXIT_TRAP | \ ARCH_SYSCALL_WORK_EXIT) /* diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index c8a974cead730..9b2158c69275e 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -43,6 +43,7 @@ enum syscall_work_bit { SYSCALL_WORK_BIT_SYSCALL_EMU, SYSCALL_WORK_BIT_SYSCALL_AUDIT, SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH, + SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP, }; #define SYSCALL_WORK_SECCOMP BIT(SYSCALL_WORK_BIT_SECCOMP) @@ -51,6 +52,7 @@ enum syscall_work_bit { #define SYSCALL_WORK_SYSCALL_EMU BIT(SYSCALL_WORK_BIT_SYSCALL_EMU) #define SYSCALL_WORK_SYSCALL_AUDIT BIT(SYSCALL_WORK_BIT_SYSCALL_AUDIT) #define SYSCALL_WORK_SYSCALL_USER_DISPATCH BIT(SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH) +#define SYSCALL_WORK_SYSCALL_EXIT_TRAP BIT(SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP) #endif #include diff --git a/kernel/entry/common.c b/kernel/entry/common.c index 6dd82be60df81..f9d491b17b78b 100644 --- a/kernel/entry/common.c +++ b/kernel/entry/common.c @@ -209,15 +209,9 @@ static void exit_to_user_mode_prepare(struct pt_regs *regs) lockdep_sys_exit(); } -#ifndef _TIF_SINGLESTEP -static inline bool report_single_step(unsigned long work) -{ - return false; -} -#else /* * If SYSCALL_EMU is set, then the only reason to report is when - * TIF_SINGLESTEP is set (i.e. PTRACE_SYSEMU_SINGLESTEP). This syscall + * SINGLESTEP is set (i.e. PTRACE_SYSEMU_SINGLESTEP). This syscall * instruction has been already reported in syscall_enter_from_user_mode(). */ static inline bool report_single_step(unsigned long work) @@ -225,10 +219,8 @@ static inline bool report_single_step(unsigned long work) if (work & SYSCALL_WORK_SYSCALL_EMU) return false; - return !!(current_thread_info()->flags & _TIF_SINGLESTEP); + return work & SYSCALL_WORK_SYSCALL_EXIT_TRAP; } -#endif - static void syscall_exit_work(struct pt_regs *regs, unsigned long work) { -- GitLab From 36a6c843fd0d8e02506681577e96dabd203dd8e8 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Fri, 5 Feb 2021 13:43:21 -0500 Subject: [PATCH 1027/1084] entry: Use different define for selector variable in SUD Michael Kerrisk suggested that, from an API perspective, it is a bad idea to share the PR_SYS_DISPATCH_ defines between the prctl operation and the selector variable. Therefore, define two new constants to be used by SUD's selector variable and update the corresponding documentation and test cases. While this changes the API syscall user dispatch has never been part of a Linux release, it will show up for the first time in 5.11. Suggested-by: Michael Kerrisk (man-pages) Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210205184321.2062251-1-krisman@collabora.com --- .../admin-guide/syscall-user-dispatch.rst | 4 ++-- include/uapi/linux/prctl.h | 3 +++ kernel/entry/syscall_user_dispatch.c | 4 ++-- .../syscall_user_dispatch/sud_benchmark.c | 8 +++++--- .../selftests/syscall_user_dispatch/sud_test.c | 14 ++++++++------ 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Documentation/admin-guide/syscall-user-dispatch.rst b/Documentation/admin-guide/syscall-user-dispatch.rst index a380d65157745..60314953c7284 100644 --- a/Documentation/admin-guide/syscall-user-dispatch.rst +++ b/Documentation/admin-guide/syscall-user-dispatch.rst @@ -70,8 +70,8 @@ trampoline code on the vDSO, that trampoline is never intercepted. [selector] is a pointer to a char-sized region in the process memory region, that provides a quick way to enable disable syscall redirection thread-wide, without the need to invoke the kernel directly. selector -can be set to PR_SYS_DISPATCH_ON or PR_SYS_DISPATCH_OFF. Any other -value should terminate the program with a SIGSYS. +can be set to SYSCALL_DISPATCH_FILTER_ALLOW or SYSCALL_DISPATCH_FILTER_BLOCK. +Any other value should terminate the program with a SIGSYS. Security Notes -------------- diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index 90deb41c8a346..667f1aed091c2 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -251,5 +251,8 @@ struct prctl_mm_map { #define PR_SET_SYSCALL_USER_DISPATCH 59 # define PR_SYS_DISPATCH_OFF 0 # define PR_SYS_DISPATCH_ON 1 +/* The control values for the user space selector when dispatch is enabled */ +# define SYSCALL_DISPATCH_FILTER_ALLOW 0 +# define SYSCALL_DISPATCH_FILTER_BLOCK 1 #endif /* _LINUX_PRCTL_H */ diff --git a/kernel/entry/syscall_user_dispatch.c b/kernel/entry/syscall_user_dispatch.c index b0338a5625d93..c240302f56e23 100644 --- a/kernel/entry/syscall_user_dispatch.c +++ b/kernel/entry/syscall_user_dispatch.c @@ -50,10 +50,10 @@ bool syscall_user_dispatch(struct pt_regs *regs) if (unlikely(__get_user(state, sd->selector))) do_exit(SIGSEGV); - if (likely(state == PR_SYS_DISPATCH_OFF)) + if (likely(state == SYSCALL_DISPATCH_FILTER_ALLOW)) return false; - if (state != PR_SYS_DISPATCH_ON) + if (state != SYSCALL_DISPATCH_FILTER_BLOCK) do_exit(SIGSYS); } diff --git a/tools/testing/selftests/syscall_user_dispatch/sud_benchmark.c b/tools/testing/selftests/syscall_user_dispatch/sud_benchmark.c index 6689f1183dbff..073a03702ff5e 100644 --- a/tools/testing/selftests/syscall_user_dispatch/sud_benchmark.c +++ b/tools/testing/selftests/syscall_user_dispatch/sud_benchmark.c @@ -22,6 +22,8 @@ # define PR_SET_SYSCALL_USER_DISPATCH 59 # define PR_SYS_DISPATCH_OFF 0 # define PR_SYS_DISPATCH_ON 1 +# define SYSCALL_DISPATCH_FILTER_ALLOW 0 +# define SYSCALL_DISPATCH_FILTER_BLOCK 1 #endif #ifdef __NR_syscalls @@ -55,8 +57,8 @@ unsigned long trapped_call_count = 0; unsigned long native_call_count = 0; char selector; -#define SYSCALL_BLOCK (selector = PR_SYS_DISPATCH_ON) -#define SYSCALL_UNBLOCK (selector = PR_SYS_DISPATCH_OFF) +#define SYSCALL_BLOCK (selector = SYSCALL_DISPATCH_FILTER_BLOCK) +#define SYSCALL_UNBLOCK (selector = SYSCALL_DISPATCH_FILTER_ALLOW) #define CALIBRATION_STEP 100000 #define CALIBRATE_TO_SECS 5 @@ -170,7 +172,7 @@ int main(void) syscall(MAGIC_SYSCALL_1); #ifdef TEST_BLOCKED_RETURN - if (selector == PR_SYS_DISPATCH_OFF) { + if (selector == SYSCALL_DISPATCH_FILTER_ALLOW) { fprintf(stderr, "Failed to return with selector blocked.\n"); exit(-1); } diff --git a/tools/testing/selftests/syscall_user_dispatch/sud_test.c b/tools/testing/selftests/syscall_user_dispatch/sud_test.c index 6498b050ef89b..b5d592d4099e8 100644 --- a/tools/testing/selftests/syscall_user_dispatch/sud_test.c +++ b/tools/testing/selftests/syscall_user_dispatch/sud_test.c @@ -18,6 +18,8 @@ # define PR_SET_SYSCALL_USER_DISPATCH 59 # define PR_SYS_DISPATCH_OFF 0 # define PR_SYS_DISPATCH_ON 1 +# define SYSCALL_DISPATCH_FILTER_ALLOW 0 +# define SYSCALL_DISPATCH_FILTER_BLOCK 1 #endif #ifndef SYS_USER_DISPATCH @@ -30,8 +32,8 @@ # define MAGIC_SYSCALL_1 (0xff00) /* Bad Linux syscall number */ #endif -#define SYSCALL_DISPATCH_ON(x) ((x) = 1) -#define SYSCALL_DISPATCH_OFF(x) ((x) = 0) +#define SYSCALL_DISPATCH_ON(x) ((x) = SYSCALL_DISPATCH_FILTER_BLOCK) +#define SYSCALL_DISPATCH_OFF(x) ((x) = SYSCALL_DISPATCH_FILTER_ALLOW) /* Test Summary: * @@ -56,7 +58,7 @@ TEST_SIGNAL(dispatch_trigger_sigsys, SIGSYS) { - char sel = 0; + char sel = SYSCALL_DISPATCH_FILTER_ALLOW; struct sysinfo info; int ret; @@ -79,7 +81,7 @@ TEST_SIGNAL(dispatch_trigger_sigsys, SIGSYS) TEST(bad_prctl_param) { - char sel = 0; + char sel = SYSCALL_DISPATCH_FILTER_ALLOW; int op; /* Invalid op */ @@ -220,7 +222,7 @@ TEST_SIGNAL(bad_selector, SIGSYS) sigset_t mask; struct sysinfo info; - glob_sel = 0; + glob_sel = SYSCALL_DISPATCH_FILTER_ALLOW; nr_syscalls_emulated = 0; si_code = 0; si_errno = 0; @@ -288,7 +290,7 @@ TEST(direct_dispatch_range) { int ret = 0; struct sysinfo info; - char sel = 0; + char sel = SYSCALL_DISPATCH_FILTER_ALLOW; /* * Instead of calculating libc addresses; allow the entire -- GitLab From 816ef8d7a2c4182e19bc06ab65751cb9e3951e94 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 5 Feb 2021 11:31:31 +0100 Subject: [PATCH 1028/1084] x86/efi: Remove EFI PGD build time checks With CONFIG_X86_5LEVEL, CONFIG_UBSAN and CONFIG_UBSAN_UNSIGNED_OVERFLOW enabled, clang fails the build with x86_64-linux-ld: arch/x86/platform/efi/efi_64.o: in function `efi_sync_low_kernel_mappings': efi_64.c:(.text+0x22c): undefined reference to `__compiletime_assert_354' which happens due to -fsanitize=unsigned-integer-overflow being enabled: -fsanitize=unsigned-integer-overflow: Unsigned integer overflow, where the result of an unsigned integer computation cannot be represented in its type. Unlike signed integer overflow, this is not undefined behavior, but it is often unintentional. This sanitizer does not check for lossy implicit conversions performed before such a computation (see -fsanitize=implicit-conversion). and that fires when the (intentional) EFI_VA_START/END defines overflow an unsigned long, leading to the assertion expressions not getting optimized away (on GCC they do)... However, those checks are superfluous: the runtime services mapping code already makes sure the ranges don't overshoot EFI_VA_END as the EFI mapping range is hardcoded. On each runtime services call, it is switched to the EFI-specific PGD and even if mappings manage to escape that last PGD, this won't remain unnoticed for long. So rip them out. See https://github.com/ClangBuiltLinux/linux/issues/256 for more info. Reported-by: Arnd Bergmann Signed-off-by: Borislav Petkov Reviewed-by: Nathan Chancellor Acked-by: Ard Biesheuvel Tested-by: Nick Desaulniers Tested-by: Nathan Chancellor Link: http://lkml.kernel.org/r/20210107223424.4135538-1-arnd@kernel.org --- arch/x86/platform/efi/efi_64.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index e1e8d4e3a2139..8efd003540cae 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -115,31 +115,12 @@ void efi_sync_low_kernel_mappings(void) pud_t *pud_k, *pud_efi; pgd_t *efi_pgd = efi_mm.pgd; - /* - * We can share all PGD entries apart from the one entry that - * covers the EFI runtime mapping space. - * - * Make sure the EFI runtime region mappings are guaranteed to - * only span a single PGD entry and that the entry also maps - * other important kernel regions. - */ - MAYBE_BUILD_BUG_ON(pgd_index(EFI_VA_END) != pgd_index(MODULES_END)); - MAYBE_BUILD_BUG_ON((EFI_VA_START & PGDIR_MASK) != - (EFI_VA_END & PGDIR_MASK)); - pgd_efi = efi_pgd + pgd_index(PAGE_OFFSET); pgd_k = pgd_offset_k(PAGE_OFFSET); num_entries = pgd_index(EFI_VA_END) - pgd_index(PAGE_OFFSET); memcpy(pgd_efi, pgd_k, sizeof(pgd_t) * num_entries); - /* - * As with PGDs, we share all P4D entries apart from the one entry - * that covers the EFI runtime mapping space. - */ - BUILD_BUG_ON(p4d_index(EFI_VA_END) != p4d_index(MODULES_END)); - BUILD_BUG_ON((EFI_VA_START & P4D_MASK) != (EFI_VA_END & P4D_MASK)); - pgd_efi = efi_pgd + pgd_index(EFI_VA_END); pgd_k = pgd_offset_k(EFI_VA_END); p4d_efi = p4d_offset(pgd_efi, 0); -- GitLab From 92bf22614b21a2706f4993b278017e437f7785b3 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 7 Feb 2021 13:57:38 -0800 Subject: [PATCH 1029/1084] Linux 5.11-rc7 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 70035c522bd3e..ade44ac4cc2ff 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 11 SUBLEVEL = 0 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc7 NAME = Kleptomaniac Octopus # *DOCUMENTATION* -- GitLab From 45a2702ce10993eda7a5b12690294782d565519c Mon Sep 17 00:00:00 2001 From: Sathyanarayana Nujella Date: Fri, 5 Feb 2021 09:14:28 -0800 Subject: [PATCH 1030/1084] ASoC: rt5682: Fix panic in rt5682_jack_detect_handler happening during system shutdown During Coldboot stress tests, system encountered the following panic. Panic logs depicts rt5682_i2c_shutdown() happened first and then later jack detect handler workqueue function triggered. This situation causes panic as rt5682_i2c_shutdown() resets codec. Fix this panic by cancelling all jack detection delayed work. Panic log: [ 20.936124] sof_pci_shutdown [ 20.940248] snd_sof_device_shutdown [ 20.945023] snd_sof_shutdown [ 21.126849] rt5682_i2c_shutdown [ 21.286053] rt5682_jack_detect_handler [ 21.291235] BUG: kernel NULL pointer dereference, address: 000000000000037c [ 21.299302] #PF: supervisor read access in kernel mode [ 21.305254] #PF: error_code(0x0000) - not-present page [ 21.311218] PGD 0 P4D 0 [ 21.314155] Oops: 0000 [#1] PREEMPT SMP NOPTI [ 21.319206] CPU: 2 PID: 123 Comm: kworker/2:3 Tainted: G U 5.4.68 #10 [ 21.333687] ACPI: Preparing to enter system sleep state S5 [ 21.337669] Workqueue: events_power_efficient rt5682_jack_detect_handler [snd_soc_rt5682] [ 21.337671] RIP: 0010:rt5682_jack_detect_handler+0x6c/0x279 [snd_soc_rt5682] Fixes: a50067d4f3c1d ('ASoC: rt5682: split i2c driver into separate module') Signed-off-by: Jairaj Arava Signed-off-by: Sathyanarayana Nujella Reviewed-by: Pierre-Louis Bossart Reviewed-by: Shuming Fan Signed-off-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20210205171428.2344210-1-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682-i2c.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/rt5682-i2c.c b/sound/soc/codecs/rt5682-i2c.c index 37d13120f5ba8..93c1603b42f10 100644 --- a/sound/soc/codecs/rt5682-i2c.c +++ b/sound/soc/codecs/rt5682-i2c.c @@ -273,6 +273,9 @@ static void rt5682_i2c_shutdown(struct i2c_client *client) { struct rt5682_priv *rt5682 = i2c_get_clientdata(client); + cancel_delayed_work_sync(&rt5682->jack_detect_work); + cancel_delayed_work_sync(&rt5682->jd_check_work); + rt5682_reset(rt5682); } -- GitLab From 9037c3bde65d339017ef41d81cb58069ffc321d4 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Mon, 8 Feb 2021 18:38:57 +0800 Subject: [PATCH 1031/1084] ASoC: SOF: debug: Fix a potential issue on string buffer termination The function simple_write_to_buffer() doesn't add string termination at the end of buf, we need to handle it on our own. This change refers to the function tokenize_input() in debug.c and the function sof_dfsentry_trace_filter_write() in trace.c. Fixes: 091c12e1f50c ("ASoC: SOF: debug: add new debugfs entries for IPC flood test") Reviewed-by: Kai Vehmanen Signed-off-by: Hui Wang Link: https://lore.kernel.org/r/20210208103857.75705-1-hui.wang@canonical.com Signed-off-by: Mark Brown --- sound/soc/sof/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c index 30213a1beaaa2..715a374b33cfb 100644 --- a/sound/soc/sof/debug.c +++ b/sound/soc/sof/debug.c @@ -352,7 +352,7 @@ static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer, char *string; int ret; - string = kzalloc(count, GFP_KERNEL); + string = kzalloc(count+1, GFP_KERNEL); if (!string) return -ENOMEM; -- GitLab From 6e4ea8aace02479186b3fdaab48d7acfe06d8715 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Sun, 7 Feb 2021 23:06:57 +0530 Subject: [PATCH 1032/1084] ASoC: audio-graph: Rename functions needed for export Following functions are renamed for a better global visibility. graph_card_probe() --> audio_graph_card_probe() graph_parse_of() --> audio_graph_parse_of() graph_remove() --> audio_graph_remove() [exported as well] The references of these are updated in audio graph and Tegra audio graph card drivers. Signed-off-by: Sameer Pujar Cc: Kuninori Morimoto Acked-by: Kuninori Morimoto Link: https://lore.kernel.org/r/1612719418-5858-2-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- include/sound/graph_card.h | 6 ++++-- sound/soc/generic/audio-graph-card.c | 17 +++++++++-------- sound/soc/tegra/tegra_audio_graph_card.c | 6 +++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/sound/graph_card.h b/include/sound/graph_card.h index bbb5a137855c1..013784467bec3 100644 --- a/include/sound/graph_card.h +++ b/include/sound/graph_card.h @@ -9,8 +9,10 @@ #include -int graph_card_probe(struct snd_soc_card *card); +int audio_graph_card_probe(struct snd_soc_card *card); -int graph_parse_of(struct asoc_simple_priv *priv, struct device *dev); +int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev); + +int audio_graph_remove(struct platform_device *pdev); #endif /* __GRAPH_CARD_H */ diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 16a04a6788282..8c5cdcdc8713c 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -532,7 +532,7 @@ static int graph_for_each_link(struct asoc_simple_priv *priv, static void graph_get_dais_count(struct asoc_simple_priv *priv, struct link_info *li); -int graph_parse_of(struct asoc_simple_priv *priv, struct device *dev) +int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev) { struct snd_soc_card *card = simple_priv_to_card(priv); struct link_info li; @@ -608,7 +608,7 @@ int graph_parse_of(struct asoc_simple_priv *priv, struct device *dev) return ret; } -EXPORT_SYMBOL_GPL(graph_parse_of); +EXPORT_SYMBOL_GPL(audio_graph_parse_of); static int graph_count_noml(struct asoc_simple_priv *priv, struct device_node *cpu_ep, @@ -705,7 +705,7 @@ static void graph_get_dais_count(struct asoc_simple_priv *priv, li->link, li->dais, li->conf); } -int graph_card_probe(struct snd_soc_card *card) +int audio_graph_card_probe(struct snd_soc_card *card) { struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card); int ret; @@ -720,7 +720,7 @@ int graph_card_probe(struct snd_soc_card *card) return 0; } -EXPORT_SYMBOL_GPL(graph_card_probe); +EXPORT_SYMBOL_GPL(audio_graph_card_probe); static int graph_probe(struct platform_device *pdev) { @@ -736,20 +736,21 @@ static int graph_probe(struct platform_device *pdev) card = simple_priv_to_card(priv); card->dapm_widgets = graph_dapm_widgets; card->num_dapm_widgets = ARRAY_SIZE(graph_dapm_widgets); - card->probe = graph_card_probe; + card->probe = audio_graph_card_probe; if (of_device_get_match_data(dev)) priv->dpcm_selectable = 1; - return graph_parse_of(priv, dev); + return audio_graph_parse_of(priv, dev); } -static int graph_remove(struct platform_device *pdev) +int audio_graph_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); return asoc_simple_clean_reference(card); } +EXPORT_SYMBOL_GPL(audio_graph_remove); static const struct of_device_id graph_of_match[] = { { .compatible = "audio-graph-card", }, @@ -766,7 +767,7 @@ static struct platform_driver graph_card = { .of_match_table = graph_of_match, }, .probe = graph_probe, - .remove = graph_remove, + .remove = audio_graph_remove, }; module_platform_driver(graph_card); diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c index 9e43f16f93361..121e5721f61d8 100644 --- a/sound/soc/tegra/tegra_audio_graph_card.c +++ b/sound/soc/tegra/tegra_audio_graph_card.c @@ -184,7 +184,7 @@ static int tegra_audio_graph_card_probe(struct snd_soc_card *card) return PTR_ERR(priv->clk_plla_out0); } - return graph_card_probe(card); + return audio_graph_card_probe(card); } static int tegra_audio_graph_probe(struct platform_device *pdev) @@ -201,12 +201,12 @@ static int tegra_audio_graph_probe(struct platform_device *pdev) card->probe = tegra_audio_graph_card_probe; - /* graph_parse_of() depends on below */ + /* audio_graph_parse_of() depends on below */ card->component_chaining = 1; priv->simple.ops = &tegra_audio_graph_ops; priv->simple.force_dpcm = 1; - return graph_parse_of(&priv->simple, dev); + return audio_graph_parse_of(&priv->simple, dev); } static const struct tegra_audio_cdata tegra210_data = { -- GitLab From 0d7475d2a5a90127a2f87961b99bcd8f95694dd9 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Sun, 7 Feb 2021 23:06:58 +0530 Subject: [PATCH 1033/1084] ASoC: tegra: Add driver remove() callback There is cleanup required, related to release of phandles, during driver removal and hence point remove callback to audio_graph_remove(). Fixes: 202e2f774543 ("ASoC: tegra: Add audio graph based card driver") Depends-on: "ASoC: audio-graph: Rename functions needed for export" Signed-off-by: Sameer Pujar Acked-by: Kuninori Morimoto Link: https://lore.kernel.org/r/1612719418-5858-3-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_audio_graph_card.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c index 121e5721f61d8..ddedf18adde18 100644 --- a/sound/soc/tegra/tegra_audio_graph_card.c +++ b/sound/soc/tegra/tegra_audio_graph_card.c @@ -2,7 +2,7 @@ // // tegra_audio_graph_card.c - Audio Graph based Tegra Machine Driver // -// Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2020-2021 NVIDIA CORPORATION. All rights reserved. #include #include @@ -243,6 +243,7 @@ static struct platform_driver tegra_audio_graph_card = { .of_match_table = graph_of_tegra_match, }, .probe = tegra_audio_graph_probe, + .remove = audio_graph_remove, }; module_platform_driver(tegra_audio_graph_card); -- GitLab From 28785f548d18e6d52785a1172e5c176784ce74cd Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Thu, 4 Feb 2021 09:42:55 +0800 Subject: [PATCH 1034/1084] ASoC: codec: hdmi-codec: Support IEC958 encoded PCM format Existing hdmi-codec driver only support standard pcm format. Support of IEC958 encoded format pass from ALSA IEC958 plugin is needed so that the IEC958 encoded data can be streamed to the HDMI chip. Signed-off-by: Sia Jee Heng Link: https://lore.kernel.org/r/20210204014258.10197-2-jee.heng.sia@intel.com Signed-off-by: Mark Brown --- include/sound/hdmi-codec.h | 5 +++++ sound/soc/codecs/hdmi-codec.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h index b55970859a13c..4b3a1d374b904 100644 --- a/include/sound/hdmi-codec.h +++ b/include/sound/hdmi-codec.h @@ -34,6 +34,11 @@ struct hdmi_codec_daifmt { unsigned int frame_clk_inv:1; unsigned int bit_clk_master:1; unsigned int frame_clk_master:1; + /* bit_fmt could be standard PCM format or + * IEC958 encoded format. ALSA IEC958 plugin will pass + * IEC958_SUBFRAME format to the underneath driver. + */ + snd_pcm_format_t bit_fmt; }; /* diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 0f3ac22f2cf8e..422539f933deb 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -489,6 +489,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, hp.sample_rate = params_rate(params); hp.channels = params_channels(params); + cf->bit_fmt = params_format(params); return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, cf, &hp); } @@ -617,7 +618,8 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = { SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) -- GitLab From 1c5f6e0714c16e3ad8732e49e07082772dcc6f87 Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Thu, 4 Feb 2021 09:42:58 +0800 Subject: [PATCH 1035/1084] ASoC: Intel: KMB: Support IEC958 encoded PCM format Support ALSA IEC958 plugin for KeemBay I2S driver. Bit manipulation needed as IEC958 format supported by ADV7511 HDMI chip is not compatible with the ALSA IEC958 plugin format. Signed-off-by: Sia Jee Heng Link: https://lore.kernel.org/r/20210204014258.10197-5-jee.heng.sia@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/keembay/kmb_platform.c | 73 +++++++++++++++++++++++++- sound/soc/intel/keembay/kmb_platform.h | 1 + 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/keembay/kmb_platform.c b/sound/soc/intel/keembay/kmb_platform.c index 4961ba89c1100..0fd1e8f62c89f 100644 --- a/sound/soc/intel/keembay/kmb_platform.c +++ b/sound/soc/intel/keembay/kmb_platform.c @@ -5,6 +5,7 @@ // Intel KeemBay Platform driver. // +#include #include #include #include @@ -39,7 +40,8 @@ static const struct snd_pcm_hardware kmb_pcm_hardware = { .rate_max = 48000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, + SNDRV_PCM_FMTBIT_S32_LE | + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE, .channels_min = 2, .channels_max = 2, .buffer_bytes_max = BUFFER_BYTES_MAX, @@ -50,6 +52,50 @@ static const struct snd_pcm_hardware kmb_pcm_hardware = { .fifo_size = 16, }; +/* + * Convert to ADV7511 HDMI hardware format. + * ADV7511 HDMI chip need parity bit replaced by block start bit and + * with the preamble bits left out. + * ALSA IEC958 subframe format: + * bit 0-3 = preamble (0x8 = block start) + * 4-7 = AUX (=0) + * 8-27 = audio data (without AUX if 24bit sample) + * 28 = validity + * 29 = user data + * 30 = channel status + * 31 = parity + * + * ADV7511 IEC958 subframe format: + * bit 0-23 = audio data + * 24 = validity + * 25 = user data + * 26 = channel status + * 27 = block start + * 28-31 = 0 + * MSB to LSB bit reverse by software as hardware not supporting it. + */ +static void hdmi_reformat_iec958(struct snd_pcm_runtime *runtime, + struct kmb_i2s_info *kmb_i2s, + unsigned int tx_ptr) +{ + u32(*buf)[2] = (void *)runtime->dma_area; + unsigned long temp; + u32 i, j, sample; + + for (i = 0; i < kmb_i2s->fifo_th; i++) { + j = 0; + do { + temp = buf[tx_ptr][j]; + /* Replace parity with block start*/ + assign_bit(31, &temp, (BIT(3) & temp)); + sample = bitrev32(temp); + buf[tx_ptr][j] = sample << 4; + j++; + } while (j < 2); + tx_ptr++; + } +} + static unsigned int kmb_pcm_tx_fn(struct kmb_i2s_info *kmb_i2s, struct snd_pcm_runtime *runtime, unsigned int tx_ptr, bool *period_elapsed) @@ -65,6 +111,8 @@ static unsigned int kmb_pcm_tx_fn(struct kmb_i2s_info *kmb_i2s, writel(((u16(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0)); writel(((u16(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0)); } else { + if (kmb_i2s->iec958_fmt) + hdmi_reformat_iec958(runtime, kmb_i2s, tx_ptr); writel(((u32(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0)); writel(((u32(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0)); } @@ -235,6 +283,7 @@ static int kmb_pcm_trigger(struct snd_soc_component *component, kmb_i2s->tx_substream = NULL; else kmb_i2s->rx_substream = NULL; + kmb_i2s->iec958_fmt = false; break; default: return -EINVAL; @@ -549,6 +598,9 @@ static int kmb_dai_hw_params(struct snd_pcm_substream *substream, kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; break; + case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: + kmb_i2s->iec958_fmt = true; + fallthrough; case SNDRV_PCM_FORMAT_S32_LE: config->data_width = 32; kmb_i2s->ccr = 0x10; @@ -686,6 +738,24 @@ static struct snd_soc_dai_ops kmb_dai_ops = { .set_fmt = kmb_set_dai_fmt, }; +static struct snd_soc_dai_driver intel_kmb_hdmi_dai[] = { + { + .name = "intel_kmb_hdmi_i2s", + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE), + }, + .ops = &kmb_dai_ops, + .probe = kmb_probe, + }, +}; + static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = { { .name = "intel_kmb_i2s", @@ -740,6 +810,7 @@ static struct snd_soc_dai_driver intel_kmb_tdm_dai[] = { static const struct of_device_id kmb_plat_of_match[] = { { .compatible = "intel,keembay-i2s", .data = &intel_kmb_i2s_dai}, + { .compatible = "intel,keembay-hdmi-i2s", .data = &intel_kmb_hdmi_dai}, { .compatible = "intel,keembay-tdm", .data = &intel_kmb_tdm_dai}, {} }; diff --git a/sound/soc/intel/keembay/kmb_platform.h b/sound/soc/intel/keembay/kmb_platform.h index 67234caee8142..29be2cd84ddb3 100644 --- a/sound/soc/intel/keembay/kmb_platform.h +++ b/sound/soc/intel/keembay/kmb_platform.h @@ -150,6 +150,7 @@ struct kmb_i2s_info { struct snd_pcm_substream *rx_substream; unsigned int tx_ptr; unsigned int rx_ptr; + bool iec958_fmt; }; #endif /* KMB_PLATFORM_H_ */ -- GitLab From d5e16dc5fdad09d7b3133b6aaea7848bfb518e04 Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Thu, 4 Feb 2021 09:42:57 +0800 Subject: [PATCH 1036/1084] ASoC: Intel, Keembay-i2s: Add hdmi-i2s compatible string Add intel,keembay-hdmi-i2s compatible string to support the HDMI interface. Signed-off-by: Sia Jee Heng Link: https://lore.kernel.org/r/20210204014258.10197-4-jee.heng.sia@intel.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml index dba25c33f0b03..6f71294909a5f 100644 --- a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml @@ -18,6 +18,7 @@ properties: enum: - intel,keembay-i2s - intel,keembay-tdm + - intel,keembay-hdmi-i2s "#sound-dai-cells": const: 0 -- GitLab From 38d89a564847048c0f6fe53a829d15edb4f21da3 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sat, 6 Feb 2021 23:58:49 +0100 Subject: [PATCH 1037/1084] ASoC: fsl: constify static snd_soc_dai_ops structs The only usage of these is to assign their address to the 'ops' field in the snd_soc_dai_driver struct, which is a pointer to const. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Acked-by: Shengjiu Wang Link: https://lore.kernel.org/r/20210206225849.51071-1-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_easrc.c | 2 +- sound/soc/fsl/fsl_micfil.c | 2 +- sound/soc/fsl/fsl_xcvr.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index 60951a8aabd30..636a702f37a62 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -1530,7 +1530,7 @@ static int fsl_easrc_hw_free(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops fsl_easrc_dai_ops = { +static const struct snd_soc_dai_ops fsl_easrc_dai_ops = { .startup = fsl_easrc_startup, .trigger = fsl_easrc_trigger, .hw_params = fsl_easrc_hw_params, diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 8aedf6590b289..5935af2e5ff47 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -381,7 +381,7 @@ static int fsl_micfil_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, return ret; } -static struct snd_soc_dai_ops fsl_micfil_dai_ops = { +static const struct snd_soc_dai_ops fsl_micfil_dai_ops = { .startup = fsl_micfil_startup, .trigger = fsl_micfil_trigger, .hw_params = fsl_micfil_hw_params, diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index dd228b421e2c5..6dd0a5fcd4556 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -857,7 +857,7 @@ static struct snd_kcontrol_new fsl_xcvr_tx_ctls[] = { }, }; -static struct snd_soc_dai_ops fsl_xcvr_dai_ops = { +static const struct snd_soc_dai_ops fsl_xcvr_dai_ops = { .prepare = fsl_xcvr_prepare, .startup = fsl_xcvr_startup, .shutdown = fsl_xcvr_shutdown, -- GitLab From 40bd053bc8e18b68e877bd4cdea1b6938ddf5fdd Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 6 Feb 2021 11:27:53 -0300 Subject: [PATCH 1038/1084] ASoC: fsl_esai: Remove unused 'imx' field The 'imx' field is not used anywhere, so get rid of it. Signed-off-by: Fabio Estevam Acked-by: Shengjiu Wang Link: https://lore.kernel.org/r/20210206142753.536459-1-festevam@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index bac9f059c9fc6..08056fa0a0fa5 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -23,11 +23,9 @@ /** * struct fsl_esai_soc_data - soc specific data - * @imx: for imx platform * @reset_at_xrun: flags for enable reset operaton */ struct fsl_esai_soc_data { - bool imx; bool reset_at_xrun; }; @@ -86,17 +84,14 @@ struct fsl_esai { }; static struct fsl_esai_soc_data fsl_esai_vf610 = { - .imx = false, .reset_at_xrun = true, }; static struct fsl_esai_soc_data fsl_esai_imx35 = { - .imx = true, .reset_at_xrun = true, }; static struct fsl_esai_soc_data fsl_esai_imx6ull = { - .imx = true, .reset_at_xrun = false, }; -- GitLab From bad929b81ce25bba1c3e9d91848ffdc166974256 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 23 Jan 2021 14:09:57 +0000 Subject: [PATCH 1039/1084] ASoC: codec/ingenic: Depend on MACH_INGENIC No need to show the options to build Ingenic-specific drivers on all MIPS kernel configurations if Ingenic SoCs support is not enabled. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20210123140958.12895-2-paul@crapouillou.net Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index df34b3b3bb143..9e2a732bae276 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -712,7 +712,7 @@ config SND_SOC_CX2072X Enable support for Conexant CX20721 and CX20723 codec chips. config SND_SOC_JZ4740_CODEC - depends on MIPS || COMPILE_TEST + depends on MACH_INGENIC || COMPILE_TEST depends on OF select REGMAP_MMIO tristate "Ingenic JZ4740 internal CODEC" @@ -724,7 +724,7 @@ config SND_SOC_JZ4740_CODEC will be called snd-soc-jz4740-codec. config SND_SOC_JZ4725B_CODEC - depends on MIPS || COMPILE_TEST + depends on MACH_INGENIC || COMPILE_TEST depends on OF select REGMAP tristate "Ingenic JZ4725B internal CODEC" @@ -736,7 +736,7 @@ config SND_SOC_JZ4725B_CODEC will be called snd-soc-jz4725b-codec. config SND_SOC_JZ4770_CODEC - depends on MIPS || COMPILE_TEST + depends on MACH_INGENIC || COMPILE_TEST depends on OF select REGMAP tristate "Ingenic JZ4770 internal CODEC" -- GitLab From d9cd22e9c87cb61488d00f7279cfb2abf5238879 Mon Sep 17 00:00:00 2001 From: Christophe Branchereau Date: Sat, 23 Jan 2021 14:09:58 +0000 Subject: [PATCH 1040/1084] ASoC: codec: Add driver for JZ4760 internal codec Add support for the internal codec found in the JZ4760 SoC from Ingenic. Signed-off-by: Christophe Branchereau Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20210123140958.12895-3-paul@crapouillou.net Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 13 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/jz4760.c | 889 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 904 insertions(+) create mode 100644 sound/soc/codecs/jz4760.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 9e2a732bae276..f9ce7bb654a5e 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -104,6 +104,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_ISABELLE imply SND_SOC_JZ4740_CODEC imply SND_SOC_JZ4725B_CODEC + imply SND_SOC_JZ4760_CODEC imply SND_SOC_JZ4770_CODEC imply SND_SOC_LM4857 imply SND_SOC_LM49453 @@ -735,6 +736,18 @@ config SND_SOC_JZ4725B_CODEC This driver can also be built as a module. If so, the module will be called snd-soc-jz4725b-codec. +config SND_SOC_JZ4760_CODEC + depends on MACH_INGENIC || COMPILE_TEST + depends on OF + select REGMAP + tristate "Ingenic JZ4760 internal CODEC" + help + Enable support for the internal CODEC found in the JZ4760 SoC + from Ingenic. + + This driver can also be built as a module. If so, the module + will be called snd-soc-jz4760-codec. + config SND_SOC_JZ4770_CODEC depends on MACH_INGENIC || COMPILE_TEST depends on OF diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 628b0c9b3e2a2..d5c7eb3544a57 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -101,6 +101,7 @@ snd-soc-inno-rk3036-objs := inno_rk3036.o snd-soc-isabelle-objs := isabelle.o snd-soc-jz4740-codec-objs := jz4740.o snd-soc-jz4725b-codec-objs := jz4725b.o +snd-soc-jz4760-codec-objs := jz4760.o snd-soc-jz4770-codec-objs := jz4770.o snd-soc-l3-objs := l3.o snd-soc-lm4857-objs := lm4857.o @@ -416,6 +417,7 @@ obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_JZ4725B_CODEC) += snd-soc-jz4725b-codec.o +obj-$(CONFIG_SND_SOC_JZ4760_CODEC) += snd-soc-jz4760-codec.o obj-$(CONFIG_SND_SOC_JZ4770_CODEC) += snd-soc-jz4770-codec.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o diff --git a/sound/soc/codecs/jz4760.c b/sound/soc/codecs/jz4760.c new file mode 100644 index 0000000000000..e8f28ccc145a2 --- /dev/null +++ b/sound/soc/codecs/jz4760.c @@ -0,0 +1,889 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Ingenic JZ4760 CODEC driver +// +// Copyright (C) 2021, Christophe Branchereau +// Copyright (C) 2021, Paul Cercueil + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define ICDC_RGADW_OFFSET 0x00 +#define ICDC_RGDATA_OFFSET 0x04 + +/* ICDC internal register access control register(RGADW) */ +#define ICDC_RGADW_RGWR BIT(16) +#define ICDC_RGADW_RGADDR_MASK GENMASK(14, 8) +#define ICDC_RGADW_RGDIN_MASK GENMASK(7, 0) + +/* ICDC internal register data output register (RGDATA)*/ +#define ICDC_RGDATA_IRQ BIT(8) +#define ICDC_RGDATA_RGDOUT_MASK GENMASK(7, 0) + +/* Internal register space, accessed through regmap */ +enum { + JZ4760_CODEC_REG_SR, + JZ4760_CODEC_REG_AICR, + JZ4760_CODEC_REG_CR1, + JZ4760_CODEC_REG_CR2, + JZ4760_CODEC_REG_CR3, + JZ4760_CODEC_REG_CR4, + JZ4760_CODEC_REG_CCR1, + JZ4760_CODEC_REG_CCR2, + JZ4760_CODEC_REG_PMR1, + JZ4760_CODEC_REG_PMR2, + JZ4760_CODEC_REG_ICR, + JZ4760_CODEC_REG_IFR, + JZ4760_CODEC_REG_GCR1, + JZ4760_CODEC_REG_GCR2, + JZ4760_CODEC_REG_GCR3, + JZ4760_CODEC_REG_GCR4, + JZ4760_CODEC_REG_GCR5, + JZ4760_CODEC_REG_GCR6, + JZ4760_CODEC_REG_GCR7, + JZ4760_CODEC_REG_GCR8, + JZ4760_CODEC_REG_GCR9, + JZ4760_CODEC_REG_AGC1, + JZ4760_CODEC_REG_AGC2, + JZ4760_CODEC_REG_AGC3, + JZ4760_CODEC_REG_AGC4, + JZ4760_CODEC_REG_AGC5, + JZ4760_CODEC_REG_MIX1, + JZ4760_CODEC_REG_MIX2, +}; + +#define REG_AICR_DAC_ADWL_MASK GENMASK(7, 6) +#define REG_AICR_DAC_SERIAL BIT(3) +#define REG_AICR_DAC_I2S BIT(1) + +#define REG_AICR_ADC_ADWL_MASK GENMASK(5, 4) + +#define REG_AICR_ADC_SERIAL BIT(2) +#define REG_AICR_ADC_I2S BIT(0) + +#define REG_CR1_HP_LOAD BIT(7) +#define REG_CR1_HP_MUTE BIT(5) +#define REG_CR1_LO_MUTE_OFFSET 4 +#define REG_CR1_BTL_MUTE_OFFSET 3 +#define REG_CR1_OUTSEL_OFFSET 0 +#define REG_CR1_OUTSEL_MASK GENMASK(1, REG_CR1_OUTSEL_OFFSET) + +#define REG_CR2_DAC_MONO BIT(7) +#define REG_CR2_DAC_MUTE BIT(5) +#define REG_CR2_DAC_NOMAD BIT(1) +#define REG_CR2_DAC_RIGHT_ONLY BIT(0) + +#define REG_CR3_ADC_INSEL_OFFSET 2 +#define REG_CR3_ADC_INSEL_MASK GENMASK(3, REG_CR3_ADC_INSEL_OFFSET) +#define REG_CR3_MICSTEREO_OFFSET 1 +#define REG_CR3_MICDIFF_OFFSET 0 + +#define REG_CR4_ADC_HPF_OFFSET 7 +#define REG_CR4_ADC_RIGHT_ONLY BIT(0) + +#define REG_CCR1_CRYSTAL_MASK GENMASK(3, 0) + +#define REG_CCR2_DAC_FREQ_MASK GENMASK(7, 4) +#define REG_CCR2_ADC_FREQ_MASK GENMASK(3, 0) + +#define REG_PMR1_SB BIT(7) +#define REG_PMR1_SB_SLEEP BIT(6) +#define REG_PMR1_SB_AIP_OFFSET 5 +#define REG_PMR1_SB_LINE_OFFSET 4 +#define REG_PMR1_SB_MIC1_OFFSET 3 +#define REG_PMR1_SB_MIC2_OFFSET 2 +#define REG_PMR1_SB_BYPASS_OFFSET 1 +#define REG_PMR1_SB_MICBIAS_OFFSET 0 + +#define REG_PMR2_SB_ADC_OFFSET 4 +#define REG_PMR2_SB_HP_OFFSET 3 +#define REG_PMR2_SB_BTL_OFFSET 2 +#define REG_PMR2_SB_LOUT_OFFSET 1 +#define REG_PMR2_SB_DAC_OFFSET 0 + +#define REG_ICR_INT_FORM_MASK GENMASK(7, 6) +#define REG_ICR_ALL_MASK GENMASK(5, 0) +#define REG_ICR_JACK_MASK BIT(5) +#define REG_ICR_SCMC_MASK BIT(4) +#define REG_ICR_RUP_MASK BIT(3) +#define REG_ICR_RDO_MASK BIT(2) +#define REG_ICR_GUP_MASK BIT(1) +#define REG_ICR_GDO_MASK BIT(0) + +#define REG_IFR_ALL_MASK GENMASK(5, 0) +#define REG_IFR_JACK BIT(6) +#define REG_IFR_JACK_EVENT BIT(5) +#define REG_IFR_SCMC BIT(4) +#define REG_IFR_RUP BIT(3) +#define REG_IFR_RDO BIT(2) +#define REG_IFR_GUP BIT(1) +#define REG_IFR_GDO BIT(0) + +#define REG_GCR_GAIN_OFFSET 0 +#define REG_GCR_GAIN_MAX 0x1f + +#define REG_GCR_RL BIT(7) + +#define REG_GCR_GIM1_MASK GENMASK(5, 3) +#define REG_GCR_GIM2_MASK GENMASK(2, 0) +#define REG_GCR_GIM_GAIN_MAX 7 + +#define REG_AGC1_EN BIT(7) +#define REG_AGC1_TARGET_MASK GENMASK(5, 2) + +#define REG_AGC2_NG_THR_MASK GENMASK(6, 4) +#define REG_AGC2_HOLD_MASK GENMASK(3, 0) + +#define REG_AGC3_ATK_MASK GENMASK(7, 4) +#define REG_AGC3_DCY_MASK GENMASK(3, 0) + +#define REG_AGC4_AGC_MAX_MASK GENMASK(4, 0) + +#define REG_AGC5_AGC_MIN_MASK GENMASK(4, 0) + +#define REG_MIX1_MIX_REC_MASK GENMASK(7, 6) +#define REG_MIX1_GIMIX_MASK GENMASK(4, 0) + +#define REG_MIX2_DAC_MIX_MASK GENMASK(7, 6) +#define REG_MIX2_GOMIX_MASK GENMASK(4, 0) + +/* codec private data */ +struct jz_codec { + struct device *dev; + struct regmap *regmap; + void __iomem *base; + struct clk *clk; +}; + +static int jz4760_codec_set_bias_level(struct snd_soc_component *codec, + enum snd_soc_bias_level level) +{ + struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); + struct regmap *regmap = jz_codec->regmap; + + switch (level) { + case SND_SOC_BIAS_PREPARE: + /* Reset all interrupt flags. */ + regmap_write(regmap, JZ4760_CODEC_REG_IFR, REG_IFR_ALL_MASK); + + regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB); + msleep(250); + regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP); + msleep(400); + break; + case SND_SOC_BIAS_STANDBY: + regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP); + regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB); + break; + default: + break; + } + + return 0; +} + +static int jz4760_codec_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *codec = dai->component; + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); + int ret; + + /* + * SYSCLK output from the codec to the AIC is required to keep the + * DMA transfer going during playback when all audible outputs have + * been disabled. + */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = snd_soc_dapm_force_enable_pin(dapm, "SYSCLK"); + return 0; +} + +static void jz4760_codec_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *codec = dai->component; + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + snd_soc_dapm_disable_pin(dapm, "SYSCLK"); +} + + +static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_soc_component *codec = dai->component; + int ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) + snd_soc_component_force_bias_level(codec, SND_SOC_BIAS_ON); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + /* do nothing */ + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int jz4760_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction) +{ + struct snd_soc_component *codec = dai->component; + struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); + unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP; + unsigned int val, reg; + int change, err; + + change = snd_soc_component_update_bits(codec, JZ4760_CODEC_REG_CR2, + REG_CR2_DAC_MUTE, + mute ? REG_CR2_DAC_MUTE : 0); + if (change == 1) { + regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_PMR2, &val); + + if (val & BIT(REG_PMR2_SB_DAC_OFFSET)) + return 1; + + err = regmap_read_poll_timeout(jz_codec->regmap, + JZ4760_CODEC_REG_IFR, + val, val & gain_bit, + 1000, 1 * USEC_PER_SEC); + if (err) { + dev_err(jz_codec->dev, + "Timeout while setting digital mute: %d", err); + return err; + } + + /* clear GUP/GDO flag */ + regmap_write(jz_codec->regmap, JZ4760_CODEC_REG_IFR, gain_bit); + } + + regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_CR2, ®); + + return 0; +} + +/* unit: 0.01dB */ +static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 100); +static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0); +static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 100); +static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0); + +/* Unconditional controls. */ +static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = { + /* record gain control */ + SOC_DOUBLE_R_TLV("PCM Capture Volume", + JZ4760_CODEC_REG_GCR9, JZ4760_CODEC_REG_GCR8, + REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 0, adc_tlv), + + SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume", + JZ4760_CODEC_REG_GCR4, JZ4760_CODEC_REG_GCR3, + REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv), + + SOC_SINGLE("High-Pass Filter Capture Switch", + JZ4760_CODEC_REG_CR4, + REG_CR4_ADC_HPF_OFFSET, 1, 0), +}; + +static const struct snd_kcontrol_new jz4760_codec_pcm_playback_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Volume", + .info = snd_soc_info_volsw, + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ + | SNDRV_CTL_ELEM_ACCESS_READWRITE, + .tlv.p = dac_tlv, + .get = snd_soc_dapm_get_volsw, + .put = snd_soc_dapm_put_volsw, + .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR6, + JZ4760_CODEC_REG_GCR5, + REG_GCR_GAIN_OFFSET, + REG_GCR_GAIN_MAX, 1), + }, +}; + +static const struct snd_kcontrol_new jz4760_codec_hp_playback_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Volume", + .info = snd_soc_info_volsw, + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ + | SNDRV_CTL_ELEM_ACCESS_READWRITE, + .tlv.p = out_tlv, + .get = snd_soc_dapm_get_volsw, + .put = snd_soc_dapm_put_volsw, + .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR2, + JZ4760_CODEC_REG_GCR1, + REG_GCR_GAIN_OFFSET, + REG_GCR_GAIN_MAX, 1), + }, +}; + +static int hpout_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm); + struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); + unsigned int val; + int err; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* unmute HP */ + regmap_clear_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1, + REG_CR1_HP_MUTE); + break; + + case SND_SOC_DAPM_POST_PMU: + /* wait for ramp-up complete (RUP) */ + err = regmap_read_poll_timeout(jz_codec->regmap, + JZ4760_CODEC_REG_IFR, + val, val & REG_IFR_RUP, + 1000, 1 * USEC_PER_SEC); + if (err) { + dev_err(jz_codec->dev, "RUP timeout: %d", err); + return err; + } + + /* clear RUP flag */ + regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR, + REG_IFR_RUP); + + break; + + case SND_SOC_DAPM_POST_PMD: + /* mute HP */ + regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1, + REG_CR1_HP_MUTE); + + err = regmap_read_poll_timeout(jz_codec->regmap, + JZ4760_CODEC_REG_IFR, + val, val & REG_IFR_RDO, + 1000, 1 * USEC_PER_SEC); + if (err) { + dev_err(jz_codec->dev, "RDO timeout: %d", err); + return err; + } + + /* clear RDO flag */ + regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR, + REG_IFR_RDO); + + break; + } + + return 0; +} + +static const char * const jz4760_codec_hp_texts[] = { + "PCM", "Line In", "Mic 1", "Mic 2" +}; + +static const unsigned int jz4760_codec_hp_values[] = { 3, 2, 0, 1 }; + +static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_hp_enum, + JZ4760_CODEC_REG_CR1, + REG_CR1_OUTSEL_OFFSET, + REG_CR1_OUTSEL_MASK >> REG_CR1_OUTSEL_OFFSET, + jz4760_codec_hp_texts, + jz4760_codec_hp_values); +static const struct snd_kcontrol_new jz4760_codec_hp_source = + SOC_DAPM_ENUM("Route", jz4760_codec_hp_enum); + +static const char * const jz4760_codec_cap_texts[] = { + "Line In", "Mic 1", "Mic 2" +}; + +static const unsigned int jz4760_codec_cap_values[] = { 2, 0, 1 }; + +static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_cap_enum, + JZ4760_CODEC_REG_CR3, + REG_CR3_ADC_INSEL_OFFSET, + REG_CR3_ADC_INSEL_MASK >> REG_CR3_ADC_INSEL_OFFSET, + jz4760_codec_cap_texts, + jz4760_codec_cap_values); +static const struct snd_kcontrol_new jz4760_codec_cap_source = + SOC_DAPM_ENUM("Route", jz4760_codec_cap_enum); + +static const struct snd_kcontrol_new jz4760_codec_mic_controls[] = { + SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4760_CODEC_REG_CR3, + REG_CR3_MICSTEREO_OFFSET, 1, 0), +}; + +static const struct snd_kcontrol_new jz4760_codec_line_out_switch = + SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1, + REG_CR1_LO_MUTE_OFFSET, 0, 0); +static const struct snd_kcontrol_new jz4760_codec_btl_out_switch = + SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1, + REG_CR1_BTL_MUTE_OFFSET, 0, 0); + +static const struct snd_soc_dapm_widget jz4760_codec_dapm_widgets[] = { + SND_SOC_DAPM_PGA_E("HP Out", JZ4760_CODEC_REG_PMR2, + REG_PMR2_SB_HP_OFFSET, 1, NULL, 0, hpout_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SWITCH("Line Out", JZ4760_CODEC_REG_PMR2, + REG_PMR2_SB_LOUT_OFFSET, 1, + &jz4760_codec_line_out_switch), + + SND_SOC_DAPM_SWITCH("BTL Out", JZ4760_CODEC_REG_PMR2, + REG_PMR2_SB_BTL_OFFSET, 1, + &jz4760_codec_btl_out_switch), + + SND_SOC_DAPM_PGA("Line In", JZ4760_CODEC_REG_PMR1, + REG_PMR1_SB_LINE_OFFSET, 1, NULL, 0), + + SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0, + &jz4760_codec_hp_source), + + SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0, + &jz4760_codec_cap_source), + + SND_SOC_DAPM_PGA("Mic 1", JZ4760_CODEC_REG_PMR1, + REG_PMR1_SB_MIC1_OFFSET, 1, NULL, 0), + + SND_SOC_DAPM_PGA("Mic 2", JZ4760_CODEC_REG_PMR1, + REG_PMR1_SB_MIC2_OFFSET, 1, NULL, 0), + + SND_SOC_DAPM_PGA("Mic Diff", JZ4760_CODEC_REG_CR3, + REG_CR3_MICDIFF_OFFSET, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0, + jz4760_codec_mic_controls, + ARRAY_SIZE(jz4760_codec_mic_controls)), + + SND_SOC_DAPM_PGA("Line In Bypass", JZ4760_CODEC_REG_PMR1, + REG_PMR1_SB_BYPASS_OFFSET, 1, NULL, 0), + + SND_SOC_DAPM_ADC("ADC", "Capture", JZ4760_CODEC_REG_PMR2, + REG_PMR2_SB_ADC_OFFSET, 1), + + SND_SOC_DAPM_DAC("DAC", "Playback", JZ4760_CODEC_REG_PMR2, + REG_PMR2_SB_DAC_OFFSET, 1), + + SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0, + jz4760_codec_pcm_playback_controls, + ARRAY_SIZE(jz4760_codec_pcm_playback_controls)), + + SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0, + jz4760_codec_hp_playback_controls, + ARRAY_SIZE(jz4760_codec_hp_playback_controls)), + + SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4760_CODEC_REG_PMR1, + REG_PMR1_SB_MICBIAS_OFFSET, 1, NULL, 0), + + SND_SOC_DAPM_INPUT("MIC1P"), + SND_SOC_DAPM_INPUT("MIC1N"), + SND_SOC_DAPM_INPUT("MIC2P"), + SND_SOC_DAPM_INPUT("MIC2N"), + + SND_SOC_DAPM_INPUT("LLINEIN"), + SND_SOC_DAPM_INPUT("RLINEIN"), + + SND_SOC_DAPM_OUTPUT("LHPOUT"), + SND_SOC_DAPM_OUTPUT("RHPOUT"), + + SND_SOC_DAPM_OUTPUT("LOUT"), + SND_SOC_DAPM_OUTPUT("ROUT"), + + SND_SOC_DAPM_OUTPUT("BTLP"), + SND_SOC_DAPM_OUTPUT("BTLN"), + + SND_SOC_DAPM_OUTPUT("SYSCLK"), +}; + +/* Unconditional routes. */ +static const struct snd_soc_dapm_route jz4760_codec_dapm_routes[] = { + { "Mic 1", NULL, "MIC1P" }, + { "Mic Diff", NULL, "MIC1N" }, + { "Mic 1", NULL, "Mic Diff" }, + { "Mic 2", NULL, "MIC2P" }, + { "Mic Diff", NULL, "MIC2N" }, + { "Mic 2", NULL, "Mic Diff" }, + + { "Line In", NULL, "LLINEIN" }, + { "Line In", NULL, "RLINEIN" }, + + { "Mic", "Stereo Capture Switch", "Mic 1" }, + { "Mic", "Stereo Capture Switch", "Mic 2" }, + { "Headphones Source", "Mic 1", "Mic" }, + { "Headphones Source", "Mic 2", "Mic" }, + { "Capture Source", "Mic 1", "Mic" }, + { "Capture Source", "Mic 2", "Mic" }, + + { "Capture Source", "Line In", "Line In" }, + { "Capture Source", "Mic 1", "Mic 1" }, + { "Capture Source", "Mic 2", "Mic 2" }, + { "ADC", NULL, "Capture Source" }, + + { "Line In Bypass", NULL, "Line In" }, + + { "Headphones Source", "Mic 1", "Mic 1" }, + { "Headphones Source", "Mic 2", "Mic 2" }, + { "Headphones Source", "Line In", "Line In Bypass" }, + { "Headphones Source", "PCM", "Headphones Playback" }, + { "HP Out", NULL, "Headphones Source" }, + + { "LHPOUT", NULL, "HP Out" }, + { "RHPOUT", NULL, "HP Out" }, + { "Line Out", "Switch", "HP Out" }, + + { "LOUT", NULL, "Line Out" }, + { "ROUT", NULL, "Line Out" }, + { "BTL Out", "Switch", "Line Out" }, + + { "BTLP", NULL, "BTL Out"}, + { "BTLN", NULL, "BTL Out"}, + + { "PCM Playback", "Volume", "DAC" }, + { "Headphones Playback", "Volume", "PCM Playback" }, + + { "SYSCLK", NULL, "DAC" }, +}; + +static void jz4760_codec_codec_init_regs(struct snd_soc_component *codec) +{ + struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); + struct regmap *regmap = jz_codec->regmap; + + /* Collect updates for later sending. */ + regcache_cache_only(regmap, true); + + /* default Amp output to PCM */ + regmap_set_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_OUTSEL_MASK); + + /* Disable stereo mic */ + regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3, + BIT(REG_CR3_MICSTEREO_OFFSET)); + + /* Set mic 1 as default source for ADC */ + regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3, + REG_CR3_ADC_INSEL_MASK); + + /* ADC/DAC: serial + i2s */ + regmap_set_bits(regmap, JZ4760_CODEC_REG_AICR, + REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S | + REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S); + + /* The generated IRQ is a high level */ + regmap_clear_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK); + regmap_update_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_ALL_MASK, + REG_ICR_JACK_MASK | REG_ICR_RUP_MASK | + REG_ICR_RDO_MASK | REG_ICR_GUP_MASK | + REG_ICR_GDO_MASK); + + /* 12M oscillator */ + regmap_clear_bits(regmap, JZ4760_CODEC_REG_CCR1, REG_CCR1_CRYSTAL_MASK); + + /* 0: 16ohm/220uF, 1: 10kohm/1uF */ + regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_HP_LOAD); + + /* default to NOMAD */ + regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR2, + REG_CR2_DAC_NOMAD); + + /* disable automatic gain */ + regmap_clear_bits(regmap, JZ4760_CODEC_REG_AGC1, REG_AGC1_EN); + + /* Independent L/R DAC gain control */ + regmap_clear_bits(regmap, JZ4760_CODEC_REG_GCR5, + REG_GCR_RL); + + /* Send collected updates. */ + regcache_cache_only(regmap, false); + regcache_sync(regmap); +} + +static int jz4760_codec_codec_probe(struct snd_soc_component *codec) +{ + struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); + + clk_prepare_enable(jz_codec->clk); + + jz4760_codec_codec_init_regs(codec); + + return 0; +} + +static void jz4760_codec_codec_remove(struct snd_soc_component *codec) +{ + struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); + + clk_disable_unprepare(jz_codec->clk); +} + +static const struct snd_soc_component_driver jz4760_codec_soc_codec_dev = { + .probe = jz4760_codec_codec_probe, + .remove = jz4760_codec_codec_remove, + .set_bias_level = jz4760_codec_set_bias_level, + .controls = jz4760_codec_snd_controls, + .num_controls = ARRAY_SIZE(jz4760_codec_snd_controls), + .dapm_widgets = jz4760_codec_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(jz4760_codec_dapm_widgets), + .dapm_routes = jz4760_codec_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(jz4760_codec_dapm_routes), + .suspend_bias_off = 1, + .use_pmdown_time = 1, +}; + +static const unsigned int jz4760_codec_sample_rates[] = { + 96000, 48000, 44100, 32000, + 24000, 22050, 16000, 12000, + 11025, 9600, 8000, +}; + +static int jz4760_codec_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component); + unsigned int rate, bit_width; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + bit_width = 0; + break; + case SNDRV_PCM_FORMAT_S18_3LE: + bit_width = 1; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + bit_width = 2; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + bit_width = 3; + break; + default: + return -EINVAL; + } + + for (rate = 0; rate < ARRAY_SIZE(jz4760_codec_sample_rates); rate++) { + if (jz4760_codec_sample_rates[rate] == params_rate(params)) + break; + } + + if (rate == ARRAY_SIZE(jz4760_codec_sample_rates)) + return -EINVAL; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR, + REG_AICR_DAC_ADWL_MASK, + FIELD_PREP(REG_AICR_DAC_ADWL_MASK, bit_width)); + regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2, + REG_CCR2_DAC_FREQ_MASK, + FIELD_PREP(REG_CCR2_DAC_FREQ_MASK, rate)); + } else { + regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR, + REG_AICR_ADC_ADWL_MASK, + FIELD_PREP(REG_AICR_ADC_ADWL_MASK, bit_width)); + regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2, + REG_CCR2_ADC_FREQ_MASK, + FIELD_PREP(REG_CCR2_ADC_FREQ_MASK, rate)); + } + + return 0; +} + +static const struct snd_soc_dai_ops jz4760_codec_dai_ops = { + .startup = jz4760_codec_startup, + .shutdown = jz4760_codec_shutdown, + .hw_params = jz4760_codec_hw_params, + .trigger = jz4760_codec_pcm_trigger, + .mute_stream = jz4760_codec_mute_stream, + .no_capture_mute = 1, +}; + +#define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S18_3LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_3LE) + +static struct snd_soc_dai_driver jz4760_codec_dai = { + .name = "jz4760-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = JZ_CODEC_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = JZ_CODEC_FORMATS, + }, + .ops = &jz4760_codec_dai_ops, +}; + +static bool jz4760_codec_volatile(struct device *dev, unsigned int reg) +{ + return reg == JZ4760_CODEC_REG_SR || reg == JZ4760_CODEC_REG_IFR; +} + +static bool jz4760_codec_writeable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case JZ4760_CODEC_REG_SR: + return false; + default: + return true; + } +} + +static int jz4760_codec_io_wait(struct jz_codec *codec) +{ + u32 reg; + + return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg, + !(reg & ICDC_RGADW_RGWR), + 1000, 1 * USEC_PER_SEC); +} + +static int jz4760_codec_reg_read(void *context, unsigned int reg, + unsigned int *val) +{ + struct jz_codec *codec = context; + unsigned int i; + u32 tmp; + int ret; + + ret = jz4760_codec_io_wait(codec); + if (ret) + return ret; + + tmp = readl(codec->base + ICDC_RGADW_OFFSET); + tmp &= ~ICDC_RGADW_RGADDR_MASK; + tmp |= FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg); + writel(tmp, codec->base + ICDC_RGADW_OFFSET); + + /* wait 6+ cycles */ + for (i = 0; i < 6; i++) + *val = readl(codec->base + ICDC_RGDATA_OFFSET) & + ICDC_RGDATA_RGDOUT_MASK; + + return 0; +} + +static int jz4760_codec_reg_write(void *context, unsigned int reg, + unsigned int val) +{ + struct jz_codec *codec = context; + int ret; + + ret = jz4760_codec_io_wait(codec); + if (ret) + return ret; + + writel(ICDC_RGADW_RGWR | FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg) | val, + codec->base + ICDC_RGADW_OFFSET); + + ret = jz4760_codec_io_wait(codec); + if (ret) + return ret; + + return 0; +} + +static const u8 jz4760_codec_reg_defaults[] = { + 0x00, 0xFC, 0x1B, 0x20, 0x00, 0x80, 0x00, 0x00, + 0xFF, 0x1F, 0x3F, 0x00, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x07, 0x44, + 0x1F, 0x00, 0x00, 0x00 +}; + +static struct regmap_config jz4760_codec_regmap_config = { + .reg_bits = 7, + .val_bits = 8, + + .max_register = JZ4760_CODEC_REG_MIX2, + .volatile_reg = jz4760_codec_volatile, + .writeable_reg = jz4760_codec_writeable, + + .reg_read = jz4760_codec_reg_read, + .reg_write = jz4760_codec_reg_write, + + .reg_defaults_raw = jz4760_codec_reg_defaults, + .num_reg_defaults_raw = ARRAY_SIZE(jz4760_codec_reg_defaults), + .cache_type = REGCACHE_FLAT, +}; + +static int jz4760_codec_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct jz_codec *codec; + int ret; + + codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL); + if (!codec) + return -ENOMEM; + + codec->dev = dev; + + codec->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(codec->base)) { + ret = PTR_ERR(codec->base); + dev_err(dev, "Failed to ioremap mmio memory: %d\n", ret); + return ret; + } + + codec->regmap = devm_regmap_init(dev, NULL, codec, + &jz4760_codec_regmap_config); + if (IS_ERR(codec->regmap)) + return PTR_ERR(codec->regmap); + + codec->clk = devm_clk_get(dev, "aic"); + if (IS_ERR(codec->clk)) + return PTR_ERR(codec->clk); + + platform_set_drvdata(pdev, codec); + + ret = devm_snd_soc_register_component(dev, &jz4760_codec_soc_codec_dev, + &jz4760_codec_dai, 1); + if (ret) { + dev_err(dev, "Failed to register codec: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct of_device_id jz4760_codec_of_matches[] = { + { .compatible = "ingenic,jz4760-codec", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, jz4760_codec_of_matches); + +static struct platform_driver jz4760_codec_driver = { + .probe = jz4760_codec_probe, + .driver = { + .name = "jz4760-codec", + .of_match_table = jz4760_codec_of_matches, + }, +}; +module_platform_driver(jz4760_codec_driver); + +MODULE_DESCRIPTION("JZ4760 SoC internal codec driver"); +MODULE_AUTHOR("Christophe Branchereau "); +MODULE_AUTHOR("Paul Cercueil "); +MODULE_LICENSE("GPL v2"); -- GitLab From 45a90d4aba1781aa382d4aeedebcac7cc78e1927 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 23 Jan 2021 14:09:56 +0000 Subject: [PATCH 1041/1084] ASoC: Add compatible strings for JZ4760(B) SoC Add the ingenic,jz4760b-codec and ingenic,jz4760-codec compatible strings. In the process, convert the previous compatible strings to use an enum instead. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20210123140958.12895-1-paul@crapouillou.net Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/ingenic,codec.yaml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/ingenic,codec.yaml b/Documentation/devicetree/bindings/sound/ingenic,codec.yaml index eb4be86464bb4..97d5f3819b276 100644 --- a/Documentation/devicetree/bindings/sound/ingenic,codec.yaml +++ b/Documentation/devicetree/bindings/sound/ingenic,codec.yaml @@ -15,9 +15,14 @@ properties: compatible: oneOf: - - const: ingenic,jz4770-codec - - const: ingenic,jz4725b-codec - - const: ingenic,jz4740-codec + - enum: + - ingenic,jz4770-codec + - ingenic,jz4760-codec + - ingenic,jz4725b-codec + - ingenic,jz4740-codec + - items: + - const: ingenic,jz4760b-codec + - const: ingenic,jz4760-codec reg: maxItems: 1 -- GitLab From 8ade6d8b02b1ead741bd4f6c42921035caab6560 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 20 Jan 2021 22:49:56 +0100 Subject: [PATCH 1042/1084] ASoC: Intel: Add DMI quirk table to soc_intel_is_byt_cr() Some Bay Trail systems: 1. Use a non CR version of the Bay Trail SoC 2. Contain at least 6 interrupt resources so that the platform_get_resource(pdev, IORESOURCE_IRQ, 5) check to workaround non CR systems which list their IPC IRQ at index 0 despite being non CR does not work 3. Despite 1. and 2. still have their IPC IRQ at index 0 rather then 5 Add a DMI quirk table to check for the few known models with this issue, so that the right IPC IRQ index is used on these systems. Reviewed-by: Andy Shevchenko Acked-by: Pierre-Louis Bossart Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20210120214957.140232-5-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-intel-quirks.h | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sound/soc/intel/common/soc-intel-quirks.h b/sound/soc/intel/common/soc-intel-quirks.h index b07df3059926d..a93987ab7f4d7 100644 --- a/sound/soc/intel/common/soc-intel-quirks.h +++ b/sound/soc/intel/common/soc-intel-quirks.h @@ -11,6 +11,7 @@ #if IS_ENABLED(CONFIG_X86) +#include #include #include #include @@ -38,12 +39,36 @@ SOC_INTEL_IS_CPU(cml, KABYLAKE_L); static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) { + /* + * List of systems which: + * 1. Use a non CR version of the Bay Trail SoC + * 2. Contain at least 6 interrupt resources so that the + * platform_get_resource(pdev, IORESOURCE_IRQ, 5) check below + * succeeds + * 3. Despite 1. and 2. still have their IPC IRQ at index 0 rather then 5 + * + * This needs to be here so that it can be shared between the SST and + * SOF drivers. We rely on the compiler to optimize this out in files + * where soc_intel_is_byt_cr is not used. + */ + static const struct dmi_system_id force_bytcr_table[] = { + { /* Lenovo Yoga Tablet 2 series */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "YOGATablet2"), + }, + }, + {} + }; struct device *dev = &pdev->dev; int status = 0; if (!soc_intel_is_byt()) return false; + if (dmi_check_system(force_bytcr_table)) + return true; + if (iosf_mbi_available()) { u32 bios_status; -- GitLab From 9a87fc1e061900e81ab13d823e85012a78849244 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 20 Jan 2021 22:49:57 +0100 Subject: [PATCH 1043/1084] ASoC: Intel: bytcr_wm5102: Add machine driver for BYT/WM5102 Add a new ASoc Machine driver for Intel Baytrail platforms with a Wolfson Microelectronics WM5102 codec. This is based on a past contributions [1] from Paulo Sergio Travaglia based on the Levono kernel [2] combined with insights in things like the speaker GPIO from the android-x86 android port for the Lenovo Yoga Tablet 2 1051F/L [3]. [1] https://patchwork.kernel.org/project/alsa-devel/patch/593313f5.3636c80a.50e05.47e9@mx.google.com/ [2] https://github.com/lenovo-yt2-dev/android_kernel_lenovo_baytrail/blob/cm-12.1/sound/soc/intel/board/byt_bl_wm5102.c [3] https://github.com/Kitsune2222/Android_Yoga_Tablet_2-1051F_Kernel The original machine driver from the Android ports was a crude modified copy of bytcr_rt5640.c adjusted to work with the WM5102 codec. This version has been extensively reworked to: 1. Remove all rt5640 related quirk handling. to the best of my knowledge this setup is only used on the Lenovo Yoga Tablet 2 series (8, 10 and 13 inch models) which all use the same setup. So there is no need to deal with all the variations with which we need to deal on rt5640 boards. 2. Rework clock handling, properly turn off the FLL and the platform-clock when they are no longer necessary and don't reconfigure the FLL unnecessarily when it is already running. This fixes a number of: "Timed out waiting for lock" warnings being logged. 3. Add the GPIO controlled Speaker-VDD regulator as a DAPM_SUPPLY This only adds the machine driver and ACPI hooks, the BYT-CR detection quirk which these devices need will be added in a separate patch. BugLink: https://github.com/thesofproject/linux/issues/2485 Co-authored-by: Pierre-Louis Bossart Signed-off-by: Pierre-Louis Bossart Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Reviewed-by: Charles Keepax Link: https://lore.kernel.org/r/20210120214957.140232-6-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Kconfig | 12 + sound/soc/intel/boards/Makefile | 2 + sound/soc/intel/boards/bytcr_wm5102.c | 465 ++++++++++++++++++ .../intel/common/soc-acpi-intel-byt-match.c | 16 + 4 files changed, 495 insertions(+) create mode 100644 sound/soc/intel/boards/bytcr_wm5102.c diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index b58b9b60d37e3..d1d28129a32b9 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -111,6 +111,18 @@ config SND_SOC_INTEL_BYTCR_RT5651_MACH Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_BYTCR_WM5102_MACH + tristate "Baytrail and Baytrail-CR with WM5102 codec" + depends on MFD_ARIZONA && MFD_WM5102 && SPI_MASTER && ACPI + depends on X86_INTEL_LPSS || COMPILE_TEST + select SND_SOC_ACPI + select SND_SOC_WM5102 + help + This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR + platforms with WM5102 audio codec. + Say Y if you have such a device. + If unsure select "N". + config SND_SOC_INTEL_CHT_BSW_RT5672_MACH tristate "Cherrytrail & Braswell with RT5672 codec" depends on I2C && ACPI diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 5f03e484b2159..616c5fbab7d5a 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -10,6 +10,7 @@ snd-soc-sst-sof-wm8804-objs := sof_wm8804.o snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o hda_dsp_common.o snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o +snd-soc-sst-bytcr-wm5102-objs := bytcr_wm5102.o snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o @@ -51,6 +52,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH) += snd-soc-sst-bdw-rt5650-mach.o obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o +obj-$(CONFIG_SND_SOC_INTEL_BYTCR_WM5102_MACH) += snd-soc-sst-bytcr-wm5102.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c new file mode 100644 index 0000000000000..f38850eb2eaf8 --- /dev/null +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -0,0 +1,465 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * bytcr_wm5102.c - ASoc Machine driver for Intel Baytrail platforms with a + * Wolfson Microelectronics WM5102 codec + * + * Copyright (C) 2020 Hans de Goede + * Loosely based on bytcr_rt5640.c which is: + * Copyright (C) 2014-2020 Intel Corp + * Author: Subhransu S. Prusty + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../codecs/wm5102.h" +#include "../atom/sst-atom-controls.h" + +#define MCLK_FREQ 25000000 + +#define WM5102_MAX_SYSCLK_4K 49152000 /* max sysclk for 4K family */ +#define WM5102_MAX_SYSCLK_11025 45158400 /* max sysclk for 11.025K family */ + +struct byt_wm5102_private { + struct clk *mclk; + struct gpio_desc *spkvdd_en_gpio; +}; + +static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_card *card = w->dapm->card; + struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); + + gpiod_set_value_cansleep(priv->spkvdd_en_gpio, + !!SND_SOC_DAPM_EVENT_ON(event)); + + return 0; +} + +static int byt_wm5102_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, int rate) +{ + struct snd_soc_component *codec_component = codec_dai->component; + int sr_mult = ((rate % 4000) == 0) ? + (WM5102_MAX_SYSCLK_4K / rate) : + (WM5102_MAX_SYSCLK_11025 / rate); + int ret; + + /* Reset FLL1 */ + snd_soc_dai_set_pll(codec_dai, WM5102_FLL1_REFCLK, ARIZONA_FLL_SRC_NONE, 0, 0); + snd_soc_dai_set_pll(codec_dai, WM5102_FLL1, ARIZONA_FLL_SRC_NONE, 0, 0); + + /* Configure the FLL1 PLL before selecting it */ + ret = snd_soc_dai_set_pll(codec_dai, WM5102_FLL1, ARIZONA_CLK_SRC_MCLK1, + MCLK_FREQ, rate * sr_mult); + if (ret) { + dev_err(codec_component->dev, "Error setting PLL: %d\n", ret); + return ret; + } + + ret = snd_soc_component_set_sysclk(codec_component, ARIZONA_CLK_SYSCLK, + ARIZONA_CLK_SRC_FLL1, rate * sr_mult, + SND_SOC_CLOCK_IN); + if (ret) { + dev_err(codec_component->dev, "Error setting SYSCLK: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, ARIZONA_CLK_SYSCLK, + rate * 512, SND_SOC_CLOCK_IN); + if (ret) { + dev_err(codec_component->dev, "Error setting clock: %d\n", ret); + return ret; + } + + return 0; +} + +static int platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; + struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); + int ret; + + codec_dai = snd_soc_card_get_codec_dai(card, "wm5102-aif1"); + if (!codec_dai) { + dev_err(card->dev, "Error codec DAI not found\n"); + return -EIO; + } + + if (SND_SOC_DAPM_EVENT_ON(event)) { + ret = clk_prepare_enable(priv->mclk); + if (ret) { + dev_err(card->dev, "Error enabling MCLK: %d\n", ret); + return ret; + } + ret = byt_wm5102_prepare_and_enable_pll1(codec_dai, 48000); + if (ret) { + dev_err(card->dev, "Error setting codec sysclk: %d\n", ret); + return ret; + } + } else { + /* + * The WM5102 has a separate 32KHz clock for jack-detect + * so we can disable the PLL, followed by disabling the + * platform clock which is the source-clock for the PLL. + */ + snd_soc_dai_set_pll(codec_dai, WM5102_FLL1, ARIZONA_FLL_SRC_NONE, 0, 0); + clk_disable_unprepare(priv->mclk); + } + + return 0; +} + +static const struct snd_soc_dapm_widget byt_wm5102_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Internal Mic", NULL), + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, + platform_clock_control, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("Speaker VDD", SND_SOC_NOPM, 0, 0, + byt_wm5102_spkvdd_power_event, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +}; + +static const struct snd_soc_dapm_route byt_wm5102_audio_map[] = { + {"Headphone", NULL, "Platform Clock"}, + {"Headset Mic", NULL, "Platform Clock"}, + {"Internal Mic", NULL, "Platform Clock"}, + {"Speaker", NULL, "Platform Clock"}, + + {"Speaker", NULL, "SPKOUTLP"}, + {"Speaker", NULL, "SPKOUTLN"}, + {"Speaker", NULL, "SPKOUTRP"}, + {"Speaker", NULL, "SPKOUTRN"}, + {"Speaker", NULL, "Speaker VDD"}, + + {"Headphone", NULL, "HPOUT1L"}, + {"Headphone", NULL, "HPOUT1R"}, + + {"Internal Mic", NULL, "MICBIAS3"}, + {"IN3L", NULL, "Internal Mic"}, + + /* + * The Headset Mix uses MICBIAS1 or 2 depending on if a CTIA/OMTP Headset + * is connected, as the MICBIAS is applied after the CTIA/OMTP cross-switch. + */ + {"Headset Mic", NULL, "MICBIAS1"}, + {"Headset Mic", NULL, "MICBIAS2"}, + {"IN1L", NULL, "Headset Mic"}, + + {"AIF1 Playback", NULL, "ssp0 Tx"}, + {"ssp0 Tx", NULL, "modem_out"}, + + {"modem_in", NULL, "ssp0 Rx"}, + {"ssp0 Rx", NULL, "AIF1 Capture"}, +}; + +static const struct snd_kcontrol_new byt_wm5102_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Internal Mic"), + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_card *card = runtime->card; + struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); + int ret; + + card->dapm.idle_bias_off = true; + + ret = snd_soc_add_card_controls(card, byt_wm5102_controls, + ARRAY_SIZE(byt_wm5102_controls)); + if (ret) { + dev_err(card->dev, "Error adding card controls: %d\n", ret); + return ret; + } + + /* + * The firmware might enable the clock at boot (this information + * may or may not be reflected in the enable clock register). + * To change the rate we must disable the clock first to cover these + * cases. Due to common clock framework restrictions that do not allow + * to disable a clock that has not been enabled, we need to enable + * the clock first. + */ + ret = clk_prepare_enable(priv->mclk); + if (!ret) + clk_disable_unprepare(priv->mclk); + + ret = clk_set_rate(priv->mclk, MCLK_FREQ); + if (ret) { + dev_err(card->dev, "Error setting MCLK rate: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct snd_soc_pcm_stream byt_wm5102_dai_params = { + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, +}; + +static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int ret; + + /* The DSP will covert the FE rate to 48k, stereo */ + rate->min = 48000; + rate->max = 48000; + channels->min = 2; + channels->max = 2; + + /* set SSP0 to 16-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + + /* + * Default mode for SSP configuration is TDM 4 slot, override config + * with explicit setting to I2S 2ch 16-bit. The word length is set with + * dai_set_tdm_slot() since there is no other API exposed + */ + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); + if (ret) { + dev_err(rtd->dev, "Error setting format to I2S: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); + if (ret) { + dev_err(rtd->dev, "Error setting I2S config: %d\n", ret); + return ret; + } + + return 0; +} + +static int byt_wm5102_aif1_startup(struct snd_pcm_substream *substream) +{ + return snd_pcm_hw_constraint_single(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, 48000); +} + +static const struct snd_soc_ops byt_wm5102_aif1_ops = { + .startup = byt_wm5102_aif1_startup, +}; + +SND_SOC_DAILINK_DEF(dummy, + DAILINK_COMP_ARRAY(COMP_DUMMY())); + +SND_SOC_DAILINK_DEF(media, + DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai"))); + +SND_SOC_DAILINK_DEF(deepbuffer, + DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai"))); + +SND_SOC_DAILINK_DEF(ssp0_port, + DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); + +SND_SOC_DAILINK_DEF(ssp0_codec, + DAILINK_COMP_ARRAY(COMP_CODEC( + /* + * Note there is no need to overwrite the codec-name as is done in + * other bytcr machine drivers, because the codec is a MFD child-dev. + */ + "wm5102-codec", + "wm5102-aif1"))); + +SND_SOC_DAILINK_DEF(platform, + DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform"))); + +static struct snd_soc_dai_link byt_wm5102_dais[] = { + [MERR_DPCM_AUDIO] = { + .name = "Baytrail Audio Port", + .stream_name = "Baytrail Audio", + .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &byt_wm5102_aif1_ops, + SND_SOC_DAILINK_REG(media, dummy, platform), + + }, + [MERR_DPCM_DEEP_BUFFER] = { + .name = "Deep-Buffer Audio Port", + .stream_name = "Deep-Buffer Audio", + .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, + .ops = &byt_wm5102_aif1_ops, + SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), + }, + /* back ends */ + { + /* + * This must be named SSP2-Codec even though this machine driver + * always uses SSP0. Most machine drivers support both and dynamically + * update the dailink to point to SSP0 or SSP2, while keeping the name + * as "SSP2-Codec". The SOF tplg files hardcode the "SSP2-Codec" even + * in the byt-foo-ssp0.tplg versions because the other machine-drivers + * use "SSP2-Codec" even when SSP0 is used. + */ + .name = "SSP2-Codec", + .id = 0, + .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBS_CFS, + .be_hw_params_fixup = byt_wm5102_codec_fixup, + .nonatomic = true, + .dpcm_playback = 1, + .dpcm_capture = 1, + .init = byt_wm5102_init, + SND_SOC_DAILINK_REG(ssp0_port, ssp0_codec, platform), + }, +}; + +/* use space before codec name to simplify card ID, and simplify driver name */ +#define SOF_CARD_NAME "bytcht wm5102" /* card name will be 'sof-bytcht wm5102' */ +#define SOF_DRIVER_NAME "SOF" + +#define CARD_NAME "bytcr-wm5102" +#define DRIVER_NAME NULL /* card name will be used for driver name */ + +/* SoC card */ +static struct snd_soc_card byt_wm5102_card = { + .owner = THIS_MODULE, + .dai_link = byt_wm5102_dais, + .num_links = ARRAY_SIZE(byt_wm5102_dais), + .dapm_widgets = byt_wm5102_widgets, + .num_dapm_widgets = ARRAY_SIZE(byt_wm5102_widgets), + .dapm_routes = byt_wm5102_audio_map, + .num_dapm_routes = ARRAY_SIZE(byt_wm5102_audio_map), + .fully_routed = true, +}; + +static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) +{ + char codec_name[SND_ACPI_I2C_ID_LEN]; + struct device *dev = &pdev->dev; + struct byt_wm5102_private *priv; + struct snd_soc_acpi_mach *mach; + const char *platform_name; + struct acpi_device *adev; + struct device *codec_dev; + bool sof_parent; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_ATOMIC); + if (!priv) + return -ENOMEM; + + /* Get MCLK */ + priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3"); + if (IS_ERR(priv->mclk)) + return dev_err_probe(dev, PTR_ERR(priv->mclk), "getting pmc_plt_clk_3\n"); + + /* + * Get speaker VDD enable GPIO: + * 1. Get codec-device-name + * 2. Get codec-device + * 3. Get GPIO from codec-device + */ + mach = dev->platform_data; + adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1); + if (!adev) { + dev_err(dev, "Error cannot find acpi-dev for codec\n"); + return -ENOENT; + } + snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); + put_device(&adev->dev); + + codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name); + if (!codec_dev) + return -EPROBE_DEFER; + + /* Note no devm_ here since we call gpiod_get on codec_dev rather then dev */ + priv->spkvdd_en_gpio = gpiod_get(codec_dev, "wlf,spkvdd-ena", GPIOD_OUT_LOW); + put_device(codec_dev); + + if (IS_ERR(priv->spkvdd_en_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->spkvdd_en_gpio), "getting spkvdd-GPIO\n"); + + /* override platform name, if required */ + byt_wm5102_card.dev = dev; + platform_name = mach->mach_params.platform; + ret = snd_soc_fixup_dai_links_platform_name(&byt_wm5102_card, platform_name); + if (ret) + goto out_put_gpio; + + /* set card and driver name and pm-ops */ + sof_parent = snd_soc_acpi_sof_parent(dev); + if (sof_parent) { + byt_wm5102_card.name = SOF_CARD_NAME; + byt_wm5102_card.driver_name = SOF_DRIVER_NAME; + dev->driver->pm = &snd_soc_pm_ops; + } else { + byt_wm5102_card.name = CARD_NAME; + byt_wm5102_card.driver_name = DRIVER_NAME; + } + + snd_soc_card_set_drvdata(&byt_wm5102_card, priv); + ret = devm_snd_soc_register_card(dev, &byt_wm5102_card); + if (ret) { + dev_err_probe(dev, ret, "registering card\n"); + goto out_put_gpio; + } + + platform_set_drvdata(pdev, &byt_wm5102_card); + return 0; + +out_put_gpio: + gpiod_put(priv->spkvdd_en_gpio); + return ret; +} + +static int snd_byt_wm5102_mc_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); + + gpiod_put(priv->spkvdd_en_gpio); + return 0; +} + +static struct platform_driver snd_byt_wm5102_mc_driver = { + .driver = { + .name = "bytcr_wm5102", + }, + .probe = snd_byt_wm5102_mc_probe, + .remove = snd_byt_wm5102_mc_remove, +}; + +module_platform_driver(snd_byt_wm5102_mc_driver); + +MODULE_DESCRIPTION("ASoC Baytrail with WM5102 codec machine driver"); +MODULE_AUTHOR("Hans de Goede "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:bytcr_wm5102"); diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c index 31e60df131c37..d1febbb53b706 100644 --- a/sound/soc/intel/common/soc-acpi-intel-byt-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-byt-match.c @@ -154,6 +154,22 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[] = { .sof_fw_filename = "sof-byt.ri", .sof_tplg_filename = "sof-byt-rt5651.tplg", }, + { + .id = "WM510204", + .drv_name = "bytcr_wm5102", + .fw_filename = "intel/fw_sst_0f28.bin", + .board = "bytcr_wm5102", + .sof_fw_filename = "sof-byt.ri", + .sof_tplg_filename = "sof-byt-wm5102.tplg", + }, + { + .id = "WM510205", + .drv_name = "bytcr_wm5102", + .fw_filename = "intel/fw_sst_0f28.bin", + .board = "bytcr_wm5102", + .sof_fw_filename = "sof-byt.ri", + .sof_tplg_filename = "sof-byt-wm5102.tplg", + }, { .id = "DLGS7212", .drv_name = "bytcht_da7213", -- GitLab From bd8036eb15263a720b8f846861c180b27d050a09 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:18:53 -0600 Subject: [PATCH 1044/1084] ASoC: SOF: sof-pci-dev: add missing Up-Extreme quirk The UpExtreme board supports the community key and was missed in previous contributions. Add it to make sure the open firmware is picked by default without needing a symlink on the target. Fixes: 46207ca24545 ('ASoC: SOF: pci: change the default firmware path when the community key is used') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20210208231853.58761-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-pci-dev.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 215711ac74509..9adf50b20a735 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -65,6 +65,13 @@ static const struct dmi_system_id community_key_platforms[] = { DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"), } }, + { + .ident = "Up Extreme", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_MATCH(DMI_BOARD_NAME, "UP-WHL01"), + } + }, { .ident = "Google Chromebooks", .matches = { -- GitLab From ae4fc532244b3bb4d86c397418d980b0c6be1dfd Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Mon, 8 Feb 2021 17:40:42 -0600 Subject: [PATCH 1045/1084] ASoC: dapm: use component prefix when checking widget names On a TigerLake SoundWire platform, we see these warnings: [ 27.360086] rt5682 sdw:0:25d:5682:0: ASoC: DAPM unknown pin MICBIAS [ 27.360092] rt5682 sdw:0:25d:5682:0: ASoC: DAPM unknown pin Vref2 This is root-caused to the addition of a component prefix in the machine driver. The tests in soc-dapm should account for a prefix instead of reporting an invalid issue. Reported-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Shuming Fan Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208234043.59750-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 2b75d0139e478..b005f9eadd719 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2528,9 +2528,20 @@ static struct snd_soc_dapm_widget *dapm_find_widget( { struct snd_soc_dapm_widget *w; struct snd_soc_dapm_widget *fallback = NULL; + char prefixed_pin[80]; + const char *pin_name; + const char *prefix = soc_dapm_prefix(dapm); + + if (prefix) { + snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s", + prefix, pin); + pin_name = prefixed_pin; + } else { + pin_name = pin; + } for_each_card_widgets(dapm->card, w) { - if (!strcmp(w->name, pin)) { + if (!strcmp(w->name, pin_name)) { if (w->dapm == dapm) return w; else -- GitLab From 1183c350011a6f6b551c200b9206bf1808c22a4c Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 8 Feb 2021 17:40:43 -0600 Subject: [PATCH 1046/1084] ASoC: Intel: boards: max98373: get dapm from cpu_dai There is a prefix on max98373 codec, and the prefix will be added to the pin name However, there is no prefix on the "Right Spk" and "Left Spk" widgets. To avoid getting a redundant prefix, we should get dapm from cpu_dai component. Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208234043.59750-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_maxim_common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index c2a9757181fe1..437d205627539 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -63,6 +63,7 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; + struct snd_soc_dai *cpu_dai; int j; int ret = 0; @@ -70,10 +71,10 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) return 0; + cpu_dai = asoc_rtd_to_cpu(rtd, 0); for_each_rtd_codec_dais(rtd, j, codec_dai) { - struct snd_soc_component *component = codec_dai->component; struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + snd_soc_component_get_dapm(cpu_dai->component); char pin_name[MAX_98373_PIN_NAME]; snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", -- GitLab From a8f50cd9be7cc4c57f29c1390568225ebee90eda Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Mon, 8 Feb 2021 17:21:45 -0600 Subject: [PATCH 1047/1084] ASoC: SOF: add missing pm debug Type is not part of debugging parse code. Add it so unknown types don't show up while debugging Reviewed-by: Ranjani Sridharan Signed-off-by: Curtis Malainey Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208232149.58899-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index fc13bb06dbf39..1bc3d6282f16d 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -106,6 +106,8 @@ static void ipc_log_header(struct device *dev, u8 *text, u32 cmd) str2 = "CLK_REQ"; break; case SOF_IPC_PM_CORE_ENABLE: str2 = "CORE_ENABLE"; break; + case SOF_IPC_PM_GATE: + str2 = "GATE"; break; default: str2 = "unknown type"; break; } -- GitLab From ce1f55bac5534aa518e26b94728173ee45f91a8c Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Mon, 8 Feb 2021 17:21:46 -0600 Subject: [PATCH 1048/1084] ASoC: SOF: fix string format for errors These are negative error return values, printing them as hex is annoying and not beneficial. Switch back to signed type to make error lookup simpler. Reviewed-by: Kai Vehmanen Reviewed-by: Daniel Baluta Reviewed-by: Guennadi Liakhovetski Signed-off-by: Curtis Malainey Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208232149.58899-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-compress.c | 2 +- sound/soc/sof/intel/hda-dsp.c | 2 +- sound/soc/sof/intel/hda-loader.c | 6 +++--- sound/soc/sof/intel/hda-pcm.c | 2 +- sound/soc/sof/intel/hda-trace.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/sof/intel/hda-compress.c b/sound/soc/sof/intel/hda-compress.c index c6cf7b3139342..fe2f3f7d236b1 100644 --- a/sound/soc/sof/intel/hda-compress.c +++ b/sound/soc/sof/intel/hda-compress.c @@ -82,7 +82,7 @@ int hda_probe_compr_set_params(struct snd_sof_dev *sdev, ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL); if (ret < 0) { - dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); return ret; } diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index e92e9750b720f..72c0b8e9a1969 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -732,7 +732,7 @@ int hda_dsp_resume(struct snd_sof_dev *sdev) ret = snd_hdac_ext_bus_link_power_up(hlink); if (ret < 0) { dev_dbg(sdev->dev, - "error %x in %s: failed to power up links", + "error %d in %s: failed to power up links", ret, __func__); return ret; } diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index d744952f69543..fc25ee8f68dcb 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -47,7 +47,7 @@ static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsig /* allocate DMA buffer */ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, &pci->dev, size, dmab); if (ret < 0) { - dev_err(sdev->dev, "error: memory alloc failed: %x\n", ret); + dev_err(sdev->dev, "error: memory alloc failed: %d\n", ret); goto error; } @@ -58,13 +58,13 @@ static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsig if (direction == SNDRV_PCM_STREAM_CAPTURE) { ret = hda_dsp_iccmax_stream_hw_params(sdev, dsp_stream, dmab, NULL); if (ret < 0) { - dev_err(sdev->dev, "error: iccmax stream prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: iccmax stream prepare failed: %d\n", ret); goto error; } } else { ret = hda_dsp_stream_hw_params(sdev, dsp_stream, dmab, NULL); if (ret < 0) { - dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); goto error; } hda_dsp_stream_spib_config(sdev, dsp_stream, HDA_DSP_SPIB_ENABLE, size); diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index 689934131a682..df00db8369c78 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -111,7 +111,7 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev, ret = hda_dsp_stream_hw_params(sdev, stream, dmab, params); if (ret < 0) { - dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); return ret; } diff --git a/sound/soc/sof/intel/hda-trace.c b/sound/soc/sof/intel/hda-trace.c index 81d76d3debc65..29e3da3c63db0 100644 --- a/sound/soc/sof/intel/hda-trace.c +++ b/sound/soc/sof/intel/hda-trace.c @@ -32,7 +32,7 @@ static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev) ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL); if (ret < 0) - dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); return ret; } @@ -59,7 +59,7 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) */ ret = hda_dsp_trace_prepare(sdev); if (ret < 0) { - dev_err(sdev->dev, "error: hdac trace init failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac trace init failed: %d\n", ret); hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE, *stream_tag); hda->dtrace_stream = NULL; *stream_tag = 0; -- GitLab From 3be46fa21088740ae5790d84b882e5a3c98fce41 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 8 Feb 2021 17:21:47 -0600 Subject: [PATCH 1049/1084] ASoC: SOF: remove unused functions hda_dsp_dump_skl() is never used and hda_dsp_get_status_skl() is only called from that function. Remove both functions. Reviewed-by: Ranjani Sridharan Reviewed-by: Keyon Jie Signed-off-by: Guennadi Liakhovetski Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208232149.58899-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 50 --------------------------------------- sound/soc/sof/intel/hda.h | 1 - 2 files changed, 51 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 447163494b05f..57853ef89cd1b 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -317,26 +317,6 @@ static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = { {HDA_DSP_ROM_NULL_FW_ENTRY, "error: null FW entry point"}, }; -static void hda_dsp_get_status_skl(struct snd_sof_dev *sdev) -{ - u32 status; - int i; - - status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_ADSP_FW_STATUS_SKL); - - for (i = 0; i < ARRAY_SIZE(hda_dsp_rom_msg); i++) { - if (status == hda_dsp_rom_msg[i].code) { - dev_err(sdev->dev, "%s - code %8.8x\n", - hda_dsp_rom_msg[i].msg, status); - return; - } - } - - /* not for us, must be generic sof message */ - dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status); -} - static void hda_dsp_get_status(struct snd_sof_dev *sdev) { u32 status; @@ -385,36 +365,6 @@ static void hda_dsp_get_registers(struct snd_sof_dev *sdev, stack_words * sizeof(u32)); } -void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags) -{ - struct sof_ipc_dsp_oops_xtensa xoops; - struct sof_ipc_panic_info panic_info; - u32 stack[HDA_DSP_STACK_DUMP_SIZE]; - u32 status, panic; - - /* try APL specific status message types first */ - hda_dsp_get_status_skl(sdev); - - /* now try generic SOF status messages */ - status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_ADSP_ERROR_CODE_SKL); - - /*TODO: Check: there is no define in spec, but it is used in the code*/ - panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_ADSP_ERROR_CODE_SKL + 0x4); - - if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) { - hda_dsp_get_registers(sdev, &xoops, &panic_info, stack, - HDA_DSP_STACK_DUMP_SIZE); - snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, - stack, HDA_DSP_STACK_DUMP_SIZE); - } else { - dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", - status, panic); - hda_dsp_get_status_skl(sdev); - } -} - /* dump the first 8 dwords representing the extended ROM status */ static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev, u32 flags) { diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 8e39d1e16178d..d979411b40415 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -517,7 +517,6 @@ int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev); int hda_dsp_runtime_resume(struct snd_sof_dev *sdev); int hda_dsp_runtime_idle(struct snd_sof_dev *sdev); int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev); -void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags); void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags); void hda_ipc_dump(struct snd_sof_dev *sdev); void hda_ipc_irq_dump(struct snd_sof_dev *sdev); -- GitLab From f1bb023525fd654121f18f6e2587eeee84c9db04 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 8 Feb 2021 17:21:48 -0600 Subject: [PATCH 1050/1084] ASoC: SOF: HDA: (cosmetic) simplify hda_dsp_d0i3_work() Simplify hda_dsp_d0i3_work() by returning immediately from it if D0i3 cannot be set. Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Libin Yang Reviewed-by: Keyon Jie Signed-off-by: Guennadi Liakhovetski Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208232149.58899-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 72c0b8e9a1969..5788fe3569605 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -934,19 +934,15 @@ void hda_dsp_d0i3_work(struct work_struct *work) d0i3_work.work); struct hdac_bus *bus = &hdev->hbus.core; struct snd_sof_dev *sdev = dev_get_drvdata(bus->dev); - struct sof_dsp_power_state target_state; + struct sof_dsp_power_state target_state = { + .state = SOF_DSP_PM_D0, + .substate = SOF_HDA_DSP_PM_D0I3, + }; int ret; - target_state.state = SOF_DSP_PM_D0; - /* DSP can enter D0I3 iff only D0I3-compatible streams are active */ - if (snd_sof_dsp_only_d0i3_compatible_stream_active(sdev)) - target_state.substate = SOF_HDA_DSP_PM_D0I3; - else - target_state.substate = SOF_HDA_DSP_PM_D0I0; - - /* remain in D0I0 */ - if (target_state.substate == SOF_HDA_DSP_PM_D0I0) + if (!snd_sof_dsp_only_d0i3_compatible_stream_active(sdev)) + /* remain in D0I0 */ return; /* This can fail but error cannot be propagated */ -- GitLab From cc11626dd9f894d93ed15d78b04452ca9acbb52b Mon Sep 17 00:00:00 2001 From: Fred Oh Date: Mon, 8 Feb 2021 17:21:49 -0600 Subject: [PATCH 1051/1084] ASoC: SOF: ext_manifest: use explicit number for elem_type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use explicit number to define elem_type enum instead of using SOF_IPC_EXT_*. Reviewed-by: Guennadi Liakhovetski Reviewed-by: Karol Trzciński Reviewed-by: Kai Vehmanen Signed-off-by: Fred Oh Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208232149.58899-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- include/sound/sof/ext_manifest.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/sound/sof/ext_manifest.h b/include/sound/sof/ext_manifest.h index 7abc4f0bd3ade..2a7e055584f9f 100644 --- a/include/sound/sof/ext_manifest.h +++ b/include/sound/sof/ext_manifest.h @@ -58,9 +58,9 @@ struct sof_ext_man_header { /* Extended manifest elements types */ enum sof_ext_man_elem_type { SOF_EXT_MAN_ELEM_FW_VERSION = 0, - SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW, - SOF_EXT_MAN_ELEM_CC_VERSION = SOF_IPC_EXT_CC_INFO, - SOF_EXT_MAN_ELEM_DBG_ABI = SOF_IPC_EXT_USER_ABI_INFO, + SOF_EXT_MAN_ELEM_WINDOW = 1, + SOF_EXT_MAN_ELEM_CC_VERSION = 2, + SOF_EXT_MAN_ELEM_DBG_ABI = 4, SOF_EXT_MAN_ELEM_CONFIG_DATA = 5, /**< ABI3.17 */ SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA = 6, }; -- GitLab From 3d09cf8d0d791a41a75123e135f604d59f4aa870 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:26 -0600 Subject: [PATCH 1052/1084] ASoC: Intel: sof_sdw: reorganize quirks by generation The quirk table is a mess, let's reorganize it by generation before making sure that the quirks are consistent for each generation. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 73 +++++++++++++++++--------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 152ea166eeaef..8bd1d6c84f193 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -48,37 +48,14 @@ static int sof_sdw_quirk_cb(const struct dmi_system_id *id) } static const struct dmi_system_id sof_sdw_quirk_table[] = { + /* CometLake devices */ { .callback = sof_sdw_quirk_cb, .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") - }, - .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_RT711_JD_SRC_JD2 | - SOF_RT715_DAI_ID_FIX | - SOF_SDW_FOUR_SPK), - }, - { - .callback = sof_sdw_quirk_cb, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") - }, - .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_RT711_JD_SRC_JD2 | - SOF_RT715_DAI_ID_FIX), - }, - { - .callback = sof_sdw_quirk_cb, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), }, - .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_RT711_JD_SRC_JD2 | - SOF_RT715_DAI_ID_FIX | - SOF_SDW_FOUR_SPK), + .driver_data = (void *)SOF_SDW_PCH_DMIC, }, { .callback = sof_sdw_quirk_cb, @@ -109,7 +86,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_RT715_DAI_ID_FIX | SOF_SDW_FOUR_SPK), }, - { + { .callback = sof_sdw_quirk_cb, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), @@ -119,6 +96,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_RT715_DAI_ID_FIX | SOF_SDW_FOUR_SPK), }, + /* IceLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), + }, + .driver_data = (void *)SOF_SDW_PCH_DMIC, + }, + /* TigerLake devices */ { .callback = sof_sdw_quirk_cb, .matches = { @@ -133,18 +120,23 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { { .callback = sof_sdw_quirk_cb, .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") }, - .driver_data = (void *)SOF_SDW_PCH_DMIC, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | + SOF_RT715_DAI_ID_FIX), }, { .callback = sof_sdw_quirk_cb, .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") }, - .driver_data = (void *)SOF_SDW_PCH_DMIC, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | + SOF_RT715_DAI_ID_FIX | + SOF_SDW_FOUR_SPK), }, { .callback = sof_sdw_quirk_cb, @@ -164,7 +156,18 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | SOF_SDW_FOUR_SPK), }, - + /* TigerLake-SDCA devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | + SOF_RT715_DAI_ID_FIX | + SOF_SDW_FOUR_SPK), + }, {} }; -- GitLab From 8caf37e2be761688c396c609880936a807af490f Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:27 -0600 Subject: [PATCH 1053/1084] ASoC: Intel: sof-sdw: indent and add quirks consistently Use the same style for all quirks to avoid misses and errors Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 8bd1d6c84f193..99c0e4b12d1cd 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -113,9 +113,10 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Tiger Lake Client Platform"), }, - .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 | - SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | - SOF_SSP_PORT(SOF_I2S_SSP2)), + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD1 | + SOF_SDW_PCH_DMIC | + SOF_SSP_PORT(SOF_I2S_SSP2)), }, { .callback = sof_sdw_quirk_cb, @@ -144,7 +145,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Google"), DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"), }, - .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_SDW_PCH_DMIC | SOF_SDW_FOUR_SPK), }, { @@ -153,7 +155,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Google"), DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"), }, - .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_SDW_PCH_DMIC | SOF_SDW_FOUR_SPK), }, /* TigerLake-SDCA devices */ -- GitLab From d92e279dee56b4b65c1af21f972413f172a9734a Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:28 -0600 Subject: [PATCH 1054/1084] ASoC: Intel: sof_sdw: add quirk for HP Spectre x360 convertible This set of devices has SoundWire support along with DMICs. The DMI information was provided by users for 3 separate skus. BugLink: https://github.com/thesofproject/linux/issues/2700 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 99c0e4b12d1cd..0e83db947a57a 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -159,6 +159,22 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_SDW_PCH_DMIC | SOF_SDW_FOUR_SPK), }, + { + /* + * this entry covers multiple HP SKUs. The family name + * does not seem robust enough, so we use a partial + * match that ignores the product name suffix + * (e.g. 15-eb1xxx, 14t-ea000 or 13-aw2xxx) + */ + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_SDW_PCH_DMIC | + SOF_RT711_JD_SRC_JD2), + }, /* TigerLake-SDCA devices */ { .callback = sof_sdw_quirk_cb, -- GitLab From 209b0b0d8d5a469a2892ad51cb448811d00b4ff4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:29 -0600 Subject: [PATCH 1055/1084] ASoC: Intel: sof_sdw: add mic:dmic and cfg-mics component strings UCM needs to know which microphone is used (dmic or RT715-based), let's add the information in the component string. Note the slight change from HDAudio platforms where 'cfg-dmics' was used. 'cfg-mics' is used here with the intent that this component string describes either the number of PCH-attached microphones or the number of RT715-attached ones (the assumption is that the two configurations are mutually exclusive). Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 0e83db947a57a..d1251a6ac3af0 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1222,6 +1222,15 @@ static int mc_probe(struct platform_device *pdev) if (!card->components) return -ENOMEM; + if (mach->mach_params.dmic_num) { + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s mic:dmic cfg-mics:%d", + card->components, + mach->mach_params.dmic_num); + if (!card->components) + return -ENOMEM; + } + card->long_name = sdw_card_long_name; /* Register the card */ -- GitLab From f88dcb9b98d3f86ead04d2453475267910448bb8 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Mon, 8 Feb 2021 17:33:30 -0600 Subject: [PATCH 1056/1084] ASoC: Intel: sof_sdw: detect DMIC number based on mach params Current driver create DMIC dai based on quirk for each platforms, so we need to add quirk for new platforms. Now driver reports DMIC number to machine driver and machine driver can create DMIC dai based on this information. The old check is reserved for some platforms may be failed to set the DMIC number in BIOS. Reviewed-by: Bard Liao Signed-off-by: Rander Wang Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208233336.59449-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index d1251a6ac3af0..06f07dd45fb46 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -955,7 +955,7 @@ static int sof_card_dai_links_create(struct device *dev, ctx->idisp_codec = true; /* enable dmic01 & dmic16k */ - dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC) ? 2 : 0; + dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) ? 2 : 0; comp_num += dmic_num; dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num, -- GitLab From 3827b7ca399245e609b3ca717550b0638d1f69cd Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 8 Feb 2021 17:33:31 -0600 Subject: [PATCH 1057/1084] ASoC: intel: sof_sdw: add trace for dai links We create dai links dynamically, so it is not easy to know what dai links are created. So adding trace for dai link name and id. Reviewed-by: Rander Wang Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208233336.59449-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 06f07dd45fb46..8adce6417b021 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -476,15 +476,14 @@ static int get_sdw_dailink_info(const struct snd_soc_acpi_link_adr *links, return 0; } -static void init_dai_link(struct snd_soc_dai_link *dai_links, int be_id, - char *name, int playback, int capture, - struct snd_soc_dai_link_component *cpus, - int cpus_num, - struct snd_soc_dai_link_component *codecs, - int codecs_num, +static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, + int be_id, char *name, int playback, int capture, + struct snd_soc_dai_link_component *cpus, int cpus_num, + struct snd_soc_dai_link_component *codecs, int codecs_num, int (*init)(struct snd_soc_pcm_runtime *rtd), const struct snd_soc_ops *ops) { + dev_dbg(dev, "create dai link %s, id %d\n", name, be_id); dai_links->id = be_id; dai_links->name = name; dai_links->platforms = platform_component; @@ -822,7 +821,7 @@ static int create_sdw_dailink(struct device *dev, int *be_index, playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); capture = (stream == SNDRV_PCM_STREAM_CAPTURE); - init_dai_link(dai_links + *be_index, *be_index, name, + init_dai_link(dev, dai_links + *be_index, *be_index, name, playback, capture, cpus + *cpu_id, cpu_dai_num, codecs, codec_num, @@ -1061,7 +1060,7 @@ static int sof_card_dai_links_create(struct device *dev, playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK]; capture = info->direction[SNDRV_PCM_STREAM_CAPTURE]; - init_dai_link(links + link_id, be_id, name, + init_dai_link(dev, links + link_id, be_id, name, playback, capture, cpus + cpu_id, 1, ssp_components, 1, @@ -1078,7 +1077,7 @@ static int sof_card_dai_links_create(struct device *dev, /* dmic */ if (dmic_num > 0) { cpus[cpu_id].dai_name = "DMIC01 Pin"; - init_dai_link(links + link_id, be_id, "dmic01", + init_dai_link(dev, links + link_id, be_id, "dmic01", 0, 1, // DMIC only supports capture cpus + cpu_id, 1, dmic_component, 1, @@ -1086,7 +1085,7 @@ static int sof_card_dai_links_create(struct device *dev, INC_ID(be_id, cpu_id, link_id); cpus[cpu_id].dai_name = "DMIC16k Pin"; - init_dai_link(links + link_id, be_id, "dmic16k", + init_dai_link(dev, links + link_id, be_id, "dmic16k", 0, 1, // DMIC only supports capture cpus + cpu_id, 1, dmic_component, 1, @@ -1129,7 +1128,7 @@ static int sof_card_dai_links_create(struct device *dev, return -ENOMEM; cpus[cpu_id].dai_name = cpu_name; - init_dai_link(links + link_id, be_id, name, + init_dai_link(dev, links + link_id, be_id, name, 1, 0, // HDMI only supports playback cpus + cpu_id, 1, idisp_components + i, 1, -- GitLab From 717a8fdd150c495cc202880cf6955294c7acae4f Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:32 -0600 Subject: [PATCH 1058/1084] ASoC: Intel: soc-acpi: add ACPI matching table for HP Spectre x360 This device only has a single amplifier on link1, so we need a dedicated entry to find a match. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Guennadi Liakhovetski Link: https://lore.kernel.org/r/20210208233336.59449-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- .../intel/common/soc-acpi-intel-tgl-match.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c index e3ddbf05bf729..40f31c8a3aba0 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -205,6 +205,20 @@ static const struct snd_soc_acpi_link_adr tgl_rvp[] = { {} }; +static const struct snd_soc_acpi_link_adr tgl_hp[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_0_adr), + .adr_d = rt711_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1308_1_single_adr), + .adr_d = rt1308_1_single_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr tgl_chromebook_base[] = { { .mask = BIT(0), @@ -383,6 +397,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-tgl-rt711-rt1316-rt714.tplg", }, + { + .link_mask = 0x3, /* rt711 on link 0 and 1 rt1308 on link 1 */ + .links = tgl_hp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg", + }, { .link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */ .links = tgl_rvp, -- GitLab From 6f5d506d7ff1d9b1ffac0130f2958b9da41175f4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:33 -0600 Subject: [PATCH 1059/1084] ASoC: SOF: Intel: SoundWire: refine ACPI match We have existing platforms where the wrong machine is selected. We need to make sure the number of devices reported on a link matches what we expect for a link descriptor. This helps avoid using the TGL-RVP configuration for an HP platform or vice-versa, depending on the order in which they are inserted in the table. Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Guennadi Liakhovetski Link: https://lore.kernel.org/r/20210208233336.59449-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 59 +++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 447163494b05f..db868376039ad 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1071,32 +1071,63 @@ static bool link_slaves_found(struct snd_sof_dev *sdev, struct sdw_intel_slave_id *ids = sdw->ids; int num_slaves = sdw->num_slaves; unsigned int part_id, link_id, unique_id, mfg_id; - int i, j; + int i, j, k; for (i = 0; i < link->num_adr; i++) { u64 adr = link->adr_d[i].adr; + int reported_part_count = 0; mfg_id = SDW_MFG_ID(adr); part_id = SDW_PART_ID(adr); link_id = SDW_DISCO_LINK_ID(adr); + + for (j = 0; j < num_slaves; j++) { + /* find out how many identical parts were reported on that link */ + if (ids[j].link_id == link_id && + ids[j].id.part_id == part_id && + ids[j].id.mfg_id == mfg_id) + reported_part_count++; + } + for (j = 0; j < num_slaves; j++) { + int expected_part_count = 0; + if (ids[j].link_id != link_id || ids[j].id.part_id != part_id || ids[j].id.mfg_id != mfg_id) continue; - /* - * we have to check unique id - * if there is more than one - * Slave on the link - */ - unique_id = SDW_UNIQUE_ID(adr); - if (link->num_adr == 1 || - ids[j].id.unique_id == SDW_IGNORED_UNIQUE_ID || - ids[j].id.unique_id == unique_id) { - dev_dbg(bus->dev, - "found %x at link %d\n", - part_id, link_id); - break; + + /* find out how many identical parts are expected */ + for (k = 0; k < link->num_adr; k++) { + u64 adr2 = link->adr_d[i].adr; + unsigned int part_id2, link_id2, mfg_id2; + + mfg_id2 = SDW_MFG_ID(adr2); + part_id2 = SDW_PART_ID(adr2); + link_id2 = SDW_DISCO_LINK_ID(adr2); + + if (link_id2 == link_id && + part_id2 == part_id && + mfg_id2 == mfg_id) + expected_part_count++; + } + + if (reported_part_count == expected_part_count) { + /* + * we have to check unique id + * if there is more than one + * Slave on the link + */ + unique_id = SDW_UNIQUE_ID(adr); + if (reported_part_count == 1 || + ids[j].id.unique_id == unique_id) { + dev_dbg(bus->dev, "found %x at link %d\n", + part_id, link_id); + break; + } + } else { + dev_dbg(bus->dev, "part %x reported %d expected %d on link %d, skipping\n", + part_id, reported_part_count, expected_part_count, link_id); } } if (j == num_slaves) { -- GitLab From 7aecf59770920cce5ff6e94b3809574364178126 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:34 -0600 Subject: [PATCH 1060/1084] ASoC: SOF: Intel: detect DMIC number in SoundWire mixed config The pinmux allows for 2 SoundWire links to be enabled along with DMICs. This was the default configuration on the TGL-RVP. One issue with this configuration is that we don't have a means to automatically detect how many DMICs are used, which in turn requires the user to manually rename the topology file required on a platform. This was borderline acceptable for Intel RVPs, but now that this configuration is present in HP devices we need to automate the process. This patch makes use of the NHLT information and will pass the DMIC number to the machine driver as a parameter. A follow-up patch will expose the DMIC number to userspace/UCM with the configuration strings. The Google devices do make use of DMICs instead of SoundWire link 2 and 3, but their topology is unique enough that they do not need any NHTL support or topology renaming. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 133 ++++++++++++++++++++++++-------------- 1 file changed, 85 insertions(+), 48 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index db868376039ad..7ae2c2c451ef7 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -285,11 +285,13 @@ static char *hda_model; module_param(hda_model, charp, 0444); MODULE_PARM_DESC(hda_model, "Use the given HDA board model."); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) static int hda_dmic_num = -1; module_param_named(dmic_num, hda_dmic_num, int, 0444); MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number"); +#endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI); module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444); MODULE_PARM_DESC(use_common_hdmi, "SOF HDA use common HDMI codec driver"); @@ -555,7 +557,7 @@ static int hda_init(struct snd_sof_dev *sdev) return ret; } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) static int check_nhlt_dmic(struct snd_sof_dev *sdev) { @@ -598,6 +600,53 @@ static const char *fixup_tplg_name(struct snd_sof_dev *sdev, return tplg_filename; } +static int dmic_topology_fixup(struct snd_sof_dev *sdev, + const char **tplg_filename, + const char *idisp_str, + int *dmic_found) +{ + const char *default_tplg_filename = *tplg_filename; + const char *fixed_tplg_filename; + const char *dmic_str; + int dmic_num; + + /* first check NHLT for DMICs */ + dmic_num = check_nhlt_dmic(sdev); + + /* allow for module parameter override */ + if (hda_dmic_num != -1) + dmic_num = hda_dmic_num; + + switch (dmic_num) { + case 1: + dmic_str = "-1ch"; + break; + case 2: + dmic_str = "-2ch"; + break; + case 3: + dmic_str = "-3ch"; + break; + case 4: + dmic_str = "-4ch"; + break; + default: + dmic_num = 0; + dmic_str = ""; + break; + } + + fixed_tplg_filename = fixup_tplg_name(sdev, default_tplg_filename, + idisp_str, dmic_str); + if (!fixed_tplg_filename) + return -ENOMEM; + + dev_info(sdev->dev, "DMICs detected in NHLT tables: %d\n", dmic_num); + *dmic_found = dmic_num; + *tplg_filename = fixed_tplg_filename; + + return 0; +} #endif static int hda_init_caps(struct snd_sof_dev *sdev) @@ -963,9 +1012,9 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev) struct snd_sof_pdata *pdata = sdev->pdata; const char *tplg_filename; const char *idisp_str; - const char *dmic_str; int dmic_num = 0; int codec_num = 0; + int ret; int i; /* codec detection */ @@ -990,10 +1039,6 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev) if (!pdata->machine && codec_num <= 2) { hda_mach = snd_soc_acpi_intel_hda_machines; - /* topology: use the info from hda_machines */ - pdata->tplg_filename = - hda_mach->sof_tplg_filename; - dev_info(bus->dev, "using HDA machine driver %s now\n", hda_mach->drv_name); @@ -1002,42 +1047,13 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev) else idisp_str = ""; - /* first check NHLT for DMICs */ - dmic_num = check_nhlt_dmic(sdev); - - /* allow for module parameter override */ - if (hda_dmic_num != -1) - dmic_num = hda_dmic_num; - - switch (dmic_num) { - case 1: - dmic_str = "-1ch"; - break; - case 2: - dmic_str = "-2ch"; - break; - case 3: - dmic_str = "-3ch"; - break; - case 4: - dmic_str = "-4ch"; - break; - default: - dmic_num = 0; - dmic_str = ""; - break; - } - - tplg_filename = pdata->tplg_filename; - tplg_filename = fixup_tplg_name(sdev, tplg_filename, - idisp_str, dmic_str); - if (!tplg_filename) - return -EINVAL; - - dev_info(bus->dev, - "DMICs detected in NHLT tables: %d\n", - dmic_num); + /* topology: use the info from hda_machines */ + tplg_filename = hda_mach->sof_tplg_filename; + ret = dmic_topology_fixup(sdev, &tplg_filename, idisp_str, &dmic_num); + if (ret < 0) + return ret; + hda_mach->mach_params.dmic_num = dmic_num; pdata->machine = hda_mach; pdata->tplg_filename = tplg_filename; } @@ -1049,7 +1065,6 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev) &pdata->machine->mach_params; mach_params->codec_mask = bus->codec_mask; mach_params->common_hdmi_codec_drv = hda_codec_use_common_hdmi; - mach_params->dmic_num = dmic_num; } return 0; @@ -1144,7 +1159,6 @@ static int hda_sdw_machine_select(struct snd_sof_dev *sdev) { struct snd_sof_pdata *pdata = sdev->pdata; const struct snd_soc_acpi_link_adr *link; - struct hdac_bus *bus = sof_to_bus(sdev); struct snd_soc_acpi_mach *mach; struct sof_intel_hda_dev *hdev; u32 link_mask; @@ -1192,10 +1206,8 @@ static int hda_sdw_machine_select(struct snd_sof_dev *sdev) break; } if (mach && mach->link_mask) { - dev_dbg(bus->dev, - "SoundWire machine driver %s topology %s\n", - mach->drv_name, - mach->sof_tplg_filename); + int dmic_num = 0; + pdata->machine = mach; mach->mach_params.links = mach->links; mach->mach_params.link_mask = mach->link_mask; @@ -1205,6 +1217,31 @@ static int hda_sdw_machine_select(struct snd_sof_dev *sdev) else pdata->fw_filename = pdata->desc->default_fw_filename; pdata->tplg_filename = mach->sof_tplg_filename; + + /* + * DMICs use up to 4 pins and are typically pin-muxed with SoundWire + * link 2 and 3, thus we only try to enable dmics if all conditions + * are true: + * a) link 2 and 3 are not used by SoundWire + * b) the NHLT table reports the presence of microphones + */ + if (!(mach->link_mask & GENMASK(3, 2))) { + const char *tplg_filename = mach->sof_tplg_filename; + int ret; + + ret = dmic_topology_fixup(sdev, &tplg_filename, "", &dmic_num); + + if (ret < 0) + return ret; + + pdata->tplg_filename = tplg_filename; + } + mach->mach_params.dmic_num = dmic_num; + + dev_dbg(sdev->dev, + "SoundWire machine driver %s topology %s\n", + mach->drv_name, + pdata->tplg_filename); } else { dev_info(sdev->dev, "No SoundWire machine driver found\n"); -- GitLab From b9088535e1021f11500f8417598b6af1f381f7dc Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 8 Feb 2021 17:33:35 -0600 Subject: [PATCH 1061/1084] ASoC: SOF: Intel: HDA: don't keep a temporary variable fixup_tplg_name() doesn't need to keep the string, allocated for filename - it's temporary. Reviewed-by: Kai Vehmanen Signed-off-by: Guennadi Liakhovetski Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208233336.59449-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 7ae2c2c451ef7..bd1cbef90278d 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -581,22 +581,22 @@ static const char *fixup_tplg_name(struct snd_sof_dev *sdev, const char *dmic_str) { const char *tplg_filename = NULL; - char *filename; - char *split_ext; + char *filename, *tmp; + const char *split_ext; - filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL); + filename = kstrdup(sof_tplg_filename, GFP_KERNEL); if (!filename) return NULL; /* this assumes a .tplg extension */ - split_ext = strsep(&filename, "."); - if (split_ext) { + tmp = filename; + split_ext = strsep(&tmp, "."); + if (split_ext) tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s%s%s.tplg", split_ext, idisp_str, dmic_str); - if (!tplg_filename) - return NULL; - } + kfree(filename); + return tplg_filename; } -- GitLab From 026370cb5bd7ef7999bc4379ab89ffd7a73874f2 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:36 -0600 Subject: [PATCH 1062/1084] ASoC: SOF: Intel: hda: add dev_dbg() when DMIC number is overridden It's useful for debug and system integration to show cases where we ignore the number of microphones reported by NHLT. Suggested-by: Guennadi Liakhovetski Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-12-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index bd1cbef90278d..0251bf83d0fef 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -614,8 +614,12 @@ static int dmic_topology_fixup(struct snd_sof_dev *sdev, dmic_num = check_nhlt_dmic(sdev); /* allow for module parameter override */ - if (hda_dmic_num != -1) + if (hda_dmic_num != -1) { + dev_dbg(sdev->dev, + "overriding DMICs detected in NHLT tables %d by kernel param %d\n", + dmic_num, hda_dmic_num); dmic_num = hda_dmic_num; + } switch (dmic_num) { case 1: -- GitLab From b6eabd247db8bb2d013fb9a9451ecb04a44ee58f Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 8 Feb 2021 16:12:45 +0800 Subject: [PATCH 1063/1084] ASoC: soc-pcm: change error message to debug message This log message should be a debug message, because it doesn't return directly but continue next loop. Signed-off-by: Shengjiu Wang Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/1612771965-5776-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index b79f064887d43..8d55f39d40143 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1344,8 +1344,8 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, /* is there a valid BE rtd for this widget */ be = dpcm_get_be(card, widget, stream); if (!be) { - dev_err(fe->dev, "ASoC: no BE found for %s\n", - widget->name); + dev_dbg(fe->dev, "ASoC: no BE found for %s\n", + widget->name); continue; } -- GitLab From 271d9373db1c76f239fe3124e552b6b58b2af984 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Wed, 10 Feb 2021 12:52:37 +0200 Subject: [PATCH 1064/1084] ASoC: SOF: fix runtime pm usage mismatch after probe errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With current delayed probe implementation, sof_probe_complete is not called in case of errors. And as this function is responsible for decrementing runtime pm usage counter, this will result in following problem: - probe driver in conditions where probe will fail (to force the condition on Intel SOF systems, set "snd_sof_intel_hda_common.codec_mask=0") - unload driver (runtime-pm usage_count is leaked) - fix the issue by installing missing fw, modifying module parameters, etc actions - try to load driver again -> success, probe ok -> device never enters runtime suspend Fix the issue by storing result of delayed probe to a state variable and providing new snd_sof_device_probe_completed() to be queried from SOF PCI/ACPI/OF drivers. If probe never completed successfully, runtime PM was not set up and thus at remove(), we should not increment usage count anymore. Signed-off-by: Kai Vehmanen Reviewed-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Link: https://lore.kernel.org/r/20210210105237.2179273-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/core.c | 10 ++++++++++ sound/soc/sof/sof-pci-dev.c | 3 ++- sound/soc/sof/sof-priv.h | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 8d13eb13fe081..6d8f7d9fd1920 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -246,6 +246,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) if (plat_data->sof_probe_complete) plat_data->sof_probe_complete(sdev->dev); + sdev->probe_completed = true; + return 0; fw_trace_err: @@ -340,6 +342,14 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) } EXPORT_SYMBOL(snd_sof_device_probe); +bool snd_sof_device_probe_completed(struct device *dev) +{ + struct snd_sof_dev *sdev = dev_get_drvdata(dev); + + return sdev->probe_completed; +} +EXPORT_SYMBOL(snd_sof_device_probe_completed); + int snd_sof_device_remove(struct device *dev) { struct snd_sof_dev *sdev = dev_get_drvdata(dev); diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 388772f9c4d2d..84990cc8aa7de 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -447,7 +447,8 @@ static void sof_pci_remove(struct pci_dev *pci) snd_sof_device_remove(&pci->dev); /* follow recommendation in pci-driver.c to increment usage counter */ - if (!(sof_pci_debug & SOF_PCI_DISABLE_PM_RUNTIME)) + if (snd_sof_device_probe_completed(&pci->dev) && + !(sof_pci_debug & SOF_PCI_DISABLE_PM_RUNTIME)) pm_runtime_get_noresume(&pci->dev); /* release pci regions and disable device */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 682c4b6d01efb..ad0d7ba2708c7 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -389,6 +389,7 @@ struct snd_sof_dev { /* work queue in case the probe is implemented in two steps */ struct work_struct probe_work; + bool probe_completed; /* DSP HW differentiation */ struct snd_sof_pdata *pdata; @@ -464,6 +465,7 @@ struct snd_sof_dev { int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data); int snd_sof_device_remove(struct device *dev); int snd_sof_device_shutdown(struct device *dev); +bool snd_sof_device_probe_completed(struct device *dev); int snd_sof_runtime_suspend(struct device *dev); int snd_sof_runtime_resume(struct device *dev); -- GitLab From 1e30f642cf2939bbdac82ea0dd3071232670b5ab Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Wed, 10 Feb 2021 12:13:39 +0530 Subject: [PATCH 1065/1084] ASoC: simple-card-utils: Fix device module clock If "clocks = <&xxx>" is specified from the CPU or Codec component device node, the clock is not getting enabled. Thus audio playback or capture fails. Fix this by populating "simple_dai->clk" field when clocks property is specified from device node as well. Also tidy up by re-organising conditional statements of parsing logic. Fixes: bb6fc620c2ed ("ASoC: simple-card-utils: add asoc_simple_card_parse_clk()") Cc: Kuninori Morimoto Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1612939421-19900-2-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/generic/simple-card-utils.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 6cada4c1e283b..ab31045cfc952 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -172,16 +172,15 @@ int asoc_simple_parse_clk(struct device *dev, * or device's module clock. */ clk = devm_get_clk_from_child(dev, node, NULL); - if (!IS_ERR(clk)) { - simple_dai->sysclk = clk_get_rate(clk); + if (IS_ERR(clk)) + clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); + if (!IS_ERR(clk)) { simple_dai->clk = clk; - } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { + simple_dai->sysclk = clk_get_rate(clk); + } else if (!of_property_read_u32(node, "system-clock-frequency", + &val)) { simple_dai->sysclk = val; - } else { - clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); - if (!IS_ERR(clk)) - simple_dai->sysclk = clk_get_rate(clk); } if (of_property_read_bool(node, "system-clock-direction-out")) -- GitLab From 0be0f142b8323378df6358c36dd15494134f5b94 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Wed, 10 Feb 2021 12:13:40 +0530 Subject: [PATCH 1066/1084] ASoC: audio-graph-card: Drop device node clocks property An endpoint is not a device and it is recommended to use clocks property in the device node. Hence reverting the original change. Fixes: 531e5b7abbde ("ASoC: audio-graph-card: Add clocks property to endpoint node") Suggested-by: Rob Herring Cc: Kuninori Morimoto Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1612939421-19900-3-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/audio-graph-port.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml index 08ed8f52c9623..766e9109b2f77 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml +++ b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml @@ -33,9 +33,6 @@ properties: properties: remote-endpoint: maxItems: 1 - clocks: - maxItems: 1 - description: Describes the clock used by audio component. mclk-fs: description: | Multiplication factor between stream rate and codec mclk. -- GitLab From f133de9e32374841c5ed1ad5cf18ed14098a0f4c Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 11 Feb 2021 12:27:29 +0000 Subject: [PATCH 1067/1084] ASoC: qcom: dt-bindings: add bindings for lpass rx macro codec This binding is for LPASS has internal codec RX macro which is for connecting with SoundWire RX codecs like WCD938x. Signed-off-by: Srinivas Kandagatla Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210211122735.5691-2-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- .../bindings/sound/qcom,lpass-rx-macro.yaml | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml new file mode 100644 index 0000000000000..443d556caa694 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/qcom,lpass-rx-macro.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LPASS(Low Power Audio Subsystem) RX Macro audio codec DT bindings + +maintainers: + - Srinivas Kandagatla + +properties: + compatible: + const: qcom,sm8250-lpass-rx-macro + + reg: + maxItems: 1 + + "#sound-dai-cells": + const: 1 + + '#clock-cells': + const: 0 + + clocks: + maxItems: 5 + + clock-names: + items: + - const: mclk + - const: npl + - const: macro + - const: dcodec + - const: fsgen + + clock-output-names: + items: + - const: mclk + +required: + - compatible + - reg + - "#sound-dai-cells" + +additionalProperties: false + +examples: + - | + #include + codec@3200000 { + compatible = "qcom,sm8250-lpass-rx-macro"; + reg = <0x3200000 0x1000>; + #sound-dai-cells = <1>; + #clock-cells = <0>; + clocks = <&audiocc 0>, + <&audiocc 1>, + <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&vamacro>; + clock-names = "mclk", "npl", "macro", "dcodec", "fsgen"; + clock-output-names = "mclk"; + }; -- GitLab From af3d54b99764f0bdd83fcbd1895d23b83f8276be Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 11 Feb 2021 12:27:30 +0000 Subject: [PATCH 1068/1084] ASoC: codecs: lpass-rx-macro: add support for lpass rx macro LPASS RX Codec Macro is available in Qualcomm LPASS (Low Power Audio SubSystem). This is used for connecting with SoundWire devices like WCD938x Codecs to provide headphone/ear/lineout functionality. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210211122735.5691-3-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/lpass-rx-macro.c | 1994 +++++++++++++++++++++++++++++ 3 files changed, 2001 insertions(+) create mode 100644 sound/soc/codecs/lpass-rx-macro.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f9ce7bb654a5e..5fb5a5a2c605d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -228,6 +228,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_UDA1380 imply SND_SOC_WCD9335 imply SND_SOC_WCD934X + imply SND_SOC_LPASS_RX_MACRO imply SND_SOC_WL1273 imply SND_SOC_WM0010 imply SND_SOC_WM1250_EV1 @@ -1833,4 +1834,8 @@ config SND_SOC_LPASS_VA_MACRO depends on COMMON_CLK tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)" +config SND_SOC_LPASS_RX_MACRO + depends on COMMON_CLK + tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)" + endmenu diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index d5c7eb3544a57..004ffcbe0b986 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -107,6 +107,7 @@ snd-soc-l3-objs := l3.o snd-soc-lm4857-objs := lm4857.o snd-soc-lm49453-objs := lm49453.o snd-soc-lochnagar-sc-objs := lochnagar-sc.o +snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o snd-soc-lpass-va-macro-objs := lpass-va-macro.o snd-soc-madera-objs := madera.o @@ -625,6 +626,7 @@ obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o +obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o # Mux obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c new file mode 100644 index 0000000000000..1c114a46c44af --- /dev/null +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -0,0 +1,1994 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CDC_RX_TOP_TOP_CFG0 (0x0000) +#define CDC_RX_TOP_SWR_CTRL (0x0008) +#define CDC_RX_TOP_DEBUG (0x000C) +#define CDC_RX_TOP_DEBUG_BUS (0x0010) +#define CDC_RX_TOP_DEBUG_EN0 (0x0014) +#define CDC_RX_TOP_DEBUG_EN1 (0x0018) +#define CDC_RX_TOP_DEBUG_EN2 (0x001C) +#define CDC_RX_TOP_HPHL_COMP_WR_LSB (0x0020) +#define CDC_RX_TOP_HPHL_COMP_WR_MSB (0x0024) +#define CDC_RX_TOP_HPHL_COMP_LUT (0x0028) +#define CDC_RX_TOP_HPH_LUT_BYPASS_MASK BIT(7) +#define CDC_RX_TOP_HPHL_COMP_RD_LSB (0x002C) +#define CDC_RX_TOP_HPHL_COMP_RD_MSB (0x0030) +#define CDC_RX_TOP_HPHR_COMP_WR_LSB (0x0034) +#define CDC_RX_TOP_HPHR_COMP_WR_MSB (0x0038) +#define CDC_RX_TOP_HPHR_COMP_LUT (0x003C) +#define CDC_RX_TOP_HPHR_COMP_RD_LSB (0x0040) +#define CDC_RX_TOP_HPHR_COMP_RD_MSB (0x0044) +#define CDC_RX_TOP_DSD0_DEBUG_CFG0 (0x0070) +#define CDC_RX_TOP_DSD0_DEBUG_CFG1 (0x0074) +#define CDC_RX_TOP_DSD0_DEBUG_CFG2 (0x0078) +#define CDC_RX_TOP_DSD0_DEBUG_CFG3 (0x007C) +#define CDC_RX_TOP_DSD1_DEBUG_CFG0 (0x0080) +#define CDC_RX_TOP_DSD1_DEBUG_CFG1 (0x0084) +#define CDC_RX_TOP_DSD1_DEBUG_CFG2 (0x0088) +#define CDC_RX_TOP_DSD1_DEBUG_CFG3 (0x008C) +#define CDC_RX_TOP_RX_I2S_CTL (0x0090) +#define CDC_RX_TOP_TX_I2S2_CTL (0x0094) +#define CDC_RX_TOP_I2S_CLK (0x0098) +#define CDC_RX_TOP_I2S_RESET (0x009C) +#define CDC_RX_TOP_I2S_MUX (0x00A0) +#define CDC_RX_CLK_RST_CTRL_MCLK_CONTROL (0x0100) +#define CDC_RX_CLK_MCLK_EN_MASK BIT(0) +#define CDC_RX_CLK_MCLK_ENABLE BIT(0) +#define CDC_RX_CLK_MCLK2_EN_MASK BIT(1) +#define CDC_RX_CLK_MCLK2_ENABLE BIT(1) +#define CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL (0x0104) +#define CDC_RX_FS_MCLK_CNT_EN_MASK BIT(0) +#define CDC_RX_FS_MCLK_CNT_ENABLE BIT(0) +#define CDC_RX_FS_MCLK_CNT_CLR_MASK BIT(1) +#define CDC_RX_FS_MCLK_CNT_CLR BIT(1) +#define CDC_RX_CLK_RST_CTRL_SWR_CONTROL (0x0108) +#define CDC_RX_SWR_CLK_EN_MASK BIT(0) +#define CDC_RX_SWR_RESET_MASK BIT(1) +#define CDC_RX_SWR_RESET BIT(1) +#define CDC_RX_CLK_RST_CTRL_DSD_CONTROL (0x010C) +#define CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL (0x0110) +#define CDC_RX_SOFTCLIP_CRC (0x0140) +#define CDC_RX_SOFTCLIP_CLK_EN_MASK BIT(0) +#define CDC_RX_SOFTCLIP_SOFTCLIP_CTRL (0x0144) +#define CDC_RX_SOFTCLIP_EN_MASK BIT(0) +#define CDC_RX_INP_MUX_RX_INT0_CFG0 (0x0180) +#define CDC_RX_INTX_1_MIX_INP0_SEL_MASK GENMASK(3, 0) +#define CDC_RX_INTX_1_MIX_INP1_SEL_MASK GENMASK(7, 4) +#define CDC_RX_INP_MUX_RX_INT0_CFG1 (0x0184) +#define CDC_RX_INTX_2_SEL_MASK GENMASK(3, 0) +#define CDC_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(7, 4) +#define CDC_RX_INP_MUX_RX_INT1_CFG0 (0x0188) +#define CDC_RX_INP_MUX_RX_INT1_CFG1 (0x018C) +#define CDC_RX_INP_MUX_RX_INT2_CFG0 (0x0190) +#define CDC_RX_INP_MUX_RX_INT2_CFG1 (0x0194) +#define CDC_RX_INP_MUX_RX_MIX_CFG4 (0x0198) +#define CDC_RX_INP_MUX_RX_MIX_CFG5 (0x019C) +#define CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (0x01A0) +#define CDC_RX_CLSH_CRC (0x0200) +#define CDC_RX_CLSH_CLK_EN_MASK BIT(0) +#define CDC_RX_CLSH_DLY_CTRL (0x0204) +#define CDC_RX_CLSH_DECAY_CTRL (0x0208) +#define CDC_RX_CLSH_DECAY_RATE_MASK GENMASK(2, 0) +#define CDC_RX_CLSH_HPH_V_PA (0x020C) +#define CDC_RX_CLSH_HPH_V_PA_MIN_MASK GENMASK(5, 0) +#define CDC_RX_CLSH_EAR_V_PA (0x0210) +#define CDC_RX_CLSH_HPH_V_HD (0x0214) +#define CDC_RX_CLSH_EAR_V_HD (0x0218) +#define CDC_RX_CLSH_K1_MSB (0x021C) +#define CDC_RX_CLSH_K1_MSB_COEFF_MASK GENMASK(3, 0) +#define CDC_RX_CLSH_K1_LSB (0x0220) +#define CDC_RX_CLSH_K2_MSB (0x0224) +#define CDC_RX_CLSH_K2_LSB (0x0228) +#define CDC_RX_CLSH_IDLE_CTRL (0x022C) +#define CDC_RX_CLSH_IDLE_HPH (0x0230) +#define CDC_RX_CLSH_IDLE_EAR (0x0234) +#define CDC_RX_CLSH_TEST0 (0x0238) +#define CDC_RX_CLSH_TEST1 (0x023C) +#define CDC_RX_CLSH_OVR_VREF (0x0240) +#define CDC_RX_CLSH_CLSG_CTL (0x0244) +#define CDC_RX_CLSH_CLSG_CFG1 (0x0248) +#define CDC_RX_CLSH_CLSG_CFG2 (0x024C) +#define CDC_RX_BCL_VBAT_PATH_CTL (0x0280) +#define CDC_RX_BCL_VBAT_CFG (0x0284) +#define CDC_RX_BCL_VBAT_ADC_CAL1 (0x0288) +#define CDC_RX_BCL_VBAT_ADC_CAL2 (0x028C) +#define CDC_RX_BCL_VBAT_ADC_CAL3 (0x0290) +#define CDC_RX_BCL_VBAT_PK_EST1 (0x0294) +#define CDC_RX_BCL_VBAT_PK_EST2 (0x0298) +#define CDC_RX_BCL_VBAT_PK_EST3 (0x029C) +#define CDC_RX_BCL_VBAT_RF_PROC1 (0x02A0) +#define CDC_RX_BCL_VBAT_RF_PROC2 (0x02A4) +#define CDC_RX_BCL_VBAT_TAC1 (0x02A8) +#define CDC_RX_BCL_VBAT_TAC2 (0x02AC) +#define CDC_RX_BCL_VBAT_TAC3 (0x02B0) +#define CDC_RX_BCL_VBAT_TAC4 (0x02B4) +#define CDC_RX_BCL_VBAT_GAIN_UPD1 (0x02B8) +#define CDC_RX_BCL_VBAT_GAIN_UPD2 (0x02BC) +#define CDC_RX_BCL_VBAT_GAIN_UPD3 (0x02C0) +#define CDC_RX_BCL_VBAT_GAIN_UPD4 (0x02C4) +#define CDC_RX_BCL_VBAT_GAIN_UPD5 (0x02C8) +#define CDC_RX_BCL_VBAT_DEBUG1 (0x02CC) +#define CDC_RX_BCL_VBAT_GAIN_UPD_MON (0x02D0) +#define CDC_RX_BCL_VBAT_GAIN_MON_VAL (0x02D4) +#define CDC_RX_BCL_VBAT_BAN (0x02D8) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD1 (0x02DC) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD2 (0x02E0) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD3 (0x02E4) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD4 (0x02E8) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD5 (0x02EC) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD6 (0x02F0) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD7 (0x02F4) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD8 (0x02F8) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD9 (0x02FC) +#define CDC_RX_BCL_VBAT_ATTN1 (0x0300) +#define CDC_RX_BCL_VBAT_ATTN2 (0x0304) +#define CDC_RX_BCL_VBAT_ATTN3 (0x0308) +#define CDC_RX_BCL_VBAT_DECODE_CTL1 (0x030C) +#define CDC_RX_BCL_VBAT_DECODE_CTL2 (0x0310) +#define CDC_RX_BCL_VBAT_DECODE_CFG1 (0x0314) +#define CDC_RX_BCL_VBAT_DECODE_CFG2 (0x0318) +#define CDC_RX_BCL_VBAT_DECODE_CFG3 (0x031C) +#define CDC_RX_BCL_VBAT_DECODE_CFG4 (0x0320) +#define CDC_RX_BCL_VBAT_DECODE_ST (0x0324) +#define CDC_RX_INTR_CTRL_CFG (0x0340) +#define CDC_RX_INTR_CTRL_CLR_COMMIT (0x0344) +#define CDC_RX_INTR_CTRL_PIN1_MASK0 (0x0360) +#define CDC_RX_INTR_CTRL_PIN1_STATUS0 (0x0368) +#define CDC_RX_INTR_CTRL_PIN1_CLEAR0 (0x0370) +#define CDC_RX_INTR_CTRL_PIN2_MASK0 (0x0380) +#define CDC_RX_INTR_CTRL_PIN2_STATUS0 (0x0388) +#define CDC_RX_INTR_CTRL_PIN2_CLEAR0 (0x0390) +#define CDC_RX_INTR_CTRL_LEVEL0 (0x03C0) +#define CDC_RX_INTR_CTRL_BYPASS0 (0x03C8) +#define CDC_RX_INTR_CTRL_SET0 (0x03D0) +#define CDC_RX_RXn_RX_PATH_CTL(n) (0x0400 + 0x80 * n) +#define CDC_RX_RX0_RX_PATH_CTL (0x0400) +#define CDC_RX_PATH_RESET_EN_MASK BIT(6) +#define CDC_RX_PATH_CLK_EN_MASK BIT(5) +#define CDC_RX_PATH_CLK_ENABLE BIT(5) +#define CDC_RX_PATH_PGA_MUTE_MASK BIT(4) +#define CDC_RX_PATH_PGA_MUTE_ENABLE BIT(4) +#define CDC_RX_PATH_PCM_RATE_MASK GENMASK(3, 0) +#define CDC_RX_RXn_RX_PATH_CFG0(n) (0x0404 + 0x80 * n) +#define CDC_RX_RXn_COMP_EN_MASK BIT(1) +#define CDC_RX_RX0_RX_PATH_CFG0 (0x0404) +#define CDC_RX_RXn_CLSH_EN_MASK BIT(6) +#define CDC_RX_DLY_ZN_EN_MASK BIT(3) +#define CDC_RX_DLY_ZN_ENABLE BIT(3) +#define CDC_RX_RXn_HD2_EN_MASK BIT(2) +#define CDC_RX_RXn_RX_PATH_CFG1(n) (0x0408 + 0x80 * n) +#define CDC_RX_RXn_SIDETONE_EN_MASK BIT(4) +#define CDC_RX_RX0_RX_PATH_CFG1 (0x0408) +#define CDC_RX_RX0_HPH_L_EAR_SEL_MASK BIT(1) +#define CDC_RX_RXn_RX_PATH_CFG2(n) (0x040C + 0x80 * n) +#define CDC_RX_RXn_HPF_CUT_FREQ_MASK GENMASK(1, 0) +#define CDC_RX_RX0_RX_PATH_CFG2 (0x040C) +#define CDC_RX_RXn_RX_PATH_CFG3(n) (0x0410 + 0x80 * n) +#define CDC_RX_RX0_RX_PATH_CFG3 (0x0410) +#define CDC_RX_DC_COEFF_SEL_MASK GENMASK(1, 0) +#define CDC_RX_DC_COEFF_SEL_TWO 0x2 +#define CDC_RX_RXn_RX_VOL_CTL(n) (0x0414 + 0x80 * n) +#define CDC_RX_RX0_RX_VOL_CTL (0x0414) +#define CDC_RX_RXn_RX_PATH_MIX_CTL(n) (0x0418 + 0x80 * n) +#define CDC_RX_RXn_MIX_PCM_RATE_MASK GENMASK(3, 0) +#define CDC_RX_RXn_MIX_RESET_MASK BIT(6) +#define CDC_RX_RXn_MIX_RESET BIT(6) +#define CDC_RX_RXn_MIX_CLK_EN_MASK BIT(5) +#define CDC_RX_RX0_RX_PATH_MIX_CTL (0x0418) +#define CDC_RX_RX0_RX_PATH_MIX_CFG (0x041C) +#define CDC_RX_RXn_RX_VOL_MIX_CTL(n) (0x0420 + 0x80 * n) +#define CDC_RX_RX0_RX_VOL_MIX_CTL (0x0420) +#define CDC_RX_RX0_RX_PATH_SEC1 (0x0424) +#define CDC_RX_RX0_RX_PATH_SEC2 (0x0428) +#define CDC_RX_RX0_RX_PATH_SEC3 (0x042C) +#define CDC_RX_RX0_RX_PATH_SEC4 (0x0430) +#define CDC_RX_RX0_RX_PATH_SEC7 (0x0434) +#define CDC_RX_DSM_OUT_DELAY_SEL_MASK GENMASK(2, 0) +#define CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE 0x2 +#define CDC_RX_RX0_RX_PATH_MIX_SEC0 (0x0438) +#define CDC_RX_RX0_RX_PATH_MIX_SEC1 (0x043C) +#define CDC_RX_RXn_RX_PATH_DSM_CTL(n) (0x0440 + 0x80 * n) +#define CDC_RX_RXn_DSM_CLK_EN_MASK BIT(0) +#define CDC_RX_RX0_RX_PATH_DSM_CTL (0x0440) +#define CDC_RX_RX0_RX_PATH_DSM_DATA1 (0x0444) +#define CDC_RX_RX0_RX_PATH_DSM_DATA2 (0x0448) +#define CDC_RX_RX0_RX_PATH_DSM_DATA3 (0x044C) +#define CDC_RX_RX0_RX_PATH_DSM_DATA4 (0x0450) +#define CDC_RX_RX0_RX_PATH_DSM_DATA5 (0x0454) +#define CDC_RX_RX0_RX_PATH_DSM_DATA6 (0x0458) +#define CDC_RX_RX1_RX_PATH_CTL (0x0480) +#define CDC_RX_RX1_RX_PATH_CFG0 (0x0484) +#define CDC_RX_RX1_RX_PATH_CFG1 (0x0488) +#define CDC_RX_RX1_RX_PATH_CFG2 (0x048C) +#define CDC_RX_RX1_RX_PATH_CFG3 (0x0490) +#define CDC_RX_RX1_RX_VOL_CTL (0x0494) +#define CDC_RX_RX1_RX_PATH_MIX_CTL (0x0498) +#define CDC_RX_RX1_RX_PATH_MIX_CFG (0x049C) +#define CDC_RX_RX1_RX_VOL_MIX_CTL (0x04A0) +#define CDC_RX_RX1_RX_PATH_SEC1 (0x04A4) +#define CDC_RX_RX1_RX_PATH_SEC2 (0x04A8) +#define CDC_RX_RX1_RX_PATH_SEC3 (0x04AC) +#define CDC_RX_RXn_HD2_ALPHA_MASK GENMASK(5, 2) +#define CDC_RX_RX1_RX_PATH_SEC4 (0x04B0) +#define CDC_RX_RX1_RX_PATH_SEC7 (0x04B4) +#define CDC_RX_RX1_RX_PATH_MIX_SEC0 (0x04B8) +#define CDC_RX_RX1_RX_PATH_MIX_SEC1 (0x04BC) +#define CDC_RX_RX1_RX_PATH_DSM_CTL (0x04C0) +#define CDC_RX_RX1_RX_PATH_DSM_DATA1 (0x04C4) +#define CDC_RX_RX1_RX_PATH_DSM_DATA2 (0x04C8) +#define CDC_RX_RX1_RX_PATH_DSM_DATA3 (0x04CC) +#define CDC_RX_RX1_RX_PATH_DSM_DATA4 (0x04D0) +#define CDC_RX_RX1_RX_PATH_DSM_DATA5 (0x04D4) +#define CDC_RX_RX1_RX_PATH_DSM_DATA6 (0x04D8) +#define CDC_RX_RX2_RX_PATH_CTL (0x0500) +#define CDC_RX_RX2_RX_PATH_CFG0 (0x0504) +#define CDC_RX_RX2_CLSH_EN_MASK BIT(4) +#define CDC_RX_RX2_DLY_Z_EN_MASK BIT(3) +#define CDC_RX_RX2_RX_PATH_CFG1 (0x0508) +#define CDC_RX_RX2_RX_PATH_CFG2 (0x050C) +#define CDC_RX_RX2_RX_PATH_CFG3 (0x0510) +#define CDC_RX_RX2_RX_VOL_CTL (0x0514) +#define CDC_RX_RX2_RX_PATH_MIX_CTL (0x0518) +#define CDC_RX_RX2_RX_PATH_MIX_CFG (0x051C) +#define CDC_RX_RX2_RX_VOL_MIX_CTL (0x0520) +#define CDC_RX_RX2_RX_PATH_SEC0 (0x0524) +#define CDC_RX_RX2_RX_PATH_SEC1 (0x0528) +#define CDC_RX_RX2_RX_PATH_SEC2 (0x052C) +#define CDC_RX_RX2_RX_PATH_SEC3 (0x0530) +#define CDC_RX_RX2_RX_PATH_SEC4 (0x0534) +#define CDC_RX_RX2_RX_PATH_SEC5 (0x0538) +#define CDC_RX_RX2_RX_PATH_SEC6 (0x053C) +#define CDC_RX_RX2_RX_PATH_SEC7 (0x0540) +#define CDC_RX_RX2_RX_PATH_MIX_SEC0 (0x0544) +#define CDC_RX_RX2_RX_PATH_MIX_SEC1 (0x0548) +#define CDC_RX_RX2_RX_PATH_DSM_CTL (0x054C) +#define CDC_RX_IDLE_DETECT_PATH_CTL (0x0780) +#define CDC_RX_IDLE_DETECT_CFG0 (0x0784) +#define CDC_RX_IDLE_DETECT_CFG1 (0x0788) +#define CDC_RX_IDLE_DETECT_CFG2 (0x078C) +#define CDC_RX_IDLE_DETECT_CFG3 (0x0790) +#define CDC_RX_COMPANDERn_CTL0(n) (0x0800 + 0x40 * n) +#define CDC_RX_COMPANDERn_CLK_EN_MASK BIT(0) +#define CDC_RX_COMPANDERn_SOFT_RST_MASK BIT(1) +#define CDC_RX_COMPANDERn_HALT_MASK BIT(2) +#define CDC_RX_COMPANDER0_CTL0 (0x0800) +#define CDC_RX_COMPANDER0_CTL1 (0x0804) +#define CDC_RX_COMPANDER0_CTL2 (0x0808) +#define CDC_RX_COMPANDER0_CTL3 (0x080C) +#define CDC_RX_COMPANDER0_CTL4 (0x0810) +#define CDC_RX_COMPANDER0_CTL5 (0x0814) +#define CDC_RX_COMPANDER0_CTL6 (0x0818) +#define CDC_RX_COMPANDER0_CTL7 (0x081C) +#define CDC_RX_COMPANDER1_CTL0 (0x0840) +#define CDC_RX_COMPANDER1_CTL1 (0x0844) +#define CDC_RX_COMPANDER1_CTL2 (0x0848) +#define CDC_RX_COMPANDER1_CTL3 (0x084C) +#define CDC_RX_COMPANDER1_CTL4 (0x0850) +#define CDC_RX_COMPANDER1_CTL5 (0x0854) +#define CDC_RX_COMPANDER1_CTL6 (0x0858) +#define CDC_RX_COMPANDER1_CTL7 (0x085C) +#define CDC_RX_COMPANDER1_HPH_LOW_PWR_MODE_MASK BIT(5) +#define CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL (0x0A00) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL (0x0A04) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL (0x0A08) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL (0x0A0C) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL (0x0A10) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL (0x0A14) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL (0x0A18) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL (0x0A1C) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL (0x0A20) +#define CDC_RX_SIDETONE_IIR0_IIR_CTL (0x0A24) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL (0x0A28) +#define CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL (0x0A2C) +#define CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL (0x0A30) +#define CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL (0x0A80) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL (0x0A84) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL (0x0A88) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL (0x0A8C) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL (0x0A90) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL (0x0A94) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL (0x0A98) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL (0x0A9C) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL (0x0AA0) +#define CDC_RX_SIDETONE_IIR1_IIR_CTL (0x0AA4) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL (0x0AA8) +#define CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL (0x0AAC) +#define CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL (0x0AB0) +#define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0 (0x0B00) +#define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1 (0x0B04) +#define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2 (0x0B08) +#define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3 (0x0B0C) +#define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0 (0x0B10) +#define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1 (0x0B14) +#define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2 (0x0B18) +#define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3 (0x0B1C) +#define CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL (0x0B40) +#define CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1 (0x0B44) +#define CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL (0x0B50) +#define CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1 (0x0B54) +#define CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL (0x0C00) +#define CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 (0x0C04) +#define CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL (0x0C40) +#define CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0 (0x0C44) +#define CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL (0x0C80) +#define CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0 (0x0C84) +#define CDC_RX_EC_ASRC0_CLK_RST_CTL (0x0D00) +#define CDC_RX_EC_ASRC0_CTL0 (0x0D04) +#define CDC_RX_EC_ASRC0_CTL1 (0x0D08) +#define CDC_RX_EC_ASRC0_FIFO_CTL (0x0D0C) +#define CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB (0x0D10) +#define CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB (0x0D14) +#define CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB (0x0D18) +#define CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB (0x0D1C) +#define CDC_RX_EC_ASRC0_STATUS_FIFO (0x0D20) +#define CDC_RX_EC_ASRC1_CLK_RST_CTL (0x0D40) +#define CDC_RX_EC_ASRC1_CTL0 (0x0D44) +#define CDC_RX_EC_ASRC1_CTL1 (0x0D48) +#define CDC_RX_EC_ASRC1_FIFO_CTL (0x0D4C) +#define CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB (0x0D50) +#define CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB (0x0D54) +#define CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB (0x0D58) +#define CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB (0x0D5C) +#define CDC_RX_EC_ASRC1_STATUS_FIFO (0x0D60) +#define CDC_RX_EC_ASRC2_CLK_RST_CTL (0x0D80) +#define CDC_RX_EC_ASRC2_CTL0 (0x0D84) +#define CDC_RX_EC_ASRC2_CTL1 (0x0D88) +#define CDC_RX_EC_ASRC2_FIFO_CTL (0x0D8C) +#define CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB (0x0D90) +#define CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB (0x0D94) +#define CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB (0x0D98) +#define CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB (0x0D9C) +#define CDC_RX_EC_ASRC2_STATUS_FIFO (0x0DA0) +#define CDC_RX_DSD0_PATH_CTL (0x0F00) +#define CDC_RX_DSD0_CFG0 (0x0F04) +#define CDC_RX_DSD0_CFG1 (0x0F08) +#define CDC_RX_DSD0_CFG2 (0x0F0C) +#define CDC_RX_DSD1_PATH_CTL (0x0F80) +#define CDC_RX_DSD1_CFG0 (0x0F84) +#define CDC_RX_DSD1_CFG1 (0x0F88) +#define CDC_RX_DSD1_CFG2 (0x0F8C) +#define RX_MAX_OFFSET (0x0F8C) + +#define MCLK_FREQ 9600000 + +#define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ + SNDRV_PCM_RATE_384000) +/* Fractional Rates */ +#define RX_MACRO_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800) + +#define RX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + +#define RX_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_48000) +#define RX_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define RX_MACRO_MAX_DMA_CH_PER_PORT 2 + +#define RX_MACRO_EC_MIX_TX0_MASK 0xf0 +#define RX_MACRO_EC_MIX_TX1_MASK 0x0f +#define RX_MACRO_EC_MIX_TX2_MASK 0x0f + +#define COMP_MAX_COEFF 25 +#define RX_NUM_CLKS_MAX 5 + +struct comp_coeff_val { + u8 lsb; + u8 msb; +}; + +enum { + HPH_ULP, + HPH_LOHIFI, + HPH_MODE_MAX, +}; + +static const struct comp_coeff_val comp_coeff_table[HPH_MODE_MAX][COMP_MAX_COEFF] = { + { + {0x40, 0x00}, + {0x4C, 0x00}, + {0x5A, 0x00}, + {0x6B, 0x00}, + {0x7F, 0x00}, + {0x97, 0x00}, + {0xB3, 0x00}, + {0xD5, 0x00}, + {0xFD, 0x00}, + {0x2D, 0x01}, + {0x66, 0x01}, + {0xA7, 0x01}, + {0xF8, 0x01}, + {0x57, 0x02}, + {0xC7, 0x02}, + {0x4B, 0x03}, + {0xE9, 0x03}, + {0xA3, 0x04}, + {0x7D, 0x05}, + {0x90, 0x06}, + {0xD1, 0x07}, + {0x49, 0x09}, + {0x00, 0x0B}, + {0x01, 0x0D}, + {0x59, 0x0F}, + }, + { + {0x40, 0x00}, + {0x4C, 0x00}, + {0x5A, 0x00}, + {0x6B, 0x00}, + {0x80, 0x00}, + {0x98, 0x00}, + {0xB4, 0x00}, + {0xD5, 0x00}, + {0xFE, 0x00}, + {0x2E, 0x01}, + {0x66, 0x01}, + {0xA9, 0x01}, + {0xF8, 0x01}, + {0x56, 0x02}, + {0xC4, 0x02}, + {0x4F, 0x03}, + {0xF0, 0x03}, + {0xAE, 0x04}, + {0x8B, 0x05}, + {0x8E, 0x06}, + {0xBC, 0x07}, + {0x56, 0x09}, + {0x0F, 0x0B}, + {0x13, 0x0D}, + {0x6F, 0x0F}, + }, +}; + +struct rx_macro_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +enum { + INTERP_HPHL, + INTERP_HPHR, + INTERP_AUX, + INTERP_MAX +}; + +enum { + RX_MACRO_RX0, + RX_MACRO_RX1, + RX_MACRO_RX2, + RX_MACRO_RX3, + RX_MACRO_RX4, + RX_MACRO_RX5, + RX_MACRO_PORTS_MAX +}; + +enum { + RX_MACRO_COMP1, /* HPH_L */ + RX_MACRO_COMP2, /* HPH_R */ + RX_MACRO_COMP_MAX +}; + +enum { + RX_MACRO_EC0_MUX = 0, + RX_MACRO_EC1_MUX, + RX_MACRO_EC2_MUX, + RX_MACRO_EC_MUX_MAX, +}; + +enum { + INTn_1_INP_SEL_ZERO = 0, + INTn_1_INP_SEL_DEC0, + INTn_1_INP_SEL_DEC1, + INTn_1_INP_SEL_IIR0, + INTn_1_INP_SEL_IIR1, + INTn_1_INP_SEL_RX0, + INTn_1_INP_SEL_RX1, + INTn_1_INP_SEL_RX2, + INTn_1_INP_SEL_RX3, + INTn_1_INP_SEL_RX4, + INTn_1_INP_SEL_RX5, +}; + +enum { + INTn_2_INP_SEL_ZERO = 0, + INTn_2_INP_SEL_RX0, + INTn_2_INP_SEL_RX1, + INTn_2_INP_SEL_RX2, + INTn_2_INP_SEL_RX3, + INTn_2_INP_SEL_RX4, + INTn_2_INP_SEL_RX5, +}; + +enum { + INTERP_MAIN_PATH, + INTERP_MIX_PATH, +}; + +struct interp_sample_rate { + int sample_rate; + int rate_val; +}; + +static struct interp_sample_rate sr_val_tbl[] = { + {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, + {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, + {176400, 0xB}, {352800, 0xC}, +}; + +enum { + RX_MACRO_AIF_INVALID = 0, + RX_MACRO_AIF1_PB, + RX_MACRO_AIF2_PB, + RX_MACRO_AIF3_PB, + RX_MACRO_AIF4_PB, + RX_MACRO_AIF_ECHO, + RX_MACRO_MAX_DAIS, +}; + +enum { + RX_MACRO_AIF1_CAP = 0, + RX_MACRO_AIF2_CAP, + RX_MACRO_AIF3_CAP, + RX_MACRO_MAX_AIF_CAP_DAIS +}; + +struct rx_macro { + struct device *dev; + int comp_enabled[RX_MACRO_COMP_MAX]; + /* Main path clock users count */ + int main_clk_users[INTERP_MAX]; + int rx_port_value[RX_MACRO_PORTS_MAX]; + u16 prim_int_users[INTERP_MAX]; + int rx_mclk_users; + bool reset_swr; + int clsh_users; + int rx_mclk_cnt; + bool is_ear_mode_on; + bool hph_pwr_mode; + bool hph_hd2_mode; + struct snd_soc_component *component; + unsigned long active_ch_mask[RX_MACRO_MAX_DAIS]; + unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS]; + u16 bit_width[RX_MACRO_MAX_DAIS]; + int is_softclip_on; + int is_aux_hpf_on; + int softclip_clk_users; + + struct regmap *regmap; + struct clk_bulk_data clks[RX_NUM_CLKS_MAX]; + struct clk_hw hw; +}; +#define to_rx_macro(_hw) container_of(_hw, struct rx_macro, hw) + +static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); + +static const char *const rx_macro_hph_pwr_mode_text[] = { + "ULP", "LOHIFI" +}; + +static const struct soc_enum rx_macro_hph_pwr_mode_enum = + SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text); + +static const struct reg_default rx_defaults[] = { + /* RX Macro */ + { CDC_RX_TOP_TOP_CFG0, 0x00 }, + { CDC_RX_TOP_SWR_CTRL, 0x00 }, + { CDC_RX_TOP_DEBUG, 0x00 }, + { CDC_RX_TOP_DEBUG_BUS, 0x00 }, + { CDC_RX_TOP_DEBUG_EN0, 0x00 }, + { CDC_RX_TOP_DEBUG_EN1, 0x00 }, + { CDC_RX_TOP_DEBUG_EN2, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_WR_LSB, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_WR_MSB, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_LUT, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_RD_LSB, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_RD_MSB, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_WR_LSB, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_WR_MSB, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_LUT, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_RD_LSB, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_RD_MSB, 0x00 }, + { CDC_RX_TOP_DSD0_DEBUG_CFG0, 0x11 }, + { CDC_RX_TOP_DSD0_DEBUG_CFG1, 0x20 }, + { CDC_RX_TOP_DSD0_DEBUG_CFG2, 0x00 }, + { CDC_RX_TOP_DSD0_DEBUG_CFG3, 0x00 }, + { CDC_RX_TOP_DSD1_DEBUG_CFG0, 0x11 }, + { CDC_RX_TOP_DSD1_DEBUG_CFG1, 0x20 }, + { CDC_RX_TOP_DSD1_DEBUG_CFG2, 0x00 }, + { CDC_RX_TOP_DSD1_DEBUG_CFG3, 0x00 }, + { CDC_RX_TOP_RX_I2S_CTL, 0x0C }, + { CDC_RX_TOP_TX_I2S2_CTL, 0x0C }, + { CDC_RX_TOP_I2S_CLK, 0x0C }, + { CDC_RX_TOP_I2S_RESET, 0x00 }, + { CDC_RX_TOP_I2S_MUX, 0x00 }, + { CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, + { CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, + { CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x00 }, + { CDC_RX_CLK_RST_CTRL_DSD_CONTROL, 0x00 }, + { CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x08 }, + { CDC_RX_SOFTCLIP_CRC, 0x00 }, + { CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x38 }, + { CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00 }, + { CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00 }, + { CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00 }, + { CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00 }, + { CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00 }, + { CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00 }, + { CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00 }, + { CDC_RX_INP_MUX_RX_MIX_CFG5, 0x00 }, + { CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00 }, + { CDC_RX_CLSH_CRC, 0x00 }, + { CDC_RX_CLSH_DLY_CTRL, 0x03 }, + { CDC_RX_CLSH_DECAY_CTRL, 0x02 }, + { CDC_RX_CLSH_HPH_V_PA, 0x1C }, + { CDC_RX_CLSH_EAR_V_PA, 0x39 }, + { CDC_RX_CLSH_HPH_V_HD, 0x0C }, + { CDC_RX_CLSH_EAR_V_HD, 0x0C }, + { CDC_RX_CLSH_K1_MSB, 0x01 }, + { CDC_RX_CLSH_K1_LSB, 0x00 }, + { CDC_RX_CLSH_K2_MSB, 0x00 }, + { CDC_RX_CLSH_K2_LSB, 0x80 }, + { CDC_RX_CLSH_IDLE_CTRL, 0x00 }, + { CDC_RX_CLSH_IDLE_HPH, 0x00 }, + { CDC_RX_CLSH_IDLE_EAR, 0x00 }, + { CDC_RX_CLSH_TEST0, 0x07 }, + { CDC_RX_CLSH_TEST1, 0x00 }, + { CDC_RX_CLSH_OVR_VREF, 0x00 }, + { CDC_RX_CLSH_CLSG_CTL, 0x02 }, + { CDC_RX_CLSH_CLSG_CFG1, 0x9A }, + { CDC_RX_CLSH_CLSG_CFG2, 0x10 }, + { CDC_RX_BCL_VBAT_PATH_CTL, 0x00 }, + { CDC_RX_BCL_VBAT_CFG, 0x10 }, + { CDC_RX_BCL_VBAT_ADC_CAL1, 0x00 }, + { CDC_RX_BCL_VBAT_ADC_CAL2, 0x00 }, + { CDC_RX_BCL_VBAT_ADC_CAL3, 0x04 }, + { CDC_RX_BCL_VBAT_PK_EST1, 0xE0 }, + { CDC_RX_BCL_VBAT_PK_EST2, 0x01 }, + { CDC_RX_BCL_VBAT_PK_EST3, 0x40 }, + { CDC_RX_BCL_VBAT_RF_PROC1, 0x2A }, + { CDC_RX_BCL_VBAT_RF_PROC1, 0x00 }, + { CDC_RX_BCL_VBAT_TAC1, 0x00 }, + { CDC_RX_BCL_VBAT_TAC2, 0x18 }, + { CDC_RX_BCL_VBAT_TAC3, 0x18 }, + { CDC_RX_BCL_VBAT_TAC4, 0x03 }, + { CDC_RX_BCL_VBAT_GAIN_UPD1, 0x01 }, + { CDC_RX_BCL_VBAT_GAIN_UPD2, 0x00 }, + { CDC_RX_BCL_VBAT_GAIN_UPD3, 0x00 }, + { CDC_RX_BCL_VBAT_GAIN_UPD4, 0x64 }, + { CDC_RX_BCL_VBAT_GAIN_UPD5, 0x01 }, + { CDC_RX_BCL_VBAT_DEBUG1, 0x00 }, + { CDC_RX_BCL_VBAT_GAIN_UPD_MON, 0x00 }, + { CDC_RX_BCL_VBAT_GAIN_MON_VAL, 0x00 }, + { CDC_RX_BCL_VBAT_BAN, 0x0C }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, 0x00 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, 0x77 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, 0x01 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, 0x00 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, 0x4B }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, 0x00 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, 0x01 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, 0x00 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, 0x00 }, + { CDC_RX_BCL_VBAT_ATTN1, 0x04 }, + { CDC_RX_BCL_VBAT_ATTN2, 0x08 }, + { CDC_RX_BCL_VBAT_ATTN3, 0x0C }, + { CDC_RX_BCL_VBAT_DECODE_CTL1, 0xE0 }, + { CDC_RX_BCL_VBAT_DECODE_CTL2, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_CFG1, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_CFG2, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_CFG3, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_CFG4, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_ST, 0x00 }, + { CDC_RX_INTR_CTRL_CFG, 0x00 }, + { CDC_RX_INTR_CTRL_CLR_COMMIT, 0x00 }, + { CDC_RX_INTR_CTRL_PIN1_MASK0, 0xFF }, + { CDC_RX_INTR_CTRL_PIN1_STATUS0, 0x00 }, + { CDC_RX_INTR_CTRL_PIN1_CLEAR0, 0x00 }, + { CDC_RX_INTR_CTRL_PIN2_MASK0, 0xFF }, + { CDC_RX_INTR_CTRL_PIN2_STATUS0, 0x00 }, + { CDC_RX_INTR_CTRL_PIN2_CLEAR0, 0x00 }, + { CDC_RX_INTR_CTRL_LEVEL0, 0x00 }, + { CDC_RX_INTR_CTRL_BYPASS0, 0x00 }, + { CDC_RX_INTR_CTRL_SET0, 0x00 }, + { CDC_RX_RX0_RX_PATH_CTL, 0x04 }, + { CDC_RX_RX0_RX_PATH_CFG0, 0x00 }, + { CDC_RX_RX0_RX_PATH_CFG1, 0x64 }, + { CDC_RX_RX0_RX_PATH_CFG2, 0x8F }, + { CDC_RX_RX0_RX_PATH_CFG3, 0x00 }, + { CDC_RX_RX0_RX_VOL_CTL, 0x00 }, + { CDC_RX_RX0_RX_PATH_MIX_CTL, 0x04 }, + { CDC_RX_RX0_RX_PATH_MIX_CFG, 0x7E }, + { CDC_RX_RX0_RX_VOL_MIX_CTL, 0x00 }, + { CDC_RX_RX0_RX_PATH_SEC1, 0x08 }, + { CDC_RX_RX0_RX_PATH_SEC2, 0x00 }, + { CDC_RX_RX0_RX_PATH_SEC3, 0x00 }, + { CDC_RX_RX0_RX_PATH_SEC4, 0x00 }, + { CDC_RX_RX0_RX_PATH_SEC7, 0x00 }, + { CDC_RX_RX0_RX_PATH_MIX_SEC0, 0x08 }, + { CDC_RX_RX0_RX_PATH_MIX_SEC1, 0x00 }, + { CDC_RX_RX0_RX_PATH_DSM_CTL, 0x08 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA1, 0x00 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA2, 0x00 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA3, 0x00 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA4, 0x55 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA5, 0x55 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA6, 0x55 }, + { CDC_RX_RX1_RX_PATH_CTL, 0x04 }, + { CDC_RX_RX1_RX_PATH_CFG0, 0x00 }, + { CDC_RX_RX1_RX_PATH_CFG1, 0x64 }, + { CDC_RX_RX1_RX_PATH_CFG2, 0x8F }, + { CDC_RX_RX1_RX_PATH_CFG3, 0x00 }, + { CDC_RX_RX1_RX_VOL_CTL, 0x00 }, + { CDC_RX_RX1_RX_PATH_MIX_CTL, 0x04 }, + { CDC_RX_RX1_RX_PATH_MIX_CFG, 0x7E }, + { CDC_RX_RX1_RX_VOL_MIX_CTL, 0x00 }, + { CDC_RX_RX1_RX_PATH_SEC1, 0x08 }, + { CDC_RX_RX1_RX_PATH_SEC2, 0x00 }, + { CDC_RX_RX1_RX_PATH_SEC3, 0x00 }, + { CDC_RX_RX1_RX_PATH_SEC4, 0x00 }, + { CDC_RX_RX1_RX_PATH_SEC7, 0x00 }, + { CDC_RX_RX1_RX_PATH_MIX_SEC0, 0x08 }, + { CDC_RX_RX1_RX_PATH_MIX_SEC1, 0x00 }, + { CDC_RX_RX1_RX_PATH_DSM_CTL, 0x08 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA1, 0x00 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA2, 0x00 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA3, 0x00 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA4, 0x55 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA5, 0x55 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA6, 0x55 }, + { CDC_RX_RX2_RX_PATH_CTL, 0x04 }, + { CDC_RX_RX2_RX_PATH_CFG0, 0x00 }, + { CDC_RX_RX2_RX_PATH_CFG1, 0x64 }, + { CDC_RX_RX2_RX_PATH_CFG2, 0x8F }, + { CDC_RX_RX2_RX_PATH_CFG3, 0x00 }, + { CDC_RX_RX2_RX_VOL_CTL, 0x00 }, + { CDC_RX_RX2_RX_PATH_MIX_CTL, 0x04 }, + { CDC_RX_RX2_RX_PATH_MIX_CFG, 0x7E }, + { CDC_RX_RX2_RX_VOL_MIX_CTL, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC0, 0x04 }, + { CDC_RX_RX2_RX_PATH_SEC1, 0x08 }, + { CDC_RX_RX2_RX_PATH_SEC2, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC3, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC4, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC5, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC6, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC7, 0x00 }, + { CDC_RX_RX2_RX_PATH_MIX_SEC0, 0x08 }, + { CDC_RX_RX2_RX_PATH_MIX_SEC1, 0x00 }, + { CDC_RX_RX2_RX_PATH_DSM_CTL, 0x00 }, + { CDC_RX_IDLE_DETECT_PATH_CTL, 0x00 }, + { CDC_RX_IDLE_DETECT_CFG0, 0x07 }, + { CDC_RX_IDLE_DETECT_CFG1, 0x3C }, + { CDC_RX_IDLE_DETECT_CFG2, 0x00 }, + { CDC_RX_IDLE_DETECT_CFG3, 0x00 }, + { CDC_RX_COMPANDER0_CTL0, 0x60 }, + { CDC_RX_COMPANDER0_CTL1, 0xDB }, + { CDC_RX_COMPANDER0_CTL2, 0xFF }, + { CDC_RX_COMPANDER0_CTL3, 0x35 }, + { CDC_RX_COMPANDER0_CTL4, 0xFF }, + { CDC_RX_COMPANDER0_CTL5, 0x00 }, + { CDC_RX_COMPANDER0_CTL6, 0x01 }, + { CDC_RX_COMPANDER0_CTL7, 0x28 }, + { CDC_RX_COMPANDER1_CTL0, 0x60 }, + { CDC_RX_COMPANDER1_CTL1, 0xDB }, + { CDC_RX_COMPANDER1_CTL2, 0xFF }, + { CDC_RX_COMPANDER1_CTL3, 0x35 }, + { CDC_RX_COMPANDER1_CTL4, 0xFF }, + { CDC_RX_COMPANDER1_CTL5, 0x00 }, + { CDC_RX_COMPANDER1_CTL6, 0x01 }, + { CDC_RX_COMPANDER1_CTL7, 0x28 }, + { CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_CTL, 0x40 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_CTL, 0x40 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0x00 }, + { CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04 }, + { CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00 }, + { CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, 0x04 }, + { CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1, 0x00 }, + { CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00 }, + { CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01 }, + { CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00 }, + { CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01 }, + { CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL, 0x00 }, + { CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0, 0x01 }, + { CDC_RX_EC_ASRC0_CLK_RST_CTL, 0x00 }, + { CDC_RX_EC_ASRC0_CTL0, 0x00 }, + { CDC_RX_EC_ASRC0_CTL1, 0x00 }, + { CDC_RX_EC_ASRC0_FIFO_CTL, 0xA8 }, + { CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC0_STATUS_FIFO, 0x00 }, + { CDC_RX_EC_ASRC1_CLK_RST_CTL, 0x00 }, + { CDC_RX_EC_ASRC1_CTL0, 0x00 }, + { CDC_RX_EC_ASRC1_CTL1, 0x00 }, + { CDC_RX_EC_ASRC1_FIFO_CTL, 0xA8 }, + { CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC1_STATUS_FIFO, 0x00 }, + { CDC_RX_EC_ASRC2_CLK_RST_CTL, 0x00 }, + { CDC_RX_EC_ASRC2_CTL0, 0x00 }, + { CDC_RX_EC_ASRC2_CTL1, 0x00 }, + { CDC_RX_EC_ASRC2_FIFO_CTL, 0xA8 }, + { CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC2_STATUS_FIFO, 0x00 }, + { CDC_RX_DSD0_PATH_CTL, 0x00 }, + { CDC_RX_DSD0_CFG0, 0x00 }, + { CDC_RX_DSD0_CFG1, 0x62 }, + { CDC_RX_DSD0_CFG2, 0x96 }, + { CDC_RX_DSD1_PATH_CTL, 0x00 }, + { CDC_RX_DSD1_CFG0, 0x00 }, + { CDC_RX_DSD1_CFG1, 0x62 }, + { CDC_RX_DSD1_CFG2, 0x96 }, +}; + +static bool rx_is_wronly_register(struct device *dev, + unsigned int reg) +{ + switch (reg) { + case CDC_RX_BCL_VBAT_GAIN_UPD_MON: + case CDC_RX_INTR_CTRL_CLR_COMMIT: + case CDC_RX_INTR_CTRL_PIN1_CLEAR0: + case CDC_RX_INTR_CTRL_PIN2_CLEAR0: + return true; + } + + return false; +} + +static bool rx_is_volatile_register(struct device *dev, unsigned int reg) +{ + /* Update volatile list for rx/tx macros */ + switch (reg) { + case CDC_RX_TOP_HPHL_COMP_RD_LSB: + case CDC_RX_TOP_HPHL_COMP_WR_LSB: + case CDC_RX_TOP_HPHL_COMP_RD_MSB: + case CDC_RX_TOP_HPHL_COMP_WR_MSB: + case CDC_RX_TOP_HPHR_COMP_RD_LSB: + case CDC_RX_TOP_HPHR_COMP_WR_LSB: + case CDC_RX_TOP_HPHR_COMP_RD_MSB: + case CDC_RX_TOP_HPHR_COMP_WR_MSB: + case CDC_RX_TOP_DSD0_DEBUG_CFG2: + case CDC_RX_TOP_DSD1_DEBUG_CFG2: + case CDC_RX_BCL_VBAT_GAIN_MON_VAL: + case CDC_RX_BCL_VBAT_DECODE_ST: + case CDC_RX_INTR_CTRL_PIN1_STATUS0: + case CDC_RX_INTR_CTRL_PIN2_STATUS0: + case CDC_RX_COMPANDER0_CTL6: + case CDC_RX_COMPANDER1_CTL6: + case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC0_STATUS_FIFO: + case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC1_STATUS_FIFO: + case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC2_STATUS_FIFO: + return true; + } + return false; +} + +static bool rx_is_rw_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CDC_RX_TOP_TOP_CFG0: + case CDC_RX_TOP_SWR_CTRL: + case CDC_RX_TOP_DEBUG: + case CDC_RX_TOP_DEBUG_BUS: + case CDC_RX_TOP_DEBUG_EN0: + case CDC_RX_TOP_DEBUG_EN1: + case CDC_RX_TOP_DEBUG_EN2: + case CDC_RX_TOP_HPHL_COMP_WR_LSB: + case CDC_RX_TOP_HPHL_COMP_WR_MSB: + case CDC_RX_TOP_HPHL_COMP_LUT: + case CDC_RX_TOP_HPHR_COMP_WR_LSB: + case CDC_RX_TOP_HPHR_COMP_WR_MSB: + case CDC_RX_TOP_HPHR_COMP_LUT: + case CDC_RX_TOP_DSD0_DEBUG_CFG0: + case CDC_RX_TOP_DSD0_DEBUG_CFG1: + case CDC_RX_TOP_DSD0_DEBUG_CFG3: + case CDC_RX_TOP_DSD1_DEBUG_CFG0: + case CDC_RX_TOP_DSD1_DEBUG_CFG1: + case CDC_RX_TOP_DSD1_DEBUG_CFG3: + case CDC_RX_TOP_RX_I2S_CTL: + case CDC_RX_TOP_TX_I2S2_CTL: + case CDC_RX_TOP_I2S_CLK: + case CDC_RX_TOP_I2S_RESET: + case CDC_RX_TOP_I2S_MUX: + case CDC_RX_CLK_RST_CTRL_MCLK_CONTROL: + case CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL: + case CDC_RX_CLK_RST_CTRL_SWR_CONTROL: + case CDC_RX_CLK_RST_CTRL_DSD_CONTROL: + case CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL: + case CDC_RX_SOFTCLIP_CRC: + case CDC_RX_SOFTCLIP_SOFTCLIP_CTRL: + case CDC_RX_INP_MUX_RX_INT0_CFG0: + case CDC_RX_INP_MUX_RX_INT0_CFG1: + case CDC_RX_INP_MUX_RX_INT1_CFG0: + case CDC_RX_INP_MUX_RX_INT1_CFG1: + case CDC_RX_INP_MUX_RX_INT2_CFG0: + case CDC_RX_INP_MUX_RX_INT2_CFG1: + case CDC_RX_INP_MUX_RX_MIX_CFG4: + case CDC_RX_INP_MUX_RX_MIX_CFG5: + case CDC_RX_INP_MUX_SIDETONE_SRC_CFG0: + case CDC_RX_CLSH_CRC: + case CDC_RX_CLSH_DLY_CTRL: + case CDC_RX_CLSH_DECAY_CTRL: + case CDC_RX_CLSH_HPH_V_PA: + case CDC_RX_CLSH_EAR_V_PA: + case CDC_RX_CLSH_HPH_V_HD: + case CDC_RX_CLSH_EAR_V_HD: + case CDC_RX_CLSH_K1_MSB: + case CDC_RX_CLSH_K1_LSB: + case CDC_RX_CLSH_K2_MSB: + case CDC_RX_CLSH_K2_LSB: + case CDC_RX_CLSH_IDLE_CTRL: + case CDC_RX_CLSH_IDLE_HPH: + case CDC_RX_CLSH_IDLE_EAR: + case CDC_RX_CLSH_TEST0: + case CDC_RX_CLSH_TEST1: + case CDC_RX_CLSH_OVR_VREF: + case CDC_RX_CLSH_CLSG_CTL: + case CDC_RX_CLSH_CLSG_CFG1: + case CDC_RX_CLSH_CLSG_CFG2: + case CDC_RX_BCL_VBAT_PATH_CTL: + case CDC_RX_BCL_VBAT_CFG: + case CDC_RX_BCL_VBAT_ADC_CAL1: + case CDC_RX_BCL_VBAT_ADC_CAL2: + case CDC_RX_BCL_VBAT_ADC_CAL3: + case CDC_RX_BCL_VBAT_PK_EST1: + case CDC_RX_BCL_VBAT_PK_EST2: + case CDC_RX_BCL_VBAT_PK_EST3: + case CDC_RX_BCL_VBAT_RF_PROC1: + case CDC_RX_BCL_VBAT_RF_PROC2: + case CDC_RX_BCL_VBAT_TAC1: + case CDC_RX_BCL_VBAT_TAC2: + case CDC_RX_BCL_VBAT_TAC3: + case CDC_RX_BCL_VBAT_TAC4: + case CDC_RX_BCL_VBAT_GAIN_UPD1: + case CDC_RX_BCL_VBAT_GAIN_UPD2: + case CDC_RX_BCL_VBAT_GAIN_UPD3: + case CDC_RX_BCL_VBAT_GAIN_UPD4: + case CDC_RX_BCL_VBAT_GAIN_UPD5: + case CDC_RX_BCL_VBAT_DEBUG1: + case CDC_RX_BCL_VBAT_BAN: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD1: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD2: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD3: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD4: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD5: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD6: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD7: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD8: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD9: + case CDC_RX_BCL_VBAT_ATTN1: + case CDC_RX_BCL_VBAT_ATTN2: + case CDC_RX_BCL_VBAT_ATTN3: + case CDC_RX_BCL_VBAT_DECODE_CTL1: + case CDC_RX_BCL_VBAT_DECODE_CTL2: + case CDC_RX_BCL_VBAT_DECODE_CFG1: + case CDC_RX_BCL_VBAT_DECODE_CFG2: + case CDC_RX_BCL_VBAT_DECODE_CFG3: + case CDC_RX_BCL_VBAT_DECODE_CFG4: + case CDC_RX_INTR_CTRL_CFG: + case CDC_RX_INTR_CTRL_PIN1_MASK0: + case CDC_RX_INTR_CTRL_PIN2_MASK0: + case CDC_RX_INTR_CTRL_LEVEL0: + case CDC_RX_INTR_CTRL_BYPASS0: + case CDC_RX_INTR_CTRL_SET0: + case CDC_RX_RX0_RX_PATH_CTL: + case CDC_RX_RX0_RX_PATH_CFG0: + case CDC_RX_RX0_RX_PATH_CFG1: + case CDC_RX_RX0_RX_PATH_CFG2: + case CDC_RX_RX0_RX_PATH_CFG3: + case CDC_RX_RX0_RX_VOL_CTL: + case CDC_RX_RX0_RX_PATH_MIX_CTL: + case CDC_RX_RX0_RX_PATH_MIX_CFG: + case CDC_RX_RX0_RX_VOL_MIX_CTL: + case CDC_RX_RX0_RX_PATH_SEC1: + case CDC_RX_RX0_RX_PATH_SEC2: + case CDC_RX_RX0_RX_PATH_SEC3: + case CDC_RX_RX0_RX_PATH_SEC4: + case CDC_RX_RX0_RX_PATH_SEC7: + case CDC_RX_RX0_RX_PATH_MIX_SEC0: + case CDC_RX_RX0_RX_PATH_MIX_SEC1: + case CDC_RX_RX0_RX_PATH_DSM_CTL: + case CDC_RX_RX0_RX_PATH_DSM_DATA1: + case CDC_RX_RX0_RX_PATH_DSM_DATA2: + case CDC_RX_RX0_RX_PATH_DSM_DATA3: + case CDC_RX_RX0_RX_PATH_DSM_DATA4: + case CDC_RX_RX0_RX_PATH_DSM_DATA5: + case CDC_RX_RX0_RX_PATH_DSM_DATA6: + case CDC_RX_RX1_RX_PATH_CTL: + case CDC_RX_RX1_RX_PATH_CFG0: + case CDC_RX_RX1_RX_PATH_CFG1: + case CDC_RX_RX1_RX_PATH_CFG2: + case CDC_RX_RX1_RX_PATH_CFG3: + case CDC_RX_RX1_RX_VOL_CTL: + case CDC_RX_RX1_RX_PATH_MIX_CTL: + case CDC_RX_RX1_RX_PATH_MIX_CFG: + case CDC_RX_RX1_RX_VOL_MIX_CTL: + case CDC_RX_RX1_RX_PATH_SEC1: + case CDC_RX_RX1_RX_PATH_SEC2: + case CDC_RX_RX1_RX_PATH_SEC3: + case CDC_RX_RX1_RX_PATH_SEC4: + case CDC_RX_RX1_RX_PATH_SEC7: + case CDC_RX_RX1_RX_PATH_MIX_SEC0: + case CDC_RX_RX1_RX_PATH_MIX_SEC1: + case CDC_RX_RX1_RX_PATH_DSM_CTL: + case CDC_RX_RX1_RX_PATH_DSM_DATA1: + case CDC_RX_RX1_RX_PATH_DSM_DATA2: + case CDC_RX_RX1_RX_PATH_DSM_DATA3: + case CDC_RX_RX1_RX_PATH_DSM_DATA4: + case CDC_RX_RX1_RX_PATH_DSM_DATA5: + case CDC_RX_RX1_RX_PATH_DSM_DATA6: + case CDC_RX_RX2_RX_PATH_CTL: + case CDC_RX_RX2_RX_PATH_CFG0: + case CDC_RX_RX2_RX_PATH_CFG1: + case CDC_RX_RX2_RX_PATH_CFG2: + case CDC_RX_RX2_RX_PATH_CFG3: + case CDC_RX_RX2_RX_VOL_CTL: + case CDC_RX_RX2_RX_PATH_MIX_CTL: + case CDC_RX_RX2_RX_PATH_MIX_CFG: + case CDC_RX_RX2_RX_VOL_MIX_CTL: + case CDC_RX_RX2_RX_PATH_SEC0: + case CDC_RX_RX2_RX_PATH_SEC1: + case CDC_RX_RX2_RX_PATH_SEC2: + case CDC_RX_RX2_RX_PATH_SEC3: + case CDC_RX_RX2_RX_PATH_SEC4: + case CDC_RX_RX2_RX_PATH_SEC5: + case CDC_RX_RX2_RX_PATH_SEC6: + case CDC_RX_RX2_RX_PATH_SEC7: + case CDC_RX_RX2_RX_PATH_MIX_SEC0: + case CDC_RX_RX2_RX_PATH_MIX_SEC1: + case CDC_RX_RX2_RX_PATH_DSM_CTL: + case CDC_RX_IDLE_DETECT_PATH_CTL: + case CDC_RX_IDLE_DETECT_CFG0: + case CDC_RX_IDLE_DETECT_CFG1: + case CDC_RX_IDLE_DETECT_CFG2: + case CDC_RX_IDLE_DETECT_CFG3: + case CDC_RX_COMPANDER0_CTL0: + case CDC_RX_COMPANDER0_CTL1: + case CDC_RX_COMPANDER0_CTL2: + case CDC_RX_COMPANDER0_CTL3: + case CDC_RX_COMPANDER0_CTL4: + case CDC_RX_COMPANDER0_CTL5: + case CDC_RX_COMPANDER0_CTL7: + case CDC_RX_COMPANDER1_CTL0: + case CDC_RX_COMPANDER1_CTL1: + case CDC_RX_COMPANDER1_CTL2: + case CDC_RX_COMPANDER1_CTL3: + case CDC_RX_COMPANDER1_CTL4: + case CDC_RX_COMPANDER1_CTL5: + case CDC_RX_COMPANDER1_CTL7: + case CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL: + case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0: + case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1: + case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2: + case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3: + case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0: + case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1: + case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2: + case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3: + case CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL: + case CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1: + case CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL: + case CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1: + case CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL: + case CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0: + case CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL: + case CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0: + case CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL: + case CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0: + case CDC_RX_EC_ASRC0_CLK_RST_CTL: + case CDC_RX_EC_ASRC0_CTL0: + case CDC_RX_EC_ASRC0_CTL1: + case CDC_RX_EC_ASRC0_FIFO_CTL: + case CDC_RX_EC_ASRC1_CLK_RST_CTL: + case CDC_RX_EC_ASRC1_CTL0: + case CDC_RX_EC_ASRC1_CTL1: + case CDC_RX_EC_ASRC1_FIFO_CTL: + case CDC_RX_EC_ASRC2_CLK_RST_CTL: + case CDC_RX_EC_ASRC2_CTL0: + case CDC_RX_EC_ASRC2_CTL1: + case CDC_RX_EC_ASRC2_FIFO_CTL: + case CDC_RX_DSD0_PATH_CTL: + case CDC_RX_DSD0_CFG0: + case CDC_RX_DSD0_CFG1: + case CDC_RX_DSD0_CFG2: + case CDC_RX_DSD1_PATH_CTL: + case CDC_RX_DSD1_CFG0: + case CDC_RX_DSD1_CFG1: + case CDC_RX_DSD1_CFG2: + return true; + } + + return false; +} + +static bool rx_is_writeable_register(struct device *dev, unsigned int reg) +{ + bool ret; + + ret = rx_is_rw_register(dev, reg); + if (!ret) + return rx_is_wronly_register(dev, reg); + + return ret; +} + +static bool rx_is_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CDC_RX_TOP_HPHL_COMP_RD_LSB: + case CDC_RX_TOP_HPHL_COMP_RD_MSB: + case CDC_RX_TOP_HPHR_COMP_RD_LSB: + case CDC_RX_TOP_HPHR_COMP_RD_MSB: + case CDC_RX_TOP_DSD0_DEBUG_CFG2: + case CDC_RX_TOP_DSD1_DEBUG_CFG2: + case CDC_RX_BCL_VBAT_GAIN_MON_VAL: + case CDC_RX_BCL_VBAT_DECODE_ST: + case CDC_RX_INTR_CTRL_PIN1_STATUS0: + case CDC_RX_INTR_CTRL_PIN2_STATUS0: + case CDC_RX_COMPANDER0_CTL6: + case CDC_RX_COMPANDER1_CTL6: + case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC0_STATUS_FIFO: + case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC1_STATUS_FIFO: + case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC2_STATUS_FIFO: + return true; + } + + return rx_is_rw_register(dev, reg); +} + +static const struct regmap_config rx_regmap_config = { + .name = "rx_macro", + .reg_bits = 16, + .val_bits = 32, /* 8 but with 32 bit read/write */ + .reg_stride = 4, + .cache_type = REGCACHE_FLAT, + .reg_defaults = rx_defaults, + .num_reg_defaults = ARRAY_SIZE(rx_defaults), + .max_register = RX_MAX_OFFSET, + .writeable_reg = rx_is_writeable_register, + .volatile_reg = rx_is_volatile_register, + .readable_reg = rx_is_readable_register, +}; + +static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, + int rate_reg_val, u32 sample_rate) +{ + + u8 int_1_mix1_inp; + u32 j, port; + u16 int_mux_cfg0, int_mux_cfg1; + u16 int_fs_reg; + u8 inp0_sel, inp1_sel, inp2_sel; + struct snd_soc_component *component = dai->component; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + for_each_set_bit(port, &rx->active_ch_mask[dai->id], RX_MACRO_PORTS_MAX) { + int_1_mix1_inp = port; + int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0; + /* + * Loop through all interpolator MUX inputs and find out + * to which interpolator input, the rx port + * is connected + */ + for (j = 0; j < INTERP_MAX; j++) { + int_mux_cfg1 = int_mux_cfg0 + 4; + + inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_RX_INTX_1_MIX_INP0_SEL_MASK); + inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_RX_INTX_1_MIX_INP1_SEL_MASK); + inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1, + CDC_RX_INTX_1_MIX_INP2_SEL_MASK); + + if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || + (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || + (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { + int_fs_reg = CDC_RX_RXn_RX_PATH_CTL(j); + /* sample_rate is in Hz */ + snd_soc_component_update_bits(component, int_fs_reg, + CDC_RX_PATH_PCM_RATE_MASK, + rate_reg_val); + } + int_mux_cfg0 += 8; + } + } + + return 0; +} + +static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, + int rate_reg_val, u32 sample_rate) +{ + + u8 int_2_inp; + u32 j, port; + u16 int_mux_cfg1, int_fs_reg; + u8 int_mux_cfg1_val; + struct snd_soc_component *component = dai->component; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + for_each_set_bit(port, &rx->active_ch_mask[dai->id], RX_MACRO_PORTS_MAX) { + int_2_inp = port; + + int_mux_cfg1 = CDC_RX_INP_MUX_RX_INT0_CFG1; + for (j = 0; j < INTERP_MAX; j++) { + int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1, + CDC_RX_INTX_2_SEL_MASK); + + if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) { + int_fs_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(j); + snd_soc_component_update_bits(component, int_fs_reg, + CDC_RX_RXn_MIX_PCM_RATE_MASK, + rate_reg_val); + } + int_mux_cfg1 += 8; + } + } + return 0; +} + +static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + int rate_val = 0; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) + if (sample_rate == sr_val_tbl[i].sample_rate) + rate_val = sr_val_tbl[i].rate_val; + + ret = rx_macro_set_prim_interpolator_rate(dai, rate_val, sample_rate); + if (ret) + return ret; + + ret = rx_macro_set_mix_interpolator_rate(dai, rate_val, sample_rate); + if (ret) + return ret; + + return ret; +} + +static int rx_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + int ret; + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ret = rx_macro_set_interpolator_rate(dai, params_rate(params)); + if (ret) { + dev_err(component->dev, "%s: cannot set sample rate: %u\n", + __func__, params_rate(params)); + return ret; + } + rx->bit_width[dai->id] = params_width(params); + break; + default: + break; + } + return 0; +} + +static int rx_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct snd_soc_component *component = dai->component; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + u16 val, mask = 0, cnt = 0, temp; + + switch (dai->id) { + case RX_MACRO_AIF1_PB: + case RX_MACRO_AIF2_PB: + case RX_MACRO_AIF3_PB: + case RX_MACRO_AIF4_PB: + for_each_set_bit(temp, &rx->active_ch_mask[dai->id], + RX_MACRO_PORTS_MAX) { + mask |= (1 << temp); + if (++cnt == RX_MACRO_MAX_DMA_CH_PER_PORT) + break; + } + /* + * CDC_DMA_RX_0 port drives RX0/RX1 -- ch_mask 0x1/0x2/0x3 + * CDC_DMA_RX_1 port drives RX2/RX3 -- ch_mask 0x1/0x2/0x3 + * CDC_DMA_RX_2 port drives RX4 -- ch_mask 0x1 + * CDC_DMA_RX_3 port drives RX5 -- ch_mask 0x1 + * AIFn can pair to any CDC_DMA_RX_n port. + * In general, below convention is used:: + * CDC_DMA_RX_0(AIF1)/CDC_DMA_RX_1(AIF2)/ + * CDC_DMA_RX_2(AIF3)/CDC_DMA_RX_3(AIF4) + */ + if (mask & 0x0C) + mask = mask >> 2; + if ((mask & 0x10) || (mask & 0x20)) + mask = 0x1; + *rx_slot = mask; + *rx_num = rx->active_ch_cnt[dai->id]; + break; + case RX_MACRO_AIF_ECHO: + val = snd_soc_component_read(component, CDC_RX_INP_MUX_RX_MIX_CFG4); + if (val & RX_MACRO_EC_MIX_TX0_MASK) { + mask |= 0x1; + cnt++; + } + if (val & RX_MACRO_EC_MIX_TX1_MASK) { + mask |= 0x2; + cnt++; + } + val = snd_soc_component_read(component, + CDC_RX_INP_MUX_RX_MIX_CFG5); + if (val & RX_MACRO_EC_MIX_TX2_MASK) { + mask |= 0x4; + cnt++; + } + *tx_slot = mask; + *tx_num = cnt; + break; + default: + dev_err(component->dev, "%s: Invalid AIF\n", __func__); + break; + } + return 0; +} + +static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_component *component = dai->component; + uint16_t j, reg, mix_reg, dsm_reg; + u16 int_mux_cfg0, int_mux_cfg1; + u8 int_mux_cfg0_val, int_mux_cfg1_val; + + switch (dai->id) { + case RX_MACRO_AIF1_PB: + case RX_MACRO_AIF2_PB: + case RX_MACRO_AIF3_PB: + case RX_MACRO_AIF4_PB: + for (j = 0; j < INTERP_MAX; j++) { + reg = CDC_RX_RXn_RX_PATH_CTL(j); + mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(j); + dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(j); + + if (mute) { + snd_soc_component_update_bits(component, reg, + CDC_RX_PATH_PGA_MUTE_MASK, + CDC_RX_PATH_PGA_MUTE_ENABLE); + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_PATH_PGA_MUTE_MASK, + CDC_RX_PATH_PGA_MUTE_ENABLE); + } else { + snd_soc_component_update_bits(component, reg, + CDC_RX_PATH_PGA_MUTE_MASK, 0x0); + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_PATH_PGA_MUTE_MASK, 0x0); + } + + if (j == INTERP_AUX) + dsm_reg = CDC_RX_RX2_RX_PATH_DSM_CTL; + + int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8; + int_mux_cfg1 = int_mux_cfg0 + 4; + int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1); + + if (snd_soc_component_read(component, dsm_reg) & 0x01) { + if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0)) + snd_soc_component_update_bits(component, reg, 0x20, 0x20); + if (int_mux_cfg1_val & 0x0F) { + snd_soc_component_update_bits(component, reg, 0x20, 0x20); + snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20); + } + } + } + break; + default: + break; + } + return 0; +} + +static struct snd_soc_dai_ops rx_macro_dai_ops = { + .hw_params = rx_macro_hw_params, + .get_channel_map = rx_macro_get_channel_map, + .mute_stream = rx_macro_digital_mute, +}; + +static struct snd_soc_dai_driver rx_macro_dai[] = { + { + .name = "rx_macro_rx1", + .id = RX_MACRO_AIF1_PB, + .playback = { + .stream_name = "RX_MACRO_AIF1 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_rx2", + .id = RX_MACRO_AIF2_PB, + .playback = { + .stream_name = "RX_MACRO_AIF2 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_rx3", + .id = RX_MACRO_AIF3_PB, + .playback = { + .stream_name = "RX_MACRO_AIF3 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_rx4", + .id = RX_MACRO_AIF4_PB, + .playback = { + .stream_name = "RX_MACRO_AIF4 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_echo", + .id = RX_MACRO_AIF_ECHO, + .capture = { + .stream_name = "RX_AIF_ECHO Capture", + .rates = RX_MACRO_ECHO_RATES, + .formats = RX_MACRO_ECHO_FORMATS, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 3, + }, + .ops = &rx_macro_dai_ops, + }, +}; + +static void rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable) +{ + struct regmap *regmap = rx->regmap; + + if (mclk_enable) { + if (rx->rx_mclk_users == 0) { + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, + CDC_RX_CLK_MCLK_EN_MASK | + CDC_RX_CLK_MCLK2_EN_MASK, + CDC_RX_CLK_MCLK_ENABLE | + CDC_RX_CLK_MCLK2_ENABLE); + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_RX_FS_MCLK_CNT_CLR_MASK, 0x00); + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_RX_FS_MCLK_CNT_EN_MASK, + CDC_RX_FS_MCLK_CNT_ENABLE); + regcache_mark_dirty(regmap); + regcache_sync(regmap); + } + rx->rx_mclk_users++; + } else { + if (rx->rx_mclk_users <= 0) { + dev_err(rx->dev, "%s: clock already disabled\n", __func__); + rx->rx_mclk_users = 0; + return; + } + rx->rx_mclk_users--; + if (rx->rx_mclk_users == 0) { + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_RX_FS_MCLK_CNT_EN_MASK, 0x0); + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_RX_FS_MCLK_CNT_CLR_MASK, + CDC_RX_FS_MCLK_CNT_CLR); + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, + CDC_RX_CLK_MCLK_EN_MASK | + CDC_RX_CLK_MCLK2_EN_MASK, 0x0); + } + } +} + +static inline void rx_macro_enable_clsh_block(struct rx_macro *rx, bool enable) +{ + if ((enable && ++rx->clsh_users == 1) || (!enable && --rx->clsh_users == 0)) + snd_soc_component_update_bits(rx->component, CDC_RX_CLSH_CRC, + CDC_RX_CLSH_CLK_EN_MASK, enable); + if (rx->clsh_users < 0) + rx->clsh_users = 0; +} + +static int rx_macro_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->comp_enabled[comp]; + return 0; +} + +static int rx_macro_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->comp_enabled[comp] = value; + + return 0; +} + +static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->is_ear_mode_on; + return 0; +} + +static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->is_ear_mode_on = (!ucontrol->value.integer.value[0] ? false : true); + return 0; +} + +static int rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->hph_hd2_mode; + return 0; +} + +static int rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->hph_hd2_mode = ucontrol->value.integer.value[0]; + return 0; +} + +static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->hph_pwr_mode; + return 0; +} + +static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->hph_pwr_mode = ucontrol->value.integer.value[0]; + return 0; +} + +static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->is_softclip_on; + + return 0; +} + +static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->is_softclip_on = ucontrol->value.integer.value[0]; + + return 0; +} + +static int rx_macro_aux_hpf_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->is_aux_hpf_on; + + return 0; +} + +static int rx_macro_aux_hpf_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->is_aux_hpf_on = ucontrol->value.integer.value[0]; + + return 0; +} + +static const struct snd_kcontrol_new rx_macro_snd_controls[] = { + SOC_SINGLE_S8_TLV("RX_RX0 Digital Volume", CDC_RX_RX0_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX1 Digital Volume", CDC_RX_RX1_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX2 Digital Volume", CDC_RX_RX2_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX0 Mix Digital Volume", CDC_RX_RX0_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX1 Mix Digital Volume", CDC_RX_RX1_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX2 Mix Digital Volume", CDC_RX_RX2_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + + SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, RX_MACRO_COMP1, 1, 0, + rx_macro_get_compander, rx_macro_set_compander), + SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0, + rx_macro_get_compander, rx_macro_set_compander), + + SOC_SINGLE_EXT("RX_EAR Mode Switch", SND_SOC_NOPM, 0, 1, 0, + rx_macro_get_ear_mode, rx_macro_put_ear_mode), + + SOC_SINGLE_EXT("RX_HPH HD2 Mode Switch", SND_SOC_NOPM, 0, 1, 0, + rx_macro_get_hph_hd2_mode, rx_macro_put_hph_hd2_mode), + + SOC_ENUM_EXT("RX_HPH PWR Mode", rx_macro_hph_pwr_mode_enum, + rx_macro_get_hph_pwr_mode, rx_macro_put_hph_pwr_mode), + + SOC_SINGLE_EXT("RX_Softclip Switch", SND_SOC_NOPM, 0, 1, 0, + rx_macro_soft_clip_enable_get, + rx_macro_soft_clip_enable_put), + SOC_SINGLE_EXT("AUX_HPF Switch", SND_SOC_NOPM, 0, 1, 0, + rx_macro_aux_hpf_mode_get, + rx_macro_aux_hpf_mode_put), +}; + +static int rx_macro_component_probe(struct snd_soc_component *component) +{ + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + snd_soc_component_init_regmap(component, rx->regmap); + + snd_soc_component_update_bits(component, CDC_RX_RX0_RX_PATH_SEC7, + CDC_RX_DSM_OUT_DELAY_SEL_MASK, + CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE); + snd_soc_component_update_bits(component, CDC_RX_RX1_RX_PATH_SEC7, + CDC_RX_DSM_OUT_DELAY_SEL_MASK, + CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE); + snd_soc_component_update_bits(component, CDC_RX_RX2_RX_PATH_SEC7, + CDC_RX_DSM_OUT_DELAY_SEL_MASK, + CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE); + snd_soc_component_update_bits(component, CDC_RX_RX0_RX_PATH_CFG3, + CDC_RX_DC_COEFF_SEL_MASK, + CDC_RX_DC_COEFF_SEL_TWO); + snd_soc_component_update_bits(component, CDC_RX_RX1_RX_PATH_CFG3, + CDC_RX_DC_COEFF_SEL_MASK, + CDC_RX_DC_COEFF_SEL_TWO); + snd_soc_component_update_bits(component, CDC_RX_RX2_RX_PATH_CFG3, + CDC_RX_DC_COEFF_SEL_MASK, + CDC_RX_DC_COEFF_SEL_TWO); + + rx->component = component; + + return 0; +} + +static int swclk_gate_enable(struct clk_hw *hw) +{ + struct rx_macro *rx = to_rx_macro(hw); + + rx_macro_mclk_enable(rx, true); + if (rx->reset_swr) + regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + CDC_RX_SWR_RESET_MASK, + CDC_RX_SWR_RESET); + + regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + CDC_RX_SWR_CLK_EN_MASK, 1); + + if (rx->reset_swr) + regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + CDC_RX_SWR_RESET_MASK, 0); + rx->reset_swr = false; + + return 0; +} + +static void swclk_gate_disable(struct clk_hw *hw) +{ + struct rx_macro *rx = to_rx_macro(hw); + + regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + CDC_RX_SWR_CLK_EN_MASK, 0); + + rx_macro_mclk_enable(rx, false); +} + +static int swclk_gate_is_enabled(struct clk_hw *hw) +{ + struct rx_macro *rx = to_rx_macro(hw); + int ret, val; + + regmap_read(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, &val); + ret = val & BIT(0); + + return ret; +} + +static unsigned long swclk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate / 2; +} + +static const struct clk_ops swclk_gate_ops = { + .prepare = swclk_gate_enable, + .unprepare = swclk_gate_disable, + .is_enabled = swclk_gate_is_enabled, + .recalc_rate = swclk_recalc_rate, + +}; + +static struct clk *rx_macro_register_mclk_output(struct rx_macro *rx) +{ + struct device *dev = rx->dev; + struct device_node *np = dev->of_node; + const char *parent_clk_name = NULL; + const char *clk_name = "lpass-rx-mclk"; + struct clk_hw *hw; + struct clk_init_data init; + int ret; + + parent_clk_name = __clk_get_name(rx->clks[2].clk); + + init.name = clk_name; + init.ops = &swclk_gate_ops; + init.flags = 0; + init.parent_names = &parent_clk_name; + init.num_parents = 1; + rx->hw.init = &init; + hw = &rx->hw; + ret = clk_hw_register(rx->dev, hw); + if (ret) + return ERR_PTR(ret); + + of_clk_add_provider(np, of_clk_src_simple_get, hw->clk); + + return NULL; +} + +static const struct snd_soc_component_driver rx_macro_component_drv = { + .name = "RX-MACRO", + .probe = rx_macro_component_probe, + .controls = rx_macro_snd_controls, + .num_controls = ARRAY_SIZE(rx_macro_snd_controls), +}; + +static int rx_macro_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rx_macro *rx; + void __iomem *base; + int ret; + + rx = devm_kzalloc(dev, sizeof(*rx), GFP_KERNEL); + if (!rx) + return -ENOMEM; + + rx->clks[0].id = "macro"; + rx->clks[1].id = "dcodec"; + rx->clks[2].id = "mclk"; + rx->clks[3].id = "npl"; + rx->clks[4].id = "fsgen"; + + ret = devm_clk_bulk_get(dev, RX_NUM_CLKS_MAX, rx->clks); + if (ret) { + dev_err(dev, "Error getting RX Clocks (%d)\n", ret); + return ret; + } + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + rx->regmap = devm_regmap_init_mmio(dev, base, &rx_regmap_config); + + dev_set_drvdata(dev, rx); + + rx->reset_swr = true; + rx->dev = dev; + + /* set MCLK and NPL rates */ + clk_set_rate(rx->clks[2].clk, MCLK_FREQ); + clk_set_rate(rx->clks[3].clk, MCLK_FREQ); + + ret = clk_bulk_prepare_enable(RX_NUM_CLKS_MAX, rx->clks); + if (ret) + return ret; + + rx_macro_register_mclk_output(rx); + + ret = devm_snd_soc_register_component(dev, &rx_macro_component_drv, + rx_macro_dai, + ARRAY_SIZE(rx_macro_dai)); + if (ret) + clk_bulk_disable_unprepare(RX_NUM_CLKS_MAX, rx->clks); + + return ret; +} + +static int rx_macro_remove(struct platform_device *pdev) +{ + struct rx_macro *rx = dev_get_drvdata(&pdev->dev); + + of_clk_del_provider(pdev->dev.of_node); + clk_bulk_disable_unprepare(RX_NUM_CLKS_MAX, rx->clks); + return 0; +} + +static const struct of_device_id rx_macro_dt_match[] = { + { .compatible = "qcom,sm8250-lpass-rx-macro" }, + { } +}; + +static struct platform_driver rx_macro_driver = { + .driver = { + .name = "rx_macro", + .owner = THIS_MODULE, + .of_match_table = rx_macro_dt_match, + .suppress_bind_attrs = true, + }, + .probe = rx_macro_probe, + .remove = rx_macro_remove, +}; + +module_platform_driver(rx_macro_driver); + +MODULE_DESCRIPTION("RX macro driver"); +MODULE_LICENSE("GPL"); -- GitLab From 4f692926f562ff48abfcca6b16f36ff8d57473b6 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 11 Feb 2021 12:27:31 +0000 Subject: [PATCH 1069/1084] ASoC: codecs: lpass-rx-macro: add dapm widgets and route This patch adds dapm widgets and routes on this codec Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210211122735.5691-4-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-rx-macro.c | 1341 +++++++++++++++++++++++++++++ 1 file changed, 1341 insertions(+) diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 1c114a46c44af..2cf6eb9238a70 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -583,12 +583,210 @@ struct rx_macro { static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); +static const char * const rx_int_mix_mux_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5" +}; + +static const char * const rx_prim_mix_text[] = { + "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2", + "RX3", "RX4", "RX5" +}; + +static const char * const rx_sidetone_mix_text[] = { + "ZERO", "SRC0", "SRC1", "SRC_SUM" +}; + +static const char * const iir_inp_mux_text[] = { + "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", + "RX0", "RX1", "RX2", "RX3", "RX4", "RX5" +}; + +static const char * const rx_int_dem_inp_mux_text[] = { + "NORMAL_DSM_OUT", "CLSH_DSM_OUT", +}; + +static const char * const rx_int0_1_interp_mux_text[] = { + "ZERO", "RX INT0_1 MIX1", +}; + +static const char * const rx_int1_1_interp_mux_text[] = { + "ZERO", "RX INT1_1 MIX1", +}; + +static const char * const rx_int2_1_interp_mux_text[] = { + "ZERO", "RX INT2_1 MIX1", +}; + +static const char * const rx_int0_2_interp_mux_text[] = { + "ZERO", "RX INT0_2 MUX", +}; + +static const char * const rx_int1_2_interp_mux_text[] = { + "ZERO", "RX INT1_2 MUX", +}; + +static const char * const rx_int2_2_interp_mux_text[] = { + "ZERO", "RX INT2_2 MUX", +}; + +static const char *const rx_macro_mux_text[] = { + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" +}; + static const char *const rx_macro_hph_pwr_mode_text[] = { "ULP", "LOHIFI" }; +static const char * const rx_echo_mux_text[] = { + "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2" +}; + static const struct soc_enum rx_macro_hph_pwr_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text); +static const struct soc_enum rx_mix_tx2_mux_enum = + SOC_ENUM_SINGLE(CDC_RX_INP_MUX_RX_MIX_CFG5, 0, 4, rx_echo_mux_text); +static const struct soc_enum rx_mix_tx1_mux_enum = + SOC_ENUM_SINGLE(CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 4, rx_echo_mux_text); +static const struct soc_enum rx_mix_tx0_mux_enum = + SOC_ENUM_SINGLE(CDC_RX_INP_MUX_RX_MIX_CFG4, 4, 4, rx_echo_mux_text); + +static SOC_ENUM_SINGLE_DECL(rx_int0_2_enum, CDC_RX_INP_MUX_RX_INT0_CFG1, 0, + rx_int_mix_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_2_enum, CDC_RX_INP_MUX_RX_INT1_CFG1, 0, + rx_int_mix_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_2_enum, CDC_RX_INP_MUX_RX_INT2_CFG1, 0, + rx_int_mix_mux_text); + +static SOC_ENUM_SINGLE_DECL(rx_int0_1_mix_inp0_enum, CDC_RX_INP_MUX_RX_INT0_CFG0, 0, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int0_1_mix_inp1_enum, CDC_RX_INP_MUX_RX_INT0_CFG0, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int0_1_mix_inp2_enum, CDC_RX_INP_MUX_RX_INT0_CFG1, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_1_mix_inp0_enum, CDC_RX_INP_MUX_RX_INT1_CFG0, 0, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_1_mix_inp1_enum, CDC_RX_INP_MUX_RX_INT1_CFG0, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_1_mix_inp2_enum, CDC_RX_INP_MUX_RX_INT1_CFG1, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_1_mix_inp0_enum, CDC_RX_INP_MUX_RX_INT2_CFG0, 0, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_1_mix_inp1_enum, CDC_RX_INP_MUX_RX_INT2_CFG0, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_1_mix_inp2_enum, CDC_RX_INP_MUX_RX_INT2_CFG1, 4, + rx_prim_mix_text); + +static SOC_ENUM_SINGLE_DECL(rx_int0_mix2_inp_enum, CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, + rx_sidetone_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_mix2_inp_enum, CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, + rx_sidetone_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_mix2_inp_enum, CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, + rx_sidetone_mix_text); +static SOC_ENUM_SINGLE_DECL(iir0_inp0_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir0_inp1_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir0_inp2_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir0_inp3_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir1_inp0_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir1_inp1_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir1_inp2_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir1_inp3_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0, + iir_inp_mux_text); + +static SOC_ENUM_SINGLE_DECL(rx_int0_1_interp_enum, SND_SOC_NOPM, 0, + rx_int0_1_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_1_interp_enum, SND_SOC_NOPM, 0, + rx_int1_1_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_1_interp_enum, SND_SOC_NOPM, 0, + rx_int2_1_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int0_2_interp_enum, SND_SOC_NOPM, 0, + rx_int0_2_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_2_interp_enum, SND_SOC_NOPM, 0, + rx_int1_2_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_2_interp_enum, SND_SOC_NOPM, 0, + rx_int2_2_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int0_dem_inp_enum, CDC_RX_RX0_RX_PATH_CFG1, 0, + rx_int_dem_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_dem_inp_enum, CDC_RX_RX1_RX_PATH_CFG1, 0, + rx_int_dem_inp_mux_text); + +static SOC_ENUM_SINGLE_DECL(rx_macro_rx0_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx1_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx2_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx3_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx4_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx5_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); + +static const struct snd_kcontrol_new rx_mix_tx1_mux = + SOC_DAPM_ENUM("RX MIX TX1_MUX Mux", rx_mix_tx1_mux_enum); +static const struct snd_kcontrol_new rx_mix_tx2_mux = + SOC_DAPM_ENUM("RX MIX TX2_MUX Mux", rx_mix_tx2_mux_enum); +static const struct snd_kcontrol_new rx_int0_2_mux = + SOC_DAPM_ENUM("rx_int0_2", rx_int0_2_enum); +static const struct snd_kcontrol_new rx_int1_2_mux = + SOC_DAPM_ENUM("rx_int1_2", rx_int1_2_enum); +static const struct snd_kcontrol_new rx_int2_2_mux = + SOC_DAPM_ENUM("rx_int2_2", rx_int2_2_enum); +static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux = + SOC_DAPM_ENUM("rx_int0_1_mix_inp0", rx_int0_1_mix_inp0_enum); +static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux = + SOC_DAPM_ENUM("rx_int0_1_mix_inp1", rx_int0_1_mix_inp1_enum); +static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux = + SOC_DAPM_ENUM("rx_int0_1_mix_inp2", rx_int0_1_mix_inp2_enum); +static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux = + SOC_DAPM_ENUM("rx_int1_1_mix_inp0", rx_int1_1_mix_inp0_enum); +static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux = + SOC_DAPM_ENUM("rx_int1_1_mix_inp1", rx_int1_1_mix_inp1_enum); +static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux = + SOC_DAPM_ENUM("rx_int1_1_mix_inp2", rx_int1_1_mix_inp2_enum); +static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux = + SOC_DAPM_ENUM("rx_int2_1_mix_inp0", rx_int2_1_mix_inp0_enum); +static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux = + SOC_DAPM_ENUM("rx_int2_1_mix_inp1", rx_int2_1_mix_inp1_enum); +static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux = + SOC_DAPM_ENUM("rx_int2_1_mix_inp2", rx_int2_1_mix_inp2_enum); +static const struct snd_kcontrol_new rx_int0_mix2_inp_mux = + SOC_DAPM_ENUM("rx_int0_mix2_inp", rx_int0_mix2_inp_enum); +static const struct snd_kcontrol_new rx_int1_mix2_inp_mux = + SOC_DAPM_ENUM("rx_int1_mix2_inp", rx_int1_mix2_inp_enum); +static const struct snd_kcontrol_new rx_int2_mix2_inp_mux = + SOC_DAPM_ENUM("rx_int2_mix2_inp", rx_int2_mix2_inp_enum); +static const struct snd_kcontrol_new iir0_inp0_mux = + SOC_DAPM_ENUM("iir0_inp0", iir0_inp0_enum); +static const struct snd_kcontrol_new iir0_inp1_mux = + SOC_DAPM_ENUM("iir0_inp1", iir0_inp1_enum); +static const struct snd_kcontrol_new iir0_inp2_mux = + SOC_DAPM_ENUM("iir0_inp2", iir0_inp2_enum); +static const struct snd_kcontrol_new iir0_inp3_mux = + SOC_DAPM_ENUM("iir0_inp3", iir0_inp3_enum); +static const struct snd_kcontrol_new iir1_inp0_mux = + SOC_DAPM_ENUM("iir1_inp0", iir1_inp0_enum); +static const struct snd_kcontrol_new iir1_inp1_mux = + SOC_DAPM_ENUM("iir1_inp1", iir1_inp1_enum); +static const struct snd_kcontrol_new iir1_inp2_mux = + SOC_DAPM_ENUM("iir1_inp2", iir1_inp2_enum); +static const struct snd_kcontrol_new iir1_inp3_mux = + SOC_DAPM_ENUM("iir1_inp3", iir1_inp3_enum); +static const struct snd_kcontrol_new rx_int0_1_interp_mux = + SOC_DAPM_ENUM("rx_int0_1_interp", rx_int0_1_interp_enum); +static const struct snd_kcontrol_new rx_int1_1_interp_mux = + SOC_DAPM_ENUM("rx_int1_1_interp", rx_int1_1_interp_enum); +static const struct snd_kcontrol_new rx_int2_1_interp_mux = + SOC_DAPM_ENUM("rx_int2_1_interp", rx_int2_1_interp_enum); +static const struct snd_kcontrol_new rx_int0_2_interp_mux = + SOC_DAPM_ENUM("rx_int0_2_interp", rx_int0_2_interp_enum); +static const struct snd_kcontrol_new rx_int1_2_interp_mux = + SOC_DAPM_ENUM("rx_int1_2_interp", rx_int1_2_interp_enum); +static const struct snd_kcontrol_new rx_int2_2_interp_mux = + SOC_DAPM_ENUM("rx_int2_2_interp", rx_int2_2_interp_enum); +static const struct snd_kcontrol_new rx_mix_tx0_mux = + SOC_DAPM_ENUM("RX MIX TX0_MUX Mux", rx_mix_tx0_mux_enum); static const struct reg_default rx_defaults[] = { /* RX Macro */ @@ -1257,6 +1455,41 @@ static const struct regmap_config rx_regmap_config = { .readable_reg = rx_is_readable_register, }; +static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned short look_ahead_dly_reg; + unsigned int val; + + val = ucontrol->value.enumerated.item[0]; + + if (e->reg == CDC_RX_RX0_RX_PATH_CFG1) + look_ahead_dly_reg = CDC_RX_RX0_RX_PATH_CFG0; + else if (e->reg == CDC_RX_RX1_RX_PATH_CFG1) + look_ahead_dly_reg = CDC_RX_RX1_RX_PATH_CFG0; + + /* Set Look Ahead Delay */ + if (val) + snd_soc_component_update_bits(component, look_ahead_dly_reg, + CDC_RX_DLY_ZN_EN_MASK, + CDC_RX_DLY_ZN_ENABLE); + else + snd_soc_component_update_bits(component, look_ahead_dly_reg, + CDC_RX_DLY_ZN_EN_MASK, 0); + /* Set DEM INP Select */ + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static const struct snd_kcontrol_new rx_int0_dem_inp_mux = + SOC_DAPM_ENUM_EXT("rx_int0_dem_inp", rx_int0_dem_inp_enum, + snd_soc_dapm_get_enum_double, rx_macro_int_dem_inp_mux_put); +static const struct snd_kcontrol_new rx_int1_dem_inp_mux = + SOC_DAPM_ENUM_EXT("rx_int1_dem_inp", rx_int1_dem_inp_enum, + snd_soc_dapm_get_enum_double, rx_macro_int_dem_inp_mux_put); + static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, int rate_reg_val, u32 sample_rate) { @@ -1615,6 +1848,248 @@ static void rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable) } } +static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + int ret = 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_mclk_enable(rx, true); + break; + case SND_SOC_DAPM_POST_PMD: + rx_macro_mclk_enable(rx, false); + break; + default: + dev_err(component->dev, "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + +static bool rx_macro_adie_lb(struct snd_soc_component *component, + int interp_idx) +{ + u16 int_mux_cfg0, int_mux_cfg1; + u8 int_n_inp0, int_n_inp1, int_n_inp2; + + int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; + int_mux_cfg1 = int_mux_cfg0 + 4; + + int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_RX_INTX_1_MIX_INP0_SEL_MASK); + int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_RX_INTX_1_MIX_INP1_SEL_MASK); + int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1, + CDC_RX_INTX_1_MIX_INP2_SEL_MASK); + + if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || + int_n_inp0 == INTn_1_INP_SEL_DEC1 || + int_n_inp0 == INTn_1_INP_SEL_IIR0 || + int_n_inp0 == INTn_1_INP_SEL_IIR1) + return true; + + if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || + int_n_inp1 == INTn_1_INP_SEL_DEC1 || + int_n_inp1 == INTn_1_INP_SEL_IIR0 || + int_n_inp1 == INTn_1_INP_SEL_IIR1) + return true; + + if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || + int_n_inp2 == INTn_1_INP_SEL_DEC1 || + int_n_inp2 == INTn_1_INP_SEL_IIR0 || + int_n_inp2 == INTn_1_INP_SEL_IIR1) + return true; + + return false; +} + +static int rx_macro_enable_interp_clk(struct snd_soc_component *component, + int event, int interp_idx); +static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + u16 gain_reg, reg; + + reg = CDC_RX_RXn_RX_PATH_CTL(w->shift); + gain_reg = CDC_RX_RXn_RX_VOL_CTL(w->shift); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_enable_interp_clk(component, event, w->shift); + if (rx_macro_adie_lb(component, w->shift)) + snd_soc_component_update_bits(component, reg, + CDC_RX_PATH_CLK_EN_MASK, + CDC_RX_PATH_CLK_ENABLE); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_write(component, gain_reg, + snd_soc_component_read(component, gain_reg)); + break; + case SND_SOC_DAPM_POST_PMD: + rx_macro_enable_interp_clk(component, event, w->shift); + break; + } + + return 0; +} + +static int rx_macro_config_compander(struct snd_soc_component *component, + struct rx_macro *rx, + int comp, int event) +{ + u8 pcm_rate, val; + + /* AUX does not have compander */ + if (comp == INTERP_AUX) + return 0; + + pcm_rate = snd_soc_component_read(component, CDC_RX_RXn_RX_PATH_CTL(comp)) & 0x0F; + if (pcm_rate < 0x06) + val = 0x03; + else if (pcm_rate < 0x08) + val = 0x01; + else if (pcm_rate < 0x0B) + val = 0x02; + else + val = 0x00; + + if (SND_SOC_DAPM_EVENT_ON(event)) + snd_soc_component_update_bits(component, CDC_RX_RXn_RX_PATH_CFG3(comp), + CDC_RX_DC_COEFF_SEL_MASK, val); + + if (SND_SOC_DAPM_EVENT_OFF(event)) + snd_soc_component_update_bits(component, CDC_RX_RXn_RX_PATH_CFG3(comp), + CDC_RX_DC_COEFF_SEL_MASK, 0x3); + if (!rx->comp_enabled[comp]) + return 0; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_CLK_EN_MASK, 0x1); + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_SOFT_RST_MASK, 0x1); + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_SOFT_RST_MASK, 0x0); + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG0(comp), + CDC_RX_RXn_COMP_EN_MASK, 0x1); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_HALT_MASK, 0x1); + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG0(comp), + CDC_RX_RXn_COMP_EN_MASK, 0x0); + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_CLK_EN_MASK, 0x0); + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_HALT_MASK, 0x0); + } + + return 0; +} + +static int rx_macro_load_compander_coeff(struct snd_soc_component *component, + struct rx_macro *rx, + int comp, int event) +{ + u16 comp_coeff_lsb_reg, comp_coeff_msb_reg; + int i; + int hph_pwr_mode = HPH_LOHIFI; + + if (!rx->comp_enabled[comp]) + return 0; + + if (comp == INTERP_HPHL) { + comp_coeff_lsb_reg = CDC_RX_TOP_HPHL_COMP_WR_LSB; + comp_coeff_msb_reg = CDC_RX_TOP_HPHL_COMP_WR_MSB; + } else if (comp == INTERP_HPHR) { + comp_coeff_lsb_reg = CDC_RX_TOP_HPHR_COMP_WR_LSB; + comp_coeff_msb_reg = CDC_RX_TOP_HPHR_COMP_WR_MSB; + } else { + /* compander coefficients are loaded only for hph path */ + return 0; + } + + hph_pwr_mode = rx->hph_pwr_mode; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Load Compander Coeff */ + for (i = 0; i < COMP_MAX_COEFF; i++) { + snd_soc_component_write(component, comp_coeff_lsb_reg, + comp_coeff_table[hph_pwr_mode][i].lsb); + snd_soc_component_write(component, comp_coeff_msb_reg, + comp_coeff_table[hph_pwr_mode][i].msb); + } + } + + return 0; +} + +static void rx_macro_enable_softclip_clk(struct snd_soc_component *component, + struct rx_macro *rx, bool enable) +{ + if (enable) { + if (rx->softclip_clk_users == 0) + snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_CRC, + CDC_RX_SOFTCLIP_CLK_EN_MASK, 1); + rx->softclip_clk_users++; + } else { + rx->softclip_clk_users--; + if (rx->softclip_clk_users == 0) + snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_CRC, + CDC_RX_SOFTCLIP_CLK_EN_MASK, 0); + } +} + +static int rx_macro_config_softclip(struct snd_soc_component *component, + struct rx_macro *rx, int event) +{ + + if (!rx->is_softclip_on) + return 0; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Softclip clock */ + rx_macro_enable_softclip_clk(component, rx, true); + /* Enable Softclip control */ + snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, + CDC_RX_SOFTCLIP_EN_MASK, 0x01); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, + CDC_RX_SOFTCLIP_EN_MASK, 0x0); + rx_macro_enable_softclip_clk(component, rx, false); + } + + return 0; +} + +static int rx_macro_config_aux_hpf(struct snd_soc_component *component, + struct rx_macro *rx, int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Update Aux HPF control */ + if (!rx->is_aux_hpf_on) + snd_soc_component_update_bits(component, + CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x00); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + /* Reset to default (HPF=ON) */ + snd_soc_component_update_bits(component, + CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x04); + } + + return 0; +} + static inline void rx_macro_enable_clsh_block(struct rx_macro *rx, bool enable) { if ((enable && ++rx->clsh_users == 1) || (!enable && --rx->clsh_users == 0)) @@ -1624,6 +2099,106 @@ static inline void rx_macro_enable_clsh_block(struct rx_macro *rx, bool enable) rx->clsh_users = 0; } +static int rx_macro_config_classh(struct snd_soc_component *component, + struct rx_macro *rx, + int interp_n, int event) +{ + if (SND_SOC_DAPM_EVENT_OFF(event)) { + rx_macro_enable_clsh_block(rx, false); + return 0; + } + + if (!SND_SOC_DAPM_EVENT_ON(event)) + return 0; + + rx_macro_enable_clsh_block(rx, true); + if (interp_n == INTERP_HPHL || + interp_n == INTERP_HPHR) { + /* + * These K1 values depend on the Headphone Impedance + * For now it is assumed to be 16 ohm + */ + snd_soc_component_write(component, CDC_RX_CLSH_K1_LSB, 0xc0); + snd_soc_component_write_field(component, CDC_RX_CLSH_K1_MSB, + CDC_RX_CLSH_K1_MSB_COEFF_MASK, 0); + } + switch (interp_n) { + case INTERP_HPHL: + if (rx->is_ear_mode_on) + snd_soc_component_update_bits(component, + CDC_RX_CLSH_HPH_V_PA, + CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x39); + else + snd_soc_component_update_bits(component, + CDC_RX_CLSH_HPH_V_PA, + CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x1c); + snd_soc_component_update_bits(component, + CDC_RX_CLSH_DECAY_CTRL, + CDC_RX_CLSH_DECAY_RATE_MASK, 0x0); + snd_soc_component_write_field(component, + CDC_RX_RX0_RX_PATH_CFG0, + CDC_RX_RXn_CLSH_EN_MASK, 0x1); + break; + case INTERP_HPHR: + if (rx->is_ear_mode_on) + snd_soc_component_update_bits(component, + CDC_RX_CLSH_HPH_V_PA, + CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x39); + else + snd_soc_component_update_bits(component, + CDC_RX_CLSH_HPH_V_PA, + CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x1c); + snd_soc_component_update_bits(component, + CDC_RX_CLSH_DECAY_CTRL, + CDC_RX_CLSH_DECAY_RATE_MASK, 0x0); + snd_soc_component_update_bits(component, + CDC_RX_RX1_RX_PATH_CFG0, + CDC_RX_RXn_CLSH_EN_MASK, 0x1); + break; + case INTERP_AUX: + snd_soc_component_update_bits(component, + CDC_RX_RX2_RX_PATH_CFG0, + CDC_RX_RX2_DLY_Z_EN_MASK, 1); + snd_soc_component_write_field(component, + CDC_RX_RX2_RX_PATH_CFG0, + CDC_RX_RX2_CLSH_EN_MASK, 1); + break; + } + + return 0; +} + +static void rx_macro_hd2_control(struct snd_soc_component *component, + u16 interp_idx, int event) +{ + u16 hd2_scale_reg, hd2_enable_reg; + + switch (interp_idx) { + case INTERP_HPHL: + hd2_scale_reg = CDC_RX_RX0_RX_PATH_SEC3; + hd2_enable_reg = CDC_RX_RX0_RX_PATH_CFG0; + break; + case INTERP_HPHR: + hd2_scale_reg = CDC_RX_RX1_RX_PATH_SEC3; + hd2_enable_reg = CDC_RX_RX1_RX_PATH_CFG0; + break; + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_component_update_bits(component, hd2_scale_reg, + CDC_RX_RXn_HD2_ALPHA_MASK, 0x14); + snd_soc_component_write_field(component, hd2_enable_reg, + CDC_RX_RXn_HD2_EN_MASK, 1); + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_write_field(component, hd2_enable_reg, + CDC_RX_RXn_HD2_EN_MASK, 0); + snd_soc_component_update_bits(component, hd2_scale_reg, + CDC_RX_RXn_HD2_ALPHA_MASK, 0x0); + } +} + static int rx_macro_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1649,6 +2224,91 @@ static int rx_macro_set_compander(struct snd_kcontrol *kcontrol, return 0; } +static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = + rx->rx_port_value[widget->shift]; + return 0; +} + +static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + u32 rx_port_value = ucontrol->value.integer.value[0]; + u32 aif_rst; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + aif_rst = rx->rx_port_value[widget->shift]; + if (!rx_port_value) { + if (aif_rst == 0) { + dev_err(component->dev, "%s:AIF reset already\n", __func__); + return 0; + } + if (aif_rst > RX_MACRO_AIF4_PB) { + dev_err(component->dev, "%s: Invalid AIF reset\n", __func__); + return 0; + } + } + rx->rx_port_value[widget->shift] = rx_port_value; + + switch (rx_port_value) { + case 0: + if (rx->active_ch_cnt[aif_rst]) { + clear_bit(widget->shift, + &rx->active_ch_mask[aif_rst]); + rx->active_ch_cnt[aif_rst]--; + } + break; + case 1: + case 2: + case 3: + case 4: + set_bit(widget->shift, + &rx->active_ch_mask[rx_port_value]); + rx->active_ch_cnt[rx_port_value]++; + break; + default: + dev_err(component->dev, + "%s:Invalid AIF_ID for RX_MACRO MUX %d\n", + __func__, rx_port_value); + goto err; + } + + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + rx_port_value, e, update); + return 0; +err: + return -EINVAL; +} + +static const struct snd_kcontrol_new rx_macro_rx0_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx0", rx_macro_rx0_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx1_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx1", rx_macro_rx1_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx2_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx2", rx_macro_rx2_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx3_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx3", rx_macro_rx3_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx4_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx4", rx_macro_rx4_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx5_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx5", rx_macro_rx5_enum, + rx_macro_mux_get, rx_macro_mux_put); + static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1753,6 +2413,189 @@ static int rx_macro_aux_hpf_mode_put(struct snd_kcontrol *kcontrol, return 0; } +static int rx_macro_hphdelay_lutbypass(struct snd_soc_component *component, + struct rx_macro *rx, + u16 interp_idx, int event) +{ + u16 hph_lut_bypass_reg; + u16 hph_comp_ctrl7; + + switch (interp_idx) { + case INTERP_HPHL: + hph_lut_bypass_reg = CDC_RX_TOP_HPHL_COMP_LUT; + hph_comp_ctrl7 = CDC_RX_COMPANDER0_CTL7; + break; + case INTERP_HPHR: + hph_lut_bypass_reg = CDC_RX_TOP_HPHR_COMP_LUT; + hph_comp_ctrl7 = CDC_RX_COMPANDER1_CTL7; + break; + default: + return -EINVAL; + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { + if (interp_idx == INTERP_HPHL) { + if (rx->is_ear_mode_on) + snd_soc_component_write_field(component, + CDC_RX_RX0_RX_PATH_CFG1, + CDC_RX_RX0_HPH_L_EAR_SEL_MASK, 0x1); + else + snd_soc_component_write_field(component, + hph_lut_bypass_reg, + CDC_RX_TOP_HPH_LUT_BYPASS_MASK, 1); + } else { + snd_soc_component_write_field(component, hph_lut_bypass_reg, + CDC_RX_TOP_HPH_LUT_BYPASS_MASK, 1); + } + if (rx->hph_pwr_mode) + snd_soc_component_write_field(component, hph_comp_ctrl7, + CDC_RX_COMPANDER1_HPH_LOW_PWR_MODE_MASK, 0x0); + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_write_field(component, + CDC_RX_RX0_RX_PATH_CFG1, + CDC_RX_RX0_HPH_L_EAR_SEL_MASK, 0x0); + snd_soc_component_update_bits(component, hph_lut_bypass_reg, + CDC_RX_TOP_HPH_LUT_BYPASS_MASK, 0); + snd_soc_component_write_field(component, hph_comp_ctrl7, + CDC_RX_COMPANDER1_HPH_LOW_PWR_MODE_MASK, 0x1); + } + + return 0; +} + +static int rx_macro_enable_interp_clk(struct snd_soc_component *component, + int event, int interp_idx) +{ + u16 main_reg, dsm_reg, rx_cfg2_reg; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + main_reg = CDC_RX_RXn_RX_PATH_CTL(interp_idx); + dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(interp_idx); + if (interp_idx == INTERP_AUX) + dsm_reg = CDC_RX_RX2_RX_PATH_DSM_CTL; + rx_cfg2_reg = CDC_RX_RXn_RX_PATH_CFG2(interp_idx); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (rx->main_clk_users[interp_idx] == 0) { + /* Main path PGA mute enable */ + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_PGA_MUTE_MASK, 0x1); + snd_soc_component_write_field(component, dsm_reg, + CDC_RX_RXn_DSM_CLK_EN_MASK, 0x1); + snd_soc_component_update_bits(component, rx_cfg2_reg, + CDC_RX_RXn_HPF_CUT_FREQ_MASK, 0x03); + rx_macro_load_compander_coeff(component, rx, interp_idx, event); + if (rx->hph_hd2_mode) + rx_macro_hd2_control(component, interp_idx, event); + rx_macro_hphdelay_lutbypass(component, rx, interp_idx, event); + rx_macro_config_compander(component, rx, interp_idx, event); + if (interp_idx == INTERP_AUX) { + rx_macro_config_softclip(component, rx, event); + rx_macro_config_aux_hpf(component, rx, event); + } + rx_macro_config_classh(component, rx, interp_idx, event); + } + rx->main_clk_users[interp_idx]++; + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + rx->main_clk_users[interp_idx]--; + if (rx->main_clk_users[interp_idx] <= 0) { + rx->main_clk_users[interp_idx] = 0; + /* Main path PGA mute enable */ + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_PGA_MUTE_MASK, 0x1); + /* Clk Disable */ + snd_soc_component_write_field(component, dsm_reg, + CDC_RX_RXn_DSM_CLK_EN_MASK, 0); + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_CLK_EN_MASK, 0); + /* Reset enable and disable */ + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_RESET_EN_MASK, 1); + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_RESET_EN_MASK, 0); + /* Reset rate to 48K*/ + snd_soc_component_update_bits(component, main_reg, + CDC_RX_PATH_PCM_RATE_MASK, + 0x04); + snd_soc_component_update_bits(component, rx_cfg2_reg, + CDC_RX_RXn_HPF_CUT_FREQ_MASK, 0x00); + rx_macro_config_classh(component, rx, interp_idx, event); + rx_macro_config_compander(component, rx, interp_idx, event); + if (interp_idx == INTERP_AUX) { + rx_macro_config_softclip(component, rx, event); + rx_macro_config_aux_hpf(component, rx, event); + } + rx_macro_hphdelay_lutbypass(component, rx, interp_idx, event); + if (rx->hph_hd2_mode) + rx_macro_hd2_control(component, interp_idx, event); + } + } + + return rx->main_clk_users[interp_idx]; +} + +static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + u16 gain_reg, mix_reg; + + gain_reg = CDC_RX_RXn_RX_VOL_MIX_CTL(w->shift); + mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(w->shift); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_enable_interp_clk(component, event, w->shift); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_write(component, gain_reg, + snd_soc_component_read(component, gain_reg)); + break; + case SND_SOC_DAPM_POST_PMD: + /* Clk Disable */ + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_RXn_MIX_CLK_EN_MASK, 0x00); + rx_macro_enable_interp_clk(component, event, w->shift); + /* Reset enable and disable */ + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_RXn_MIX_RESET_MASK, + CDC_RX_RXn_MIX_RESET); + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_RXn_MIX_RESET_MASK, 0x00); + break; + } + + return 0; +} + +static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_enable_interp_clk(component, event, w->shift); + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG1(w->shift), + CDC_RX_RXn_SIDETONE_EN_MASK, 1); + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CTL(w->shift), + CDC_RX_PATH_CLK_EN_MASK, 1); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG1(w->shift), + CDC_RX_RXn_SIDETONE_EN_MASK, 0); + rx_macro_enable_interp_clk(component, event, w->shift); + break; + default: + break; + }; + return 0; +} + static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_S8_TLV("RX_RX0 Digital Volume", CDC_RX_RX0_RX_VOL_CTL, -84, 40, digital_gain), @@ -1789,6 +2632,500 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { rx_macro_aux_hpf_mode_put), }; +static int rx_macro_enable_echo(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + u16 val, ec_hq_reg; + int ec_tx; + + val = snd_soc_component_read(component, + CDC_RX_INP_MUX_RX_MIX_CFG4); + if (!(strcmp(w->name, "RX MIX TX0 MUX"))) + ec_tx = ((val & 0xf0) >> 0x4) - 1; + else if (!(strcmp(w->name, "RX MIX TX1 MUX"))) + ec_tx = (val & 0x0f) - 1; + + val = snd_soc_component_read(component, + CDC_RX_INP_MUX_RX_MIX_CFG5); + if (!(strcmp(w->name, "RX MIX TX2 MUX"))) + ec_tx = (val & 0x0f) - 1; + + if (ec_tx < 0 || (ec_tx >= RX_MACRO_EC_MUX_MAX)) { + dev_err(component->dev, "%s: EC mix control not set correctly\n", + __func__); + return -EINVAL; + } + ec_hq_reg = CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL + + 0x40 * ec_tx; + snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01); + ec_hq_reg = CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 + + 0x40 * ec_tx; + /* default set to 48k */ + snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08); + + return 0; +} + +static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("RX AIF1 PB", "RX_MACRO_AIF1 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("RX AIF2 PB", "RX_MACRO_AIF2 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("RX AIF3 PB", "RX_MACRO_AIF3 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("RX AIF4 PB", "RX_MACRO_AIF4 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MUX("RX_MACRO RX0 MUX", SND_SOC_NOPM, RX_MACRO_RX0, 0, + &rx_macro_rx0_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX1 MUX", SND_SOC_NOPM, RX_MACRO_RX1, 0, + &rx_macro_rx1_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX2 MUX", SND_SOC_NOPM, RX_MACRO_RX2, 0, + &rx_macro_rx2_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX3 MUX", SND_SOC_NOPM, RX_MACRO_RX3, 0, + &rx_macro_rx3_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX4 MUX", SND_SOC_NOPM, RX_MACRO_RX4, 0, + &rx_macro_rx4_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX5 MUX", SND_SOC_NOPM, RX_MACRO_RX5, 0, + &rx_macro_rx5_mux), + + SND_SOC_DAPM_MIXER("RX_RX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX5", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux), + SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux), + SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux), + SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux), + SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux), + SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux), + SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux), + SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux), + + SND_SOC_DAPM_MUX_E("RX MIX TX0 MUX", SND_SOC_NOPM, + RX_MACRO_EC0_MUX, 0, + &rx_mix_tx0_mux, rx_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX MIX TX1 MUX", SND_SOC_NOPM, + RX_MACRO_EC1_MUX, 0, + &rx_mix_tx1_mux, rx_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX MIX TX2 MUX", SND_SOC_NOPM, + RX_MACRO_EC2_MUX, 0, + &rx_mix_tx2_mux, rx_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("SRC0", CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SRC1", CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + + SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0, + &rx_int0_dem_inp_mux), + SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0, + &rx_int1_dem_inp_mux), + + SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int0_2_mux, rx_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int1_2_mux, rx_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0, + &rx_int2_2_mux, rx_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, &rx_int0_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_int0_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, &rx_int0_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, &rx_int1_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_int1_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, &rx_int1_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, &rx_int2_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_int2_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, &rx_int2_1_mix_inp2_mux), + + SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int0_1_interp_mux, rx_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int1_1_interp_mux, rx_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0, + &rx_int2_1_interp_mux, rx_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("RX INT0_2 INTERP", SND_SOC_NOPM, 0, 0, + &rx_int0_2_interp_mux), + SND_SOC_DAPM_MUX("RX INT1_2 INTERP", SND_SOC_NOPM, 0, 0, + &rx_int1_2_interp_mux), + SND_SOC_DAPM_MUX("RX INT2_2 INTERP", SND_SOC_NOPM, 0, 0, + &rx_int2_2_interp_mux), + + SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL, + 0, &rx_int0_mix2_inp_mux, rx_macro_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR, + 0, &rx_int1_mix2_inp_mux, rx_macro_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_AUX, + 0, &rx_int2_mix2_inp_mux, rx_macro_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("HPHL_OUT"), + SND_SOC_DAPM_OUTPUT("HPHR_OUT"), + SND_SOC_DAPM_OUTPUT("AUX_OUT"), + + SND_SOC_DAPM_INPUT("RX_TX DEC0_INP"), + SND_SOC_DAPM_INPUT("RX_TX DEC1_INP"), + SND_SOC_DAPM_INPUT("RX_TX DEC2_INP"), + SND_SOC_DAPM_INPUT("RX_TX DEC3_INP"), + + SND_SOC_DAPM_SUPPLY_S("RX_MCLK", 0, SND_SOC_NOPM, 0, 0, + rx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route rx_audio_map[] = { + {"RX AIF1 PB", NULL, "RX_MCLK"}, + {"RX AIF2 PB", NULL, "RX_MCLK"}, + {"RX AIF3 PB", NULL, "RX_MCLK"}, + {"RX AIF4 PB", NULL, "RX_MCLK"}, + + {"RX_MACRO RX0 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX1 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX2 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX3 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX4 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX5 MUX", "AIF1_PB", "RX AIF1 PB"}, + + {"RX_MACRO RX0 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX1 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX2 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX3 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX4 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX5 MUX", "AIF2_PB", "RX AIF2 PB"}, + + {"RX_MACRO RX0 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX1 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX2 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX3 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX4 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX5 MUX", "AIF3_PB", "RX AIF3 PB"}, + + {"RX_MACRO RX0 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX1 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX2 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX3 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX4 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX5 MUX", "AIF4_PB", "RX AIF4 PB"}, + + {"RX_RX0", NULL, "RX_MACRO RX0 MUX"}, + {"RX_RX1", NULL, "RX_MACRO RX1 MUX"}, + {"RX_RX2", NULL, "RX_MACRO RX2 MUX"}, + {"RX_RX3", NULL, "RX_MACRO RX3 MUX"}, + {"RX_RX4", NULL, "RX_MACRO RX4 MUX"}, + {"RX_RX5", NULL, "RX_MACRO RX5 MUX"}, + + {"RX INT0_1 MIX1 INP0", "RX0", "RX_RX0"}, + {"RX INT0_1 MIX1 INP0", "RX1", "RX_RX1"}, + {"RX INT0_1 MIX1 INP0", "RX2", "RX_RX2"}, + {"RX INT0_1 MIX1 INP0", "RX3", "RX_RX3"}, + {"RX INT0_1 MIX1 INP0", "RX4", "RX_RX4"}, + {"RX INT0_1 MIX1 INP0", "RX5", "RX_RX5"}, + {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT0_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT0_1 MIX1 INP1", "RX0", "RX_RX0"}, + {"RX INT0_1 MIX1 INP1", "RX1", "RX_RX1"}, + {"RX INT0_1 MIX1 INP1", "RX2", "RX_RX2"}, + {"RX INT0_1 MIX1 INP1", "RX3", "RX_RX3"}, + {"RX INT0_1 MIX1 INP1", "RX4", "RX_RX4"}, + {"RX INT0_1 MIX1 INP1", "RX5", "RX_RX5"}, + {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT0_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT0_1 MIX1 INP2", "RX0", "RX_RX0"}, + {"RX INT0_1 MIX1 INP2", "RX1", "RX_RX1"}, + {"RX INT0_1 MIX1 INP2", "RX2", "RX_RX2"}, + {"RX INT0_1 MIX1 INP2", "RX3", "RX_RX3"}, + {"RX INT0_1 MIX1 INP2", "RX4", "RX_RX4"}, + {"RX INT0_1 MIX1 INP2", "RX5", "RX_RX5"}, + {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT0_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, + + {"RX INT1_1 MIX1 INP0", "RX0", "RX_RX0"}, + {"RX INT1_1 MIX1 INP0", "RX1", "RX_RX1"}, + {"RX INT1_1 MIX1 INP0", "RX2", "RX_RX2"}, + {"RX INT1_1 MIX1 INP0", "RX3", "RX_RX3"}, + {"RX INT1_1 MIX1 INP0", "RX4", "RX_RX4"}, + {"RX INT1_1 MIX1 INP0", "RX5", "RX_RX5"}, + {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT1_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT1_1 MIX1 INP1", "RX0", "RX_RX0"}, + {"RX INT1_1 MIX1 INP1", "RX1", "RX_RX1"}, + {"RX INT1_1 MIX1 INP1", "RX2", "RX_RX2"}, + {"RX INT1_1 MIX1 INP1", "RX3", "RX_RX3"}, + {"RX INT1_1 MIX1 INP1", "RX4", "RX_RX4"}, + {"RX INT1_1 MIX1 INP1", "RX5", "RX_RX5"}, + {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT1_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT1_1 MIX1 INP2", "RX0", "RX_RX0"}, + {"RX INT1_1 MIX1 INP2", "RX1", "RX_RX1"}, + {"RX INT1_1 MIX1 INP2", "RX2", "RX_RX2"}, + {"RX INT1_1 MIX1 INP2", "RX3", "RX_RX3"}, + {"RX INT1_1 MIX1 INP2", "RX4", "RX_RX4"}, + {"RX INT1_1 MIX1 INP2", "RX5", "RX_RX5"}, + {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT1_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, + + {"RX INT2_1 MIX1 INP0", "RX0", "RX_RX0"}, + {"RX INT2_1 MIX1 INP0", "RX1", "RX_RX1"}, + {"RX INT2_1 MIX1 INP0", "RX2", "RX_RX2"}, + {"RX INT2_1 MIX1 INP0", "RX3", "RX_RX3"}, + {"RX INT2_1 MIX1 INP0", "RX4", "RX_RX4"}, + {"RX INT2_1 MIX1 INP0", "RX5", "RX_RX5"}, + {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT2_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT2_1 MIX1 INP1", "RX0", "RX_RX0"}, + {"RX INT2_1 MIX1 INP1", "RX1", "RX_RX1"}, + {"RX INT2_1 MIX1 INP1", "RX2", "RX_RX2"}, + {"RX INT2_1 MIX1 INP1", "RX3", "RX_RX3"}, + {"RX INT2_1 MIX1 INP1", "RX4", "RX_RX4"}, + {"RX INT2_1 MIX1 INP1", "RX5", "RX_RX5"}, + {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT2_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT2_1 MIX1 INP2", "RX0", "RX_RX0"}, + {"RX INT2_1 MIX1 INP2", "RX1", "RX_RX1"}, + {"RX INT2_1 MIX1 INP2", "RX2", "RX_RX2"}, + {"RX INT2_1 MIX1 INP2", "RX3", "RX_RX3"}, + {"RX INT2_1 MIX1 INP2", "RX4", "RX_RX4"}, + {"RX INT2_1 MIX1 INP2", "RX5", "RX_RX5"}, + {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT2_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, + + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"}, + + {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX AIF_ECHO", NULL, "RX MIX TX0 MUX"}, + {"RX AIF_ECHO", NULL, "RX MIX TX1 MUX"}, + {"RX AIF_ECHO", NULL, "RX MIX TX2 MUX"}, + {"RX AIF_ECHO", NULL, "RX_MCLK"}, + + /* Mixing path INT0 */ + {"RX INT0_2 MUX", "RX0", "RX_RX0"}, + {"RX INT0_2 MUX", "RX1", "RX_RX1"}, + {"RX INT0_2 MUX", "RX2", "RX_RX2"}, + {"RX INT0_2 MUX", "RX3", "RX_RX3"}, + {"RX INT0_2 MUX", "RX4", "RX_RX4"}, + {"RX INT0_2 MUX", "RX5", "RX_RX5"}, + {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"}, + + /* Mixing path INT1 */ + {"RX INT1_2 MUX", "RX0", "RX_RX0"}, + {"RX INT1_2 MUX", "RX1", "RX_RX1"}, + {"RX INT1_2 MUX", "RX2", "RX_RX2"}, + {"RX INT1_2 MUX", "RX3", "RX_RX3"}, + {"RX INT1_2 MUX", "RX4", "RX_RX4"}, + {"RX INT1_2 MUX", "RX5", "RX_RX5"}, + {"RX INT1_2 INTERP", NULL, "RX INT1_2 MUX"}, + {"RX INT1 SEC MIX", NULL, "RX INT1_2 INTERP"}, + + /* Mixing path INT2 */ + {"RX INT2_2 MUX", "RX0", "RX_RX0"}, + {"RX INT2_2 MUX", "RX1", "RX_RX1"}, + {"RX INT2_2 MUX", "RX2", "RX_RX2"}, + {"RX INT2_2 MUX", "RX3", "RX_RX3"}, + {"RX INT2_2 MUX", "RX4", "RX_RX4"}, + {"RX INT2_2 MUX", "RX5", "RX_RX5"}, + {"RX INT2_2 INTERP", NULL, "RX INT2_2 MUX"}, + {"RX INT2 SEC MIX", NULL, "RX INT2_2 INTERP"}, + + {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"}, + {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"}, + {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"}, + {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"}, + {"HPHL_OUT", NULL, "RX INT0 DEM MUX"}, + {"HPHL_OUT", NULL, "RX_MCLK"}, + + {"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"}, + {"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"}, + {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"}, + {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"}, + {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX2"}, + {"HPHR_OUT", NULL, "RX INT1 DEM MUX"}, + {"HPHR_OUT", NULL, "RX_MCLK"}, + + {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"}, + + {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"}, + {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"}, + {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"}, + {"AUX_OUT", NULL, "RX INT2 MIX2"}, + {"AUX_OUT", NULL, "RX_MCLK"}, + + {"IIR0", NULL, "RX_MCLK"}, + {"IIR0", NULL, "IIR0 INP0 MUX"}, + {"IIR0 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP0 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP0 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP0 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP0 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP0 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP0 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP0 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP0 MUX", "RX5", "RX_RX5"}, + {"IIR0", NULL, "IIR0 INP1 MUX"}, + {"IIR0 INP1 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP1 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP1 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP1 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP1 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP1 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP1 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP1 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP1 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP1 MUX", "RX5", "RX_RX5"}, + {"IIR0", NULL, "IIR0 INP2 MUX"}, + {"IIR0 INP2 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP2 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP2 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP2 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP2 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP2 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP2 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP2 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP2 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP2 MUX", "RX5", "RX_RX5"}, + {"IIR0", NULL, "IIR0 INP3 MUX"}, + {"IIR0 INP3 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP3 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP3 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP3 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP3 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP3 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP3 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP3 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP3 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP3 MUX", "RX5", "RX_RX5"}, + + {"IIR1", NULL, "RX_MCLK"}, + {"IIR1", NULL, "IIR1 INP0 MUX"}, + {"IIR1 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP0 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP0 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP0 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP0 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP0 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP0 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP0 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP0 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "IIR1 INP1 MUX"}, + {"IIR1 INP1 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP1 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP1 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP1 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP1 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP1 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP1 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP1 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP1 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP1 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "IIR1 INP2 MUX"}, + {"IIR1 INP2 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP2 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP2 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP2 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP2 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP2 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP2 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP2 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP2 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP2 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "IIR1 INP3 MUX"}, + {"IIR1 INP3 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP3 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP3 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP3 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP3 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP3 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP3 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP3 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP3 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP3 MUX", "RX5", "RX_RX5"}, + + {"SRC0", NULL, "IIR0"}, + {"SRC1", NULL, "IIR1"}, + {"RX INT0 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT0 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT1 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT1 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT2 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT2 MIX2 INP", "SRC1", "SRC1"}, +}; + static int rx_macro_component_probe(struct snd_soc_component *component) { struct rx_macro *rx = snd_soc_component_get_drvdata(component); @@ -1908,6 +3245,10 @@ static const struct snd_soc_component_driver rx_macro_component_drv = { .probe = rx_macro_component_probe, .controls = rx_macro_snd_controls, .num_controls = ARRAY_SIZE(rx_macro_snd_controls), + .dapm_widgets = rx_macro_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(rx_macro_dapm_widgets), + .dapm_routes = rx_audio_map, + .num_dapm_routes = ARRAY_SIZE(rx_audio_map), }; static int rx_macro_probe(struct platform_device *pdev) -- GitLab From f3ce6f3c9a994d3fa5057cadfaa1d883e0d938fa Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 11 Feb 2021 12:27:32 +0000 Subject: [PATCH 1070/1084] ASoC: codecs: lpass-rx-macro: add iir widgets This patch adds iir widgets and mixers on this codec Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210211122735.5691-5-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-rx-macro.c | 264 ++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 2cf6eb9238a70..c9c21d22c2c45 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -525,6 +525,38 @@ enum { INTERP_MIX_PATH, }; +/* Codec supports 2 IIR filters */ +enum { + IIR0 = 0, + IIR1, + IIR_MAX, +}; + +/* Each IIR has 5 Filter Stages */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +#define RX_MACRO_IIR_FILTER_SIZE (sizeof(u32) * BAND_MAX) + +#define RX_MACRO_IIR_FILTER_CTL(xname, iidx, bidx) \ +{ \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = rx_macro_iir_filter_info, \ + .get = rx_macro_get_iir_band_audio_mixer, \ + .put = rx_macro_put_iir_band_audio_mixer, \ + .private_value = (unsigned long)&(struct wcd_iir_filter_ctl) { \ + .iir_idx = iidx, \ + .band_idx = bidx, \ + .bytes_ext = {.max = RX_MACRO_IIR_FILTER_SIZE, }, \ + } \ +} + struct interp_sample_rate { int sample_rate; int rate_val; @@ -581,6 +613,12 @@ struct rx_macro { }; #define to_rx_macro(_hw) container_of(_hw, struct rx_macro, hw) +struct wcd_iir_filter_ctl { + unsigned int iir_idx; + unsigned int band_idx; + struct soc_bytes_ext bytes_ext; +}; + static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); static const char * const rx_int_mix_mux_text[] = { @@ -2596,6 +2634,166 @@ static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w, return 0; } +static int rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: /* fall through */ + case SND_SOC_DAPM_PRE_PMD: + if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); + } else { + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL)); + } + break; + } + return 0; +} + +static uint32_t get_iir_band_coeff(struct snd_soc_component *component, + int iir_idx, int band_idx, int coeff_idx) +{ + u32 value; + int reg, b2_reg; + + /* Address does not automatically update if reading */ + reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx; + b2_reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; + + snd_soc_component_write(component, reg, + ((band_idx * BAND_MAX + coeff_idx) * + sizeof(uint32_t)) & 0x7F); + + value = snd_soc_component_read(component, b2_reg); + snd_soc_component_write(component, reg, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_component_read(component, b2_reg) << 8); + snd_soc_component_write(component, reg, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_component_read(component, b2_reg) << 16); + snd_soc_component_write(component, reg, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= (snd_soc_component_read(component, b2_reg) << 24); + return value; +} + +static void set_iir_band_coeff(struct snd_soc_component *component, + int iir_idx, int band_idx, uint32_t value) +{ + int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; + + snd_soc_component_write(component, reg, (value & 0xFF)); + snd_soc_component_write(component, reg, (value >> 8) & 0xFF); + snd_soc_component_write(component, reg, (value >> 16) & 0xFF); + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_component_write(component, reg, (value >> 24) & 0x3F); +} + +static int rx_macro_put_iir_band_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd_iir_filter_ctl *ctl = + (struct wcd_iir_filter_ctl *)kcontrol->private_value; + struct soc_bytes_ext *params = &ctl->bytes_ext; + int iir_idx = ctl->iir_idx; + int band_idx = ctl->band_idx; + u32 coeff[BAND_MAX]; + int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx; + + memcpy(&coeff[0], ucontrol->value.bytes.data, params->max); + + /* Mask top bit it is reserved */ + /* Updates addr automatically for each B2 write */ + snd_soc_component_write(component, reg, (band_idx * BAND_MAX * + sizeof(uint32_t)) & 0x7F); + + set_iir_band_coeff(component, iir_idx, band_idx, coeff[0]); + set_iir_band_coeff(component, iir_idx, band_idx, coeff[1]); + set_iir_band_coeff(component, iir_idx, band_idx, coeff[2]); + set_iir_band_coeff(component, iir_idx, band_idx, coeff[3]); + set_iir_band_coeff(component, iir_idx, band_idx, coeff[4]); + + return 0; +} + +static int rx_macro_get_iir_band_audio_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd_iir_filter_ctl *ctl = + (struct wcd_iir_filter_ctl *)kcontrol->private_value; + struct soc_bytes_ext *params = &ctl->bytes_ext; + int iir_idx = ctl->iir_idx; + int band_idx = ctl->band_idx; + u32 coeff[BAND_MAX]; + + coeff[0] = get_iir_band_coeff(component, iir_idx, band_idx, 0); + coeff[1] = get_iir_band_coeff(component, iir_idx, band_idx, 1); + coeff[2] = get_iir_band_coeff(component, iir_idx, band_idx, 2); + coeff[3] = get_iir_band_coeff(component, iir_idx, band_idx, 3); + coeff[4] = get_iir_band_coeff(component, iir_idx, band_idx, 4); + + memcpy(ucontrol->value.bytes.data, &coeff[0], params->max); + + return 0; +} + +static int rx_macro_iir_filter_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *ucontrol) +{ + struct wcd_iir_filter_ctl *ctl = + (struct wcd_iir_filter_ctl *)kcontrol->private_value; + struct soc_bytes_ext *params = &ctl->bytes_ext; + + ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; + ucontrol->count = params->max; + + return 0; +} + static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_S8_TLV("RX_RX0 Digital Volume", CDC_RX_RX0_RX_VOL_CTL, -84, 40, digital_gain), @@ -2630,6 +2828,65 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_EXT("AUX_HPF Switch", SND_SOC_NOPM, 0, 1, 0, rx_macro_aux_hpf_mode_get, rx_macro_aux_hpf_mode_put), + + SOC_SINGLE_S8_TLV("IIR0 INP0 Volume", + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR0 INP1 Volume", + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR0 INP2 Volume", + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR0 INP3 Volume", + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP0 Volume", + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, -84, 40, + digital_gain), + + SOC_SINGLE("IIR1 Band1 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 0, 1, 0), + SOC_SINGLE("IIR1 Band2 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 1, 1, 0), + SOC_SINGLE("IIR1 Band3 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 2, 1, 0), + SOC_SINGLE("IIR1 Band4 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 3, 1, 0), + SOC_SINGLE("IIR1 Band5 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 4, 1, 0), + SOC_SINGLE("IIR2 Band1 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 0, 1, 0), + SOC_SINGLE("IIR2 Band2 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 1, 1, 0), + SOC_SINGLE("IIR2 Band3 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 2, 1, 0), + SOC_SINGLE("IIR2 Band4 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 3, 1, 0), + SOC_SINGLE("IIR2 Band5 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 4, 1, 0), + + RX_MACRO_IIR_FILTER_CTL("IIR0 Band1", IIR0, BAND1), + RX_MACRO_IIR_FILTER_CTL("IIR0 Band2", IIR0, BAND2), + RX_MACRO_IIR_FILTER_CTL("IIR0 Band3", IIR0, BAND3), + RX_MACRO_IIR_FILTER_CTL("IIR0 Band4", IIR0, BAND4), + RX_MACRO_IIR_FILTER_CTL("IIR0 Band5", IIR0, BAND5), + + RX_MACRO_IIR_FILTER_CTL("IIR1 Band1", IIR1, BAND1), + RX_MACRO_IIR_FILTER_CTL("IIR1 Band2", IIR1, BAND2), + RX_MACRO_IIR_FILTER_CTL("IIR1 Band3", IIR1, BAND3), + RX_MACRO_IIR_FILTER_CTL("IIR1 Band4", IIR1, BAND4), + RX_MACRO_IIR_FILTER_CTL("IIR1 Band5", IIR1, BAND5), + }; static int rx_macro_enable_echo(struct snd_soc_dapm_widget *w, @@ -2725,6 +2982,13 @@ static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { RX_MACRO_EC2_MUX, 0, &rx_mix_tx2_mux, rx_macro_enable_echo, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("IIR0", CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, + 4, 0, NULL, 0, rx_macro_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MIXER_E("IIR1", CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, + 4, 0, NULL, 0, rx_macro_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_MIXER("SRC0", CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, 4, 0, NULL, 0), SND_SOC_DAPM_MIXER("SRC1", CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, -- GitLab From ca955cc980afc066a380567e371480634e48eb7e Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 11 Feb 2021 12:27:33 +0000 Subject: [PATCH 1071/1084] ASoC: qcom: dt-bindings: add bindings for lpass tx macro codec This binding is for LPASS has internal codec TX macro which is for connecting with Soundwire TX codecs like WCD938x. Signed-off-by: Srinivas Kandagatla Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210211122735.5691-6-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- .../bindings/sound/qcom,lpass-tx-macro.yaml | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml new file mode 100644 index 0000000000000..6b5ca02ccce41 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/qcom,lpass-tx-macro.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LPASS(Low Power Audio Subsystem) TX Macro audio codec DT bindings + +maintainers: + - Srinivas Kandagatla + +properties: + compatible: + const: qcom,sm8250-lpass-tx-macro + + reg: + maxItems: 1 + + "#sound-dai-cells": + const: 1 + + '#clock-cells': + const: 0 + + clocks: + maxItems: 5 + + clock-names: + items: + - const: mclk + - const: npl + - const: macro + - const: dcodec + - const: fsgen + + clock-output-names: + items: + - const: mclk + + qcom,dmic-sample-rate: + description: dmic sample rate + $ref: /schemas/types.yaml#/definitions/uint32 + +required: + - compatible + - reg + - "#sound-dai-cells" + +additionalProperties: false + +examples: + - | + #include + codec@3220000 { + compatible = "qcom,sm8250-lpass-tx-macro"; + reg = <0x3220000 0x1000>; + #sound-dai-cells = <1>; + #clock-cells = <0>; + clocks = <&aoncc 0>, + <&aoncc 1>, + <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&vamacro>; + clock-names = "mclk", "npl", "macro", "dcodec", "fsgen"; + clock-output-names = "mclk"; + qcom,dmic-sample-rate = <600000>; + }; -- GitLab From c39667ddcfc516fee084e449179d54430a558298 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 11 Feb 2021 12:27:34 +0000 Subject: [PATCH 1072/1084] ASoC: codecs: lpass-tx-macro: add support for lpass tx macro Qualcomm LPASS (Low Power Audio SubSystem) has internal codec TX macro block which is used for connecting with external Soundwire TX Codecs like WCD938x. This patch adds support to the codec part of the TX Macro block Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210211122735.5691-7-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/lpass-tx-macro.c | 1177 +++++++++++++++++++++++++++++ 3 files changed, 1184 insertions(+) create mode 100644 sound/soc/codecs/lpass-tx-macro.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 5fb5a5a2c605d..e4cf14e66a51b 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -229,6 +229,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_WCD9335 imply SND_SOC_WCD934X imply SND_SOC_LPASS_RX_MACRO + imply SND_SOC_LPASS_TX_MACRO imply SND_SOC_WL1273 imply SND_SOC_WM0010 imply SND_SOC_WM1250_EV1 @@ -1838,4 +1839,8 @@ config SND_SOC_LPASS_RX_MACRO depends on COMMON_CLK tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)" +config SND_SOC_LPASS_TX_MACRO + depends on COMMON_CLK + tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)" + endmenu diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 004ffcbe0b986..81357dc62ea09 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -108,6 +108,7 @@ snd-soc-lm4857-objs := lm4857.o snd-soc-lm49453-objs := lm49453.o snd-soc-lochnagar-sc-objs := lochnagar-sc.o snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o +snd-soc-lpass-tx-macro-objs := lpass-tx-macro.o snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o snd-soc-lpass-va-macro-objs := lpass-va-macro.o snd-soc-madera-objs := madera.o @@ -627,6 +628,7 @@ obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o +obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) += snd-soc-lpass-tx-macro.o # Mux obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c new file mode 100644 index 0000000000000..06589dad6bc2c --- /dev/null +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -0,0 +1,1177 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CDC_TX_CLK_RST_CTRL_MCLK_CONTROL (0x0000) +#define CDC_TX_MCLK_EN_MASK BIT(0) +#define CDC_TX_MCLK_ENABLE BIT(0) +#define CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL (0x0004) +#define CDC_TX_FS_CNT_EN_MASK BIT(0) +#define CDC_TX_FS_CNT_ENABLE BIT(0) +#define CDC_TX_CLK_RST_CTRL_SWR_CONTROL (0x0008) +#define CDC_TX_SWR_RESET_MASK BIT(1) +#define CDC_TX_SWR_RESET_ENABLE BIT(1) +#define CDC_TX_SWR_CLK_EN_MASK BIT(0) +#define CDC_TX_SWR_CLK_ENABLE BIT(0) +#define CDC_TX_TOP_CSR_TOP_CFG0 (0x0080) +#define CDC_TX_TOP_CSR_ANC_CFG (0x0084) +#define CDC_TX_TOP_CSR_SWR_CTRL (0x0088) +#define CDC_TX_TOP_CSR_FREQ_MCLK (0x0090) +#define CDC_TX_TOP_CSR_DEBUG_BUS (0x0094) +#define CDC_TX_TOP_CSR_DEBUG_EN (0x0098) +#define CDC_TX_TOP_CSR_TX_I2S_CTL (0x00A4) +#define CDC_TX_TOP_CSR_I2S_CLK (0x00A8) +#define CDC_TX_TOP_CSR_I2S_RESET (0x00AC) +#define CDC_TX_TOP_CSR_SWR_DMICn_CTL(n) (0x00C0 + n * 0x4) +#define CDC_TX_TOP_CSR_SWR_DMIC0_CTL (0x00C0) +#define CDC_TX_SWR_DMIC_CLK_SEL_MASK GENMASK(3, 1) +#define CDC_TX_TOP_CSR_SWR_DMIC1_CTL (0x00C4) +#define CDC_TX_TOP_CSR_SWR_DMIC2_CTL (0x00C8) +#define CDC_TX_TOP_CSR_SWR_DMIC3_CTL (0x00CC) +#define CDC_TX_TOP_CSR_SWR_AMIC0_CTL (0x00D0) +#define CDC_TX_TOP_CSR_SWR_AMIC1_CTL (0x00D4) +#define CDC_TX_INP_MUX_ADC_MUXn_CFG0(n) (0x0100 + 0x8 * n) +#define CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK GENMASK(3, 0) +#define CDC_TX_INP_MUX_ADC_MUX0_CFG0 (0x0100) +#define CDC_TX_INP_MUX_ADC_MUXn_CFG1(n) (0x0104 + 0x8 * n) +#define CDC_TX_INP_MUX_ADC_MUX0_CFG1 (0x0104) +#define CDC_TX_INP_MUX_ADC_MUX1_CFG0 (0x0108) +#define CDC_TX_INP_MUX_ADC_MUX1_CFG1 (0x010C) +#define CDC_TX_INP_MUX_ADC_MUX2_CFG0 (0x0110) +#define CDC_TX_INP_MUX_ADC_MUX2_CFG1 (0x0114) +#define CDC_TX_INP_MUX_ADC_MUX3_CFG0 (0x0118) +#define CDC_TX_INP_MUX_ADC_MUX3_CFG1 (0x011C) +#define CDC_TX_INP_MUX_ADC_MUX4_CFG0 (0x0120) +#define CDC_TX_INP_MUX_ADC_MUX4_CFG1 (0x0124) +#define CDC_TX_INP_MUX_ADC_MUX5_CFG0 (0x0128) +#define CDC_TX_INP_MUX_ADC_MUX5_CFG1 (0x012C) +#define CDC_TX_INP_MUX_ADC_MUX6_CFG0 (0x0130) +#define CDC_TX_INP_MUX_ADC_MUX6_CFG1 (0x0134) +#define CDC_TX_INP_MUX_ADC_MUX7_CFG0 (0x0138) +#define CDC_TX_INP_MUX_ADC_MUX7_CFG1 (0x013C) +#define CDC_TX_ANC0_CLK_RESET_CTL (0x0200) +#define CDC_TX_ANC0_MODE_1_CTL (0x0204) +#define CDC_TX_ANC0_MODE_2_CTL (0x0208) +#define CDC_TX_ANC0_FF_SHIFT (0x020C) +#define CDC_TX_ANC0_FB_SHIFT (0x0210) +#define CDC_TX_ANC0_LPF_FF_A_CTL (0x0214) +#define CDC_TX_ANC0_LPF_FF_B_CTL (0x0218) +#define CDC_TX_ANC0_LPF_FB_CTL (0x021C) +#define CDC_TX_ANC0_SMLPF_CTL (0x0220) +#define CDC_TX_ANC0_DCFLT_SHIFT_CTL (0x0224) +#define CDC_TX_ANC0_IIR_ADAPT_CTL (0x0228) +#define CDC_TX_ANC0_IIR_COEFF_1_CTL (0x022C) +#define CDC_TX_ANC0_IIR_COEFF_2_CTL (0x0230) +#define CDC_TX_ANC0_FF_A_GAIN_CTL (0x0234) +#define CDC_TX_ANC0_FF_B_GAIN_CTL (0x0238) +#define CDC_TX_ANC0_FB_GAIN_CTL (0x023C) +#define CDC_TXn_TX_PATH_CTL(n) (0x0400 + 0x80 * n) +#define CDC_TXn_PCM_RATE_MASK GENMASK(3, 0) +#define CDC_TXn_PGA_MUTE_MASK BIT(4) +#define CDC_TXn_CLK_EN_MASK BIT(5) +#define CDC_TX0_TX_PATH_CTL (0x0400) +#define CDC_TXn_TX_PATH_CFG0(n) (0x0404 + 0x80 * n) +#define CDC_TX0_TX_PATH_CFG0 (0x0404) +#define CDC_TXn_PH_EN_MASK BIT(0) +#define CDC_TXn_ADC_MODE_MASK GENMASK(2, 1) +#define CDC_TXn_HPF_CUT_FREQ_MASK GENMASK(6, 5) +#define CDC_TXn_ADC_DMIC_SEL_MASK BIT(7) +#define CDC_TX0_TX_PATH_CFG1 (0x0408) +#define CDC_TXn_TX_VOL_CTL(n) (0x040C + 0x80 * n) +#define CDC_TX0_TX_VOL_CTL (0x040C) +#define CDC_TX0_TX_PATH_SEC0 (0x0410) +#define CDC_TX0_TX_PATH_SEC1 (0x0414) +#define CDC_TXn_TX_PATH_SEC2(n) (0x0418 + 0x80 * n) +#define CDC_TXn_HPF_F_CHANGE_MASK BIT(1) +#define CDC_TXn_HPF_ZERO_GATE_MASK BIT(0) +#define CDC_TX0_TX_PATH_SEC2 (0x0418) +#define CDC_TX0_TX_PATH_SEC3 (0x041C) +#define CDC_TX0_TX_PATH_SEC4 (0x0420) +#define CDC_TX0_TX_PATH_SEC5 (0x0424) +#define CDC_TX0_TX_PATH_SEC6 (0x0428) +#define CDC_TX0_TX_PATH_SEC7 (0x042C) +#define CDC_TX0_MBHC_CTL_EN_MASK BIT(6) +#define CDC_TX1_TX_PATH_CTL (0x0480) +#define CDC_TX1_TX_PATH_CFG0 (0x0484) +#define CDC_TX1_TX_PATH_CFG1 (0x0488) +#define CDC_TX1_TX_VOL_CTL (0x048C) +#define CDC_TX1_TX_PATH_SEC0 (0x0490) +#define CDC_TX1_TX_PATH_SEC1 (0x0494) +#define CDC_TX1_TX_PATH_SEC2 (0x0498) +#define CDC_TX1_TX_PATH_SEC3 (0x049C) +#define CDC_TX1_TX_PATH_SEC4 (0x04A0) +#define CDC_TX1_TX_PATH_SEC5 (0x04A4) +#define CDC_TX1_TX_PATH_SEC6 (0x04A8) +#define CDC_TX2_TX_PATH_CTL (0x0500) +#define CDC_TX2_TX_PATH_CFG0 (0x0504) +#define CDC_TX2_TX_PATH_CFG1 (0x0508) +#define CDC_TX2_TX_VOL_CTL (0x050C) +#define CDC_TX2_TX_PATH_SEC0 (0x0510) +#define CDC_TX2_TX_PATH_SEC1 (0x0514) +#define CDC_TX2_TX_PATH_SEC2 (0x0518) +#define CDC_TX2_TX_PATH_SEC3 (0x051C) +#define CDC_TX2_TX_PATH_SEC4 (0x0520) +#define CDC_TX2_TX_PATH_SEC5 (0x0524) +#define CDC_TX2_TX_PATH_SEC6 (0x0528) +#define CDC_TX3_TX_PATH_CTL (0x0580) +#define CDC_TX3_TX_PATH_CFG0 (0x0584) +#define CDC_TX3_TX_PATH_CFG1 (0x0588) +#define CDC_TX3_TX_VOL_CTL (0x058C) +#define CDC_TX3_TX_PATH_SEC0 (0x0590) +#define CDC_TX3_TX_PATH_SEC1 (0x0594) +#define CDC_TX3_TX_PATH_SEC2 (0x0598) +#define CDC_TX3_TX_PATH_SEC3 (0x059C) +#define CDC_TX3_TX_PATH_SEC4 (0x05A0) +#define CDC_TX3_TX_PATH_SEC5 (0x05A4) +#define CDC_TX3_TX_PATH_SEC6 (0x05A8) +#define CDC_TX4_TX_PATH_CTL (0x0600) +#define CDC_TX4_TX_PATH_CFG0 (0x0604) +#define CDC_TX4_TX_PATH_CFG1 (0x0608) +#define CDC_TX4_TX_VOL_CTL (0x060C) +#define CDC_TX4_TX_PATH_SEC0 (0x0610) +#define CDC_TX4_TX_PATH_SEC1 (0x0614) +#define CDC_TX4_TX_PATH_SEC2 (0x0618) +#define CDC_TX4_TX_PATH_SEC3 (0x061C) +#define CDC_TX4_TX_PATH_SEC4 (0x0620) +#define CDC_TX4_TX_PATH_SEC5 (0x0624) +#define CDC_TX4_TX_PATH_SEC6 (0x0628) +#define CDC_TX5_TX_PATH_CTL (0x0680) +#define CDC_TX5_TX_PATH_CFG0 (0x0684) +#define CDC_TX5_TX_PATH_CFG1 (0x0688) +#define CDC_TX5_TX_VOL_CTL (0x068C) +#define CDC_TX5_TX_PATH_SEC0 (0x0690) +#define CDC_TX5_TX_PATH_SEC1 (0x0694) +#define CDC_TX5_TX_PATH_SEC2 (0x0698) +#define CDC_TX5_TX_PATH_SEC3 (0x069C) +#define CDC_TX5_TX_PATH_SEC4 (0x06A0) +#define CDC_TX5_TX_PATH_SEC5 (0x06A4) +#define CDC_TX5_TX_PATH_SEC6 (0x06A8) +#define CDC_TX6_TX_PATH_CTL (0x0700) +#define CDC_TX6_TX_PATH_CFG0 (0x0704) +#define CDC_TX6_TX_PATH_CFG1 (0x0708) +#define CDC_TX6_TX_VOL_CTL (0x070C) +#define CDC_TX6_TX_PATH_SEC0 (0x0710) +#define CDC_TX6_TX_PATH_SEC1 (0x0714) +#define CDC_TX6_TX_PATH_SEC2 (0x0718) +#define CDC_TX6_TX_PATH_SEC3 (0x071C) +#define CDC_TX6_TX_PATH_SEC4 (0x0720) +#define CDC_TX6_TX_PATH_SEC5 (0x0724) +#define CDC_TX6_TX_PATH_SEC6 (0x0728) +#define CDC_TX7_TX_PATH_CTL (0x0780) +#define CDC_TX7_TX_PATH_CFG0 (0x0784) +#define CDC_TX7_TX_PATH_CFG1 (0x0788) +#define CDC_TX7_TX_VOL_CTL (0x078C) +#define CDC_TX7_TX_PATH_SEC0 (0x0790) +#define CDC_TX7_TX_PATH_SEC1 (0x0794) +#define CDC_TX7_TX_PATH_SEC2 (0x0798) +#define CDC_TX7_TX_PATH_SEC3 (0x079C) +#define CDC_TX7_TX_PATH_SEC4 (0x07A0) +#define CDC_TX7_TX_PATH_SEC5 (0x07A4) +#define CDC_TX7_TX_PATH_SEC6 (0x07A8) +#define TX_MAX_OFFSET (0x07A8) + +#define TX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) +#define TX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 +#define TX_ADC_MAX 5 +#define TX_ADC_TO_DMIC(n) ((n - TX_ADC_MAX)/2) +#define NUM_DECIMATORS 8 +#define TX_NUM_CLKS_MAX 5 +#define TX_MACRO_DMIC_UNMUTE_DELAY_MS 40 +#define TX_MACRO_AMIC_UNMUTE_DELAY_MS 100 +#define TX_MACRO_DMIC_HPF_DELAY_MS 300 +#define TX_MACRO_AMIC_HPF_DELAY_MS 300 +#define MCLK_FREQ 9600000 + +enum { + TX_MACRO_AIF_INVALID = 0, + TX_MACRO_AIF1_CAP, + TX_MACRO_AIF2_CAP, + TX_MACRO_AIF3_CAP, + TX_MACRO_MAX_DAIS +}; + +enum { + TX_MACRO_DEC0, + TX_MACRO_DEC1, + TX_MACRO_DEC2, + TX_MACRO_DEC3, + TX_MACRO_DEC4, + TX_MACRO_DEC5, + TX_MACRO_DEC6, + TX_MACRO_DEC7, + TX_MACRO_DEC_MAX, +}; + +enum { + TX_MACRO_CLK_DIV_2, + TX_MACRO_CLK_DIV_3, + TX_MACRO_CLK_DIV_4, + TX_MACRO_CLK_DIV_6, + TX_MACRO_CLK_DIV_8, + TX_MACRO_CLK_DIV_16, +}; + +enum { + MSM_DMIC, + SWR_MIC, + ANC_FB_TUNE1 +}; + +struct tx_mute_work { + struct tx_macro *tx; + u32 decimator; + struct delayed_work dwork; +}; + +struct hpf_work { + struct tx_macro *tx; + u8 decimator; + u8 hpf_cut_off_freq; + struct delayed_work dwork; +}; + +struct tx_macro { + struct device *dev; + struct snd_soc_component *component; + struct hpf_work tx_hpf_work[NUM_DECIMATORS]; + struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; + unsigned long active_ch_mask[TX_MACRO_MAX_DAIS]; + unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS]; + unsigned long active_decimator[TX_MACRO_MAX_DAIS]; + struct regmap *regmap; + struct clk_bulk_data clks[TX_NUM_CLKS_MAX]; + struct clk_hw hw; + bool dec_active[NUM_DECIMATORS]; + bool reset_swr; + int tx_mclk_users; + u16 dmic_clk_div; + bool bcs_enable; + int dec_mode[NUM_DECIMATORS]; + bool bcs_clk_en; +}; +#define to_tx_macro(_hw) container_of(_hw, struct tx_macro, hw) + +static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); + +static const struct reg_default tx_defaults[] = { + /* TX Macro */ + { CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, + { CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, + { CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x00}, + { CDC_TX_TOP_CSR_TOP_CFG0, 0x00}, + { CDC_TX_TOP_CSR_ANC_CFG, 0x00}, + { CDC_TX_TOP_CSR_SWR_CTRL, 0x00}, + { CDC_TX_TOP_CSR_FREQ_MCLK, 0x00}, + { CDC_TX_TOP_CSR_DEBUG_BUS, 0x00}, + { CDC_TX_TOP_CSR_DEBUG_EN, 0x00}, + { CDC_TX_TOP_CSR_TX_I2S_CTL, 0x0C}, + { CDC_TX_TOP_CSR_I2S_CLK, 0x00}, + { CDC_TX_TOP_CSR_I2S_RESET, 0x00}, + { CDC_TX_TOP_CSR_SWR_DMIC0_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_DMIC1_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_DMIC2_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_DMIC3_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_AMIC0_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_AMIC1_CTL, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX4_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX5_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX6_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX7_CFG1, 0x00}, + { CDC_TX_ANC0_CLK_RESET_CTL, 0x00}, + { CDC_TX_ANC0_MODE_1_CTL, 0x00}, + { CDC_TX_ANC0_MODE_2_CTL, 0x00}, + { CDC_TX_ANC0_FF_SHIFT, 0x00}, + { CDC_TX_ANC0_FB_SHIFT, 0x00}, + { CDC_TX_ANC0_LPF_FF_A_CTL, 0x00}, + { CDC_TX_ANC0_LPF_FF_B_CTL, 0x00}, + { CDC_TX_ANC0_LPF_FB_CTL, 0x00}, + { CDC_TX_ANC0_SMLPF_CTL, 0x00}, + { CDC_TX_ANC0_DCFLT_SHIFT_CTL, 0x00}, + { CDC_TX_ANC0_IIR_ADAPT_CTL, 0x00}, + { CDC_TX_ANC0_IIR_COEFF_1_CTL, 0x00}, + { CDC_TX_ANC0_IIR_COEFF_2_CTL, 0x00}, + { CDC_TX_ANC0_FF_A_GAIN_CTL, 0x00}, + { CDC_TX_ANC0_FF_B_GAIN_CTL, 0x00}, + { CDC_TX_ANC0_FB_GAIN_CTL, 0x00}, + { CDC_TX0_TX_PATH_CTL, 0x04}, + { CDC_TX0_TX_PATH_CFG0, 0x10}, + { CDC_TX0_TX_PATH_CFG1, 0x0B}, + { CDC_TX0_TX_VOL_CTL, 0x00}, + { CDC_TX0_TX_PATH_SEC0, 0x00}, + { CDC_TX0_TX_PATH_SEC1, 0x00}, + { CDC_TX0_TX_PATH_SEC2, 0x01}, + { CDC_TX0_TX_PATH_SEC3, 0x3C}, + { CDC_TX0_TX_PATH_SEC4, 0x20}, + { CDC_TX0_TX_PATH_SEC5, 0x00}, + { CDC_TX0_TX_PATH_SEC6, 0x00}, + { CDC_TX0_TX_PATH_SEC7, 0x25}, + { CDC_TX1_TX_PATH_CTL, 0x04}, + { CDC_TX1_TX_PATH_CFG0, 0x10}, + { CDC_TX1_TX_PATH_CFG1, 0x0B}, + { CDC_TX1_TX_VOL_CTL, 0x00}, + { CDC_TX1_TX_PATH_SEC0, 0x00}, + { CDC_TX1_TX_PATH_SEC1, 0x00}, + { CDC_TX1_TX_PATH_SEC2, 0x01}, + { CDC_TX1_TX_PATH_SEC3, 0x3C}, + { CDC_TX1_TX_PATH_SEC4, 0x20}, + { CDC_TX1_TX_PATH_SEC5, 0x00}, + { CDC_TX1_TX_PATH_SEC6, 0x00}, + { CDC_TX2_TX_PATH_CTL, 0x04}, + { CDC_TX2_TX_PATH_CFG0, 0x10}, + { CDC_TX2_TX_PATH_CFG1, 0x0B}, + { CDC_TX2_TX_VOL_CTL, 0x00}, + { CDC_TX2_TX_PATH_SEC0, 0x00}, + { CDC_TX2_TX_PATH_SEC1, 0x00}, + { CDC_TX2_TX_PATH_SEC2, 0x01}, + { CDC_TX2_TX_PATH_SEC3, 0x3C}, + { CDC_TX2_TX_PATH_SEC4, 0x20}, + { CDC_TX2_TX_PATH_SEC5, 0x00}, + { CDC_TX2_TX_PATH_SEC6, 0x00}, + { CDC_TX3_TX_PATH_CTL, 0x04}, + { CDC_TX3_TX_PATH_CFG0, 0x10}, + { CDC_TX3_TX_PATH_CFG1, 0x0B}, + { CDC_TX3_TX_VOL_CTL, 0x00}, + { CDC_TX3_TX_PATH_SEC0, 0x00}, + { CDC_TX3_TX_PATH_SEC1, 0x00}, + { CDC_TX3_TX_PATH_SEC2, 0x01}, + { CDC_TX3_TX_PATH_SEC3, 0x3C}, + { CDC_TX3_TX_PATH_SEC4, 0x20}, + { CDC_TX3_TX_PATH_SEC5, 0x00}, + { CDC_TX3_TX_PATH_SEC6, 0x00}, + { CDC_TX4_TX_PATH_CTL, 0x04}, + { CDC_TX4_TX_PATH_CFG0, 0x10}, + { CDC_TX4_TX_PATH_CFG1, 0x0B}, + { CDC_TX4_TX_VOL_CTL, 0x00}, + { CDC_TX4_TX_PATH_SEC0, 0x00}, + { CDC_TX4_TX_PATH_SEC1, 0x00}, + { CDC_TX4_TX_PATH_SEC2, 0x01}, + { CDC_TX4_TX_PATH_SEC3, 0x3C}, + { CDC_TX4_TX_PATH_SEC4, 0x20}, + { CDC_TX4_TX_PATH_SEC5, 0x00}, + { CDC_TX4_TX_PATH_SEC6, 0x00}, + { CDC_TX5_TX_PATH_CTL, 0x04}, + { CDC_TX5_TX_PATH_CFG0, 0x10}, + { CDC_TX5_TX_PATH_CFG1, 0x0B}, + { CDC_TX5_TX_VOL_CTL, 0x00}, + { CDC_TX5_TX_PATH_SEC0, 0x00}, + { CDC_TX5_TX_PATH_SEC1, 0x00}, + { CDC_TX5_TX_PATH_SEC2, 0x01}, + { CDC_TX5_TX_PATH_SEC3, 0x3C}, + { CDC_TX5_TX_PATH_SEC4, 0x20}, + { CDC_TX5_TX_PATH_SEC5, 0x00}, + { CDC_TX5_TX_PATH_SEC6, 0x00}, + { CDC_TX6_TX_PATH_CTL, 0x04}, + { CDC_TX6_TX_PATH_CFG0, 0x10}, + { CDC_TX6_TX_PATH_CFG1, 0x0B}, + { CDC_TX6_TX_VOL_CTL, 0x00}, + { CDC_TX6_TX_PATH_SEC0, 0x00}, + { CDC_TX6_TX_PATH_SEC1, 0x00}, + { CDC_TX6_TX_PATH_SEC2, 0x01}, + { CDC_TX6_TX_PATH_SEC3, 0x3C}, + { CDC_TX6_TX_PATH_SEC4, 0x20}, + { CDC_TX6_TX_PATH_SEC5, 0x00}, + { CDC_TX6_TX_PATH_SEC6, 0x00}, + { CDC_TX7_TX_PATH_CTL, 0x04}, + { CDC_TX7_TX_PATH_CFG0, 0x10}, + { CDC_TX7_TX_PATH_CFG1, 0x0B}, + { CDC_TX7_TX_VOL_CTL, 0x00}, + { CDC_TX7_TX_PATH_SEC0, 0x00}, + { CDC_TX7_TX_PATH_SEC1, 0x00}, + { CDC_TX7_TX_PATH_SEC2, 0x01}, + { CDC_TX7_TX_PATH_SEC3, 0x3C}, + { CDC_TX7_TX_PATH_SEC4, 0x20}, + { CDC_TX7_TX_PATH_SEC5, 0x00}, + { CDC_TX7_TX_PATH_SEC6, 0x00}, +}; + +static bool tx_is_volatile_register(struct device *dev, unsigned int reg) +{ + /* Update volatile list for tx/tx macros */ + switch (reg) { + case CDC_TX_TOP_CSR_SWR_DMIC0_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC1_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC2_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC3_CTL: + return true; + } + return false; +} + +static bool tx_is_rw_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CDC_TX_CLK_RST_CTRL_MCLK_CONTROL: + case CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL: + case CDC_TX_CLK_RST_CTRL_SWR_CONTROL: + case CDC_TX_TOP_CSR_TOP_CFG0: + case CDC_TX_TOP_CSR_ANC_CFG: + case CDC_TX_TOP_CSR_SWR_CTRL: + case CDC_TX_TOP_CSR_FREQ_MCLK: + case CDC_TX_TOP_CSR_DEBUG_BUS: + case CDC_TX_TOP_CSR_DEBUG_EN: + case CDC_TX_TOP_CSR_TX_I2S_CTL: + case CDC_TX_TOP_CSR_I2S_CLK: + case CDC_TX_TOP_CSR_I2S_RESET: + case CDC_TX_TOP_CSR_SWR_DMIC0_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC1_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC2_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC3_CTL: + case CDC_TX_TOP_CSR_SWR_AMIC0_CTL: + case CDC_TX_TOP_CSR_SWR_AMIC1_CTL: + case CDC_TX_ANC0_CLK_RESET_CTL: + case CDC_TX_ANC0_MODE_1_CTL: + case CDC_TX_ANC0_MODE_2_CTL: + case CDC_TX_ANC0_FF_SHIFT: + case CDC_TX_ANC0_FB_SHIFT: + case CDC_TX_ANC0_LPF_FF_A_CTL: + case CDC_TX_ANC0_LPF_FF_B_CTL: + case CDC_TX_ANC0_LPF_FB_CTL: + case CDC_TX_ANC0_SMLPF_CTL: + case CDC_TX_ANC0_DCFLT_SHIFT_CTL: + case CDC_TX_ANC0_IIR_ADAPT_CTL: + case CDC_TX_ANC0_IIR_COEFF_1_CTL: + case CDC_TX_ANC0_IIR_COEFF_2_CTL: + case CDC_TX_ANC0_FF_A_GAIN_CTL: + case CDC_TX_ANC0_FF_B_GAIN_CTL: + case CDC_TX_ANC0_FB_GAIN_CTL: + case CDC_TX_INP_MUX_ADC_MUX0_CFG0: + case CDC_TX_INP_MUX_ADC_MUX0_CFG1: + case CDC_TX_INP_MUX_ADC_MUX1_CFG0: + case CDC_TX_INP_MUX_ADC_MUX1_CFG1: + case CDC_TX_INP_MUX_ADC_MUX2_CFG0: + case CDC_TX_INP_MUX_ADC_MUX2_CFG1: + case CDC_TX_INP_MUX_ADC_MUX3_CFG0: + case CDC_TX_INP_MUX_ADC_MUX3_CFG1: + case CDC_TX_INP_MUX_ADC_MUX4_CFG0: + case CDC_TX_INP_MUX_ADC_MUX4_CFG1: + case CDC_TX_INP_MUX_ADC_MUX5_CFG0: + case CDC_TX_INP_MUX_ADC_MUX5_CFG1: + case CDC_TX_INP_MUX_ADC_MUX6_CFG0: + case CDC_TX_INP_MUX_ADC_MUX6_CFG1: + case CDC_TX_INP_MUX_ADC_MUX7_CFG0: + case CDC_TX_INP_MUX_ADC_MUX7_CFG1: + case CDC_TX0_TX_PATH_CTL: + case CDC_TX0_TX_PATH_CFG0: + case CDC_TX0_TX_PATH_CFG1: + case CDC_TX0_TX_VOL_CTL: + case CDC_TX0_TX_PATH_SEC0: + case CDC_TX0_TX_PATH_SEC1: + case CDC_TX0_TX_PATH_SEC2: + case CDC_TX0_TX_PATH_SEC3: + case CDC_TX0_TX_PATH_SEC4: + case CDC_TX0_TX_PATH_SEC5: + case CDC_TX0_TX_PATH_SEC6: + case CDC_TX0_TX_PATH_SEC7: + case CDC_TX1_TX_PATH_CTL: + case CDC_TX1_TX_PATH_CFG0: + case CDC_TX1_TX_PATH_CFG1: + case CDC_TX1_TX_VOL_CTL: + case CDC_TX1_TX_PATH_SEC0: + case CDC_TX1_TX_PATH_SEC1: + case CDC_TX1_TX_PATH_SEC2: + case CDC_TX1_TX_PATH_SEC3: + case CDC_TX1_TX_PATH_SEC4: + case CDC_TX1_TX_PATH_SEC5: + case CDC_TX1_TX_PATH_SEC6: + case CDC_TX2_TX_PATH_CTL: + case CDC_TX2_TX_PATH_CFG0: + case CDC_TX2_TX_PATH_CFG1: + case CDC_TX2_TX_VOL_CTL: + case CDC_TX2_TX_PATH_SEC0: + case CDC_TX2_TX_PATH_SEC1: + case CDC_TX2_TX_PATH_SEC2: + case CDC_TX2_TX_PATH_SEC3: + case CDC_TX2_TX_PATH_SEC4: + case CDC_TX2_TX_PATH_SEC5: + case CDC_TX2_TX_PATH_SEC6: + case CDC_TX3_TX_PATH_CTL: + case CDC_TX3_TX_PATH_CFG0: + case CDC_TX3_TX_PATH_CFG1: + case CDC_TX3_TX_VOL_CTL: + case CDC_TX3_TX_PATH_SEC0: + case CDC_TX3_TX_PATH_SEC1: + case CDC_TX3_TX_PATH_SEC2: + case CDC_TX3_TX_PATH_SEC3: + case CDC_TX3_TX_PATH_SEC4: + case CDC_TX3_TX_PATH_SEC5: + case CDC_TX3_TX_PATH_SEC6: + case CDC_TX4_TX_PATH_CTL: + case CDC_TX4_TX_PATH_CFG0: + case CDC_TX4_TX_PATH_CFG1: + case CDC_TX4_TX_VOL_CTL: + case CDC_TX4_TX_PATH_SEC0: + case CDC_TX4_TX_PATH_SEC1: + case CDC_TX4_TX_PATH_SEC2: + case CDC_TX4_TX_PATH_SEC3: + case CDC_TX4_TX_PATH_SEC4: + case CDC_TX4_TX_PATH_SEC5: + case CDC_TX4_TX_PATH_SEC6: + case CDC_TX5_TX_PATH_CTL: + case CDC_TX5_TX_PATH_CFG0: + case CDC_TX5_TX_PATH_CFG1: + case CDC_TX5_TX_VOL_CTL: + case CDC_TX5_TX_PATH_SEC0: + case CDC_TX5_TX_PATH_SEC1: + case CDC_TX5_TX_PATH_SEC2: + case CDC_TX5_TX_PATH_SEC3: + case CDC_TX5_TX_PATH_SEC4: + case CDC_TX5_TX_PATH_SEC5: + case CDC_TX5_TX_PATH_SEC6: + case CDC_TX6_TX_PATH_CTL: + case CDC_TX6_TX_PATH_CFG0: + case CDC_TX6_TX_PATH_CFG1: + case CDC_TX6_TX_VOL_CTL: + case CDC_TX6_TX_PATH_SEC0: + case CDC_TX6_TX_PATH_SEC1: + case CDC_TX6_TX_PATH_SEC2: + case CDC_TX6_TX_PATH_SEC3: + case CDC_TX6_TX_PATH_SEC4: + case CDC_TX6_TX_PATH_SEC5: + case CDC_TX6_TX_PATH_SEC6: + case CDC_TX7_TX_PATH_CTL: + case CDC_TX7_TX_PATH_CFG0: + case CDC_TX7_TX_PATH_CFG1: + case CDC_TX7_TX_VOL_CTL: + case CDC_TX7_TX_PATH_SEC0: + case CDC_TX7_TX_PATH_SEC1: + case CDC_TX7_TX_PATH_SEC2: + case CDC_TX7_TX_PATH_SEC3: + case CDC_TX7_TX_PATH_SEC4: + case CDC_TX7_TX_PATH_SEC5: + case CDC_TX7_TX_PATH_SEC6: + return true; + } + + return false; +} + +static const struct regmap_config tx_regmap_config = { + .name = "tx_macro", + .reg_bits = 16, + .val_bits = 32, + .reg_stride = 4, + .cache_type = REGCACHE_FLAT, + .max_register = TX_MAX_OFFSET, + .reg_defaults = tx_defaults, + .num_reg_defaults = ARRAY_SIZE(tx_defaults), + .writeable_reg = tx_is_rw_register, + .volatile_reg = tx_is_volatile_register, + .readable_reg = tx_is_rw_register, +}; + +static int tx_macro_mclk_enable(struct tx_macro *tx, + bool mclk_enable) +{ + struct regmap *regmap = tx->regmap; + + if (mclk_enable) { + if (tx->tx_mclk_users == 0) { + /* 9.6MHz MCLK, set value 0x00 if other frequency */ + regmap_update_bits(regmap, CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01); + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + CDC_TX_MCLK_EN_MASK, + CDC_TX_MCLK_ENABLE); + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_TX_FS_CNT_EN_MASK, + CDC_TX_FS_CNT_ENABLE); + regcache_mark_dirty(regmap); + regcache_sync(regmap); + } + tx->tx_mclk_users++; + } else { + if (tx->tx_mclk_users <= 0) { + dev_err(tx->dev, "clock already disabled\n"); + tx->tx_mclk_users = 0; + goto exit; + } + tx->tx_mclk_users--; + if (tx->tx_mclk_users == 0) { + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_TX_FS_CNT_EN_MASK, 0x0); + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + CDC_TX_MCLK_EN_MASK, 0x0); + } + } +exit: + return 0; +} + +static bool is_amic_enabled(struct snd_soc_component *component, int decimator) +{ + u16 adc_mux_reg, adc_reg, adc_n; + + adc_mux_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG1(decimator); + + if (snd_soc_component_read(component, adc_mux_reg) & SWR_MIC) { + adc_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG0(decimator); + adc_n = snd_soc_component_read_field(component, adc_reg, + CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK); + if (adc_n < TX_ADC_MAX) + return true; + } + + return false; +} + +static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct tx_macro *tx; + struct snd_soc_component *component; + u16 dec_cfg_reg, hpf_gate_reg; + u8 hpf_cut_off_freq; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + tx = hpf_work->tx; + component = tx->component; + hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; + + dec_cfg_reg = CDC_TXn_TX_PATH_CFG0(hpf_work->decimator); + hpf_gate_reg = CDC_TXn_TX_PATH_SEC2(hpf_work->decimator); + + if (is_amic_enabled(component, hpf_work->decimator)) { + snd_soc_component_write_field(component, + dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK, + hpf_cut_off_freq); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x02); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x01); + } else { + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK, + hpf_cut_off_freq); + snd_soc_component_write_field(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK, 0x1); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_component_write_field(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK, 0x0); + } +} + +static void tx_macro_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork; + struct snd_soc_component *component; + struct tx_macro *tx; + struct delayed_work *delayed_work; + u8 decimator; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + tx = tx_mute_dwork->tx; + component = tx->component; + decimator = tx_mute_dwork->decimator; + + snd_soc_component_write_field(component, CDC_TXn_TX_PATH_CTL(decimator), + CDC_TXn_PGA_MUTE_MASK, 0x0); +} + +static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int path = e->shift_l; + + ucontrol->value.integer.value[0] = tx->dec_mode[path]; + + return 0; +} + +static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + int value = ucontrol->value.integer.value[0]; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int path = e->shift_l; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + tx->dec_mode[path] = value; + + return 0; +} + +static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = tx->bcs_enable; + + return 0; +} + +static int tx_macro_set_bcs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + int value = ucontrol->value.integer.value[0]; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + tx->bcs_enable = value; + + return 0; +} + +static int tx_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + u32 decimator, sample_rate; + int tx_fs_rate; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + sample_rate = params_rate(params); + switch (sample_rate) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 3; + break; + case 48000: + tx_fs_rate = 4; + break; + case 96000: + tx_fs_rate = 5; + break; + case 192000: + tx_fs_rate = 6; + break; + case 384000: + tx_fs_rate = 7; + break; + default: + dev_err(component->dev, "%s: Invalid TX sample rate: %d\n", + __func__, params_rate(params)); + return -EINVAL; + } + + for_each_set_bit(decimator, &tx->active_ch_mask[dai->id], TX_MACRO_DEC_MAX) + snd_soc_component_update_bits(component, CDC_TXn_TX_PATH_CTL(decimator), + CDC_TXn_PCM_RATE_MASK, + tx_fs_rate); + return 0; +} + +static int tx_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct snd_soc_component *component = dai->component; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + switch (dai->id) { + case TX_MACRO_AIF1_CAP: + case TX_MACRO_AIF2_CAP: + case TX_MACRO_AIF3_CAP: + *tx_slot = tx->active_ch_mask[dai->id]; + *tx_num = tx->active_ch_cnt[dai->id]; + break; + default: + break; + } + return 0; +} + +static int tx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_component *component = dai->component; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + u16 decimator; + + decimator = tx->active_decimator[dai->id]; + + if (mute) + snd_soc_component_write_field(component, + CDC_TXn_TX_PATH_CTL(decimator), + CDC_TXn_PGA_MUTE_MASK, 0x1); + else + snd_soc_component_update_bits(component, + CDC_TXn_TX_PATH_CTL(decimator), + CDC_TXn_PGA_MUTE_MASK, 0x0); + + return 0; +} + +static struct snd_soc_dai_ops tx_macro_dai_ops = { + .hw_params = tx_macro_hw_params, + .get_channel_map = tx_macro_get_channel_map, + .mute_stream = tx_macro_digital_mute, +}; + +static struct snd_soc_dai_driver tx_macro_dai[] = { + { + .name = "tx_macro_tx1", + .id = TX_MACRO_AIF1_CAP, + .capture = { + .stream_name = "TX_AIF1 Capture", + .rates = TX_MACRO_RATES, + .formats = TX_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tx_macro_dai_ops, + }, + { + .name = "tx_macro_tx2", + .id = TX_MACRO_AIF2_CAP, + .capture = { + .stream_name = "TX_AIF2 Capture", + .rates = TX_MACRO_RATES, + .formats = TX_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tx_macro_dai_ops, + }, + { + .name = "tx_macro_tx3", + .id = TX_MACRO_AIF3_CAP, + .capture = { + .stream_name = "TX_AIF3 Capture", + .rates = TX_MACRO_RATES, + .formats = TX_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tx_macro_dai_ops, + }, +}; + +static const char * const dec_mode_mux_text[] = { + "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", +}; + +static const struct soc_enum dec_mode_mux_enum[] = { + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 4, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 5, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 6, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 7, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), +}; + +static const struct snd_kcontrol_new tx_macro_snd_controls[] = { + SOC_SINGLE_S8_TLV("TX_DEC0 Volume", + CDC_TX0_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC1 Volume", + CDC_TX1_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC2 Volume", + CDC_TX2_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC3 Volume", + CDC_TX3_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC4 Volume", + CDC_TX4_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC5 Volume", + CDC_TX5_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC6 Volume", + CDC_TX6_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC7 Volume", + CDC_TX7_TX_VOL_CTL, + -84, 40, digital_gain), + + SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum[0], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum[1], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum[2], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum[3], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum[4], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum[5], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum[6], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum[7], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0, + tx_macro_get_bcs, tx_macro_set_bcs), +}; + +static int tx_macro_component_probe(struct snd_soc_component *comp) +{ + struct tx_macro *tx = snd_soc_component_get_drvdata(comp); + int i; + + snd_soc_component_init_regmap(comp, tx->regmap); + + for (i = 0; i < NUM_DECIMATORS; i++) { + tx->tx_hpf_work[i].tx = tx; + tx->tx_hpf_work[i].decimator = i; + INIT_DELAYED_WORK(&tx->tx_hpf_work[i].dwork, + tx_macro_tx_hpf_corner_freq_callback); + } + + for (i = 0; i < NUM_DECIMATORS; i++) { + tx->tx_mute_dwork[i].tx = tx; + tx->tx_mute_dwork[i].decimator = i; + INIT_DELAYED_WORK(&tx->tx_mute_dwork[i].dwork, + tx_macro_mute_update_callback); + } + tx->component = comp; + + snd_soc_component_update_bits(comp, CDC_TX0_TX_PATH_SEC7, 0x3F, + 0x0A); + + return 0; +} + +static int swclk_gate_enable(struct clk_hw *hw) +{ + struct tx_macro *tx = to_tx_macro(hw); + struct regmap *regmap = tx->regmap; + + tx_macro_mclk_enable(tx, true); + if (tx->reset_swr) + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_RESET_MASK, + CDC_TX_SWR_RESET_ENABLE); + + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_CLK_EN_MASK, + CDC_TX_SWR_CLK_ENABLE); + if (tx->reset_swr) + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_RESET_MASK, 0x0); + tx->reset_swr = false; + + return 0; +} + +static void swclk_gate_disable(struct clk_hw *hw) +{ + struct tx_macro *tx = to_tx_macro(hw); + struct regmap *regmap = tx->regmap; + + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_CLK_EN_MASK, 0x0); + + tx_macro_mclk_enable(tx, false); +} + +static int swclk_gate_is_enabled(struct clk_hw *hw) +{ + struct tx_macro *tx = to_tx_macro(hw); + int ret, val; + + regmap_read(tx->regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, &val); + ret = val & BIT(0); + + return ret; +} + +static unsigned long swclk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate / 2; +} + +static const struct clk_ops swclk_gate_ops = { + .prepare = swclk_gate_enable, + .unprepare = swclk_gate_disable, + .is_enabled = swclk_gate_is_enabled, + .recalc_rate = swclk_recalc_rate, + +}; + +static struct clk *tx_macro_register_mclk_output(struct tx_macro *tx) +{ + struct device *dev = tx->dev; + struct device_node *np = dev->of_node; + const char *parent_clk_name = NULL; + const char *clk_name = "lpass-tx-mclk"; + struct clk_hw *hw; + struct clk_init_data init; + int ret; + + parent_clk_name = __clk_get_name(tx->clks[2].clk); + + init.name = clk_name; + init.ops = &swclk_gate_ops; + init.flags = 0; + init.parent_names = &parent_clk_name; + init.num_parents = 1; + tx->hw.init = &init; + hw = &tx->hw; + ret = clk_hw_register(tx->dev, hw); + if (ret) + return ERR_PTR(ret); + + of_clk_add_provider(np, of_clk_src_simple_get, hw->clk); + + return NULL; +} + +static const struct snd_soc_component_driver tx_macro_component_drv = { + .name = "RX-MACRO", + .probe = tx_macro_component_probe, + .controls = tx_macro_snd_controls, + .num_controls = ARRAY_SIZE(tx_macro_snd_controls), +}; + +static int tx_macro_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tx_macro *tx; + void __iomem *base; + int ret; + + tx = devm_kzalloc(dev, sizeof(*tx), GFP_KERNEL); + if (!tx) + return -ENOMEM; + + tx->clks[0].id = "macro"; + tx->clks[1].id = "dcodec"; + tx->clks[2].id = "mclk"; + tx->clks[3].id = "npl"; + tx->clks[4].id = "fsgen"; + + ret = devm_clk_bulk_get(dev, TX_NUM_CLKS_MAX, tx->clks); + if (ret) { + dev_err(dev, "Error getting RX Clocks (%d)\n", ret); + return ret; + } + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + tx->regmap = devm_regmap_init_mmio(dev, base, &tx_regmap_config); + + dev_set_drvdata(dev, tx); + + tx->reset_swr = true; + tx->dev = dev; + + /* set MCLK and NPL rates */ + clk_set_rate(tx->clks[2].clk, MCLK_FREQ); + clk_set_rate(tx->clks[3].clk, MCLK_FREQ); + + ret = clk_bulk_prepare_enable(TX_NUM_CLKS_MAX, tx->clks); + if (ret) + return ret; + + tx_macro_register_mclk_output(tx); + + ret = devm_snd_soc_register_component(dev, &tx_macro_component_drv, + tx_macro_dai, + ARRAY_SIZE(tx_macro_dai)); + if (ret) + goto err; + return ret; +err: + clk_bulk_disable_unprepare(TX_NUM_CLKS_MAX, tx->clks); + + return ret; +} + +static int tx_macro_remove(struct platform_device *pdev) +{ + struct tx_macro *tx = dev_get_drvdata(&pdev->dev); + + of_clk_del_provider(pdev->dev.of_node); + + clk_bulk_disable_unprepare(TX_NUM_CLKS_MAX, tx->clks); + + return 0; +} + +static const struct of_device_id tx_macro_dt_match[] = { + { .compatible = "qcom,sm8250-lpass-tx-macro" }, + { } +}; +static struct platform_driver tx_macro_driver = { + .driver = { + .name = "tx_macro", + .of_match_table = tx_macro_dt_match, + .suppress_bind_attrs = true, + }, + .probe = tx_macro_probe, + .remove = tx_macro_remove, +}; + +module_platform_driver(tx_macro_driver); + +MODULE_DESCRIPTION("TX macro driver"); +MODULE_LICENSE("GPL"); -- GitLab From d207bdea0ca9efde321ff142e9b9f2ef73f9cdf5 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 11 Feb 2021 12:27:35 +0000 Subject: [PATCH 1073/1084] ASoC: codecs: lpass-tx-macro: add dapm widgets and route This patch adds dapm widgets and routes on this codec Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20210211122735.5691-8-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-tx-macro.c | 685 ++++++++++++++++++++++++++++++ 1 file changed, 685 insertions(+) diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index 06589dad6bc2c..36d7a6442cdbc 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -706,6 +706,289 @@ static void tx_macro_mute_update_callback(struct work_struct *work) CDC_TXn_PGA_MUTE_MASK, 0x0); } +static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tx_macro_mclk_enable(tx, true); + break; + case SND_SOC_DAPM_POST_PMD: + tx_macro_mclk_enable(tx, false); + break; + default: + break; + } + + return 0; +} + +static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val, dmic; + u16 mic_sel_reg; + u16 dmic_clk_reg; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + val = ucontrol->value.enumerated.item[0]; + + switch (e->reg) { + case CDC_TX_INP_MUX_ADC_MUX0_CFG0: + mic_sel_reg = CDC_TX0_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX1_CFG0: + mic_sel_reg = CDC_TX1_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX2_CFG0: + mic_sel_reg = CDC_TX2_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX3_CFG0: + mic_sel_reg = CDC_TX3_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX4_CFG0: + mic_sel_reg = CDC_TX4_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX5_CFG0: + mic_sel_reg = CDC_TX5_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX6_CFG0: + mic_sel_reg = CDC_TX6_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX7_CFG0: + mic_sel_reg = CDC_TX7_TX_PATH_CFG0; + break; + } + + if (val != 0) { + if (val < 5) { + snd_soc_component_write_field(component, mic_sel_reg, + CDC_TXn_ADC_DMIC_SEL_MASK, 0); + } else { + snd_soc_component_write_field(component, mic_sel_reg, + CDC_TXn_ADC_DMIC_SEL_MASK, 1); + dmic = TX_ADC_TO_DMIC(val); + dmic_clk_reg = CDC_TX_TOP_CSR_SWR_DMICn_CTL(dmic); + snd_soc_component_write_field(component, dmic_clk_reg, + CDC_TX_SWR_DMIC_CLK_SEL_MASK, + tx->dmic_clk_div); + } + } + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + u32 dai_id = widget->shift; + u32 dec_id = mc->shift; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + if (test_bit(dec_id, &tx->active_ch_mask[dai_id])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + return 0; +} + +static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct snd_soc_dapm_update *update = NULL; + struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + u32 dai_id = widget->shift; + u32 dec_id = mc->shift; + u32 enable = ucontrol->value.integer.value[0]; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + if (enable) { + set_bit(dec_id, &tx->active_ch_mask[dai_id]); + tx->active_ch_cnt[dai_id]++; + tx->active_decimator[dai_id] = dec_id; + } else { + tx->active_ch_cnt[dai_id]--; + clear_bit(dec_id, &tx->active_ch_mask[dai_id]); + tx->active_decimator[dai_id] = -1; + } + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); + + return 0; +} + +static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + unsigned int decimator; + u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg, tx_gain_ctl_reg; + u8 hpf_cut_off_freq; + int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS; + int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS; + u16 adc_mux_reg, adc_reg, adc_n, dmic; + u16 dmic_clk_reg; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + decimator = w->shift; + tx_vol_ctl_reg = CDC_TXn_TX_PATH_CTL(decimator); + hpf_gate_reg = CDC_TXn_TX_PATH_SEC2(decimator); + dec_cfg_reg = CDC_TXn_TX_PATH_CFG0(decimator); + tx_gain_ctl_reg = CDC_TXn_TX_VOL_CTL(decimator); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + adc_mux_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG1(decimator); + if (snd_soc_component_read(component, adc_mux_reg) & SWR_MIC) { + adc_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG0(decimator); + adc_n = snd_soc_component_read(component, adc_reg) & + CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK; + if (adc_n >= TX_ADC_MAX) { + dmic = TX_ADC_TO_DMIC(adc_n); + dmic_clk_reg = CDC_TX_TOP_CSR_SWR_DMICn_CTL(dmic); + + snd_soc_component_write_field(component, dmic_clk_reg, + CDC_TX_SWR_DMIC_CLK_SEL_MASK, + tx->dmic_clk_div); + } + } + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_ADC_MODE_MASK, + tx->dec_mode[decimator]); + /* Enable TX PGA Mute */ + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_PGA_MUTE_MASK, 0x1); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_CLK_EN_MASK, 0x1); + if (!is_amic_enabled(component, decimator)) { + snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x00); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + } + hpf_cut_off_freq = snd_soc_component_read_field(component, dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK); + + tx->tx_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK, + CF_MIN_3DB_150HZ); + + if (is_amic_enabled(component, decimator)) { + hpf_delay = TX_MACRO_AMIC_HPF_DELAY_MS; + unmute_delay = TX_MACRO_AMIC_UNMUTE_DELAY_MS; + } + /* schedule work queue to Remove Mute */ + queue_delayed_work(system_freezable_wq, + &tx->tx_mute_dwork[decimator].dwork, + msecs_to_jiffies(unmute_delay)); + if (tx->tx_hpf_work[decimator].hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + queue_delayed_work(system_freezable_wq, + &tx->tx_hpf_work[decimator].dwork, + msecs_to_jiffies(hpf_delay)); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x02); + if (!is_amic_enabled(component, decimator)) + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x00); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x01); + + /* + * 6ms delay is required as per HW spec + */ + usleep_range(6000, 6010); + } + /* apply gain after decimator is enabled */ + snd_soc_component_write(component, tx_gain_ctl_reg, + snd_soc_component_read(component, + tx_gain_ctl_reg)); + if (tx->bcs_enable) { + snd_soc_component_update_bits(component, dec_cfg_reg, + 0x01, 0x01); + tx->bcs_clk_en = true; + } + break; + case SND_SOC_DAPM_PRE_PMD: + hpf_cut_off_freq = + tx->tx_hpf_work[decimator].hpf_cut_off_freq; + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_PGA_MUTE_MASK, 0x1); + if (cancel_delayed_work_sync( + &tx->tx_hpf_work[decimator].dwork)) { + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_component_write_field( + component, dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK, + hpf_cut_off_freq); + if (is_amic_enabled(component, decimator)) + snd_soc_component_update_bits(component, + hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x02); + else + snd_soc_component_update_bits(component, + hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x03); + + /* + * Minimum 1 clk cycle delay is required + * as per HW spec + */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x1); + } + } + cancel_delayed_work_sync(&tx->tx_mute_dwork[decimator].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_CLK_EN_MASK, 0x0); + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_ADC_MODE_MASK, 0x0); + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_PGA_MUTE_MASK, 0x0); + if (tx->bcs_enable) { + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_PH_EN_MASK, 0x0); + snd_soc_component_write_field(component, + CDC_TX0_TX_PATH_SEC7, + CDC_TX0_MBHC_CTL_EN_MASK, + 0x0); + tx->bcs_clk_en = false; + } + break; + } + return 0; +} + static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -892,6 +1175,83 @@ static struct snd_soc_dai_driver tx_macro_dai[] = { }, }; +static const char * const adc_mux_text[] = { + "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1" +}; + +static SOC_ENUM_SINGLE_DECL(tx_dec0_enum, CDC_TX_INP_MUX_ADC_MUX0_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec1_enum, CDC_TX_INP_MUX_ADC_MUX1_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec2_enum, CDC_TX_INP_MUX_ADC_MUX2_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec3_enum, CDC_TX_INP_MUX_ADC_MUX3_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec4_enum, CDC_TX_INP_MUX_ADC_MUX4_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec5_enum, CDC_TX_INP_MUX_ADC_MUX5_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec6_enum, CDC_TX_INP_MUX_ADC_MUX6_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec7_enum, CDC_TX_INP_MUX_ADC_MUX7_CFG1, + 0, adc_mux_text); + +static const struct snd_kcontrol_new tx_dec0_mux = SOC_DAPM_ENUM("tx_dec0", tx_dec0_enum); +static const struct snd_kcontrol_new tx_dec1_mux = SOC_DAPM_ENUM("tx_dec1", tx_dec1_enum); +static const struct snd_kcontrol_new tx_dec2_mux = SOC_DAPM_ENUM("tx_dec2", tx_dec2_enum); +static const struct snd_kcontrol_new tx_dec3_mux = SOC_DAPM_ENUM("tx_dec3", tx_dec3_enum); +static const struct snd_kcontrol_new tx_dec4_mux = SOC_DAPM_ENUM("tx_dec4", tx_dec4_enum); +static const struct snd_kcontrol_new tx_dec5_mux = SOC_DAPM_ENUM("tx_dec5", tx_dec5_enum); +static const struct snd_kcontrol_new tx_dec6_mux = SOC_DAPM_ENUM("tx_dec6", tx_dec6_enum); +static const struct snd_kcontrol_new tx_dec7_mux = SOC_DAPM_ENUM("tx_dec7", tx_dec7_enum); + +static const char * const smic_mux_text[] = { + "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_DMIC0", + "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4", + "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7" +}; + +static SOC_ENUM_SINGLE_DECL(tx_smic0_enum, CDC_TX_INP_MUX_ADC_MUX0_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic1_enum, CDC_TX_INP_MUX_ADC_MUX1_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic2_enum, CDC_TX_INP_MUX_ADC_MUX2_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic3_enum, CDC_TX_INP_MUX_ADC_MUX3_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic4_enum, CDC_TX_INP_MUX_ADC_MUX4_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic5_enum, CDC_TX_INP_MUX_ADC_MUX5_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic6_enum, CDC_TX_INP_MUX_ADC_MUX6_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic7_enum, CDC_TX_INP_MUX_ADC_MUX7_CFG0, + 0, smic_mux_text); + +static const struct snd_kcontrol_new tx_smic0_mux = SOC_DAPM_ENUM_EXT("tx_smic0", tx_smic0_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic1_mux = SOC_DAPM_ENUM_EXT("tx_smic1", tx_smic1_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic2_mux = SOC_DAPM_ENUM_EXT("tx_smic2", tx_smic2_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic3_mux = SOC_DAPM_ENUM_EXT("tx_smic3", tx_smic3_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic4_mux = SOC_DAPM_ENUM_EXT("tx_smic4", tx_smic4_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic5_mux = SOC_DAPM_ENUM_EXT("tx_smic5", tx_smic5_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic6_mux = SOC_DAPM_ENUM_EXT("tx_smic6", tx_smic6_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic7_mux = SOC_DAPM_ENUM_EXT("tx_smic7", tx_smic7_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); + static const char * const dec_mode_mux_text[] = { "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", }; @@ -915,6 +1275,327 @@ static const struct soc_enum dec_mode_mux_enum[] = { dec_mode_mux_text), }; +static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { + SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0), + + SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0), + + SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0), + + SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0, + tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)), + + SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0, + tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)), + + SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0, + tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)), + + SND_SOC_DAPM_MUX("TX SMIC MUX0", SND_SOC_NOPM, 0, 0, &tx_smic0_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX1", SND_SOC_NOPM, 0, 0, &tx_smic1_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX2", SND_SOC_NOPM, 0, 0, &tx_smic2_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX3", SND_SOC_NOPM, 0, 0, &tx_smic3_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX4", SND_SOC_NOPM, 0, 0, &tx_smic4_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX5", SND_SOC_NOPM, 0, 0, &tx_smic5_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX6", SND_SOC_NOPM, 0, 0, &tx_smic6_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX7", SND_SOC_NOPM, 0, 0, &tx_smic7_mux), + + SND_SOC_DAPM_INPUT("TX SWR_ADC0"), + SND_SOC_DAPM_INPUT("TX SWR_ADC1"), + SND_SOC_DAPM_INPUT("TX SWR_ADC2"), + SND_SOC_DAPM_INPUT("TX SWR_ADC3"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC0"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC1"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC2"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC3"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC4"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC5"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC6"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC7"), + + SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM, + TX_MACRO_DEC0, 0, + &tx_dec0_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM, + TX_MACRO_DEC1, 0, + &tx_dec1_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM, + TX_MACRO_DEC2, 0, + &tx_dec2_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM, + TX_MACRO_DEC3, 0, + &tx_dec3_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM, + TX_MACRO_DEC4, 0, + &tx_dec4_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM, + TX_MACRO_DEC5, 0, + &tx_dec5_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM, + TX_MACRO_DEC6, 0, + &tx_dec6_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM, + TX_MACRO_DEC7, 0, + &tx_dec7_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0, + tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + NULL, 0), +}; + +static const struct snd_soc_dapm_route tx_audio_map[] = { + {"TX_AIF1 CAP", NULL, "TX_MCLK"}, + {"TX_AIF2 CAP", NULL, "TX_MCLK"}, + {"TX_AIF3 CAP", NULL, "TX_MCLK"}, + + {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"}, + {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"}, + {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"}, + + {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX DEC0 MUX", NULL, "TX_MCLK"}, + {"TX DEC1 MUX", NULL, "TX_MCLK"}, + {"TX DEC2 MUX", NULL, "TX_MCLK"}, + {"TX DEC3 MUX", NULL, "TX_MCLK"}, + {"TX DEC4 MUX", NULL, "TX_MCLK"}, + {"TX DEC5 MUX", NULL, "TX_MCLK"}, + {"TX DEC6 MUX", NULL, "TX_MCLK"}, + {"TX DEC7 MUX", NULL, "TX_MCLK"}, + + {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"}, + {"TX SMIC MUX0", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"}, + {"TX SMIC MUX1", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"}, + {"TX SMIC MUX2", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"}, + {"TX SMIC MUX3", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"}, + {"TX SMIC MUX4", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"}, + {"TX SMIC MUX5", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"}, + {"TX SMIC MUX6", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"}, + {"TX SMIC MUX7", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"}, +}; + static const struct snd_kcontrol_new tx_macro_snd_controls[] = { SOC_SINGLE_S8_TLV("TX_DEC0 Volume", CDC_TX0_TX_VOL_CTL, @@ -1088,6 +1769,10 @@ static const struct snd_soc_component_driver tx_macro_component_drv = { .probe = tx_macro_component_probe, .controls = tx_macro_snd_controls, .num_controls = ARRAY_SIZE(tx_macro_snd_controls), + .dapm_widgets = tx_macro_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tx_macro_dapm_widgets), + .dapm_routes = tx_audio_map, + .num_dapm_routes = ARRAY_SIZE(tx_audio_map), }; static int tx_macro_probe(struct platform_device *pdev) -- GitLab From 53129e66e4b716ea7cffa4477a96ccb48f78e7ac Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 11 Feb 2021 19:24:40 +0200 Subject: [PATCH 1074/1084] ASoC: SOF: relax ABI checks and avoid unnecessary warnings With recent SOF 1.7 pre-releases, kernel has been emitting following warnings at probe: [10006.645216] sof-audio-pci 0000:00:1f.3: warn: FW ABI is more recent than kernel [10006.652137] sof-audio-pci 0000:00:1f.3: warn: topology ABI is more recent than kernel The warnings are emitted due to increase of the patch-level in firmware mainline (to 3.17.1). But the patch level should not be considered even in the strict ABI check, so modify the kernel side logic that makes the check and only consider the major.minor components. BugLink: https://github.com/thesofproject/linux/issues/2647 Signed-off-by: Kai Vehmanen Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20210211172440.2371447-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc.c | 2 +- sound/soc/sof/topology.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 1bc3d6282f16d..c2d07b783f60a 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -798,7 +798,7 @@ int snd_sof_ipc_valid(struct snd_sof_dev *sdev) return -EINVAL; } - if (v->abi_version > SOF_ABI_VERSION) { + if (SOF_ABI_VERSION_MINOR(v->abi_version) > SOF_ABI_MINOR) { if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { dev_warn(sdev->dev, "warn: FW ABI is more recent than kernel\n"); } else { diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index d6e1f33eb1e9f..10f99620eb317 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -3658,7 +3658,7 @@ static int sof_manifest(struct snd_soc_component *scomp, int index, return -EINVAL; } - if (abi_version > SOF_ABI_VERSION) { + if (SOF_ABI_VERSION_MINOR(abi_version) > SOF_ABI_MINOR) { if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { dev_warn(scomp->dev, "warn: topology ABI is more recent than kernel\n"); } else { -- GitLab From 6e9586361e145cd688e525880e1f84c0ccf57566 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 11 Feb 2021 17:21:06 +0000 Subject: [PATCH 1075/1084] ASoC: wm_adsp: Remove unused control callback structure This callback structure has never been used and it is not clear why it was added in the first place. Remove it to clear up the code a little. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20210211172106.16258-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 262c2db4f81ce..070ca7d8c6610 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -595,13 +595,6 @@ static const struct { [WM_ADSP_FW_MISC] = { .file = "misc" }, }; -struct wm_coeff_ctl_ops { - int (*xget)(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); - int (*xput)(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -}; - struct wm_coeff_ctl { const char *name; const char *fw_name; @@ -609,7 +602,6 @@ struct wm_coeff_ctl { const char *subname; unsigned int subname_len; struct wm_adsp_alg_region alg_region; - struct wm_coeff_ctl_ops ops; struct wm_adsp *dsp; unsigned int enabled:1; struct list_head list; @@ -1497,8 +1489,6 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, } ctl->enabled = 1; ctl->set = 0; - ctl->ops.xget = wm_coeff_get; - ctl->ops.xput = wm_coeff_put; ctl->dsp = dsp; ctl->flags = flags; -- GitLab From f6c04af5dc4b80e70160acd9a7b04b185e093c71 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 4 Feb 2021 08:50:31 +0900 Subject: [PATCH 1076/1084] ASoC: soc-pcm: add soc_pcm_hw_update_rate() To update hw, we need to follow setting order 1) set hw->rates 2) call snd_pcm_limit_hw_rates() 3) update hw->rate_min/max To avoid random settings, this patch adds new soc_pcm_hw_update_rate() and share updating code. Signed-off-by: Kuninori Morimoto Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/87sg6c90qv.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 56 ++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 8d55f39d40143..0cf212c8bd882 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -473,6 +473,26 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream) soc_pcm_set_msb(substream, cpu_bits); } +static void soc_pcm_hw_init(struct snd_pcm_hardware *hw) +{ + hw->rates = UINT_MAX; + hw->rate_min = 0; + hw->rate_max = UINT_MAX; +} + +static void soc_pcm_hw_update_rate(struct snd_pcm_hardware *hw, + struct snd_soc_pcm_stream *p) +{ + hw->rates = snd_pcm_rate_mask_intersect(hw->rates, p->rates); + + /* setup hw->rate_min/max via hw->rates first */ + snd_pcm_hw_limit_rates(hw); + + /* update hw->rate_min/max by snd_soc_pcm_stream */ + hw->rate_min = max(hw->rate_min, p->rate_min); + hw->rate_max = min_not_zero(hw->rate_max, p->rate_max); +} + /** * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream * @rtd: ASoC PCM runtime @@ -491,12 +511,11 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, struct snd_soc_pcm_stream *cpu_stream; unsigned int chan_min = 0, chan_max = UINT_MAX; unsigned int cpu_chan_min = 0, cpu_chan_max = UINT_MAX; - unsigned int rate_min = 0, rate_max = UINT_MAX; - unsigned int cpu_rate_min = 0, cpu_rate_max = UINT_MAX; - unsigned int rates = UINT_MAX, cpu_rates = UINT_MAX; u64 formats = ULLONG_MAX; int i; + soc_pcm_hw_init(hw); + /* first calculate min/max only for CPUs in the DAI link */ for_each_rtd_cpu_dais(rtd, i, cpu_dai) { @@ -513,11 +532,8 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, cpu_chan_min = max(cpu_chan_min, cpu_stream->channels_min); cpu_chan_max = min(cpu_chan_max, cpu_stream->channels_max); - cpu_rate_min = max(cpu_rate_min, cpu_stream->rate_min); - cpu_rate_max = min_not_zero(cpu_rate_max, cpu_stream->rate_max); + soc_pcm_hw_update_rate(hw, cpu_stream); formats &= cpu_stream->formats; - cpu_rates = snd_pcm_rate_mask_intersect(cpu_stream->rates, - cpu_rates); } /* second calculate min/max only for CODECs in the DAI link */ @@ -536,10 +552,8 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, chan_min = max(chan_min, codec_stream->channels_min); chan_max = min(chan_max, codec_stream->channels_max); - rate_min = max(rate_min, codec_stream->rate_min); - rate_max = min_not_zero(rate_max, codec_stream->rate_max); + soc_pcm_hw_update_rate(hw, codec_stream); formats &= codec_stream->formats; - rates = snd_pcm_rate_mask_intersect(codec_stream->rates, rates); } /* Verify both a valid CPU DAI and a valid CODEC DAI were found */ @@ -560,14 +574,6 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, hw->channels_min = max(chan_min, cpu_chan_min); hw->channels_max = min(chan_max, cpu_chan_max); hw->formats = formats; - hw->rates = snd_pcm_rate_mask_intersect(rates, cpu_rates); - - snd_pcm_hw_limit_rates(hw); - - hw->rate_min = max(hw->rate_min, cpu_rate_min); - hw->rate_min = max(hw->rate_min, rate_min); - hw->rate_max = min_not_zero(hw->rate_max, cpu_rate_max); - hw->rate_max = min_not_zero(hw->rate_max, rate_max); return 0; } @@ -1514,12 +1520,9 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, struct snd_soc_pcm_stream *stream) { - runtime->hw.rates = stream->rates; - - snd_pcm_limit_hw_rates(runtime); + struct snd_pcm_hardware *hw = &runtime->hw; - runtime->hw.rate_min = stream->rate_min; - runtime->hw.rate_max = min_not_zero(stream->rate_max, UINT_MAX); + soc_pcm_hw_update_rate(hw, stream); runtime->hw.channels_min = stream->channels_min; runtime->hw.channels_max = stream->channels_max; if (runtime->hw.formats) @@ -1651,12 +1654,7 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, pcm = snd_soc_dai_get_pcm_stream(dai, stream); - hw->rates = snd_pcm_rate_mask_intersect(hw->rates, pcm->rates); - - snd_pcm_limit_hw_rates(runtime); - - hw->rate_min = max(hw->rate_min, pcm->rate_min); - hw->rate_max = min_not_zero(hw->rate_max, pcm->rate_max); + soc_pcm_hw_update_rate(hw, pcm); } } } -- GitLab From 6cb56a4549e9e2e0f7f67b99cb1887c0e803245a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 4 Feb 2021 08:51:49 +0900 Subject: [PATCH 1077/1084] ASoC: soc-pcm: add soc_pcm_hw_update_chan() We have soc_pcm_hw_update_rate() now. This patch creates same function for chan. Signed-off-by: Kuninori Morimoto Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/87r1lw90oo.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 0cf212c8bd882..23d6709a295d6 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -478,6 +478,8 @@ static void soc_pcm_hw_init(struct snd_pcm_hardware *hw) hw->rates = UINT_MAX; hw->rate_min = 0; hw->rate_max = UINT_MAX; + hw->channels_min = 0; + hw->channels_max = UINT_MAX; } static void soc_pcm_hw_update_rate(struct snd_pcm_hardware *hw, @@ -493,6 +495,13 @@ static void soc_pcm_hw_update_rate(struct snd_pcm_hardware *hw, hw->rate_max = min_not_zero(hw->rate_max, p->rate_max); } +static void soc_pcm_hw_update_chan(struct snd_pcm_hardware *hw, + struct snd_soc_pcm_stream *p) +{ + hw->channels_min = max(hw->channels_min, p->channels_min); + hw->channels_max = min(hw->channels_max, p->channels_max); +} + /** * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream * @rtd: ASoC PCM runtime @@ -509,7 +518,6 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *cpu_dai; struct snd_soc_pcm_stream *codec_stream; struct snd_soc_pcm_stream *cpu_stream; - unsigned int chan_min = 0, chan_max = UINT_MAX; unsigned int cpu_chan_min = 0, cpu_chan_max = UINT_MAX; u64 formats = ULLONG_MAX; int i; @@ -530,11 +538,12 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, cpu_stream = snd_soc_dai_get_pcm_stream(cpu_dai, stream); - cpu_chan_min = max(cpu_chan_min, cpu_stream->channels_min); - cpu_chan_max = min(cpu_chan_max, cpu_stream->channels_max); + soc_pcm_hw_update_chan(hw, cpu_stream); soc_pcm_hw_update_rate(hw, cpu_stream); formats &= cpu_stream->formats; } + cpu_chan_min = hw->channels_min; + cpu_chan_max = hw->channels_max; /* second calculate min/max only for CODECs in the DAI link */ for_each_rtd_codec_dais(rtd, i, codec_dai) { @@ -550,14 +559,13 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, codec_stream = snd_soc_dai_get_pcm_stream(codec_dai, stream); - chan_min = max(chan_min, codec_stream->channels_min); - chan_max = min(chan_max, codec_stream->channels_max); + soc_pcm_hw_update_chan(hw, codec_stream); soc_pcm_hw_update_rate(hw, codec_stream); formats &= codec_stream->formats; } /* Verify both a valid CPU DAI and a valid CODEC DAI were found */ - if (!chan_min || !cpu_chan_min) + if (!hw->channels_min) return -EINVAL; /* @@ -566,13 +574,11 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, * channel allocation be fixed up later */ if (rtd->num_codecs > 1) { - chan_min = cpu_chan_min; - chan_max = cpu_chan_max; + hw->channels_min = cpu_chan_min; + hw->channels_max = cpu_chan_max; } /* finally find a intersection between CODECs and CPUs */ - hw->channels_min = max(chan_min, cpu_chan_min); - hw->channels_max = min(chan_max, cpu_chan_max); hw->formats = formats; return 0; @@ -1523,8 +1529,7 @@ static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, struct snd_pcm_hardware *hw = &runtime->hw; soc_pcm_hw_update_rate(hw, stream); - runtime->hw.channels_min = stream->channels_min; - runtime->hw.channels_max = stream->channels_max; + soc_pcm_hw_update_chan(hw, stream); if (runtime->hw.formats) runtime->hw.formats &= stream->formats; else @@ -1601,10 +1606,7 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream); - hw->channels_min = max(hw->channels_min, - cpu_stream->channels_min); - hw->channels_max = min(hw->channels_max, - cpu_stream->channels_max); + soc_pcm_hw_update_chan(hw, cpu_stream); } /* @@ -1614,10 +1616,7 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, if (be->num_codecs == 1) { codec_stream = snd_soc_dai_get_pcm_stream(asoc_rtd_to_codec(be, 0), stream); - hw->channels_min = max(hw->channels_min, - codec_stream->channels_min); - hw->channels_max = min(hw->channels_max, - codec_stream->channels_max); + soc_pcm_hw_update_chan(hw, codec_stream); } } } -- GitLab From debc71f26cdbd45798c63b0dcdabdea93d2f6870 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 4 Feb 2021 08:52:04 +0900 Subject: [PATCH 1078/1084] ASoC: soc-pcm: add soc_pcm_hw_update_format() We have soc_pcm_hw_update_xxx() now. This patch creates same function for format. Signed-off-by: Kuninori Morimoto Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/87pn1g90oa.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 23d6709a295d6..b7c90da1820e9 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -480,6 +480,7 @@ static void soc_pcm_hw_init(struct snd_pcm_hardware *hw) hw->rate_max = UINT_MAX; hw->channels_min = 0; hw->channels_max = UINT_MAX; + hw->formats = ULLONG_MAX; } static void soc_pcm_hw_update_rate(struct snd_pcm_hardware *hw, @@ -502,6 +503,12 @@ static void soc_pcm_hw_update_chan(struct snd_pcm_hardware *hw, hw->channels_max = min(hw->channels_max, p->channels_max); } +static void soc_pcm_hw_update_format(struct snd_pcm_hardware *hw, + struct snd_soc_pcm_stream *p) +{ + hw->formats &= p->formats; +} + /** * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream * @rtd: ASoC PCM runtime @@ -519,7 +526,6 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, struct snd_soc_pcm_stream *codec_stream; struct snd_soc_pcm_stream *cpu_stream; unsigned int cpu_chan_min = 0, cpu_chan_max = UINT_MAX; - u64 formats = ULLONG_MAX; int i; soc_pcm_hw_init(hw); @@ -540,7 +546,7 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, soc_pcm_hw_update_chan(hw, cpu_stream); soc_pcm_hw_update_rate(hw, cpu_stream); - formats &= cpu_stream->formats; + soc_pcm_hw_update_format(hw, cpu_stream); } cpu_chan_min = hw->channels_min; cpu_chan_max = hw->channels_max; @@ -561,7 +567,7 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, soc_pcm_hw_update_chan(hw, codec_stream); soc_pcm_hw_update_rate(hw, codec_stream); - formats &= codec_stream->formats; + soc_pcm_hw_update_format(hw, codec_stream); } /* Verify both a valid CPU DAI and a valid CODEC DAI were found */ @@ -578,9 +584,6 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, hw->channels_max = cpu_chan_max; } - /* finally find a intersection between CODECs and CPUs */ - hw->formats = formats; - return 0; } EXPORT_SYMBOL_GPL(snd_soc_runtime_calc_hw); @@ -1568,7 +1571,7 @@ static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, codec_stream = snd_soc_dai_get_pcm_stream(dai, stream); - hw->formats &= codec_stream->formats; + soc_pcm_hw_update_format(hw, codec_stream); } } } -- GitLab From 140f553d1298e0ddbe21983efe5789fe8b484273 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Mon, 15 Feb 2021 00:04:14 +0200 Subject: [PATCH 1079/1084] ASoC: soc-pcm: fix hwparams min/max init for dpcm When runtime is initialized with dpcm_init_runtime_hw(), some of the min/max calculations assume that defaults are set. For example calculation of channel min/max values may be done using zero-initialized data and soc_pcm_hw_update_chan() will always return max-channels of 0 in this case. This will result in failure to open the PCM at all. Fix the issue by calling soc_pcm_hw_init() before calling any soc_pcm_hw_update_*() functions. Remove the conditional code on runtime->hw.formats as this field is anyways set in soc_pcm_hw_init(). Fixes: 6cb56a4549e9 ("ASoC: soc-pcm: add soc_pcm_hw_update_chan()") Reported-by: Pierre-Louis Bossart Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210214220414.2876690-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index b7c90da1820e9..37094aeff4403 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1531,12 +1531,10 @@ static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, { struct snd_pcm_hardware *hw = &runtime->hw; + soc_pcm_hw_init(hw); soc_pcm_hw_update_rate(hw, stream); soc_pcm_hw_update_chan(hw, stream); - if (runtime->hw.formats) - runtime->hw.formats &= stream->formats; - else - runtime->hw.formats = stream->formats; + soc_pcm_hw_update_format(hw, stream); } static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, -- GitLab From bdea43fc0436c9e98fdfe151c2ed8a3fc7277404 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 16 Feb 2021 22:35:52 +0100 Subject: [PATCH 1080/1084] ASoC: Intel: bytcr_rt5640: Add quirk for the Estar Beauty HD MID 7316R tablet The Estar Beauty HD MID 7316R tablet almost fully works with out default settings. The only problem is that it has only 1 speaker so any sounds only playing on the right channel get lost. Add a quirk for this model using the default settings + MONO_SPEAKER. Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210216213555.36555-2-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_rt5640.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 2dee84578b90a..3008e3cbcbb87 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -531,6 +531,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_MONO_SPEAKER | BYT_RT5640_MCLK_EN), }, + { /* Estar Beauty HD MID 7316R */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Estar"), + DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | + BYT_RT5640_MONO_SPEAKER | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), -- GitLab From e1317cc9ca4ac20262895fddb065ffda4fc29cfb Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 16 Feb 2021 22:35:53 +0100 Subject: [PATCH 1081/1084] ASoC: Intel: bytcr_rt5640: Add quirk for the Voyo Winpad A15 tablet The Voyo Winpad A15 tablet uses a Bay Trail (non CR) SoC, so it is using SSP2 (AIF1) and it mostly works with the defaults. But instead of using DMIC1 it is using an analog mic on IN1, add a quirk for this. Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210216213555.36555-3-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_rt5640.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 3008e3cbcbb87..a81820943de67 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -824,6 +824,20 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF2 | BYT_RT5640_MCLK_EN), }, + { /* Voyo Winpad A15 */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), + /* Above strings are too generic, also match on BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "11/20/2014"), + }, + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_MCLK_EN), + }, { /* Catch-all for generic Insyde tablets, must be last */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), -- GitLab From df8359c512fa770ffa6b0b0309807d9b9825a47f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 16 Feb 2021 22:35:54 +0100 Subject: [PATCH 1082/1084] ASoC: Intel: bytcr_rt5651: Add quirk for the Jumper EZpad 7 tablet Add a DMI quirk for the Jumper EZpad 7 tablet, this tablet has a jack-detect switch which reads 1/high when a jack is inserted, rather then using the standard active-low setup which most jack-detect switches use. All other settings are using the defaults. Add a DMI-quirk setting the defaults + the BYT_RT5651_JD_NOT_INV flags for this. Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210216213555.36555-4-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_rt5651.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index f289ec8563a11..148b7b1bd3e8c 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -435,6 +435,19 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = { BYT_RT5651_SSP0_AIF1 | BYT_RT5651_MONO_SPEAKER), }, + { + /* Jumper EZpad 7 */ + .callback = byt_rt5651_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Jumper"), + DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"), + /* Jumper12x.WJ2012.bsBKRCP05 with the version dropped */ + DMI_MATCH(DMI_BIOS_VERSION, "Jumper12x.WJ2012.bsBKRCP"), + }, + .driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS | + BYT_RT5651_IN2_MAP | + BYT_RT5651_JD_NOT_INV), + }, { /* KIANO SlimNote 14.2 */ .callback = byt_rt5651_quirk_cb, -- GitLab From c58947af08aedbdee0fce5ea6e6bf3e488ae0e2c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 16 Feb 2021 22:35:55 +0100 Subject: [PATCH 1083/1084] ASoC: Intel: bytcr_rt5640: Add quirk for the Acer One S1002 tablet The Acer One S1002 tablet is using an analog mic on IN1 and has its jack-detect connected to JD2_IN4N, instead of using the default IN3 for its internal mic and JD1_IN4P for jack-detect. Note it is also using AIF2 instead of AIF1 which is somewhat unusual, this is correctly advertised in the ACPI CHAN package, so the speakers do work without the quirk. Add a quirk for the mic and jack-detect settings. Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210216213555.36555-5-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_rt5640.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index a81820943de67..782f2b4d72ad9 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -406,6 +406,19 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { /* Acer One 10 S1002 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "One S1002"), + }, + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_SSP0_AIF2 | + BYT_RT5640_MCLK_EN), + }, { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), -- GitLab From 8a353d7bafddb447fae136ca68899a6ba6187be6 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 16 Feb 2021 19:22:51 +0200 Subject: [PATCH 1084/1084] ASoC: soc-pcm: fix hw param limits calculation for multi-DAI In case DPCM runtime has multiple CPU DAIs, dpcm_init_runtime_hw() is called multiple times, once for each CPU DAI. This will lead to ignoring hw limits of all but the last DAI. Fix this by moving soc_pcm_hw_init() up by one level to dpcm_init_runtime_hw(). Fixes: 140f553d1298 ("ASoC: soc-pcm: fix hwparams min/max init for dpcm") Suggested-by: Kuninori Morimoto Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210216172251.3023723-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 37094aeff4403..14d85ca1e4357 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1531,10 +1531,12 @@ static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, { struct snd_pcm_hardware *hw = &runtime->hw; - soc_pcm_hw_init(hw); soc_pcm_hw_update_rate(hw, stream); soc_pcm_hw_update_chan(hw, stream); - soc_pcm_hw_update_format(hw, stream); + if (runtime->hw.formats) + runtime->hw.formats &= stream->formats; + else + runtime->hw.formats = stream->formats; } static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, @@ -1662,10 +1664,13 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_pcm_hardware *hw = &runtime->hw; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai; int i; + soc_pcm_hw_init(hw); + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { /* * Skip CPUs which don't support the current stream -- GitLab