[alsa-devel] [PATCH 1/3] ALSA: hda: add hdac_ext stream creation and cleanup routines
HDAC extended core should create streams for an extended bus and also free up those on cleanup. So introduce snd_hdac_ext_stream_init_all and snd_hdac_stream_free_all routines
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- include/sound/hdaudio_ext.h | 3 +++ sound/hda/ext/hdac_ext_stream.c | 50 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+)
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 202350a8eddb..877661629322 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -87,6 +87,9 @@ struct hdac_ext_stream { void snd_hdac_ext_stream_init(struct hdac_ext_bus *bus, struct hdac_ext_stream *stream, int idx, int direction, int tag); +int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx, + int num_stream, int dir); +void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus); struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_ext_bus *bus, struct snd_pcm_substream *substream, int type); diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index 0677bb65a494..f8ffbdbb450d 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c @@ -18,6 +18,7 @@ */
#include <linux/delay.h> +#include <linux/slab.h> #include <sound/pcm.h> #include <sound/hda_register.h> #include <sound/hdaudio_ext.h> @@ -54,6 +55,55 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus, EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init);
/** + * snd_hdac_ext_stream_init_all - create and initialize the stream objects + * for an extended hda bus + * @ebus: HD-audio ext core bus + * @start_idx: start index for streams + * @num_stream: number of streams to initialize + * @dir: direction of streams + */ +int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx, + int num_stream, int dir) +{ + int stream_tag = 0; + int i, tag, idx = start_idx; + + for (i = 0; i < num_stream; i++) { + struct hdac_ext_stream *stream = + kzalloc(sizeof(*stream), GFP_KERNEL); + if (!stream) + return -ENOMEM; + tag = ++stream_tag; + snd_hdac_ext_stream_init(ebus, stream, idx, dir, tag); + idx++; + } + + return 0; + +} +EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init_all); + +/** + * snd_hdac_stream_free_all - free hdac extended stream objects + * + * @ebus: HD-audio ext core bus + */ +void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus) +{ + struct hdac_stream *s; + struct hdac_ext_stream *stream; + struct hdac_bus *bus = ebus_to_hbus(ebus); + + while (!list_empty(&bus->stream_list)) { + s = list_first_entry(&bus->stream_list, struct hdac_stream, list); + stream = stream_to_hdac_ext_stream(s); + list_del(&s->list); + kfree(stream); + } +} +EXPORT_SYMBOL_GPL(snd_hdac_stream_free_all); + +/** * snd_hdac_ext_stream_decouple - decouple the hdac stream * @ebus: HD-audio ext core bus * @stream: HD-audio ext core stream object to initialize
In HDA extended bus the HDA link objects are created when multilink capabilities are parsed. We need a routine which free up these link objects for a bus. So add snd_hdac_link_free_all routine
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- include/sound/hdaudio_ext.h | 1 + sound/hda/ext/hdac_ext_controller.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+)
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 877661629322..0f89df1511dc 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -90,6 +90,7 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *bus, int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx, int num_stream, int dir); void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus); +void snd_hdac_link_free_all(struct hdac_ext_bus *ebus); struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_ext_bus *bus, struct snd_pcm_substream *substream, int type); diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index adffc89541c9..b2da19b60f4e 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -194,6 +194,24 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus) EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_ml_capabilities);
/** + * snd_hdac_link_free_all- free hdac extended link objects + * + * @ebus: HD-audio ext core bus + */ + +void snd_hdac_link_free_all(struct hdac_ext_bus *ebus) +{ + struct hdac_ext_link *l; + + while (!list_empty(&ebus->hlink_list)) { + l = list_first_entry(&ebus->hlink_list, struct hdac_ext_link, list); + list_del(&l->list); + kfree(l); + } +} +EXPORT_SYMBOL_GPL(snd_hdac_link_free_all); + +/** * snd_hdac_ext_bus_get_link_index - get link based on codec name * @ebus: HD-audio extended core bus * @codec_name: codec name
A typical io ops use simple io accessors which can be common for most drivers, so provide a default ops which will be used if driver doesn't provide one
Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/hda/ext/hdac_ext_bus.c | 59 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index f1100354c591..0aa5d9eb6c3f 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c @@ -24,12 +24,65 @@ MODULE_DESCRIPTION("HDA extended core"); MODULE_LICENSE("GPL v2");
+static void hdac_ext_writel(u32 value, u32 __iomem *addr) +{ + writel(value, addr); +} + +static u32 hdac_ext_readl(u32 __iomem *addr) +{ + return readl(addr); +} + +static void hdac_ext_writew(u16 value, u16 __iomem *addr) +{ + writew(value, addr); +} + +static u16 hdac_ext_readw(u16 __iomem *addr) +{ + return readw(addr); +} + +static void hdac_ext_writeb(u8 value, u8 __iomem *addr) +{ + writeb(value, addr); +} + +static u8 hdac_ext_readb(u8 __iomem *addr) +{ + return readb(addr); +} + +static int hdac_ext_dma_alloc_pages(struct hdac_bus *bus, int type, + size_t size, struct snd_dma_buffer *buf) +{ + return snd_dma_alloc_pages(type, bus->dev, size, buf); +} + +static void hdac_ext_dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf) +{ + snd_dma_free_pages(buf); +} + +static const struct hdac_io_ops hdac_ext_default_io = { + .reg_writel = hdac_ext_writel, + .reg_readl = hdac_ext_readl, + .reg_writew = hdac_ext_writew, + .reg_readw = hdac_ext_readw, + .reg_writeb = hdac_ext_writeb, + .reg_readb = hdac_ext_readb, + .dma_alloc_pages = hdac_ext_dma_alloc_pages, + .dma_free_pages = hdac_ext_dma_free_pages, +}; + /** * snd_hdac_ext_bus_init - initialize a HD-audio extended bus * @ebus: the pointer to extended bus object * @dev: device pointer * @ops: bus verb operators - * @io_ops: lowlevel I/O operators + * @io_ops: lowlevel I/O operators, can be NULL. If NULL core will use + * default ops * * Returns 0 if successful, or a negative error code. */ @@ -40,6 +93,10 @@ int snd_hdac_ext_bus_init(struct hdac_ext_bus *ebus, struct device *dev, int ret; static int idx;
+ /* check if io ops are provided, if not load the defaults */ + if (io_ops == NULL) + io_ops = &hdac_ext_default_io; + ret = snd_hdac_bus_init(&ebus->bus, dev, ops, io_ops); if (ret < 0) return ret;
At Wed, 17 Jun 2015 11:20:16 +0530, Vinod Koul wrote:
HDAC extended core should create streams for an extended bus and also free up those on cleanup. So introduce snd_hdac_ext_stream_init_all and snd_hdac_stream_free_all routines
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com
Applied all three patches, thanks.
Takashi
include/sound/hdaudio_ext.h | 3 +++ sound/hda/ext/hdac_ext_stream.c | 50 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+)
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 202350a8eddb..877661629322 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -87,6 +87,9 @@ struct hdac_ext_stream { void snd_hdac_ext_stream_init(struct hdac_ext_bus *bus, struct hdac_ext_stream *stream, int idx, int direction, int tag); +int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx,
int num_stream, int dir);
+void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus); struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_ext_bus *bus, struct snd_pcm_substream *substream, int type); diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index 0677bb65a494..f8ffbdbb450d 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c @@ -18,6 +18,7 @@ */
#include <linux/delay.h> +#include <linux/slab.h> #include <sound/pcm.h> #include <sound/hda_register.h> #include <sound/hdaudio_ext.h> @@ -54,6 +55,55 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus, EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init);
/**
- snd_hdac_ext_stream_init_all - create and initialize the stream objects
- for an extended hda bus
- @ebus: HD-audio ext core bus
- @start_idx: start index for streams
- @num_stream: number of streams to initialize
- @dir: direction of streams
- */
+int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx,
int num_stream, int dir)
+{
- int stream_tag = 0;
- int i, tag, idx = start_idx;
- for (i = 0; i < num_stream; i++) {
struct hdac_ext_stream *stream =
kzalloc(sizeof(*stream), GFP_KERNEL);
if (!stream)
return -ENOMEM;
tag = ++stream_tag;
snd_hdac_ext_stream_init(ebus, stream, idx, dir, tag);
idx++;
- }
- return 0;
+} +EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init_all);
+/**
- snd_hdac_stream_free_all - free hdac extended stream objects
- @ebus: HD-audio ext core bus
- */
+void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus) +{
- struct hdac_stream *s;
- struct hdac_ext_stream *stream;
- struct hdac_bus *bus = ebus_to_hbus(ebus);
- while (!list_empty(&bus->stream_list)) {
s = list_first_entry(&bus->stream_list, struct hdac_stream, list);
stream = stream_to_hdac_ext_stream(s);
list_del(&s->list);
kfree(stream);
- }
+} +EXPORT_SYMBOL_GPL(snd_hdac_stream_free_all);
+/**
- snd_hdac_ext_stream_decouple - decouple the hdac stream
- @ebus: HD-audio ext core bus
- @stream: HD-audio ext core stream object to initialize
-- 1.9.1
participants (2)
-
Takashi Iwai
-
Vinod Koul