Skip to content

Conversation

@wxjstz
Copy link

@wxjstz wxjstz commented Dec 31, 2025

Summary by Sourcery

Add Sophgo SG2042 Mango platform support including timer, reset, GPIO, and PMU handling improvements

New Features:

  • Introduce SG2042 global mtimer (GMT) driver and FDT-based timer initialization for Sophgo SG2042 SoCs
  • Add Sophgo-specific GPIO FDT driver and CPLD/MCU/WDT-based reset drivers for Mango platforms
  • Support per-platform forced emulation of time CSR and SG2042-specific cold-boot and TLB configurations

Bug Fixes:

  • Fix memory barrier definitions and add additional fences to improve SMP ordering and spinlock correctness on Mango platforms
  • Prevent PMU overflow interrupts from persisting after counter stop and ensure TIME CSR is not probed when emulated
  • Use unsigned comparison for hart index bounds and flush TLB in trap handler to avoid incorrect hangs or stale mappings

Enhancements:

  • Extend generic platform operations with a hook to control time CSR emulation and wire it into SG2042 and core initialization paths
  • Adjust ACLINT mtimer domain registration to support external timer domains and scale SG2042 timer MMIO region size by hart count
  • Tune T-Head C9xx PMU event mask/width and expose SG2042-specific hart stack size and cold-boot policy

Build:

  • Wire new Sophgo timer, GPIO, and reset drivers into Kconfig and objects.mk so they can be selected for generic builds

pisces system reboot will ecall gpio chip but not watchdog, and pull up cpu gpio5 to tell
CPLD. CPLD will help for cold reboot.
Add the function, gpio chip will pull up gpio16 after chip is probed.

Signed-off-by: chunzhi.lin <chunzhi.lin@sophgo.com>
This problem was found on sg2042 server platform with the litmus test.

This patch is based on Guo Ren's patch [1].

[1] c-sky/csky-linux@c539252

riscv: qspinlock: errata: Add ERRATA_THEAD_WRITE_ONCE fixup
The early version of T-Head C9xx cores has a store merge buffer
delay problem. The store merge buffer could improve the store queue
performance by merging multi-store requests, but when there are not
continued store requests, the prior single store request would be
waiting in the store queue for a long time. That would cause
significant problems for communication between multi-cores. This
problem was found on sg2042 & th1520 platforms with the qspinlock
lock torture test.

So appending a fence w.o could immediately flush the store merge
buffer and let other cores see the write result.

This will apply the WRITE_ONCE errata to handle the non-standard
behavior via appending a fence w.o instruction for WRITE_ONCE().

Signed-off-by: haijiao.liu@sophgo.com <haijiao.liu@sophgo.com>
… deletion process

Signed-off-by: haijiao.liu <haijiao.liu@sophgo.com>
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Add a virtual global timer device driver. It uses a global timer
register as timer counter, and it uses mtimecmp CSR of clint as
interrupt source.
Using this virtul timer resolves dual way timer sync issue.
On dual way system, we should enable this driver and on single way
system, we should use standard risc-v clint timer.

1. Add a virtual global timer device driver, it is probed by fdt

	sg2042-global-mtimer@70300101c0 {
		compatible = "sophgo,sg2042-global-mtimer";
		reg = < 0x00000070 0x300101c0 0x00000000 0x00000008
			0x00000070 0xac000000 0x00000000 0x00200000>;
		clock-frequency = <50000000 50000000>;
	};

Its compatible should be "sophgo,sg2042-global-mtimer".
And the first region delcared in reg prop is the address of global
timer. The second region delcared in reg prop is the base of clint
timers.
The first clock in clock-frequency is the actual frequency of global
timer, the second clock is the actual frequency of clint timer.

2. Add a quirk in platform specific code.
Add a function sbi_platform_force_emulate_time_csr, it indicates if
opensbi should skip time CSR detection and make software in
supervisor and user mode use emulated time CSR.

Signed-off-by: Chao Wei <chao.wei@sophgo.com>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
@sourcery-ai
Copy link

sourcery-ai bot commented Dec 31, 2025

Reviewer's Guide

Adds Sophgo SG2042/Mango platform support for global timer (GMT), GPIO, and multiple reset mechanisms, introduces a platform hook to force emulated time CSR, tightens memory-ordering primitives and spinlock/coldboot fences, and fixes PMU overflow handling and warm-boot hart comparison while wiring in new FDT compatibles and build options.

Sequence diagram for SG2042 GMT timer initialization from FDT

sequenceDiagram
    participant Boot as Bootloader
    participant Fw as OpenSBI_firmware
    participant FDT as FDT_blob
    participant FdtCore as fdt_timer
    participant Drv as fdt_timer_sg2042_gmt
    participant GMT as sg2042gmt_cold_timer_init
    participant TimerCore as sbi_timer

    Boot->>Fw: pass FDT pointer
    Fw->>FdtCore: fdt_timer_cold_init(FDT)
    FdtCore->>FDT: find_node(compatible = sophgo,sg2042-global-mtimer)
    FDT-->>FdtCore: nodeoff
    FdtCore->>Drv: init(FDT, nodeoff)

    Drv->>FDT: fdt_get_node_addr_size(index 0)
    FDT-->>Drv: mtimer_base, mtimer_size
    Drv->>FDT: fdt_get_node_addr_size(index 1)
    FDT-->>Drv: mtimecmp_base, mtimecmp_size

    Drv->>FDT: fdt_parse_timebase_frequency
    FDT-->>Drv: declared_freq
    Drv->>FDT: getprop(clock-frequency)
    FDT-->>Drv: actual_freq, timecmp_freq

    Drv->>GMT: sg2042gmt_cold_timer_init(mtimer_base, mtimecmp_base, mtimecmp_size, declared_freq, actual_freq, timecmp_freq)
    GMT->>TimerCore: sbi_timer_set_device(&sg2042gmt_timer)
    TimerCore-->>GMT: OK
    GMT-->>Drv: OK
    Drv-->>FdtCore: OK
    FdtCore-->>Fw: timers initialized
Loading

Updated class diagram for SG2042 timer and FDT driver structures

classDiagram
    class sg2042gmt_data {
        +unsigned long mtimer_base
        +unsigned long mtimecmp_base
        +unsigned long mtimecmp_size
        +unsigned long declared_freq
        +unsigned long actual_freq
        +unsigned long timecmp_freq
    }

    class sbi_timer_device {
        +char* name
        +unsigned long timer_freq
        +u64 (*timer_value)()
        +void (*timer_event_start)(u64 next_event)
        +void (*timer_event_stop)()
        +int (*warm_init)()
    }

    class sg2042gmt_timer_device {
        <<instance_of_sbi_timer_device>>
        +name = "sg2042gmt"
        +timer_freq
        +timer_value()
        +timer_event_start(u64 next_event)
        +timer_event_stop()
        +warm_init()
    }

    class fdt_driver {
        +const struct fdt_match* match_table
        +int (*init)(const void* fdt, int nodeoff, const struct fdt_match* match)
    }

    class fdt_driver_sg2042_gmt {
        <<instance_of_fdt_driver>>
        +match_table = timer_sg2042gmt_match
        +init = fdt_sg2042gmt_cold_timer_init
    }

    class sg2042_gmt_api {
        +int sg2042gmt_cold_timer_init(unsigned long mtimer_base, unsigned long mtimecmp_base, unsigned long mtimecmp_size, unsigned long delcared_freq, unsigned long actual_freq, unsigned long timecmp_freq)
        +int sg2042gmt_warm_timer_init()
    }

    sg2042gmt_data <.. sg2042_gmt_api : uses
    sg2042gmt_timer_device <.. sg2042_gmt_api : configured_by
    sg2042gmt_timer_device --|> sbi_timer_device

    fdt_driver_sg2042_gmt --|> fdt_driver
    fdt_driver_sg2042_gmt ..> sg2042_gmt_api : calls
Loading

Updated class diagram for Sophgo GPIO and Mango reset devices

classDiagram
    class gpio_chip {
        +const void* driver
        +int id
        +unsigned int ngpio
        +int (*direction_output)(struct gpio_pin* gp, int value)
        +void (*set)(struct gpio_pin* gp, int value)
    }

    class gpio_pin {
        +struct gpio_chip* chip
        +unsigned int offset
    }

    class sophgo_gpio_chip {
        +unsigned long addr
        +struct gpio_chip chip
    }

    class fdt_gpio {
        +struct fdt_driver driver
        +int (*xlate)(...)
    }

    class fdt_gpio_sophgo_instance {
        <<instance of fdt_gpio>>
        +driver.match_table = sophgo_gpio_match
        +driver.init = sophgo_gpio_init
        +xlate = fdt_gpio_simple_xlate
    }

    class sbi_system_reset_device {
        +char* name
        +int (*system_reset_check)(u32 type, u32 reason)
        +void (*system_reset)(u32 type, u32 reason)
    }

    class cpld_reset {
        +struct gpio_pin pin
        +u32 active_delay
        +u32 inactive_delay
        +gpio_pin* pin
    }

    class mango_reset_gpio_poweroff_device {
        <<instance of sbi_system_reset_device>>
        +name = "mango-cpld"
        +system_reset_check = cpld_system_poweroff_check
        +system_reset = cpld_system_poweroff
    }

    class mango_reset_gpio_reboot_device {
        <<instance of sbi_system_reset_device>>
        +name = "mango-cpld"
        +system_reset_check = cpld_system_reboot_check
        +system_reset = cpld_system_reboot
    }

    class i2c_adapter {
        +int nr
        +int (*reg_read)(...)
        +int (*reg_write)(...)
    }

    class mango_mcu_state {
        +struct i2c_adapter* adapter
        +u32 reg
    }

    class mango_reset_i2c_device {
        <<instance of sbi_system_reset_device>>
        +name = "mango-reset"
        +system_reset_check = mango_system_reset_check
        +system_reset = mango_system_reset
    }

    class mango_reset_wdt_device {
        <<instance of sbi_system_reset_device>>
        +name = "mango-wdt"
        +system_reset_check = sophgo_wdt_system_reset_check
        +system_reset = sophgo_wdt_system_reset
    }

    sophgo_gpio_chip --> gpio_chip : embeds
    cpld_reset --> gpio_pin : uses

    fdt_gpio_sophgo_instance --> fdt_gpio : instance_of
    fdt_gpio_sophgo_instance ..> sophgo_gpio_chip : init_chips

    mango_reset_gpio_poweroff_device --> sbi_system_reset_device
    mango_reset_gpio_reboot_device --> sbi_system_reset_device

    mango_reset_i2c_device --> sbi_system_reset_device
    mango_mcu_state --> i2c_adapter : holds

    mango_reset_wdt_device --> sbi_system_reset_device
Loading

File-Level Changes

Change Details Files
Refine Sophgo SG2042/Mango platform wiring, including timer region sizing, cold-boot policy, TLB sizing, PMU setup, time CSR emulation, and FDT cleanup of legacy reset nodes.
  • Include libfdt and declare platform-global variables and flags for selected hart and forced time CSR emulation.
  • Replace fixed SG2042 timer MMIO span with a size derived from sbi_platform_hart_count.
  • Extend hfeatures initialization to set MHPM mask and width for 64-bit PMU counters.
  • Introduce mango_cold_boot_allowed to limit cold-boot to either a selected hart or harts below 64.
  • Add mango_force_emulate_time_csr, mango_tlb_num_entries, and mango_final_init; the latter prunes mango reset and CPLD nodes from the FDT before delegating to generic_final_init.
  • In sophgo_sg2042_platform_init, enforce a minimum hart stack size, determine force_emulate_time_csr based on presence of the global mtimer node, and hook the new platform ops (early_init, extensions_init, cold_boot_allowed, force_emulate_time_csr, get_tlb_num_entries, final_init).
platform/generic/sophgo/sg2042.c
Tighten RISC-V memory barriers and fences, including SMP store-release semantics, spinlock fences, and coldboot_done publication.
  • Broaden rmb/wmb and SMP rmb/wmb to include IO ordering by adjusting RISCV_FENCE arguments.
  • Add a Mango-specific __smp_store_release that wraps the store with fences before and after when CONFIG_PLATFORM_SOPHGO_MANGO is enabled; keep the original for other platforms.
  • Insert a fence "w, o" before the atomic loop and a RISCV_FENCE(w, o) after __smp_store_release in spin_unlock.
  • After marking coldboot_done via __smp_store_release, add RISCV_FENCE(w, o) in wake_coldboot_harts.
include/sbi/riscv_barrier.h
lib/sbi/riscv_locks.c
lib/sbi/sbi_init.c
Add an sbi_platform hook and plumbing to force emulation of the time CSR, hiding TIME from feature detection and disabling time counters when needed.
  • Extend sbi_platform_operations with a force_emulate_time_csr callback and add sbi_platform_force_emulate_time_csr helper.
  • During mstatus_init, if the platform forces emulated time CSR, clear the TM bit in MCOUNTEREN and SCOUNTEREN to prevent direct time use.
  • During hart feature detection, skip probing CSR_TIME when time CSR emulation is forced.
  • In sbi_pmu_exit, clear MCOUNTEREN TM when time CSR is emulated to keep PMU state consistent.
include/sbi/sbi_platform.h
lib/sbi/sbi_hart.c
lib/sbi/sbi_pmu.c
include/sbi/riscv_encoding.h
Introduce SG2042 global mtimer (GMT) timer driver with FDT integration and timer-domain quirks so ACLINT can share or avoid MMIO regions as needed.
  • Extend aclint_mtimer_data and timer_mtimer_quirks with a use_extern_domain flag and propagate it during mtimer cold init to optionally skip adding its MMIO range to the root domain.
  • Add new thead_clint_sep_quirks that treat CLINT as having separate mtimer, set clint_mtime_offset and use_extern_domain, and register compatibles for "thead,c900-clint-mtimer" and "sophgo,sg2042-clint-mtimer".
  • Implement sg2042_gmt.c, providing a timer device that reads a global mtimer, translates to declared frequency, and programs per-hart timecmp registers based on CLINT CSR_TIME and frequency ratios; wire it into the timer device framework.
  • Implement fdt_timer_sg2042_gmt.c to parse GMT and timecmp MMIO regions plus clock-frequency pair from FDT and call sg2042gmt_cold_timer_init.
  • Add Kconfig and objects.mk entries to build the SG2042 GMT timer and FDT driver when enabled.
lib/utils/timer/aclint_mtimer.c
include/sbi_utils/timer/aclint_mtimer.h
lib/utils/timer/fdt_timer_mtimer.c
lib/utils/timer/sg2042_gmt.c
lib/utils/timer/fdt_timer_sg2042_gmt.c
include/sbi_utils/timer/sg2042_gmt.h
lib/utils/timer/objects.mk
lib/utils/timer/Kconfig
platform/generic/configs/defconfig
Add Sophgo Mango reset drivers for MCU-, CPLD-, and watchdog-based system reset and poweroff, and integrate them into the FDT reset framework while cleaning redundant DT nodes at runtime.
  • Introduce an I2C-based MCU reset driver that identifies Mango boards, issues shutdown or reboot commands via MCU registers, and registers as an sbi_system_reset_device via FDT (mango,reset).
  • Add a GPIO/CPLD-based reset driver that uses GPIO pins with configurable active/inactive delays to implement poweroff and reboot for mango,cpld-poweroff and mango,cpld-reboot compatibles, wiring them as separate system_reset devices.
  • Implement a watchdog-based reset driver that configures TOP syscon and watchdog registers to trigger system reset for mango,wdt-reset nodes.
  • Register the new reset drivers in reset/objects.mk and Kconfig and ensure mango_final_init removes the original reset/poweroff/reboot nodes from the FDT when using the SBI drivers.
lib/utils/reset/fdt_reset_sophgo_mcu.c
lib/utils/reset/fdt_reset_sophgo_cpld.c
lib/utils/reset/fdt_reset_sophgo_wdt.c
lib/utils/reset/objects.mk
lib/utils/reset/Kconfig
platform/generic/sophgo/sg2042.c
Add Sophgo GPIO controller support and wire it into the FDT GPIO subsystem for use by reset drivers and platform logic.
  • Implement a simple MMIO-based Sophgo GPIO chip supporting output direction and set operations, along with a startup flag toggle to mark normal boot.
  • Provide address derivation via parent reg property, maintain up to three GPIO chips, and register them into the gpio_chip framework via an fdt_gpio driver with compatible "sophgo,gpio0".
  • Hook the Sophgo GPIO driver into the GPIO objects and Kconfig so it is built and discoverable via FDT.
lib/utils/gpio/fdt_gpio_sophgo.c
lib/utils/gpio/objects.mk
lib/utils/gpio/Kconfig
Fix PMU counter overflow handling for T-Head C9xx and ensure PMU stop paths clear overflow state before reusing counters.
  • In thead_c9xx_pmu_ctr_disable_irq, check CSR_MIP for the PMU overflow interrupt and clear the corresponding bit in the MCOUNTEROF CSR before exiting.
  • When stopping a PMU counter with RESET flag, call hw_counter_disable_irq if provided by the pmu device, then clear active_events index and reset MHPMevent CSR.
platform/generic/thead/thead_c9xx_pmu.c
lib/sbi/sbi_pmu.c
Adjust firmware startup and trap handling for correctness on Mango: fix hart-index comparison and flush TLB on trap entry.
  • Change the warm-boot hart index bounds check from signed bge to unsigned bgeu to avoid incorrect hang on large hart indices.
  • Insert an sfence.vma zero, t0 at the beginning of _trap_handler to flush TLB entries for the faulting address space before saving context.
firmware/fw_base.S
Register additional MSWI and CLINT compatibles for Sophgo/T-Head variants so existing IPI and timer drivers bind correctly.
  • Extend ipi_mswi FDT match table with "sophgo,sg2042-clint-mswi" and "thead,c900-clint-mswi" so MSWI driver attaches.
  • Add new CLINT/MTIMER compatibles "thead,c900-clint-mtimer" and "sophgo,sg2042-clint-mtimer" mapped to the new separated-CLINT quirks in the mtimer driver.
lib/utils/ipi/fdt_ipi_mswi.c
lib/utils/timer/fdt_timer_mtimer.c

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

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 4 issues, and left some high level feedback:

  • In fdt_gpio_sophgo.c, sophgo_gpio_addr_get() derives the base address from the parent node's "reg" assuming a fixed 2-cell 64-bit address layout; consider using fdt_get_node_addr_size() on the GPIO node itself (respecting #address-cells/#size-cells) to avoid hard‑coding and potential misparsing on different DTs.
  • The GPIO chip size in fdt_gpio_sophgo.c is set to SOPHGO_GPIO_PINS_MAX (31) even though offsets are 0–31 inclusive; if the hardware exposes 32 pins, set ngpio accordingly (e.g., use SOPHGO_GPIO_PINS_MAX + 1) to avoid silently ignoring the last GPIO.
  • In sg2042_gmt.c, the frequency ratio arithmetic (e.g., actual_freq / declared_freq, timecmp_freq / actual_freq) assumes these divisors are nonzero and divide cleanly; consider adding basic validation (and perhaps using 64-bit-safe scaling or gcd-based reduction) to avoid divide-by-zero or large rounding errors if DT values are unexpected.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In fdt_gpio_sophgo.c, sophgo_gpio_addr_get() derives the base address from the parent node's "reg" assuming a fixed 2-cell 64-bit address layout; consider using fdt_get_node_addr_size() on the GPIO node itself (respecting #address-cells/#size-cells) to avoid hard‑coding and potential misparsing on different DTs.
- The GPIO chip size in fdt_gpio_sophgo.c is set to SOPHGO_GPIO_PINS_MAX (31) even though offsets are 0–31 inclusive; if the hardware exposes 32 pins, set ngpio accordingly (e.g., use SOPHGO_GPIO_PINS_MAX + 1) to avoid silently ignoring the last GPIO.
- In sg2042_gmt.c, the frequency ratio arithmetic (e.g., actual_freq / declared_freq, timecmp_freq / actual_freq) assumes these divisors are nonzero and divide cleanly; consider adding basic validation (and perhaps using 64-bit-safe scaling or gcd-based reduction) to avoid divide-by-zero or large rounding errors if DT values are unexpected.

## Individual Comments

### Comment 1
<location> `lib/utils/gpio/fdt_gpio_sophgo.c:132-134` </location>
<code_context>
+		return rc;
+
+	chip->addr = addr;
+	chip->chip.driver = &fdt_gpio_sophgo;
+	chip->chip.id = nodeoff;
+	chip->chip.ngpio = SOPHGO_GPIO_PINS_MAX;
+	chip->chip.direction_output = sophgo_gpio_direction_output;
+	chip->chip.set = sophgo_gpio_set;
</code_context>

<issue_to_address>
**issue (bug_risk):** GPIO ngpio should likely be count, not max index

`SOPHGO_GPIO_PINS_MAX` is 31, but `ngpio` should be the count of GPIOs rather than the highest index. For pins 0..31, `ngpio` should be 32 (e.g., `SOPHGO_GPIO_PINS_MAX + 1`), otherwise the last pin may not be addressable and the range semantics will be off.
</issue_to_address>

### Comment 2
<location> `lib/utils/reset/fdt_reset_sophgo_wdt.c:73-74` </location>
<code_context>
+	const fdt32_t *val;
+	int len, noff;
+
+	val = fdt_getprop(fdt, nodeoff, "subctrl-syscon", &len);
+	if (val || len >= sizeof(fdt32_t)) {
+		noff = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*val));
+		if (noff < 0)
</code_context>

<issue_to_address>
**issue (bug_risk):** Logical condition should likely use && instead of || when checking FDT property

`if (val || len >= sizeof(fdt32_t))` will succeed whenever either the pointer is non-NULL or `len` is large enough, which means you can call `fdt32_to_cpu(*val)` when `val` is NULL or when the property is too short. This risks reading an invalid phandle. Use `if (val && len >= sizeof(fdt32_t))` so you only proceed when the property exists and contains at least one 32-bit cell.
</issue_to_address>

### Comment 3
<location> `lib/sbi/riscv_locks.c:67` </location>
<code_context>
 #error "need A or Zaamo or Zalrsc"
 #endif

+		"fence w, o\n"
+
 		/* Did we get the lock? */
</code_context>

<issue_to_address>
**suggestion (performance):** Additional fence in spin_lock hot path may hurt performance without clear benefit

The `fence w, o` inside the spin_lock loop adds a barrier on every failed CAS in the contended path and may degrade scalability, given that `__smp_store_release` and other barriers already provide ordering for lock acquire/release. Please confirm that this specific fence is needed for a particular device-ordering requirement; if not, consider removing it or relocating it outside the hot retry loop.
</issue_to_address>

### Comment 4
<location> `include/sbi_utils/timer/sg2042_gmt.h:13-18` </location>
<code_context>
+int sg2042gmt_cold_timer_init(unsigned long mtimer_base,
+			      unsigned long mtimecmp_base,
+			      unsigned long mtimecmp_size,
+			      unsigned long delcared_freq,
+			      unsigned long actual_freq,
+			      unsigned long timecmp_freq);
</code_context>

<issue_to_address>
**nitpick (typo):** Typo in parameter name `delcared_freq` in SG2042 GMT timer header

The prototype uses `delcared_freq` but the implementation uses `declared_freq`. Please align the spelling here to avoid confusion when searching or reading the header.

```suggestion
int sg2042gmt_cold_timer_init(unsigned long mtimer_base,
			      unsigned long mtimecmp_base,
			      unsigned long mtimecmp_size,
			      unsigned long declared_freq,
			      unsigned long actual_freq,
			      unsigned long timecmp_freq);
```
</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.

Comment on lines +132 to +134
chip->chip.driver = &fdt_gpio_sophgo;
chip->chip.id = nodeoff;
chip->chip.ngpio = SOPHGO_GPIO_PINS_MAX;
Copy link

Choose a reason for hiding this comment

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

issue (bug_risk): GPIO ngpio should likely be count, not max index

SOPHGO_GPIO_PINS_MAX is 31, but ngpio should be the count of GPIOs rather than the highest index. For pins 0..31, ngpio should be 32 (e.g., SOPHGO_GPIO_PINS_MAX + 1), otherwise the last pin may not be addressable and the range semantics will be off.

Comment on lines +73 to +74
val = fdt_getprop(fdt, nodeoff, "subctrl-syscon", &len);
if (val || len >= sizeof(fdt32_t)) {
Copy link

Choose a reason for hiding this comment

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

issue (bug_risk): Logical condition should likely use && instead of || when checking FDT property

if (val || len >= sizeof(fdt32_t)) will succeed whenever either the pointer is non-NULL or len is large enough, which means you can call fdt32_to_cpu(*val) when val is NULL or when the property is too short. This risks reading an invalid phandle. Use if (val && len >= sizeof(fdt32_t)) so you only proceed when the property exists and contains at least one 32-bit cell.

#error "need A or Zaamo or Zalrsc"
#endif

"fence w, o\n"
Copy link

Choose a reason for hiding this comment

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

suggestion (performance): Additional fence in spin_lock hot path may hurt performance without clear benefit

The fence w, o inside the spin_lock loop adds a barrier on every failed CAS in the contended path and may degrade scalability, given that __smp_store_release and other barriers already provide ordering for lock acquire/release. Please confirm that this specific fence is needed for a particular device-ordering requirement; if not, consider removing it or relocating it outside the hot retry loop.

Comment on lines +13 to +18
int sg2042gmt_cold_timer_init(unsigned long mtimer_base,
unsigned long mtimecmp_base,
unsigned long mtimecmp_size,
unsigned long delcared_freq,
unsigned long actual_freq,
unsigned long timecmp_freq);
Copy link

Choose a reason for hiding this comment

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

nitpick (typo): Typo in parameter name delcared_freq in SG2042 GMT timer header

The prototype uses delcared_freq but the implementation uses declared_freq. Please align the spelling here to avoid confusion when searching or reading the header.

Suggested change
int sg2042gmt_cold_timer_init(unsigned long mtimer_base,
unsigned long mtimecmp_base,
unsigned long mtimecmp_size,
unsigned long delcared_freq,
unsigned long actual_freq,
unsigned long timecmp_freq);
int sg2042gmt_cold_timer_init(unsigned long mtimer_base,
unsigned long mtimecmp_base,
unsigned long mtimecmp_size,
unsigned long declared_freq,
unsigned long actual_freq,
unsigned long timecmp_freq);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant