Skip to content

gpio: phytium: update phytium gpio controller driver support#1539

Open
newearth-ss wants to merge 7 commits intodeepin-community:linux-6.6.yfrom
newearth-ss:gpio-6.6.0.3
Open

gpio: phytium: update phytium gpio controller driver support#1539
newearth-ss wants to merge 7 commits intodeepin-community:linux-6.6.yfrom
newearth-ss:gpio-6.6.0.3

Conversation

@newearth-ss
Copy link
Contributor

@newearth-ss newearth-ss commented Mar 10, 2026

This patch updates the support for phytium gpio controller driver.

Summary by Sourcery

Update Phytium GPIO core, PCI, platform, and SGPIO drivers to improve interrupt handling, suspend/resume behavior, and expose driver versioning.

New Features:

  • Add GPIO IRQ wake support so Phytium GPIO lines can be used as system wakeup sources.

Enhancements:

  • Adjust IRQ affinity handling to correctly support controllers with a single parent interrupt.
  • Initialize GPIO interrupt enable/EOI registers on probe to start from a known state and use a common constant for clearing interrupts.
  • Track per-line wake enable state across suspend/resume to restore interrupt and mask configuration correctly.
  • Expose driver version strings via MODULE_VERSION for the Phytium GPIO and SGPIO drivers.

Improve gpio set affinity logic to ensure the correctness of sharing interruptions.

Mainline: Open-Source
Signed-off-by: Cui Fulong <cuifulong2112@phytium.com.cn>
Signed-off-by: Li Yuze <liyuze@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
When gpio irq is enabled by firmware, kernel will report
soft lock and rcu, which will cause it to freeze. So unable and
clear irq before registering irq in gpio driver.

Mainline: Open-Source
Signed-off-by: Cui Fulong <cuifulong2112@phytium.com.cn>
Signed-off-by: Li Yuze <liyuze@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
This patch add driver version information, which will be
used to synchronize and manage driver patches in the future.

Mainline: Open-Source
Signed-off-by: Cui Fulong <cuifulong2112@phytium.com.cn>
Signed-off-by: Li Yuze <liyuze@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
This patch supports irq_set_wake for phytium GPIO driver. It
allows GPIOs to be configured as wakeup sources and
wake the system from suspend.

Mainline: Open-Source
Signed-off-by: Cui Fulong <cuifulong2112@phytium.com.cn>
Signed-off-by: Li Yuze <liyuze@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Add irq_set_affinity interface for gpio-pci driver to
use set affinity function normally.

Mainline: Open-Source
Signed-off-by: Cui Fulong <cuifulong2112@phytium.com.cn>
Signed-off-by: Li Yuze <liyuze@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Add irq clear macro definitions as 0xffffffff to make the
code more standardized. And delete the redundant code about
"is_resuming" variable initialization.

Mainline: Open-Source
Signed-off-by: Cui Fulong <cuifulong2112@phytium.com.cn>
Signed-off-by: Li Yuze <liyuze@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Add lock for irq_set_wake function to prevent concurrency
access register issue.

Mainline: Open-Source
Signed-off-by: Cui Fulong <cuifulong2112@phytium.com.cn>
Signed-off-by: Li Yuze <liyuze@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
@sourcery-ai
Copy link

sourcery-ai bot commented Mar 10, 2026

Reviewer's Guide

Extends the Phytium GPIO core, PCI, platform, and SGPIO drivers with IRQ wake support, refined affinity handling for single-parent IRQs, improved suspend/resume interrupt masking, explicit IRQ clearing on init/resume, and driver version macros.

Sequence diagram for GPIO IRQ wake configuration via phytium_gpio_irq_set_wake

sequenceDiagram
    actor PMCore
    participant IRQCore as IRQ_subsystem
    participant IRQChip as phytium_gpio_irq_chip
    participant Core as phytium_gpio_core
    participant HW as GPIO_hardware

    PMCore->>IRQCore: enable/disable_irq_wake(virtual_irq, enable)
    IRQCore->>IRQChip: irq_set_wake(irq_data, enable)
    IRQChip->>Core: phytium_gpio_irq_set_wake(irq_data, enable)
    Core->>Core: irq_data_get_irq_chip_data
    Core->>Core: gpiochip_get_data
    Core->>Core: irqd_to_hwirq -> bit
    alt dedicated_parent_irq
        Core->>IRQCore: irq_set_irq_wake(gpio->irq[bit], enable)
    else single_parent_irq
        Core->>IRQCore: irq_set_irq_wake(gpio->irq[0], enable)
    end
    Core->>Core: update ctx.wake_en with BIT(bit)
    alt gpio_is_resuming
        Core->>HW: writel(~ctx.wake_en, regs + GPIO_INTMASK)
        Core->>HW: writel(ctx.wake_en, regs + GPIO_INTEN)
    end
    Core-->>IRQChip: return 0
    IRQChip-->>IRQCore: return
    IRQCore-->>PMCore: completion
Loading

Sequence diagram for updated GPIO suspend and resume interrupt handling

sequenceDiagram
    participant PM as PM_core
    participant PCI as phytium_gpio_pci_or_platform_driver
    participant Core as phytium_gpio_core
    participant HW as GPIO_hardware

    PM->>PCI: phytium_gpio_pci_suspend or phytium_gpio_suspend
    PCI->>Core: save ctx.inten, ctx.intmask, ctx.int_type, ctx.int_polarity, ctx.debounce
    PCI->>HW: readl current interrupt registers
    PCI->>HW: writel(~ctx.wake_en, regs + GPIO_INTMASK)
    PCI->>HW: writel(ctx.wake_en, regs + GPIO_INTEN)
    PCI-->>PM: suspend_complete

    PM->>PCI: phytium_gpio_pci_resume or phytium_gpio_resume
    PCI->>HW: writel(ctx.ls_sync, regs + GPIO_LS_SYNC)
    PCI->>HW: writel(ctx.intmask, regs + GPIO_INTMASK)
    PCI->>HW: writel(ctx.int_type, regs + GPIO_INTTYPE_LEVEL)
    PCI->>HW: writel(ctx.int_polarity, regs + GPIO_INT_POLARITY)
    PCI->>HW: writel(ctx.debounce, regs + GPIO_DEBOUNCE)
    PCI->>HW: writel(GPIO_CLEAR_IRQ, regs + GPIO_PORTA_EOI)
    PCI->>HW: writel(ctx.inten, regs + GPIO_INTEN)
    PCI->>Core: gpio->is_resuming = 0
    PCI-->>PM: resume_complete
Loading

Updated class diagram for Phytium GPIO core context and IRQ operations

classDiagram
    class phytium_gpio_ctx {
        u32 inten
        u32 intmask
        u32 int_type
        u32 int_polarity
        u32 raw_intstatus
        u32 ls_sync
        u32 debounce
        u32 wake_en
    }

    class phytium_gpio {
        struct gpio_chip gc
        void __iomem *regs
        raw_spinlock_t lock
        struct phytium_gpio_ctx ctx
        int irq[NGPIO_MAX]
        int is_resuming
    }

    class gpio_chip {
        int base
        function get_direction(gc, offset)
        function direction_input(gc, offset)
        function direction_output(gc, offset, value)
        struct irq_chip_data irq
    }

    class irq_chip_data {
        unsigned int num_parents
        int *parents
        function handler
        unsigned int default_type
    }

    class irq_chip {
        function irq_print_chip(irq_data, seq_file)
        function irq_enable(irq_data)
        function irq_disable(irq_data)
        function irq_set_wake(irq_data, enable)
        function irq_set_affinity(irq_data, mask_val, force)
        unsigned long flags
    }

    class phytium_gpio_core_api {
        int phytium_gpio_get_direction(gc, offset)
        void phytium_gpio_irq_print_chip(irq_data, seq_file)
        void phytium_gpio_irq_enable(irq_data)
        void phytium_gpio_irq_disable(irq_data)
        void phytium_gpio_irq_handler(irq_desc)
        int phytium_gpio_irq_set_wake(irq_data, enable)
        int phytium_gpio_irq_set_affinity(irq_data, cpumask, force)
    }

    class phytium_gpio_pci_driver {
        function phytium_gpio_pci_probe(pci_dev, pci_device_id)
        function phytium_gpio_pci_remove(pci_dev)
        function phytium_gpio_pci_suspend(device)
        function phytium_gpio_pci_resume(device)
        const char *version = PHYTIUM_GPIO_DRIVER_VERSION
    }

    class phytium_gpio_platform_driver {
        function phytium_gpio_probe(platform_device)
        function phytium_gpio_remove(platform_device)
        function phytium_gpio_suspend(device)
        function phytium_gpio_resume(device)
        const char *version = PHYTIUM_GPIO_DRIVER_VERSION
    }

    class phytium_sgpio_driver {
        const char *version = GPIO_SGPIO_DRIVER_VERSION
    }

    phytium_gpio_ctx <.. phytium_gpio : contains
    phytium_gpio o-- gpio_chip : embeds
    gpio_chip o-- irq_chip_data : irq
    irq_chip_data ..> irq_chip : uses
    phytium_gpio_core_api <.. phytium_gpio : implemented_by
    phytium_gpio_pci_driver ..> phytium_gpio_core_api : calls
    phytium_gpio_platform_driver ..> phytium_gpio_core_api : calls
Loading

File-Level Changes

Change Details Files
Add GPIO IRQ wake configuration and tracking in the core driver and wire it into PCI/platform irq_chip ops.
  • Introduce phytium_gpio_irq_set_wake() to configure wake-capable GPIO interrupts and maintain a wake_en bitmask in the controller context under raw spinlock protection.
  • Update suspend paths to program INTMASK/INTEN from the saved wake_en mask instead of globally disabling all GPIO interrupts.
  • Expose the new irq_set_wake callback in the PCI and platform phytium irq_chip definitions so wake configuration can be used by consumers.
drivers/gpio/gpio-phytium-core.c
drivers/gpio/gpio-phytium-core.h
drivers/gpio/gpio-phytium-pci.c
drivers/gpio/gpio-phytium-platform.c
Fix IRQ affinity handling when there is only a single parent interrupt.
  • Adjust phytium_gpio_irq_set_affinity() to map any GPIO line to parent[0] when there is exactly one parent IRQ before calling into the parent irq_chip.
drivers/gpio/gpio-phytium-core.c
Initialize and clear GPIO interrupts consistently at probe and resume.
  • At PCI and platform probe, disable all GPIO interrupts and clear pending IRQs by writing GPIO_INTEN=0 and GPIO_PORTA_EOI=GPIO_CLEAR_IRQ.
  • At resume, use GPIO_CLEAR_IRQ instead of a hard-coded 0xffffffff when writing GPIO_PORTA_EOI to acknowledge any pending interrupts.
drivers/gpio/gpio-phytium-pci.c
drivers/gpio/gpio-phytium-platform.c
drivers/gpio/gpio-phytium-core.h
Add driver version macros and module version strings for GPIO and SGPIO drivers.
  • Define PHYTIUM_GPIO_DRIVER_VERSION and GPIO_SGPIO_DRIVER_VERSION macros and use MODULE_VERSION in the respective drivers to expose these versions.
  • Introduce a GPIO_CLEAR_IRQ constant to centralize the clear-IRQ value used across drivers.
drivers/gpio/gpio-phytium-core.h
drivers/gpio/gpio-phytium-pci.c
drivers/gpio/gpio-phytium-platform.c
drivers/gpio/gpio-phytium-sgpio.c
Minor cleanup related to resume state tracking.
  • Remove redundant initialization of is_resuming in PCI and platform probe paths, keeping the field managed by runtime paths instead.
drivers/gpio/gpio-phytium-pci.c
drivers/gpio/gpio-phytium-platform.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

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign avenger-285714 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found 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

@deepin-ci-robot
Copy link

Hi @newearth-ss. 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 left some high level feedback:

  • In phytium_gpio_irq_set_wake(), the function always returns 0 even if irq_set_irq_wake() fails; consider propagating the actual error code (and possibly including the IRQ number in the log) so callers can handle wake configuration failures correctly.
  • The new wake_en state in phytium_gpio_ctx is used in suspend/resume and set_wake paths; ensure it is explicitly initialized to 0 at probe (rather than relying on implicit zeroing) to avoid undefined wake mask state on first suspend.
  • GPIO_CLEAR_IRQ is hard-coded as 0xffffffff; if the hardware IRQ status width can vary with NGPIO or between variants, consider deriving this mask from the actual number of lines or a register-specific constant to avoid inadvertently touching undefined bits.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In phytium_gpio_irq_set_wake(), the function always returns 0 even if irq_set_irq_wake() fails; consider propagating the actual error code (and possibly including the IRQ number in the log) so callers can handle wake configuration failures correctly.
- The new wake_en state in phytium_gpio_ctx is used in suspend/resume and set_wake paths; ensure it is explicitly initialized to 0 at probe (rather than relying on implicit zeroing) to avoid undefined wake mask state on first suspend.
- GPIO_CLEAR_IRQ is hard-coded as 0xffffffff; if the hardware IRQ status width can vary with NGPIO or between variants, consider deriving this mask from the actual number of lines or a register-specific constant to avoid inadvertently touching undefined bits.

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.

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

Adds version metadata and improves Phytium GPIO interrupt handling across platform/PCI variants, including wake-from-suspend support.

Changes:

  • Add MODULE_VERSION() reporting for SGPIO and GPIO platform/PCI drivers.
  • Introduce irq_set_wake support and a new wake_en context field to manage wake-enabled GPIOs during suspend/resume.
  • Clear/disable pending/enable interrupt registers during probe and standardize IRQ clear constant usage.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
drivers/gpio/gpio-phytium-sgpio.c Adds driver version macro and exposes it via MODULE_VERSION().
drivers/gpio/gpio-phytium-platform.c Hooks irq_set_wake, clears IRQ/INTEN on probe, and updates suspend/resume interrupt masking based on wake configuration.
drivers/gpio/gpio-phytium-pci.c Hooks irq_set_wake/affinity, clears IRQ/INTEN on probe, and updates suspend/resume interrupt masking based on wake configuration.
drivers/gpio/gpio-phytium-core.h Adds IRQ clear constant, driver version macro, and wake_en in suspend context; declares phytium_gpio_irq_set_wake().
drivers/gpio/gpio-phytium-core.c Implements phytium_gpio_irq_set_wake() and hardens single-parent affinity handling.

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

Comment on lines +391 to +395
if (gpio->irq[bit])
ret = irq_set_irq_wake(gpio->irq[bit], enable);
else
ret = irq_set_irq_wake(gpio->irq[0], enable);

Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

phytium_gpio_irq_set_wake() treats gpio->irq[bit] as a boolean and may pass an invalid IRQ number to irq_set_irq_wake() (e.g., negative values in gpio->irq[] or a valid IRQ number of 0). It should instead select the parent IRQ based on gc->irq.num_parents (e.g., use parents[0] when num_parents==1, otherwise parents[bit] after validating bit < num_parents) and only call irq_set_irq_wake() with a non-negative IRQ.

Copilot uses AI. Check for mistakes.
Comment on lines +396 to +413
if (ret < 0)
dev_err(gc->parent, "set gpio irq wake failed!\n");

raw_spin_lock_irqsave(&gpio->lock, flags);

if (enable) {
ctx->wake_en |= BIT(bit);
if (gpio->is_resuming == 1) {
writel(~ctx->wake_en, gpio->regs + GPIO_INTMASK);
writel(ctx->wake_en, gpio->regs + GPIO_INTEN);
}
} else
ctx->wake_en &= ~BIT(bit);

raw_spin_unlock_irqrestore(&gpio->lock, flags);

return 0;
}
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

phytium_gpio_irq_set_wake() logs errors from irq_set_irq_wake() but always returns 0. This prevents callers from detecting wake configuration failures; please propagate the return value (or an appropriate error) back to the IRQ core/PM subsystem.

Copilot uses AI. Check for mistakes.
Comment on lines +407 to +408
} else
ctx->wake_en &= ~BIT(bit);
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

When disabling wake (enable==0), ctx->wake_en is updated but GPIO_INTMASK/GPIO_INTEN are only reprogrammed in the enable path (and only when is_resuming==1). If irq_set_wake(..., 0) is called while the device is in the suspended/is_resuming state, the hardware wake mask may remain stale. Consider updating GPIO_INTMASK/GPIO_INTEN in both the enable and disable paths when is_resuming is set.

Suggested change
} else
ctx->wake_en &= ~BIT(bit);
} else {
ctx->wake_en &= ~BIT(bit);
if (gpio->is_resuming == 1) {
writel(~ctx->wake_en, gpio->regs + GPIO_INTMASK);
writel(ctx->wake_en, gpio->regs + GPIO_INTEN);
}
}

Copilot uses AI. Check for mistakes.
.irq_enable = phytium_gpio_irq_enable,
.irq_disable = phytium_gpio_irq_disable,
.irq_set_wake = phytium_gpio_irq_set_wake,
.irq_set_affinity = phytium_gpio_irq_set_affinity,
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

Indentation/alignment on this line uses spaces instead of the usual tab alignment used throughout the file/kernel style. This is likely to trigger checkpatch warnings; please align the assignment consistently with the surrounding irq_chip fields.

Suggested change
.irq_set_affinity = phytium_gpio_irq_set_affinity,
.irq_set_affinity = phytium_gpio_irq_set_affinity,

Copilot uses AI. Check for mistakes.
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.

3 participants