aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-01-29 11:13:32 -0500
committerTakashi Iwai <tiwai@suse.de>2015-02-02 08:42:42 -0500
commit7b46160000197209f7ebca8b92bdbb75795c473f (patch)
tree8655e2cacefc6fa10cfdd4b84a3c697bbbafdc6b
parent0fcd9f4b3c60382205e5819c456aa9ea17b6f20f (diff)
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 ae04a3ec9c77..ab9fcb2f97f0 100644
--- a/include/sound/hwdep.h
+++ b/include/sound/hwdep.h
@@ -68,8 +68,7 @@ struct snd_hwdep {
68 wait_queue_head_t open_wait; 68 wait_queue_head_t open_wait;
69 void *private_data; 69 void *private_data;
70 void (*private_free) (struct snd_hwdep *hwdep); 70 void (*private_free) (struct snd_hwdep *hwdep);
71 struct device *dev; 71 struct device dev;
72 const struct attribute_group **groups;
73 72
74 struct mutex open_mutex; 73 struct mutex open_mutex;
75 int used; /* reference counter */ 74 int used; /* reference counter */
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 85096a150eda..506387ba645d 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -38,7 +38,6 @@ MODULE_LICENSE("GPL");
38static LIST_HEAD(snd_hwdep_devices); 38static LIST_HEAD(snd_hwdep_devices);
39static DEFINE_MUTEX(register_mutex); 39static DEFINE_MUTEX(register_mutex);
40 40
41static int snd_hwdep_free(struct snd_hwdep *hwdep);
42static int snd_hwdep_dev_free(struct snd_device *device); 41static int snd_hwdep_dev_free(struct snd_device *device);
43static int snd_hwdep_dev_register(struct snd_device *device); 42static int snd_hwdep_dev_register(struct snd_device *device);
44static int snd_hwdep_dev_disconnect(struct snd_device *device); 43static int snd_hwdep_dev_disconnect(struct snd_device *device);
@@ -345,6 +344,11 @@ static const struct file_operations snd_hwdep_f_ops =
345 .mmap = snd_hwdep_mmap, 344 .mmap = snd_hwdep_mmap,
346}; 345};
347 346
347static void release_hwdep_device(struct device *dev)
348{
349 kfree(container_of(dev, struct snd_hwdep, dev));
350}
351
348/** 352/**
349 * snd_hwdep_new - create a new hwdep instance 353 * snd_hwdep_new - create a new hwdep instance
350 * @card: the card instance 354 * @card: the card instance
@@ -378,48 +382,49 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
378 dev_err(card->dev, "hwdep: cannot allocate\n"); 382 dev_err(card->dev, "hwdep: cannot allocate\n");
379 return -ENOMEM; 383 return -ENOMEM;
380 } 384 }
385
386 init_waitqueue_head(&hwdep->open_wait);
387 mutex_init(&hwdep->open_mutex);
381 hwdep->card = card; 388 hwdep->card = card;
382 hwdep->device = device; 389 hwdep->device = device;
383 if (id) 390 if (id)
384 strlcpy(hwdep->id, id, sizeof(hwdep->id)); 391 strlcpy(hwdep->id, id, sizeof(hwdep->id));
392
393 snd_device_initialize(&hwdep->dev, card);
394 hwdep->dev.release = release_hwdep_device;
395 dev_set_name(&hwdep->dev, "hwC%iD%i", card->number, device);
385#ifdef CONFIG_SND_OSSEMUL 396#ifdef CONFIG_SND_OSSEMUL
386 hwdep->oss_type = -1; 397 hwdep->oss_type = -1;
387#endif 398#endif
388 if ((err = snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops)) < 0) { 399
389 snd_hwdep_free(hwdep); 400 err = snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops);
401 if (err < 0) {
402 put_device(&hwdep->dev);
390 return err; 403 return err;
391 } 404 }
392 init_waitqueue_head(&hwdep->open_wait); 405
393 mutex_init(&hwdep->open_mutex);
394 if (rhwdep) 406 if (rhwdep)
395 *rhwdep = hwdep; 407 *rhwdep = hwdep;
396 return 0; 408 return 0;
397} 409}
398EXPORT_SYMBOL(snd_hwdep_new); 410EXPORT_SYMBOL(snd_hwdep_new);
399 411
400static int snd_hwdep_free(struct snd_hwdep *hwdep) 412static int snd_hwdep_dev_free(struct snd_device *device)
401{ 413{
414 struct snd_hwdep *hwdep = device->device_data;
402 if (!hwdep) 415 if (!hwdep)
403 return 0; 416 return 0;
404 if (hwdep->private_free) 417 if (hwdep->private_free)
405 hwdep->private_free(hwdep); 418 hwdep->private_free(hwdep);
406 kfree(hwdep); 419 put_device(&hwdep->dev);
407 return 0; 420 return 0;
408} 421}
409 422
410static int snd_hwdep_dev_free(struct snd_device *device)
411{
412 struct snd_hwdep *hwdep = device->device_data;
413 return snd_hwdep_free(hwdep);
414}
415
416static int snd_hwdep_dev_register(struct snd_device *device) 423static int snd_hwdep_dev_register(struct snd_device *device)
417{ 424{
418 struct snd_hwdep *hwdep = device->device_data; 425 struct snd_hwdep *hwdep = device->device_data;
419 struct snd_card *card = hwdep->card; 426 struct snd_card *card = hwdep->card;
420 struct device *dev;
421 int err; 427 int err;
422 char name[32];
423 428
424 mutex_lock(&register_mutex); 429 mutex_lock(&register_mutex);
425 if (snd_hwdep_search(card, hwdep->device)) { 430 if (snd_hwdep_search(card, hwdep->device)) {
@@ -427,54 +432,31 @@ static int snd_hwdep_dev_register(struct snd_device *device)
427 return -EBUSY; 432 return -EBUSY;
428 } 433 }
429 list_add_tail(&hwdep->list, &snd_hwdep_devices); 434 list_add_tail(&hwdep->list, &snd_hwdep_devices);
430 sprintf(name, "hwC%iD%i", hwdep->card->number, hwdep->device);
431 dev = hwdep->dev;
432 if (!dev)
433 dev = snd_card_get_device_link(hwdep->card);
434 err = snd_register_device_for_dev(SNDRV_DEVICE_TYPE_HWDEP, 435 err = snd_register_device_for_dev(SNDRV_DEVICE_TYPE_HWDEP,
435 hwdep->card, hwdep->device, 436 hwdep->card, hwdep->device,
436 &snd_hwdep_f_ops, hwdep, 437 &snd_hwdep_f_ops, hwdep,
437 NULL, dev, name); 438 &hwdep->dev, NULL, NULL);
438 if (err < 0) { 439 if (err < 0) {
439 dev_err(dev, 440 dev_err(&hwdep->dev, "unable to register\n");
440 "unable to register hardware dependent device %i:%i\n",
441 card->number, hwdep->device);
442 list_del(&hwdep->list); 441 list_del(&hwdep->list);
443 mutex_unlock(&register_mutex); 442 mutex_unlock(&register_mutex);
444 return err; 443 return err;
445 } 444 }
446 445
447 if (hwdep->groups) {
448 struct device *d = snd_get_device(SNDRV_DEVICE_TYPE_HWDEP,
449 hwdep->card, hwdep->device);
450 if (d) {
451 if (hwdep->private_data)
452 dev_set_drvdata(d, hwdep->private_data);
453 err = sysfs_create_groups(&d->kobj, hwdep->groups);
454 if (err < 0)
455 dev_warn(dev,
456 "hwdep %d:%d: cannot create sysfs groups\n",
457 card->number, hwdep->device);
458 put_device(d);
459 }
460 }
461
462#ifdef CONFIG_SND_OSSEMUL 446#ifdef CONFIG_SND_OSSEMUL
463 hwdep->ossreg = 0; 447 hwdep->ossreg = 0;
464 if (hwdep->oss_type >= 0) { 448 if (hwdep->oss_type >= 0) {
465 if ((hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM) && (hwdep->device != 0)) { 449 if (hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM &&
466 dev_warn(dev, 450 hwdep->device)
451 dev_warn(&hwdep->dev,
467 "only hwdep device 0 can be registered as OSS direct FM device!\n"); 452 "only hwdep device 0 can be registered as OSS direct FM device!\n");
468 } else { 453 else if (snd_register_oss_device(hwdep->oss_type,
469 if (snd_register_oss_device(hwdep->oss_type, 454 card, hwdep->device,
470 card, hwdep->device, 455 &snd_hwdep_f_ops, hwdep) < 0)
471 &snd_hwdep_f_ops, hwdep) < 0) { 456 dev_warn(&hwdep->dev,
472 dev_err(dev, 457 "unable to register OSS compatibility device\n");
473 "unable to register OSS compatibility device %i:%i\n", 458 else
474 card->number, hwdep->device); 459 hwdep->ossreg = 1;
475 } else
476 hwdep->ossreg = 1;
477 }
478 } 460 }
479#endif 461#endif
480 mutex_unlock(&register_mutex); 462 mutex_unlock(&register_mutex);
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 014a7849e8fd..11b5a42b4ec8 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)
109 hwdep->iface = SNDRV_HWDEP_IFACE_HDA; 109 hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
110 hwdep->private_data = codec; 110 hwdep->private_data = codec;
111 hwdep->exclusive = 1; 111 hwdep->exclusive = 1;
112 hwdep->groups = snd_hda_dev_attr_groups;
113 112
114 hwdep->ops.open = hda_hwdep_open; 113 hwdep->ops.open = hda_hwdep_open;
115 hwdep->ops.ioctl = hda_hwdep_ioctl; 114 hwdep->ops.ioctl = hda_hwdep_ioctl;
@@ -118,7 +117,11 @@ int snd_hda_create_hwdep(struct hda_codec *codec)
118#endif 117#endif
119 118
120 /* link to codec */ 119 /* link to codec */
121 hwdep->dev = &codec->dev; 120 hwdep->dev.parent = &codec->dev;
121
122 /* for sysfs */
123 hwdep->dev.groups = snd_hda_dev_attr_groups;
124 dev_set_drvdata(&hwdep->dev, codec);
122 125
123 return 0; 126 return 0;
124} 127}