ALSA: hda: hda_component: Introduce component parent structure

In preparation for moving duplicated members from the hda_component
structure introduce a parent structure that wraps the array of
components. This also allows us to confine the knowledge of the maximum
number of entries to the hda_component files and eliminate passing that
redundant information around and making direct accesses to the array.

Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/20240617154105.108635-2-simont@opensource.cirrus.com
This commit is contained in:
Simon Trimmer 2024-06-17 16:41:02 +01:00 committed by Takashi Iwai
parent d85002b5d1
commit 960ccf6eaf
3 changed files with 71 additions and 53 deletions

View File

@ -15,35 +15,39 @@
#include "hda_local.h"
#ifdef CONFIG_ACPI
void hda_component_acpi_device_notify(struct hda_component *comps, int num_comps,
void hda_component_acpi_device_notify(struct hda_component_parent *parent,
acpi_handle handle, u32 event, void *data)
{
struct hda_component *comp;
int i;
for (i = 0; i < num_comps; i++) {
if (comps[i].dev && comps[i].acpi_notify)
comps[i].acpi_notify(acpi_device_handle(comps[i].adev), event,
comps[i].dev);
for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
comp = hda_component_from_index(parent, i);
if (comp->dev && comp->acpi_notify)
comp->acpi_notify(acpi_device_handle(comp->adev), event, comp->dev);
}
}
EXPORT_SYMBOL_NS_GPL(hda_component_acpi_device_notify, SND_HDA_SCODEC_COMPONENT);
int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps, int num_comps,
struct hda_component_parent *parent,
acpi_notify_handler handler, void *data)
{
bool support_notifications = false;
struct acpi_device *adev;
struct hda_component *comp;
int ret;
int i;
adev = comps[0].adev;
adev = parent->comps[0].adev;
if (!acpi_device_handle(adev))
return 0;
for (i = 0; i < num_comps; i++)
for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
comp = hda_component_from_index(parent, i);
support_notifications = support_notifications ||
comps[i].acpi_notifications_supported;
comp->acpi_notifications_supported;
}
if (support_notifications) {
ret = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY,
@ -61,13 +65,13 @@ int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind_acpi_notifications, SND_HDA_SCODEC_COMPONENT);
void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps,
struct hda_component_parent *parent,
acpi_notify_handler handler)
{
struct acpi_device *adev;
int ret;
adev = comps[0].adev;
adev = parent->comps[0].adev;
if (!acpi_device_handle(adev))
return;
@ -78,21 +82,25 @@ void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
EXPORT_SYMBOL_NS_GPL(hda_component_manager_unbind_acpi_notifications, SND_HDA_SCODEC_COMPONENT);
#endif /* ifdef CONFIG_ACPI */
void hda_component_manager_playback_hook(struct hda_component *comps, int num_comps, int action)
void hda_component_manager_playback_hook(struct hda_component_parent *parent, int action)
{
struct hda_component *comp;
int i;
for (i = 0; i < num_comps; i++) {
if (comps[i].dev && comps[i].pre_playback_hook)
comps[i].pre_playback_hook(comps[i].dev, action);
for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
comp = hda_component_from_index(parent, i);
if (comp->dev && comp->pre_playback_hook)
comp->pre_playback_hook(comp->dev, action);
}
for (i = 0; i < num_comps; i++) {
if (comps[i].dev && comps[i].playback_hook)
comps[i].playback_hook(comps[i].dev, action);
for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
comp = hda_component_from_index(parent, i);
if (comp->dev && comp->playback_hook)
comp->playback_hook(comp->dev, action);
}
for (i = 0; i < num_comps; i++) {
if (comps[i].dev && comps[i].post_playback_hook)
comps[i].post_playback_hook(comps[i].dev, action);
for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
comp = hda_component_from_index(parent, i);
if (comp->dev && comp->post_playback_hook)
comp->post_playback_hook(comp->dev, action);
}
}
EXPORT_SYMBOL_NS_GPL(hda_component_manager_playback_hook, SND_HDA_SCODEC_COMPONENT);
@ -124,22 +132,21 @@ static int hda_comp_match_dev_name(struct device *dev, void *data)
}
int hda_component_manager_bind(struct hda_codec *cdc,
struct hda_component *comps, int count)
struct hda_component_parent *parent)
{
int i;
/* Init shared data */
for (i = 0; i < count; ++i) {
memset(&comps[i], 0, sizeof(comps[i]));
comps[i].codec = cdc;
}
/* Init shared and component specific data */
memset(parent, 0, sizeof(*parent));
for (i = 0; i < ARRAY_SIZE(parent->comps); i++)
parent->comps[i].codec = cdc;
return component_bind_all(hda_codec_dev(cdc), comps);
return component_bind_all(hda_codec_dev(cdc), &parent->comps);
}
EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind, SND_HDA_SCODEC_COMPONENT);
int hda_component_manager_init(struct hda_codec *cdc,
struct hda_component *comps, int count,
struct hda_component_parent *parent, int count,
const char *bus, const char *hid,
const char *match_str,
const struct component_master_ops *ops)

View File

@ -28,18 +28,21 @@ struct hda_component {
void (*post_playback_hook)(struct device *dev, int action);
};
struct hda_component_parent {
struct hda_component comps[HDA_MAX_COMPONENTS];
};
#ifdef CONFIG_ACPI
void hda_component_acpi_device_notify(struct hda_component *comps, int num_comps,
void hda_component_acpi_device_notify(struct hda_component_parent *parent,
acpi_handle handle, u32 event, void *data);
int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps, int num_comps,
struct hda_component_parent *parent,
acpi_notify_handler handler, void *data);
void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps,
struct hda_component_parent *parent,
acpi_notify_handler handler);
#else
static inline void hda_component_acpi_device_notify(struct hda_component *comps,
int num_comps,
static inline void hda_component_acpi_device_notify(struct hda_component_parent *parent,
acpi_handle handle,
u32 event,
void *data)
@ -47,8 +50,7 @@ static inline void hda_component_acpi_device_notify(struct hda_component *comps,
}
static inline int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps,
int num_comps,
struct hda_component_parent *parent,
acpi_notify_handler handler,
void *data)
@ -57,17 +59,16 @@ static inline int hda_component_manager_bind_acpi_notifications(struct hda_codec
}
static inline void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps,
struct hda_component_parent *parent,
acpi_notify_handler handler)
{
}
#endif /* ifdef CONFIG_ACPI */
void hda_component_manager_playback_hook(struct hda_component *comps, int num_comps,
int action);
void hda_component_manager_playback_hook(struct hda_component_parent *parent, int action);
int hda_component_manager_init(struct hda_codec *cdc,
struct hda_component *comps, int count,
struct hda_component_parent *parent, int count,
const char *bus, const char *hid,
const char *match_str,
const struct component_master_ops *ops);
@ -75,13 +76,24 @@ int hda_component_manager_init(struct hda_codec *cdc,
void hda_component_manager_free(struct hda_codec *cdc,
const struct component_master_ops *ops);
int hda_component_manager_bind(struct hda_codec *cdc,
struct hda_component *comps, int count);
int hda_component_manager_bind(struct hda_codec *cdc, struct hda_component_parent *parent);
static inline struct hda_component *hda_component_from_index(struct hda_component_parent *parent,
int index)
{
if (!parent)
return NULL;
if (index < 0 || index >= ARRAY_SIZE(parent->comps))
return NULL;
return &parent->comps[index];
}
static inline void hda_component_manager_unbind(struct hda_codec *cdc,
struct hda_component *comps)
struct hda_component_parent *parent)
{
component_unbind_all(hda_codec_dev(cdc), comps);
component_unbind_all(hda_codec_dev(cdc), &parent->comps);
}
#endif /* ifndef __HDA_COMPONENT_H__ */

View File

@ -131,7 +131,7 @@ struct alc_spec {
u8 alc_mute_keycode_map[1];
/* component binding */
struct hda_component comps[HDA_MAX_COMPONENTS];
struct hda_component_parent comps;
};
/*
@ -6793,8 +6793,7 @@ static void comp_acpi_device_notify(acpi_handle handle, u32 event, void *data)
codec_info(cdc, "ACPI Notification %d\n", event);
hda_component_acpi_device_notify(spec->comps, ARRAY_SIZE(spec->comps),
handle, event, data);
hda_component_acpi_device_notify(&spec->comps, handle, event, data);
}
static int comp_bind(struct device *dev)
@ -6803,12 +6802,12 @@ static int comp_bind(struct device *dev)
struct alc_spec *spec = cdc->spec;
int ret;
ret = hda_component_manager_bind(cdc, spec->comps, ARRAY_SIZE(spec->comps));
ret = hda_component_manager_bind(cdc, &spec->comps);
if (ret)
return ret;
return hda_component_manager_bind_acpi_notifications(cdc,
spec->comps, ARRAY_SIZE(spec->comps),
&spec->comps,
comp_acpi_device_notify, cdc);
}
@ -6817,8 +6816,8 @@ static void comp_unbind(struct device *dev)
struct hda_codec *cdc = dev_to_hda_codec(dev);
struct alc_spec *spec = cdc->spec;
hda_component_manager_unbind_acpi_notifications(cdc, spec->comps, comp_acpi_device_notify);
hda_component_manager_unbind(cdc, spec->comps);
hda_component_manager_unbind_acpi_notifications(cdc, &spec->comps, comp_acpi_device_notify);
hda_component_manager_unbind(cdc, &spec->comps);
}
static const struct component_master_ops comp_master_ops = {
@ -6831,7 +6830,7 @@ static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_
{
struct alc_spec *spec = cdc->spec;
hda_component_manager_playback_hook(spec->comps, ARRAY_SIZE(spec->comps), action);
hda_component_manager_playback_hook(&spec->comps, action);
}
static void comp_generic_fixup(struct hda_codec *cdc, int action, const char *bus,
@ -6842,7 +6841,7 @@ static void comp_generic_fixup(struct hda_codec *cdc, int action, const char *bu
switch (action) {
case HDA_FIXUP_ACT_PRE_PROBE:
ret = hda_component_manager_init(cdc, spec->comps, count, bus, hid,
ret = hda_component_manager_init(cdc, &spec->comps, count, bus, hid,
match_str, &comp_master_ops);
if (ret)
return;