@@ -13,7 +13,6 @@
#define AC97_COMPAT_H
#include <sound/ac97_codec.h>
-#include <sound/soc.h>
struct snd_ac97 *snd_ac97_compat_alloc(struct ac97_codec_device *adev);
void snd_ac97_compat_release(struct snd_ac97 *ac97);
@@ -8,12 +8,13 @@
#ifndef AC97_CONTROLLER_H
#define AC97_CONTROLLER_H
+#include <linux/device.h>
#include <linux/list.h>
#define AC97_BUS_MAX_CODECS 4
#define AC97_SLOTS_AVAILABLE_ALL 0xf
-struct device;
+struct ac97_controller_ops;
/**
* struct ac97_controller - The AC97 controller of the AC-Link
@@ -21,8 +22,8 @@ struct device;
* @controllers: linked list of all existing controllers.
* @adap: the shell device ac97-%d, ie. ac97 adapter
* @nr: the number of the shell device
- * @parent: the device providing the AC97 controller.
* @slots_available: the mask of accessible/scanable codecs.
+ * @parent: the device providing the AC97 controller.
* @codecs: the 4 possible AC97 codecs (NULL if none found).
* @codecs_pdata: platform_data for each codec (NULL if no pdata).
*
@@ -34,8 +35,8 @@ struct ac97_controller {
struct list_head controllers;
struct device adap;
int nr;
- struct device *parent;
unsigned short slots_available;
+ struct device *parent;
struct ac97_codec_device *codecs[AC97_BUS_MAX_CODECS];
void *codecs_pdata[AC97_BUS_MAX_CODECS];
};
@@ -8,3 +8,9 @@
unsigned int snd_ac97_bus_scan_one(struct ac97_controller *ac97,
unsigned int codec_num);
+
+static inline bool ac97_ids_match(unsigned int id1, unsigned int id2,
+ unsigned int mask)
+{
+ return (id1 & mask) == (id2 & mask);
+}
@@ -105,6 +105,7 @@ static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
return 0;
err_free_codec:
+ put_device(&codec->dev);
kfree(codec);
ac97_ctrl->codecs[idx] = NULL;
@@ -171,14 +172,10 @@ static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
*/
int snd_ac97_codec_driver_register(struct ac97_codec_driver *drv)
{
- int ret;
-
drv->driver.bus = &ac97_bus_type;
- ret = driver_register(&drv->driver);
-
- return ret;
+ return driver_register(&drv->driver);
}
-EXPORT_SYMBOL(snd_ac97_codec_driver_register);
+EXPORT_SYMBOL_GPL(snd_ac97_codec_driver_register);
/**
* snd_ac97_codec_driver_unregister - unregister an AC97 codec driver
@@ -190,7 +187,7 @@ void snd_ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
{
driver_unregister(&drv->driver);
}
-EXPORT_SYMBOL(snd_ac97_codec_driver_unregister);
+EXPORT_SYMBOL_GPL(snd_ac97_codec_driver_unregister);
/**
* snd_ac97_codec_get_platdata - get platform_data
@@ -208,7 +205,7 @@ void *snd_ac97_codec_get_platdata(const struct ac97_codec_device *adev)
return ac97_ctrl->codecs_pdata[adev->num];
}
-EXPORT_SYMBOL(snd_ac97_codec_get_platdata);
+EXPORT_SYMBOL_GPL(snd_ac97_codec_get_platdata);
static void ac97_ctrl_codecs_unregister(struct ac97_controller *ac97_ctrl)
{
@@ -359,7 +356,7 @@ struct ac97_controller *snd_ac97_controller_register(
kfree(ac97_ctrl);
return ERR_PTR(ret);
}
-EXPORT_SYMBOL(snd_ac97_controller_register);
+EXPORT_SYMBOL_GPL(snd_ac97_controller_register);
/**
* snd_ac97_controller_unregister - unregister an ac97 controller
@@ -370,7 +367,7 @@ void snd_ac97_controller_unregister(struct ac97_controller *ac97_ctrl)
{
ac97_del_adapter(ac97_ctrl);
}
-EXPORT_SYMBOL(snd_ac97_controller_unregister);
+EXPORT_SYMBOL_GPL(snd_ac97_controller_unregister);
#ifdef CONFIG_PM
static int ac97_pm_runtime_suspend(struct device *dev)
@@ -466,7 +463,7 @@ static int ac97_bus_match(struct device *dev, struct device_driver *drv)
return false;
do {
- if ((id[i].id & id->mask) == (adev->vendor_id & id[i].mask))
+ if (ac97_ids_match(id[i].id, adev->vendor_id, id[i].mask))
return true;
} while (id[i++].id);
@@ -88,16 +88,19 @@ int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
{
struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
struct ac97_controller *actrl = adev->ac97_ctrl;
+ unsigned int scanned;
if (try_warm) {
compat_ac97_warm_reset(ac97);
- if (snd_ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
+ scanned = snd_ac97_bus_scan_one(actrl, adev->num);
+ if (ac97_ids_match(scanned, adev->vendor_id, id_mask))
return 1;
}
compat_ac97_reset(ac97);
compat_ac97_warm_reset(ac97);
- if (snd_ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
+ scanned = snd_ac97_bus_scan_one(actrl, adev->num);
+ if (ac97_ids_match(scanned, adev->vendor_id, id_mask))
return 0;
return -ENODEV;