Re: [PATCH v2 10/21] ipmi: kcs_bmc: Turn the driver data-structures inside-out
On Fri, 9 Apr 2021, at 13:27, Zev Weiss wrote: > On Fri, Mar 19, 2021 at 01:27:41AM CDT, Andrew Jeffery wrote: > >Make the KCS device drivers responsible for allocating their own memory. > > > >Until now the private data for the device driver was allocated internal > >to the private data for the chardev interface. This coupling required > >the slightly awkward API of passing through the struct size for the > >driver private data to the chardev constructor, and then retrieving a > >pointer to the driver private data from the allocated chardev memory. > > > >In addition to being awkward, the arrangement prevents the > >implementation of alternative userspace interfaces as the device driver > >private data is not independent. > > > >Peel a layer off the onion and turn the data-structures inside out by > >exploiting container_of() and embedding `struct kcs_device` in the > >driver private data. > > > >Signed-off-by: Andrew Jeffery > >--- > > drivers/char/ipmi/kcs_bmc.c | 15 +-- > > drivers/char/ipmi/kcs_bmc.h | 12 ++ > > drivers/char/ipmi/kcs_bmc_aspeed.c| 60 --- > > drivers/char/ipmi/kcs_bmc_cdev_ipmi.c | 60 ++- > > drivers/char/ipmi/kcs_bmc_npcm7xx.c | 37 ++--- > > 5 files changed, 113 insertions(+), 71 deletions(-) > > > >diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c > >index ef5c48ffe74a..709b6bdec165 100644 > >--- a/drivers/char/ipmi/kcs_bmc.c > >+++ b/drivers/char/ipmi/kcs_bmc.c > >@@ -44,12 +44,19 @@ int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) > > } > > EXPORT_SYMBOL(kcs_bmc_handle_event); > > > >-struct kcs_bmc *kcs_bmc_ipmi_alloc(struct device *dev, int sizeof_priv, u32 > >channel); > >-struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 > >channel) > >+int kcs_bmc_ipmi_attach_cdev(struct kcs_bmc *kcs_bmc); > > Another declaration perhaps intended for kcs_bmc.h? These are temporary while the code gets shuffled around. The symbol name is an implementation detail, not a "public" part of the API; after some further shuffling these are eventually assigned as callbacks in an ops struct. > > >+int kcs_bmc_add_device(struct kcs_bmc *kcs_bmc) > > { > >-return kcs_bmc_ipmi_alloc(dev, sizeof_priv, channel); > >+return kcs_bmc_ipmi_attach_cdev(kcs_bmc); > > } > >-EXPORT_SYMBOL(kcs_bmc_alloc); > >+EXPORT_SYMBOL(kcs_bmc_add_device); > >+ > >+int kcs_bmc_ipmi_detach_cdev(struct kcs_bmc *kcs_bmc); > > Here too. > > >+int kcs_bmc_remove_device(struct kcs_bmc *kcs_bmc) > >+{ > >+return kcs_bmc_ipmi_detach_cdev(kcs_bmc); > >+} > >+EXPORT_SYMBOL(kcs_bmc_remove_device); > > > > MODULE_LICENSE("GPL v2"); > > MODULE_AUTHOR("Haiyue Wang "); > >diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h > >index febea0c8deb4..bf0ae327997f 100644 > >--- a/drivers/char/ipmi/kcs_bmc.h > >+++ b/drivers/char/ipmi/kcs_bmc.h > >@@ -67,6 +67,8 @@ struct kcs_ioreg { > > }; > > > > struct kcs_bmc { > >+struct device *dev; > >+ > > spinlock_t lock; > > > > u32 channel; > >@@ -94,17 +96,11 @@ struct kcs_bmc { > > u8 *kbuffer; > > > > struct miscdevice miscdev; > >- > >-unsigned long priv[]; > > }; > > > >-static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc) > >-{ > >-return kcs_bmc->priv; > >-} > >- > > int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc); > >-struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 > >channel); > >+int kcs_bmc_add_device(struct kcs_bmc *kcs_bmc); > >+int kcs_bmc_remove_device(struct kcs_bmc *kcs_bmc); > > > > u8 kcs_bmc_read_data(struct kcs_bmc *kcs_bmc); > > void kcs_bmc_write_data(struct kcs_bmc *kcs_bmc, u8 data); > >diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c > >b/drivers/char/ipmi/kcs_bmc_aspeed.c > >index 630cf095560e..0416ac78ce68 100644 > >--- a/drivers/char/ipmi/kcs_bmc_aspeed.c > >+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c > >@@ -61,6 +61,8 @@ > > #define LPC_STR4 0x11C > > > > struct aspeed_kcs_bmc { > >+struct kcs_bmc kcs_bmc; > >+ > > struct regmap *map; > > }; > > > >@@ -69,9 +71,14 @@ struct aspeed_kcs_of_ops { > > int (*get_io_address)(struct platform_device *pdev); > > }; > > > >+static inline struct aspeed_kcs_bmc *to_aspeed_kcs_bmc(struct kcs_bmc > >*kcs_bmc) > >+{ > >+return container_of(kcs_bmc, struct aspeed_kcs_bmc, kcs_bmc); > >+} > >+ > > static u8 aspeed_kcs_inb(struct kcs_bmc *kcs_bmc, u32 reg) > > { > >-struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); > >+struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc); > > u32 val = 0; > > int rc; > > > >@@ -83,7 +90,7 @@ static u8 aspeed_kcs_inb(struct kcs_bmc *kcs_bmc, u32 reg) > > > > static void aspeed_kcs_outb(struct kcs_bmc *kcs_bmc, u32 reg, u8 data) > > { > >-struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); > >+struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc); > > int rc; > > > > rc = regmap_write(priv->map, reg, data); >
[PATCH] mm/page_alloc: Ensure that HUGETLB_PAGE_ORDER is less than MAX_ORDER
pageblock_order must always be less than MAX_ORDER, otherwise it might lead to an warning during boot. A similar problem got fixed on arm64 platform with the commit 79cc2ed5a716 ("arm64/mm: Drop THP conditionality from FORCE_MAX_ZONEORDER"). Assert the above condition before HUGETLB_PAGE_ORDER gets assigned as pageblock_order. This will help detect the problem earlier on platforms where HUGETLB_PAGE_SIZE_VARIABLE is enabled. Cc: Andrew Morton Cc: linux...@kvack.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Anshuman Khandual --- mm/page_alloc.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 604dcd69397b..81b7460e1228 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -7068,10 +7068,17 @@ void __init set_pageblock_order(void) if (pageblock_order) return; - if (HPAGE_SHIFT > PAGE_SHIFT) + if (HPAGE_SHIFT > PAGE_SHIFT) { + /* +* pageblock_order must always be less than +* MAX_ORDER. So does HUGETLB_PAGE_ORDER if +* that is being assigned here. +*/ + WARN_ON(HUGETLB_PAGE_ORDER >= MAX_ORDER); order = HUGETLB_PAGE_ORDER; - else + } else { order = MAX_ORDER - 1; + } /* * Assume the largest contiguous order of interest is a huge page. -- 2.20.1
[PATCH v2 1/1] kernel/cpu: to track which CPUHP callback is failed
During bootup or cpu hotplug, the cpuhp_up_callbacks() or cpuhp_down_callbacks() call many CPUHP callbacks (e.g., perf, mm, workqueue, RCU, kvmclock and more) for each cpu to online/offline. It may roll back to its previous state if any of callbacks is failed. As a result, the user will not be able to know which callback is failed and usually the only symptom is cpu online/offline failure. This patch is to print more debug log to help user narrow down where is the root cause. Below is the example that how the patch helps narrow down the root cause for the issue fixed by commit d7eb79c6290c ("KVM: kvmclock: Fix vCPUs > 64 can't be online/hotpluged"). We will have below dynamic debug log once we add dyndbg="file kernel/cpu.c +p" to kernel command line and when issue is reproduced. "CPUHP up callback failure (-12) for cpu 64 at kvmclock:setup_percpu (66)" Cc: Joe Jin Signed-off-by: Dongli Zhang --- Changed since v1 RFC: - use pr_debug() but not pr_err_once() (suggested by Qais Yousef) - print log for cpuhp_down_callbacks() as well (suggested by Qais Yousef) kernel/cpu.c | 8 1 file changed, 8 insertions(+) diff --git a/kernel/cpu.c b/kernel/cpu.c index 1b6302ecbabe..bcd4dd7de9c3 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -621,6 +621,10 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, st->state++; ret = cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL); if (ret) { + pr_debug("CPUHP up callback failure (%d) for cpu %u at %s (%d)\n", +ret, cpu, cpuhp_get_step(st->state)->name, +st->state); + if (can_rollback_cpu(st)) { st->target = prev_state; undo_cpu_up(cpu, st); @@ -990,6 +994,10 @@ static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, for (; st->state > target; st->state--) { ret = cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL); if (ret) { + pr_debug("CPUHP down callback failure (%d) for cpu %u at %s (%d)\n", +ret, cpu, cpuhp_get_step(st->state)->name, +st->state); + st->target = prev_state; if (st->state < prev_state) undo_cpu_down(cpu, st); -- 2.17.1
About add an A64FX cache control function into resctrl
Hello I'm Tan Shaopeng from Fujitsu Limited. I’m trying to implement Fujitsu A64FX’s cache related features. It is a cache partitioning function we called sector cache function that using the value of the tag that is upper 8 bits of the 64bit address and the value of the sector cache register to control virtual cache capacity of the L1D cache. A few days ago, when I sent a driver that realizes this function to ARM64 kernel community, Will Deacon and Arnd Bergmann suggested an idea to add the sector cache function of A64FX into resctrl. https://lore.kernel.org/linux-arm-kernel/CAK8P3a2pFcNTw9NpRtQfYr7A5OcZ=as2km0d_sbffcgq_j2...@mail.gmail.com/ Based on my study, I think the sector cache function of A64FX can be added into the allocation features of resctrl after James' resctrl rework has finished. But, in order to implement this function, more interfaces for resctrl are need. The details are as follow, and could you give me some advice? [Sector cache function] The sector cache function split cache into multiple sectors and control them separately. It is implemented on the L1D cache and L2 cache in the A64FX processor and can be controlled individually for L1D cache and L2 cache. A64FX has no L3 cache. Each L1D cache and L2 cache has 4 sectors. Which L1D sector is used is specified by the value of [57:56] bits of address, how many ways of sector are specified by the value of register (IMP_SCCR_L1_EL0). Which L2 sector is used is specified by the value of [56] bits of address, and how many ways of sector are specified by value of register (IMP_SCCR_ASSIGN_EL1, IMP_SCCR_SET0_L2_EL1, IMP_SCCR_SET1_L2_EL1). For more details of sector cache function, see A64FX HPC extension specification (1.2. Sector cache) in https://github.com/fujitsu/A64FX [Difference between resctrl(CAT) and this sector cache function] L2/L3 CAT (Cache Allocation Technology) enables the user to specify some physical partition of cache space that an application can fill. A64FX's L1D/L2 cache has 4 sectors and 16ways. This sector function enables a user to specify number of ways each sector uses. Therefore, for CAT it is enough to specify a cache portion for each cache_id (socket). On the other hand, sector cache needs to specify cache portion of each sector for each cache_id, and following extension to resctrl interface is needed to support sector cache. [Idear for A64FX sector cache function control interface (schemata file details)] L1:=,,,;=,,,;… L2:=>=,,,;=,,,;… ・L1: Add a new interface to control the L1D cache. ・,,,:Specify the number of ways for each sector. ・cwbm:Specify the number of ways in each sector as a bitmap (percentage), but the bitmap does not indicate the location of the cache. * In the sector cache function, L2 sector cache way setting register is shared among PEs (Processor Element) in shared domain. If two PEs which share L2 cache belongs to different resource groups, one resource group's L2 setting will affect to other resource group's L2 setting. * Since A64FX does not support MPAM, it is not necessary to consider how to switch between MPAM and sector cache function now. Some questions: 1.I'm still studying about RDT, could you tell me whether RDT has the similar mechanism with sector cache function? 2.In RDT, L3 cache is shared among cores in socket. If two cores which share L3 cache belongs to different resource groups, one resource group's L3 setting will affect to other resource group's L3 setting? 3.Is this approach acceptable? could you give me some advice? Best regards Tan Shaopeng
linux-next: manual merge of the irqchip tree with the arm-soc tree
Hi all, Today's linux-next merge of the irqchip tree got conflicts in: drivers/irqchip/Kconfig drivers/irqchip/Makefile between commit: 76cde2639411 ("irqchip/apple-aic: Add support for the Apple Interrupt Controller") from the arm-soc tree and commits: fead4dd49663 ("irqchip: Add driver for WPCM450 interrupt controller") 94bc94209a66 ("irqchip/wpcm450: Drop COMPILE_TEST") from the irqchip tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc drivers/irqchip/Kconfig index d3a14f304ec8,715eb4366e35.. --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@@ -577,12 -577,10 +577,18 @@@ config MST_IR help Support MStar Interrupt Controller. +config APPLE_AIC + bool "Apple Interrupt Controller (AIC)" + depends on ARM64 + default ARCH_APPLE + help +Support for the Apple Interrupt Controller found on Apple Silicon SoCs, +such as the M1. + + config WPCM450_AIC + bool "Nuvoton WPCM450 Advanced Interrupt Controller" + depends on ARCH_WPCM450 + help + Support for the interrupt controller in the Nuvoton WPCM450 BMC SoC. + endmenu diff --cc drivers/irqchip/Makefile index eb6a515f0f64,bef57937e729.. --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@@ -113,4 -113,4 +113,5 @@@ obj-$(CONFIG_LOONGSON_PCH_MSI) += irq- obj-$(CONFIG_MST_IRQ) += irq-mst-intc.o obj-$(CONFIG_SL28CPLD_INTC) += irq-sl28cpld.o obj-$(CONFIG_MACH_REALTEK_RTL)+= irq-realtek-rtl.o +obj-$(CONFIG_APPLE_AIC) += irq-apple-aic.o + obj-$(CONFIG_WPCM450_AIC) += irq-wpcm450-aic.o pgpAMbGlwpkkf.pgp Description: OpenPGP digital signature
[PATCH 2/2] selinux:Delete selinux_xfrm_policy_lookup() useless argument
From: Zhongjun Tan seliunx_xfrm_policy_lookup() is hooks of security_xfrm_policy_lookup(). The dir argument is uselss in security_xfrm_policy_lookup(). So remove the dir argument from selinux_xfrm_policy_lookup() and security_xfrm_policy_lookup(). Signed-off-by: Zhongjun Tan --- include/linux/lsm_hook_defs.h | 3 +-- include/linux/security.h| 4 ++-- net/xfrm/xfrm_policy.c | 6 ++ security/security.c | 4 ++-- security/selinux/include/xfrm.h | 2 +- security/selinux/xfrm.c | 2 +- 6 files changed, 9 insertions(+), 12 deletions(-) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 04c0179..2adeea4 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -358,8 +358,7 @@ struct xfrm_sec_ctx *polsec, u32 secid) LSM_HOOK(void, LSM_RET_VOID, xfrm_state_free_security, struct xfrm_state *x) LSM_HOOK(int, 0, xfrm_state_delete_security, struct xfrm_state *x) -LSM_HOOK(int, 0, xfrm_policy_lookup, struct xfrm_sec_ctx *ctx, u32 fl_secid, -u8 dir) +LSM_HOOK(int, 0, xfrm_policy_lookup, struct xfrm_sec_ctx *ctx, u32 fl_secid) LSM_HOOK(int, 1, xfrm_state_pol_flow_match, struct xfrm_state *x, struct xfrm_policy *xp, const struct flowi_common *flic) LSM_HOOK(int, 0, xfrm_decode_session, struct sk_buff *skb, u32 *secid, diff --git a/include/linux/security.h b/include/linux/security.h index 06f7c50..24eda04 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1681,7 +1681,7 @@ int security_xfrm_state_alloc_acquire(struct xfrm_state *x, struct xfrm_sec_ctx *polsec, u32 secid); int security_xfrm_state_delete(struct xfrm_state *x); void security_xfrm_state_free(struct xfrm_state *x); -int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); +int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid); int security_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp, const struct flowi_common *flic); @@ -1732,7 +1732,7 @@ static inline int security_xfrm_state_delete(struct xfrm_state *x) return 0; } -static inline int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) +static inline int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid) { return 0; } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 156347f..d5d934e 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1902,8 +1902,7 @@ static int xfrm_policy_match(const struct xfrm_policy *pol, match = xfrm_selector_match(sel, fl, family); if (match) - ret = security_xfrm_policy_lookup(pol->security, fl->flowi_secid, - dir); + ret = security_xfrm_policy_lookup(pol->security, fl->flowi_secid); return ret; } @@ -2181,8 +2180,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, goto out; } err = security_xfrm_policy_lookup(pol->security, - fl->flowi_secid, - dir); + fl->flowi_secid); if (!err) { if (!xfrm_pol_hold_rcu(pol)) goto again; diff --git a/security/security.c b/security/security.c index b38155b..0c1c979 100644 --- a/security/security.c +++ b/security/security.c @@ -2466,9 +2466,9 @@ void security_xfrm_state_free(struct xfrm_state *x) call_void_hook(xfrm_state_free_security, x); } -int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) +int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid) { - return call_int_hook(xfrm_policy_lookup, 0, ctx, fl_secid, dir); + return call_int_hook(xfrm_policy_lookup, 0, ctx, fl_secid); } int security_xfrm_state_pol_flow_match(struct xfrm_state *x, diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 0a6f34a..7415940 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h @@ -23,7 +23,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, struct xfrm_sec_ctx *polsec, u32 secid); void selinux_xfrm_state_free(struct xfrm_state *x); int selinux_xfrm_state_delete(struct xfrm_state *x); -int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); +int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid); int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp,
Re: [PATCH v2] char: tpm: fix error return code in tpm_cr50_i2c_tis_recv()
On Fri, Apr 09, 2021 at 09:12:01AM +0800, Zhihao Cheng wrote: > Fix to return a negative error code from the error handling > case instead of 0, as done elsewhere in this function. > > Fixes: 3a253caaad11 ("char: tpm: add i2c driver for cr50") > Reported-by: Hulk Robot > Signed-off-by: Zhihao Cheng Reviewed-by: Jarkko Sakkinen > --- > drivers/char/tpm/tpm_tis_i2c_cr50.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/char/tpm/tpm_tis_i2c_cr50.c > b/drivers/char/tpm/tpm_tis_i2c_cr50.c > index ec9a65e7887d..f19c227d20f4 100644 > --- a/drivers/char/tpm/tpm_tis_i2c_cr50.c > +++ b/drivers/char/tpm/tpm_tis_i2c_cr50.c > @@ -483,6 +483,7 @@ static int tpm_cr50_i2c_tis_recv(struct tpm_chip *chip, > u8 *buf, size_t buf_len) > expected = be32_to_cpup((__be32 *)(buf + 2)); > if (expected > buf_len) { > dev_err(>dev, "Buffer too small to receive i2c data\n"); > + rc = -E2BIG; > goto out_err; > } > > -- > 2.25.4 > > /Jarkko
Re: [PATCH v2 09/21] ipmi: kcs_bmc: Split out kcs_bmc_cdev_ipmi
On Fri, 9 Apr 2021, at 13:26, Zev Weiss wrote: > On Fri, Mar 19, 2021 at 01:27:40AM CDT, Andrew Jeffery wrote: > >Take steps towards defining a coherent API to separate the KCS device > >drivers from the userspace interface. Decreasing the coupling will > >improve the separation of concerns and enable the introduction of > >alternative userspace interfaces. > > > >For now, simply split the chardev logic out to a separate file. The code > >continues to build into the same module. > > > >Signed-off-by: Andrew Jeffery > >--- > > drivers/char/ipmi/Makefile| 2 +- > > drivers/char/ipmi/kcs_bmc.c | 423 + > > drivers/char/ipmi/kcs_bmc.h | 10 +- > > drivers/char/ipmi/kcs_bmc_cdev_ipmi.c | 428 ++ > > 4 files changed, 451 insertions(+), 412 deletions(-) > > create mode 100644 drivers/char/ipmi/kcs_bmc_cdev_ipmi.c > > > >diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile > >index 0822adc2ec41..a302bc865370 100644 > >--- a/drivers/char/ipmi/Makefile > >+++ b/drivers/char/ipmi/Makefile > >@@ -22,7 +22,7 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o > > obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o > > obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o > > obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o > >-obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o > >+obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o kcs_bmc_cdev_ipmi.o > > obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o > > obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o > > obj-$(CONFIG_NPCM7XX_KCS_IPMI_BMC) += kcs_bmc_npcm7xx.o > >diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c > >index c4336c1f2d6d..ef5c48ffe74a 100644 > >--- a/drivers/char/ipmi/kcs_bmc.c > >+++ b/drivers/char/ipmi/kcs_bmc.c > >@@ -3,446 +3,51 @@ > > * Copyright (c) 2015-2018, Intel Corporation. > > */ > > > >-#define pr_fmt(fmt) "kcs-bmc: " fmt > >- > >-#include > >-#include > >-#include > > #include > >-#include > >-#include > >-#include > >-#include > > > > #include "kcs_bmc.h" > > > >-#define DEVICE_NAME "ipmi-kcs" > >- > >-#define KCS_MSG_BUFSIZ1000 > >- > >-#define KCS_ZERO_DATA 0 > >- > >- > >-/* IPMI 2.0 - Table 9-1, KCS Interface Status Register Bits */ > >-#define KCS_STATUS_STATE(state) (state << 6) > >-#define KCS_STATUS_STATE_MASK GENMASK(7, 6) > >-#define KCS_STATUS_CMD_DAT BIT(3) > >-#define KCS_STATUS_SMS_ATN BIT(2) > >-#define KCS_STATUS_IBF BIT(1) > >-#define KCS_STATUS_OBF BIT(0) > >- > >-/* IPMI 2.0 - Table 9-2, KCS Interface State Bits */ > >-enum kcs_states { > >-IDLE_STATE = 0, > >-READ_STATE = 1, > >-WRITE_STATE = 2, > >-ERROR_STATE = 3, > >-}; > >- > >-/* IPMI 2.0 - Table 9-3, KCS Interface Control Codes */ > >-#define KCS_CMD_GET_STATUS_ABORT 0x60 > >-#define KCS_CMD_WRITE_START 0x61 > >-#define KCS_CMD_WRITE_END 0x62 > >-#define KCS_CMD_READ_BYTE 0x68 > >- > >-static inline u8 kcs_bmc_read_data(struct kcs_bmc *kcs_bmc) > >+u8 kcs_bmc_read_data(struct kcs_bmc *kcs_bmc) > > { > > return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.idr); > > } > >+EXPORT_SYMBOL(kcs_bmc_read_data); > > > >-static inline void kcs_bmc_write_data(struct kcs_bmc *kcs_bmc, u8 data) > >+void kcs_bmc_write_data(struct kcs_bmc *kcs_bmc, u8 data) > > { > > kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.odr, data); > > } > >+EXPORT_SYMBOL(kcs_bmc_write_data); > > > >-static inline u8 kcs_bmc_read_status(struct kcs_bmc *kcs_bmc) > >+u8 kcs_bmc_read_status(struct kcs_bmc *kcs_bmc) > > { > > return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.str); > > } > >+EXPORT_SYMBOL(kcs_bmc_read_status); > > > >-static inline void kcs_bmc_write_status(struct kcs_bmc *kcs_bmc, u8 data) > >+void kcs_bmc_write_status(struct kcs_bmc *kcs_bmc, u8 data) > > { > > kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.str, data); > > } > >+EXPORT_SYMBOL(kcs_bmc_write_status); > > > >-static void kcs_bmc_update_status(struct kcs_bmc *kcs_bmc, u8 mask, u8 val) > >+void kcs_bmc_update_status(struct kcs_bmc *kcs_bmc, u8 mask, u8 val) > > { > > kcs_bmc->io_updateb(kcs_bmc, kcs_bmc->ioreg.str, mask, val); > > } > >+EXPORT_SYMBOL(kcs_bmc_update_status); > > > >-static inline void set_state(struct kcs_bmc *kcs_bmc, u8 state) > >-{ > >-kcs_bmc_update_status(kcs_bmc, KCS_STATUS_STATE_MASK, > >-KCS_STATUS_STATE(state)); > >-} > >- > >-static void kcs_force_abort(struct kcs_bmc *kcs_bmc) > >-{ > >-set_state(kcs_bmc, ERROR_STATE); > >-kcs_bmc_read_data(kcs_bmc); > >-kcs_bmc_write_data(kcs_bmc, KCS_ZERO_DATA); > >- > >-kcs_bmc->phase = KCS_PHASE_ERROR; > >-kcs_bmc->data_in_avail = false; > >-kcs_bmc->data_in_idx = 0; > >-} > >- > >-static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc) > >-{ > >-u8 data; > >- > >-switch (kcs_bmc->phase) { > >-case KCS_PHASE_WRITE_START: > >-kcs_bmc->phase = KCS_PHASE_WRITE_DATA; > >-fallthrough; > >- > >-
Re: [PATCH] ext4: add a configurable parameter to prevent endless loop in ext4_mb_discard_group_p
On 21/04/09 02:50AM, Wen Yang wrote: > > On Apr 7, 2021, at 5:16 AM, riteshh wrote: > >> > >> On 21/04/07 03:01PM, Wen Yang wrote: > >>> From: Wen Yang > >>> > >>> The kworker has occupied 100% of the CPU for several days: > >>> PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND > >>> 68086 root 20 0 00 0 R 100.0 0.0 9718:18 kworker/u64:11 > >>> > >>> And the stack obtained through sysrq is as follows: > >>> [20613144.850426] task: 8800b5e08000 task.stack: c9001342c000 > >>> [20613144.850438] Call Trace: > >>> [20613144.850439] []ext4_mb_new_blocks+0x429/0x550 > [ext4] > >>> [20613144.850439] [] ext4_ext_map_blocks+0xb5e/0xf30 > [ext4] > >>> [20613144.850441] [] ext4_map_blocks+0x172/0x620 > [ext4] > >>> [20613144.850442] [] ext4_writepages+0x7e5/0xf00 > [ext4] > >>> [20613144.850443] [] do_writepages+0x1e/0x30 > >>> [20613144.850444] [] > __writeback_single_inode+0x45/0x320 > >>> [20613144.850444] [] writeback_sb_inodes+0x272/0x600 > >>> [20613144.850445] [] __writeback_inodes_wb+0x92/0xc0 > >>> [20613144.850445] [] wb_writeback+0x268/0x300 > >>> [20613144.850446] [] wb_workfn+0xb4/0x380 > >>> [20613144.850447] [] process_one_work+0x189/0x420 > >>> [20613144.850447] [] worker_thread+0x4e/0x4b0 > >>> > >>> The cpu resources of the cloud server are precious, and the server > >>> cannot be restarted after running for a long time, so a configuration > >>> parameter is added to prevent this endless loop. > >> > >> Strange, if there is a endless loop here. Then I would definitely see > >> if there is any accounting problem in pa->pa_count. Otherwise busy=1 > >> should not be set everytime. ext4_mb_show_pa() function may help debug > this. > >> > >> If yes, then that means there always exists either a file preallocation > >> or a group preallocation. Maybe it is possible, in some use case. > >> Others may know of such use case, if any. > > > If this code is broken, then it doesn't make sense to me that we would > > leave it in the "run forever" state after the patch, and require a sysfs > > tunable to be set to have a properly working system? > > > Is there anything particularly strange about the workload/system that > > might cause this? Filesystem is very full, memory is very low, etc? > > Hi Ritesh and Andreas, > > Thank you for your reply. Since there is still a faulty machine, we have > analyzed it again and found it is indeed a very special case: > > > crash> struct ext4_group_info 8813bb5f72d0 > struct ext4_group_info { > bb_state = 0, > bb_free_root = { > rb_node = 0x0 > }, > bb_first_free = 1681, > bb_free = 0, Not related to this issue, but above two variables values doesn't looks consistent. > bb_fragments = 0, > bb_largest_free_order = -1, > bb_prealloc_list = { > next = 0x880268291d78, > prev = 0x880268291d78 ---> *** The list is empty > }, Ok. So when you collected the dump this list was empty. > alloc_sem = { > count = { > counter = 0 > }, > wait_list = { > next = 0x8813bb5f7308, > prev = 0x8813bb5f7308 > }, > wait_lock = { > raw_lock = { > { > val = { > counter = 0 > }, > { > locked = 0 '\000', > pending = 0 '\000' > }, > { > locked_pending = 0, > tail = 0 > } > } > } > }, > osq = { > tail = { > counter = 0 > } > }, > owner = 0x0 > }, > bb_counters = 0x8813bb5f7328 > } > crash> > > > crash> list 0x880268291d78 -l ext4_prealloc_space.pa_group_list -s No point of doing this I guess, since the list anyway is empty. What you may be seeing below is some garbage data. > ext4_prealloc_space.pa_count > 880268291d78 > pa_count = { > counter = 1 ---> pa->pa_count > } > 8813bb5f72f0 > pa_count = { > counter = -30701 > } I guess, since list is empty and you are seeing garbage hence counter value of above node looks weird. > > > crash> struct -xo ext4_prealloc_space > struct ext4_prealloc_space { >[0x0] struct list_head pa_inode_list; > [0x10] struct list_head pa_group_list; > union { > struct list_head pa_tmp_list; > struct callback_head pa_rcu; > [0x20] } u; > [0x30] spinlock_t pa_lock; > [0x34] atomic_t pa_count; > [0x38] unsigned int pa_deleted; > [0x40] ext4_fsblk_t pa_pstart; > [0x48] ext4_lblk_t pa_lstart; > [0x4c] ext4_grpblk_t pa_len; > [0x50] ext4_grpblk_t pa_free; > [0x54] unsigned short pa_type; > [0x58] spinlock_t *pa_obj_lock; > [0x60] struct inode *pa_inode; > } > SIZE: 0x68 > > > crash> rd 0x880268291d68 20 > 880268291d68: 881822f8a4c8 881822f8a4c8 ..."..." > 880268291d78: 8813bb5f72f0 8813bb5f72f0 .r_..r_. > 880268291d88: 1000 880db2371000 ..7. > 880268291d98:
Re: [PATCH 4/6] usb: xhci-mtk: add support runtime PM
On Thu, Apr 8, 2021 at 5:35 PM Chunfeng Yun wrote: > > A dedicated wakeup irq will be used to handle runtime suspend/resume, > we use dev_pm_set_dedicated_wake_irq API to take care of requesting > and attaching wakeup irq, then the suspend/resume framework will help > to enable/disable wakeup irq. > > The runtime PM is default off since some platforms may not support it. > users can enable it via power/control (set "auto") in sysfs. > > Signed-off-by: Chunfeng Yun > --- > drivers/usb/host/xhci-mtk.c | 140 +++- > 1 file changed, 124 insertions(+), 16 deletions(-) > > diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c > index a74764ab914a..30927f4064d4 100644 > --- a/drivers/usb/host/xhci-mtk.c > +++ b/drivers/usb/host/xhci-mtk.c > @@ -16,6 +16,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -358,7 +359,6 @@ static int usb_wakeup_of_property_parse(struct > xhci_hcd_mtk *mtk, > mtk->uwk_reg_base, mtk->uwk_vers); > > return PTR_ERR_OR_ZERO(mtk->uwk); > - > } > > static void usb_wakeup_set(struct xhci_hcd_mtk *mtk, bool enable) > @@ -458,6 +458,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) > struct resource *res; > struct usb_hcd *hcd; > int ret = -ENODEV; > + int wakeup_irq; > int irq; > > if (usb_disabled()) > @@ -485,6 +486,21 @@ static int xhci_mtk_probe(struct platform_device *pdev) > if (ret) > return ret; > > + irq = platform_get_irq_byname_optional(pdev, "host"); > + if (irq < 0) { > + if (irq == -EPROBE_DEFER) > + return irq; > + > + /* for backward compatibility */ > + irq = platform_get_irq(pdev, 0); > + if (irq < 0) > + return irq; > + } > + > + wakeup_irq = platform_get_irq_byname_optional(pdev, "wakeup"); > + if (wakeup_irq == -EPROBE_DEFER) > + return wakeup_irq; > + > mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable"); > /* optional property, ignore the error if it does not exist */ > of_property_read_u32(node, "mediatek,u3p-dis-msk", > @@ -496,9 +512,11 @@ static int xhci_mtk_probe(struct platform_device *pdev) > return ret; > } > > + pm_runtime_set_active(dev); > + pm_runtime_use_autosuspend(dev); > + pm_runtime_set_autosuspend_delay(dev, 4000); > pm_runtime_enable(dev); > pm_runtime_get_sync(dev); > - device_enable_async_suspend(dev); > > ret = xhci_mtk_ldos_enable(mtk); > if (ret) > @@ -508,12 +526,6 @@ static int xhci_mtk_probe(struct platform_device *pdev) > if (ret) > goto disable_ldos; > > - irq = platform_get_irq(pdev, 0); > - if (irq < 0) { > - ret = irq; > - goto disable_clk; > - } > - > hcd = usb_create_hcd(driver, dev, dev_name(dev)); > if (!hcd) { > ret = -ENOMEM; > @@ -579,8 +591,26 @@ static int xhci_mtk_probe(struct platform_device *pdev) > if (ret) > goto dealloc_usb2_hcd; > > + if (wakeup_irq > 0) { > + ret = dev_pm_set_dedicated_wake_irq(dev, wakeup_irq); > + if (ret) { > + dev_err(dev, "set wakeup irq %d failed\n", > wakeup_irq); > + goto dealloc_usb3_hcd; > + } > + dev_info(dev, "wakeup irq %d\n", wakeup_irq); > + } > + > + device_enable_async_suspend(dev); > + pm_runtime_mark_last_busy(dev); > + pm_runtime_put_autosuspend(dev); > + pm_runtime_forbid(dev); > + > return 0; > > +dealloc_usb3_hcd: > + usb_remove_hcd(xhci->shared_hcd); > + xhci->shared_hcd = NULL; > + > dealloc_usb2_hcd: > usb_remove_hcd(hcd); > > @@ -601,25 +631,26 @@ static int xhci_mtk_probe(struct platform_device *pdev) > xhci_mtk_ldos_disable(mtk); > > disable_pm: > - pm_runtime_put_sync(dev); > + pm_runtime_put_sync_autosuspend(dev); > pm_runtime_disable(dev); > return ret; > } > > -static int xhci_mtk_remove(struct platform_device *dev) > +static int xhci_mtk_remove(struct platform_device *pdev) > { > - struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev); > + struct xhci_hcd_mtk *mtk = platform_get_drvdata(pdev); > struct usb_hcd *hcd = mtk->hcd; > struct xhci_hcd *xhci = hcd_to_xhci(hcd); > struct usb_hcd *shared_hcd = xhci->shared_hcd; > + struct device *dev = >dev; > > - pm_runtime_put_noidle(>dev); > - pm_runtime_disable(>dev); > + pm_runtime_get_sync(dev); > + xhci->xhc_state |= XHCI_STATE_REMOVING; > + dev_pm_clear_wake_irq(dev); > + device_init_wakeup(dev, false); > > usb_remove_hcd(shared_hcd); >
Re: [PATCH 2/3] fpga: dfl: Add DFL bus driver for Altera SPI Master
On Fri, Apr 09, 2021 at 12:02:47PM +0800, Wu, Hao wrote: > > > > > > > > > + > > > > > > > > > +static void dfl_spi_altera_remove(struct dfl_device *dfl_dev) > > > > > > > > > +{ > > > > > > > > > +struct dfl_altera_spi *aspi = dev_get_drvdata(_dev->dev); > > > > > > > > > + > > > > > > > > > +platform_device_unregister(aspi->altr_spi); > > > > > > > > > +} > > > > > > > > > + > > > > > > > > > +#define FME_FEATURE_ID_MAX10_SPI0xe > > > > > > > > > + > > > > > > > > > +static const struct dfl_device_id dfl_spi_altera_ids[] = { > > > > > > > > > +{ FME_ID, FME_FEATURE_ID_MAX10_SPI }, > > > > > > > > > +{ } > > > > > > > > > +}; > > > > > > > > > > > > > > > > Maybe you can extend the Altera SPI driver with this part? > > > > > > > > > > > > > > The file, drivers/spi/spi-altera.c, already has platform MODULE_ > > related > > > > > > > code. Wouldn't moving this code to that file produce conflicts? > > > > > > > > > > > > I've seen other drivers support multiple busses, so it should be > > > > > > possible, there might be nuances I'm missing in my brief look at > > > > > > this, > > > > > > though. > > > > > > > > > > > > I think one of them would be MODULE_DEVICE_TABLE(platform, ...) > > > > > > and the other one MODULE_DEVICE_TABLE(dfl, ...) > > > > > > > > > > > > See drivers/i2c/busses/i2c-designware-platdrv.c for an example > > > > > > (though > > > > > > they might be guarding against what you describe with CONFIG_OF vs > > > > > > CONFIG_ACPI) > > > > > > > > > > > > If that doesn't work we could split it up into > > > > > > > > > > > > altera-spi-plat.c and altera-spi-dfl.c and altera-spi-core.c > > > > > > or something of that sort? > > > > > > > > > > > > My point being, now that we have a bus, let's use it and develop > > > > > > drivers > > > > > > according to the Linux device model where possible :) > > > > > > > > > > Agree. This does make sense from my side too. DFL core provides the > > > > mechanism > > > > > to enumerate different IPs on FPGA, but each function driver needs to > > > > > go > > to > > > > > related subsystem for review. : ) > > > > > > > > > > I understand that for FPGA case, it may have some additional logics > > > > > for > > specific > > > > > purposes based on common altera spi master IP, then additional code > > > > > for > > > > > > > > I'm wondering if the additional logics are extensions for common > > > > spi-altera. > > Like > > > > the > > > > SPI_CORE_PARAMETER register, it is not within the register space of > > > > spi-altera, > > > > > > > > > > > > | | +-+ > > > > |DFL|--| ++ | > > > > |BUS| | |SPI CORE| | > > > > | | | |PARAM | | > > > > | | | ++ | > > > > | | | | > > > > | | | ++ | +---+ > > > > | |Indirect| | |spi| > > > > | |access +--+---|altera | > > > > | |master | | +---+ > > > > | ++ | > > > > +-+ > > > > > a specific product still can be put into altera-spi-.c or > > > > > altera-spi-dfl- > > .c > > > > > > > > So is it proper we integrate this feature into spi-altera? Previously > > > > we have merged the dfl-n3000-nios, its spi part is very similar as > > > > this driver. The dfl-n3000-nios make the spi-altera as a sub device. > > > > Could we borrow the idea, or could we just integrate this driver in > > > > dfl-n3000-nios? > > > > > > Looks like those are enhancements of the IP. They can be applied even > > > > I don't think the extra registers are the enhancement of the IP. They > > are not part of the IP because they are not within the IP's register > > space. They are like some external way of describing the IP like > > Devicetree or ACPI. > > Why adding new registers can't be consider as enhancement, those > changes serve the original IP and make it better, right? small mmio > footprint and parameter registers? > > > > > > other buses are used, not only for DFL, like PCI device or platform > > > device, > > > right? then why not put related code together with the original IP? > > > > The code of devicetree or ACPI parsing are integrated in the IP drivers, > > but for this case, it may not be proper for now, cause this style is not > > formally introduced by any standard. IP specific parameters description > > are not within the scope of DFL now. > > Not sure if I get your point, but it's possible that we add some enhancements > to one IP then driver could be simplified and doesn't need devicetree any > more. > For sure, it's IP specific thing, not the scope of DFL. > > Then things become this: extension to IP to allow this IP to be used without > device tree, so that this IP can be used in DFL or PCI or other buses without > device tree? It's good to extend an IP, but it needs a published SPEC and stable register interfaces. For now, the spi-altera driver conforms to the "SPI Core" chapter
Re: [PATCH v2 17/21] dt-bindings: ipmi: Convert ASPEED KCS binding to schema
On Fri, Apr 09, 2021 at 12:33:10AM CDT, Andrew Jeffery wrote: > > >On Fri, 9 Apr 2021, at 14:45, Zev Weiss wrote: >> On Fri, Mar 19, 2021 at 01:27:48AM CDT, Andrew Jeffery wrote: >> >Given the deprecated binding, improve the ability to detect issues in >> >the platform devicetrees. Further, a subsequent patch will introduce a >> >new interrupts property for specifying SerIRQ behaviour, so convert >> >before we do any further additions. >> > >> >Signed-off-by: Andrew Jeffery >> >--- >> > .../bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml | 92 +++ >> > .../bindings/ipmi/aspeed-kcs-bmc.txt | 33 --- >> > 2 files changed, 92 insertions(+), 33 deletions(-) >> > create mode 100644 >> > Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml >> > delete mode 100644 >> > Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt >> > >> >diff --git >> >a/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml >> >b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml >> >new file mode 100644 >> >index ..697ca575454f >> >--- /dev/null >> >+++ b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml >> >@@ -0,0 +1,92 @@ >> >+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) >> >+%YAML 1.2 >> >+--- >> >+$id: http://devicetree.org/schemas/ipmi/aspeed,ast2400-kcs-bmc.yaml >> >+$schema: http://devicetree.org/meta-schemas/core.yaml >> >+ >> >+title: ASPEED BMC KCS Devices >> >+ >> >+maintainers: >> >+ - Andrew Jeffery >> >+ >> >+description: | >> >+ The Aspeed BMC SoCs typically use the Keyboard-Controller-Style (KCS) >> >+ interfaces on the LPC bus for in-band IPMI communication with their host. >> >+ >> >+properties: >> >+ compatible: >> >+oneOf: >> >+ - description: Channel ID derived from reg >> >+items: >> >+ enum: >> >+- aspeed,ast2400-kcs-bmc-v2 >> >+- aspeed,ast2500-kcs-bmc-v2 >> >+- aspeed,ast2600-kcs-bmc >> >> Should this have a "-v2" suffix? > >Well, that was kind of a matter of perspective. The 2600 compatible was >added after we'd done the v2 of the binding for the 2400 and 2500 so it >never needed correcting. But it is a case of "don't use the deprecated >properties with the 2600 compatible". > >I don't think a change is necessary? > It just looked inconsistent with the corresponding string in the ast_kcs_bmc_match[] table; perhaps that should be changed instead then? Zev
Re: [PATCH 04/10] mm/migrate: make migrate_pages() return nr_succeeded
I agree that it is a good further improvement to make nr_succeeded an optional output argument of migrate_pages() given that most callers don't need it. IMHO, the most important thing in this matter is to ensure that nr_succeeded only returns (when its return value is needed) the successfully migrated pages in this round and doesn't accumulate. This is addressed by both proposals. On Thu, Apr 8, 2021 at 10:06 PM Oscar Salvador wrote: > > On Thu, Apr 08, 2021 at 01:40:33PM -0700, Yang Shi wrote: > > Thanks a lot for the example code. You didn't miss anything. At first > > glance, I thought your suggestion seemed neater. Actually I > > misunderstood what Dave said about "That could really have caused some > > interesting problems." with multiple calls to migrate_pages(). I was > > thinking about: > > > > unsigned long foo() > > { > > unsigned long *ret_succeeded; > > > > migrate_pages(..., ret_succeeded); > > > > migrate_pages(..., ret_succeeded); > > > > return *ret_succeeded; > > } > > But that would not be a problem as well. I mean I am not sure what is > foo() supposed to do. > I assume is supposed to return the *total* number of pages that were > migrated? > > Then could do something like: > > unsigned long foo() > { > unsigned long ret_succeeded; > unsigned long total_succeeded = 0; > > migrate_pages(..., _succeeded); > total_succeeded += ret_succeeded; > > migrate_pages(..., _succeeded); > total_succeeded += ret_succeeded; > > return *total_succeeded; > } > > But AFAICS, you would have to do that with Wei Xu's version and with > mine, no difference there. > > IIUC, Dave's concern was that nr_succeeded was only set to 0 at the beginning > of the function, and never reset back, which means, we would carry the > sum of previous nr_succeeded instead of the nr_succeeded in that round. > That would be misleading for e.g: reclaim in case we were to call > migrate_pages() several times, as instead of a delta value, nr_succeeded > would accumulate. > > But that won't happen neither with Wei Xu's version nor with mine. > > -- > Oscar Salvador > SUSE L3
Re: [syzbot] memory leak in ext4_multi_mount_protect
syzbot has found a reproducer for the following issue on: HEAD commit:4fa56ad0 Merge tag 'for-linus' of git://git.kernel.org/pub.. git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=12390a96d0 kernel config: https://syzkaller.appspot.com/x/.config?x=b8dbd3c72fdc dashboard link: https://syzkaller.appspot.com/bug?extid=d9e482e303930fa4f6ff syz repro: https://syzkaller.appspot.com/x/repro.syz?x=109aaa7ed0 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=16e77d16d0 IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+d9e482e303930fa4f...@syzkaller.appspotmail.com executing program BUG: memory leak unreferenced object 0x888111edd780 (size 32): comm "syz-executor633", pid 8448, jiffies 4294951405 (age 17.620s) hex dump (first 32 bytes): 10 64 d1 0f 81 88 ff ff 00 10 7e 12 81 88 ff ff .d~. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 backtrace: [] kmalloc include/linux/slab.h:554 [inline] [] ext4_multi_mount_protect+0x4a6/0x5d0 fs/ext4/mmp.c:367 [] ext4_fill_super+0x56a4/0x5b20 fs/ext4/super.c:4769 [] mount_bdev+0x223/0x260 fs/super.c:1367 [] legacy_get_tree+0x2b/0x90 fs/fs_context.c:592 [] vfs_get_tree+0x28/0x100 fs/super.c:1497 [] do_new_mount fs/namespace.c:2903 [inline] [] path_mount+0xc3e/0x1120 fs/namespace.c:3233 [] do_mount fs/namespace.c:3246 [inline] [] __do_sys_mount fs/namespace.c:3454 [inline] [] __se_sys_mount fs/namespace.c:3431 [inline] [] __x64_sys_mount+0x18e/0x1d0 fs/namespace.c:3431 [] do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 [] entry_SYSCALL_64_after_hwframe+0x44/0xae
Re: [PATCH] iommu/vt-d: Force to flush iotlb before creating superpage
Hi Longpeng, On 4/8/21 3:37 PM, Longpeng (Mike, Cloud Infrastructure Service Product Dept.) wrote: Hi Baolu, -Original Message- From: Lu Baolu [mailto:baolu...@linux.intel.com] Sent: Thursday, April 8, 2021 12:32 PM To: Longpeng (Mike, Cloud Infrastructure Service Product Dept.) ; io...@lists.linux-foundation.org; linux-kernel@vger.kernel.org Cc: baolu...@linux.intel.com; David Woodhouse ; Nadav Amit ; Alex Williamson ; Kevin Tian ; Gonglei (Arei) ; sta...@vger.kernel.org Subject: Re: [PATCH] iommu/vt-d: Force to flush iotlb before creating superpage Hi Longpeng, On 4/7/21 2:35 PM, Longpeng (Mike, Cloud Infrastructure Service Product Dept.) wrote: Hi Baolu, -Original Message- From: Lu Baolu [mailto:baolu...@linux.intel.com] Sent: Friday, April 2, 2021 12:44 PM To: Longpeng (Mike, Cloud Infrastructure Service Product Dept.) ; io...@lists.linux-foundation.org; linux-kernel@vger.kernel.org Cc: baolu...@linux.intel.com; David Woodhouse ; Nadav Amit ; Alex Williamson ; Kevin Tian ; Gonglei (Arei) ; sta...@vger.kernel.org Subject: Re: [PATCH] iommu/vt-d: Force to flush iotlb before creating superpage Hi Longpeng, On 4/1/21 3:18 PM, Longpeng(Mike) wrote: diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index ee09323..cbcb434 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2342,9 +2342,20 @@ static inline int hardware_largepage_caps(struct dmar_domain *domain, * removed to make room for superpage(s). * We're adding new large pages, so make sure * we don't remove their parent tables. +* +* We also need to flush the iotlb before creating +* superpage to ensure it does not perserves any +* obsolete info. */ - dma_pte_free_pagetable(domain, iov_pfn, end_pfn, - largepage_lvl + 1); + if (dma_pte_present(pte)) { The dma_pte_free_pagetable() clears a batch of PTEs. So checking current PTE is insufficient. How about removing this check and always performing cache invalidation? Um...the PTE here may be present( e.g. 4K mapping --> superpage mapping ) orNOT-present ( e.g. create a totally new superpage mapping ), but we only need to call free_pagetable and flush_iotlb in the former case, right ? But this code covers multiple PTEs and perhaps crosses the page boundary. How about moving this code into a separated function and check PTE presence there. A sample code could look like below: [compiled but not tested!] diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index d334f5b4e382..0e04d450c38a 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2300,6 +2300,41 @@ static inline int hardware_largepage_caps(struct dmar_domain *domain, return level; } +/* + * Ensure that old small page tables are removed to make room for superpage(s). + * We're going to add new large pages, so make sure we don't remove their parent + * tables. The IOTLB/devTLBs should be flushed if any PDE/PTEs are cleared. + */ +static void switch_to_super_page(struct dmar_domain *domain, +unsigned long start_pfn, +unsigned long end_pfn, int level) { Maybe "swith_to" will lead people to think "remove old and then setup new", so how about something like "remove_room_for_super_page" or "prepare_for_super_page" ? I named it like this because we also want to have a opposite operation split_from_super_page() which switch a PDE or PDPE from super page setting up to small pages, which is needed to optimize dirty bit tracking during VM live migration. + unsigned long lvl_pages = lvl_to_nr_pages(level); + struct dma_pte *pte = NULL; + int i; + + while (start_pfn <= end_pfn) { start_pfn < end_pfn ? end_pfn is inclusive. + if (!pte) + pte = pfn_to_dma_pte(domain, start_pfn, ); + + if (dma_pte_present(pte)) { + dma_pte_free_pagetable(domain, start_pfn, + start_pfn + lvl_pages - 1, + level + 1); + + for_each_domain_iommu(i, domain) + iommu_flush_iotlb_psi(g_iommus[i], domain, + start_pfn, lvl_pages, + 0, 0); + } + + pte++; + start_pfn += lvl_pages; + if (first_pte_in_page(pte)) + pte = NULL; + } +} + static int __domain_mapping(struct dmar_domain
Re: [PATCH v2 20/21] ipmi: kcs_bmc_aspeed: Fix IBFIE typo from datasheet
On Fri, Mar 19, 2021 at 01:27:51AM CDT, Andrew Jeffery wrote: >Input Buffer Full Interrupt Enable (IBFIE) is typoed as IBFIF for some >registers in the datasheet. Fix the driver to use the sensible acronym. > >Signed-off-by: Andrew Jeffery Reviewed-by: Zev Weiss
Re: [PATCH 1/6] PM: runtime: enable wake irq after runtime_suspend hook called
* Ikjoon Jang [210409 05:33]: > Hi Chunfeng, > > On Thu, Apr 8, 2021 at 5:35 PM Chunfeng Yun wrote: > > > > When the dedicated wake irq is level trigger, enable it before > > calling runtime_suspend, will trigger an interrupt. > > > > e.g. > > for a low level trigger type, it's low level at running time (0), > > and becomes high level when enters suspend (runtime_suspend (1) is > > called), a wakeup signal at (2) make it become low level, wake irq > > will be triggered. > > > > -- > >| ^ ^| > > | | -- > > |<---(0)--->|<--(1)--| (3) (2)(4) > > > > Can't we just use a falling edge type for this irq line? Sounds reasonable to me :) Tony
Re: [PATCH v2 00/21] ipmi: Allow raw access to KCS devices
On Fri, 9 Apr 2021, at 13:37, Joel Stanley wrote: > On Thu, 8 Apr 2021 at 23:47, Andrew Jeffery wrote: > > On Thu, 8 Apr 2021, at 21:44, Corey Minyard wrote: > > > On Thu, Apr 08, 2021 at 10:27:46AM +0930, Andrew Jeffery wrote: > > > > > > 1. It begins with patches 1-5 put together by Chia-Wei, which I've > > > > > rebased on v5.12-rc2. These fix the ASPEED LPC bindings and other > > > > > non-KCS LPC-related ASPEED device drivers in a way that enables the > > > > > SerIRQ patches at the end of the series. With Joel's review I'm hoping > > > > > these 5 can go through the aspeed tree, and that the rest can go > > > > > through > > > > > the IPMI tree. > > > > > > > > > > > Please review! > > > > > > > > Unfortunately the cover letter got detached from the rest of the series. > > > > > > > > Any chance you can take a look at the patches? > > > > > > There were some minor concerns that were unanswered, and there really > > > was no review by others for many of the patches. > > > > Right; I was planning to clean up the minor concerns once I'd received > > some more feedback. I could have done a better job of communicating > > that :) > > I'll merge the first five through the aspeed tree this coming merge > window. We have acks from the relevant maintainers. > > Arnd: would you prefer that this come as it's own pull request, or as > part of the device tree branch? > > Andrew, Corey: once I've got my pull requests out I'll look at > reviewing the rest of the series. Perhaps it would pay to re-send that > hunk of patches Andrew with the nits fixed? Yep; Zev has done some reviews for me so I'll address those, rebase on your tree once you've sent out the pull-req and send out a v3. Corey: Are you okay with that for now? Cheers, Andrew
Re: [PATCH 1/6] PM: runtime: enable wake irq after runtime_suspend hook called
* Chunfeng Yun [210409 01:54]: > On Thu, 2021-04-08 at 19:41 +0200, Rafael J. Wysocki wrote: > > On Thu, Apr 8, 2021 at 11:35 AM Chunfeng Yun > > wrote: > > > > > > When the dedicated wake irq is level trigger, enable it before > > > calling runtime_suspend, will trigger an interrupt. > > > > > > e.g. > > > for a low level trigger type, it's low level at running time (0), > > > and becomes high level when enters suspend (runtime_suspend (1) is > > > called), a wakeup signal at (2) make it become low level, wake irq > > > will be triggered. > > > > > > -- > > >| ^ ^| > > > | | -- > > > |<---(0)--->|<--(1)--| (3) (2)(4) > > > > > > if we enable the wake irq before calling runtime_suspend during (0), > > > an interrupt will arise, it causes resume immediately; > > > > But that's necessary to avoid missing a wakeup interrupt, isn't it? > That's also what I worry about. Yeah sounds like this patch will lead into missed wakeirqs. Regards, Tony
[PATCH] PCI: cadence: LTSSM Detect Quiet state minimum delay setting.
Adding a quirk flag "quirk_detect_quiet_flag" to program the minimum time that LTSSM waits on entering Detect.Quiet state. Setting this to 2ms for TI j721e SOC as a workaround to resolve a bug in IP. In future revisions this setting will not be required. As per PCIe specification, all Receivers must meet the Z-RX-DC specification for 2.5 GT/s within 1ms of entering Detect.Quiet LTSSM substate. The LTSSM must stay in this substate until the ZRXDC specification for 2.5 GT/s is met. 00 : 0us minimum wait time in Detect.Quiet state. 01 : 100us minimum wait time in Detect.Quiet state. 10 : 1ms minimum wait time in Detect.Quiet state. 11 : 2ms minimum wait time in Detect.Quiet state. Signed-off-by: Nadeem Athani --- drivers/pci/controller/cadence/pci-j721e.c | 6 ++ drivers/pci/controller/cadence/pcie-cadence-ep.c | 21 + drivers/pci/controller/cadence/pcie-cadence-host.c | 21 + drivers/pci/controller/cadence/pcie-cadence.h | 12 4 files changed, 60 insertions(+) diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index 35e61048e133..40ebe698e179 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -67,6 +67,7 @@ enum j721e_pcie_mode { struct j721e_pcie_data { enum j721e_pcie_modemode; bool quirk_retrain_flag; + bool quirk_detect_quiet_flag; }; static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset) @@ -284,10 +285,12 @@ static struct pci_ops cdns_ti_pcie_host_ops = { static const struct j721e_pcie_data j721e_pcie_rc_data = { .mode = PCI_MODE_RC, .quirk_retrain_flag = true, + .quirk_detect_quiet_flag = true, }; static const struct j721e_pcie_data j721e_pcie_ep_data = { .mode = PCI_MODE_EP, + .quirk_detect_quiet_flag = true, }; static const struct of_device_id of_j721e_pcie_match[] = { @@ -394,6 +397,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) bridge->ops = _ti_pcie_host_ops; rc = pci_host_bridge_priv(bridge); rc->quirk_retrain_flag = data->quirk_retrain_flag; + rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag; cdns_pcie = >pcie; cdns_pcie->dev = dev; @@ -460,6 +464,8 @@ static int j721e_pcie_probe(struct platform_device *pdev) goto err_get_sync; } + ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag; + cdns_pcie = >pcie; cdns_pcie->dev = dev; cdns_pcie->ops = _pcie_ops; diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c index 897cdde02bd8..245771f03c21 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c @@ -552,6 +552,23 @@ static const struct pci_epc_ops cdns_pcie_epc_ops = { .get_features = cdns_pcie_ep_get_features, }; +static void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie_ep *ep) +{ + struct cdns_pcie *pcie = >pcie; + u32 delay = 0x3; + u32 ltssm_control_cap; + + /* +* Set the LTSSM Detect Quiet state min. delay to 2ms. +*/ + + ltssm_control_cap = cdns_pcie_readl(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP); + ltssm_control_cap = ((ltssm_control_cap & + ~CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK) | + CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay)); + + cdns_pcie_writel(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP, ltssm_control_cap); +} int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep) { @@ -623,6 +640,10 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep) ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE; /* Reserve region 0 for IRQs */ set_bit(0, >ob_region_map); + + if (ep->quirk_detect_quiet_flag) + cdns_pcie_detect_quiet_min_delay_set(ep); + spin_lock_init(>lock); return 0; diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c index 73dcf8cf98fb..0ed2bfac4855 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-host.c +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c @@ -461,6 +461,24 @@ static int cdns_pcie_host_init(struct device *dev, return cdns_pcie_host_init_address_translation(rc); } +static void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie_rc *rc) +{ + struct cdns_pcie *pcie = >pcie; + u32 delay = 0x3; + u32 ltssm_control_cap; + + /* +* Set the LTSSM Detect Quiet state min. delay to 2ms. +*/ + + ltssm_control_cap = cdns_pcie_readl(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP); + ltssm_control_cap = ((ltssm_control_cap & +
[PATCH 1/1] drm/bridge: anx7625: send DPCD command to downstream
Send DPCD command to downstream before anx7625 power down, tell downstream into standby mode. Signed-off-by: Xin Ji --- drivers/gpu/drm/bridge/analogix/anx7625.c | 75 +++ 1 file changed, 75 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 65cc05982f82..53d2f0d0ee30 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -124,6 +124,23 @@ static int anx7625_reg_write(struct anx7625_data *ctx, return ret; } +static int anx7625_reg_block_write(struct anx7625_data *ctx, + struct i2c_client *client, + u8 reg_addr, u8 len, u8 *buf) +{ + int ret; + struct device *dev = >dev; + + i2c_access_workaround(ctx, client); + + ret = i2c_smbus_write_i2c_block_data(client, reg_addr, len, buf); + if (ret < 0) + DRM_DEV_ERROR(dev, "write i2c block failed id=%x\n:%x", + client->addr, reg_addr); + + return ret; +} + static int anx7625_write_or(struct anx7625_data *ctx, struct i2c_client *client, u8 offset, u8 mask) @@ -195,6 +212,55 @@ static int wait_aux_op_finish(struct anx7625_data *ctx) return val; } +static int anx7625_aux_dpcd_write(struct anx7625_data *ctx, + u8 addrh, u8 addrm, u8 addrl, + u8 len, u8 *buf) +{ + struct device *dev = >client->dev; + int ret; + u8 cmd; + + if (len > MAX_DPCD_BUFFER_SIZE) { + DRM_DEV_ERROR(dev, "exceed aux buffer len.\n"); + return -EINVAL; + } + + cmd = ((len - 1) << 4) | 0x08; + + /* Set command and length */ + ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, + AP_AUX_COMMAND, cmd); + + /* Set aux access address */ + ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, +AP_AUX_ADDR_7_0, addrl); + ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, +AP_AUX_ADDR_15_8, addrm); + ret |= anx7625_write_and(ctx, ctx->i2c.rx_p0_client, +AP_AUX_ADDR_19_16, addrh); + + /* Set write data */ + ret |= anx7625_reg_block_write(ctx, ctx->i2c.rx_p0_client, + AP_AUX_BUFF_START, len, buf); + /* Enable aux access */ + ret |= anx7625_write_or(ctx, ctx->i2c.rx_p0_client, + AP_AUX_CTRL_STATUS, AP_AUX_CTRL_OP_EN); + if (ret < 0) { + DRM_DEV_ERROR(dev, "cannot access aux related register.\n"); + return -EIO; + } + + usleep_range(2000, 2100); + + ret = wait_aux_op_finish(ctx); + if (ret) { + DRM_DEV_ERROR(dev, "aux IO error: wait aux op finish.\n"); + return ret; + } + + return 0; +} + static int anx7625_video_mute_control(struct anx7625_data *ctx, u8 status) { @@ -617,6 +683,7 @@ static void anx7625_dp_stop(struct anx7625_data *ctx) { struct device *dev = >client->dev; int ret; + u8 data; DRM_DEV_DEBUG_DRIVER(dev, "stop dp output\n"); @@ -628,8 +695,16 @@ static void anx7625_dp_stop(struct anx7625_data *ctx) ret |= anx7625_write_and(ctx, ctx->i2c.tx_p2_client, 0x08, 0x7f); ret |= anx7625_video_mute_control(ctx, 1); + + DRM_DEV_DEBUG_DRIVER(dev, "notify downstream enter into standby\n"); + + /* Downstream monitor enter into standby mode */ + data = 2; + ret |= anx7625_aux_dpcd_write(ctx, 0x00, 0x06, 0x00, 1, ); if (ret < 0) DRM_DEV_ERROR(dev, "IO error : mute video fail\n"); + + return; } static int sp_tx_rst_aux(struct anx7625_data *ctx) -- 2.25.1
Re: [next] drivers/cdrom/gdrom.c:586:61: error: 'rq' undeclared (first use in this function)
Naresh, On 4/8/21 22:31, Chaitanya Kulkarni wrote: > On 4/8/21 22:21, Naresh Kamboju wrote: >> Linux next tag 20210408 architecture sh builds failed due to these errors. >> >> # to reproduce this build locally: >> >> make --silent --keep-going --jobs=8 >> O=/home/tuxbuild/.cache/tuxmake/builds/1/tmp ARCH=sh >> CROSS_COMPILE=sh4-linux-gnu- 'CC=sccache sh4-linux-gnu-gcc' >> 'HOSTCC=sccache gcc' >> >> >> In file included from /builds/linux/include/linux/scatterlist.h:9, >> from /builds/linux/include/linux/dma-mapping.h:10, >> from /builds/linux/drivers/cdrom/gdrom.c:16: >> /builds/linux/drivers/cdrom/gdrom.c: In function 'gdrom_readdisk_dma': >> /builds/linux/drivers/cdrom/gdrom.c:586:61: error: 'rq' undeclared >> (first use in this function) >> 586 | __raw_writel(page_to_phys(bio_page(req->bio)) + bio_offset(rq->bio), >> | ^~ >> >> Reported-by: Naresh Kamboju >> >> Regressions found on sh: >> - build/gcc-9-dreamcast_defconfig >> - build/gcc-10-dreamcast_defconfig >> - build/gcc-8-dreamcast_defconfig >> >> -- >> Linaro LKFT >> https://lkft.linaro.org >> You can try following fix and see if the error goes away. > This can be fixed by following :- > > diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c > index e7717d090868..742b4a0932e3 100644 > --- a/drivers/cdrom/gdrom.c > +++ b/drivers/cdrom/gdrom.c > @@ -583,7 +583,7 @@ static blk_status_t gdrom_readdisk_dma(struct > request *req) > read_command->cmd[1] = 0x20; > block = blk_rq_pos(req)/GD_TO_BLK + GD_SESSION_OFFSET; > block_cnt = blk_rq_sectors(req)/GD_TO_BLK; > - __raw_writel(page_to_phys(bio_page(req->bio)) + bio_offset(rq->bio), > + __raw_writel(page_to_phys(bio_page(req->bio)) + > bio_offset(req->bio), > GDROM_DMA_STARTADDR_REG); > __raw_writel(block_cnt * GDROM_HARD_SECTOR, GDROM_DMA_LENGTH_REG); > __raw_writel(1, GDROM_DMA_DIRECTION_REG); >
[PATCH 13/14] phy: cadence-torrent: Add debug information for PHY configuration
Display information in probe regarding PHY configuration parameters like single link or multilink protocol information along with number of lanes used for each protocol link. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 32 +-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index bf37569c6c51..39145e56e061 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -574,6 +574,24 @@ static const struct coefficients vltg_coeff[4][4] = { } }; +static const char *cdns_torrent_get_phy_type(enum cdns_torrent_phy_type phy_type) +{ + switch (phy_type) { + case TYPE_DP: + return "DisplayPort"; + case TYPE_PCIE: + return "PCIe"; + case TYPE_SGMII: + return "SGMII"; + case TYPE_QSGMII: + return "QSGMII"; + case TYPE_USB: + return "USB"; + default: + return "None"; + } +} + /* * Set registers responsible for enabling and configuring SSC, with second and * third register values provided by parameters. @@ -2504,8 +2522,7 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev) init_dp_regmap++; } - dev_info(dev, "%d lanes, max bit rate %d.%03d Gbps\n", -cdns_phy->phys[node].num_lanes, + dev_info(dev, "DP max bit rate %d.%03d Gbps\n", cdns_phy->max_bit_rate / 1000, cdns_phy->max_bit_rate % 1000); @@ -2539,6 +2556,17 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev) goto put_lnk_rst; } + if (cdns_phy->nsubnodes > 1) + dev_info(dev, "%s (%d lanes) & %s (%d lanes)", +cdns_torrent_get_phy_type(cdns_phy->phys[0].phy_type), +cdns_phy->phys[0].num_lanes, +cdns_torrent_get_phy_type(cdns_phy->phys[1].phy_type), +cdns_phy->phys[1].num_lanes); + else + dev_info(dev, "%s (%d lanes)", +cdns_torrent_get_phy_type(cdns_phy->phys[0].phy_type), +cdns_phy->phys[0].num_lanes); + return 0; put_child: -- 2.26.1
[PATCH 11/14] phy: cadence-torrent: Add multilink DP support
Add multilink support for DP. This needs changes in functions configuring default single link DP with master lane 0 to support non-zero master lane values and associated PLL configurations. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 498 +- 1 file changed, 289 insertions(+), 209 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 44e28ea8ffa7..becbf8456b2d 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -62,16 +62,11 @@ */ #define PHY_AUX_CTRL 0x04 #define PHY_RESET 0x20 -#define PMA_TX_ELEC_IDLE_MASK 0xF0U #define PMA_TX_ELEC_IDLE_SHIFT 4 -#define PHY_L00_RESET_N_MASK 0x01U #define PHY_PMA_XCVR_PLLCLK_EN 0x24 #define PHY_PMA_XCVR_PLLCLK_EN_ACK 0x28 #define PHY_PMA_XCVR_POWER_STATE_REQ 0x2c -#define PHY_POWER_STATE_LN_0 0x -#define PHY_POWER_STATE_LN_1 0x0008 -#define PHY_POWER_STATE_LN_2 0x0010 -#define PHY_POWER_STATE_LN_3 0x0018 +#define PHY_POWER_STATE_LN(ln) ((ln) * 8) #define PMA_XCVR_POWER_STATE_REQ_LN_MASK 0x3FU #define PHY_PMA_XCVR_POWER_STATE_ACK 0x30 #define PHY_PMA_CMN_READY 0x34 @@ -834,74 +829,90 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_100mhz(struct cdns_torrent_phy *cdns_phy, /* Setting VCO for 10.8GHz */ case 2700: case 5400: - cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0028); - cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_FBH_OVRD_M0, 0x0022); - cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBH_OVRD_M0, 0x0022); - cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBL_OVRD_M0, 0x000C); + if (cdns_phy->dp_pll & DP_PLL0) + cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_FBH_OVRD_M0, 0x0022); + + if (cdns_phy->dp_pll & DP_PLL1) { + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0028); + cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBH_OVRD_M0, 0x0022); + cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBL_OVRD_M0, 0x000C); + } break; /* Setting VCO for 9.72GHz */ case 1620: case 2430: case 3240: - cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004); - cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004); - cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509); - cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509); - cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00); - cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00); - cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08); - cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08); - cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0061); - cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0061); - cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x); - cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x); - cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); - cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); - cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0042); - cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0042); - cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002); - cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002); + if (cdns_phy->dp_pll & DP_PLL0) { + cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08); + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0061); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0042); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002); + } + if (cdns_phy->dp_pll & DP_PLL1) { + cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509); +
[PATCH 04/14] phy: cadence-torrent: Select register configuration based on PHY reference clock
Add PHY input reference clock frequency as a new dimension to select proper register configuration. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 830 +++--- 1 file changed, 422 insertions(+), 408 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 252920ea7fdf..39a26a1a4c51 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -375,12 +375,12 @@ struct cdns_torrent_data { [NUM_SSC_MODE]; struct cdns_torrent_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] [NUM_SSC_MODE]; - struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] - [NUM_SSC_MODE]; - struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] - [NUM_SSC_MODE]; - struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] - [NUM_SSC_MODE]; + struct cdns_torrent_vals *cmn_vals[NUM_REF_CLK][NUM_PHY_TYPE] + [NUM_PHY_TYPE][NUM_SSC_MODE]; + struct cdns_torrent_vals *tx_ln_vals[NUM_REF_CLK][NUM_PHY_TYPE] + [NUM_PHY_TYPE][NUM_SSC_MODE]; + struct cdns_torrent_vals *rx_ln_vals[NUM_REF_CLK][NUM_PHY_TYPE] + [NUM_PHY_TYPE][NUM_SSC_MODE]; }; struct cdns_regmap_cdb_context { @@ -1958,6 +1958,7 @@ static int cdns_torrent_phy_init(struct phy *phy) struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); const struct cdns_torrent_data *init_data = cdns_phy->init_data; struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals; + enum cdns_torrent_ref_clk ref_clk = cdns_phy->ref_clk_rate; struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals; struct cdns_torrent_inst *inst = phy_get_drvdata(phy); enum cdns_torrent_phy_type phy_type = inst->phy_type; @@ -2023,7 +2024,7 @@ static int cdns_torrent_phy_init(struct phy *phy) } /* PMA common registers configurations */ - cmn_vals = init_data->cmn_vals[phy_type][TYPE_NONE][ssc]; + cmn_vals = init_data->cmn_vals[ref_clk][phy_type][TYPE_NONE][ssc]; if (cmn_vals) { reg_pairs = cmn_vals->reg_pairs; num_regs = cmn_vals->num_regs; @@ -2034,7 +2035,7 @@ static int cdns_torrent_phy_init(struct phy *phy) } /* PMA TX lane registers configurations */ - tx_ln_vals = init_data->tx_ln_vals[phy_type][TYPE_NONE][ssc]; + tx_ln_vals = init_data->tx_ln_vals[ref_clk][phy_type][TYPE_NONE][ssc]; if (tx_ln_vals) { reg_pairs = tx_ln_vals->reg_pairs; num_regs = tx_ln_vals->num_regs; @@ -2047,7 +2048,7 @@ static int cdns_torrent_phy_init(struct phy *phy) } /* PMA RX lane registers configurations */ - rx_ln_vals = init_data->rx_ln_vals[phy_type][TYPE_NONE][ssc]; + rx_ln_vals = init_data->rx_ln_vals[ref_clk][phy_type][TYPE_NONE][ssc]; if (rx_ln_vals) { reg_pairs = rx_ln_vals->reg_pairs; num_regs = rx_ln_vals->num_regs; @@ -2088,6 +2089,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy) { const struct cdns_torrent_data *init_data = cdns_phy->init_data; struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals; + enum cdns_torrent_ref_clk ref_clk = cdns_phy->ref_clk_rate; struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals; enum cdns_torrent_phy_type phy_t1, phy_t2, tmp_phy_type; struct cdns_torrent_vals *pcs_cmn_vals; @@ -2176,7 +2178,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy) } /* PMA common registers configurations */ - cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc]; + cmn_vals = init_data->cmn_vals[ref_clk][phy_t1][phy_t2][ssc]; if (cmn_vals) { reg_pairs = cmn_vals->reg_pairs; num_regs = cmn_vals->num_regs; @@ -2187,7 +2189,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy) } /* PMA TX lane registers configurations */ - tx_ln_vals = init_data->tx_ln_vals[phy_t1][phy_t2][ssc]; + tx_ln_vals = init_data->tx_ln_vals[ref_clk][phy_t1][phy_t2][ssc]; if (tx_ln_vals) { reg_pairs = tx_ln_vals->reg_pairs; num_regs = tx_ln_vals->num_regs; @@ -2200,7 +2202,7 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy) } /* PMA RX lane registers
[PATCH 05/14] phy: cadence-torrent: Add PHY registers for DP in array format
Add PHY registers for single link DP in array format to simplify code and to improve readability. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 450 +- 1 file changed, 274 insertions(+), 176 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 39a26a1a4c51..4ec5909f192c 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -341,20 +341,12 @@ struct cdns_torrent_derived_refclk { #define to_cdns_torrent_derived_refclk(_hw)\ container_of(_hw, struct cdns_torrent_derived_refclk, hw) -static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy, - struct cdns_torrent_inst *inst); -static -void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy); static void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy, u32 rate, bool ssc); static -void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy); -static void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy, u32 rate, bool ssc); -static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy, -unsigned int lane); struct cdns_reg_pairs { u32 val; @@ -759,9 +751,6 @@ static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy, unsigned int hsclk_div_val = 0; unsigned int i; - /* 16'h for single DP link configuration */ - regmap_field_write(cdns_phy->phy_pll_cfg, 0x0); - switch (rate) { case 1620: clk_sel_val = 0x0f01; @@ -806,8 +795,7 @@ static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy, static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy, struct phy_configure_opts_dp *dp) { - u32 ret; - u32 read_val; + u32 read_val, ret; /* Disable the cmn_pll0_en before re-programming the new data rate. */ regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x0); @@ -825,17 +813,12 @@ static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy, ndelay(200); /* DP Rate Change - VCO Output settings. */ - if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) { + if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) /* PMA common configuration 19.2MHz */ - cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate, - dp->ssc); - cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy); - } else if (cdns_phy->ref_clk_rate == CLK_25_MHZ) { + cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate, dp->ssc); + else if (cdns_phy->ref_clk_rate == CLK_25_MHZ) /* PMA common configuration 25MHz */ - cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate, - dp->ssc); - cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy); - } + cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate, dp->ssc); cdns_torrent_dp_pma_cmn_rate(cdns_phy, dp->link_rate, dp->lanes); /* Enable the cmn_pll0_en. */ @@ -1184,9 +1167,6 @@ static int cdns_torrent_dp_init(struct phy *phy) cdns_torrent_dp_write(regmap, PHY_AUX_CTRL, 0x0003); /* enable AUX */ - /* PHY PMA registers configuration function */ - cdns_torrent_dp_pma_cfg(cdns_phy, inst); - /* * Set lines power state to A0 * Set lines pll clk enable to 0 @@ -1231,67 +1211,6 @@ static int cdns_torrent_dp_init(struct phy *phy) return ret; } -static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy, - struct cdns_torrent_inst *inst) -{ - unsigned int i; - - if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) - /* PMA common configuration 19.2MHz */ - cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy); - else if (cdns_phy->ref_clk_rate == CLK_25_MHZ) - /* PMA common configuration 25MHz */ - cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy); - - /* PMA lane configuration to deal with multi-link operation */ - for (i = 0; i < inst->num_lanes; i++) - cdns_torrent_dp_pma_lane_cfg(cdns_phy, i); -} - -static -void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy) -{ - struct regmap *regmap = cdns_phy->regmap_common_cdb; - - /* refclock registers - assumes 19.2 MHz refclock */ - cdns_torrent_phy_write(regmap, CMN_SSM_BIAS_TMR, 0x0014); - cdns_torrent_phy_write(regmap,
[PATCH 14/14] phy: cadence-torrent: Check PIPE mode PHY status to be ready for operation
PIPE PHY status is used to communicate the completion of several PHY functions. Check if PHY is ready for operation while configured for PIPE mode during startup. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 60 +++ 1 file changed, 60 insertions(+) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 39145e56e061..42a1bdfd18d5 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -51,6 +51,10 @@ #define TORRENT_PHY_PCS_COMMON_OFFSET(block_offset)\ (0xC000 << (block_offset)) +#define TORRENT_PHY_PCS_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \ + ((0xD000 << (block_offset)) + \ + (((ln) << 9) << (reg_offset))) + #define TORRENT_PHY_PMA_COMMON_OFFSET(block_offset)\ (0xE000 << (block_offset)) @@ -218,6 +222,9 @@ #define PHY_PIPE_USB3_GEN2_POST_CFG0 0x0022U #define PHY_PIPE_USB3_GEN2_POST_CFG1 0x0023U +/* PHY PCS lane registers */ +#define PHY_PCS_ISO_LINK_CTRL 0x000BU + /* PHY PMA common registers */ #define PHY_PMA_CMN_CTRL1 0xU #define PHY_PMA_CMN_CTRL2 0x0001U @@ -242,6 +249,9 @@ static const struct reg_field phy_pma_pll_raw_ctrl = static const struct reg_field phy_reset_ctrl = REG_FIELD(PHY_RESET, 8, 8); +static const struct reg_field phy_pcs_iso_link_ctrl_1 = + REG_FIELD(PHY_PCS_ISO_LINK_CTRL, 1, 1); + static const struct reg_field phy_pipe_cmn_ctrl1_0 = REG_FIELD(PHY_PIPE_CMN_CTRL1, 0, 0); #define REFCLK_OUT_NUM_CMN_CONFIG 5 @@ -316,12 +326,14 @@ struct cdns_torrent_phy { struct regmap *regmap_phy_pma_common_cdb; struct regmap *regmap_tx_lane_cdb[MAX_NUM_LANES]; struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES]; + struct regmap *regmap_phy_pcs_lane_cdb[MAX_NUM_LANES]; struct regmap *regmap_dptx_phy_reg; struct regmap_field *phy_pll_cfg; struct regmap_field *phy_pma_cmn_ctrl_1; struct regmap_field *phy_pma_cmn_ctrl_2; struct regmap_field *phy_pma_pll_raw_ctrl; struct regmap_field *phy_reset_ctrl; + struct regmap_field *phy_pcs_iso_link_ctrl_1[MAX_NUM_LANES]; struct clk *clks[CDNS_TORRENT_REFCLK_DRIVER + 1]; struct clk_onecell_data clk_data; }; @@ -456,6 +468,22 @@ static const struct regmap_config cdns_torrent_common_cdb_config = { .reg_read = cdns_regmap_read, }; +#define TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF(n) \ +{ \ + .name = "torrent_phy_pcs_lane" n "_cdb", \ + .reg_stride = 1, \ + .fast_io = true, \ + .reg_write = cdns_regmap_write, \ + .reg_read = cdns_regmap_read, \ +} + +static const struct regmap_config cdns_torrent_phy_pcs_lane_cdb_config[] = { + TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("0"), + TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("1"), + TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("2"), + TORRENT_PHY_PCS_LANE_CDB_REGMAP_CONF("3"), +}; + static const struct regmap_config cdns_torrent_phy_pcs_cmn_cdb_config = { .name = "torrent_phy_pcs_cmn_cdb", .reg_stride = 1, @@ -1546,6 +1574,16 @@ static int cdns_torrent_phy_on(struct phy *phy) return ret; } + if (inst->phy_type == TYPE_PCIE || inst->phy_type == TYPE_USB) { + ret = regmap_field_read_poll_timeout(cdns_phy->phy_pcs_iso_link_ctrl_1[inst->mlane], +read_val, !read_val, 1000, +PLL_LOCK_TIMEOUT); + if (ret == -ETIMEDOUT) { + dev_err(cdns_phy->dev, "Timeout waiting for PHY status ready\n"); + return ret; + } + } + mdelay(10); return 0; @@ -1822,6 +1860,7 @@ static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy) struct device *dev = cdns_phy->dev; struct regmap_field *field; struct regmap *regmap; + int i; regmap = cdns_phy->regmap_phy_pcs_common_cdb; field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg); @@ -1855,6 +1894,16 @@ static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy) } cdns_phy->phy_pma_pll_raw_ctrl = field; + for (i = 0; i < MAX_NUM_LANES; i++) { + regmap = cdns_phy->regmap_phy_pcs_lane_cdb[i]; + field = devm_regmap_field_alloc(dev, regmap, phy_pcs_iso_link_ctrl_1); + if (IS_ERR(field)) { + dev_err(dev, "PHY_PCS_ISO_LINK_CTRL reg field init for ln %d failed\n", i); + return PTR_ERR(field); + } + cdns_phy->phy_pcs_iso_link_ctrl_1[i] = field; + } +
[PATCH 03/14] phy: cadence-torrent: Add enum to support different input reference clocks
Torrent PHY supports different input reference clock frequencies. Register configurations will be different based on reference clock value. Prepare driver to support register configs for multiple reference clocks. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 51 +-- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 6eeb753fbb78..252920ea7fdf 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -26,11 +26,13 @@ #define REF_CLK_19_2MHZ1920 #define REF_CLK_25MHZ 2500 +#define REF_CLK_100MHZ 1 #define MAX_NUM_LANES 4 #define DEFAULT_MAX_BIT_RATE 8100 /* in Mbps */ #define NUM_SSC_MODE 3 +#define NUM_REF_CLK3 #define NUM_PHY_TYPE 6 #define POLL_TIMEOUT_US5000 @@ -273,6 +275,12 @@ enum cdns_torrent_phy_type { TYPE_USB, }; +enum cdns_torrent_ref_clk { + CLK_19_2_MHZ, + CLK_25_MHZ, + CLK_100_MHZ +}; + enum cdns_torrent_ssc_mode { NO_SSC, EXTERNAL_SSC, @@ -296,7 +304,7 @@ struct cdns_torrent_phy { struct reset_control *apb_rst; struct device *dev; struct clk *clk; - unsigned long ref_clk_rate; + enum cdns_torrent_ref_clk ref_clk_rate; struct cdns_torrent_inst phys[MAX_NUM_LANES]; int nsubnodes; const struct cdns_torrent_data *init_data; @@ -817,12 +825,12 @@ static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy, ndelay(200); /* DP Rate Change - VCO Output settings. */ - if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) { + if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) { /* PMA common configuration 19.2MHz */ cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate, dp->ssc); cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy); - } else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) { + } else if (cdns_phy->ref_clk_rate == CLK_25_MHZ) { /* PMA common configuration 25MHz */ cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate, dp->ssc); @@ -1165,8 +1173,8 @@ static int cdns_torrent_dp_init(struct phy *phy) struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; switch (cdns_phy->ref_clk_rate) { - case REF_CLK_19_2MHZ: - case REF_CLK_25MHZ: + case CLK_19_2_MHZ: + case CLK_25_MHZ: /* Valid Ref Clock Rate */ break; default: @@ -1198,11 +1206,11 @@ static int cdns_torrent_dp_init(struct phy *phy) /* PHY PMA registers configuration functions */ /* Initialize PHY with max supported link rate, without SSC. */ - if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) + if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, cdns_phy->max_bit_rate, false); - else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) + else if (cdns_phy->ref_clk_rate == CLK_25_MHZ) cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, cdns_phy->max_bit_rate, false); @@ -1228,10 +1236,10 @@ static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy, { unsigned int i; - if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) + if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) /* PMA common configuration 19.2MHz */ cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy); - else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) + else if (cdns_phy->ref_clk_rate == CLK_25_MHZ) /* PMA common configuration 25MHz */ cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy); @@ -1636,10 +1644,10 @@ static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy, unsigned int lane) { /* Per lane, refclock-dependent receiver detection setting */ - if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) + if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], TX_RCVDET_ST_TMR, 0x0780); - else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) + else if (cdns_phy->ref_clk_rate == CLK_25_MHZ) cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], TX_RCVDET_ST_TMR, 0x09C4); @@ -2270,6
[PATCH 06/14] phy: cadence-torrent: Reorder functions to avoid function declarations
Reorder some functions to avoid function declarations. Also, remove unnecessary line breaks while moving. No functional change. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 305 +- 1 file changed, 121 insertions(+), 184 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 4ec5909f192c..396c3810a69d 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -342,9 +342,6 @@ struct cdns_torrent_derived_refclk { container_of(_hw, struct cdns_torrent_derived_refclk, hw) static -void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy, -u32 rate, bool ssc); -static void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy, u32 rate, bool ssc); @@ -579,6 +576,127 @@ static const struct coefficients vltg_coeff[4][4] = { } }; +/* + * Set registers responsible for enabling and configuring SSC, with second and + * third register values provided by parameters. + */ +static +void cdns_torrent_dp_enable_ssc_19_2mhz(struct cdns_torrent_phy *cdns_phy, + u32 ctrl2_val, u32 ctrl3_val) +{ + struct regmap *regmap = cdns_phy->regmap_common_cdb; + + cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001); + cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val); + cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl3_val); + cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003); + cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001); + cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val); + cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl3_val); + cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003); +} + +static +void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy, +u32 rate, bool ssc) +{ + struct regmap *regmap = cdns_phy->regmap_common_cdb; + + /* Assumes 19.2 MHz refclock */ + switch (rate) { + /* Setting VCO for 10.8GHz */ + case 2700: + case 5400: + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0119); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x4000); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00BC); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0012); + cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0119); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x4000); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00BC); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0012); + if (ssc) + cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x033A, 0x006A); + break; + /* Setting VCO for 9.72GHz */ + case 1620: + case 2430: + case 3240: + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01FA); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x4000); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0152); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01FA); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x4000); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0152); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002); + if (ssc) + cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x05DD, 0x0069); + break; + /* Setting VCO for 8.64GHz */ + case 2160: + case 4320: + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01C2); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x012C); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01C2); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); +
[PATCH 07/14] phy: cadence-torrent: Reorder functions to avoid function declarations
Reorder some functions to avoid function declarations. No functional change. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 250 +++--- 1 file changed, 123 insertions(+), 127 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 396c3810a69d..a6331927d775 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -341,10 +341,6 @@ struct cdns_torrent_derived_refclk { #define to_cdns_torrent_derived_refclk(_hw)\ container_of(_hw, struct cdns_torrent_derived_refclk, hw) -static -void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy, - u32 rate, bool ssc); - struct cdns_reg_pairs { u32 val; u32 off; @@ -697,6 +693,129 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy, cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x0099); } +/* + * Set registers responsible for enabling and configuring SSC, with second + * register value provided by a parameter. + */ +static void cdns_torrent_dp_enable_ssc_25mhz(struct cdns_torrent_phy *cdns_phy, +u32 ctrl2_val) +{ + struct regmap *regmap = cdns_phy->regmap_common_cdb; + + cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001); + cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val); + cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x007F); + cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003); + cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001); + cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val); + cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x007F); + cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003); +} + +static +void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy, + u32 rate, bool ssc) +{ + struct regmap *regmap = cdns_phy->regmap_common_cdb; + + /* Assumes 25 MHz refclock */ + switch (rate) { + /* Setting VCO for 10.8GHz */ + case 2700: + case 5400: + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01B0); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0120); + cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01B0); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0120); + if (ssc) + cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x0423); + break; + /* Setting VCO for 9.72GHz */ + case 1620: + case 2430: + case 3240: + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0184); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0xCCCD); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0104); + cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0184); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0xCCCD); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0104); + if (ssc) + cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x03B9); + break; + /* Setting VCO for 8.64GHz */ + case 2160: + case 4320: + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0159); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x999A); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00E7); + cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0159); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x999A); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00E7); + if (ssc) + cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x034F); + break; + /* Setting VCO for 8.1GHz */ + case 8100: + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0144); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap,
[PATCH 02/14] phy: cadence-torrent: Reorder few functions to remove function declarations
Reorder some functions to avoid function declarations. No functional change. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 474 +++--- 1 file changed, 229 insertions(+), 245 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index ff647669f1a3..6eeb753fbb78 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -333,12 +333,6 @@ struct cdns_torrent_derived_refclk { #define to_cdns_torrent_derived_refclk(_hw)\ container_of(_hw, struct cdns_torrent_derived_refclk, hw) -static int cdns_torrent_phy_init(struct phy *phy); -static int cdns_torrent_dp_init(struct phy *phy); -static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, - u32 num_lanes); -static -int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy); static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy, struct cdns_torrent_inst *inst); static @@ -353,36 +347,6 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy, u32 rate, bool ssc); static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy, unsigned int lane); -static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy, -u32 rate, u32 num_lanes); -static int cdns_torrent_dp_configure(struct phy *phy, -union phy_configure_opts *opts); -static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy, - u32 num_lanes, - enum phy_powerstate powerstate); -static int cdns_torrent_phy_on(struct phy *phy); -static int cdns_torrent_phy_off(struct phy *phy); - -static const struct phy_ops cdns_torrent_phy_ops = { - .init = cdns_torrent_phy_init, - .configure = cdns_torrent_dp_configure, - .power_on = cdns_torrent_phy_on, - .power_off = cdns_torrent_phy_off, - .owner = THIS_MODULE, -}; - -static int cdns_torrent_noop_phy_on(struct phy *phy) -{ - /* Give 5ms to 10ms delay for the PIPE clock to be stable */ - usleep_range(5000, 1); - - return 0; -} - -static const struct phy_ops noop_ops = { - .power_on = cdns_torrent_noop_phy_on, - .owner = THIS_MODULE, -}; struct cdns_reg_pairs { u32 val; @@ -669,6 +633,164 @@ static int cdns_torrent_dp_set_pll_en(struct cdns_torrent_phy *cdns_phy, return ret; } +static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy, + u32 num_lanes, + enum phy_powerstate powerstate) +{ + /* Register value for power state for a single byte. */ + u32 value_part; + u32 value; + u32 mask; + u32 read_val; + u32 ret; + struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; + + switch (powerstate) { + case (POWERSTATE_A0): + value_part = 0x01U; + break; + case (POWERSTATE_A2): + value_part = 0x04U; + break; + default: + /* Powerstate A3 */ + value_part = 0x08U; + break; + } + + /* Select values of registers and mask, depending on enabled +* lane count. +*/ + switch (num_lanes) { + /* lane 0 */ + case (1): + value = value_part; + mask = 0x003FU; + break; + /* lanes 0-1 */ + case (2): + value = (value_part +| (value_part << 8)); + mask = 0x3F3FU; + break; + /* lanes 0-3, all */ + default: + value = (value_part +| (value_part << 8) +| (value_part << 16) +| (value_part << 24)); + mask = 0x3F3F3F3FU; + break; + } + + /* Set power state A. */ + cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, value); + /* Wait, until PHY acknowledges power state completion. */ + ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_POWER_STATE_ACK, + read_val, (read_val & mask) == value, 0, + POLL_TIMEOUT_US); + cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, 0x); + ndelay(100); + + return ret; +} + +static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, u32 num_lanes) +{ + unsigned int read_val; + int ret; + struct regmap *regmap =
[PATCH 00/14] PHY: Add multilink DP support in Cadence Torrent PHY driver
This patch series enables Torrent PHY driver to support different input reference clock frequencies. It also adds support for multilink multiprotocol DisplayPort configuration. Currently, PCIe + DP multilink register sequences are added. Swapnil Jakhade (14): phy: cadence-torrent: Remove use of CamelCase to fix checkpatch CHECK message phy: cadence-torrent: Reorder few functions to remove function declarations phy: cadence-torrent: Add enum to support different input reference clocks phy: cadence-torrent: Select register configuration based on PHY reference clock phy: cadence-torrent: Add PHY registers for DP in array format phy: cadence-torrent: Reorder functions to avoid function declarations phy: cadence-torrent: Reorder functions to avoid function declarations phy: cadence-torrent: Add PHY configuration for DP with 100MHz ref clock phy: cadence-torrent: Add separate functions for reusable code phy: cadence-torrent: Add function to get PLL to be configured for DP phy: cadence-torrent: Add multilink DP support phy: cadence-torrent: Add PCIe + DP multilink configuration phy: cadence-torrent: Add debug information for PHY configuration phy: cadence-torrent: Check PIPE mode PHY status to be ready for operation drivers/phy/cadence/phy-cadence-torrent.c | 3422 - 1 file changed, 1993 insertions(+), 1429 deletions(-) -- 2.26.1
[PATCH 08/14] phy: cadence-torrent: Add PHY configuration for DP with 100MHz ref clock
Add PHY configuration registers for DP with 100MHz ref clock and NO_SSC. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 162 ++ 1 file changed, 162 insertions(+) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index a6331927d775..69466481af26 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -103,6 +103,7 @@ #define CMN_PLL0_FRACDIVH_M0 0x0092U #define CMN_PLL0_HIGH_THR_M0 0x0093U #define CMN_PLL0_DSM_DIAG_M0 0x0094U +#define CMN_PLL0_DSM_FBH_OVRD_M0 0x0095U #define CMN_PLL0_SS_CTRL1_M0 0x0098U #define CMN_PLL0_SS_CTRL2_M00x0099U #define CMN_PLL0_SS_CTRL3_M00x009AU @@ -816,6 +817,89 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy, cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x00C7); } +static +void cdns_torrent_dp_pma_cmn_vco_cfg_100mhz(struct cdns_torrent_phy *cdns_phy, + u32 rate, bool ssc) +{ + struct regmap *regmap = cdns_phy->regmap_common_cdb; + + /* Assumes 100 MHz refclock */ + switch (rate) { + /* Setting VCO for 10.8GHz */ + case 2700: + case 5400: + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0028); + cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_FBH_OVRD_M0, 0x0022); + cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBH_OVRD_M0, 0x0022); + cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_FBL_OVRD_M0, 0x000C); + break; + /* Setting VCO for 9.72GHz */ + case 1620: + case 2430: + case 3240: + cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004); + cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08); + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0061); + cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0061); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0042); + cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0042); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002); + break; + /* Setting VCO for 8.64GHz */ + case 2160: + case 4320: + cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004); + cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08); + cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0056); + cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0056); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x); + cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x003A); + cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x003A); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002); + cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002); + break; + /* Setting VCO for 8.1GHz */ + case 8100: + cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004); + cdns_torrent_phy_write(regmap,
[PATCH 09/14] phy: cadence-torrent: Add separate functions for reusable code
Torrent PHY driver currently supports single link DP configuration. Prepare driver to support multilink DP configurations by adding separate functions for common initialization sequence. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 53 +++ 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 69466481af26..e4dd8d1711a6 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -1472,24 +1472,11 @@ static int cdns_torrent_phy_off(struct phy *phy) return reset_control_assert(inst->lnk_rst); } -static int cdns_torrent_dp_init(struct phy *phy) +static void cdns_torrent_dp_common_init(struct cdns_torrent_phy *cdns_phy, + struct cdns_torrent_inst *inst) { - unsigned char lane_bits; - int ret; - struct cdns_torrent_inst *inst = phy_get_drvdata(phy); - struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; - - switch (cdns_phy->ref_clk_rate) { - case CLK_19_2_MHZ: - case CLK_25_MHZ: - case CLK_100_MHZ: - /* Valid Ref Clock Rate */ - break; - default: - dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n"); - return -EINVAL; - } + unsigned char lane_bits; cdns_torrent_dp_write(regmap, PHY_AUX_CTRL, 0x0003); /* enable AUX */ @@ -1510,8 +1497,10 @@ static int cdns_torrent_dp_init(struct phy *phy) /* release pma_xcvr_pllclk_en_ln_*, only for the master lane */ cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001); - /* PHY PMA registers configuration functions */ - /* Initialize PHY with max supported link rate, without SSC. */ + /* +* PHY PMA registers configuration functions +* Initialize PHY with max supported link rate, without SSC. +*/ if (cdns_phy->ref_clk_rate == CLK_19_2_MHZ) cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, cdns_phy->max_bit_rate, @@ -1530,6 +1519,13 @@ static int cdns_torrent_dp_init(struct phy *phy) /* take out of reset */ regmap_field_write(cdns_phy->phy_reset_ctrl, 0x1); +} + +static int cdns_torrent_dp_start(struct cdns_torrent_phy *cdns_phy, +struct cdns_torrent_inst *inst, +struct phy *phy) +{ + int ret; cdns_torrent_phy_on(phy); @@ -1542,6 +1538,27 @@ static int cdns_torrent_dp_init(struct phy *phy) return ret; } +static int cdns_torrent_dp_init(struct phy *phy) +{ + struct cdns_torrent_inst *inst = phy_get_drvdata(phy); + struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); + + switch (cdns_phy->ref_clk_rate) { + case CLK_19_2_MHZ: + case CLK_25_MHZ: + case CLK_100_MHZ: + /* Valid Ref Clock Rate */ + break; + default: + dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n"); + return -EINVAL; + } + + cdns_torrent_dp_common_init(cdns_phy, inst); + + return cdns_torrent_dp_start(cdns_phy, inst, phy); +} + static int cdns_torrent_derived_refclk_enable(struct clk_hw *hw) { struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw); -- 2.26.1
[PATCH 10/14] phy: cadence-torrent: Add function to get PLL to be configured for DP
Torrent PHY PLL0 or PLL1 is used for DP depending on the single link or multilink protocol configuration for which PHY is configured. In multilink configurations with other protocols, either PLL0 or PLL1 will be used for DP. For single link DP, both PLLs need to be configured at POR. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 32 +++ 1 file changed, 32 insertions(+) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index e4dd8d1711a6..44e28ea8ffa7 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -288,6 +288,11 @@ enum cdns_torrent_ssc_mode { INTERNAL_SSC }; +enum cdns_torrent_dp_pll { + DP_PLL0 = 0x1, + DP_PLL1 = 0x2 +}; + struct cdns_torrent_inst { struct phy *phy; u32 mlane; @@ -301,6 +306,7 @@ struct cdns_torrent_phy { void __iomem *base; /* DPTX registers base */ void __iomem *sd_base; /* SD0801 registers base */ u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */ + u32 dp_pll; struct reset_control *phy_rst; struct reset_control *apb_rst; struct device *dev; @@ -900,6 +906,30 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_100mhz(struct cdns_torrent_phy *cdns_phy, } } +/* Set PLL used for DP configuration */ +static int cdns_torrent_dp_get_pll(struct cdns_torrent_phy *cdns_phy, + enum cdns_torrent_phy_type phy_t2) +{ + switch (phy_t2) { + case TYPE_PCIE: + case TYPE_USB: + cdns_phy->dp_pll = DP_PLL1; + break; + case TYPE_SGMII: + case TYPE_QSGMII: + cdns_phy->dp_pll = DP_PLL0; + break; + case TYPE_NONE: + cdns_phy->dp_pll = DP_PLL0 | DP_PLL1; + break; + default: + dev_err(cdns_phy->dev, "Unsupported PHY configuration\n"); + return -EINVAL; + } + + return 0; +} + /* * Enable or disable PLL for selected lanes. */ @@ -1554,6 +1584,8 @@ static int cdns_torrent_dp_init(struct phy *phy) return -EINVAL; } + cdns_torrent_dp_get_pll(cdns_phy, TYPE_NONE); + cdns_torrent_dp_common_init(cdns_phy, inst); return cdns_torrent_dp_start(cdns_phy, inst, phy); -- 2.26.1
[PATCH 12/14] phy: cadence-torrent: Add PCIe + DP multilink configuration
Add PCIe + DP no SSC multilink configuration sequences. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 131 ++ 1 file changed, 131 insertions(+) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index becbf8456b2d..bf37569c6c51 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -2572,6 +2572,77 @@ static int cdns_torrent_phy_remove(struct platform_device *pdev) return 0; } +/* PCIe and DP link configuration */ +static struct cdns_reg_pairs pcie_dp_link_cmn_regs[] = { + {0x0003, PHY_PLL_CFG}, + {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0}, + {0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1} +}; + +static struct cdns_reg_pairs pcie_dp_xcvr_diag_ln_regs[] = { + {0x, XCVR_DIAG_HSCLK_SEL}, + {0x0001, XCVR_DIAG_HSCLK_DIV}, + {0x0012, XCVR_DIAG_PLLDRC_CTRL} +}; + +static struct cdns_reg_pairs dp_pcie_xcvr_diag_ln_regs[] = { + {0x0001, XCVR_DIAG_HSCLK_SEL}, + {0x0009, XCVR_DIAG_PLLDRC_CTRL} +}; + +static struct cdns_torrent_vals pcie_dp_link_cmn_vals = { + .reg_pairs = pcie_dp_link_cmn_regs, + .num_regs = ARRAY_SIZE(pcie_dp_link_cmn_regs), +}; + +static struct cdns_torrent_vals pcie_dp_xcvr_diag_ln_vals = { + .reg_pairs = pcie_dp_xcvr_diag_ln_regs, + .num_regs = ARRAY_SIZE(pcie_dp_xcvr_diag_ln_regs), +}; + +static struct cdns_torrent_vals dp_pcie_xcvr_diag_ln_vals = { + .reg_pairs = dp_pcie_xcvr_diag_ln_regs, + .num_regs = ARRAY_SIZE(dp_pcie_xcvr_diag_ln_regs), +}; + +/* DP Multilink, 100 MHz Ref clk, no SSC */ +static struct cdns_reg_pairs dp_100_no_ssc_cmn_regs[] = { + {0x007F, CMN_TXPUCAL_TUNE}, + {0x007F, CMN_TXPDCAL_TUNE} +}; + +static struct cdns_reg_pairs dp_100_no_ssc_tx_ln_regs[] = { + {0x00FB, TX_PSC_A0}, + {0x04AA, TX_PSC_A2}, + {0x04AA, TX_PSC_A3}, + {0x000F, XCVR_DIAG_BIDI_CTRL} +}; + +static struct cdns_reg_pairs dp_100_no_ssc_rx_ln_regs[] = { + {0x, RX_PSC_A0}, + {0x, RX_PSC_A2}, + {0x, RX_PSC_A3}, + {0x, RX_PSC_CAL}, + {0x, RX_REE_GCSM1_CTRL}, + {0x, RX_REE_GCSM2_CTRL}, + {0x, RX_REE_PERGCSM_CTRL} +}; + +static struct cdns_torrent_vals dp_100_no_ssc_cmn_vals = { + .reg_pairs = dp_100_no_ssc_cmn_regs, + .num_regs = ARRAY_SIZE(dp_100_no_ssc_cmn_regs), +}; + +static struct cdns_torrent_vals dp_100_no_ssc_tx_ln_vals = { + .reg_pairs = dp_100_no_ssc_tx_ln_regs, + .num_regs = ARRAY_SIZE(dp_100_no_ssc_tx_ln_regs), +}; + +static struct cdns_torrent_vals dp_100_no_ssc_rx_ln_vals = { + .reg_pairs = dp_100_no_ssc_rx_ln_regs, + .num_regs = ARRAY_SIZE(dp_100_no_ssc_rx_ln_regs), +}; + /* Single DisplayPort(DP) link configuration */ static struct cdns_reg_pairs sl_dp_link_cmn_regs[] = { {0x, PHY_PLL_CFG}, @@ -3514,6 +3585,9 @@ static const struct cdns_torrent_data cdns_map_torrent = { [TYPE_NONE] = { [NO_SSC] = _dp_link_cmn_vals, }, + [TYPE_PCIE] = { + [NO_SSC] = _dp_link_cmn_vals, + }, }, [TYPE_PCIE] = { [TYPE_NONE] = { @@ -3536,6 +3610,9 @@ static const struct cdns_torrent_data cdns_map_torrent = { [EXTERNAL_SSC] = _usb_link_cmn_vals, [INTERNAL_SSC] = _usb_link_cmn_vals, }, + [TYPE_DP] = { + [NO_SSC] = _dp_link_cmn_vals, + }, }, [TYPE_SGMII] = { [TYPE_NONE] = { @@ -3595,6 +3672,9 @@ static const struct cdns_torrent_data cdns_map_torrent = { [TYPE_NONE] = { [NO_SSC] = _dp_xcvr_diag_ln_vals, }, + [TYPE_PCIE] = { + [NO_SSC] = _pcie_xcvr_diag_ln_vals, + }, }, [TYPE_PCIE] = { [TYPE_NONE] = { @@ -3617,6 +3697,9 @@ static const struct cdns_torrent_data cdns_map_torrent = { [EXTERNAL_SSC] = _usb_xcvr_diag_ln_vals, [INTERNAL_SSC] = _usb_xcvr_diag_ln_vals, }, + [TYPE_DP] = { + [NO_SSC] = _dp_xcvr_diag_ln_vals, + }, }, [TYPE_SGMII] = { [TYPE_NONE] = { @@ -3715,6 +3798,9 @@ static const struct cdns_torrent_data cdns_map_torrent = { [TYPE_NONE] = { [NO_SSC] = _dp_100_no_ssc_cmn_vals, }, +
[PATCH 01/14] phy: cadence-torrent: Remove use of CamelCase to fix checkpatch CHECK message
Script checkpatch with --strict option gives message: CHECK: Avoid CamelCase: CHECK: Avoid CamelCase: Fix this by removing CamelCase usage. No functional change. Signed-off-by: Swapnil Jakhade --- drivers/phy/cadence/phy-cadence-torrent.c | 24 +++ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 0477e7beebbf..ff647669f1a3 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -24,8 +24,8 @@ #include #include -#define REF_CLK_19_2MHz1920 -#define REF_CLK_25MHz 2500 +#define REF_CLK_19_2MHZ1920 +#define REF_CLK_25MHZ 2500 #define MAX_NUM_LANES 4 #define DEFAULT_MAX_BIT_RATE 8100 /* in Mbps */ @@ -695,12 +695,12 @@ static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy, ndelay(200); /* DP Rate Change - VCO Output settings. */ - if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) { + if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) { /* PMA common configuration 19.2MHz */ cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate, dp->ssc); cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy); - } else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) { + } else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) { /* PMA common configuration 25MHz */ cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate, dp->ssc); @@ -993,8 +993,8 @@ static int cdns_torrent_dp_init(struct phy *phy) struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; switch (cdns_phy->ref_clk_rate) { - case REF_CLK_19_2MHz: - case REF_CLK_25MHz: + case REF_CLK_19_2MHZ: + case REF_CLK_25MHZ: /* Valid Ref Clock Rate */ break; default: @@ -1026,11 +1026,11 @@ static int cdns_torrent_dp_init(struct phy *phy) /* PHY PMA registers configuration functions */ /* Initialize PHY with max supported link rate, without SSC. */ - if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) + if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, cdns_phy->max_bit_rate, false); - else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) + else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, cdns_phy->max_bit_rate, false); @@ -1074,10 +1074,10 @@ static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy, { unsigned int i; - if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) + if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) /* PMA common configuration 19.2MHz */ cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy); - else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) + else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) /* PMA common configuration 25MHz */ cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy); @@ -1529,10 +1529,10 @@ static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy, unsigned int lane) { /* Per lane, refclock-dependent receiver detection setting */ - if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) + if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHZ) cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], TX_RCVDET_ST_TMR, 0x0780); - else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) + else if (cdns_phy->ref_clk_rate == REF_CLK_25MHZ) cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], TX_RCVDET_ST_TMR, 0x09C4); -- 2.26.1
Re: [PATCH v2 08/21] ipmi: kcs_bmc: Rename {read, write}_{status, data}() functions
On Fri, Mar 19, 2021 at 01:27:39AM CDT, Andrew Jeffery wrote: >Rename the functions in preparation for separating the IPMI chardev out >from the KCS BMC core. > >Signed-off-by: Andrew Jeffery Reviewed-by: Zev Weiss
Re: [PATCH v2 17/21] dt-bindings: ipmi: Convert ASPEED KCS binding to schema
On Fri, 9 Apr 2021, at 14:45, Zev Weiss wrote: > On Fri, Mar 19, 2021 at 01:27:48AM CDT, Andrew Jeffery wrote: > >Given the deprecated binding, improve the ability to detect issues in > >the platform devicetrees. Further, a subsequent patch will introduce a > >new interrupts property for specifying SerIRQ behaviour, so convert > >before we do any further additions. > > > >Signed-off-by: Andrew Jeffery > >--- > > .../bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml | 92 +++ > > .../bindings/ipmi/aspeed-kcs-bmc.txt | 33 --- > > 2 files changed, 92 insertions(+), 33 deletions(-) > > create mode 100644 > > Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml > > delete mode 100644 Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt > > > >diff --git > >a/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml > >b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml > >new file mode 100644 > >index ..697ca575454f > >--- /dev/null > >+++ b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml > >@@ -0,0 +1,92 @@ > >+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > >+%YAML 1.2 > >+--- > >+$id: http://devicetree.org/schemas/ipmi/aspeed,ast2400-kcs-bmc.yaml > >+$schema: http://devicetree.org/meta-schemas/core.yaml > >+ > >+title: ASPEED BMC KCS Devices > >+ > >+maintainers: > >+ - Andrew Jeffery > >+ > >+description: | > >+ The Aspeed BMC SoCs typically use the Keyboard-Controller-Style (KCS) > >+ interfaces on the LPC bus for in-band IPMI communication with their host. > >+ > >+properties: > >+ compatible: > >+oneOf: > >+ - description: Channel ID derived from reg > >+items: > >+ enum: > >+- aspeed,ast2400-kcs-bmc-v2 > >+- aspeed,ast2500-kcs-bmc-v2 > >+- aspeed,ast2600-kcs-bmc > > Should this have a "-v2" suffix? Well, that was kind of a matter of perspective. The 2600 compatible was added after we'd done the v2 of the binding for the 2400 and 2500 so it never needed correcting. But it is a case of "don't use the deprecated properties with the 2600 compatible". I don't think a change is necessary? Cheers, Andrew
Re: [PATCH v2 07/21] ipmi: kcs_bmc: Make status update atomic
On Fri, Mar 19, 2021 at 01:27:38AM CDT, Andrew Jeffery wrote: >Enable more efficient implementation of read-modify-write sequences. >Both device drivers for the KCS BMC stack use regmaps. The new callback >allows us to exploit regmap_update_bits(). > >Signed-off-by: Andrew Jeffery Reviewed-by: Zev Weiss
Re: [PATCH 01/10] mm/numa: node demotion data structure and lookup
It makes sense to start with a simple node tiering model like this change, which looks good to me. I do want to mention a likely usage scenario that motivates the need for a list of nodes as the demotion target of a source node. Access to a cross-socket DRAM node is still fast enough. So to minimize memory stranding, job processes can be allowed to fall back to allocate pages from a remote DRAM node. But cross-socket access to PMEM nodes (the slower tier) can be slow, especially for random writes. It is then desirable not to demote the pages of a process to a remote PMEM node, even when the pages are on a remote DRAM node, which has the remote PMEM node as its demotion target. At the same time, it is also desirable to still be able to demote such pages when they become cold so that the more precious DRAM occupied by these pages can be used for more active data. To support such use cases, we need to be able to specify a list of demotion target nodes for the remote DRAM node, which should include the PMEM node closer to the process. Certainly, we will also need an ability to limit the demotion target nodes of a process (or a cgroup) to ensure that only local PMEM nodes are eligible as the actual demotion target. Note that demoting a page to a remote PMEM node is more acceptable than a process accesses the same remote PMEM node because demotion is one-time, sequential access, and can also use non-temporal stores to reduce the access overheads and bypass caches. Reviewed-by: Wei Xu On Thu, Apr 1, 2021 at 11:35 AM Dave Hansen wrote: > > > From: Dave Hansen > > Prepare for the kernel to auto-migrate pages to other memory nodes > with a user defined node migration table. This allows creating single > migration target for each NUMA node to enable the kernel to do NUMA > page migrations instead of simply reclaiming colder pages. A node > with no target is a "terminal node", so reclaim acts normally there. > The migration target does not fundamentally _need_ to be a single node, > but this implementation starts there to limit complexity. > > If you consider the migration path as a graph, cycles (loops) in the > graph are disallowed. This avoids wasting resources by constantly > migrating (A->B, B->A, A->B ...). The expectation is that cycles will > never be allowed. > > Signed-off-by: Dave Hansen > Reviewed-by: Yang Shi > Cc: Wei Xu > Cc: David Rientjes > Cc: Huang Ying > Cc: Dan Williams > Cc: David Hildenbrand > Cc: osalvador > > -- > > changes since 20200122: > * Make node_demotion[] __read_mostly > > changes in July 2020: > - Remove loop from next_demotion_node() and get_online_mems(). >This means that the node returned by next_demotion_node() >might now be offline, but the worst case is that the >allocation fails. That's fine since it is transient. > --- > > b/mm/migrate.c | 17 + > 1 file changed, 17 insertions(+) > > diff -puN mm/migrate.c~0006-node-Define-and-export-memory-migration-path > mm/migrate.c > --- a/mm/migrate.c~0006-node-Define-and-export-memory-migration-path > 2021-03-31 15:17:10.734000264 -0700 > +++ b/mm/migrate.c 2021-03-31 15:17:10.742000264 -0700 > @@ -1163,6 +1163,23 @@ out: > return rc; > } > > +static int node_demotion[MAX_NUMNODES] __read_mostly = > + {[0 ... MAX_NUMNODES - 1] = NUMA_NO_NODE}; > + > +/** > + * next_demotion_node() - Get the next node in the demotion path > + * @node: The starting node to lookup the next node > + * > + * @returns: node id for next memory node in the demotion path hierarchy > + * from @node; NUMA_NO_NODE if @node is terminal. This does not keep > + * @node online or guarantee that it *continues* to be the next demotion > + * target. > + */ > +int next_demotion_node(int node) > +{ > + return node_demotion[node]; > +} > + > /* > * Obtain the lock on page, remove all ptes and migrate the page > * to the newly allocated page in newpage. > _
Re: [PATCH 1/6] PM: runtime: enable wake irq after runtime_suspend hook called
Hi Chunfeng, On Thu, Apr 8, 2021 at 5:35 PM Chunfeng Yun wrote: > > When the dedicated wake irq is level trigger, enable it before > calling runtime_suspend, will trigger an interrupt. > > e.g. > for a low level trigger type, it's low level at running time (0), > and becomes high level when enters suspend (runtime_suspend (1) is > called), a wakeup signal at (2) make it become low level, wake irq > will be triggered. > > -- >| ^ ^| > | | -- > |<---(0)--->|<--(1)--| (3) (2)(4) > Can't we just use a falling edge type for this irq line? > if we enable the wake irq before calling runtime_suspend during (0), > an interrupt will arise, it causes resume immediately; > enable wake irq after calling runtime_suspend, e.g. at (3) or (4), > will works. > > This patch seems no side effect on edge trigger wake irq. > > Signed-off-by: Chunfeng Yun > --- > drivers/base/power/runtime.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > > diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c > index a46a7e30881b..796739a015a5 100644 > --- a/drivers/base/power/runtime.c > +++ b/drivers/base/power/runtime.c > @@ -619,12 +619,12 @@ static int rpm_suspend(struct device *dev, int rpmflags) > __update_runtime_status(dev, RPM_SUSPENDING); > > callback = RPM_GET_CALLBACK(dev, runtime_suspend); > - > - dev_pm_enable_wake_irq_check(dev, true); > retval = rpm_callback(callback, dev); > if (retval) > goto fail; > > + dev_pm_enable_wake_irq_check(dev, true); > + > no_callback: > __update_runtime_status(dev, RPM_SUSPENDED); > pm_runtime_deactivate_timer(dev); > @@ -659,7 +659,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) > return retval; > > fail: > - dev_pm_disable_wake_irq_check(dev); > __update_runtime_status(dev, RPM_ACTIVE); > dev->power.deferred_resume = false; > wake_up_all(>power.wait_queue); > -- > 2.18.0 >
Re: [PATCH net v3] net: sched: fix packet stuck problem for lockless qdisc
On 25.03.21 04:13, Yunsheng Lin wrote: Lockless qdisc has below concurrent problem: cpu0 cpu1 . . q->enqueue . . . qdisc_run_begin() . . . dequeue_skb() . . . sch_direct_xmit() . . . .q->enqueue . qdisc_run_begin() .return and do nothing . . qdisc_run_end(). cpu1 enqueue a skb without calling __qdisc_run() because cpu0 has not released the lock yet and spin_trylock() return false for cpu1 in qdisc_run_begin(), and cpu0 do not see the skb enqueued by cpu1 when calling dequeue_skb() because cpu1 may enqueue the skb after cpu0 calling dequeue_skb() and before cpu0 calling qdisc_run_end(). Lockless qdisc has below another concurrent problem when tx_action is involved: cpu0(serving tx_action) cpu1 cpu2 . .. . q->enqueue. .qdisc_run_begin() . . dequeue_skb() . . .q->enqueue . .. . sch_direct_xmit() . . . qdisc_run_begin() . . return and do nothing . .. clear __QDISC_STATE_SCHED.. qdisc_run_begin().. return and do nothing.. . .. .qdisc_run_end() . This patch fixes the above data race by: 1. Get the flag before doing spin_trylock(). 2. If the first spin_trylock() return false and the flag is not set before the first spin_trylock(), Set the flag and retry another spin_trylock() in case other CPU may not see the new flag after it releases the lock. 3. reschedule if the flags is set after the lock is released at the end of qdisc_run_end(). For tx_action case, the flags is also set when cpu1 is at the end if qdisc_run_end(), so tx_action will be rescheduled again to dequeue the skb enqueued by cpu2. Only clear the flag before retrying a dequeuing when dequeuing returns NULL in order to reduce the overhead of the above double spin_trylock() and __netif_schedule() calling. The performance impact of this patch, tested using pktgen and dummy netdev with pfifo_fast qdisc attached: threads without+this_patch with+this_patch delta 12.61Mpps2.60Mpps -0.3% 23.97Mpps3.82Mpps -3.7% 45.62Mpps5.59Mpps -0.5% 82.78Mpps2.77Mpps -0.3% 162.22Mpps2.22Mpps -0.0% Fixes: 6b3ba9146fe6 ("net: sched: allow qdiscs to handle locking") Signed-off-by: Yunsheng Lin I have a setup which is able to reproduce the issue quite reliably: In a Xen guest I'm mounting 8 NFS shares and run sysbench fileio on each of them. The average latency reported by sysbench is well below 1 msec, but at least once per hour I get latencies in the minute range. With this patch I don't see these high latencies any longer (test is running for more than 20 hours now). So you can add my: Tested-by: Juergen Gross Juergen OpenPGP_0xB0DE9DD628BF132F.asc Description: application/pgp-keys OpenPGP_signature Description: OpenPGP digital signature
Re: [next] drivers/cdrom/gdrom.c:586:61: error: 'rq' undeclared (first use in this function)
On 4/8/21 22:21, Naresh Kamboju wrote: > Linux next tag 20210408 architecture sh builds failed due to these errors. > > # to reproduce this build locally: > > make --silent --keep-going --jobs=8 > O=/home/tuxbuild/.cache/tuxmake/builds/1/tmp ARCH=sh > CROSS_COMPILE=sh4-linux-gnu- 'CC=sccache sh4-linux-gnu-gcc' > 'HOSTCC=sccache gcc' > > > In file included from /builds/linux/include/linux/scatterlist.h:9, > from /builds/linux/include/linux/dma-mapping.h:10, > from /builds/linux/drivers/cdrom/gdrom.c:16: > /builds/linux/drivers/cdrom/gdrom.c: In function 'gdrom_readdisk_dma': > /builds/linux/drivers/cdrom/gdrom.c:586:61: error: 'rq' undeclared > (first use in this function) > 586 | __raw_writel(page_to_phys(bio_page(req->bio)) + bio_offset(rq->bio), > | ^~ > > Reported-by: Naresh Kamboju > > Regressions found on sh: > - build/gcc-9-dreamcast_defconfig > - build/gcc-10-dreamcast_defconfig > - build/gcc-8-dreamcast_defconfig > > -- > Linaro LKFT > https://lkft.linaro.org > This can be fixed by following :- diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index e7717d090868..742b4a0932e3 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -583,7 +583,7 @@ static blk_status_t gdrom_readdisk_dma(struct request *req) read_command->cmd[1] = 0x20; block = blk_rq_pos(req)/GD_TO_BLK + GD_SESSION_OFFSET; block_cnt = blk_rq_sectors(req)/GD_TO_BLK; - __raw_writel(page_to_phys(bio_page(req->bio)) + bio_offset(rq->bio), + __raw_writel(page_to_phys(bio_page(req->bio)) + bio_offset(req->bio), GDROM_DMA_STARTADDR_REG); __raw_writel(block_cnt * GDROM_HARD_SECTOR, GDROM_DMA_LENGTH_REG); __raw_writel(1, GDROM_DMA_DIRECTION_REG);
Re: New 'make dtbs_check W=1' warnings
On 2021-04-09 05:37, Florian Fainelli wrote: On 4/8/2021 8:08 AM, Arnd Bergmann wrote: Greetings to all Arm platform maintainers, I've just gone through the DT merges I've received so far and, with a little help from Rob, managed to run 'make dtbs_check W=1' before and after, to see what warnings we get. The good news is that the number of warnings is going down, but unfortunately there is still an unmanageable amount of remaining warnings, and some new ones crept in. I'm still working on my tooling for this, to catch these better, but ideally I think we should try to not introduce new warnings. I think some platforms are already clean, and I did not see any new warnings for mvebu, samsung and broadcom. There were a lot of warnings from .dtsi files, and I probably did an incomplete job at deduplicating those. There are definitively a ton of warnings for Broacom DTS files, a number of those warnings exist because the bindings were not converted to YAML. Rafal, do you think you could help me with taking care of the BCM5301X/4908 warnings? Sure, I got rid of one or two warnings already, I'll keep working on that.
Re: [PATCH v2 01/21] dt-bindings: aspeed-lpc: Remove LPC partitioning
On Fri, 9 Apr 2021, at 12:48, Joel Stanley wrote: > On Fri, 19 Mar 2021 at 06:28, Andrew Jeffery wrote: > > > > From: "Chia-Wei, Wang" > > > > The LPC controller has no concept of the BMC and the Host partitions. > > This patch fixes the documentation by removing the description on LPC > > partitions. The register offsets illustrated in the DTS node examples > > are also fixed to adapt to the LPC DTS change. > > Is this accurate: > > The node examples change their reg address to be an offset from the > LPC HC to be an offset from the base of the LPC region. Everything becomes based from the start of the LPC region, yes. Andrew
Re: [RFC v3 0/2] CPU-Idle latency selftest framework
Hi Pratik, I tried V3 on a Intel i5-10600K processor with 6 cores and 12 CPUs. The core to cpu mappings are: core 0 has cpus 0 and 6 core 1 has cpus 1 and 7 core 2 has cpus 2 and 8 core 3 has cpus 3 and 9 core 4 has cpus 4 and 10 core 5 has cpus 5 and 11 By default, it will test CPUs 0,2,4,6,10 on cores 0,2,4,0,2,4. wouldn't it make more sense to test each core once? With the source CPU always 0, I think the results from the results from the destination CPUs 0 and 6, on core 0 bias the results, at least in the deeper idle states. They don't make much difference in the shallow states. Myself, I wouldn't include them in the results. Example, where I used the -v option for all CPUs: --IPI Latency Test--- --Baseline IPI Latency measurement: CPU Busy-- SRC_CPU DEST_CPU IPI_Latency(ns) 00 101 01 790 02 609 03 595 04 737 05 759 06 780 07 741 08 574 09 681 0 10 527 0 11 552 Baseline Avg IPI latency(ns): 620 suggest 656 here ---Enabling state: 0--- SRC_CPU DEST_CPU IPI_Latency(ns) 00 76 01 471 02 420 03 462 04 454 05 468 06 453 07 473 08 380 09 483 0 10 492 0 11 454 Expected IPI latency(ns): 0 Observed Avg IPI latency(ns) - State 0: 423 < suggest 456 here ---Enabling state: 1--- SRC_CPU DEST_CPU IPI_Latency(ns) 00 112 01 866 02 663 03 851 04 1090 05 1314 06 1941 07 1458 08 687 09 802 0 10 1041 0 11 1284 Expected IPI latency(ns): 1000 Observed Avg IPI latency(ns) - State 1: 1009 suggest 1006 here ---Enabling state: 2--- SRC_CPU DEST_CPU IPI_Latency(ns) 00 75 0116362 0216785 0319650 0417356 0517606 06 2217 0717958 0817332 0916615 0 1017382 0 1117423 Expected IPI latency(ns): 12 Observed Avg IPI latency(ns) - State 2: 14730 suggest 17447 here ---Enabling state: 3--- SRC_CPU DEST_CPU IPI_Latency(ns) 00 103 0117416 0217961 0316651 0417867 0517726 06 2178 0716620 0820951 0916567 0 1017131 0 1117563 Expected IPI latency(ns): 1034000 Observed Avg IPI latency(ns) - State 3: 14894 suggest 17645 here Hope this helps. ... Doug
Re: [PATCH v8] vfs: fix copy_file_range regression in cross-fs copies
On Wed, Feb 24, 2021 at 6:44 PM Nicolas Boichat wrote: > > On Wed, Feb 24, 2021 at 6:22 PM Luis Henriques wrote: > > > > On Tue, Feb 23, 2021 at 08:00:54PM -0500, Olga Kornievskaia wrote: > > > On Mon, Feb 22, 2021 at 5:25 AM Luis Henriques wrote: > > > > > > > > A regression has been reported by Nicolas Boichat, found while using the > > > > copy_file_range syscall to copy a tracefs file. Before commit > > > > 5dae222a5ff0 ("vfs: allow copy_file_range to copy across devices") the > > > > kernel would return -EXDEV to userspace when trying to copy a file > > > > across > > > > different filesystems. After this commit, the syscall doesn't fail > > > > anymore > > > > and instead returns zero (zero bytes copied), as this file's content is > > > > generated on-the-fly and thus reports a size of zero. > > > > > > > > This patch restores some cross-filesystem copy restrictions that existed > > > > prior to commit 5dae222a5ff0 ("vfs: allow copy_file_range to copy across > > > > devices"). Filesystems are still allowed to fall-back to the VFS > > > > generic_copy_file_range() implementation, but that has now to be done > > > > explicitly. > > > > > > > > nfsd is also modified to fall-back into generic_copy_file_range() in > > > > case > > > > vfs_copy_file_range() fails with -EOPNOTSUPP or -EXDEV. > > > > > > > > Fixes: 5dae222a5ff0 ("vfs: allow copy_file_range to copy across > > > > devices") > > > > Link: > > > > https://lore.kernel.org/linux-fsdevel/20210212044405.4120619-1-drink...@chromium.org/ > > > > Link: > > > > https://lore.kernel.org/linux-fsdevel/CANMq1KDZuxir2LM5jOTm0xx+BnvW=zmpsg47cyhfjwnw7zs...@mail.gmail.com/ > > > > Link: > > > > https://lore.kernel.org/linux-fsdevel/20210126135012.1.If45b7cdc3ff707bc1efa17f5366057d60603c45f@changeid/ > > > > Reported-by: Nicolas Boichat > > > > Signed-off-by: Luis Henriques > > > > > > I tested v8 and I believe it works for NFS. > > > > Thanks a lot for the testing. And to everyone else for reviews, > > feedback,... and patience. > > Thanks so much to you!!! > > Works here, you can add my > Tested-by: Nicolas Boichat What happened to this patch? It does not seem to have been picked up yet? Any reason why? > > > > I'll now go look into the manpage and see what needs to be changed. > > > > Cheers, > > -- > > Luís
Re: [PATCH v2 16/21] ipmi: kcs_bmc: Add a "raw" character device interface
On Fri, Mar 19, 2021 at 01:27:47AM CDT, Andrew Jeffery wrote: >The existing IPMI chardev encodes IPMI behaviours as the name suggests. >However, KCS devices are useful beyond IPMI (or keyboards), as they >provide a means to generate IRQs and exchange arbitrary data between a >BMC and its host system. > >Implement a "raw" KCS character device that exposes the IDR, ODR and STR >registers to userspace via read() and write() implemented on a character >device: > >+++-+ >| Offset | read() | write() | >+++-+ >| 0| IDR | ODR | >+++-+ >| 1| STR | STR | >+++-+ > >This interface allows userspace to implement arbitrary (though somewhat >inefficient) protocols for exchanging information between a BMC and host >firmware. Conceptually the KCS interface can be used as an out-of-band >machanism for interrupt-signaled control messages while bulk data Typo ("mechanism") >transfers occur over more appropriate interfaces between the BMC and the >host (which may lack their own interrupt mechanism, e.g. LPC FW cycles). > >poll() is provided, which will wait for IBF or OBE conditions for data >reads and writes respectively. Reads of STR on its own never blocks, >though accessing both offsets in the one system call may block if the >data registers are not ready. > >Signed-off-by: Andrew Jeffery >--- > Documentation/ABI/testing/dev-raw-kcs | 25 ++ > drivers/char/ipmi/Kconfig | 17 + > drivers/char/ipmi/Makefile| 1 + > drivers/char/ipmi/kcs_bmc_cdev_raw.c | 443 ++ > 4 files changed, 486 insertions(+) > create mode 100644 Documentation/ABI/testing/dev-raw-kcs > create mode 100644 drivers/char/ipmi/kcs_bmc_cdev_raw.c > >diff --git a/Documentation/ABI/testing/dev-raw-kcs >b/Documentation/ABI/testing/dev-raw-kcs >new file mode 100644 >index ..06e7e2071562 >--- /dev/null >+++ b/Documentation/ABI/testing/dev-raw-kcs >@@ -0,0 +1,25 @@ >+What: /dev/raw-kcs* >+Date: 2021-02-15 >+KernelVersion:5.13 >+Contact: open...@lists.ozlabs.org >+Contact: openipmi-develo...@lists.sourceforge.net >+Contact: Andrew Jeffery >+Description: ``/dev/raw-kcs*`` exposes to userspace the data and >+ status registers of Keyboard-Controller-Style (KCS) IPMI >+ interfaces via read() and write() syscalls. Direct >+ exposure of the data and status registers enables >+ inefficient but arbitrary protocols to be implemented >+ over the device. A typical approach is to use KCS >+ devices for out-of-band signalling for bulk data >+ transfers over other interfaces between a Baseboard >+ Management Controller and its host. >+ >+ +++-+ >+ | Offset | read() | write() | >+ +++-+ >+ | 0| IDR | ODR | >+ +++-+ >+ | 1| STR | STR | >+ +++-+ >+ >+Users:libmctp: https://github.com/openbmc/libmctp >diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig >index bc5f81899b62..273ac1a1f870 100644 >--- a/drivers/char/ipmi/Kconfig >+++ b/drivers/char/ipmi/Kconfig >@@ -137,6 +137,23 @@ config IPMI_KCS_BMC_CDEV_IPMI > This support is also available as a module. The module will be > called kcs_bmc_cdev_ipmi. > >+config IPMI_KCS_BMC_CDEV_RAW >+ depends on IPMI_KCS_BMC >+ tristate "Raw character device interface for BMC KCS devices" >+ help >+Provides a BMC-side character device directly exposing the >+data and status registers of a KCS device to userspace. While >+KCS devices are commonly used to implement IPMI message >+passing, they provide a general interface for exchange of >+interrupts, data and status information between the BMC and >+its host. >+ >+Say YES if you wish to use the KCS devices to implement >+protocols that are not IPMI. >+ >+This support is also available as a module. The module will be >+called kcs_bmc_cdev_raw. >+ > config ASPEED_BT_IPMI_BMC > depends on ARCH_ASPEED || COMPILE_TEST > depends on REGMAP && REGMAP_MMIO && MFD_SYSCON >diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile >index fcfa676afddb..c8cc248ddd90 100644 >--- a/drivers/char/ipmi/Makefile >+++ b/drivers/char/ipmi/Makefile >@@ -24,6 +24,7 @@ obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o > obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o > obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o > obj-$(CONFIG_IPMI_KCS_BMC_CDEV_IPMI) += kcs_bmc_cdev_ipmi.o >+obj-$(CONFIG_IPMI_KCS_BMC_CDEV_RAW) += kcs_bmc_cdev_raw.o > obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o > obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o >
[next] drivers/cdrom/gdrom.c:586:61: error: 'rq' undeclared (first use in this function)
Linux next tag 20210408 architecture sh builds failed due to these errors. # to reproduce this build locally: make --silent --keep-going --jobs=8 O=/home/tuxbuild/.cache/tuxmake/builds/1/tmp ARCH=sh CROSS_COMPILE=sh4-linux-gnu- 'CC=sccache sh4-linux-gnu-gcc' 'HOSTCC=sccache gcc' In file included from /builds/linux/include/linux/scatterlist.h:9, from /builds/linux/include/linux/dma-mapping.h:10, from /builds/linux/drivers/cdrom/gdrom.c:16: /builds/linux/drivers/cdrom/gdrom.c: In function 'gdrom_readdisk_dma': /builds/linux/drivers/cdrom/gdrom.c:586:61: error: 'rq' undeclared (first use in this function) 586 | __raw_writel(page_to_phys(bio_page(req->bio)) + bio_offset(rq->bio), | ^~ Reported-by: Naresh Kamboju Regressions found on sh: - build/gcc-9-dreamcast_defconfig - build/gcc-10-dreamcast_defconfig - build/gcc-8-dreamcast_defconfig -- Linaro LKFT https://lkft.linaro.org
Re: [PATCH v2 17/21] dt-bindings: ipmi: Convert ASPEED KCS binding to schema
On Fri, Mar 19, 2021 at 01:27:48AM CDT, Andrew Jeffery wrote: >Given the deprecated binding, improve the ability to detect issues in >the platform devicetrees. Further, a subsequent patch will introduce a >new interrupts property for specifying SerIRQ behaviour, so convert >before we do any further additions. > >Signed-off-by: Andrew Jeffery >--- > .../bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml | 92 +++ > .../bindings/ipmi/aspeed-kcs-bmc.txt | 33 --- > 2 files changed, 92 insertions(+), 33 deletions(-) > create mode 100644 > Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml > delete mode 100644 Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt > >diff --git >a/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml >b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml >new file mode 100644 >index ..697ca575454f >--- /dev/null >+++ b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-kcs-bmc.yaml >@@ -0,0 +1,92 @@ >+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) >+%YAML 1.2 >+--- >+$id: http://devicetree.org/schemas/ipmi/aspeed,ast2400-kcs-bmc.yaml >+$schema: http://devicetree.org/meta-schemas/core.yaml >+ >+title: ASPEED BMC KCS Devices >+ >+maintainers: >+ - Andrew Jeffery >+ >+description: | >+ The Aspeed BMC SoCs typically use the Keyboard-Controller-Style (KCS) >+ interfaces on the LPC bus for in-band IPMI communication with their host. >+ >+properties: >+ compatible: >+oneOf: >+ - description: Channel ID derived from reg >+items: >+ enum: >+- aspeed,ast2400-kcs-bmc-v2 >+- aspeed,ast2500-kcs-bmc-v2 >+- aspeed,ast2600-kcs-bmc Should this have a "-v2" suffix? >+ >+ - description: Old-style with explicit channel ID, no reg >+deprecated: true >+items: >+ enum: >+- aspeed,ast2400-kcs-bmc >+- aspeed,ast2500-kcs-bmc >+ >+ interrupts: >+maxItems: 1 >+ >+ reg: >+# maxItems: 3 >+items: >+ - description: IDR register >+ - description: ODR register >+ - description: STR register >+ >+ aspeed,lpc-io-reg: >+$ref: '/schemas/types.yaml#/definitions/uint32-array' >+minItems: 1 >+maxItems: 2 >+description: | >+ The host CPU LPC IO data and status addresses for the device. For most >+ channels the status address is derived from the data address, but the >+ status address may be optionally provided. >+ >+ kcs_chan: >+deprecated: true >+$ref: '/schemas/types.yaml#/definitions/uint32' >+description: The LPC channel number in the controller >+ >+ kcs_addr: >+deprecated: true >+$ref: '/schemas/types.yaml#/definitions/uint32' >+description: The host CPU IO map address >+ >+required: >+ - compatible >+ - interrupts >+ >+additionalProperties: false >+ >+allOf: >+ - if: >+ properties: >+compatible: >+ contains: >+enum: >+ - aspeed,ast2400-kcs-bmc >+ - aspeed,ast2500-kcs-bmc >+then: >+ required: >+- kcs_chan >+- kcs_addr >+else: >+ required: >+- reg >+- aspeed,lpc-io-reg >+ >+examples: >+ - | >+kcs3: kcs@24 { >+compatible = "aspeed,ast2600-kcs-bmc"; And likewise here. >+reg = <0x24 0x1>, <0x30 0x1>, <0x3c 0x1>; >+aspeed,lpc-io-reg = <0xca2>; >+interrupts = <8>; >+}; >diff --git a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt >b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt >deleted file mode 100644 >index 193e71ca96b0.. >--- a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt >+++ /dev/null >@@ -1,33 +0,0 @@ >-# Aspeed KCS (Keyboard Controller Style) IPMI interface >- >-The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs >-(Baseboard Management Controllers) and the KCS interface can be >-used to perform in-band IPMI communication with their host. >- >-## v1 >-Required properties: >-- compatible : should be one of >-"aspeed,ast2400-kcs-bmc" >-"aspeed,ast2500-kcs-bmc" >-- interrupts : interrupt generated by the controller >-- kcs_chan : The LPC channel number in the controller >-- kcs_addr : The host CPU IO map address >- >-## v2 >-Required properties: >-- compatible : should be one of >-"aspeed,ast2400-kcs-bmc-v2" >-"aspeed,ast2500-kcs-bmc-v2" >-- reg : The address and size of the IDR, ODR and STR registers >-- interrupts : interrupt generated by the controller >-- aspeed,lpc-io-reg : The host CPU LPC IO address for the device >- >-Example: >- >-kcs3: kcs@24 { >-compatible = "aspeed,ast2500-kcs-bmc-v2"; >-reg = <0x24 0x1>, <0x30 0x1>, <0x3c 0x1>; >-aspeed,lpc-reg = <0xca2>; >-interrupts = <8>; >-status = "okay"; >-}; >-- >2.27.0 >
Re: [PATCH -next] mmc: owl-mmc: Remove unnecessary error log
On Fri, Apr 09, 2021 at 10:33:49AM +0800, Laibin Qiu wrote: > devm_ioremap_resource() has recorded error log, so it's > unnecessary to record log again. > > Reported-by: Hulk Robot > Signed-off-by: Laibin Qiu Reviewed-by: Manivannan Sadhasivam Thanks, Mani > --- > drivers/mmc/host/owl-mmc.c | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/drivers/mmc/host/owl-mmc.c b/drivers/mmc/host/owl-mmc.c > index 5490962dc8e5..3dc143b03939 100644 > --- a/drivers/mmc/host/owl-mmc.c > +++ b/drivers/mmc/host/owl-mmc.c > @@ -581,7 +581,6 @@ static int owl_mmc_probe(struct platform_device *pdev) > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > owl_host->base = devm_ioremap_resource(>dev, res); > if (IS_ERR(owl_host->base)) { > - dev_err(>dev, "Failed to remap registers\n"); > ret = PTR_ERR(owl_host->base); > goto err_free_host; > } > -- > 2.25.1 >
Re: [PATCH v5 3/4] drivers/tty/serial/8250: add aspeed, lpc-io-reg and aspeed, lpc-interrupts DT properties
Hi Zev, A couple of minor comments: On Thu, 8 Apr 2021, at 10:46, Zev Weiss wrote: > These allow describing all the Aspeed VUART attributes currently > available via sysfs. aspeed,sirq aspeed,lpc-interrupts now > provides a replacement for the > deprecated aspeed,sirq-polarity-sense property. > > Signed-off-by: Zev Weiss > --- > drivers/tty/serial/8250/8250_aspeed_vuart.c | 44 - > 1 file changed, 43 insertions(+), 1 deletion(-) > > diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c > b/drivers/tty/serial/8250/8250_aspeed_vuart.c > index 8433f8dbb186..75ef006fa24b 100644 > --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c > +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c > @@ -28,6 +28,10 @@ > #define ASPEED_VUART_ADDRL 0x28 > #define ASPEED_VUART_ADDRH 0x2c > > +#define ASPEED_VUART_DEFAULT_LPC_ADDR0x3f8 > +#define ASPEED_VUART_DEFAULT_SIRQ4 > +#define ASPEED_VUART_DEFAULT_SIRQ_POLARITY IRQ_TYPE_LEVEL_LOW > + > struct aspeed_vuart { > struct device *dev; > void __iomem*regs; > @@ -393,7 +397,8 @@ static int aspeed_vuart_probe(struct platform_device > *pdev) > struct aspeed_vuart *vuart; > struct device_node *np; > struct resource *res; > - u32 clk, prop; > + u32 clk, prop, sirq[2]; > + bool sirq_polarity; > int rc; > > np = pdev->dev.of_node; > @@ -501,6 +506,43 @@ static int aspeed_vuart_probe(struct platform_device > *pdev) > of_node_put(sirq_polarity_sense_args.np); > } > > + rc = of_property_read_u32(np, "aspeed,lpc-io-reg", ); > + if (rc < 0) > + prop = ASPEED_VUART_DEFAULT_LPC_ADDR; > + > + rc = aspeed_vuart_set_lpc_address(vuart, prop); > + if (rc < 0) { > + dev_err(>dev, "invalid value in aspeed,lpc-io-reg > property\n"); > + goto err_clk_disable; > + } > + > + rc = of_property_read_u32_array(np, "aspeed,lpc-interrupts", sirq, 2); > + if (rc < 0) { > + sirq[0] = ASPEED_VUART_DEFAULT_SIRQ; > + sirq[1] = ASPEED_VUART_DEFAULT_SIRQ_POLARITY; > + } > + > + rc = aspeed_vuart_set_sirq(vuart, sirq[0]); > + if (rc < 0) { > + dev_err(>dev, "invalid sirq number in > aspeed,lpc-interrupts > property\n"); > + goto err_clk_disable; > + } > + > + switch (sirq[1]) { > + case IRQ_TYPE_LEVEL_LOW: > + sirq_polarity = false; > + break; > + case IRQ_TYPE_LEVEL_HIGH: > + sirq_polarity = true; > + break; > + default: > + dev_err(>dev, "invalid sirq polarity in > aspeed,lpc-interrupts > property\n"); > + rc = -EINVAL; > + goto err_clk_disable; > + } A bit ugly open-coding the mapping and error handling, maybe worth a helper? Looks okay otherwise. Cheers, Andrew
Re: [PATCH 3/4] sched/fair: Consider SMT in ASYM_PACKING load balance
On Thu, Apr 08, 2021 at 01:21:22PM +0200, Peter Zijlstra wrote: > On Tue, Apr 06, 2021 at 04:17:51PM -0700, Ricardo Neri wrote: > > On Tue, Apr 06, 2021 at 01:18:09PM +0200, Peter Zijlstra wrote: > > > On Mon, Apr 05, 2021 at 09:11:07PM -0700, Ricardo Neri wrote: > > > > +static bool cpu_group_is_smt(int cpu, struct sched_group *sg) > > > > +{ > > > > +#ifdef CONFIG_SCHED_SMT > > > > + if (!static_branch_likely(_smt_present)) > > > > + return false; > > > > + > > > > + if (sg->group_weight == 1) > > > > + return false; > > > > + > > > > + if (cpumask_weight(cpu_smt_mask(cpu)) == 1) > > > > + return false; > > > > > > Please explain this condition. Why is it required? > > > > Thank you for your quick review Peter! > > > > Probably this is not required since the previous check verifies the > > group weight, and the subsequent check makes sure that @sg matches the > > SMT siblings of @cpu. > > So the thing is that cpumask_weight() can be fairly expensive, depending > on how large the machine is. > > Now I suppose this mixing of SMT and !SMT cores is typical for 'small' > machines (for now), but this is enabled for everything with ITMT on, > which might very well include large systems. > > So yes, if it can go away, that'd be good. Sure Peter, I think this check can be removed. I'll post a v2 with the updates. Thanks and BR, Ricardo
Re: [PATCH 3/4] sched/fair: Consider SMT in ASYM_PACKING load balance
On Thu, Apr 08, 2021 at 01:10:39PM +0200, Peter Zijlstra wrote: > On Tue, Apr 06, 2021 at 04:17:10PM -0700, Ricardo Neri wrote: > > On Tue, Apr 06, 2021 at 01:17:28PM +0200, Peter Zijlstra wrote: > > > On Mon, Apr 05, 2021 at 09:11:07PM -0700, Ricardo Neri wrote: > > > > @@ -8507,6 +8619,10 @@ static bool update_sd_pick_busiest(struct lb_env > > > > *env, > > > > if (!sgs->sum_h_nr_running) > > > > return false; > > > > > > > > + if (sgs->group_type == group_asym_packing && > > > > + !asym_can_pull_tasks(env->dst_cpu, sds, sgs, sg)) > > > > + return false; > > > > > > All of this makes my head hurt; but afaict this isn't right. > > > > > > Your update_sg_lb_stats() change makes that we unconditionally set > > > sgs->group_asym_packing, and then this is to undo that. But it's not > > > clear this covers all cases right. > > > > We could not make a decision to set sgs->group_asym_packing in > > update_sg_lb_stats() because we don't have information about the dst_cpu > > and its SMT siblings if any. That is the reason I proposed to delay the > > decision to update_sd_pick_busiest(), where we can compare local and > > sgs. > > Yeah, I sorta got that. > > > > Even if !sched_asym_prefer(), we could end up selecting this sg as > > > busiest, but you're just bailing out here. > > > > Even if sgs->group_asym_packing is unconditionally set, sgs can still > > be classified as group_overloaded and group_imbalanced. In such cases > > we wouldn't bailout. sgs could not be classified as group_fully_busy > > or group_has_spare and we would bailout, though. Is your concern about > > these? I can fixup these two cases. > > Yes. Either explain (in a comment) why those cases are not relevant, or > handle them properly. > > Because when reading this, it wasn't at all obvious that this is correct > or as intended. Sure Peter, I will post a v2 handling the remaining cases properly. Thanks and BR, Ricardo
Re: [PATCH v6 4/8] mm,memory_hotplug: Allocate memmap from the added memory range
On Thu, Apr 08, 2021 at 10:05:18PM -0700, Andrew Morton wrote: > Yes please. I just sent v7 with that yesterday [1] Hope David/Michal finds some time to review patch#4 as that is the only missing piece atm. [1] https://lkml.org/lkml/2021/4/8/546 -- Oscar Salvador SUSE L3
Re: [PATCH v2 15/21] ipmi: kcs_bmc: Don't enforce single-open policy in the kernel
On Fri, Mar 19, 2021 at 01:27:46AM CDT, Andrew Jeffery wrote: >Soon it will be possible for one KCS device to have multiple associated >chardevs exposed to userspace (for IPMI and raw-style access). However, >don't prevent userspace from: > >1. Opening more than one chardev at a time, or >2. Opening the same chardev more than once. > >System behaviour is undefined for both classes of multiple access, so >userspace must manage itself accordingly. > >The implementation delivers IBF and OBF events to the first chardev >client to associate with the KCS device. An open on a related chardev >cannot associate its client with the KCS device and so will not >receive notification of events. However, any fd on any chardev may race >their accesses to the data and status registers. > >Signed-off-by: Andrew Jeffery >--- > drivers/char/ipmi/kcs_bmc.c | 34 ++--- > drivers/char/ipmi/kcs_bmc_aspeed.c | 3 +-- > drivers/char/ipmi/kcs_bmc_npcm7xx.c | 3 +-- > 3 files changed, 14 insertions(+), 26 deletions(-) > >diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c >index 05bbb72418b2..2fafa9541934 100644 >--- a/drivers/char/ipmi/kcs_bmc.c >+++ b/drivers/char/ipmi/kcs_bmc.c >@@ -55,24 +55,12 @@ EXPORT_SYMBOL(kcs_bmc_update_status); > int kcs_bmc_handle_event(struct kcs_bmc_device *kcs_bmc) > { > struct kcs_bmc_client *client; >- int rc; >+ int rc = KCS_BMC_EVENT_NONE; > > spin_lock(_bmc->lock); > client = kcs_bmc->client; >- if (client) { >+ if (!WARN_ON_ONCE(!client)) > rc = client->ops->event(client); The double-negation split by a macro seems a bit confusing to me readability-wise; could we simplify to something like if (client) rc = client->ops->event(client); else WARN_ONCE(); ? >- } else { >- u8 status; >- >- status = kcs_bmc_read_status(kcs_bmc); >- if (status & KCS_BMC_STR_IBF) { >- /* Ack the event by reading the data */ >- kcs_bmc_read_data(kcs_bmc); >- rc = KCS_BMC_EVENT_HANDLED; >- } else { >- rc = KCS_BMC_EVENT_NONE; >- } >- } > spin_unlock(_bmc->lock); > > return rc; >@@ -81,26 +69,28 @@ EXPORT_SYMBOL(kcs_bmc_handle_event); > > int kcs_bmc_enable_device(struct kcs_bmc_device *kcs_bmc, struct > kcs_bmc_client *client) > { >- int rc; >- > spin_lock_irq(_bmc->lock); >- if (kcs_bmc->client) { >- rc = -EBUSY; >- } else { >+ if (!kcs_bmc->client) { >+ u8 mask = KCS_BMC_EVENT_TYPE_IBF; >+ > kcs_bmc->client = client; >- rc = 0; >+ kcs_bmc_update_event_mask(kcs_bmc, mask, mask); > } > spin_unlock_irq(_bmc->lock); > >- return rc; >+ return 0; Since this function appears to be infallible now, should it just return void? (Might be more churn than it's worth...shrug.) > } > EXPORT_SYMBOL(kcs_bmc_enable_device); > > void kcs_bmc_disable_device(struct kcs_bmc_device *kcs_bmc, struct > kcs_bmc_client *client) > { > spin_lock_irq(_bmc->lock); >- if (client == kcs_bmc->client) >+ if (client == kcs_bmc->client) { >+ u8 mask = KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE; >+ >+ kcs_bmc_update_event_mask(kcs_bmc, mask, 0); > kcs_bmc->client = NULL; >+ } > spin_unlock_irq(_bmc->lock); > } > EXPORT_SYMBOL(kcs_bmc_disable_device); >diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c >b/drivers/char/ipmi/kcs_bmc_aspeed.c >index 5f26471c038c..271845eb2e26 100644 >--- a/drivers/char/ipmi/kcs_bmc_aspeed.c >+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c >@@ -419,8 +419,7 @@ static int aspeed_kcs_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, priv); > >- aspeed_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | >KCS_BMC_EVENT_TYPE_OBE), >- KCS_BMC_EVENT_TYPE_IBF); >+ aspeed_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | >KCS_BMC_EVENT_TYPE_OBE), 0); > aspeed_kcs_enable_channel(kcs_bmc, true); > > rc = kcs_bmc_add_device(>kcs_bmc); >diff --git a/drivers/char/ipmi/kcs_bmc_npcm7xx.c >b/drivers/char/ipmi/kcs_bmc_npcm7xx.c >index c2032728a03d..fdf35cad2eba 100644 >--- a/drivers/char/ipmi/kcs_bmc_npcm7xx.c >+++ b/drivers/char/ipmi/kcs_bmc_npcm7xx.c >@@ -207,8 +207,7 @@ static int npcm7xx_kcs_probe(struct platform_device *pdev) > if (rc) > return rc; > >- npcm7xx_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | >KCS_BMC_EVENT_TYPE_OBE), >- KCS_BMC_EVENT_TYPE_IBF); >+ npcm7xx_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | >KCS_BMC_EVENT_TYPE_OBE), 0); > npcm7xx_kcs_enable_channel(kcs_bmc, true); > > pr_info("channel=%u idr=0x%x odr=0x%x str=0x%x\n", >-- >2.27.0 >
Re: [PATCH v5 2/4] drivers/tty/serial/8250: refactor sirq and lpc address setting code
On Thu, 8 Apr 2021, at 10:46, Zev Weiss wrote: > This splits dedicated aspeed_vuart_set_{sirq,lpc_address}() functions > out of the sysfs store functions in preparation for adding DT > properties that will be poking the same registers. While we're at it, > these functions now provide some basic bounds-checking on their > arguments. > > Signed-off-by: Zev Weiss > --- > drivers/tty/serial/8250/8250_aspeed_vuart.c | 51 ++--- > 1 file changed, 35 insertions(+), 16 deletions(-) > > diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c > b/drivers/tty/serial/8250/8250_aspeed_vuart.c > index c33e02cbde93..8433f8dbb186 100644 > --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c > +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c > @@ -72,22 +72,31 @@ static ssize_t lpc_address_show(struct device *dev, > return snprintf(buf, PAGE_SIZE - 1, "0x%x\n", addr); > } > > +static int aspeed_vuart_set_lpc_address(struct aspeed_vuart *vuart, u32 addr) > +{ > + if (addr > U16_MAX) > + return -EINVAL; > + > + writeb(addr >> 8, vuart->regs + ASPEED_VUART_ADDRH); > + writeb(addr >> 0, vuart->regs + ASPEED_VUART_ADDRL); > + > + return 0; > +} > + > static ssize_t lpc_address_store(struct device *dev, >struct device_attribute *attr, >const char *buf, size_t count) > { > struct aspeed_vuart *vuart = dev_get_drvdata(dev); > - unsigned long val; > + u32 val; > int err; > > - err = kstrtoul(buf, 0, ); > + err = kstrtou32(buf, 0, ); > if (err) > return err; > > - writeb(val >> 8, vuart->regs + ASPEED_VUART_ADDRH); > - writeb(val >> 0, vuart->regs + ASPEED_VUART_ADDRL); > - > - return count; > + err = aspeed_vuart_set_lpc_address(vuart, val); > + return err ? : count; > } > > static DEVICE_ATTR_RW(lpc_address); > @@ -105,27 +114,37 @@ static ssize_t sirq_show(struct device *dev, > return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg); > } > > +static int aspeed_vuart_set_sirq(struct aspeed_vuart *vuart, u32 sirq) > +{ > + u8 reg; > + > + if (sirq > (ASPEED_VUART_GCRB_HOST_SIRQ_MASK >> > ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT)) > + return -EINVAL; > + > + sirq <<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT; > + sirq &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK; This might be less verbose if we reordered things a little: ``` sirq <<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT; if (sirq & ASPEED_VUART_GCRB_HOST_SIRQ_MASK) return -EINVAL; sirq &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK; ``` But otherwise it looks okay, so Reviewed-by: Andrew Jeffery > + > + reg = readb(vuart->regs + ASPEED_VUART_GCRB); > + reg &= ~ASPEED_VUART_GCRB_HOST_SIRQ_MASK; > + reg |= sirq; > + writeb(reg, vuart->regs + ASPEED_VUART_GCRB); > + > + return 0; > +} > + > static ssize_t sirq_store(struct device *dev, struct device_attribute > *attr, > const char *buf, size_t count) > { > struct aspeed_vuart *vuart = dev_get_drvdata(dev); > unsigned long val; > int err; > - u8 reg; > > err = kstrtoul(buf, 0, ); > if (err) > return err; > > - val <<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT; > - val &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK; > - > - reg = readb(vuart->regs + ASPEED_VUART_GCRB); > - reg &= ~ASPEED_VUART_GCRB_HOST_SIRQ_MASK; > - reg |= val; > - writeb(reg, vuart->regs + ASPEED_VUART_GCRB); > - > - return count; > + err = aspeed_vuart_set_sirq(vuart, val); > + return err ? : count; > } > > static DEVICE_ATTR_RW(sirq); > -- > 2.31.1 > > > ___ > linux-arm-kernel mailing list > linux-arm-ker...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel >
Re: [PATCH 04/10] mm/migrate: make migrate_pages() return nr_succeeded
On Thu, Apr 08, 2021 at 01:40:33PM -0700, Yang Shi wrote: > Thanks a lot for the example code. You didn't miss anything. At first > glance, I thought your suggestion seemed neater. Actually I > misunderstood what Dave said about "That could really have caused some > interesting problems." with multiple calls to migrate_pages(). I was > thinking about: > > unsigned long foo() > { > unsigned long *ret_succeeded; > > migrate_pages(..., ret_succeeded); > > migrate_pages(..., ret_succeeded); > > return *ret_succeeded; > } But that would not be a problem as well. I mean I am not sure what is foo() supposed to do. I assume is supposed to return the *total* number of pages that were migrated? Then could do something like: unsigned long foo() { unsigned long ret_succeeded; unsigned long total_succeeded = 0; migrate_pages(..., _succeeded); total_succeeded += ret_succeeded; migrate_pages(..., _succeeded); total_succeeded += ret_succeeded; return *total_succeeded; } But AFAICS, you would have to do that with Wei Xu's version and with mine, no difference there. IIUC, Dave's concern was that nr_succeeded was only set to 0 at the beginning of the function, and never reset back, which means, we would carry the sum of previous nr_succeeded instead of the nr_succeeded in that round. That would be misleading for e.g: reclaim in case we were to call migrate_pages() several times, as instead of a delta value, nr_succeeded would accumulate. But that won't happen neither with Wei Xu's version nor with mine. -- Oscar Salvador SUSE L3
[next] ERROR: modpost: "dns_query" [fs/cifs/cifs.ko] undefined
Large number of Linux next tag 20210408 builds failed due to these errors. make --silent --keep-going --jobs=8 O=/home/tuxbuild/.cache/tuxmake/builds/1/tmp ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- 'CC=sccache arm-linux-gnueabihf-gcc' 'HOSTCC=sccache gcc' ERROR: modpost: "dns_query" [fs/cifs/cifs.ko] undefined Reported-by: Naresh Kamboju Regressions found on parisc: - build/gcc-9-defconfig - build/gcc-8-defconfig - build/gcc-10-defconfig Regressions found on sh: - build/gcc-9-dreamcast_defconfig - build/gcc-10-dreamcast_defconfig - build/gcc-8-dreamcast_defconfig Regressions found on arm: - build/clang-12-s3c2410_defconfig - build/gcc-8-s3c2410_defconfig - build/clang-10-nhk8815_defconfig - build/gcc-9-s3c2410_defconfig - build/gcc-10-nhk8815_defconfig - build/gcc-8-nhk8815_defconfig - build/gcc-10-s3c2410_defconfig - build/clang-12-nhk8815_defconfig - build/clang-11-s3c2410_defconfig - build/gcc-9-nhk8815_defconfig - build/clang-11-nhk8815_defconfig - build/clang-10-s3c2410_defconfig -- Linaro LKFT https://lkft.linaro.org
Re: [PATCH v6 4/8] mm,memory_hotplug: Allocate memmap from the added memory range
On Wed, 07 Apr 2021 22:38:37 +0200 Oscar Salvador wrote: > On 2021-04-06 22:28, Oscar Salvador wrote: > > Heh, it seems I spaced out today. > > > > We need a few things on top: > > > Yes please.
Re: [PATCH v4 0/8] make hugetlb put_page safe for all calling contexts
On Thu, 8 Apr 2021 09:11:30 +0200 Oscar Salvador wrote: > But if It is going to be easier for Andrew, just pull them all out and I > will resend the whole series once this work goes in. I think so. I shall drop these: mmpage_alloc-bail-out-earlier-on-enomem-in-alloc_contig_migrate_range.patch mmcompaction-let-isolate_migratepages_rangeblock-return-error-codes.patch mmcompaction-let-isolate_migratepages_rangeblock-return-error-codes-fix.patch mm-make-alloc_contig_range-handle-free-hugetlb-pages.patch mm-make-alloc_contig_range-handle-in-use-hugetlb-pages.patch mmpage_alloc-drop-unnecessary-checks-from-pfn_range_valid_contig.patch and these: mm-cma-change-cma-mutex-to-irq-safe-spinlock.patch hugetlb-no-need-to-drop-hugetlb_lock-to-call-cma_release.patch hugetlb-add-per-hstate-mutex-to-synchronize-user-adjustments.patch hugetlb-create-remove_hugetlb_page-to-separate-functionality.patch hugetlb-call-update_and_free_page-without-hugetlb_lock.patch hugetlb-change-free_pool_huge_page-to-remove_pool_huge_page.patch hugetlb-make-free_huge_page-irq-safe.patch hugetlb-make-free_huge_page-irq-safe-fix.patch hugetlb-add-lockdep_assert_held-calls-for-hugetlb_lock.patch Along with notes-to-self that this: https://lkml.kernel.org/r/YGwnPCPaq1xKh/8...@hirez.programming.kicks-ass.net might need attention and that this: hugetlb-make-free_huge_page-irq-safe.patch might need updating.
Re: [PATCH v4] lib/string: Introduce sysfs_streqcase
On Thu, 8 Apr 2021 15:06:05 +0200 Gioh Kim wrote: > As the name shows, it checks if strings are equal in case insensitive > manner. Peh. Who would die if we simply made sysfs_streq() case-insensitive?
Re: [PATCH] init/version.c: remove unused including
On Thu, 8 Apr 2021 14:26:58 +0800 Tian Tao wrote: > Remove including that don't need it. > Um, how can version.c possibly not include version.h? Sure, it may obtain access to version.h via some other include, but that's plain luck and nonsense. And it's unreliable and it requires whichever-header-is-doing-this to continue to include version.h on behalf of some .c file which should be including it directly!
Re: [PATCH 0/9] userfaultfd: add minor fault handling for shmem
On Thu, 8 Apr 2021 16:43:18 -0700 Axel Rasmussen wrote: > The idea is that it will apply cleanly to akpm's tree, *replacing* the > following > patches (i.e., drop these first, and then apply this series): > > userfaultfd-support-minor-fault-handling-for-shmem.patch > userfaultfd-support-minor-fault-handling-for-shmem-fix.patch > userfaultfd-support-minor-fault-handling-for-shmem-fix-2.patch > userfaultfd-support-minor-fault-handling-for-shmem-fix-3.patch > userfaultfd-support-minor-fault-handling-for-shmem-fix-4.patch > userfaultfd-selftests-use-memfd_create-for-shmem-test-type.patch > userfaultfd-selftests-create-alias-mappings-in-the-shmem-test.patch > userfaultfd-selftests-reinitialize-test-context-in-each-test.patch > userfaultfd-selftests-exercise-minor-fault-handling-shmem-support.patch Well. the problem is, > + if (area_alias == MAP_FAILED) > + err("mmap of memfd alias failed"); `err' doesn't exist until eleventy patches later, in Peter's "userfaultfd/selftests: unify error handling". I got tired of (and lost confidence in) replacing "err(...)" with "fprintf(stderr, ...); exit(1)" everywhere then fixing up the fallout when Peter's patch came along. Shudder. Sorry, all this material pretty clearly isn't going to make 5.12 (potentially nine days hence), so I shall drop all the userfaultfd patches. Let's take a fresh run at all of this after -rc1. I have tentatively retained the first series: userfaultfd-add-minor-fault-registration-mode.patch userfaultfd-add-minor-fault-registration-mode-fix.patch userfaultfd-disable-huge-pmd-sharing-for-minor-registered-vmas.patch userfaultfd-hugetlbfs-only-compile-uffd-helpers-if-config-enabled.patch userfaultfd-add-uffdio_continue-ioctl.patch userfaultfd-update-documentation-to-describe-minor-fault-handling.patch userfaultfd-selftests-add-test-exercising-minor-fault-handling.patch but I don't believe they have had much testing standalone, without the other userfaultfd patches present. So I don't think it's smart to upstream these in this cycle. Or I could drop them so you and Peter can have a clean shot at redoing the whole thing. Please let me know.
Re: [PATCH 4/4] mm/hugeltb: handle the error case in hugetlb_fix_reserve_counts()
On Fri, 9 Apr 2021 11:17:49 +0800 Miaohe Lin wrote: > On 2021/4/9 7:25, Mike Kravetz wrote: > > On 4/2/21 2:32 AM, Miaohe Lin wrote: > >> A rare out of memory error would prevent removal of the reserve map region > >> for a page. hugetlb_fix_reserve_counts() handles this rare case to avoid > >> dangling with incorrect counts. Unfortunately, hugepage_subpool_get_pages > >> and hugetlb_acct_memory could possibly fail too. We should correctly handle > >> these cases. > > > > Yes, this is a potential issue. > > > > The 'good news' is that hugetlb_fix_reserve_counts() is unlikely to ever > > be called. To do so would imply we could not allocate a region entry > > which is only 6 words in size. We also keep a 'cache' of entries so we > > may not even need to allocate. > > > > But, as mentioned it is a potential issue. > > Yes, a potential *theoretical* issue. > > > > >> Fixes: b5cec28d36f5 ("hugetlbfs: truncate_hugepages() takes a range of > >> pages") > > > > This is likely going to make this get picked by by stable releases. > > That is unfortunate as mentioned above this is mostly theoretical. > > > > I will drop this. This does not worth backport. > -stable have been asked not to backport MM patches unless MM patches include "cc:stable". ie, no making our backporting decisions for us, please.
[PATCH -next] media: camss: ispif: Remove redundant dev_err call in msm_ispif_subdev_init()
There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Reported-by: Hulk Robot Signed-off-by: Yang Yingliang --- drivers/media/platform/qcom/camss/camss-ispif.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index a30e453de162..37611c8861da 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -1145,17 +1145,13 @@ int msm_ispif_subdev_init(struct camss *camss, r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); ispif->base = devm_ioremap_resource(dev, r); - if (IS_ERR(ispif->base)) { - dev_err(dev, "could not map memory\n"); + if (IS_ERR(ispif->base)) return PTR_ERR(ispif->base); - } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[1]); ispif->base_clk_mux = devm_ioremap_resource(dev, r); - if (IS_ERR(ispif->base_clk_mux)) { - dev_err(dev, "could not map memory\n"); + if (IS_ERR(ispif->base_clk_mux)) return PTR_ERR(ispif->base_clk_mux); - } /* Interrupt */ -- 2.25.1
[PATCH -next] staging: rtl8723bs: remove unused variable pwrctl
GCC reports the following warning with W=1: drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c:532:23: warning: variable 'pwrctl' set but not used [-Wunused-but-set-variable] 532 | struct pwrctrl_priv *pwrctl; | ^~ This variable is not used so remove it to fix the warning. Signed-off-by: Pu Lehui --- drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c b/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c index f2ab878babcb..f8c6028f89f3 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c @@ -529,7 +529,6 @@ static void rtl8723b_set_FwRsvdPagePkt( struct xmit_priv *pxmitpriv; struct mlme_ext_priv *pmlmeext; struct mlme_ext_info *pmlmeinfo; - struct pwrctrl_priv *pwrctl; struct mlme_priv *pmlmepriv = >mlmepriv; u32 BeaconLength = 0, PSPollLength = 0; u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0; @@ -544,7 +543,6 @@ static void rtl8723b_set_FwRsvdPagePkt( pxmitpriv = >xmitpriv; pmlmeext = >mlmeextpriv; pmlmeinfo = >mlmext_info; - pwrctl = adapter_to_pwrctl(padapter); RsvdPageNum = BCNQ_PAGE_NUM_8723B + WOWLAN_PAGE_NUM_8723B; MaxRsvdPageBufSize = RsvdPageNum*PageSize; -- 2.17.1
答复: [PATCH v1 01/14] vfio: Create vfio_fs_type with inode per device
> -邮件原件- > 发件人: Alex Williamson [mailto:alex.william...@redhat.com] > 发送时间: 2021年3月9日 5:47 > 收件人: alex.william...@redhat.com > 抄送: coh...@redhat.com; k...@vger.kernel.org; > linux-kernel@vger.kernel.org; j...@nvidia.com; pet...@redhat.com > 主题: [PATCH v1 01/14] vfio: Create vfio_fs_type with inode per device > > By linking all the device fds we provide to userspace to an address space > through a new pseudo fs, we can use tools like > unmap_mapping_range() to zap all vmas associated with a device. > > Suggested-by: Jason Gunthorpe > Signed-off-by: Alex Williamson > --- > drivers/vfio/vfio.c | 54 > +++ > 1 file changed, 54 insertions(+) > > diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index > 38779e6fd80c..abdf8d52a911 100644 > --- a/drivers/vfio/vfio.c > +++ b/drivers/vfio/vfio.c > @@ -32,11 +32,18 @@ > #include > #include > #include > +#include > +#include Minor: keep the headers in alphabetical order. > > #define DRIVER_VERSION "0.3" > #define DRIVER_AUTHOR"Alex Williamson " > #define DRIVER_DESC "VFIO - User Level meta-driver" > > +#define VFIO_MAGIC 0x5646494f /* "VFIO" */ Move to include/uapi/linux/magic.h ? > + > +static int vfio_fs_cnt; > +static struct vfsmount *vfio_fs_mnt; > + > static struct vfio { > struct class*class; > struct list_headiommu_drivers_list; > @@ -97,6 +104,7 @@ struct vfio_device { > struct vfio_group *group; > struct list_headgroup_next; > void*device_data; > + struct inode*inode; > }; > > #ifdef CONFIG_VFIO_NOIOMMU > @@ -529,6 +537,34 @@ static struct vfio_group > *vfio_group_get_from_dev(struct device *dev) > return group; > } > > +static int vfio_fs_init_fs_context(struct fs_context *fc) { > + return init_pseudo(fc, VFIO_MAGIC) ? 0 : -ENOMEM; } > + > +static struct file_system_type vfio_fs_type = { > + .name = "vfio", > + .owner = THIS_MODULE, > + .init_fs_context = vfio_fs_init_fs_context, > + .kill_sb = kill_anon_super, > +}; > + > +static struct inode *vfio_fs_inode_new(void) { > + struct inode *inode; > + int ret; > + > + ret = simple_pin_fs(_fs_type, _fs_mnt, _fs_cnt); > + if (ret) > + return ERR_PTR(ret); > + > + inode = alloc_anon_inode(vfio_fs_mnt->mnt_sb); > + if (IS_ERR(inode)) > + simple_release_fs(_fs_mnt, _fs_cnt); > + > + return inode; > +} > + > /** > * Device objects - create, release, get, put, search > */ > @@ -539,11 +575,19 @@ struct vfio_device > *vfio_group_create_device(struct vfio_group *group, >void *device_data) > { > struct vfio_device *device; > + struct inode *inode; > > device = kzalloc(sizeof(*device), GFP_KERNEL); > if (!device) > return ERR_PTR(-ENOMEM); > > + inode = vfio_fs_inode_new(); > + if (IS_ERR(inode)) { > + kfree(device); > + return ERR_CAST(inode); > + } > + device->inode = inode; > + > kref_init(>kref); > device->dev = dev; > device->group = group; > @@ -574,6 +618,9 @@ static void vfio_device_release(struct kref *kref) > > dev_set_drvdata(device->dev, NULL); > > + iput(device->inode); > + simple_release_fs(_fs_mnt, _fs_cnt); > + > kfree(device); > > /* vfio_del_group_dev may be waiting for this device */ @@ -1488,6 > +1535,13 @@ static int vfio_group_get_device_fd(struct vfio_group *group, > char *buf) >*/ > filep->f_mode |= (FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); > > + /* > + * Use the pseudo fs inode on the device to link all mmaps > + * to the same address space, allowing us to unmap all vmas > + * associated to this device using unmap_mapping_range(). > + */ > + filep->f_mapping = device->inode->i_mapping; > + > atomic_inc(>container_users); > > fd_install(ret, filep);
Re: [PATCH] nilfs2: Fix typos in comments
Hi Andrew, Please also queue this typo fix patch that came separately. Thanks, Ryusuke Konishi On Fri, Apr 9, 2021 at 1:35 PM Ryusuke Konishi wrote: > > From: Lu Jialin > > numer -> number in fs/nilfs2/cpfile.c > Decription -> Description in fs/nilfs2/ioctl.c > isntance -> instance in fs/nilfs2/the_nilfs.c > > Signed-off-by: Lu Jialin > Link: https://lore.kernel.org/r/20210409022519.176988-1-lujial...@huawei.com > Signed-off-by: Ryusuke Konishi > --- > fs/nilfs2/cpfile.c| 2 +- > fs/nilfs2/ioctl.c | 4 ++-- > fs/nilfs2/the_nilfs.c | 2 +- > 3 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c > index 025fb082575a..ce144776b4ef 100644 > --- a/fs/nilfs2/cpfile.c > +++ b/fs/nilfs2/cpfile.c > @@ -293,7 +293,7 @@ void nilfs_cpfile_put_checkpoint(struct inode *cpfile, > __u64 cno, > * nilfs_cpfile_delete_checkpoints - delete checkpoints > * @cpfile: inode of checkpoint file > * @start: start checkpoint number > - * @end: end checkpoint numer > + * @end: end checkpoint number > * > * Description: nilfs_cpfile_delete_checkpoints() deletes the checkpoints in > * the period from @start to @end, excluding @end itself. The checkpoints > diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c > index b053b40315bf..d1db73030085 100644 > --- a/fs/nilfs2/ioctl.c > +++ b/fs/nilfs2/ioctl.c > @@ -1058,7 +1058,7 @@ static int nilfs_ioctl_resize(struct inode *inode, > struct file *filp, > * @inode: inode object > * @argp: pointer on argument from userspace > * > - * Decription: nilfs_ioctl_trim_fs is the FITRIM ioctl handle function. It > + * Description: nilfs_ioctl_trim_fs is the FITRIM ioctl handle function. It > * checks the arguments from userspace and calls nilfs_sufile_trim_fs, which > * performs the actual trim operation. > * > @@ -1100,7 +1100,7 @@ static int nilfs_ioctl_trim_fs(struct inode *inode, > void __user *argp) > * @inode: inode object > * @argp: pointer on argument from userspace > * > - * Decription: nilfs_ioctl_set_alloc_range() function defines lower limit > + * Description: nilfs_ioctl_set_alloc_range() function defines lower limit > * of segments in bytes and upper limit of segments in bytes. > * The NILFS_IOCTL_SET_ALLOC_RANGE is used by nilfs_resize utility. > * > diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c > index 221a1cc597f0..8b7b01a380ce 100644 > --- a/fs/nilfs2/the_nilfs.c > +++ b/fs/nilfs2/the_nilfs.c > @@ -195,7 +195,7 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs, > /** > * load_nilfs - load and recover the nilfs > * @nilfs: the_nilfs structure to be released > - * @sb: super block isntance used to recover past segment > + * @sb: super block instance used to recover past segment > * > * load_nilfs() searches and load the latest super root, > * attaches the last segment, and does recovery if needed. > -- > 1.8.3.1 >
[PATCH -next] clocksource/drivers/qcom: add missing iounmap() on error in msm_dt_timer_init()
base and cpu0_base are not unmapped on error path, add the missing iounmap() before return msm_dt_timer_init() in the error handling cases. Fixes: 6e3321631ac2 ("ARM: msm: Add DT support to msm_timer") Reported-by: Hulk Robot Signed-off-by: Yang Yingliang --- drivers/clocksource/timer-qcom.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/clocksource/timer-qcom.c b/drivers/clocksource/timer-qcom.c index b4afe3a67583..3488876198e0 100644 --- a/drivers/clocksource/timer-qcom.c +++ b/drivers/clocksource/timer-qcom.c @@ -213,7 +213,8 @@ static int __init msm_dt_timer_init(struct device_node *np) irq = irq_of_parse_and_map(np, 1); if (irq <= 0) { pr_err("Can't get irq\n"); - return -EINVAL; + ret = -EINVAL; + goto err_unmap_base; } /* We use CPU0's DGT for the clocksource */ @@ -223,18 +224,19 @@ static int __init msm_dt_timer_init(struct device_node *np) ret = of_address_to_resource(np, 0, ); if (ret) { pr_err("Failed to parse DGT resource\n"); - return ret; + goto err_unmap_base; } cpu0_base = ioremap(res.start + percpu_offset, resource_size()); if (!cpu0_base) { pr_err("Failed to map source base\n"); - return -EINVAL; + goto err_unmap_base; } if (of_property_read_u32(np, "clock-frequency", )) { pr_err("Unknown frequency\n"); - return -EINVAL; + ret = -EINVAL; + goto err_unmap_cpu0_base; } event_base = base + 0x4; @@ -243,7 +245,18 @@ static int __init msm_dt_timer_init(struct device_node *np) freq /= 4; writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); - return msm_timer_init(freq, 32, irq, !!percpu_offset); + ret = msm_timer_init(freq, 32, irq, !!percpu_offset); + if (ret) + goto err_unmap_cpu0_base; + + return 0; + +err_unmap_cpu0_base: + iounmap(cpu0_base); +err_unmap_base: + iounmap(base); + + return ret; } TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); -- 2.25.1
[PATCH 2/2] arm64: dts: mt8183: Add panel rotation
krane, kakadu, and kodama boards have a default panel rotation. Signed-off-by: Hsin-Yi Wang --- arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index ff56bcfa3370..793cc9501337 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -263,6 +263,7 @@ panel: panel@0 { avee-supply = <_lcd>; pp1800-supply = <_lcd>; backlight = <_lcd0>; + rotation = <270>; port { panel_in: endpoint { remote-endpoint = <_out>; -- 2.31.1.295.g9ea45b61b8-goog
[PATCH 1/2] drm/mediatek: set panel orientation before drm_dev_register().
drm_dev_register() sets connector->registration_state to DRM_CONNECTOR_REGISTERED and dev->registered to true. If drm_connector_set_panel_orientation() is first called after drm_dev_register(), it will fail several checks and results in following warning. So set panel orientation in dsi before drm_dev_register() is called. [4.480976] [ cut here ] [4.485603] WARNING: CPU: 5 PID: 369 at drivers/gpu/drm/drm_mode_object.c:45 __drm_mode_object_add+0xb4/0xbc [4.609772] Call trace: [4.612208] __drm_mode_object_add+0xb4/0xbc [4.616466] drm_mode_object_add+0x20/0x2c [4.620552] drm_property_create+0xdc/0x174 [4.624723] drm_property_create_enum+0x34/0x98 [4.629241] drm_connector_set_panel_orientation+0x64/0xa0 [4.634716] boe_panel_get_modes+0x88/0xd8 [4.638802] drm_panel_get_modes+0x2c/0x48 [4.642887] panel_bridge_get_modes+0x1c/0x28 [4.647233] drm_bridge_connector_get_modes+0xa0/0xd4 [4.652273] drm_helper_probe_single_connector_modes+0x218/0x700 [4.658266] drm_mode_getconnector+0x1b4/0x45c [4.662699] drm_ioctl_kernel+0xac/0x128 [4.11] drm_ioctl+0x268/0x410 [4.670002] drm_compat_ioctl+0xdc/0xf0 [4.673829] __arm64_compat_sys_ioctl+0xc8/0x100 [4.678436] el0_svc_common+0xf4/0x1c0 [4.682174] do_el0_svc_compat+0x28/0x3c [4.686088] el0_svc_compat+0x10/0x1c [4.689738] el0_sync_compat_handler+0xa8/0xcc [4.694171] el0_sync_compat+0x178/0x180 [4.698082] ---[ end trace b4f2db9d9c88610b ]--- [4.702721] [ cut here ] [4.707329] WARNING: CPU: 5 PID: 369 at drivers/gpu/drm/drm_mode_object.c:243 drm_object_attach_property+0x48/0xb8 [4.833830] Call trace: [4.836266] drm_object_attach_property+0x48/0xb8 [4.840958] drm_connector_set_panel_orientation+0x84/0xa0 [4.846432] boe_panel_get_modes+0x88/0xd8 [4.850516] drm_panel_get_modes+0x2c/0x48 [4.854600] panel_bridge_get_modes+0x1c/0x28 [4.858946] drm_bridge_connector_get_modes+0xa0/0xd4 [4.863984] drm_helper_probe_single_connector_modes+0x218/0x700 [4.869978] drm_mode_getconnector+0x1b4/0x45c [4.874410] drm_ioctl_kernel+0xac/0x128 [4.878320] drm_ioctl+0x268/0x410 [4.881711] drm_compat_ioctl+0xdc/0xf0 [4.885536] __arm64_compat_sys_ioctl+0xc8/0x100 [4.890142] el0_svc_common+0xf4/0x1c0 [4.893879] do_el0_svc_compat+0x28/0x3c [4.897791] el0_svc_compat+0x10/0x1c [4.901441] el0_sync_compat_handler+0xa8/0xcc [4.905873] el0_sync_compat+0x178/0x180 [4.909783] ---[ end trace b4f2db9d9c88610c ]--- Signed-off-by: Hsin-Yi Wang --- drivers/gpu/drm/mediatek/mtk_dsi.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index ae403c67cbd9..45a702ee09f3 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -205,6 +205,7 @@ struct mtk_dsi { u32 irq_data; wait_queue_head_t irq_wait_queue; const struct mtk_dsi_driver_data *driver_data; + enum drm_panel_orientation orientation; }; static inline struct mtk_dsi *bridge_to_dsi(struct drm_bridge *b) @@ -966,6 +967,8 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi) } drm_connector_attach_encoder(dsi->connector, >encoder); + drm_connector_set_panel_orientation(dsi->connector, dsi->orientation); + return 0; err_cleanup_encoder: @@ -1029,6 +1032,12 @@ static int mtk_dsi_probe(struct platform_device *pdev) ret = PTR_ERR(dsi->next_bridge); goto err_unregister_host; } + + ret = of_drm_get_panel_orientation(panel->dev->of_node, >orientation); + if (ret) { + dev_err(dev, "failed to get panel orientation %d\n", ret); + return ret; + } } dsi->driver_data = of_device_get_match_data(dev); -- 2.31.1.295.g9ea45b61b8-goog
Re: [PATCH 1/7] x86/syscalls: fix -Wmissing-prototypes warnings from COND_SYSCALL()
Hello, x86 maintainers, Thanks for picking up 1/7. Could you check 2/7 - 7/7, please? Thank you. On Thu, Mar 25, 2021 at 11:31 PM Masahiro Yamada wrote: > > On Thu, Mar 25, 2021 at 8:48 PM Mickaël Salaün wrote: > > > > Hi Masahiro, > > > > What is the status of this patch? Could you please push it to -next? > > This would avoid emails from lkp: > > https://lore.kernel.org/linux-security-module/202103191423.jl0jvzfl-...@intel.com/ > > > Hmm, I also want to know the answer. > This is the *third* time that I resent this patch > to the x86 ML. > > This is a territory of the x86 subsystem > because it is only touching > arch/x86/include/asm/syscall_wrapper.h > It is preferred to get this in via the x86 tree. > > x86 Maintainers, > could you take a look please? > > > -- Best Regards Masahiro Yamada
Re: [PATCH v14 06/13] iommu/smmuv3: Allow stage 1 invalidation with unmanaged ASIDs
Hi Eric, On 2021/4/8 20:30, Auger Eric wrote: Hi Kunkun, On 4/1/21 2:37 PM, Kunkun Jiang wrote: Hi Eric, On 2021/2/24 4:56, Eric Auger wrote: With nested stage support, soon we will need to invalidate S1 contexts and ranges tagged with an unmanaged asid, this latter being managed by the guest. So let's introduce 2 helpers that allow to invalidate with externally managed ASIDs Signed-off-by: Eric Auger --- v13 -> v14 - Actually send the NH_ASID command (reported by Xingang Wang) --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 38 - 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 5579ec4fccc8..4c19a1114de4 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -1843,9 +1843,9 @@ int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid, } /* IO_PGTABLE API */ -static void arm_smmu_tlb_inv_context(void *cookie) +static void __arm_smmu_tlb_inv_context(struct arm_smmu_domain *smmu_domain, + int ext_asid) { - struct arm_smmu_domain *smmu_domain = cookie; struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cmdq_ent cmd; @@ -1856,7 +1856,13 @@ static void arm_smmu_tlb_inv_context(void *cookie) * insertion to guarantee those are observed before the TLBI. Do be * careful, 007. */ - if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { + if (ext_asid >= 0) { /* guest stage 1 invalidation */ + cmd.opcode = CMDQ_OP_TLBI_NH_ASID; + cmd.tlbi.asid = ext_asid; + cmd.tlbi.vmid = smmu_domain->s2_cfg.vmid; + arm_smmu_cmdq_issue_cmd(smmu, ); + arm_smmu_cmdq_issue_sync(smmu); + } else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { arm_smmu_tlb_inv_asid(smmu, smmu_domain->s1_cfg.cd.asid); } else { cmd.opcode = CMDQ_OP_TLBI_S12_VMALL; @@ -1867,6 +1873,13 @@ static void arm_smmu_tlb_inv_context(void *cookie) arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0); } +static void arm_smmu_tlb_inv_context(void *cookie) +{ + struct arm_smmu_domain *smmu_domain = cookie; + + __arm_smmu_tlb_inv_context(smmu_domain, -1); +} + static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd, unsigned long iova, size_t size, size_t granule, @@ -1926,9 +1939,10 @@ static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd, arm_smmu_cmdq_batch_submit(smmu, ); } Here is the part of code in __arm_smmu_tlb_inv_range(): if (smmu->features & ARM_SMMU_FEAT_RANGE_INV) { /* Get the leaf page size */ tg = __ffs(smmu_domain->domain.pgsize_bitmap); /* Convert page size of 12,14,16 (log2) to 1,2,3 */ cmd->tlbi.tg = (tg - 10) / 2; /* Determine what level the granule is at */ cmd->tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3)); num_pages = size >> tg; } When pSMMU supports RIL, we get the leaf page size by __ffs(smmu_domain-> domain.pgsize_bitmap). In nested mode, it is determined by host PAGE_SIZE. If the host kernel and guest kernel has different translation granule (e.g. host 16K, guest 4K), __arm_smmu_tlb_inv_range() will issue an incorrect tlbi command. Do you have any idea about this issue? I think this is the same issue as the one reported by Chenxiang https://lore.kernel.org/lkml/15938ed5-2095-e903-a290-333c29901...@hisilicon.com/ In case RIL is not supported by the host, next version will use the smallest pSMMU supported page size, as done in __arm_smmu_tlb_inv_range Thanks Eric I think they are different. In normal cases, when we want to invalidate the cache of stage 1, we should use the granule size supported by vSMMU to implement and issue an tlbi command if pSMMU supports RIL. But in the current __arm_smmu_tlb_inv_range(), it always uses the granule size supported by host. (tg = __ffs(smmu_domain->domain.pgsize_bitmap);) Let me explain more clearly. Preconditions of this issue: 1. pSMMU supports RIL 2. host and guest use different translation granule (e.g. host 16K, guest 4K) Guest wants to invalidate 4K, so info->granule_size = 4K. In __arm_smmu_tlb_inv_range(), if pSMMU supports RIL and host 16K, tg = 14, tlbi.tg = 2, tlbi.ttl = 4, tlbi.scale = 0, tlbi.num = -1. It is an incorrect tlbi command. So it would be better to pass the leaf page size supported by vSMMU to host. Perhaps this issue and the one reported by Chenxiang can be solved together. Thanks, Kunkun Jiang Best Regards, Kunkun Jiang -static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size, - size_t granule, bool leaf, - struct arm_smmu_domain *smmu_domain) +static void
Re: [RFC PATCH] vdpa: mandate 1.0 device
在 2021/4/8 下午11:59, Michael S. Tsirkin 写道: On Thu, Apr 08, 2021 at 04:26:48PM +0800, Jason Wang wrote: This patch mandates 1.0 for vDPA devices. The goal is to have the semantic of normative statement in the virtio spec and eliminate the burden of transitional device for both vDPA bus and vDPA parent. uAPI seems fine since all the vDPA parent mandates VIRTIO_F_ACCESS_PLATFORM which implies 1.0 devices. For legacy guests, it can still work since Qemu will mediate when necessary (e.g doing the endian conversion). Signed-off-by: Jason Wang Hmm. If we do this, don't we still have a problem with legacy drivers which don't ack 1.0? Yes, but it's not something that is introduced in this commit. The legacy driver never work ... Note 1.0 affects ring endianness which is not mediated in QEMU so QEMU can't pretend to device guest is 1.0. Right, I plan to send patches to do mediation in the Qemu to unbreak legacy drivers. Thanks --- include/linux/vdpa.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h index 0fefeb976877..cfde4ec999b4 100644 --- a/include/linux/vdpa.h +++ b/include/linux/vdpa.h @@ -6,6 +6,7 @@ #include #include #include +#include /** * vDPA callback definition. @@ -317,6 +318,11 @@ static inline int vdpa_set_features(struct vdpa_device *vdev, u64 features) { const struct vdpa_config_ops *ops = vdev->config; +/* Mandating 1.0 to have semantics of normative statements in + * the spec. */ +if (!(features & BIT_ULL(VIRTIO_F_VERSION_1))) + return -EINVAL; + vdev->features_valid = true; return ops->set_features(vdev, features); } -- 2.25.1
[PATCH v3] bus: mhi: core: Fix shadow declarations
This commit fixes below sparse warnings with W=2 about shadow declarations: drivers/bus/mhi/core/main.c: In function ‘parse_xfer_event’: drivers/bus/mhi/core/main.c:667:17: warning: declaration of ‘flags’ shadows a previous local [-Wshadow] 667 | unsigned long flags; | ^ drivers/bus/mhi/core/main.c:565:16: note: shadowed declaration is here 565 | unsigned long flags = 0; |^ drivers/bus/mhi/core/main.c: In function ‘mhi_process_ctrl_ev_ring’: drivers/bus/mhi/core/main.c:856:23: warning: declaration of ‘new_state’ shadows a previous local [-Wshadow] 856 | enum mhi_pm_state new_state; | ^ drivers/bus/mhi/core/main.c:837:19: note: shadowed declaration is here 837 |enum mhi_state new_state; | ^ Signed-off-by: Manivannan Sadhasivam --- Changes in v3: * Fixed the usage of "flags" by renaming to "pm_lock_flags" drivers/bus/mhi/core/main.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c index b0c8afe16e3a..22acde118bc3 100644 --- a/drivers/bus/mhi/core/main.c +++ b/drivers/bus/mhi/core/main.c @@ -664,15 +664,15 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, case MHI_EV_CC_OOB: case MHI_EV_CC_DB_MODE: { - unsigned long flags; + unsigned long pm_lock_flags; mhi_chan->db_cfg.db_mode = 1; - read_lock_irqsave(_cntrl->pm_lock, flags); + read_lock_irqsave(_cntrl->pm_lock, pm_lock_flags); if (tre_ring->wp != tre_ring->rp && MHI_DB_ACCESS_VALID(mhi_cntrl)) { mhi_ring_chan_db(mhi_cntrl, mhi_chan); } - read_unlock_irqrestore(_cntrl->pm_lock, flags); + read_unlock_irqrestore(_cntrl->pm_lock, pm_lock_flags); break; } case MHI_EV_CC_BAD_TRE: @@ -853,14 +853,14 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, break; case MHI_STATE_SYS_ERR: { - enum mhi_pm_state new_state; + enum mhi_pm_state pm_state; dev_dbg(dev, "System error detected\n"); write_lock_irq(_cntrl->pm_lock); - new_state = mhi_tryset_pm_state(mhi_cntrl, + pm_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_SYS_ERR_DETECT); write_unlock_irq(_cntrl->pm_lock); - if (new_state == MHI_PM_SYS_ERR_DETECT) + if (pm_state == MHI_PM_SYS_ERR_DETECT) mhi_pm_sys_err_handler(mhi_cntrl); break; } -- 2.25.1
[PATCH -next] soc/tegra: fuse: add missing iounmap() on error in tegra_init_fuse()
Add the missing iounmap() before return from tegra_init_fuse() in the error handling case. Fixes: 9f94fadd75d3 ("soc/tegra: fuse: Register cell lookups for compatibility") Reported-by: Hulk Robot Signed-off-by: Yang Yingliang --- drivers/soc/tegra/fuse/fuse-tegra.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 94b60a692b51..bc8d70e6a676 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -489,8 +489,10 @@ static int __init tegra_init_fuse(void) size_t size = sizeof(*fuse->lookups) * fuse->soc->num_lookups; fuse->lookups = kmemdup(fuse->soc->lookups, size, GFP_KERNEL); - if (!fuse->lookups) + if (!fuse->lookups) { + iounmap(fuse->base); return -ENOMEM; + } nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups); } -- 2.25.1
[PATCH V2 2/2] soc: qcom: aoss: Add debugfs entry
It can be useful to control the different power states of various parts of hardware for device testing. Add a debugfs node for qmp so messages can be sent to aoss for debugging and testing purposes. Signed-off-by: Chris Lew Signed-off-by: Deepak Kumar Singh --- drivers/soc/qcom/qcom_aoss.c | 41 + 1 file changed, 41 insertions(+) diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c index 0e397a7..6057bbe 100644 --- a/drivers/soc/qcom/qcom_aoss.c +++ b/drivers/soc/qcom/qcom_aoss.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include #include @@ -88,6 +89,9 @@ struct qmp { struct clk_hw qdss_clk; struct genpd_onecell_data pd_data; struct qmp_cooling_device *cooling_devs; +#if IS_ENABLED(CONFIG_DEBUG_FS) + struct dentry *debugfs_file; +#endif /* CONFIG_DEBUG_FS */ }; struct qmp_pd { @@ -560,6 +564,34 @@ void qmp_put(struct platform_device *pdev) } EXPORT_SYMBOL(qmp_put); +#if IS_ENABLED(CONFIG_DEBUG_FS) +static ssize_t aoss_dbg_write(struct file *file, const char __user *userstr, + size_t len, loff_t *pos) +{ + struct qmp *qmp = file->private_data; + char buf[QMP_MSG_LEN] = {}; + int ret; + + if (!len || len >= QMP_MSG_LEN) + return -EINVAL; + + ret = copy_from_user(buf, userstr, len); + if (ret) { + dev_err(qmp->dev, "copy from user failed, ret:%d\n", ret); + return -EFAULT; + } + + ret = qmp_send(qmp, buf, QMP_MSG_LEN); + + return ret ? ret : len; +} + +static const struct file_operations aoss_dbg_fops = { + .open = simple_open, + .write = aoss_dbg_write, +}; +#endif /* CONFIG_DEBUG_FS */ + static int qmp_probe(struct platform_device *pdev) { struct resource *res; @@ -616,6 +648,11 @@ static int qmp_probe(struct platform_device *pdev) atomic_set(>orphan, 0); +#if IS_ENABLED(CONFIG_DEBUG_FS) + qmp->debugfs_file = debugfs_create_file("aoss_send_message", 0220, NULL, + qmp, _dbg_fops); +#endif /* CONFIG_DEBUG_FS */ + return 0; err_remove_qdss_clk: @@ -632,6 +669,10 @@ static int qmp_remove(struct platform_device *pdev) { struct qmp *qmp = platform_get_drvdata(pdev); +#if IS_ENABLED(CONFIG_DEBUG_FS) + debugfs_remove(qmp->debugfs_file); +#endif /* CONFIG_DEBUG_FS */ + qmp_qdss_clk_remove(qmp); qmp_pd_remove(qmp); qmp_cooling_devices_remove(qmp); -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH V2 1/2] soc: qcom: aoss: Expose send for generic usecase
From: Deepak Kumar Singh Not all upcoming usecases will have an interface to allow the aoss driver to hook onto. Expose the send api and create a get function to enable drivers to send their own messages to aoss. Signed-off-by: Chris Lew Signed-off-by: Deepak Kumar Singh --- drivers/soc/qcom/qcom_aoss.c | 50 +- include/linux/soc/qcom/qcom_aoss.h | 33 + 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 include/linux/soc/qcom/qcom_aoss.h diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c index 53acb94..0e397a7 100644 --- a/drivers/soc/qcom/qcom_aoss.c +++ b/drivers/soc/qcom/qcom_aoss.c @@ -8,10 +8,12 @@ #include #include #include +#include #include #include #include #include +#include #define QMP_DESC_MAGIC 0x0 #define QMP_DESC_VERSION 0x4 @@ -61,6 +63,7 @@ struct qmp_cooling_device { * @mbox_chan: mailbox channel used to ring the doorbell on transmit * @offset: offset within @msgram where messages should be written * @size: maximum size of the messages to be transmitted + * @orphan: tarcks whether qmp handle is valid * @event: wait_queue for synchronization with the IRQ * @tx_lock: provides synchronization between multiple callers of qmp_send() * @qdss_clk: QDSS clock hw struct @@ -76,6 +79,7 @@ struct qmp { size_t offset; size_t size; + atomic_t orphan; wait_queue_head_t event; @@ -223,11 +227,17 @@ static bool qmp_message_empty(struct qmp *qmp) * * Return: 0 on success, negative errno on failure */ -static int qmp_send(struct qmp *qmp, const void *data, size_t len) +int qmp_send(struct qmp *qmp, const void *data, size_t len) { long time_left; int ret; + if (WARN_ON(IS_ERR_OR_NULL(qmp) || !data)) + return -EINVAL; + + if (atomic_read(>orphan)) + return -EINVAL; + if (WARN_ON(len + sizeof(u32) > qmp->size)) return -EINVAL; @@ -261,6 +271,7 @@ static int qmp_send(struct qmp *qmp, const void *data, size_t len) return ret; } +EXPORT_SYMBOL(qmp_send); static int qmp_qdss_clk_prepare(struct clk_hw *hw) { @@ -515,6 +526,40 @@ static void qmp_cooling_devices_remove(struct qmp *qmp) thermal_cooling_device_unregister(qmp->cooling_devs[i].cdev); } +/** + * qmp_get() - get a qmp handle from a device + * @dev: client device pointer + * + * Return: handle to qmp device on success, ERR_PTR() on failure + */ +struct qmp *qmp_get(struct device *dev) +{ + struct platform_device *pdev; + struct device_node *np; + struct qmp *qmp; + + if (!dev || !dev->of_node) + return ERR_PTR(-EINVAL); + + np = of_parse_phandle(dev->of_node, "qcom,qmp", 0); + if (!np) + return ERR_PTR(-ENODEV); + + pdev = of_find_device_by_node(np); + if (!pdev) + return ERR_PTR(-EINVAL); + + qmp = platform_get_drvdata(pdev); + return qmp ? qmp : ERR_PTR(-EPROBE_DEFER); +} +EXPORT_SYMBOL(qmp_get); + +void qmp_put(struct platform_device *pdev) +{ + platform_device_put(pdev); +} +EXPORT_SYMBOL(qmp_put); + static int qmp_probe(struct platform_device *pdev) { struct resource *res; @@ -569,6 +614,8 @@ static int qmp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, qmp); + atomic_set(>orphan, 0); + return 0; err_remove_qdss_clk: @@ -590,6 +637,7 @@ static int qmp_remove(struct platform_device *pdev) qmp_cooling_devices_remove(qmp); qmp_close(qmp); + atomic_set(>orphan, 1); mbox_free_channel(qmp->mbox_chan); return 0; diff --git a/include/linux/soc/qcom/qcom_aoss.h b/include/linux/soc/qcom/qcom_aoss.h new file mode 100644 index 000..27d00f7 --- /dev/null +++ b/include/linux/soc/qcom/qcom_aoss.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __QCOM_AOSS_H__ +#define __QCOM_AOSS_H__ + +#include +#include + +struct qmp; + +#if IS_ENABLED(CONFIG_QCOM_AOSS_QMP) + +int qmp_send(struct qmp *qmp, const void *data, size_t len); +struct qmp *qmp_get(struct device *dev); + +#else + +static inline int qmp_send(struct qmp *qmp, const void *data, size_t len) +{ + return -ENODEV; +} + +static inline struct qmp *qmp_get(struct device *dev) +{ + return ERR_PTR(-ENODEV); +} + +#endif + +#endif -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH V2 0/2] soc: qcom: aoss: Expose send for generic usecase
Change from V1 Addressesed all review comments in previous set. Deepak Kumar Singh (2): soc: qcom: aoss: Expose send for generic usecase soc: qcom: aoss: Add debugfs entry drivers/soc/qcom/qcom_aoss.c | 91 +- include/linux/soc/qcom/qcom_aoss.h | 33 ++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 include/linux/soc/qcom/qcom_aoss.h -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: linux-next: manual merge of the security tree with the ext3 tree
Hi all, On Fri, 19 Mar 2021 13:05:51 +1100 Stephen Rothwell wrote: > > Today's linux-next merge of the security tree got conflicts in: > > arch/alpha/kernel/syscalls/syscall.tbl > arch/arm/tools/syscall.tbl > arch/arm64/include/asm/unistd.h > arch/arm64/include/asm/unistd32.h > arch/ia64/kernel/syscalls/syscall.tbl > arch/m68k/kernel/syscalls/syscall.tbl > arch/microblaze/kernel/syscalls/syscall.tbl > arch/mips/kernel/syscalls/syscall_n32.tbl > arch/mips/kernel/syscalls/syscall_n64.tbl > arch/mips/kernel/syscalls/syscall_o32.tbl > arch/parisc/kernel/syscalls/syscall.tbl > arch/powerpc/kernel/syscalls/syscall.tbl > arch/s390/kernel/syscalls/syscall.tbl > arch/sh/kernel/syscalls/syscall.tbl > arch/sparc/kernel/syscalls/syscall.tbl > arch/x86/entry/syscalls/syscall_32.tbl > arch/x86/entry/syscalls/syscall_64.tbl > arch/xtensa/kernel/syscalls/syscall.tbl > include/uapi/asm-generic/unistd.h > > between commit: > > fa8b90070a80 ("quota: wire up quotactl_path") > > from the ext3 tree and commit: > > 818946f8b806 ("arch: Wire up Landlock syscalls") This is now commit 9fbebb70210a ("arch: Wire up Landlock syscalls") > from the security tree. > > I fixed it up (see below) and can carry the fix as necessary. This > is now fixed as far as linux-next is concerned, but any non trivial > conflicts should be mentioned to your upstream maintainer when your tree > is submitted for merging. You may also want to consider cooperating > with the maintainer of the conflicting tree to minimise any particularly > complex conflicts. The resolution now looks like below (since the lanlock syscall number have been updated). -- Cheers, Stephen Rothwell diff --cc arch/alpha/kernel/syscalls/syscall.tbl index c5f7e595adab,4240f21b10b3.. --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl @@@ -482,4 -482,6 +482,7 @@@ 550 common process_madvise sys_process_madvise 551 common epoll_pwait2sys_epoll_pwait2 552 common mount_setattr sys_mount_setattr +553 common quotactl_path sys_quotactl_path + 554 common landlock_create_ruleset sys_landlock_create_ruleset + 555 common landlock_add_rule sys_landlock_add_rule + 556 common landlock_restrict_self sys_landlock_restrict_self diff --cc arch/arm/tools/syscall.tbl index 90cbe207cf3e,161423a5d773.. --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@@ -456,4 -456,6 +456,7 @@@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common quotactl_path sys_quotactl_path + 444 common landlock_create_ruleset sys_landlock_create_ruleset + 445 common landlock_add_rule sys_landlock_add_rule + 446 common landlock_restrict_self sys_landlock_restrict_self diff --cc arch/arm64/include/asm/unistd.h index d1f7d35f986e,727bfc3be99b.. --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h diff --cc arch/arm64/include/asm/unistd32.h index 8361c5138e5f,fdfe06bae3fc.. --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h @@@ -893,8 -893,12 +893,14 @@@ __SYSCALL(__NR_process_madvise, sys_pro __SYSCALL(__NR_epoll_pwait2, compat_sys_epoll_pwait2) #define __NR_mount_setattr 442 __SYSCALL(__NR_mount_setattr, sys_mount_setattr) +#define __NR_quotactl_path 443 +__SYSCALL(__NR_quotactl_path, sys_quotactl_path) + #define __NR_landlock_create_ruleset 444 + __SYSCALL(__NR_landlock_create_ruleset, sys_landlock_create_ruleset) + #define __NR_landlock_add_rule 445 + __SYSCALL(__NR_landlock_add_rule, sys_landlock_add_rule) + #define __NR_landlock_restrict_self 446 + __SYSCALL(__NR_landlock_restrict_self, sys_landlock_restrict_self) /* * Please add new compat syscalls above this comment and update diff --cc arch/ia64/kernel/syscalls/syscall.tbl index c072cd459bb5,48dbbc95a01f.. --- a/arch/ia64/kernel/syscalls/syscall.tbl +++ b/arch/ia64/kernel/syscalls/syscall.tbl @@@ -363,4 -363,6 +363,7 @@@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common quotactl_path sys_quotactl_path + 444 common landlock_create_ruleset sys_landlock_create_ruleset + 445 common landlock_add_rule sys_landlock_add_rule + 446 common landlock_restrict_self sys_landlock_restrict_self diff --cc arch/m68k/kernel/syscalls/syscall.tbl index 5e9f81073ff4,595108bbbe42.. --- a/arch/m68k/kernel/syscalls/syscall.tbl +++ b/arch/m68k/kernel/syscalls/syscall.tbl @@@ -442,4 -442,6
Re: [PATCH v5 2/6] w1: ds2438: fixed if brackets coding style issue
On Fri, 2021-04-09 at 00:09 -0300, Luiz Sampaio wrote: > Since there is only one statement inside the if clause, no brackets are > required. > > Signed-off-by: Luiz Sampaio > --- > drivers/w1/slaves/w1_ds2438.c | 16 > 1 file changed, 8 insertions(+), 8 deletions(-) > > diff --git a/drivers/w1/slaves/w1_ds2438.c b/drivers/w1/slaves/w1_ds2438.c > index 148921fb9702..56e53a748059 100644 > --- a/drivers/w1/slaves/w1_ds2438.c > +++ b/drivers/w1/slaves/w1_ds2438.c > @@ -287,9 +287,9 @@ static ssize_t iad_read(struct file *filp, struct kobject > *kobj, > if (!buf) > return -EINVAL; > > > - if (w1_ds2438_get_current(sl, ) == 0) { > + if (w1_ds2438_get_current(sl, ) == 0) > ret = snprintf(buf, count, "%i\n", voltage); > - } else > + else > ret = -EIO; > > > return ret; > @@ -338,9 +338,9 @@ static ssize_t temperature_read(struct file *filp, struct > kobject *kobj, > if (!buf) > return -EINVAL; > > > - if (w1_ds2438_get_temperature(sl, ) == 0) { > + if (w1_ds2438_get_temperature(sl, ) == 0) > ret = snprintf(buf, count, "%i\n", temp); > - } else > + else > ret = -EIO; > > > return ret; > @@ -359,9 +359,9 @@ static ssize_t vad_read(struct file *filp, struct kobject > *kobj, > if (!buf) > return -EINVAL; > > > - if (w1_ds2438_get_voltage(sl, DS2438_ADC_INPUT_VAD, ) == 0) { > + if (w1_ds2438_get_voltage(sl, DS2438_ADC_INPUT_VAD, ) == 0) > ret = snprintf(buf, count, "%u\n", voltage); > - } else > + else > ret = -EIO; > > > return ret; > @@ -380,9 +380,9 @@ static ssize_t vdd_read(struct file *filp, struct kobject > *kobj, > if (!buf) > return -EINVAL; > > > - if (w1_ds2438_get_voltage(sl, DS2438_ADC_INPUT_VDD, ) == 0) { > + if (w1_ds2438_get_voltage(sl, DS2438_ADC_INPUT_VDD, ) == 0) > ret = snprintf(buf, count, "%u\n", voltage); > - } else > + else > ret = -EIO; > > > return ret;
Re: [PATCH v2 14/21] ipmi: kcs_bmc: Allow clients to control KCS IRQ state
On Fri, Mar 19, 2021 at 01:27:45AM CDT, Andrew Jeffery wrote: >Add a mechanism for controlling whether the client associated with a >KCS device will receive Input Buffer Full (IBF) and Output Buffer Empty >(OBE) events. This enables an abstract implementation of poll() for KCS >devices. > >A wart in the implementation is that the ASPEED KCS devices don't >support an OBE interrupt for the BMC. Instead we pretend it has one by >polling the status register waiting for the Output Buffer Full (OBF) bit >to clear, and generating an event when OBE is observed. > >Signed-off-by: Andrew Jeffery >--- > drivers/char/ipmi/kcs_bmc.c | 6 ++ > drivers/char/ipmi/kcs_bmc.h | 3 + > drivers/char/ipmi/kcs_bmc_aspeed.c | 150 ++-- > drivers/char/ipmi/kcs_bmc_client.h | 2 + > drivers/char/ipmi/kcs_bmc_device.h | 1 + > drivers/char/ipmi/kcs_bmc_npcm7xx.c | 25 - > 6 files changed, 130 insertions(+), 57 deletions(-) > >diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c >index 694db6ee2a92..05bbb72418b2 100644 >--- a/drivers/char/ipmi/kcs_bmc.c >+++ b/drivers/char/ipmi/kcs_bmc.c >@@ -184,6 +184,12 @@ int kcs_bmc_unregister_cdev(struct kcs_bmc_cdev *cdev) > } > EXPORT_SYMBOL(kcs_bmc_unregister_cdev); > >+void kcs_bmc_update_event_mask(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 >events) >+{ >+ kcs_bmc->ops->irq_mask_update(kcs_bmc, mask, events); >+} >+EXPORT_SYMBOL(kcs_bmc_update_event_mask); >+ > MODULE_LICENSE("GPL v2"); > MODULE_AUTHOR("Haiyue Wang "); > MODULE_AUTHOR("Andrew Jeffery "); >diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h >index 5deb9a0b8e60..11fff935218c 100644 >--- a/drivers/char/ipmi/kcs_bmc.h >+++ b/drivers/char/ipmi/kcs_bmc.h >@@ -11,6 +11,9 @@ > #define KCS_BMC_EVENT_NONE0 > #define KCS_BMC_EVENT_HANDLED 1 > >+#define KCS_BMC_EVENT_TYPE_OBEBIT(0) >+#define KCS_BMC_EVENT_TYPE_IBFBIT(1) >+ > #define KCS_BMC_STR_OBF BIT(0) > #define KCS_BMC_STR_IBF BIT(1) > #define KCS_BMC_STR_CMD_DAT BIT(3) >diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c >b/drivers/char/ipmi/kcs_bmc_aspeed.c >index 6f26e7366c0b..5f26471c038c 100644 >--- a/drivers/char/ipmi/kcs_bmc_aspeed.c >+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c >@@ -60,10 +60,18 @@ > #define LPC_ODR4 0x118 > #define LPC_STR4 0x11C > >+#define OBE_POLL_PERIOD(HZ / 2) >+ > struct aspeed_kcs_bmc { > struct kcs_bmc_device kcs_bmc; > > struct regmap *map; >+ >+ struct { >+ spinlock_t lock; >+ bool remove; >+ struct timer_list timer; >+ } obe; > }; > > struct aspeed_kcs_of_ops { >@@ -159,68 +167,89 @@ static void aspeed_kcs_enable_channel(struct >kcs_bmc_device *kcs_bmc, bool enabl > > switch (kcs_bmc->channel) { > case 1: >- if (enable) { >- regmap_update_bits(priv->map, LPC_HICR2, >- LPC_HICR2_IBFIF1, LPC_HICR2_IBFIF1); >- regmap_update_bits(priv->map, LPC_HICR0, >- LPC_HICR0_LPC1E, LPC_HICR0_LPC1E); >- } else { >- regmap_update_bits(priv->map, LPC_HICR0, >- LPC_HICR0_LPC1E, 0); >- regmap_update_bits(priv->map, LPC_HICR2, >- LPC_HICR2_IBFIF1, 0); >- } >- break; >- >+ regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC1E, >enable * LPC_HICR0_LPC1E); >+ return; > case 2: >- if (enable) { >- regmap_update_bits(priv->map, LPC_HICR2, >- LPC_HICR2_IBFIF2, LPC_HICR2_IBFIF2); >- regmap_update_bits(priv->map, LPC_HICR0, >- LPC_HICR0_LPC2E, LPC_HICR0_LPC2E); >- } else { >- regmap_update_bits(priv->map, LPC_HICR0, >- LPC_HICR0_LPC2E, 0); >- regmap_update_bits(priv->map, LPC_HICR2, >- LPC_HICR2_IBFIF2, 0); >- } >- break; >- >+ regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC2E, >enable * LPC_HICR0_LPC2E); >+ return; > case 3: >- if (enable) { >- regmap_update_bits(priv->map, LPC_HICR2, >- LPC_HICR2_IBFIF3, LPC_HICR2_IBFIF3); >- regmap_update_bits(priv->map, LPC_HICR0, >- LPC_HICR0_LPC3E, LPC_HICR0_LPC3E); >- regmap_update_bits(priv->map, LPC_HICR4, >- LPC_HICR4_KCSENBL, LPC_HICR4_KCSENBL); >- } else { >- regmap_update_bits(priv->map, LPC_HICR0, >-
Re: [PATCH 3/4] mm/hugeltb: fix potential wrong gbl_reserve value for hugetlb_acct_memory()
On 4/8/21 8:01 PM, Miaohe Lin wrote: > On 2021/4/9 6:53, Mike Kravetz wrote: >> >> Yes, add a comment to hugetlb_unreserve_pages saying that !resv_map >> implies freed == 0. >> > > Sounds good! > >> It would also be helpful to check for (chg - freed) == 0 and skip the >> calls to hugepage_subpool_put_pages() and hugetlb_acct_memory(). Both >> of those routines may perform an unnecessary lock/unlock cycle in this >> case. >> >> A simple >> if (chg == free) >> return 0; >> before the call to hugepage_subpool_put_pages would work. > > This may not be really helpful because hugepage_subpool_put_pages() and > hugetlb_acct_memory() > both would handle delta == 0 case without unnecessary lock/unlock cycle. > Does this make sense for you? If so, I will prepare v2 with the changes to > add a comment > to hugetlb_unreserve_pages() __without__ the check for (chg - freed) == 0. Sorry, I forgot about the recent changes to check for delta == 0. No need for the check here, just the comment. -- Mike Kravetz
Re: [PATCH v2 00/10] Initial support for Nuvoton WPCM450 BMC SoC
On Tue, 6 Apr 2021 at 21:59, Jonathan Neuschäfer wrote: > > On Tue, Apr 06, 2021 at 05:15:01PM +0200, Arnd Bergmann wrote: > > On Tue, Apr 6, 2021 at 2:09 PM Jonathan Neuschäfer > > wrote: > > > > > > This series adds basic support for the Nuvoton WPCM450 BMC SoC. It's an > > > older > > > SoC but still commonly found on eBay, mostly in Supermicro X9 server > > > boards. > > > > > > Third-party documentation is available at: > > > https://github.com/neuschaefer/wpcm450/wiki > > > > > > Patches 1-4 add devicetree bindings for the WPCM450 SoC and its various > > > parts. > > > Patches 5-7 add arch and driver support. Patches 8 and 9 add a devicetree > > > for > > > the SoC and a board based on it. Patch 10 finally updates the MAINTAINERS > > > file. > > > > > > Patch 2 requires "dt-bindings: arm: Convert nuvoton,npcm750 binding to > > > YAML" > > > (https://lore.kernel.org/lkml/20210320164023.614059-1-j.neuschae...@gmx.net/) > > > > Hi Jonathan, > > > > It appears these patches are doing roughly the right thing, and we may still > > be able to get them into v5.13, but I'm not sure what your plan for > > maintaining > > them is. The two options are that you either send your patches to be picked > > up > > by Joel, or you send everything directly to s...@kernel.org once it's fully > > reviewed. > > The route via Joel sounds alright with me. I've Cc'd him on this version > of the series. I've had a look at the series and it looks good to me: Reviewed-by: Joel Stanley Nice work Jonathan. I'll put this in it's own branch along with the bindings change it depends on and send a pull request to Arnd for v5.13. Cheers, Joel
Re: [PATCH v2 13/21] ipmi: kcs_bmc: Decouple the IPMI chardev from the core
On Fri, Mar 19, 2021 at 01:27:44AM CDT, Andrew Jeffery wrote: >Now that we have untangled the data-structures, split the userspace >interface out into its own module. Userspace interfaces and drivers are >registered to the KCS BMC core to support arbitrary binding of either. > >Signed-off-by: Andrew Jeffery >--- > drivers/char/ipmi/Kconfig | 13 + > drivers/char/ipmi/Makefile| 3 +- > drivers/char/ipmi/kcs_bmc.c | 78 ++- > drivers/char/ipmi/kcs_bmc.h | 4 -- > drivers/char/ipmi/kcs_bmc_cdev_ipmi.c | 33 +--- > drivers/char/ipmi/kcs_bmc_client.h| 14 + > 6 files changed, 132 insertions(+), 13 deletions(-) > >diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig >index 07847d9a459a..bc5f81899b62 100644 >--- a/drivers/char/ipmi/Kconfig >+++ b/drivers/char/ipmi/Kconfig >@@ -124,6 +124,19 @@ config NPCM7XX_KCS_IPMI_BMC > This support is also available as a module. If so, the module > will be called kcs_bmc_npcm7xx. > >+config IPMI_KCS_BMC_CDEV_IPMI >+ depends on IPMI_KCS_BMC >+ tristate "IPMI character device interface for BMC KCS devices" >+ help >+Provides a BMC-side character device implementing IPMI >+semantics for KCS IPMI devices. >+ >+Say YES if you wish to expose KCS devices on the BMC for IPMI >+purposes. >+ >+This support is also available as a module. The module will be >+called kcs_bmc_cdev_ipmi. >+ > config ASPEED_BT_IPMI_BMC > depends on ARCH_ASPEED || COMPILE_TEST > depends on REGMAP && REGMAP_MMIO && MFD_SYSCON >diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile >index a302bc865370..fcfa676afddb 100644 >--- a/drivers/char/ipmi/Makefile >+++ b/drivers/char/ipmi/Makefile >@@ -22,7 +22,8 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o > obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o > obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o > obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o >-obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o kcs_bmc_cdev_ipmi.o >+obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o >+obj-$(CONFIG_IPMI_KCS_BMC_CDEV_IPMI) += kcs_bmc_cdev_ipmi.o > obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o > obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o > obj-$(CONFIG_NPCM7XX_KCS_IPMI_BMC) += kcs_bmc_npcm7xx.o >diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c >index 266ebec71d6f..694db6ee2a92 100644 >--- a/drivers/char/ipmi/kcs_bmc.c >+++ b/drivers/char/ipmi/kcs_bmc.c >@@ -5,7 +5,9 @@ > */ > > #include >+#include > #include >+#include > > #include "kcs_bmc.h" > >@@ -13,6 +15,11 @@ > #include "kcs_bmc_device.h" > #include "kcs_bmc_client.h" > >+/* Record probed devices and cdevs */ >+static DEFINE_MUTEX(kcs_bmc_lock); >+static LIST_HEAD(kcs_bmc_devices); >+static LIST_HEAD(kcs_bmc_cdevs); >+ > /* Consumer data access */ > > u8 kcs_bmc_read_data(struct kcs_bmc_device *kcs_bmc) >@@ -100,16 +107,83 @@ EXPORT_SYMBOL(kcs_bmc_disable_device); > > int kcs_bmc_add_device(struct kcs_bmc_device *kcs_bmc) > { >- return kcs_bmc_ipmi_attach_cdev(kcs_bmc); >+ struct kcs_bmc_cdev *cdev; >+ int rc; >+ >+ spin_lock_init(_bmc->lock); >+ kcs_bmc->client = NULL; >+ >+ mutex_lock(_bmc_lock); >+ list_add(_bmc->entry, _bmc_devices); >+ list_for_each_entry(cdev, _bmc_cdevs, entry) { >+ rc = cdev->ops->add_device(kcs_bmc); >+ if (rc) >+ dev_err(kcs_bmc->dev, "Failed to add chardev for KCS >channel %d: %d", >+ kcs_bmc->channel, rc); >+ } >+ mutex_unlock(_bmc_lock); >+ >+ return 0; We're ignoring failed ->add_device() calls here? > } > EXPORT_SYMBOL(kcs_bmc_add_device); > > int kcs_bmc_remove_device(struct kcs_bmc_device *kcs_bmc) > { >- return kcs_bmc_ipmi_detach_cdev(kcs_bmc); >+ struct kcs_bmc_cdev *cdev; >+ int rc; >+ >+ mutex_lock(_bmc_lock); >+ list_del(_bmc->entry); >+ list_for_each_entry(cdev, _bmc_cdevs, entry) { >+ rc = cdev->ops->remove_device(kcs_bmc); >+ if (rc) >+ dev_err(kcs_bmc->dev, "Failed to remove chardev for KCS >channel %d: %d", >+ kcs_bmc->channel, rc); >+ } >+ mutex_unlock(_bmc_lock); >+ >+ return 0; Similarly with the return value here... > } > EXPORT_SYMBOL(kcs_bmc_remove_device); > >+int kcs_bmc_register_cdev(struct kcs_bmc_cdev *cdev) >+{ >+ struct kcs_bmc_device *kcs_bmc; >+ int rc; >+ >+ mutex_lock(_bmc_lock); >+ list_add(>entry, _bmc_cdevs); >+ list_for_each_entry(kcs_bmc, _bmc_devices, entry) { >+ rc = cdev->ops->add_device(kcs_bmc); >+ if (rc) >+ dev_err(kcs_bmc->dev, "Failed to add chardev for KCS >channel %d: %d", >+ kcs_bmc->channel, rc); >+ } >+ mutex_unlock(_bmc_lock); >+ >+ return 0; ...return value again
Re: [PATCH v2 1/1] powerpc/iommu: Enable remaining IOMMU Pagesizes present in LoPAR
On 08/04/2021 19:04, Michael Ellerman wrote: Alexey Kardashevskiy writes: On 08/04/2021 15:37, Michael Ellerman wrote: Leonardo Bras writes: According to LoPAR, ibm,query-pe-dma-window output named "IO Page Sizes" will let the OS know all possible pagesizes that can be used for creating a new DDW. Currently Linux will only try using 3 of the 8 available options: 4K, 64K and 16M. According to LoPAR, Hypervisor may also offer 32M, 64M, 128M, 256M and 16G. Do we know of any hardware & hypervisor combination that will actually give us bigger pages? On P8 16MB host pages and 16MB hardware iommu pages worked. On P9, VM's 16MB IOMMU pages worked on top of 2MB host pages + 2MB hardware IOMMU pages. The current code already tries 16MB though. I'm wondering if we're going to ask for larger sizes that have never been tested and possibly expose bugs. But it sounds like this is mainly targeted at future platforms. I tried for fun to pass through a PCI device to a guest with this patch as: pbuild/qemu-killslof-aiku1904le-ppc64/qemu-system-ppc64 \ -nodefaults \ -chardev stdio,id=STDIO0,signal=off,mux=on \ -device spapr-vty,id=svty0,reg=0x71000110,chardev=STDIO0 \ -mon id=MON0,chardev=STDIO0,mode=readline \ -nographic \ -vga none \ -enable-kvm \ -m 16G \ -kernel ./vmldbg \ -initrd /home/aik/t/le.cpio \ -device vfio-pci,id=vfio0001_01_00_0,host=0001:01:00.0 \ -mem-prealloc \ -mem-path qemu_hp_1G_node0 \ -global spapr-pci-host-bridge.pgsz=0xff000 \ -machine cap-cfpc=broken,cap-ccf-assist=off \ -smp 1,threads=1 \ -L /home/aik/t/qemu-ppc64-bios/ \ -trace events=qemu_trace_events \ -d guest_errors,mmu \ -chardev socket,id=SOCKET0,server=on,wait=off,path=qemu.mon.1_1_0_0 \ -mon chardev=SOCKET0,mode=control The guest created a huge window: xhci_hcd :00:00.0: ibm,create-pe-dma-window(2027) 0 800 2000 22 22 returned 0 (liobn = 0x8001 starting addr = 800 0) The first "22" is page_shift in hex (16GB), the second "22" is window_shift (so we have 1 TCE). On the host side the window#1 was created with 1GB pages: pci 0001:01 : [PE# fd] Setting up window#1 800..80007ff pg=4000 The XHCI seems working. Without the patch 16MB was the maximum. diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 9fc5217f0c8e..6cda1c92597d 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -53,6 +53,20 @@ enum { DDW_EXT_QUERY_OUT_SIZE = 2 }; A comment saying where the values come from would be good. +#define QUERY_DDW_PGSIZE_4K0x01 +#define QUERY_DDW_PGSIZE_64K 0x02 +#define QUERY_DDW_PGSIZE_16M 0x04 +#define QUERY_DDW_PGSIZE_32M 0x08 +#define QUERY_DDW_PGSIZE_64M 0x10 +#define QUERY_DDW_PGSIZE_128M 0x20 +#define QUERY_DDW_PGSIZE_256M 0x40 +#define QUERY_DDW_PGSIZE_16G 0x80 I'm not sure the #defines really gain us much vs just putting the literal values in the array below? Then someone says "u magic values" :) I do not mind either way. Thanks, Yeah that's true. But #defining them doesn't make them less magic, if you only use them in one place :) Defining them with "QUERY_DDW" in the names kinda tells where they are from. Can also grep QEMU using these to see how the other side handles it. Dunno. btw the bot complained about __builtin_ctz(SZ_16G) which should be __builtin_ctzl(SZ_16G) so we have to ask Leonardo to repost anyway :) -- Alexey
Re: [PATCH v2 10/21] ipmi: kcs_bmc: Turn the driver data-structures inside-out
On Fri, Mar 19, 2021 at 01:27:41AM CDT, Andrew Jeffery wrote: >Make the KCS device drivers responsible for allocating their own memory. > >Until now the private data for the device driver was allocated internal >to the private data for the chardev interface. This coupling required >the slightly awkward API of passing through the struct size for the >driver private data to the chardev constructor, and then retrieving a >pointer to the driver private data from the allocated chardev memory. > >In addition to being awkward, the arrangement prevents the >implementation of alternative userspace interfaces as the device driver >private data is not independent. > >Peel a layer off the onion and turn the data-structures inside out by >exploiting container_of() and embedding `struct kcs_device` in the >driver private data. > >Signed-off-by: Andrew Jeffery >--- > drivers/char/ipmi/kcs_bmc.c | 15 +-- > drivers/char/ipmi/kcs_bmc.h | 12 ++ > drivers/char/ipmi/kcs_bmc_aspeed.c| 60 --- > drivers/char/ipmi/kcs_bmc_cdev_ipmi.c | 60 ++- > drivers/char/ipmi/kcs_bmc_npcm7xx.c | 37 ++--- > 5 files changed, 113 insertions(+), 71 deletions(-) > >diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c >index ef5c48ffe74a..709b6bdec165 100644 >--- a/drivers/char/ipmi/kcs_bmc.c >+++ b/drivers/char/ipmi/kcs_bmc.c >@@ -44,12 +44,19 @@ int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) > } > EXPORT_SYMBOL(kcs_bmc_handle_event); > >-struct kcs_bmc *kcs_bmc_ipmi_alloc(struct device *dev, int sizeof_priv, u32 >channel); >-struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 >channel) >+int kcs_bmc_ipmi_attach_cdev(struct kcs_bmc *kcs_bmc); Another declaration perhaps intended for kcs_bmc.h? >+int kcs_bmc_add_device(struct kcs_bmc *kcs_bmc) > { >- return kcs_bmc_ipmi_alloc(dev, sizeof_priv, channel); >+ return kcs_bmc_ipmi_attach_cdev(kcs_bmc); > } >-EXPORT_SYMBOL(kcs_bmc_alloc); >+EXPORT_SYMBOL(kcs_bmc_add_device); >+ >+int kcs_bmc_ipmi_detach_cdev(struct kcs_bmc *kcs_bmc); Here too. >+int kcs_bmc_remove_device(struct kcs_bmc *kcs_bmc) >+{ >+ return kcs_bmc_ipmi_detach_cdev(kcs_bmc); >+} >+EXPORT_SYMBOL(kcs_bmc_remove_device); > > MODULE_LICENSE("GPL v2"); > MODULE_AUTHOR("Haiyue Wang "); >diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h >index febea0c8deb4..bf0ae327997f 100644 >--- a/drivers/char/ipmi/kcs_bmc.h >+++ b/drivers/char/ipmi/kcs_bmc.h >@@ -67,6 +67,8 @@ struct kcs_ioreg { > }; > > struct kcs_bmc { >+ struct device *dev; >+ > spinlock_t lock; > > u32 channel; >@@ -94,17 +96,11 @@ struct kcs_bmc { > u8 *kbuffer; > > struct miscdevice miscdev; >- >- unsigned long priv[]; > }; > >-static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc) >-{ >- return kcs_bmc->priv; >-} >- > int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc); >-struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 >channel); >+int kcs_bmc_add_device(struct kcs_bmc *kcs_bmc); >+int kcs_bmc_remove_device(struct kcs_bmc *kcs_bmc); > > u8 kcs_bmc_read_data(struct kcs_bmc *kcs_bmc); > void kcs_bmc_write_data(struct kcs_bmc *kcs_bmc, u8 data); >diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c >b/drivers/char/ipmi/kcs_bmc_aspeed.c >index 630cf095560e..0416ac78ce68 100644 >--- a/drivers/char/ipmi/kcs_bmc_aspeed.c >+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c >@@ -61,6 +61,8 @@ > #define LPC_STR4 0x11C > > struct aspeed_kcs_bmc { >+ struct kcs_bmc kcs_bmc; >+ > struct regmap *map; > }; > >@@ -69,9 +71,14 @@ struct aspeed_kcs_of_ops { > int (*get_io_address)(struct platform_device *pdev); > }; > >+static inline struct aspeed_kcs_bmc *to_aspeed_kcs_bmc(struct kcs_bmc >*kcs_bmc) >+{ >+ return container_of(kcs_bmc, struct aspeed_kcs_bmc, kcs_bmc); >+} >+ > static u8 aspeed_kcs_inb(struct kcs_bmc *kcs_bmc, u32 reg) > { >- struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); >+ struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc); > u32 val = 0; > int rc; > >@@ -83,7 +90,7 @@ static u8 aspeed_kcs_inb(struct kcs_bmc *kcs_bmc, u32 reg) > > static void aspeed_kcs_outb(struct kcs_bmc *kcs_bmc, u32 reg, u8 data) > { >- struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); >+ struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc); > int rc; > > rc = regmap_write(priv->map, reg, data); >@@ -92,7 +99,7 @@ static void aspeed_kcs_outb(struct kcs_bmc *kcs_bmc, u32 >reg, u8 data) > > static void aspeed_kcs_updateb(struct kcs_bmc *kcs_bmc, u32 reg, u8 mask, u8 > val) > { >- struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); >+ struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc); > int rc; > > rc = regmap_update_bits(priv->map, reg, mask, val); >@@ -114,7 +121,7 @@ static void aspeed_kcs_updateb(struct kcs_bmc *kcs_bmc, >u32 reg, u8 mask, u8 val > */ > static
[PATCH] nilfs2: Fix typos in comments
From: Lu Jialin numer -> number in fs/nilfs2/cpfile.c Decription -> Description in fs/nilfs2/ioctl.c isntance -> instance in fs/nilfs2/the_nilfs.c Signed-off-by: Lu Jialin Link: https://lore.kernel.org/r/20210409022519.176988-1-lujial...@huawei.com Signed-off-by: Ryusuke Konishi --- fs/nilfs2/cpfile.c| 2 +- fs/nilfs2/ioctl.c | 4 ++-- fs/nilfs2/the_nilfs.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index 025fb082575a..ce144776b4ef 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c @@ -293,7 +293,7 @@ void nilfs_cpfile_put_checkpoint(struct inode *cpfile, __u64 cno, * nilfs_cpfile_delete_checkpoints - delete checkpoints * @cpfile: inode of checkpoint file * @start: start checkpoint number - * @end: end checkpoint numer + * @end: end checkpoint number * * Description: nilfs_cpfile_delete_checkpoints() deletes the checkpoints in * the period from @start to @end, excluding @end itself. The checkpoints diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index b053b40315bf..d1db73030085 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c @@ -1058,7 +1058,7 @@ static int nilfs_ioctl_resize(struct inode *inode, struct file *filp, * @inode: inode object * @argp: pointer on argument from userspace * - * Decription: nilfs_ioctl_trim_fs is the FITRIM ioctl handle function. It + * Description: nilfs_ioctl_trim_fs is the FITRIM ioctl handle function. It * checks the arguments from userspace and calls nilfs_sufile_trim_fs, which * performs the actual trim operation. * @@ -1100,7 +1100,7 @@ static int nilfs_ioctl_trim_fs(struct inode *inode, void __user *argp) * @inode: inode object * @argp: pointer on argument from userspace * - * Decription: nilfs_ioctl_set_alloc_range() function defines lower limit + * Description: nilfs_ioctl_set_alloc_range() function defines lower limit * of segments in bytes and upper limit of segments in bytes. * The NILFS_IOCTL_SET_ALLOC_RANGE is used by nilfs_resize utility. * diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 221a1cc597f0..8b7b01a380ce 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -195,7 +195,7 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs, /** * load_nilfs - load and recover the nilfs * @nilfs: the_nilfs structure to be released - * @sb: super block isntance used to recover past segment + * @sb: super block instance used to recover past segment * * load_nilfs() searches and load the latest super root, * attaches the last segment, and does recovery if needed. -- 1.8.3.1
Re: Linux Kernel build bug with AMD_IOMMU_V2=M and HSA_AMD=Y
This should have been fixed by this commit in amd-staging-drm-next: https://lore.kernel.org/patchwork/patch/1392368/ commit b8aff1f3a0b3d8434f8ccf5d3017137c29aca77b Author: Felix Kuehling Date: Mon Mar 8 22:15:42 2021 -0500 drm/amdkfd: fix build error with AMD_IOMMU_V2=m Using 'imply AMD_IOMMU_V2' does not guarantee that the driver can link against the exported functions. If the GPU driver is built-in but the IOMMU driver is a loadable module, the kfd_iommu.c file is indeed built but does not work: x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_bind_process_to_device': kfd_iommu.c:(.text+0x516): undefined reference to `amd_iommu_bind_pasid' x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_unbind_process': kfd_iommu.c:(.text+0x691): undefined reference to `amd_iommu_unbind_pasid' x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_suspend': kfd_iommu.c:(.text+0x966): undefined reference to `amd_iommu_set_invalidate_ctx_cb' x86_64-linux-ld: kfd_iommu.c:(.text+0x97f): undefined reference to `amd_iommu_set_invalid_ppr_cb' x86_64-linux-ld: kfd_iommu.c:(.text+0x9a4): undefined reference to `amd_iommu_free_device' x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_resume': kfd_iommu.c:(.text+0xa9a): undefined reference to `amd_iommu_init_device' x86_64-linux-ld: kfd_iommu.c:(.text+0xadc): undefined reference to `amd_iommu_set_invalidate_ctx_cb' x86_64-linux-ld: kfd_iommu.c:(.text+0xaff): undefined reference to `amd_iommu_set_invalid_ppr_cb' x86_64-linux-ld: kfd_iommu.c:(.text+0xc72): undefined reference to `amd_iommu_bind_pasid' x86_64-linux-ld: kfd_iommu.c:(.text+0xe08): undefined reference to `amd_iommu_set_invalidate_ctx_cb' x86_64-linux-ld: kfd_iommu.c:(.text+0xe26): undefined reference to `amd_iommu_set_invalid_ppr_cb' x86_64-linux-ld: kfd_iommu.c:(.text+0xe42): undefined reference to `amd_iommu_free_device' Use IS_REACHABLE to only build IOMMU-V2 support if the amd_iommu symbols are reachable by the amdkfd driver. Output a warning if they are not, because that may not be what the user was expecting. Fixes: 64d1c3a43a6f ("drm/amdkfd: Centralize IOMMUv2 code and make it conditional") Reported-by: Arnd Bergmann Signed-off-by: Felix Kuehling Reviewed-by: Christian König Regards, Felix On 2021-04-08 7:04 p.m., David Niklas wrote: Hello, (There are so many maintainers for kfd_iommu.c I feel like I'm spamming.) When compiling for Linux version 5.11.12 using the AMDGPU GPU driver with HSA_AMD enabled, I get the below set of errors. To work around this, I need to change AMD_IOMMU_V2 from M to Y. This bug doesn't affect linux kernel version 5.6 as it requires AMD_IOMMU_V2 to by Y when HSA_AMD is enabled. I'd bisect and request the removal of the relevant patch, but it's possible that building the linux kernel should work this way and so a fix, not a patch removal, is what should be issued. I'm attaching my kernel config for 5.11. Thanks, David PS: I made an official bug report in case you'd prefer that: https://bugzilla.kernel.org/show_bug.cgi?id=212619 drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: In function `kfd_iommu_bind_process_to_device': /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:120: undefined reference to `amd_iommu_bind_pasid' drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: In function `kfd_iommu_unbind_process': /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:138: undefined reference to `amd_iommu_unbind_pasid' drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: In function `kfd_iommu_suspend': /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:292: undefined reference to `amd_iommu_set_invalidate_ctx_cb' /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:293: undefined reference to `amd_iommu_set_invalid_ppr_cb' drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: In function `kfd_iommu_resume': /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:312: undefined reference to `amd_iommu_init_device' /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:316: undefined reference to `amd_iommu_set_invalidate_ctx_cb' /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:318: undefined reference to `amd_iommu_set_invalid_ppr_cb' /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:323: undefined reference to `amd_iommu_set_invalidate_ctx_cb' /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:324: undefined reference to `amd_iommu_set_invalid_ppr_cb' /root/working/linux-5.11.12/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_iommu.c:325: undefined reference to `amd_iommu_free_device'
Re: [PATCH v2 06/21] ipmi: kcs_bmc_aspeed: Use of match data to extract KCS properties
On Fri, Mar 19, 2021 at 01:27:37AM CDT, Andrew Jeffery wrote: >Unpack and remove the aspeed_kcs_probe_of_v[12]() functions to aid >rearranging how the private device-driver memory is allocated. > >Signed-off-by: Andrew Jeffery >--- > drivers/char/ipmi/kcs_bmc_aspeed.c | 146 ++--- > 1 file changed, 68 insertions(+), 78 deletions(-) > >diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c >b/drivers/char/ipmi/kcs_bmc_aspeed.c >index eefe362f65f0..061f53676206 100644 >--- a/drivers/char/ipmi/kcs_bmc_aspeed.c >+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c >@@ -13,6 +13,7 @@ > #include > #include > #include >+#include > #include > #include > #include >@@ -63,6 +64,10 @@ struct aspeed_kcs_bmc { > struct regmap *map; > }; > >+struct aspeed_kcs_of_ops { >+ int (*get_channel)(struct platform_device *pdev); >+ int (*get_io_address)(struct platform_device *pdev); >+}; > > static u8 aspeed_kcs_inb(struct kcs_bmc *kcs_bmc, u32 reg) > { >@@ -231,13 +236,10 @@ static const struct kcs_ioreg >ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = { > { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 }, > }; > >-static struct kcs_bmc *aspeed_kcs_probe_of_v1(struct platform_device *pdev) >+static int aspeed_kcs_of_v1_get_channel(struct platform_device *pdev) > { >- struct aspeed_kcs_bmc *priv; > struct device_node *np; >- struct kcs_bmc *kcs; > u32 channel; >- u32 slave; > int rc; > > np = pdev->dev.of_node; >@@ -245,105 +247,78 @@ static struct kcs_bmc *aspeed_kcs_probe_of_v1(struct >platform_device *pdev) > rc = of_property_read_u32(np, "kcs_chan", ); > if ((rc != 0) || (channel == 0 || channel > KCS_CHANNEL_MAX)) { > dev_err(>dev, "no valid 'kcs_chan' configured\n"); >- return ERR_PTR(-EINVAL); >+ return -EINVAL; > } > >- kcs = kcs_bmc_alloc(>dev, sizeof(struct aspeed_kcs_bmc), channel); >- if (!kcs) >- return ERR_PTR(-ENOMEM); >+ return channel; >+} > >- priv = kcs_bmc_priv(kcs); >- priv->map = syscon_node_to_regmap(pdev->dev.parent->of_node); >- if (IS_ERR(priv->map)) { >- dev_err(>dev, "Couldn't get regmap\n"); >- return ERR_PTR(-ENODEV); >- } >+static int aspeed_kcs_of_v1_get_io_address(struct platform_device *pdev) >+{ >+ u32 slave; >+ int rc; > >- rc = of_property_read_u32(np, "kcs_addr", ); >- if (rc) { >+ rc = of_property_read_u32(pdev->dev.of_node, "kcs_addr", ); >+ if (rc || slave > 0x) { > dev_err(>dev, "no valid 'kcs_addr' configured\n"); >- return ERR_PTR(-EINVAL); >+ return -EINVAL; > } > >- kcs->ioreg = ast_kcs_bmc_ioregs[channel - 1]; >- aspeed_kcs_set_address(kcs, slave); >- >- return kcs; >-} >- >-static int aspeed_kcs_calculate_channel(const struct kcs_ioreg *regs) >-{ >- int i; >- >- for (i = 0; i < ARRAY_SIZE(ast_kcs_bmc_ioregs); i++) { >- if (!memcmp(_kcs_bmc_ioregs[i], regs, sizeof(*regs))) >- return i + 1; >- } >- >- return -EINVAL; >+ return slave; > } > >-static struct kcs_bmc *aspeed_kcs_probe_of_v2(struct platform_device *pdev) >+static int aspeed_kcs_of_v2_get_channel(struct platform_device *pdev) > { >- struct aspeed_kcs_bmc *priv; > struct device_node *np; > struct kcs_ioreg ioreg; >- struct kcs_bmc *kcs; > const __be32 *reg; >- int channel; >- u32 slave; >- int rc; >+ int i; > > np = pdev->dev.of_node; > > /* Don't translate addresses, we want offsets for the regmaps */ > reg = of_get_address(np, 0, NULL, NULL); > if (!reg) >- return ERR_PTR(-EINVAL); >+ return -EINVAL; > ioreg.idr = be32_to_cpup(reg); > > reg = of_get_address(np, 1, NULL, NULL); > if (!reg) >- return ERR_PTR(-EINVAL); >+ return -EINVAL; > ioreg.odr = be32_to_cpup(reg); > > reg = of_get_address(np, 2, NULL, NULL); > if (!reg) >- return ERR_PTR(-EINVAL); >+ return -EINVAL; > ioreg.str = be32_to_cpup(reg); > >- channel = aspeed_kcs_calculate_channel(); >- if (channel < 0) >- return ERR_PTR(channel); >- >- kcs = kcs_bmc_alloc(>dev, sizeof(struct aspeed_kcs_bmc), channel); >- if (!kcs) >- return ERR_PTR(-ENOMEM); >- >- kcs->ioreg = ioreg; >- >- priv = kcs_bmc_priv(kcs); >- priv->map = syscon_node_to_regmap(pdev->dev.parent->of_node); >- if (IS_ERR(priv->map)) { >- dev_err(>dev, "Couldn't get regmap\n"); >- return ERR_PTR(-ENODEV); >+ for (i = 0; i < ARRAY_SIZE(ast_kcs_bmc_ioregs); i++) { >+ if (!memcmp(_kcs_bmc_ioregs[i], , sizeof(ioreg))) >+ return i + 1; Did some patches perhaps get a bit jumbled during a rebase here or something? This patch removes the
Re: [PATCH][next] cifs: cifspdu.h: Replace one-element array with flexible-array member
merged into cifs-2.6.git for-next On Fri, Mar 26, 2021 at 12:02 PM Gustavo A. R. Silva wrote: > > > > On 3/26/21 10:54, Aurélien Aptel wrote: > > "Gustavo A. R. Silva" writes: > >> There is a regular need in the kernel to provide a way to declare having > >> a dynamically sized set of trailing elements in a structure. Kernel code > >> should always use “flexible array members”[1] for these cases. The older > >> style of one-element or zero-length arrays should no longer be used[2]. > > > > I've checked the usages of the struct, looks OK (we don't allocate it > > directly, we use memory from the small/big buff pools). > > Awesome. :) > > > Reviewed-by: Aurelien Aptel > > Thank you, Aurelien. > -- > Gustavo -- Thanks, Steve
[PATCH v2 3/3] KVM: X86: Do not yield to self
From: Wanpeng Li If the target is self we do not need to yield, we can avoid malicious guest to play this. Signed-off-by: Wanpeng Li --- v1 -> v2: * update comments 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 f08e9b4..ce9a1d2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8231,6 +8231,10 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id) if (!target || !READ_ONCE(target->ready)) goto no_yield; + /* Ignore requests to yield to self */ + if (vcpu == target) + goto no_yield; + if (kvm_vcpu_yield_to(target) <= 0) goto no_yield; -- 2.7.4
[PATCH v2 2/3] KVM: X86: Count attempted/successful directed yield
From: Wanpeng Li To analyze some performance issues with lock contention and scheduling, it is nice to know when directed yield are successful or failing. Signed-off-by: Wanpeng Li --- v1 -> v2: * rename new vcpu stat * account success instead of ignore arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/x86.c | 24 ++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 44f8930..5af7411 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1126,6 +1126,8 @@ struct kvm_vcpu_stat { u64 halt_poll_success_ns; u64 halt_poll_fail_ns; u64 nested_run; + u64 directed_yield_attempted; + u64 directed_yield_successful; }; struct x86_instruction_info; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 16fb395..f08e9b4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -246,6 +246,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns), VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns), VCPU_STAT("nested_run", nested_run), + VCPU_STAT("directed_yield_attempted", directed_yield_attempted), + VCPU_STAT("directed_yield_successful", directed_yield_successful), VM_STAT("mmu_shadow_zapped", mmu_shadow_zapped), VM_STAT("mmu_pte_write", mmu_pte_write), VM_STAT("mmu_pde_zapped", mmu_pde_zapped), @@ -8211,21 +8213,31 @@ void kvm_apicv_init(struct kvm *kvm, bool enable) } EXPORT_SYMBOL_GPL(kvm_apicv_init); -static void kvm_sched_yield(struct kvm *kvm, unsigned long dest_id) +static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id) { struct kvm_vcpu *target = NULL; struct kvm_apic_map *map; + vcpu->stat.directed_yield_attempted++; + rcu_read_lock(); - map = rcu_dereference(kvm->arch.apic_map); + map = rcu_dereference(vcpu->kvm->arch.apic_map); if (likely(map) && dest_id <= map->max_apic_id && map->phys_map[dest_id]) target = map->phys_map[dest_id]->vcpu; rcu_read_unlock(); - if (target && READ_ONCE(target->ready)) - kvm_vcpu_yield_to(target); + if (!target || !READ_ONCE(target->ready)) + goto no_yield; + + if (kvm_vcpu_yield_to(target) <= 0) + goto no_yield; + + vcpu->stat.directed_yield_successful++; + +no_yield: + return; } int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) @@ -8272,7 +8284,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) break; kvm_pv_kick_cpu_op(vcpu->kvm, a0, a1); - kvm_sched_yield(vcpu->kvm, a1); + kvm_sched_yield(vcpu, a1); ret = 0; break; #ifdef CONFIG_X86_64 @@ -8290,7 +8302,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) if (!guest_pv_has(vcpu, KVM_FEATURE_PV_SCHED_YIELD)) break; - kvm_sched_yield(vcpu->kvm, a0); + kvm_sched_yield(vcpu, a0); ret = 0; break; default: -- 2.7.4
[PATCH v2 1/3] x86/kvm: Don't bother __pv_cpu_mask when !CONFIG_SMP
From: Wanpeng Li Enable PV TLB shootdown when !CONFIG_SMP doesn't make sense. Let's move it inside CONFIG_SMP. In addition, we can avoid define and alloc __pv_cpu_mask when !CONFIG_SMP and get rid of 'alloc' variable in kvm_alloc_cpumask. Signed-off-by: Wanpeng Li --- v1 -> v2: * shuffle things around a bit more arch/x86/kernel/kvm.c | 118 +++--- 1 file changed, 55 insertions(+), 63 deletions(-) diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 5e78e01..224a7a1 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -451,6 +451,10 @@ static void __init sev_map_percpu_data(void) } } +#ifdef CONFIG_SMP + +static DEFINE_PER_CPU(cpumask_var_t, __pv_cpu_mask); + static bool pv_tlb_flush_supported(void) { return (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && @@ -458,10 +462,6 @@ static bool pv_tlb_flush_supported(void) kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)); } -static DEFINE_PER_CPU(cpumask_var_t, __pv_cpu_mask); - -#ifdef CONFIG_SMP - static bool pv_ipi_supported(void) { return kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI); @@ -574,6 +574,49 @@ static void kvm_smp_send_call_func_ipi(const struct cpumask *mask) } } +static void kvm_flush_tlb_others(const struct cpumask *cpumask, + const struct flush_tlb_info *info) +{ + u8 state; + int cpu; + struct kvm_steal_time *src; + struct cpumask *flushmask = this_cpu_cpumask_var_ptr(__pv_cpu_mask); + + cpumask_copy(flushmask, cpumask); + /* +* We have to call flush only on online vCPUs. And +* queue flush_on_enter for pre-empted vCPUs +*/ + for_each_cpu(cpu, flushmask) { + src = _cpu(steal_time, cpu); + state = READ_ONCE(src->preempted); + if ((state & KVM_VCPU_PREEMPTED)) { + if (try_cmpxchg(>preempted, , + state | KVM_VCPU_FLUSH_TLB)) + __cpumask_clear_cpu(cpu, flushmask); + } + } + + native_flush_tlb_others(flushmask, info); +} + +static __init int kvm_alloc_cpumask(void) +{ + int cpu; + + if (!kvm_para_available() || nopv) + return 0; + + if (pv_tlb_flush_supported() || pv_ipi_supported()) + for_each_possible_cpu(cpu) { + zalloc_cpumask_var_node(per_cpu_ptr(&__pv_cpu_mask, cpu), + GFP_KERNEL, cpu_to_node(cpu)); + } + + return 0; +} +arch_initcall(kvm_alloc_cpumask); + static void __init kvm_smp_prepare_boot_cpu(void) { /* @@ -611,33 +654,8 @@ static int kvm_cpu_down_prepare(unsigned int cpu) local_irq_enable(); return 0; } -#endif - -static void kvm_flush_tlb_others(const struct cpumask *cpumask, - const struct flush_tlb_info *info) -{ - u8 state; - int cpu; - struct kvm_steal_time *src; - struct cpumask *flushmask = this_cpu_cpumask_var_ptr(__pv_cpu_mask); - - cpumask_copy(flushmask, cpumask); - /* -* We have to call flush only on online vCPUs. And -* queue flush_on_enter for pre-empted vCPUs -*/ - for_each_cpu(cpu, flushmask) { - src = _cpu(steal_time, cpu); - state = READ_ONCE(src->preempted); - if ((state & KVM_VCPU_PREEMPTED)) { - if (try_cmpxchg(>preempted, , - state | KVM_VCPU_FLUSH_TLB)) - __cpumask_clear_cpu(cpu, flushmask); - } - } - native_flush_tlb_others(flushmask, info); -} +#endif static void __init kvm_guest_init(void) { @@ -653,12 +671,6 @@ static void __init kvm_guest_init(void) pv_ops.time.steal_clock = kvm_steal_clock; } - if (pv_tlb_flush_supported()) { - pv_ops.mmu.flush_tlb_others = kvm_flush_tlb_others; - pv_ops.mmu.tlb_remove_table = tlb_remove_table; - pr_info("KVM setup pv remote TLB flush\n"); - } - if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) apic_set_eoi_write(kvm_guest_apic_eoi_write); @@ -668,6 +680,12 @@ static void __init kvm_guest_init(void) } #ifdef CONFIG_SMP + if (pv_tlb_flush_supported()) { + pv_ops.mmu.flush_tlb_others = kvm_flush_tlb_others; + pv_ops.mmu.tlb_remove_table = tlb_remove_table; + pr_info("KVM setup pv remote TLB flush\n"); + } + smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; if (pv_sched_yield_supported()) { smp_ops.send_call_func_ipi = kvm_smp_send_call_func_ipi; @@ -734,7 +752,7 @@ static uint32_t __init kvm_detect(void) static void __init kvm_apic_init(void) { -#if defined(CONFIG_SMP) +#ifdef CONFIG_SMP if
Re: [PATCH v2 2/2] media: staging/intel-ipu3: Fix set_fmt error handling
On Mon, Mar 15, 2021 at 01:34:06PM +0100, Ricardo Ribalda wrote: > If there in an error during a set_fmt, do not overwrite the previous > sizes with the invalid config. > > [ 38.662975] ipu3-imgu :00:05.0: swiotlb buffer is full (sz: 4096 bytes) > [ 38.662980] DMA: Out of SW-IOMMU space for 4096 bytes at device > :00:05.0 > [ 38.663010] general protection fault: [#1] PREEMPT SMP > > Cc: sta...@vger.kernel.org > Fixes: 6d5f26f2e045 ("media: staging/intel-ipu3-v4l: reduce kernel stack > usage") > Signed-off-by: Ricardo Ribalda > --- > drivers/staging/media/ipu3/ipu3-v4l2.c | 25 ++--- > 1 file changed, 14 insertions(+), 11 deletions(-) Reviewed-by: Tomasz Figa Best regards, Tomasz
Re: [PATCH] riscv/kprobe: fix kernel panic when invoking sys_read traced by kprobe
在 2021/4/8 19:20, Jisheng Zhang 写道: > On Tue, 30 Mar 2021 16:18:48 +0800 > Liao Chang wrote: > > >> >> The execution of sys_read end up hitting a BUG_ON() in __find_get_block >> after installing kprobe at sys_read, the BUG message like the following: >> >> [ 65.708663] [ cut here ] >> [ 65.709987] kernel BUG at fs/buffer.c:1251! >> [ 65.711283] Kernel BUG [#1] >> [ 65.712032] Modules linked in: >> [ 65.712925] CPU: 0 PID: 51 Comm: sh Not tainted 5.12.0-rc4 #1 >> [ 65.714407] Hardware name: riscv-virtio,qemu (DT) >> [ 65.715696] epc : __find_get_block+0x218/0x2c8 >> [ 65.716835] ra : __getblk_gfp+0x1c/0x4a >> [ 65.717831] epc : ffe00019f11e ra : ffe00019f56a sp : >> ffe002437930 >> [ 65.719553] gp : ffe000f06030 tp : ffe0015abc00 t0 : >> ffe00191e038 >> [ 65.721290] t1 : ffe00191e038 t2 : 000a s0 : >> ffe002437960 >> [ 65.723051] s1 : ffe00160ad00 a0 : ffe00160ad00 a1 : >> 012a >> [ 65.724772] a2 : 0400 a3 : 0008 a4 : >> 0040 >> [ 65.726545] a5 : a6 : ffe00191e000 a7 : >> >> [ 65.728308] s2 : 012a s3 : 0400 s4 : >> 0008 >> [ 65.730049] s5 : 006c s6 : ffe00240f800 s7 : >> ffe000f080a8 >> [ 65.731802] s8 : 0001 s9 : 012a s10: >> 0008 >> [ 65.733516] s11: 0008 t3 : 03ff t4 : >> 000f >> [ 65.734434] t5 : 03ff t6 : 0004 >> [ 65.734613] status: 0100 badaddr: cause: >> 0003 >> [ 65.734901] Call Trace: >> [ 65.735076] [] __find_get_block+0x218/0x2c8 >> [ 65.735417] [] __ext4_get_inode_loc+0xb2/0x2f6 >> [ 65.735618] [] ext4_get_inode_loc+0x3a/0x8a >> [ 65.735802] [] ext4_reserve_inode_write+0x2e/0x8c >> [ 65.735999] [] __ext4_mark_inode_dirty+0x4c/0x18e >> [ 65.736208] [] ext4_dirty_inode+0x46/0x66 >> [ 65.736387] [] __mark_inode_dirty+0x12c/0x3da >> [ 65.736576] [] touch_atime+0x146/0x150 >> [ 65.736748] [] filemap_read+0x234/0x246 >> [ 65.736920] [] generic_file_read_iter+0xc0/0x114 >> [ 65.737114] [] ext4_file_read_iter+0x42/0xea >> [ 65.737310] [] new_sync_read+0xe2/0x15a >> [ 65.737483] [] vfs_read+0xca/0xf2 >> [ 65.737641] [] ksys_read+0x5e/0xc8 >> [ 65.737816] [] sys_read+0xe/0x16 >> [ 65.737973] [] ret_from_syscall+0x0/0x2 >> [ 65.738858] ---[ end trace fe93f985456c935d ]--- >> >> A simple reproducer looks like: >> echo 'p:myprobe sys_read fd=%a0 buf=%a1 count=%a2' > >> /sys/kernel/debug/tracing/kprobe_events >> echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable >> cat /sys/kernel/debug/tracing/trace >> > > I can't reproduce the BUG_ON with the above step, I may miss something. > My test platform versions Kernel: 0d02ec6b3136 Linux 5.12-rc4 QEMU: fdd76fecdd Update version for v5.0.0 release >> Here's what happens to hit that BUG_ON(): >> >> 1) After installing kprobe at entry of sys_read, the first instruction >>is replaced by 'ebreak' instruction on riscv64 platform. >> >> 2) Once kernel reach the 'ebreak' instruction at the entry of sys_read, >>it trap into the riscv breakpoint handler, where it do something to >>setup for coming single-step of origin instruction, including backup >>the 'sstatus' in pt_regs, followed by disable interrupt during single >>stepping via clear 'SIE' bit of 'sstatus' in pt_regs. >> >> 3) Then kernel restore to the instruction slot contains two instructions, >>one is original instruction at entry of sys_read, the other is 'ebreak'. >>Here it trigger a 'Instruction page fault' exception (value at 'scause' >>is '0xc'), if PF is not filled into PageTabe for that slot yet. >> >> 4) Again kernel trap into page fault exception handler, where it choose >>different policy according to the state of running kprobe. Because >>afte 2) the state is KPROBE_HIT_SS, so kernel reset the current kprobe >>and 'pc' points back to the probe address. >> >> 5) Because 'epc' point back to 'ebreak' instrution at sys_read probe, >>kernel trap into breakpoint handler again, and repeat the operations >>at 2), however 'sstatus' without 'SIE' is keep at 4), it cause the >>real 'sstatus' saved at 2) is overwritten by the one withou 'SIE'. > > Is kprobe_single_step_handler() handled firstly this time? thus we won't > enter kprobe_breakpoint_handler(). > No,because this time kcb->ss.ctx.match_addr points to the single-step slot,but instruction_pointer(regs) points to the first instruction of sys_read('ebreak') so the condition is not token eventually, then we enter kprobe_breakpoint_handler(). bool __kprobes kprobe_single_step_handler(struct pt_regs *regs) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); if ((kcb->ss_ctx.ss_pending)
Re: [PATCH v1 2/2] mmc: sdhci-of-aspeed: Support toggling SD bus signal voltage by GPIO
Hi Steven, On Thu, 8 Apr 2021, at 11:22, Steven Lee wrote: > AST2600-A2 EVB provides reference design to support toggling signal > voltage between 3.3v and 1.8v by power-switch-gpio pin that defined in > the device tree. Is this something you think we need support for beyond the EVB? It sounds a lot like a knob to enable testing of different SD/MMC power configurations and not something that you'd otherwise see in a system design. > It also supporting enabling/disabling SD bus power by > power-gpio. This sounds like it could be useful but I'll defer to Ulf with regards to the binding. > > In the reference design, GPIOV0 of AST2600-A2 EVB is connected to power > load switch that providing 3.3v to SD1 bus vdd. GPIOV1 is connected to > a 1.8v and a 3.3v power load switch that providing signal voltage to > SD1 bus. > If GPIOV0 is active high, SD1 bus is enabled. Otherwise, SD1 bus is > disabled. > If GPIOV1 is active high, 3.3v power load switch is enabled, SD1 signal > voltage is 3.3v, otherwise, 1.8v power load switch will be enabled, SD1 > signal voltage becomes 1.8v. > > AST2600-A2 EVB also support toggling signal voltage for SD2 bus. > The design is the same as SD1 bus. It uses GPIOV2 as power-gpio and > GPIOV3 as power-switch-gpio. > > Signed-off-by: Steven Lee > --- > drivers/mmc/host/sdhci-of-aspeed.c | 155 + > 1 file changed, 137 insertions(+), 18 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-of-aspeed.c > b/drivers/mmc/host/sdhci-of-aspeed.c > index 7d8692e90996..a74a03d37915 100644 > --- a/drivers/mmc/host/sdhci-of-aspeed.c > +++ b/drivers/mmc/host/sdhci-of-aspeed.c > @@ -5,6 +5,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -30,6 +31,7 @@ > #define ASPEED_SDC_S0_PHASE_IN_EN BIT(2) > #define ASPEED_SDC_S0_PHASE_OUT_EN GENMASK(1, 0) > #define ASPEED_SDC_PHASE_MAX 31 > +#define ASPEED_CLOCK_PHASE 0xf4 This isn't related to the power GPIOs, and we already have phase support as suggested by the macros immediately above the one you've added here. Please remove it and make use of the existing mmc phase devicetree binding and driver support. > > struct aspeed_sdc { > struct clk *clk; > @@ -58,18 +60,21 @@ struct aspeed_sdhci_phase_desc { > struct aspeed_sdhci_tap_desc out; > }; > > -struct aspeed_sdhci_pdata { > +struct aspeed_sdhci_data { Why are we renaming this? It looks like it creates a lot of noise in the patch. The data it captured was platform data, hence 'pdata' in the name. In my opinon it's fine if we also have a member called pdata. > unsigned int clk_div_start; > const struct aspeed_sdhci_phase_desc *phase_desc; > size_t nr_phase_descs; > + const struct sdhci_pltfm_data *pdata; > }; > > struct aspeed_sdhci { > - const struct aspeed_sdhci_pdata *pdata; > + const struct aspeed_sdhci_data *data; > struct aspeed_sdc *parent; > u32 width_mask; > struct mmc_clk_phase_map phase_map; > const struct aspeed_sdhci_phase_desc *phase_desc; > + struct gpio_desc *pwr_pin; > + struct gpio_desc *pwr_sw_pin; > }; > > static void aspeed_sdc_configure_8bit_mode(struct aspeed_sdc *sdc, > @@ -209,7 +214,6 @@ static void aspeed_sdhci_set_clock(struct > sdhci_host *host, unsigned int clock) > sdhci = sdhci_pltfm_priv(pltfm_host); > > parent = clk_get_rate(pltfm_host->clk); > - Unrelated whitespace cleanup. > sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); > > if (clock == 0) > @@ -234,14 +238,13 @@ static void aspeed_sdhci_set_clock(struct > sdhci_host *host, unsigned int clock) >* supporting the value 0 in (EMMC12C[7:6], EMMC12C[15:8]), and > capture >* the 0-value capability in clk_div_start. >*/ > - for (div = sdhci->pdata->clk_div_start; div < 256; div *= 2) { > + for (div = sdhci->data->clk_div_start; div < 256; div *= 2) { > bus = parent / div; > if (bus <= clock) > break; > } > > div >>= 1; > - Unrelated whitespace cleanup. > clk = div << SDHCI_DIVIDER_SHIFT; > > aspeed_sdhci_configure_phase(host, bus); > @@ -292,8 +295,78 @@ static u32 aspeed_sdhci_readl(struct sdhci_host > *host, int reg) > return val; > } > > +static void sdhci_aspeed_set_power(struct sdhci_host *host, unsigned char > mode, > +unsigned short vdd) > +{ > + struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host); > + struct aspeed_sdhci *dev = sdhci_pltfm_priv(pltfm_priv); > + u8 pwr = 0; > + > + if (!dev->pwr_pin) > + return sdhci_set_power(host, mode, vdd); > + > + if (mode != MMC_POWER_OFF) { > + switch (1 << vdd) { > + case MMC_VDD_165_195: > + /* > + * Without a regulator, SDHCI does not support 2.0v > + * so we only get here if the driver
[tip:x86/sgx] BUILD SUCCESS ae40aaf6bdbf0354a75b8284a0de453fcf5f4d32
allyesconfig mips allmodconfig powerpc allyesconfig powerpc allmodconfig powerpc allnoconfig x86_64 randconfig-a004-20210408 x86_64 randconfig-a005-20210408 x86_64 randconfig-a003-20210408 x86_64 randconfig-a001-20210408 x86_64 randconfig-a002-20210408 x86_64 randconfig-a006-20210408 i386 randconfig-a006-20210408 i386 randconfig-a003-20210408 i386 randconfig-a004-20210408 i386 randconfig-a005-20210408 i386 randconfig-a002-20210408 i386 randconfig-a001-20210408 i386 randconfig-a014-20210408 i386 randconfig-a016-20210408 i386 randconfig-a011-20210408 i386 randconfig-a012-20210408 i386 randconfig-a013-20210408 i386 randconfig-a015-20210408 riscvnommu_k210_defconfig riscvnommu_virt_defconfig riscv allnoconfig riscv rv32_defconfig um allmodconfig umallnoconfig um allyesconfig um defconfig x86_64rhel-8.3-kselftests x86_64 defconfig x86_64 rhel-8.3 x86_64 rhel-8.3-kbuiltin x86_64 kexec clang tested configs: x86_64 randconfig-a014-20210408 x86_64 randconfig-a015-20210408 x86_64 randconfig-a012-20210408 x86_64 randconfig-a011-20210408 x86_64 randconfig-a013-20210408 x86_64 randconfig-a016-20210408 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org