summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-01-29 17:13:32 +0100
committerTakashi Iwai <tiwai@suse.de>2015-02-02 14:42:42 +0100
commit7b46160000197209f7ebca8b92bdbb75795c473f (patch)
tree8655e2cacefc6fa10cfdd4b84a3c697bbbafdc6b
parent0fcd9f4b3c60382205e5819c456aa9ea17b6f20f (diff)
downloadop-kernel-dev-7b46160000197209f7ebca8b92bdbb75795c473f.zip
op-kernel-dev-7b46160000197209f7ebca8b92bdbb75795c473f.tar.gz
ALSA: hwdep: Embed struct device
Like the previous patch, this one embeds the device object into hwdep object. For a proper object lifecycle, it's freed in the release callback. This also allows us to create sysfs entries via passing to the groups field of the device without explicit function calls. Since each driver can see the device and touch its groups field directly, we don't need to delegate in hwdep core any longer. So, remove the groups field from snd_hwdep, and let the user (in this case only hda_hwdep.c) modify the device groups. Reviewed-by: Jaroslav Kysela <perex@perex.cz> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/hwdep.h3
-rw-r--r--sound/core/hwdep.c82
-rw-r--r--sound/pci/hda/hda_hwdep.c7
3 files changed, 38 insertions, 54 deletions
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h
index ae04a3e..ab9fcb2 100644
--- a/include/sound/hwdep.h
+++ b/include/sound/hwdep.h
@@ -68,8 +68,7 @@ struct snd_hwdep {
wait_queue_head_t open_wait;
void *private_data;
void (*private_free) (struct snd_hwdep *hwdep);
- struct device *dev;
- const struct attribute_group **groups;
+ struct device dev;
struct mutex open_mutex;
int used; /* reference counter */
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 85096a1..506387b 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -38,7 +38,6 @@ MODULE_LICENSE("GPL");
static LIST_HEAD(snd_hwdep_devices);
static DEFINE_MUTEX(register_mutex);
-static int snd_hwdep_free(struct snd_hwdep *hwdep);
static int snd_hwdep_dev_free(struct snd_device *device);
static int snd_hwdep_dev_register(struct snd_device *device);
static int snd_hwdep_dev_disconnect(struct snd_device *device);
@@ -345,6 +344,11 @@ static const struct file_operations snd_hwdep_f_ops =
.mmap = snd_hwdep_mmap,
};
+static void release_hwdep_device(struct device *dev)
+{
+ kfree(container_of(dev, struct snd_hwdep, dev));
+}
+
/**
* snd_hwdep_new - create a new hwdep instance
* @card: the card instance
@@ -378,48 +382,49 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
dev_err(card->dev, "hwdep: cannot allocate\n");
return -ENOMEM;
}
+
+ init_waitqueue_head(&hwdep->open_wait);
+ mutex_init(&hwdep->open_mutex);
hwdep->card = card;
hwdep->device = device;
if (id)
strlcpy(hwdep->id, id, sizeof(hwdep->id));
+
+ snd_device_initialize(&hwdep->dev, card);
+ hwdep->dev.release = release_hwdep_device;
+ dev_set_name(&hwdep->dev, "hwC%iD%i", card->number, device);
#ifdef CONFIG_SND_OSSEMUL
hwdep->oss_type = -1;
#endif
- if ((err = snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops)) < 0) {
- snd_hwdep_free(hwdep);
+
+ err = snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops);
+ if (err < 0) {
+ put_device(&hwdep->dev);
return err;
}
- init_waitqueue_head(&hwdep->open_wait);
- mutex_init(&hwdep->open_mutex);
+
if (rhwdep)
*rhwdep = hwdep;
return 0;
}
EXPORT_SYMBOL(snd_hwdep_new);
-static int snd_hwdep_free(struct snd_hwdep *hwdep)
+static int snd_hwdep_dev_free(struct snd_device *device)
{
+ struct snd_hwdep *hwdep = device->device_data;
if (!hwdep)
return 0;
if (hwdep->private_free)
hwdep->private_free(hwdep);
- kfree(hwdep);
+ put_device(&hwdep->dev);
return 0;
}
-static int snd_hwdep_dev_free(struct snd_device *device)
-{
- struct snd_hwdep *hwdep = device->device_data;
- return snd_hwdep_free(hwdep);
-}
-
static int snd_hwdep_dev_register(struct snd_device *device)
{
struct snd_hwdep *hwdep = device->device_data;
struct snd_card *card = hwdep->card;
- struct device *dev;
int err;
- char name[32];
mutex_lock(&register_mutex);
if (snd_hwdep_search(card, hwdep->device)) {
@@ -427,54 +432,31 @@ static int snd_hwdep_dev_register(struct snd_device *device)
return -EBUSY;
}
list_add_tail(&hwdep->list, &snd_hwdep_devices);
- sprintf(name, "hwC%iD%i", hwdep->card->number, hwdep->device);
- dev = hwdep->dev;
- if (!dev)
- dev = snd_card_get_device_link(hwdep->card);
err = snd_register_device_for_dev(SNDRV_DEVICE_TYPE_HWDEP,
hwdep->card, hwdep->device,
&snd_hwdep_f_ops, hwdep,
- NULL, dev, name);
+ &hwdep->dev, NULL, NULL);
if (err < 0) {
- dev_err(dev,
- "unable to register hardware dependent device %i:%i\n",
- card->number, hwdep->device);
+ dev_err(&hwdep->dev, "unable to register\n");
list_del(&hwdep->list);
mutex_unlock(&register_mutex);
return err;
}
- if (hwdep->groups) {
- struct device *d = snd_get_device(SNDRV_DEVICE_TYPE_HWDEP,
- hwdep->card, hwdep->device);
- if (d) {
- if (hwdep->private_data)
- dev_set_drvdata(d, hwdep->private_data);
- err = sysfs_create_groups(&d->kobj, hwdep->groups);
- if (err < 0)
- dev_warn(dev,
- "hwdep %d:%d: cannot create sysfs groups\n",
- card->number, hwdep->device);
- put_device(d);
- }
- }
-
#ifdef CONFIG_SND_OSSEMUL
hwdep->ossreg = 0;
if (hwdep->oss_type >= 0) {
- if ((hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM) && (hwdep->device != 0)) {
- dev_warn(dev,
+ if (hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM &&
+ hwdep->device)
+ dev_warn(&hwdep->dev,
"only hwdep device 0 can be registered as OSS direct FM device!\n");
- } else {
- if (snd_register_oss_device(hwdep->oss_type,
- card, hwdep->device,
- &snd_hwdep_f_ops, hwdep) < 0) {
- dev_err(dev,
- "unable to register OSS compatibility device %i:%i\n",
- card->number, hwdep->device);
- } else
- hwdep->ossreg = 1;
- }
+ else if (snd_register_oss_device(hwdep->oss_type,
+ card, hwdep->device,
+ &snd_hwdep_f_ops, hwdep) < 0)
+ dev_warn(&hwdep->dev,
+ "unable to register OSS compatibility device\n");
+ else
+ hwdep->ossreg = 1;
}
#endif
mutex_unlock(&register_mutex);
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 014a784..11b5a42 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -109,7 +109,6 @@ int snd_hda_create_hwdep(struct hda_codec *codec)
hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
hwdep->private_data = codec;
hwdep->exclusive = 1;
- hwdep->groups = snd_hda_dev_attr_groups;
hwdep->ops.open = hda_hwdep_open;
hwdep->ops.ioctl = hda_hwdep_ioctl;
@@ -118,7 +117,11 @@ int snd_hda_create_hwdep(struct hda_codec *codec)
#endif
/* link to codec */
- hwdep->dev = &codec->dev;
+ hwdep->dev.parent = &codec->dev;
+
+ /* for sysfs */
+ hwdep->dev.groups = snd_hda_dev_attr_groups;
+ dev_set_drvdata(&hwdep->dev, codec);
return 0;
}
OpenPOWER on IntegriCloud