[PATCH OLK-6.6 00/10] LoongArch: internal repository sync 20250508

Binbin Zhou (1): dt-bindings: pwm: Add Loongson PWM controller Ming Wang (1): LoongArch: Return NULL from huge_pte_offset() for invalid PMD Tianyang Zhang (3): mm/page_alloc.c: avoid infinite retries caused by cpuset race nvme: Add udelay to avoid data error caused by dma sequence megaraid: Add udelay to avoid data error caused by dma sequence wanghongliang (5): pwm: Add Loongson pwm driver support LoongArch: CONFIG_NR_CPUS expanded to 2048 LoongArch: Enable IGC driver LoongArch: Enable GPIO_PCA953X driver LoongArch: support CONFIG_SCHED_MC .../bindings/pwm/loongson,ls7a-pwm.yaml | 67 +++++ MAINTAINERS | 7 + arch/loongarch/Kconfig | 16 +- arch/loongarch/configs/loongson3_defconfig | 4 +- arch/loongarch/include/asm/smp.h | 1 + arch/loongarch/include/asm/topology.h | 9 + arch/loongarch/kernel/smp.c | 46 +++ arch/loongarch/mm/hugetlbpage.c | 2 +- drivers/nvme/host/pci.c | 10 + drivers/pwm/Kconfig | 12 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-loongson.c | 280 ++++++++++++++++++ drivers/scsi/megaraid/megaraid_sas_fusion.c | 8 +- mm/page_alloc.c | 8 + 14 files changed, 465 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml create mode 100644 drivers/pwm/pwm-loongson.c -- 2.33.0

From: Tianyang Zhang <zhangtianyang@loongson.cn> linux-next inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?... -------------------------------- __alloc_pages_slowpath has no change detection for ac->nodemask in the part of retry path, while cpuset can modify it in parallel. For some processes that set mempolicy as MPOL_BIND, this results ac->nodemask changes, and then the should_reclaim_retry will judge based on the latest nodemask and jump to retry, while the get_page_from_freelist only traverses the zonelist from ac->preferred_zoneref, which selected by a expired nodemask and may cause infinite retries in some cases cpu 64: __alloc_pages_slowpath { /* ..... */ retry: /* ac->nodemask = 0x1, ac->preferred->zone->nid = 1 */ if (alloc_flags & ALLOC_KSWAPD) wake_all_kswapds(order, gfp_mask, ac); /* cpu 1: cpuset_write_resmask update_nodemask update_nodemasks_hier update_tasks_nodemask mpol_rebind_task mpol_rebind_policy mpol_rebind_nodemask // mempolicy->nodes has been modified, // which ac->nodemask point to */ /* ac->nodemask = 0x3, ac->preferred->zone->nid = 1 */ if (should_reclaim_retry(gfp_mask, order, ac, alloc_flags, did_some_progress > 0, &no_progress_loops)) goto retry; } Simultaneously starting multiple cpuset01 from LTP can quickly reproduce this issue on a multi node server when the maximum memory pressure is reached and the swap is enabled Signed-off-by: Tianyang Zhang <zhangtianyang@loongson.cn> Change-Id: Ie687a9318b5fd2e42b8927569ea86561c7114609 --- mm/page_alloc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 09aea6306ec3..ada5e2264792 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4283,6 +4283,14 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, } retry: + /* + * Deal with possible cpuset update races or zonelist updates to avoid + * infinite retries. + */ + if (check_retry_cpuset(cpuset_mems_cookie, ac) || + check_retry_zonelist(zonelist_iter_cookie)) + goto restart; + /* Ensure kswapd doesn't accidentally go to sleep as long as we loop */ if (alloc_flags & ALLOC_KSWAPD) wake_all_kswapds(order, gfp_mask, ac); -- 2.33.0

From: Ming Wang <wangming01@loongson.cn> stable inclusion from stable-v6.6.89 commit 2ca9380b12711afe95b3589bd82b59623b3c96b3 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- LoongArch's huge_pte_offset() currently returns a pointer to a PMD slot even if the underlying entry points to invalid_pte_table (indicating no mapping). Callers like smaps_hugetlb_range() fetch this invalid entry value (the address of invalid_pte_table) via this pointer. The generic is_swap_pte() check then incorrectly identifies this address as a swap entry on LoongArch, because it satisfies the !pte_present() && !pte_none() conditions. This misinterpretation, combined with a coincidental match by is_migration_entry() on the address bits, leads to kernel crashes in pfn_swap_entry_to_page(). Fix this at the architecture level by modifying huge_pte_offset() to check the PMD entry's content using pmd_none() before returning. If the entry is none (i.e., it points to invalid_pte_table), return NULL instead of the pointer to the slot. Change-Id: Ic3b605551c5fe4e21ee3d02606bd0340cddcbf91 Co-developed-by: Hongchen Zhang <zhanghongchen@loongson.cn> Signed-off-by: Hongchen Zhang <zhanghongchen@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: Ming Wang <wangming01@loongson.cn> --- arch/loongarch/mm/hugetlbpage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/loongarch/mm/hugetlbpage.c b/arch/loongarch/mm/hugetlbpage.c index 62ddcea0aa14..aca52c42e94e 100644 --- a/arch/loongarch/mm/hugetlbpage.c +++ b/arch/loongarch/mm/hugetlbpage.c @@ -47,7 +47,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, pmd = pmd_offset(pud, addr); } } - return (pte_t *) pmd; + return pmd_none(pmdp_get(pmd)) ? NULL : (pte_t *) pmd; } int pmd_huge(pmd_t pmd) -- 2.33.0

From: Binbin Zhou <zhoubinbin@loongson.cn> linux-next inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?... -------------------------------- Add Loongson PWM controller binding with DT schema format using json-schema. Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Acked-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> Link: https://lore.kernel.org/r/57e0cbd4b7ce37da94094205e28a2ec2256c7175.174340307... Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org> --- .../bindings/pwm/loongson,ls7a-pwm.yaml | 67 +++++++++++++++++++ MAINTAINERS | 6 ++ 2 files changed, 73 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml diff --git a/Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml b/Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml new file mode 100644 index 000000000000..5d64fb40a0d6 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pwm/loongson,ls7a-pwm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Loongson PWM Controller + +maintainers: + - Binbin Zhou <zhoubinbin@loongson.cn> + +description: + The Loongson PWM has one pulse width output signal and one pulse input + signal to be measured. + It can be found on Loongson-2K series cpus and Loongson LS7A bridge chips. + +allOf: + - $ref: pwm.yaml# + +properties: + compatible: + oneOf: + - const: loongson,ls7a-pwm + - items: + - enum: + - loongson,ls2k0500-pwm + - loongson,ls2k1000-pwm + - loongson,ls2k2000-pwm + - const: loongson,ls7a-pwm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + '#pwm-cells': + description: + The first cell must have a value of 0, which specifies the PWM output signal; + The second cell is the period in nanoseconds; + The third cell flag supported by this binding is PWM_POLARITY_INVERTED. + const: 3 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/clock/loongson,ls2k-clk.h> + + pwm@1fe22000 { + compatible = "loongson,ls2k1000-pwm", "loongson,ls7a-pwm"; + reg = <0x1fe22000 0x10>; + interrupt-parent = <&liointc0>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LOONGSON2_APB_CLK>; + #pwm-cells = <3>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index c6a3ac61989c..0031d4f2c05c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12438,6 +12438,12 @@ S: Maintained F: Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml F: drivers/i2c/busses/i2c-ls2x.c +LOONGSON PWM DRIVER +M: Binbin Zhou <zhoubinbin@loongson.cn> +L: linux-pwm@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml + LOONGSON-2 SOC SERIES CLOCK DRIVER M: Yinbo Zhu <zhuyinbo@loongson.cn> L: linux-clk@vger.kernel.org -- 2.33.0

From: wanghongliang <wanghongliang@loongson.cn> LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA -------------------------------- Add loongson pwm driver. Signed-off-by: wanghongliang <wanghongliang@loongson.cn> Change-Id: I511861526904d1ae824090feea691b2be30a456e --- MAINTAINERS | 1 + arch/loongarch/configs/loongson3_defconfig | 1 + drivers/pwm/Kconfig | 12 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-loongson.c | 280 +++++++++++++++++++++ 5 files changed, 295 insertions(+) create mode 100644 drivers/pwm/pwm-loongson.c diff --git a/MAINTAINERS b/MAINTAINERS index 0031d4f2c05c..5f7d8f641800 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12443,6 +12443,7 @@ M: Binbin Zhou <zhoubinbin@loongson.cn> L: linux-pwm@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml +F: drivers/pwm/pwm-loongson.c LOONGSON-2 SOC SERIES CLOCK DRIVER M: Yinbo Zhu <zhuyinbo@loongson.cn> diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig index 210ab156facd..c67ca62ed747 100644 --- a/arch/loongarch/configs/loongson3_defconfig +++ b/arch/loongarch/configs/loongson3_defconfig @@ -1945,6 +1945,7 @@ CONFIG_NTB_TOOL=m CONFIG_NTB_PERF=m CONFIG_NTB_TRANSPORT=m CONFIG_PWM=y +CONFIG_PWM_LOONGSON=y CONFIG_POWERCAP=y CONFIG_USB4=m CONFIG_DAX=y diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 8ebcddf91f7b..da57f4a2bde0 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -314,6 +314,18 @@ config PWM_KEEMBAY To compile this driver as a module, choose M here: the module will be called pwm-keembay. +config PWM_LOONGSON + tristate "Loongson PWM support" + depends on MACH_LOONGSON64 || COMPILE_TEST + depends on COMMON_CLK + help + Generic PWM framework driver for Loongson family. + It can be found on Loongson-2K series cpus and Loongson LS7A + bridge chips. + + To compile this driver as a module, choose M here: the module + will be called pwm-loongson. + config PWM_LP3943 tristate "TI/National Semiconductor LP3943 PWM support" depends on MFD_LP3943 diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index c822389c2a24..5d5b64c25b7f 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_PWM_INTEL_LGM) += pwm-intel-lgm.o obj-$(CONFIG_PWM_IQS620A) += pwm-iqs620a.o obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o obj-$(CONFIG_PWM_KEEMBAY) += pwm-keembay.o +obj-$(CONFIG_PWM_LOONGSON) += pwm-loongson.o obj-$(CONFIG_PWM_LP3943) += pwm-lp3943.o obj-$(CONFIG_PWM_LPC18XX_SCT) += pwm-lpc18xx-sct.o obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c new file mode 100644 index 000000000000..8432a6ad1d10 --- /dev/null +++ b/drivers/pwm/pwm-loongson.c @@ -0,0 +1,280 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2017-2025 Loongson Technology Corporation Limited. + * + * Loongson PWM driver + * + * For Loongson's PWM IP block documentation please refer Chapter 11 of + * Reference Manual: https://loongson.github.io/LoongArch-Documentation/Loongson-7A1000-usermanua... + * + * Author: Juxin Gao <gaojuxin@loongson.cn> + * Further cleanup and restructuring by: + * Binbin Zhou <zhoubinbin@loongson.cn> + * + * Limitations: + * - If both DUTY and PERIOD are set to 0, the output is a constant low signal. + * - When disabled the output is driven to 0 independent of the configured + * polarity. + * - If the register is reconfigured while PWM is running, it does not complete + * the currently running period. + * - Disabling the PWM stops the output immediately (without waiting for current + * period to complete first). + */ + +#include <linux/acpi.h> +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pwm.h> +#include <linux/units.h> + +/* Loongson PWM registers */ +#define LOONGSON_PWM_REG_DUTY 0x4 /* Low Pulse Buffer Register */ +#define LOONGSON_PWM_REG_PERIOD 0x8 /* Pulse Period Buffer Register */ +#define LOONGSON_PWM_REG_CTRL 0xc /* Control Register */ + +/* Control register bits */ +#define LOONGSON_PWM_CTRL_REG_EN BIT(0) /* Counter Enable Bit */ +#define LOONGSON_PWM_CTRL_REG_OE BIT(3) /* Pulse Output Enable Control Bit, Valid Low */ +#define LOONGSON_PWM_CTRL_REG_SINGLE BIT(4) /* Single Pulse Control Bit */ +#define LOONGSON_PWM_CTRL_REG_INTE BIT(5) /* Interrupt Enable Bit */ +#define LOONGSON_PWM_CTRL_REG_INT BIT(6) /* Interrupt Bit */ +#define LOONGSON_PWM_CTRL_REG_RST BIT(7) /* Counter Reset Bit */ +#define LOONGSON_PWM_CTRL_REG_CAPTE BIT(8) /* Measurement Pulse Enable Bit */ +#define LOONGSON_PWM_CTRL_REG_INVERT BIT(9) /* Output flip-flop Enable Bit */ +#define LOONGSON_PWM_CTRL_REG_DZONE BIT(10) /* Anti-dead Zone Enable Bit */ + +/* default input clk frequency for the ACPI case */ +#define LOONGSON_PWM_FREQ_DEFAULT 50000 /* Hz */ + +struct pwm_loongson_ddata { + struct pwm_chip chip; + struct clk *clk; + void __iomem *base; + u64 clk_rate; +}; + +static inline __pure struct pwm_loongson_ddata *to_pwm_loongson_ddata(struct pwm_chip *chip) +{ + return container_of(chip, struct pwm_loongson_ddata, chip); +} + +static inline u32 pwm_loongson_readl(struct pwm_loongson_ddata *ddata, u32 offset) +{ + return readl(ddata->base + offset); +} + +static inline void pwm_loongson_writel(struct pwm_loongson_ddata *ddata, + u32 val, u32 offset) +{ + writel(val, ddata->base + offset); +} + +static int pwm_loongson_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, + enum pwm_polarity polarity) +{ + u16 val; + struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); + + val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); + + if (polarity == PWM_POLARITY_INVERSED) + /* Duty cycle defines LOW period of PWM */ + val |= LOONGSON_PWM_CTRL_REG_INVERT; + else + /* Duty cycle defines HIGH period of PWM */ + val &= ~LOONGSON_PWM_CTRL_REG_INVERT; + + pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); + + return 0; +} + +static void pwm_loongson_disable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + u32 val; + struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); + + val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); + val &= ~LOONGSON_PWM_CTRL_REG_EN; + pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); +} + +static int pwm_loongson_enable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + u32 val; + struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); + + val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); + val |= LOONGSON_PWM_CTRL_REG_EN; + pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); + + return 0; +} + +static int pwm_loongson_config(struct pwm_chip *chip, struct pwm_device *pwm, + u64 duty_ns, u64 period_ns) +{ + u32 duty, period; + struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); + + /* duty = duty_ns * ddata->clk_rate / NSEC_PER_SEC */ + duty = mul_u64_u64_div_u64(duty_ns, ddata->clk_rate, NSEC_PER_SEC); + if (duty > U32_MAX) + duty = U32_MAX; + + /* period = period_ns * ddata->clk_rate / NSEC_PER_SEC */ + period = mul_u64_u64_div_u64(period_ns, ddata->clk_rate, NSEC_PER_SEC); + if (period > U32_MAX) + period = U32_MAX; + + pwm_loongson_writel(ddata, duty, LOONGSON_PWM_REG_DUTY); + pwm_loongson_writel(ddata, period, LOONGSON_PWM_REG_PERIOD); + + return 0; +} + +static int pwm_loongson_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) +{ + int ret; + bool enabled = pwm->state.enabled; + + if (!state->enabled) { + if (enabled) + pwm_loongson_disable(chip, pwm); + return 0; + } + + ret = pwm_loongson_set_polarity(chip, pwm, state->polarity); + if (ret) + return ret; + + ret = pwm_loongson_config(chip, pwm, state->duty_cycle, state->period); + if (ret) + return ret; + + if (!enabled && state->enabled) + ret = pwm_loongson_enable(chip, pwm); + + return ret; +} + +static int pwm_loongson_get_state(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_state *state) +{ + u32 duty, period, ctrl; + struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); + + duty = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_DUTY); + period = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_PERIOD); + ctrl = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); + + /* duty & period have a max of 2^32, so we can't overflow */ + state->duty_cycle = DIV64_U64_ROUND_UP((u64)duty * NSEC_PER_SEC, ddata->clk_rate); + state->period = DIV64_U64_ROUND_UP((u64)period * NSEC_PER_SEC, ddata->clk_rate); + state->polarity = (ctrl & LOONGSON_PWM_CTRL_REG_INVERT) ? PWM_POLARITY_INVERSED : + PWM_POLARITY_NORMAL; + state->enabled = (ctrl & LOONGSON_PWM_CTRL_REG_EN) ? true : false; + + return 0; +} + +static const struct pwm_ops pwm_loongson_ops = { + .apply = pwm_loongson_apply, + .get_state = pwm_loongson_get_state, +}; + +static int pwm_loongson_probe(struct platform_device *pdev) +{ + int ret; + struct pwm_loongson_ddata *ddata; + struct device *dev = &pdev->dev; + + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); + if (!ddata) + return -ENOMEM; + + ddata->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ddata->base)) + return PTR_ERR(ddata->base); + + if (!has_acpi_companion(dev)) { + ddata->clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(ddata->clk)) + return dev_err_probe(dev, PTR_ERR(ddata->clk), + "failed to get pwm clock\n"); + ddata->clk_rate = clk_get_rate(ddata->clk); + } else { + ddata->clk_rate = LOONGSON_PWM_FREQ_DEFAULT; + } + + /* This check is done to prevent an overflow in .apply */ + if (ddata->clk_rate > NSEC_PER_SEC) + return dev_err_probe(dev, -EINVAL, "PWM clock out of range\n"); + + ddata->chip.dev = dev; + ddata->chip.ops = &pwm_loongson_ops; + ddata->chip.npwm = 1; + platform_set_drvdata(pdev, ddata); + + ret = devm_pwmchip_add(dev, &ddata->chip); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to add PWM chip\n"); + + return 0; +} + +static int pwm_loongson_suspend(struct device *dev) +{ + struct pwm_loongson_ddata *ddata = dev_get_drvdata(dev); + struct pwm_device *pwm = &ddata->chip.pwms[0]; + + if (pwm->state.enabled) + return -EBUSY; + + clk_disable_unprepare(ddata->clk); + + return 0; +} + +static int pwm_loongson_resume(struct device *dev) +{ + struct pwm_loongson_ddata *ddata = dev_get_drvdata(dev); + + return clk_prepare_enable(ddata->clk); +} + +static DEFINE_SIMPLE_DEV_PM_OPS(pwm_loongson_pm_ops, pwm_loongson_suspend, + pwm_loongson_resume); + +static const struct of_device_id pwm_loongson_of_ids[] = { + { .compatible = "loongson,ls7a-pwm" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, pwm_loongson_of_ids); + +static const struct acpi_device_id pwm_loongson_acpi_ids[] = { + { "LOON0006" }, + { } +}; +MODULE_DEVICE_TABLE(acpi, pwm_loongson_acpi_ids); + +static struct platform_driver pwm_loongson_driver = { + .probe = pwm_loongson_probe, + .driver = { + .name = "loongson-pwm", + .pm = pm_ptr(&pwm_loongson_pm_ops), + .of_match_table = pwm_loongson_of_ids, + .acpi_match_table = pwm_loongson_acpi_ids, + }, +}; +module_platform_driver(pwm_loongson_driver); + +MODULE_DESCRIPTION("Loongson PWM driver"); +MODULE_AUTHOR("Loongson Technology Corporation Limited."); +MODULE_LICENSE("GPL"); -- 2.33.0

From: wanghongliang <wanghongliang@loongson.cn> LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA -------------------------------- Extend NR_CPUS to 2048 to enable machines with more CPU cores to run normally. Change-Id: I09fd711ade949268365a7566a424e4c6e77abddb Signed-off-by: wanghongliang <wanghongliang@loongson.cn> --- arch/loongarch/Kconfig | 7 ++++--- arch/loongarch/configs/loongson3_defconfig | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 4a021d86fc57..fa47efea7a13 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -184,6 +184,7 @@ config LOONGARCH select USE_PERCPU_NUMA_NODE_ID select USER_STACKTRACE_SUPPORT select ZONE_DMA32 + select CPUMASK_OFFSTACK if NR_CPUS > 256 config 32BIT bool @@ -447,10 +448,10 @@ config HOTPLUG_CPU Say N if you want to disable CPU hotplug. config NR_CPUS - int "Maximum number of CPUs (2-256)" - range 2 256 + int "Maximum number of CPUs (2-2048)" + range 2 2048 depends on SMP - default "64" + default "2048" help This allows you to specify the maximum number of CPUs which this kernel will support. diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig index c67ca62ed747..ae624f624b1e 100644 --- a/arch/loongarch/configs/loongson3_defconfig +++ b/arch/loongarch/configs/loongson3_defconfig @@ -42,7 +42,6 @@ CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y CONFIG_CMDLINE="vfio_iommu_type1.allow_unsafe_interrupts=1 nokaslr" CONFIG_CMDLINE_EXTEND=y -CONFIG_NR_CPUS=256 CONFIG_NUMA=y CONFIG_ARCH_IOREMAP=y CONFIG_CPU_HAS_LSX=y -- 2.33.0

From: wanghongliang <wanghongliang@loongson.cn> LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA -------------------------------- support intel i225/i226 network card driver. Signed-off-by: wanghongliang <wanghongliang@loongson.cn> Change-Id: Ia9dc7347fbcfb70f800ea85488aa8d47243939a4 --- arch/loongarch/configs/loongson3_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig index ae624f624b1e..f9acc8a9eb40 100644 --- a/arch/loongarch/configs/loongson3_defconfig +++ b/arch/loongarch/configs/loongson3_defconfig @@ -846,6 +846,7 @@ CONFIG_I40E_DCB=y CONFIG_I40EVF=m CONFIG_ICE=m CONFIG_FM10K=m +CONFIG_IGC=m # CONFIG_NET_VENDOR_MARVELL is not set CONFIG_MLX4_EN=m # CONFIG_MLX4_CORE_GEN2 is not set -- 2.33.0

From: wanghongliang <wanghongliang@loongson.cn> LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA -------------------------------- Enable gpio-pca953x driver. Signed-off-by: wanghongliang <wanghongliang@loongson.cn> Change-Id: I98b0e70b0f44274f2f2c89bd05b143ee08fe64f9 --- arch/loongarch/configs/loongson3_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig index f9acc8a9eb40..f0bcd1644e4b 100644 --- a/arch/loongarch/configs/loongson3_defconfig +++ b/arch/loongarch/configs/loongson3_defconfig @@ -1179,6 +1179,7 @@ CONFIG_PINCTRL_LOONGSON2=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_AMDPT=m CONFIG_GPIO_LOONGSON_64BIT=y +CONFIG_GPIO_PCA953X=m CONFIG_GPIO_VIPERBOARD=m CONFIG_POWER_RESET=y CONFIG_SENSORS_AD7414=m -- 2.33.0

From: wanghongliang <wanghongliang@loongson.cn> LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA -------------------------------- In order to achieve more reasonable load balancing behavior, support for SCHED_MC has been added. The LLC distribution of Loongarch now is consistent with numa-node, the balancing domain of SCHED_MC can effectively reduce the situation where processes are awakened to smt_slibing Signed-off-by: wanghongliang <wanghongliang@loongson.cn> Signed-off-by: Tianyang Zhang <zhangtianyang@loongson.cn> Change-Id: I8388f208d93bf53d79473ba995895e5cd89d81b4 --- arch/loongarch/Kconfig | 9 ++++++ arch/loongarch/include/asm/smp.h | 1 + arch/loongarch/include/asm/topology.h | 9 ++++++ arch/loongarch/kernel/smp.c | 46 +++++++++++++++++++++++++++ 4 files changed, 65 insertions(+) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index fa47efea7a13..316bf567759d 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -456,6 +456,15 @@ config NR_CPUS This allows you to specify the maximum number of CPUs which this kernel will support. +config SCHED_MC + def_bool y + prompt "Multi-core scheduler support" + depends on SMP + help + Multi-core scheduler support improves the CPU scheduler's decision + making when dealing with multi-core CPU chips at a cost of slightly + increased overhead in some places. If unsure say N here. + config NUMA bool "NUMA Support" select SMP diff --git a/arch/loongarch/include/asm/smp.h b/arch/loongarch/include/asm/smp.h index cc232901e4dd..1a7dba6256ea 100644 --- a/arch/loongarch/include/asm/smp.h +++ b/arch/loongarch/include/asm/smp.h @@ -24,6 +24,7 @@ extern int num_processors; extern int disabled_cpus; extern cpumask_t cpu_sibling_map[]; extern cpumask_t cpu_core_map[]; +extern cpumask_t cpu_llc_shared_map[]; extern cpumask_t cpu_foreign_map[]; void loongson_smp_setup(void); diff --git a/arch/loongarch/include/asm/topology.h b/arch/loongarch/include/asm/topology.h index 379f5e4830eb..5c485999cbb2 100644 --- a/arch/loongarch/include/asm/topology.h +++ b/arch/loongarch/include/asm/topology.h @@ -35,6 +35,15 @@ extern unsigned int __max_packages; #define topology_core_id(cpu) (cpu_data[cpu].core) #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) #define topology_sibling_cpumask(cpu) (&cpu_sibling_map[cpu]) + +/* + * return cpus that shares the last level cache. + */ +static inline const struct cpumask *cpu_coregroup_mask(int cpu) +{ + return &cpu_llc_shared_map[cpu]; +} + #else #define topology_max_packages() (1) #endif diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 5d02bf5126b7..0201eb35df4c 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -49,6 +49,9 @@ EXPORT_SYMBOL(cpu_sibling_map); cpumask_t cpu_core_map[NR_CPUS] __read_mostly; EXPORT_SYMBOL(cpu_core_map); +cpumask_t cpu_llc_shared_map[NR_CPUS] __read_mostly; +EXPORT_SYMBOL(cpu_llc_shared_map); + static DECLARE_COMPLETION(cpu_starting); static DECLARE_COMPLETION(cpu_running); @@ -65,6 +68,10 @@ static cpumask_t cpu_sibling_setup_map; /* representing cpus for which core maps can be computed */ static cpumask_t cpu_core_setup_map; +/* representing cpus for which llc sibling maps can be computed */ +static cpumask_t cpu_llc_shared_setup_map; + + struct secondary_data cpuboot_data; static DEFINE_PER_CPU(int, cpu_state); @@ -103,6 +110,42 @@ static inline void set_cpu_core_map(int cpu) } } +static inline bool cpus_are_shared_llc(int cpua, int cpub) +{ + if (cpu_to_node(cpua) != cpu_to_node(cpub)) + return false; + + return true; +} + +static inline void set_cpu_llc_shared_map(int cpu) +{ + int i; + + cpumask_set_cpu(cpu, &cpu_llc_shared_setup_map); + + for_each_cpu(i, &cpu_llc_shared_setup_map) { + if (cpus_are_shared_llc(cpu, i)) { + cpumask_set_cpu(i, &cpu_llc_shared_map[cpu]); + cpumask_set_cpu(cpu, &cpu_llc_shared_map[i]); + } + } +} + +static inline void clear_cpu_llc_shared_map(int cpu) +{ + int i; + + for_each_cpu(i, &cpu_llc_shared_setup_map) { + if (cpus_are_shared_llc(cpu, i)) { + cpumask_clear_cpu(i, &cpu_llc_shared_map[cpu]); + cpumask_clear_cpu(cpu, &cpu_llc_shared_map[i]); + } + } + + cpumask_clear_cpu(cpu, &cpu_llc_shared_setup_map); +} + static inline void set_cpu_sibling_map(int cpu) { int i; @@ -401,6 +444,7 @@ int loongson_cpu_disable(void) #endif set_cpu_online(cpu, false); clear_cpu_sibling_map(cpu); + clear_cpu_llc_shared_map(cpu); calculate_cpu_foreign_map(); local_irq_save(flags); fixup_irqs(); @@ -523,6 +567,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) loongson_prepare_cpus(max_cpus); set_cpu_sibling_map(0); set_cpu_core_map(0); + set_cpu_llc_shared_map(0); calculate_cpu_foreign_map(); #ifndef CONFIG_HOTPLUG_CPU init_cpu_present(cpu_possible_mask); @@ -564,6 +609,7 @@ asmlinkage void start_secondary(void) set_cpu_sibling_map(cpu); set_cpu_core_map(cpu); + set_cpu_llc_shared_map(cpu); notify_cpu_starting(cpu); -- 2.33.0

From: Tianyang Zhang <zhangtianyang@loongson.cn> LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA -------------------------------- There is no guarantee of sequence between DMA and interrupts on the Loongson platform. Signed-off-by: songwenge <songwenge@loongson.cn> Signed-off-by: Tianyang Zhang <zhangtianyang@loongson.cn> Change-Id: Ide7456d6fdeb29a3b2b421ee54af27a8b13adad2 --- drivers/nvme/host/pci.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index b1310e69d07d..f5b44909c742 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -10,6 +10,9 @@ #include <linux/blk-mq.h> #include <linux/blk-mq-pci.h> #include <linux/blk-integrity.h> +#ifdef CONFIG_LOONGARCH +#include <linux/delay.h> +#endif #include <linux/dmi.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -1079,6 +1082,13 @@ static irqreturn_t nvme_irq(int irq, void *data) struct nvme_queue *nvmeq = data; DEFINE_IO_COMP_BATCH(iob); +#ifdef CONFIG_LOONGARCH + /* + * There is no guarantee of sequence between DMA + * and interrupts on the Loongson platform. + */ + udelay(30); +#endif if (nvme_poll_cq(nvmeq, &iob)) { if (!rq_list_empty(iob.req_list)) nvme_pci_complete_batch(&iob); -- 2.33.0

From: Tianyang Zhang <zhangtianyang@loongson.cn> LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC6CVG CVE: NA -------------------------------- There is no guarantee of sequence between DMA and interrupts on the Loongson platform. Signed-off-by: songwenge <songwenge@loongson.cn> Signed-off-by: Tianyang Zhang <zhangtianyang@loongson.cn> Change-Id: I20f03062f766eb5b4cfe7e2eef5a8785234ebc09 --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index d4b97f0a5013..68cf8840d8c2 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3881,7 +3881,13 @@ static irqreturn_t megasas_isr_fusion(int irq, void *devp) instance->instancet->clear_intr(instance); return IRQ_HANDLED; } - +#ifdef CONFIG_LOONGARCH + /* + * There is no guarantee of sequence between DMA + * and interrupts on the Loongson platform. + */ + udelay(30); +#endif return complete_cmd_fusion(instance, irq_context->MSIxIndex, irq_context) ? IRQ_HANDLED : IRQ_NONE; } -- 2.33.0

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/16181 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/MPP... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/16181 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/MPP...
participants (2)
-
Hongchen Zhang
-
patchwork bot