forked from Minki/linux
9780ded39b
The refresh of HD-audio widget sysfs kobjects via snd_hdac_refresh_widget_sysfs() is slightly racy. The driver recreates the whole tree from scratch after deleting the whole. When CONFIG_DEBUG_KOBJECT_RELEASE option is used, kobject release doesn't happen immediately but delayed, while the re-creation of the same named kobject happens soon after invoking kobject_put(). This may end up with the conflicts of duplicated kobjects, as found in the bug report below. In this patch, we take another approach to refresh the tree: instead of recreating the whole tree, just add the new nodes and delete the non-existing nodes. Since the refresh happens only once at initialization, no longer race would happen. Along with the code change, merge snd_hdac_refresh_widget_sysfs() with the existing snd_hdac_refresh_widgets() with an additional bool flag for simplifying the code. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=197307 Signed-off-by: Takashi Iwai <tiwai@suse.de>
36 lines
890 B
C
36 lines
890 B
C
/*
|
|
* Local helper macros and functions for HD-audio core drivers
|
|
*/
|
|
|
|
#ifndef __HDAC_LOCAL_H
|
|
#define __HDAC_LOCAL_H
|
|
|
|
#define get_wcaps(codec, nid) \
|
|
snd_hdac_read_parm(codec, nid, AC_PAR_AUDIO_WIDGET_CAP)
|
|
|
|
/* get the widget type from widget capability bits */
|
|
static inline int get_wcaps_type(unsigned int wcaps)
|
|
{
|
|
if (!wcaps)
|
|
return -1; /* invalid type */
|
|
return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
|
}
|
|
|
|
static inline unsigned int get_wcaps_channels(u32 wcaps)
|
|
{
|
|
unsigned int chans;
|
|
|
|
chans = (wcaps & AC_WCAP_CHAN_CNT_EXT) >> 13;
|
|
chans = (chans + 1) * 2;
|
|
|
|
return chans;
|
|
}
|
|
|
|
extern const struct attribute_group *hdac_dev_attr_groups[];
|
|
int hda_widget_sysfs_init(struct hdac_device *codec);
|
|
int hda_widget_sysfs_reinit(struct hdac_device *codec, hda_nid_t start_nid,
|
|
int num_nodes);
|
|
void hda_widget_sysfs_exit(struct hdac_device *codec);
|
|
|
|
#endif /* __HDAC_LOCAL_H */
|