Skip to content

Linux 6.6.y hda#1570

Open
tianwei08222 wants to merge 4 commits intodeepin-community:linux-6.6.yfrom
tianwei08222:linux-6.6.y-hda
Open

Linux 6.6.y hda#1570
tianwei08222 wants to merge 4 commits intodeepin-community:linux-6.6.yfrom
tianwei08222:linux-6.6.y-hda

Conversation

@tianwei08222
Copy link

@tianwei08222 tianwei08222 commented Mar 17, 2026

Add parameters to enable automatic power-saving features.
Add runtime status query nodes.
Defer creation of runtime query nodes.
Enable asynchronous suspend feature.

Summary by Sourcery

Enable configurable power saving and runtime status reporting for the Phytium HDA controller driver.

New Features:

  • Add a module parameter to control automatic power-saving timeout for the Phytium HDA driver.
  • Expose a read-only sysfs attribute to query the codec runtime power state on Phytium HDA devices.

Enhancements:

  • Hook power-saving parameter updates to reconfigure power-save settings on all active Phytium HDA cards.
  • Enable asynchronous suspend for the Phytium HDA platform device.

Dai Jingtao added 4 commits March 17, 2026 14:32
Add power_save parameter to enable automatic power saving mode.
The value of power_save is timeout value of automatic power-saving
(in second, 0 is disable). Default value is 1.

Mainline: NA
Signed-off-by: Dai Jingtao <daijingtao1503@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Change-Id: Ib2e3da17a96bc5a654a998fc90bd2d76e915e63a
Add runtime status inquiry node. Use "cat runtime_status" to inquire
the runtime status of codec. D0 is working, and D3 is in IDLE.

Mainline: NA
Signed-off-by: Dai Jingtao <daijingtao1503@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Change-Id: I3fe0ce7eb99c5f45dbcfe0e74a76795883fa5ae7
HDA driver will use schedule work to register codec driver used by
input_register_device function. There will be a conflict if
sysfs_create_group is operated at the same time. So put off creating
runtime inquiry node to avoid this conflict.

Mainline: NA
Signed-off-by: Dai Jingtao <daijingtao1503@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Change-Id: I9b6d5711a874cbd3e15eb2b19595b69285fbc129
Enable async suspend so that different driver can resume
parallely.

Mainline: NA
Signed-off-by: Dai Jingtao <daijingtao1503@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Change-Id: I581ebf5972236c4357a7d34ab215d7e58053e79b
@sourcery-ai
Copy link

sourcery-ai bot commented Mar 17, 2026

Reviewer's Guide

Enable configurable power-saving and runtime status reporting for the Phytium HDA controller, including a tunable power_save module parameter, a sysfs runtime_status attribute, and asynchronous suspend support, while wiring these features into the controller’s probe and card-list management paths.

Sequence diagram for power_save module parameter handling

sequenceDiagram
    actor Admin
    participant Kernel as Linux_kernel
    participant Module as hda_phytium_module
    participant List as card_list
    participant HDA as hda_ft
    participant Chip as azx
    participant Bus as hdac_bus

    Admin->>Kernel: write to module parameter power_save
    Kernel->>Module: param_set_xint(val, kp)
    Module->>Module: param_set_int(val, kp)
    Module->>Module: compare prev and power_save
    alt power_save changed and success
        Module->>List: mutex_lock(card_list_lock)
        loop for each hda in card_list
            List->>HDA: iterate list entry
            HDA->>Chip: access chip
            Module->>Chip: check probe_continued and disabled
            alt probe_continued and not disabled
                Chip->>Bus: get bus reference
                Module->>Bus: snd_hda_set_power_save(bus, power_save * 1000)
            end
        end
        Module->>List: mutex_unlock(card_list_lock)
    else unchanged or error
        Module-->>Kernel: return ret
    end
    Module-->>Kernel: return 0 or error
    Kernel-->>Admin: write completes
Loading

Sequence diagram for runtime_status sysfs query

sequenceDiagram
    actor Admin
    participant Sysfs as sysfs_runtime_status
    participant Dev as hda_ft_device
    participant Card as snd_card
    participant Chip as azx
    participant Bus as hdac_bus

    Admin->>Sysfs: cat /sys/.../runtime_status
    Sysfs->>Dev: runtime_status_show(dev, buf)
    Dev->>Card: dev_get_drvdata(dev)
    Card->>Chip: access private_data
    Chip->>Bus: azx_bus(chip)
    Bus->>Bus: mutex_lock(cmd_mutex)
    Bus->>Bus: snd_hdac_bus_send_cmd(cmd=0x001f0500)
    Bus->>Bus: snd_hdac_bus_get_response(addr=0, res)
    Bus->>Bus: mutex_unlock(cmd_mutex)
    Bus-->>Dev: response res
    Dev->>Dev: decode res & 0x3 to status D0..D3
    Dev-->>Sysfs: sprintf(buf, status)
    Sysfs-->>Admin: D0 or D1 or D2 or D3
Loading

Updated class diagram for Phytium HDA power management and runtime status

classDiagram
    class hda_ft {
        +struct azx chip
        +struct device* dev
        +struct work_struct probe_work
        +int probe_continued
        +struct list_head list
    }

    class azx {
        +struct hdac_bus bus
        +int dev_index
        +bool disabled
    }

    class hdac_bus {
        +struct mutex cmd_mutex
        +int irq
    }

    class snd_card {
        +void* private_data
    }

    class attribute_group {
        +struct attribute** attrs
    }

    class device_attribute_runtime_status {
        +const char* name = runtime_status
        +mode_t mode = 0444
        +ssize_t runtime_status_show(struct device* dev, struct device_attribute* attr, char* buf)
    }

    class hda_ft_runtime_status_group {
        +struct attribute_group hda_ft_runtime_status_group
        +struct attribute* runtime_status_attrs[2]
    }

    class hda_phytium_module_params {
        +int power_save
        +int param_set_xint(const char* val, const struct kernel_param* kp)
    }

    hda_ft --> azx : has
    azx --> hdac_bus : has
    snd_card --> azx : private_data points_to

    hda_ft_runtime_status_group --> attribute_group : wraps
    hda_ft_runtime_status_group --> device_attribute_runtime_status : contains

    hda_phytium_module_params --> hda_ft : iterates_card_list
    hda_phytium_module_params --> azx : uses_chip
    hda_phytium_module_params --> hdac_bus : calls_snd_hda_set_power_save

    device_attribute_runtime_status --> hdac_bus : sends_codec_cmd
    hda_ft --> hda_ft_runtime_status_group : sysfs_group_lifecycle
    hda_ft --> snd_card : owns_via_probe
    hda_ft --> hdac_bus : via_chip_bus

    class platform_device_probe_flow {
        +int hda_ft_probe(struct platform_device* pdev)
        +int azx_probe_continue(struct azx* chip)
        +int hda_ft_remove(struct platform_device* pdev)
        +int azx_first_init(struct azx* chip)
    }

    platform_device_probe_flow --> hda_ft : creates_and_initializes
    platform_device_probe_flow --> hda_ft_runtime_status_group : create_and_remove_sysfs
    platform_device_probe_flow --> hda_phytium_module_params : honors_power_save
    platform_device_probe_flow --> hdac_bus : uses_irq_and_cmd_mutex
    platform_device_probe_flow --> azx : controller_lifecycle
Loading

File-Level Changes

Change Details Files
Introduce a configurable power_save module parameter wired to all existing HDA FT cards via the global card list.
  • Replace the hard-coded power_save macro with a CONFIG_PM-gated integer module parameter defaulting to enabled
  • Define custom param_set_xint kernel-param setter that wraps param_set_int and triggers a power-save reconfiguration on change
  • On parameter updates, iterate the global HDA FT card list under card_list_lock and call snd_hda_set_power_save per active, non-disabled controller
sound/pci/hda/hda_phytium.c
Add a runtime_status sysfs node to query codec power state at runtime.
  • Implement runtime_status_show() to send an HDA verb (0x001f0500) via the HDAC bus, read the response, and map the low 2 bits to D0-D3 power states
  • Declare a read-only DEVICE_ATTR_RO(runtime_status) and group it into a dedicated attribute_group
  • Create the sysfs group on successful probe continuation and tear it down both on error path and in the remove() callback
sound/pci/hda/hda_phytium.c
Enable asynchronous suspend and defer runtime status node creation until probe continuation.
  • Call device_enable_async_suspend() early in azx_first_init() to allow async PM suspend for the HDA controller device
  • Move creation of runtime_status sysfs group into azx_probe_continue() after the controller and codecs are initialized, with proper error handling and cleanup paths
sound/pci/hda/hda_phytium.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

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

  • In runtime_status_show, status can be left uninitialized if res & 0x3 somehow falls outside 0–3 and res is also pre-initialized to -1 (which will report D3 even if no valid response is received); it would be safer to check the return from snd_hdac_bus_get_response() and provide a defined fallback string (e.g., "unknown") instead of relying on the masked value.
  • Using dev_info() on every read of the runtime_status sysfs attribute is likely to be noisy in production; consider switching this to dev_dbg() or dropping the log entirely to avoid log spam when the attribute is polled.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `runtime_status_show`, `status` can be left uninitialized if `res & 0x3` somehow falls outside 0–3 and `res` is also pre-initialized to `-1` (which will report D3 even if no valid response is received); it would be safer to check the return from `snd_hdac_bus_get_response()` and provide a defined fallback string (e.g., `"unknown"`) instead of relying on the masked value.
- Using `dev_info()` on every read of the `runtime_status` sysfs attribute is likely to be noisy in production; consider switching this to `dev_dbg()` or dropping the log entirely to avoid log spam when the attribute is polled.

## Individual Comments

### Comment 1
<location path="sound/pci/hda/hda_phytium.c" line_range="968-969" />
<code_context>
+
+	dev_info(dev, "Inquire codec status!\n");
+	mutex_lock(&bus->cmd_mutex);
+	snd_hdac_bus_send_cmd(bus, cmd);
+	snd_hdac_bus_get_response(bus, 0, &res);
+	mutex_unlock(&bus->cmd_mutex);
+
</code_context>
<issue_to_address>
**issue:** Handle possible errors or timeouts from `snd_hdac_bus_get_response` instead of always trusting `res`.

If `snd_hdac_bus_get_response` fails or times out, `res` could be stale, yet the code still uses it to derive a power state. Please check the return value (and whether a valid response was received) before using `res`, and on failure return an error (e.g. `-EIO`) or a clearly invalid status string instead of reporting a normal power state.
</issue_to_address>

### Comment 2
<location path="sound/pci/hda/hda_phytium.c" line_range="966" />
<code_context>
+	unsigned int res = -1;
+	char *status;
+
+	dev_info(dev, "Inquire codec status!\n");
+	mutex_lock(&bus->cmd_mutex);
+	snd_hdac_bus_send_cmd(bus, cmd);
</code_context>
<issue_to_address>
**suggestion:** This `dev_info` will be emitted on every sysfs read and may be too noisy.

Because this runs on every read of the sysfs attribute, this log may be excessively noisy. Consider switching to `dev_dbg()` (leveraging dynamic debug) or removing the message to avoid flooding the logs.

```suggestion
	dev_dbg(dev, "Inquire codec status!\n");
```
</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 +968 to +969
snd_hdac_bus_send_cmd(bus, cmd);
snd_hdac_bus_get_response(bus, 0, &res);
Copy link

Choose a reason for hiding this comment

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

issue: Handle possible errors or timeouts from snd_hdac_bus_get_response instead of always trusting res.

If snd_hdac_bus_get_response fails or times out, res could be stale, yet the code still uses it to derive a power state. Please check the return value (and whether a valid response was received) before using res, and on failure return an error (e.g. -EIO) or a clearly invalid status string instead of reporting a normal power state.

unsigned int res = -1;
char *status;

dev_info(dev, "Inquire codec status!\n");
Copy link

Choose a reason for hiding this comment

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

suggestion: This dev_info will be emitted on every sysfs read and may be too noisy.

Because this runs on every read of the sysfs attribute, this log may be excessively noisy. Consider switching to dev_dbg() (leveraging dynamic debug) or removing the message to avoid flooding the logs.

Suggested change
dev_info(dev, "Inquire codec status!\n");
dev_dbg(dev, "Inquire codec status!\n");

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 PR adds configurable power-saving and runtime status reporting capabilities to the Phytium HD-audio controller driver, and enables async suspend to improve suspend/resume behavior.

Changes:

  • Add a power_save module parameter (with live reconfiguration across active cards) to control automatic power-saving timeout.
  • Add a read-only sysfs attribute group to query codec power state, created after probe continuation.
  • Enable asynchronous suspend for the Phytium HDA platform device.

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

Comment on lines +967 to +970
mutex_lock(&bus->cmd_mutex);
snd_hdac_bus_send_cmd(bus, cmd);
snd_hdac_bus_get_response(bus, 0, &res);
mutex_unlock(&bus->cmd_mutex);
unsigned int res = -1;
char *status;

dev_info(dev, "Inquire codec status!\n");
break;
}

return sprintf(buf, "%s\n", status);
static int single_cmd = -1;
static int enable_msi = -1;
#ifdef CONFIG_PM
static int power_save = 1;
Comment on lines +1097 to 1105
if (sysfs_create_group(&hda->dev->kobj, &hda_ft_runtime_status_group)) {
dev_warn(hda->dev, "failed create sysfs\n");
goto err_sysfs;
}

return err;

err_sysfs:
sysfs_remove_group(&hda->dev->kobj, &hda_ft_runtime_status_group);
out_free:
Comment on lines +964 to +969
char *status;

dev_info(dev, "Inquire codec status!\n");
mutex_lock(&bus->cmd_mutex);
snd_hdac_bus_send_cmd(bus, cmd);
snd_hdac_bus_get_response(bus, 0, &res);
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.

3 participants