Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef8e39b5 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Fix undefined symbol due to builtin/module mixup



Even after the fix for leftover kconfig handling (commit f8f1becf),
the current code still doesn't handle properly the builtin/module
mixup case between the core snd-hda-codec and other codec drivers.
For example, when CONFIG_SND_HDA_INTEL=y and
CONFIG_SND_HDA_CODEC_HDMI=m, it'll end up with an unresolved symbol
snd_hda_parse_hdmi_codec.  This patch fixes the issue.

Now codec->parser points to the parser object *only* when a module
(either generic or HDMI parser) is loaded and bound.  When a builtin
symbol is used, codec->parser still points to NULL.  This is the
difference from the previous versions.

Fixes: f8f1becf ('ALSA: hda - Fix leftover ifdef checks after modularization')
Reported-by: default avatarFengguang Wu <fengguang.wu@intel.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent f88abaa0
Loading
Loading
Loading
Loading
+15 −15
Original line number Original line Diff line number Diff line
@@ -1339,24 +1339,16 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
/*
/*
 * Dynamic symbol binding for the codec parsers
 * Dynamic symbol binding for the codec parsers
 */
 */
#ifdef MODULE
#define load_parser_sym(sym)		((int (*)(struct hda_codec *))symbol_request(sym))
#define unload_parser_addr(addr)	symbol_put_addr(addr)
#else
#define load_parser_sym(sym)		(sym)
#define unload_parser_addr(addr)	do {} while (0)
#endif


#define load_parser(codec, sym) \
#define load_parser(codec, sym) \
	((codec)->parser = load_parser_sym(sym))
	((codec)->parser = (int (*)(struct hda_codec *))symbol_request(sym))


static void unload_parser(struct hda_codec *codec)
static void unload_parser(struct hda_codec *codec)
{
{
	if (codec->parser) {
	if (codec->parser)
		unload_parser_addr(codec->parser);
		symbol_put_addr(codec->parser);
	codec->parser = NULL;
	codec->parser = NULL;
}
}
}


/*
/*
 * codec destructor
 * codec destructor
@@ -1620,12 +1612,20 @@ int snd_hda_codec_configure(struct hda_codec *codec)
		patch = codec->preset->patch;
		patch = codec->preset->patch;
	if (!patch) {
	if (!patch) {
		unload_parser(codec); /* to be sure */
		unload_parser(codec); /* to be sure */
		if (is_likely_hdmi_codec(codec))
		if (is_likely_hdmi_codec(codec)) {
#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
			patch = load_parser(codec, snd_hda_parse_hdmi_codec);
			patch = load_parser(codec, snd_hda_parse_hdmi_codec);
#if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
#elif IS_BUILTIN(CONFIG_SND_HDA_CODEC_HDMI)
		if (!patch)
			patch = snd_hda_parse_hdmi_codec;
#endif
		}
		if (!patch) {
#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
			patch = load_parser(codec, snd_hda_parse_generic_codec);
			patch = load_parser(codec, snd_hda_parse_generic_codec);
#elif IS_BUILTIN(CONFIG_SND_HDA_GENERIC)
			patch = snd_hda_parse_generic_codec;
#endif
#endif
		}
		if (!patch) {
		if (!patch) {
			printk(KERN_ERR "hda-codec: No codec parser is available\n");
			printk(KERN_ERR "hda-codec: No codec parser is available\n");
			return -ENODEV;
			return -ENODEV;