Skip to content

Conversation

@WangJia-UR
Copy link
Contributor

@WangJia-UR WangJia-UR commented Jan 9, 2026

  1. Backport the ultrarisc dp1000 plic implementation from the upstream;
  2. Support corepvt of ultrarisc dp100;
  3. Backport ledtrig-netdev and "net: phy: realtek: Add support for PHY LEDs on RTL8211F" to enable setting phy leds on MilkV Titan;
  4. Update ultrarisc device tree and defconfig.

Summary by Sourcery

Add UltraRISC DP1000 core PVT hwmon support, enhance LED trigger and Realtek PHY LED integration, and update UltraRISC platform IRQ, PCIe, and device tree bindings for DP1000/Titan.

New Features:

  • Introduce a hwmon driver and DT binding for the UltraRISC DP1000 core PVT voltage and temperature sensor.
  • Enable hardware-controlled PHY LEDs on Realtek RTL8211F PHYs and advertise the netdev LED trigger via a module alias.
  • Extend netdev LED triggers to support additional link speeds up to 10G and expose only speeds supported by the underlying link.

Bug Fixes:

  • Handle the UltraRISC CP100 PLIC claim register erratum by isolating pending interrupts before claiming and restoring the enable state.
  • Avoid spurious error logs when LED backends do not support fixed brightness settings or are unplugged, and correctly apply default and panic LED triggers.

Enhancements:

  • Refine LED trigger core to support a "default" trigger selection via sysfs and deferred loading of default trigger modules.
  • Improve netdev LED trigger behavior with hardware-offload awareness, cached link mode capabilities, and updated sysfs visibility semantics.
  • Adjust PCIe and PLIC UltraRISC compatibles and DT bindings to match upstream names and add the CP100 PLIC compatible pairing.
  • Clarify UltraRISC DP1000 pinctrl binding header naming in documentation and correct the DP1000 M0 DTB name in the UltraRISC DTS Makefile.

Build:

  • Hook the new UltraRISC core PVT hwmon driver into the hwmon Kconfig and Makefile so it can be built when enabled.

Documentation:

  • Document the UltraRISC DP1000 core PVT device tree binding for the new hwmon driver.
  • Update PLIC and pinctrl device tree binding documentation to reflect new UltraRISC compatibles and header names.

@sourcery-ai
Copy link

sourcery-ai bot commented Jan 9, 2026

Reviewer's Guide

Backports and extends PLIC, LED trigger, and Realtek PHY LED support while adding an UltraRISC DP1000 core PVT hwmon driver and updating Ultrarisc DTS/defconfig so MilkV Titan can use PHY-controlled LEDs and on-chip sensors correctly.

Sequence diagram for cp100 PLIC interrupt handling with claim-register erratum

sequenceDiagram
    participant Device as Device_irq_source
    participant PLIC as cp100_PLIC
    participant CPU as RISC_V_CPU
    participant Handler as plic_handle_irq_cp100
    participant Core as cp100_get_hwirq
    participant IRQ as generic_handle_domain_irq

    Device->>PLIC: Assert_interrupt
    PLIC-->>CPU: External_interrupt
    CPU->>Handler: Enter_chained_handler
    Handler->>Core: cp100_get_hwirq(handler, claim)
    loop While_pending_irq
        Core->>Core: cp100_isolate_pending_irq()
        Core->>PLIC: Read_pending_registers
        Core->>PLIC: Write_enable_registers_isolating_first_pending
        Core->>PLIC: Read_claim_register
        Core-->>Handler: hwirq
        Handler->>IRQ: generic_handle_domain_irq(irqdomain, hwirq)
        IRQ-->>Handler: err
        alt Mapping_missing
            Handler->>Handler: pr_warn_ratelimited()
        end
        Core->>PLIC: Restore_enable_registers_from_enable_save
    end
    Handler->>CPU: chained_irq_exit()
    CPU-->>PLIC: End_of_interrupt
Loading

Sequence diagram for LED default trigger resolution and hw control

sequenceDiagram
    actor User as Userspace
    participant Sysfs as led_trigger_write
    participant LED as led_classdev
    participant TrigCore as led_trigger_set_default
    participant Match as led_match_default_trigger
    participant Mod as request_module_nowait
    participant TrigReg as led_trigger_register

    User->>Sysfs: Write("default") to trigger_file
    Sysfs->>LED: Get_led_cdev_from_kobj
    alt Buffer_is_default
        Sysfs->>TrigCore: led_trigger_set_default(led_cdev)
        alt Default_trigger_is_none
            TrigCore->>TrigCore: led_trigger_remove(led_cdev)
        else Named_default_trigger
            TrigCore->>TrigCore: Iterate_trigger_list
            TrigCore->>Match: led_match_default_trigger(led_cdev, trig)
            alt Trigger_found_and_relevant
                Match->>LED: led_trigger_set(led_cdev, trig)
            else Trigger_not_found
                TrigCore->>Mod: request_module_nowait(ledtrig:<name>)
            end
        end
    end

    TrigReg->>TrigCore: led_trigger_register(trig)
    TrigCore->>TrigCore: Iterate_leds_list
    TrigCore->>Match: led_match_default_trigger(led_cdev, trig)
    alt Match_success
        Match->>LED: led_trigger_set(led_cdev, trig)
    end
Loading

Class diagram for corepvt-ultrarisc DP1000 PVT hwmon driver

classDiagram
    class corepvt_channel_config {
        +const_char_pointer label
        +u32 trim
    }

    class corepvt_data {
        +const_hwmon_chip_info_pointer chip_info
        +u64 temp_chl_mask
        +u64 vol_chl_mask
    }

    class corepvt_hwmon {
        +struct_device_pointer dev
        +struct_device_pointer hwmon
        +void_pointer regs
        +int irq
        +int clk_freq
        +int channels
        +const_hwmon_chip_info_pointer chip_info
        +corepvt_channel_config config[PVT_MAX_CHANNEL]
        +const_corepvt_data_pointer pvt_data
        +raw_spinlock_t lock
        +int corepvt_read_vol(corepvt_hwmon_pointer pvt, int channel, long_pointer val)
        +int corepvt_read_temp(corepvt_hwmon_pointer pvt, int channel, long_pointer val)
        +umode_t corepvt_is_visible(const_void_pointer drvdata, enum_hwmon_sensor_types type, u32 attr, int channel)
        +int corepvt_read(struct_device_pointer dev, enum_hwmon_sensor_types type, u32 attr, int channel, long_pointer val)
        +int corepvt_read_string(struct_device_pointer dev, enum_hwmon_sensor_types type, u32 attr, int channel, const_char_pointer_pointer str)
        +int corepvt_init(corepvt_hwmon_pointer pvt)
        +int corepvt_probe_channel_from_dt(struct_platform_device_pointer pdev, corepvt_hwmon_pointer pvt)
        +int corepvt_probe(struct_platform_device_pointer pdev)
    }

    class hwmon_chip_info {
        +const_hwmon_ops_pointer ops
        +const_hwmon_channel_info_pointer_const_pointer info
    }

    class hwmon_ops {
        +umode_t_pointer is_visible
        +int_pointer read
        +int_pointer read_string
    }

    class hwmon_channel_info {
        +enum_hwmon_sensor_types type
        +u32_pointer config
    }

    corepvt_hwmon --> corepvt_channel_config : has_many
    corepvt_hwmon --> corepvt_data : uses
    corepvt_data --> hwmon_chip_info : provides
    hwmon_chip_info --> hwmon_ops : uses
    hwmon_chip_info --> hwmon_channel_info : describes

    class platform_driver_corepvt_driver {
        +int_pointer probe
        +struct_device_driver driver
    }

    platform_driver_corepvt_driver --> corepvt_hwmon : creates
    platform_driver_corepvt_driver --> corepvt_data : matches_via_of_match
Loading

File-Level Changes

Change Details Files
Implement UltraRISC CP100 PLIC claim-register erratum handling and related cleanups in the SiFive PLIC driver and bindings.
  • Rename the PLIC quirk bit to PLIC_QUIRK_CP100_CLAIM_REGISTER_ERRATUM and switch the compatible string from ultrarisc,dp1000-plic to ultrarisc,cp100-plic
  • Change enable register handling to cache enable state in handler->enable_save on each toggle and stop saving it in suspend, relying on the cached values instead
  • Introduce cp100_get_hwirq/cp100_isolate_pending_irq and plic_handle_irq_cp100 to temporarily mask all but the first pending interrupt before reading the claim register, then restore previous enables
  • Select the chained handler function dynamically at probe time based on the quirk bit and use for_each_present_cpu in resume
  • Simplify M-mode context init by zeroing entire enable register banks instead of per-IRQ toggling and adjust DT binding to require both dp1000-plic and cp100-plic compatibles
drivers/irqchip/irq-sifive-plic.c
Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
Extend the netdev LED trigger to support more link speeds, PHY offload, and dynamic visibility, and export it as a module alias.
  • Track supported link modes via an ethtool link settings snapshot and expose per-speed link_* attributes (10/100/1000/2500/5000/10000) with visibility gated by PHY capabilities
  • Teach set_baseline_state and trigger work logic to handle the new high-speed link bits when deciding whether to blink
  • Refresh supported link speed visibility on device_name changes and NETDEV_CHANGE events using a dedicated attribute group
  • Integrate with hardware-controlled LEDs by caching hw_control, avoiding redundant baseline state programming, and using hw_control_get in netdev_trig_activate
  • Register two attribute groups (generic trigger attributes and link-speed attributes) and add MODULE_ALIAS("ledtrig:netdev")
drivers/leds/trigger/ledtrig-netdev.c
include/linux/leds.h
Documentation/ABI/testing/sysfs-class-led-trigger-netdev
Add PHY-level LED hardware control for Realtek RTL8211F using netdev trigger rules.
  • Define RTL8211F LED control register layout, LED count, and bitfields for link/active modes
  • Implement rtl8211f_led_hw_is_supported to validate requested trigger rules (subset of link speeds plus optional RX/TX, RX/TX must match, up to three LEDs)
  • Implement rtl8211f_led_hw_control_get to read back current LED configuration and translate register bits into TRIGGER_NETDEV_* rules
  • Implement rtl8211f_led_hw_control_set to program the LED control register (mode B) based on requested rules and hook these callbacks into the RTL8211F phy_driver
drivers/net/phy/realtek.c
Improve LED trigger/core behavior around default triggers, panic trigger takeover, and brightness setting error handling.
  • Make trigger_list local-static in led-triggers.c and stop exporting it in leds.h
  • Allow writing "default" to the trigger sysfs file to re-apply the LED's default_trigger and show it in the trigger list formatting
  • Refactor default-trigger selection into led_match_default_trigger, add support for "none" defaults (clearing triggers), and auto-request trigger modules if the named default is not yet registered
  • During trigger registration, reuse led_match_default_trigger for newly created triggers to attach them to LEDs that want them
  • Simplify ledtrig-panic by using the already-found global panic trigger pointer instead of scanning trigger_list, and ensure it disables delayed blinking immediately
  • In led-core, treat ENOTSUPP from both async and blocking brightness callbacks as "no fixed brightness support" (no error), only log errors after filtering ENODEV for unplugged pluggable devices
  • In led-class, if hw_control_trigger is set and no default_trigger is specified, automatically use the hw_control trigger as default before calling led_trigger_set_default
drivers/leds/led-triggers.c
drivers/leds/trigger/ledtrig-panic.c
drivers/leds/led-core.c
drivers/leds/led-class.c
drivers/leds/leds.h
Documentation/ABI/testing/sysfs-class-led
Introduce an UltraRISC DP1000 core PVT hwmon driver with DT binding and hook it into the build.
  • Add CONFIG_SENSORS_COREPVT_ULTRARISC Kconfig entry and hook corepvt-ultrarisc.o into drivers/hwmon/Makefile
  • Implement corepvt-ultrarisc platform hwmon driver that maps the PVT controller, configures PSCR/CFDR/CIR per channel based on clock-frequency, channels, and per-channel TRIM, and exposes temperature and voltage inputs via hwmon
  • Use masks to map continuous temp/voltage channel blocks, implement label reporting per channel from DT child nodes, and protect register accesses with a raw spinlock
  • Add DeviceTree binding ultrarisc,dp1000-pvt.yaml documenting top-level properties, per-channel child nodes, and an example DP1000 PVT node
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/corepvt-ultrarisc.c
Documentation/devicetree/bindings/hwmon/ultrarisc,dp1000-pvt.yaml
Update UltraRISC DP1000 platform integration (PCIe, pinctrl, DTS, defconfig) for new naming, PLIC, PVT, and Titan board support.
  • Extend ultrarisc PCIe controller of_match table to match both ultrarisc,dp1000-pcie and ultrarisc,dw-pcie
  • Fix the DP1000 pinctrl binding header file name and switch the board dtb name from dp1000-mo-v1 to dp1000-m0-v1 in the Ultrarisc DTS Makefile
  • Adjust various Ultrarisc DP1000 DTS files (EVB, M0, Titan, common dtsi) to use the new pinctrl and PVT bindings and to expose Titan-specific features like PHY LED control (details in DTS diff)
  • Update deepin_riscv64_desktop_defconfig to enable the new core PVT and LED/PHY features as needed
drivers/pci/controller/dwc/pcie-ultrarisc.c
Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
arch/riscv/boot/dts/ultrarisc/Makefile
arch/riscv/boot/dts/ultrarisc/dp1000-*.dtsi
arch/riscv/configs/deepin_riscv64_desktop_defconfig

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot
Copy link

Hi @WangJia-UR. Thanks for your PR.

I'm waiting for a deepin-community member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • In corepvt_probe_channel_from_dt(), you only consider children whose node name equals "channel", but the binding and example use channel@… nodes; this means no channels will be discovered in practice—consider matching via of_node_name_prefix(child, "channel") or using the unit address–style naming expected by the schema.
  • The corepvt hwmon visibility logic currently only checks channel < pvt->channels and ignores temp_chl_mask/vol_chl_mask, so sysfs may expose channels for which no backing PVT channel or label exists; it would be more robust to derive visibility from the respective masks instead of just channels.
  • In corepvt_probe(), error paths for devm_platform_ioremap_resource() and devm_hwmon_device_register_with_info() hardcode -EINVAL and manually call devm_kfree(), which both loses the original error and defeats devm—return PTR_ERR(...) directly and drop the explicit kfree.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `corepvt_probe_channel_from_dt()`, you only consider children whose node name equals "channel", but the binding and example use `channel@…` nodes; this means no channels will be discovered in practice—consider matching via `of_node_name_prefix(child, "channel")` or using the unit address–style naming expected by the schema.
- The corepvt hwmon visibility logic currently only checks `channel < pvt->channels` and ignores `temp_chl_mask`/`vol_chl_mask`, so sysfs may expose channels for which no backing PVT channel or label exists; it would be more robust to derive visibility from the respective masks instead of just `channels`.
- In `corepvt_probe()`, error paths for `devm_platform_ioremap_resource()` and `devm_hwmon_device_register_with_info()` hardcode `-EINVAL` and manually call `devm_kfree()`, which both loses the original error and defeats devm—return `PTR_ERR(...)` directly and drop the explicit kfree.

## Individual Comments

### Comment 1
<location> `drivers/irqchip/irq-sifive-plic.c:636` </location>
<code_context>
-				void __iomem *enable_base = priv->regs +
-					CONTEXT_ENABLE_BASE +
-					i * CONTEXT_ENABLE_SIZE;
+				u32 __iomem *enable_base = priv->regs +	CONTEXT_ENABLE_BASE +
+							   i * CONTEXT_ENABLE_SIZE;

</code_context>

<issue_to_address>
**issue (bug_risk):** Off-by-one when clearing context enable words during probe

The loop `for (int j = 0; j <= nr_irqs / 32; j++)` iterates `nr_irqs / 32 + 1` times. When `nr_irqs` is a multiple of 32, this writes one word past the last valid enable register and may access undefined MMIO. Please bound by the actual number of 32-bit groups, e.g. `j < DIV_ROUND_UP(nr_irqs, 32)` or similar.
</issue_to_address>

### Comment 2
<location> `drivers/net/phy/realtek.c:546-555` </location>
<code_context>
+static int rtl8211f_led_hw_control_set(struct phy_device *phydev, u8 index,
+				       unsigned long rules)
+{
+	const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index);
+	u16 reg = 0;
+
+	if (index >= RTL8211F_LED_COUNT)
+		return -EINVAL;
+
+	if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
+		reg |= RTL8211F_LEDCR_LINK_10;
+
+	if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
+		reg |= RTL8211F_LEDCR_LINK_100;
+
+	if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
+		reg |= RTL8211F_LEDCR_LINK_1000;
+
+	if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
+	    test_bit(TRIGGER_NETDEV_TX, &rules)) {
+		reg |= RTL8211F_LEDCR_ACT_TXRX;
+	}
+
+	reg <<= RTL8211F_LEDCR_SHIFT * index;
+	reg |= RTL8211F_LEDCR_MODE;	 /* Mode B */
+
+	return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg);
</code_context>

<issue_to_address>
**issue (bug_risk):** RTL8211F LED mode bit handling appears misaligned for index > 0

`RTL8211F_LEDCR_MODE` (`BIT(15)`) looks like a global LED mode bit, but here it’s combined into `reg` and then shifted by `RTL8211F_LEDCR_SHIFT * index`. For `index > 0`, this moves the mode bit off bit 15, and the `mask` passed to `phy_modify_paged()` doesn’t cover it, so the mode will not be programmed as expected. You likely want to keep the mode bit unshifted and include it in the mask (if always forcing Mode B), or program it once independently of the per‑LED fields.
</issue_to_address>

### Comment 3
<location> `drivers/hwmon/corepvt-ultrarisc.c:282-284` </location>
<code_context>
+	if (!pvt)
+		return -ENOMEM;
+
+	pvt->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(pvt->regs)) {
+		dev_err(&pdev->dev, "get ioremap resource failed\n");
+		ret = -EINVAL;
+		goto free_pvt;
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Error propagation from devm_platform_ioremap_resource and hwmon registration should preserve the original error code

You’re replacing the specific errno from `devm_platform_ioremap_resource()` / `devm_hwmon_device_register_with_info()` with `-EINVAL`, which obscures the real failure (e.g. `-ENOMEM`, `-EIO`) for callers and debugging. Instead, return `PTR_ERR(pvt->regs)` / `PTR_ERR(pvt->hwmon)` directly. Also, the `devm_kfree()` in the error path is unnecessary because `devm_kzalloc()` allocations are released automatically.

Suggested implementation:

```c
	pvt = devm_kzalloc(&pdev->dev, sizeof(*pvt), GFP_KERNEL);
	if (!pvt)
		return -ENOMEM;

	pvt->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(pvt->regs)) {
		ret = PTR_ERR(pvt->regs);
		dev_err(&pdev->dev, "get ioremap resource failed: %d\n", ret);
		return ret;
	}

	if (device_property_present(&pdev->dev, "interrupts"))
		pvt->irq = platform_get_irq(pdev, 0);

	ret = device_property_read_u32(&pdev->dev, "clock-frequency", &pvt->clk_freq);
	if (ret) {
		dev_err(&pdev->dev, "get clock-frequency failed: %d\n", ret);
		return ret;
	}

```

1. Remove the `free_pvt:` label and any associated `devm_kfree(pvt);` (or similar manual cleanup of `pvt`) in `corepvt_probe()`, as `pvt` is allocated with `devm_kzalloc()` and will be freed automatically.
2. If there is a similar error path for `devm_hwmon_device_register_with_info()` that currently overwrites its error code with a fixed errno (e.g. `-EINVAL`) or uses `goto free_pvt`, update it to:
   * capture the return value in `ret`,
   * log it (optionally including the errno), and
   * `return ret;` directly instead of using the `free_pvt` path.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

WangJia-UR and others added 10 commits January 9, 2026 15:10
This reverts commit efe39fe.

Implement using the upstream mainline.
…pu()

mainline inclusion
from mainline-v6.18-rc1
commit b92ff23
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Replace the open coded for_each_cpu(cpu, cpu_present_mask) loop with the
more readable and equivalent for_each_present_cpu(cpu) macro.

Signed-off-by: Fushuai Wang <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/all/[email protected]
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.19-rc1
commit 14ff9e54dd14339776afff78e2d29e0edb3a4402
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Optimize the PLIC driver by maintaining the interrupt enable state in the
handler's enable_save array during normal operation rather than only during
suspend/resume. This eliminates the need to read enable registers during
suspend and makes the enable state immediately available for other
purposes.

Let __plic_toggle() update both the hardware registers and the cached
enable_save state atomically within the existing enable_lock protection.

That allows to remove the suspend-time enable register reading since
handler::enable_save now always reflects the current state.

[ tglx: Massaged change log ]

Signed-off-by: Charles Mirabile <[email protected]>
Signed-off-by: Lucas Zampieri <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.19-rc1
commit 539d147ef69c3e2f9817de0fcf1dc8ba12938909
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Add a new compatible for the plic found in UltraRISC DP1000 with a quirk to
work around a known hardware bug with IRQ claiming in the UR-CP100 cores.

When claiming an interrupt on UR-CP100 cores, all other interrupts must be
disabled before the claim register is accessed to prevent incorrect
handling of the interrupt. This is a hardware bug in the CP100 core
implementation, not specific to the DP1000 SoC.

When the PLIC_QUIRK_CP100_CLAIM_REGISTER_ERRATUM flag is present, a
specialized handler (plic_handle_irq_cp100) disables all interrupts except
for the first pending one before reading the claim register, and then
restores the interrupts before further processing of the claimed interrupt
continues.

This implementation leverages the enable_save optimization, which maintains
the current interrupt enable state in memory, avoiding additional register
reads during the workaround.

The driver matches on "ultrarisc,cp100-plic" to apply the quirk to all
SoCs using UR-CP100 cores, regardless of the specific SoC implementation.
This has no impact on other platforms.

[ tglx: Condensed the code a bit, massaged change log and comments ]

Co-developed-by: Zhang Xincheng <[email protected]>
Signed-off-by: Zhang Xincheng <[email protected]>
Signed-off-by: Charles Mirabile <[email protected]>
Signed-off-by: Lucas Zampieri <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Samuel Holland <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.19-rc1
commit 9dfb295a93eb109be989aac48f675db5b1c68bd8
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Add compatible strings for the PLIC found in UltraRISC DP1000 SoC.

The PLIC is part of the UR-CP100 core and has a hardware bug requiring
a workaround.

Signed-off-by: Charles Mirabile <[email protected]>
Signed-off-by: Lucas Zampieri <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Conor Dooley <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.19-rc1
commit a045359e72455c4fd178fbedbf398f8df7da97e7
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

The code path for M-Mode linux that disables interrupts for other contexts
was missed when refactoring __plic_toggle().

Since the new version caches updates to the state for the primary context,
its use in this codepath is no longer desireable even if it could be made
correct.

Replace the calls to __plic_toggle() with a loop that simply disables all
of the interrupts in groups of 32 with a direct mmio write.

Fixes: 14ff9e54dd14 ("irqchip/sifive-plic: Cache the interrupt enable state")
Reported-by: kernel test robot <[email protected]>
Signed-off-by: Charles Mirabile <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://patch.msgid.link/[email protected]
Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
Signed-off-by: Jia Wang <[email protected]>
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

1. Remove aer interrupt from PCIe nodes:
   The PCIe nodes in DP1000 series devices do not support Advanced Error
   Reporting (AER) interrupt. Remove the aer interrupt from interrupts and
   interrupt-names properties in all affected device tree files.

2. Add cache information:
   Add detailed L1 I-cache and D-cache configuration (64B block size, 4-way set
   associative, 64KB size per core) and L3 cache configuration to CPU nodes.

3. Extend ISA information:
   Add comprehensive ISA base and extension list to CPU nodes, including
   standard extensions and custom extensions.

4. Update key-wakeup for titan board:
   - Rename existing key-wakeup to key-wakeup@0
   - Add key-wakeup@1 (Power key) on porta 11
   - Add key-wakeup@2 (USB wakeup) on porta 4

5. Add ethernet MDIO and PHY configuration:
   Configure MDIO bus and PHY0 for ethernet interface on titan board.

Signed-off-by: Jia Wang <[email protected]>
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Add support for UltraRISC Core PVT (Voltage, Temperature) sensor
embedded into dp1000 series SoCs.

The driver provides:
1. Support for 11 temperature channels (cores and SoC components)
2. Support for 2 voltage channels (cluster voltages)
3. Hardware monitoring via hwmon interface
4. Device tree based configuration

Add necessary Kconfig and Makefile entries, and update device tree with
PVT sensor nodes and channel configurations.

Signed-off-by: Jia Wang <[email protected]>
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Add device tree binding documentation for UltraRISC DP1000
Core voltage and temperature (PVT) sensor.

Signed-off-by: Jia Wang <[email protected]>
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Add support for UltraRISC Core PVT sensor driver by enabling
CONFIG_SENSORS_COREPVT_ULTRARISC=m.
Enable CONFIG_KEYBOARD_GPIO=m.

Signed-off-by: Jia Wang <[email protected]>
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: opsiff

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds support for UltraRISC DP1000 platform features including core PVT monitoring, PHY LED control on MilkV Titan, and PLIC interrupt controller errata handling. It backports several upstream features and updates device tree configurations.

  • Adds UltraRISC DP1000 core PVT hwmon driver for temperature and voltage monitoring
  • Enables hardware-controlled PHY LEDs on Realtek RTL8211F with netdev trigger support
  • Implements CP100 PLIC claim register erratum workaround
  • Extends netdev LED triggers to support higher link speeds (2.5G, 5G, 10G)

Reviewed changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
drivers/hwmon/corepvt-ultrarisc.c New hwmon driver for DP1000 PVT sensor monitoring
drivers/net/phy/realtek.c Adds LED hardware control support for RTL8211F PHY
drivers/irqchip/irq-sifive-plic.c Implements CP100 claim register erratum workaround
drivers/leds/trigger/ledtrig-netdev.c Adds 2.5G/5G/10G link speed support and visibility control
drivers/leds/led-*.c Enhances LED trigger core with default trigger support
drivers/pci/controller/dwc/pcie-ultrarisc.c Adds DP1000-specific PCIe compatible string
arch/riscv/boot/dts/ultrarisc/* Updates device trees with cache info, PVT nodes, and board configs
include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h Adds pinctrl definitions for DP1000
Documentation/* Updates binding docs for PLIC, hwmon, and LED ABI

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

u32 dout;
u32 chl_offset = 0;

// Assume that the voltage channel is continuous
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use C-style comments (/* */) instead of C++-style comments (//) for consistency with Linux kernel coding style.

Suggested change
// Assume that the voltage channel is continuous
/* Assume that the voltage channel is continuous */

Copilot uses AI. Check for mistakes.
pvt->dev = &pdev->dev;
raw_spin_lock_init(&pvt->lock);

// Config and enable corepvt
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use C-style comments (/* */) instead of C++-style comments (//) for consistency with Linux kernel coding style.

Suggested change
// Config and enable corepvt
/* Config and enable corepvt */

Copilot uses AI. Check for mistakes.
Comment on lines +71 to +72
- const: ultrarisc,dp1000-plic
- const: ultrarisc,cp100-plic
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compatible string ordering in the PLIC binding documentation is incorrect. According to the binding pattern, the compatible should list the most specific first, then the fallback. The code shows "ultrarisc,cp100-plic", "ultrarisc,dp1000-plic" but the binding documentation shows them in reverse order. This mismatch needs to be corrected.

Suggested change
- const: ultrarisc,dp1000-plic
- const: ultrarisc,cp100-plic
- const: ultrarisc,cp100-plic
- const: ultrarisc,dp1000-plic

Copilot uses AI. Check for mistakes.
Comment on lines +286 to +327
goto free_pvt;
}

if (device_property_present(&pdev->dev, "interrupts"))
pvt->irq = platform_get_irq(pdev, 0);

ret = device_property_read_u32(&pdev->dev, "clock-frequency", &pvt->clk_freq);
if (ret) {
dev_err(&pdev->dev, "get clock-frequency failed\n");
goto free_pvt;
}

ret = device_property_read_u32(&pdev->dev, "channels", &pvt->channels);
if (ret) {
dev_err(&pdev->dev, "get channels failed\n");
goto free_pvt;
}

pvt_data = device_get_match_data(&pdev->dev);
if (!pvt_data) {
dev_err(&pdev->dev, "No chip info found\n");
ret = -ENODATA;
goto free_pvt;
}

pvt->dev = &pdev->dev;
pvt->chip_info = pvt_data->chip_info;
pvt->pvt_data = pvt_data;

if (pdev->dev.of_node) {
ret = corepvt_probe_channel_from_dt(pdev, pvt);
if (ret)
dev_warn(&pdev->dev, "WARN: probe channel failed\n");
}

pvt->hwmon = devm_hwmon_device_register_with_info(&pdev->dev, "corepvt_ultrarisc",
pvt, pvt->chip_info,
NULL);
if (IS_ERR(pvt->hwmon)) {
dev_err(&pdev->dev, "register hwmon failed(%ld)\n", PTR_ERR(pvt->hwmon));
ret = -EINVAL;
goto free_pvt;
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All error paths using 'goto free_pvt' should be changed to 'return ret' directly since the devm_kfree is unnecessary. This affects lines 286, 295, 301, 308, and 327.

Copilot uses AI. Check for mistakes.
u32 dout;
u32 chl_offset = 0;

// Assume that the temperature channel is continuous
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use C-style comments (/* */) instead of C++-style comments (//) for consistency with Linux kernel coding style.

Copilot uses AI. Check for mistakes.
return 0;

free_pvt:
devm_kfree(&pdev->dev, pvt);
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goto label 'free_pvt' is unnecessary because devm_kzalloc automatically frees the memory when the device is unbound. The explicit devm_kfree call on line 339 is redundant and should be removed along with the goto.

Suggested change
devm_kfree(&pdev->dev, pvt);

Copilot uses AI. Check for mistakes.

interrupts:
maxItems: 1
description: Optional interrupt number for the PVT controller. This property is optional and can be omitted if not used.
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interrupts property documentation states it is optional, but the 'required' section at line 57 does not list it, which is correct. However, the description on line 26 should more clearly indicate it's optional by starting with "Optional:" or similar wording for clarity.

Suggested change
description: Optional interrupt number for the PVT controller. This property is optional and can be omitted if not used.
description: Optional: interrupt number for the PVT controller. This property can be omitted if not used.

Copilot uses AI. Check for mistakes.
Comment on lines 163 to 483
* 8-way set associative, size 512KB
* per-core.
*/
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <0x80000>;
cache-sets = <1024>;
cache-unified;
next-level-cache = <&cluster0_l3>;
};
};
cpu3: cpu@3 {
device_type = "cpu";
reg = <0x3>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcbh";
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i","m","a","f","d","c","h","zba",
"zbb","zbc","zbs","zicntr","zicsr",
"zifencei","zihpm","ziccif","ziccrse",
"ziccamoa","za64rs","zic64b","zicbom",
"zicbop","zicboz","zkt","zama16b",
"svade","ssccptr","sstvecd","sscounterenw",
"shcounterenw","shtvala","shvstvecd",
"shvsatpa","ssstrict","svvptc";
mmu-type = "riscv,sv48";
clock-frequency = <2000000000>;
/* L1 I-cache and D-cache:
* block-size 64B
* 4-way set associative, size 64KB
* per-core.
*/
d-cache-block-size = <64>;
d-cache-sets = <256>;
d-cache-size = <0x10000>;
i-cache-block-size = <64>;
i-cache-sets = <256>;
i-cache-size = <0x10000>;
next-level-cache = <&l2_cache3>;
riscv,cbom-block-size = <64>;
riscv,cboz-block-size = <64>;
cpu3_intc:interrupt-controller {
#address-cells = <0x01>;
interrupt-controller;
compatible = "riscv,cpu-intc";
#interrupt-cells = <0x01>;
};
l2_cache3: l2-cache3 {
/* L2 cache:
* cache-unified, block-size 64B
* 8-way set associative, size 512KB
* per-core.
*/
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <0x80000>;
cache-sets = <1024>;
cache-unified;
next-level-cache = <&cluster0_l3>;
};
};
cpu4: cpu@4 {
device_type = "cpu";
reg = <0x10>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcbh";
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i","m","a","f","d","c","h","zba",
"zbb","zbc","zbs","zicntr","zicsr",
"zifencei","zihpm","ziccif","ziccrse",
"ziccamoa","za64rs","zic64b","zicbom",
"zicbop","zicboz","zkt","zama16b",
"svade","ssccptr","sstvecd","sscounterenw",
"shcounterenw","shtvala","shvstvecd",
"shvsatpa","ssstrict","svvptc";
mmu-type = "riscv,sv48";
clock-frequency = <2000000000>;
/* L1 I-cache and D-cache:
* block-size 64B
* 4-way set associative, size 64KB
* per-core.
*/
d-cache-block-size = <64>;
d-cache-sets = <256>;
d-cache-size = <0x10000>;
i-cache-block-size = <64>;
i-cache-sets = <256>;
i-cache-size = <0x10000>;
next-level-cache = <&l2_cache4>;
riscv,cbom-block-size = <64>;
riscv,cboz-block-size = <64>;
cpu4_intc:interrupt-controller {
#address-cells = <0x01>;
interrupt-controller;
compatible = "riscv,cpu-intc";
#interrupt-cells = <0x01>;
};
l2_cache4: l2-cache4 {
/* L2 cache:
* cache-unified, block-size 64B
* 8-way set associative, size 512KB
* per-core.
*/
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <0x80000>;
cache-sets = <1024>;
cache-unified;
next-level-cache = <&cluster1_l3>;
};
};
cpu5: cpu@5 {
device_type = "cpu";
reg = <0x11>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcbh";
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i","m","a","f","d","c","h","zba",
"zbb","zbc","zbs","zicntr","zicsr",
"zifencei","zihpm","ziccif","ziccrse",
"ziccamoa","za64rs","zic64b","zicbom",
"zicbop","zicboz","zkt","zama16b",
"svade","ssccptr","sstvecd","sscounterenw",
"shcounterenw","shtvala","shvstvecd",
"shvsatpa","ssstrict","svvptc";
mmu-type = "riscv,sv48";
clock-frequency = <2000000000>;
/* L1 I-cache and D-cache:
* block-size 64B
* 4-way set associative, size 64KB
* per-core.
*/
d-cache-block-size = <64>;
d-cache-sets = <256>;
d-cache-size = <0x10000>;
i-cache-block-size = <64>;
i-cache-sets = <256>;
i-cache-size = <0x10000>;
next-level-cache = <&l2_cache5>;
riscv,cbom-block-size = <64>;
riscv,cboz-block-size = <64>;
cpu5_intc:interrupt-controller {
#address-cells = <0x01>;
interrupt-controller;
compatible = "riscv,cpu-intc";
#interrupt-cells = <0x01>;
};
l2_cache5: l2-cache5 {
/* L2 cache:
* cache-unified, block-size 64B
* 8-way set associative, size 512KB
* per-core.
*/
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <0x80000>;
cache-sets = <1024>;
cache-unified;
next-level-cache = <&cluster1_l3>;
};
};
cpu6: cpu@6 {
device_type = "cpu";
reg = <0x12>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcbh";
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i","m","a","f","d","c","h","zba",
"zbb","zbc","zbs","zicntr","zicsr",
"zifencei","zihpm","ziccif","ziccrse",
"ziccamoa","za64rs","zic64b","zicbom",
"zicbop","zicboz","zkt","zama16b",
"svade","ssccptr","sstvecd","sscounterenw",
"shcounterenw","shtvala","shvstvecd",
"shvsatpa","ssstrict","svvptc";
mmu-type = "riscv,sv48";

clock-frequency = <2000000000>;

/* L1 I-cache and D-cache:
* block-size 64B
* 4-way set associative, size 64KB
* per-core.
*/
d-cache-block-size = <64>;
d-cache-sets = <256>;
d-cache-size = <0x10000>;
i-cache-block-size = <64>;
i-cache-sets = <256>;
i-cache-size = <0x10000>;
next-level-cache = <&l2_cache6>;
riscv,cbom-block-size = <64>;
riscv,cboz-block-size = <64>;
cpu6_intc:interrupt-controller {
#address-cells = <0x01>;
interrupt-controller;
compatible = "riscv,cpu-intc";
#interrupt-cells = <0x01>;
};
l2_cache6: l2-cache6 {
/* L2 cache:
* cache-unified, block-size 64B
* 8-way set associative, size 512KB
* per-core.
*/
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <0x80000>;
cache-sets = <1024>;
cache-unified;
next-level-cache = <&cluster1_l3>;
};
};
cpu7: cpu@7 {
device_type = "cpu";
reg = <0x13>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcbh";
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i","m","a","f","d","c","h","zba",
"zbb","zbc","zbs","zicntr","zicsr",
"zifencei","zihpm","ziccif","ziccrse",
"ziccamoa","za64rs","zic64b","zicbom",
"zicbop","zicboz","zkt","zama16b",
"svade","ssccptr","sstvecd","sscounterenw",
"shcounterenw","shtvala","shvstvecd",
"shvsatpa","ssstrict","svvptc";
mmu-type = "riscv,sv48";
clock-frequency = <2000000000>;
/* L1 I-cache and D-cache:
* block-size 64B
* 4-way set associative, size 64KB
* per-core.
*/
d-cache-block-size = <64>;
d-cache-sets = <256>;
d-cache-size = <0x10000>;
i-cache-block-size = <64>;
i-cache-sets = <256>;
i-cache-size = <0x10000>;
next-level-cache = <&l2_cache7>;
riscv,cbom-block-size = <64>;
riscv,cboz-block-size = <64>;
cpu7_intc:interrupt-controller {
#address-cells = <0x01>;
interrupt-controller;
compatible = "riscv,cpu-intc";
#interrupt-cells = <0x01>;
};
l2_cache7: l2-cache7 {
/* L2 cache:
* cache-unified, block-size 64B
* 8-way set associative, size 512KB
* per-core.
*/
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <0x80000>;
cache-sets = <1024>;
cache-unified;
next-level-cache = <&cluster1_l3>;
};
};

cpu-map {
cluster0: cluster0 {
core0 {
cpu = <&cpu0>;
};
core1 {
cpu = <&cpu1>;
};
core2 {
cpu = <&cpu2>;
};
core3 {
cpu = <&cpu3>;
};

cluster0_l3: l3-cache0 {
/* L3 cache:
* cache-unified, block-size 64B
* 16-way set associative, size 4MB
* per-cluster.
*/
compatible = "cache";
cache-block-size = <64>;
cache-level = <3>;
cache-size = <0x400000>;
cache-sets = <0x1000>;
cache-unified;
next-level-cache = <&l4_cache>;
};
};
cluster1: cluster1 {
core0 {
cpu = <&cpu4>;
};
core1 {
cpu = <&cpu5>;
};
core2 {
cpu = <&cpu6>;
};
core3 {
cpu = <&cpu7>;
};
cluster1_l3: l3-cache1 {
/* L3 cache:
* cache-unified, block-size 64B
* 16-way set associative, size 4MB
* per-cluster.
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Chinese full-width comma (,) in multiple cache description comments. These should be changed to use standard ASCII punctuation for consistency. This issue appears in multiple L2 and L3 cache descriptions throughout the file.

Copilot uses AI. Check for mistakes.
return -EOPNOTSUPP;

/* RX and TX are not differentiated, either both are set or not set. */
if (!(rules & BIT(TRIGGER_NETDEV_RX)) ^ !(rules & BIT(TRIGGER_NETDEV_TX)))
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XOR logic check is incorrect. The condition checks if "RX is not set XOR TX is not set", which means it returns an error when both are set or both are unset. This is the opposite of the intended behavior described in the comment. The condition should be: if ((rules & BIT(TRIGGER_NETDEV_RX)) ^ (rules & BIT(TRIGGER_NETDEV_TX))) to ensure both are either set together or unset together.

Suggested change
if (!(rules & BIT(TRIGGER_NETDEV_RX)) ^ !(rules & BIT(TRIGGER_NETDEV_TX)))
if ((rules & BIT(TRIGGER_NETDEV_RX)) ^ (rules & BIT(TRIGGER_NETDEV_TX)))

Copilot uses AI. Check for mistakes.
l2_cache0: l2-cache0 {
/* L2 cache:
* cache-unified, block-size 64B
* 8-way set associative,size 512KB
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Chinese full-width comma (,) in comments instead of ASCII comma (,). This should be changed to use standard ASCII punctuation for consistency with the rest of the codebase.

Suggested change
* 8-way set associativesize 512KB
* 8-way set associative, size 512KB

Copilot uses AI. Check for mistakes.
WangJia-UR and others added 5 commits January 9, 2026 16:03
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Fix naming inconsistencies in dp1000 device tree files:
1. Correct filename typo: dp1000-mo-* -> dp1000-m0-*(replace letter 'o'
with digit '0')
2. Rename pinctrl header to use company prefix: ur-dp1000-pinctrl.h ->
ultrarisc,dp1000-pinctrl.h
3. Update all include paths to match the new filename

Signed-off-by: Jia Wang <[email protected]>
…trarisc,dp1000-pinctrl.h

community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Rename pinctrl header to use company prefix: ur-dp1000-pinctrl.h ->
ultrarisc,dp1000-pinctrl.h

Signed-off-by: Jia Wang <[email protected]>
Enable CONFIG_DRM_AMD_ACP and CONFIG_DRM_AMD_SECURE_DISPLAY for AMD GPU.

Enable CONFIG_RTC_DRV_DS1307_CENTURY and CONFIG_RTC_DRV_SD3078.

Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.9-rc1
commit e09c706
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Even if a trigger is set as default trigger for a LED device,
the respective trigger module (if built as module) isn't automatically
loaded by the kernel if the LED device is registered. I think we can
do better. Try to load the module asynchronously by alias
ledtrig:<trigger name>. This requires that such an alias is added to
relevant triggers.

Signed-off-by: Heiner Kallweit <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
…controlled

mainline inclusion
from mainline-v6.9-rc1
commit f574751
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

The current codes uses the sw_control path in set_baseline_state() when
called from netdev_trig_activate() even if we're hw-controlled. This
may result in errors when led_set_brightness() is called because we may
not have set_brightness led ops (if hw doesn't support setting a "LED"
to ON). In addition this path may schedule trigger_data->work which
doesn't make sense when being hw-controlled.

Therefore set trigger_data->hw_control = true before calling
set_device_name() from netdev_trig_activate(). In this call chain we
have to prevent set_baseline_state() from being called, because this
would call hw_control_set(). Use led_cdev->trigger_data == NULL as
indicator for being called from netdev_trig_activate().

Signed-off-by: Heiner Kallweit <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
hkallweit and others added 20 commits January 9, 2026 16:03
mainline inclusion
from mainline-v6.9-rc1
commit fd14a87
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Add module alias ledtrig:netdev to enable auto-loading of the module.

Signed-off-by: Heiner Kallweit <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
…the default trigger

mainline inclusion
from mainline-v6.9-rc1
commit 66601a2
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

If a hw_control_trigger is defined, it's usually desirable to make it
the default trigger. Therefore make it the default trigger, except
the driver explicitly set a default trigger.

Signed-off-by: Heiner Kallweit <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.8-rc1
commit 59b3e31
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Add 2.5G, 5G and 10G as available speeds to the netdev LED trigger.

Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Link: https://lore.kernel.org/r/99e7d3304c6bba7f4863a4a80764a869855f2085.1701143925.git.daniel@makrotopia.org
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.8-rc1
commit ee8bfb4
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Document newly introduced modes for the LED netdev trigger.

Add documentation for new modes:
- link_2500
- link_5000
- link_10000

Signed-off-by: Daniel Golle <[email protected]>
Link: https://lore.kernel.org/r/e72a6794639cf3881d698e1d34b456e747da1b95.1701143925.git.daniel@makrotopia.org
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.9-rc1
commit 06cdca0
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

With the addition of more link speed mode to the netdev trigger, it was
pointed out that there may be a problem with bloating the attribute list
with modes that won't ever be supported by the trigger as the attached
device name doesn't support them.

To clear and address this problem, change the logic where these
additional trigger modes are listed.

Since the netdev trigger REQUIRE a device name to be set, attach to the
device name change function additional logic to parse the supported link
speed modes using ethtool APIs and show only the supported link speed
modes attribute.

Link speed attribute are refreshed on device_name set and on
NETDEV_CHANGE events.

This only apply to the link speed modes and every other mode is still
provided by default.

Signed-off-by: Christian Marangi <[email protected]>
Reviewed-by: Marek Behún <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.9-rc1
commit 5fe5e2a
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Document now hidable link speed modes for the LED netdev trigger.

Link speed modes are now showed only if the named network device
supports them and are hidden if not.

Signed-off-by: Christian Marangi <[email protected]>
Reviewed-by: Marek Behún <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.14-rc1
commit 0dfda50
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

The trigger_data->hw_control indicates whether the LED is controlled by HW
offload, i.e. the PHY. The trigger_data->hw_control = can_hw_control() is
currently called only from netdev_led_attr_store(), i.e. when writing any
sysfs attribute of the netdev trigger instance associated with a PHY LED.

The can_hw_control() calls validate_net_dev() which internally calls
led_cdev->hw_control_get_device(), which is phy_led_hw_control_get_device()
for PHY LEDs. The phy_led_hw_control_get_device() returns NULL if the PHY
is not attached.

At least in case of DWMAC (STM32MP, iMX8M, ...), the PHY device is attached
only when the interface is brought up and is detached again when the
interface is brought down. In case e.g. udev rules configure the netdev
LED trigger sysfs attributes before the interface is brought up, then when
the interface is brought up, the LEDs are not blinking.

This is because trigger_data->hw_control = can_hw_control() was called
when udev wrote the sysfs attribute files, before the interface was up,
so can_hw_control() resp. validate_net_dev() returned false, and the
trigger_data->hw_control = can_hw_control() was never called again to
update the trigger_data->hw_control content and let the offload take
over the LED blinking.

Call data->hw_control = can_hw_control() from netdev_trig_notify() to
update the offload capability of the LED when the UP notification arrives.
This makes the LEDs blink after the interface is brought up.

On STM32MP13xx with RTL8211F, it is enough to have the following udev rule
in place, boot the machine with cable plugged in, and the LEDs won't work
without this patch once the interface is brought up, even if they should:
"
ACTION=="add", SUBSYSTEM=="leds", KERNEL=="stmmac-0:01:green:wan", ATTR{trigger}="netdev", ATTR{link_10}="1", ATTR{link_100}="1", ATTR{link_1000}="1", ATTR{device_name}="end0"
ACTION=="add", SUBSYSTEM=="leds", KERNEL=="stmmac-0:01:yellow:wan", ATTR{trigger}="netdev", ATTR{rx}="1", ATTR{tx}="1", ATTR{device_name}="end0"
"

Signed-off-by: Marek Vasut <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.16-rc1
commit 06d99fc
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Accept "default" written to sysfs trigger attr.
If the text "default" is written to the LED's sysfs 'trigger' attr, then
call led_trigger_set_default() to set the LED to its default trigger.

If the default trigger is set to "none", then led_trigger_set_default()
will remove a trigger. This is in contrast to the default trigger being
unset, in which case led_trigger_set_default() does nothing.

Signed-off-by: Craig McQueen <[email protected]>
Reviewed-by: Jacek Anaszewski <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.9-rc1
commit 7eef64d
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

I don't see why we iterate over all triggers to find the panic trigger.
We *are* the panic trigger. Therefore we also know that the panic
trigger doesn't have an activate() hook. So we can simplify the code
significantly.

Signed-off-by: Heiner Kallweit <[email protected]>
Reviewed-by: Jacek Anaszewski <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.9-rc1
commit e838a5a
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Commit 682e98564ffb ("leds: trigger: panic: Simplify
led_trigger_set_panic") removed the last external user of variable
trigger_list. So stop exporting it. If in future a need should arise
again to access this variable, I think we better add some accessor
instead of exporting the variable directly.

Signed-off-by: Heiner Kallweit <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.9-rc1
commit 9225333
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Avoid code duplication and factor out common functionality to new
helper led_match_default_trigger().

Signed-off-by: Heiner Kallweit <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.11-rc1
commit 1778480
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Realtek RTL8211F Ethernet PHY supports 3 LED pins which are used to
indicate link status and activity. Add minimal LED controller driver
supporting the most common uses with the 'netdev' trigger.

Signed-off-by: Marek Vasut <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.11-rc5
commit a2f5c50
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

The current implementation incorrectly sets the mode bit of the PHY chip.
Bit 15 (RTL8211F_LEDCR_MODE) should not be shifted together with the
configuration nibble of a LED- it should be set independently of the
index of the LED being configured.
As a consequence, the RTL8211F LED control is actually operating in Mode A.
Fix the error by or-ing final register value to write with a const-value of
RTL8211F_LEDCR_MODE, thus setting Mode bit explicitly.

Fixes: 1778480 ("net: phy: realtek: Add support for PHY LEDs on RTL8211F")
Signed-off-by: Sava Jakovljev <[email protected]>
Reviewed-by: Marek Vasut <[email protected]>
Link: https://patch.msgid.link/PAWP192MB21287372F30C4E55B6DF6158C38E2@PAWP192MB2128.EURP192.PROD.OUTLOOK.COM
Signed-off-by: Paolo Abeni <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
… trigger only

mainline inclusion
from mainline-v6.11-rc1
commit d33d121
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

If both set_brightness functions return -ENOTSUPP, then the LED doesn't
support setting a fixed brightness value, and the error message isn't
helpful. This can be the case e.g. for LEDs supporting a specific hw
trigger only.

Pinched the subject line and commit message from Heiner:
Link: https://lore.kernel.org/all/[email protected]/

Reworked the function to provide Heiner's required semantics whilst
simultaneously increasing readability and flow.

Cc: Pavel Machek <[email protected]>
Cc: [email protected]
Suggested-by: Heiner Kallweit <[email protected]>
Reviewed-by: Heiner Kallweit <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
mainline inclusion
from mainline-v6.12-rc2
commit c283782
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Just like rtl8211f_led_hw_is_supported() and
rtl8211f_led_hw_control_set(), the rtl8211f_led_hw_control_get() also
needs to check the index value, otherwise the caller is likely to get
an incorrect rules.

Fixes: 1778480 ("net: phy: realtek: Add support for PHY LEDs on RTL8211F")
Signed-off-by: Hui Wang <[email protected]>
Reviewed-by: Marek Vasut <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Jia Wang <[email protected]>
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Add phy leds support for MilkV Titan. The mode of the two PHY LEDs can be
set through 'netdev'.

Signed-off-by: Jia Wang <[email protected]>
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Add model and compatible properties to UltraRISC DP1000 device tree files:
- dp1000-evb-v1.dts: Set model to "UltraRISC EVB v1"
- dp1000-m0-v1.dts: Set model to "Rongda M0 Board v1"

Signed-off-by: Jia Wang <[email protected]>
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Update the compatible string for UltraRISC DP1000 SoC PCIe controllers
from 'ultrarisc,dw-pcie' to 'ultrarisc,dp1000-pcie', 'ultrarisc,dw-pcie'
to better distinguish the DP1000 implementation while maintaining
backward compatibility.

This change updates both the device tree nodes and the driver's
device ID matching table to ensure proper driver binding.

Signed-off-by: Jia Wang <[email protected]>
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Update UltraRISC DP1000 pcie and gmac compatible strings:

1. Update ethernet device compatible from 'ultrarisc,dp1000-gmac' to
'snps,dwmac' to align with standard Synopsys DWMAC driver expectations

2. Add 'ultrarisc,dp1000-pcie' as primary compatible string for PCIe
controllers while retaining 'ultrarisc,dw-pcie' for backward compatibility

Signed-off-by: Jia Wang <[email protected]>
community inclusion
category: feature
bugzilla: RVCK-Project/rvck#71

--------------------------------

Remove 'bootargs' and only use 'stdout-path'.

Signed-off-by: Jia Wang <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants