~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/sh/rcar/ssiu.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 //
  3 // Renesas R-Car SSIU support
  4 //
  5 // Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  6 
  7 #include "rsnd.h"
  8 
  9 #define SSIU_NAME "ssiu"
 10 
 11 struct rsnd_ssiu {
 12         struct rsnd_mod mod;
 13         u32 busif_status[8]; /* for BUSIF0 - BUSIF7 */
 14         unsigned int usrcnt;
 15         int id;
 16         int id_sub;
 17 };
 18 
 19 /* SSI_MODE */
 20 #define TDM_EXT         (1 << 0)
 21 #define TDM_SPLIT       (1 << 8)
 22 
 23 #define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr)
 24 #define rsnd_mod_to_ssiu(_mod) container_of((_mod), struct rsnd_ssiu, mod)
 25 #define for_each_rsnd_ssiu(pos, priv, i)                                \
 26         for (i = 0;                                                     \
 27              (i < rsnd_ssiu_nr(priv)) &&                                \
 28                      ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i));  \
 29              i++)
 30 
 31 /*
 32  *      SSI     Gen2            Gen3            Gen4
 33  *      0       BUSIF0-3        BUSIF0-7        BUSIF0-7
 34  *      1       BUSIF0-3        BUSIF0-7
 35  *      2       BUSIF0-3        BUSIF0-7
 36  *      3       BUSIF0          BUSIF0-7
 37  *      4       BUSIF0          BUSIF0-7
 38  *      5       BUSIF0          BUSIF0
 39  *      6       BUSIF0          BUSIF0
 40  *      7       BUSIF0          BUSIF0
 41  *      8       BUSIF0          BUSIF0
 42  *      9       BUSIF0-3        BUSIF0-7
 43  *      total   22              52              8
 44  */
 45 static const int gen2_id[] = { 0, 4,  8, 12, 13, 14, 15, 16, 17, 18 };
 46 static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };
 47 static const int gen4_id[] = { 0 };
 48 
 49 /* enable busif buffer over/under run interrupt. */
 50 #define rsnd_ssiu_busif_err_irq_enable(mod)  rsnd_ssiu_busif_err_irq_ctrl(mod, 1)
 51 #define rsnd_ssiu_busif_err_irq_disable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 0)
 52 static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
 53 {
 54         int id = rsnd_mod_id(mod);
 55         int shift, offset;
 56         int i;
 57 
 58         switch (id) {
 59         case 0:
 60         case 1:
 61         case 2:
 62         case 3:
 63         case 4:
 64                 shift  = id;
 65                 offset = 0;
 66                 break;
 67         case 9:
 68                 shift  = 1;
 69                 offset = 1;
 70                 break;
 71         default:
 72                 return;
 73         }
 74 
 75         for (i = 0; i < 4; i++) {
 76                 enum rsnd_reg reg = SSI_SYS_INT_ENABLE((i * 2) + offset);
 77                 u32 val = 0xf << (shift * 4);
 78                 u32 sys_int_enable = rsnd_mod_read(mod, reg);
 79 
 80                 if (enable)
 81                         sys_int_enable |= val;
 82                 else
 83                         sys_int_enable &= ~val;
 84                 rsnd_mod_write(mod, reg, sys_int_enable);
 85         }
 86 }
 87 
 88 bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
 89 {
 90         bool error = false;
 91         int id = rsnd_mod_id(mod);
 92         int shift, offset;
 93         int i;
 94 
 95         switch (id) {
 96         case 0:
 97         case 1:
 98         case 2:
 99         case 3:
100         case 4:
101                 shift  = id;
102                 offset = 0;
103                 break;
104         case 9:
105                 shift  = 1;
106                 offset = 1;
107                 break;
108         default:
109                 goto out;
110         }
111 
112         for (i = 0; i < 4; i++) {
113                 u32 reg = SSI_SYS_STATUS(i * 2) + offset;
114                 u32 status = rsnd_mod_read(mod, reg);
115                 u32 val = 0xf << (shift * 4);
116 
117                 status &= val;
118                 if (status) {
119                         struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
120                         struct device *dev = rsnd_priv_to_dev(priv);
121 
122                         rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
123                                               rsnd_mod_name(mod), status);
124                         error = true;
125                 }
126                 rsnd_mod_write(mod, reg, val);
127         }
128 out:
129         return error;
130 }
131 
132 static u32 *rsnd_ssiu_get_status(struct rsnd_mod *mod,
133                                  struct rsnd_dai_stream *io,
134                                  enum rsnd_mod_type type)
135 {
136         struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
137         int busif = rsnd_mod_id_sub(mod);
138 
139         return &ssiu->busif_status[busif];
140 }
141 
142 static int rsnd_ssiu_init(struct rsnd_mod *mod,
143                           struct rsnd_dai_stream *io,
144                           struct rsnd_priv *priv)
145 {
146         struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
147         u32 ssis = rsnd_ssi_multi_secondaries_runtime(io);
148         int use_busif = rsnd_ssi_use_busif(io);
149         int id = rsnd_mod_id(mod);
150         int is_clk_master = rsnd_rdai_is_clk_master(rdai);
151         u32 val1, val2;
152 
153         /* clear status */
154         rsnd_ssiu_busif_err_status_clear(mod);
155 
156         /* Gen4 doesn't have SSI_MODE */
157         if (rsnd_is_gen4(priv))
158                 goto ssi_mode_setting_end;
159 
160         /*
161          * SSI_MODE0
162          */
163         rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
164 
165         /*
166          * SSI_MODE1 / SSI_MODE2
167          *
168          * FIXME
169          * sharing/multi with SSI0 are mainly supported
170          */
171         val1 = rsnd_mod_read(mod, SSI_MODE1);
172         val2 = rsnd_mod_read(mod, SSI_MODE2);
173         if (rsnd_ssi_is_pin_sharing(io)) {
174 
175                 ssis |= (1 << id);
176 
177         } else if (ssis) {
178                 /*
179                  * Multi SSI
180                  *
181                  * set synchronized bit here
182                  */
183 
184                 /* SSI4 is synchronized with SSI3 */
185                 if (ssis & (1 << 4))
186                         val1 |= (1 << 20);
187                 /* SSI012 are synchronized */
188                 if (ssis == 0x0006)
189                         val1 |= (1 << 4);
190                 /* SSI0129 are synchronized */
191                 if (ssis == 0x0206)
192                         val2 |= (1 << 4);
193         }
194 
195         /* SSI1 is sharing pin with SSI0 */
196         if (ssis & (1 << 1))
197                 val1 |= is_clk_master ? 0x2 : 0x1;
198 
199         /* SSI2 is sharing pin with SSI0 */
200         if (ssis & (1 << 2))
201                 val1 |= is_clk_master ? 0x2 << 2 :
202                                         0x1 << 2;
203         /* SSI4 is sharing pin with SSI3 */
204         if (ssis & (1 << 4))
205                 val1 |= is_clk_master ? 0x2 << 16 :
206                                         0x1 << 16;
207         /* SSI9 is sharing pin with SSI0 */
208         if (ssis & (1 << 9))
209                 val2 |= is_clk_master ? 0x2 : 0x1;
210 
211         rsnd_mod_bset(mod, SSI_MODE1, 0x0013001f, val1);
212         rsnd_mod_bset(mod, SSI_MODE2, 0x00000017, val2);
213 
214 ssi_mode_setting_end:
215         /*
216          * Enable busif buffer over/under run interrupt.
217          * It will be handled from ssi.c
218          * see
219          *      __rsnd_ssi_interrupt()
220          */
221         rsnd_ssiu_busif_err_irq_enable(mod);
222 
223         return 0;
224 }
225 
226 static int rsnd_ssiu_quit(struct rsnd_mod *mod,
227                           struct rsnd_dai_stream *io,
228                           struct rsnd_priv *priv)
229 {
230         /* disable busif buffer over/under run interrupt. */
231         rsnd_ssiu_busif_err_irq_disable(mod);
232 
233         return 0;
234 }
235 
236 static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
237         .name           = SSIU_NAME,
238         .init           = rsnd_ssiu_init,
239         .quit           = rsnd_ssiu_quit,
240         .get_status     = rsnd_ssiu_get_status,
241 };
242 
243 static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
244                                struct rsnd_dai_stream *io,
245                                struct rsnd_priv *priv)
246 {
247         struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
248         u32 has_hdmi0 = rsnd_flags_has(io, RSND_STREAM_HDMI0);
249         u32 has_hdmi1 = rsnd_flags_has(io, RSND_STREAM_HDMI1);
250         int ret;
251         u32 mode = 0;
252 
253         ret = rsnd_ssiu_init(mod, io, priv);
254         if (ret < 0)
255                 return ret;
256 
257         ssiu->usrcnt++;
258 
259         /*
260          * TDM Extend/Split Mode
261          * see
262          *      rsnd_ssi_config_init()
263          */
264         if (rsnd_runtime_is_tdm(io))
265                 mode = TDM_EXT;
266         else if (rsnd_runtime_is_tdm_split(io))
267                 mode = TDM_SPLIT;
268 
269         rsnd_mod_write(mod, SSI_MODE, mode);
270 
271         if (rsnd_ssi_use_busif(io)) {
272                 int id = rsnd_mod_id(mod);
273                 int busif = rsnd_mod_id_sub(mod);
274                 enum rsnd_reg adinr_reg, mode_reg, dalign_reg;
275 
276                 if ((id == 9) && (busif >= 4)) {
277                         adinr_reg = SSI9_BUSIF_ADINR(busif);
278                         mode_reg = SSI9_BUSIF_MODE(busif);
279                         dalign_reg = SSI9_BUSIF_DALIGN(busif);
280                 } else {
281                         adinr_reg = SSI_BUSIF_ADINR(busif);
282                         mode_reg = SSI_BUSIF_MODE(busif);
283                         dalign_reg = SSI_BUSIF_DALIGN(busif);
284                 }
285 
286                 rsnd_mod_write(mod, adinr_reg,
287                                rsnd_get_adinr_bit(mod, io) |
288                                (rsnd_io_is_play(io) ?
289                                 rsnd_runtime_channel_after_ctu(io) :
290                                 rsnd_runtime_channel_original(io)));
291                 rsnd_mod_write(mod, mode_reg,
292                                rsnd_get_busif_shift(io, mod) | 1);
293                 rsnd_mod_write(mod, dalign_reg,
294                                rsnd_get_dalign(mod, io));
295         }
296 
297         if (has_hdmi0 || has_hdmi1) {
298                 enum rsnd_mod_type rsnd_ssi_array[] = {
299                         RSND_MOD_SSIM1,
300                         RSND_MOD_SSIM2,
301                         RSND_MOD_SSIM3,
302                 };
303                 struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
304                 struct rsnd_mod *pos;
305                 u32 val;
306                 int i;
307 
308                 i = rsnd_mod_id(ssi_mod);
309 
310                 /* output all same SSI as default */
311                 val =   i << 16 |
312                         i << 20 |
313                         i << 24 |
314                         i << 28 |
315                         i;
316 
317                 for_each_rsnd_mod_array(i, pos, io, rsnd_ssi_array) {
318                         int shift = (i * 4) + 20;
319 
320                         val     = (val & ~(0xF << shift)) |
321                                 rsnd_mod_id(pos) << shift;
322                 }
323 
324                 if (has_hdmi0)
325                         rsnd_mod_write(mod, HDMI0_SEL, val);
326                 if (has_hdmi1)
327                         rsnd_mod_write(mod, HDMI1_SEL, val);
328         }
329 
330         return 0;
331 }
332 
333 static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
334                                 struct rsnd_dai_stream *io,
335                                 struct rsnd_priv *priv)
336 {
337         int busif = rsnd_mod_id_sub(mod);
338 
339         if (!rsnd_ssi_use_busif(io))
340                 return 0;
341 
342         rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 1 << (busif * 4));
343 
344         if (rsnd_ssi_multi_secondaries_runtime(io))
345                 rsnd_mod_write(mod, SSI_CONTROL, 0x1);
346 
347         return 0;
348 }
349 
350 static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
351                                struct rsnd_dai_stream *io,
352                                struct rsnd_priv *priv)
353 {
354         struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
355         int busif = rsnd_mod_id_sub(mod);
356 
357         if (!rsnd_ssi_use_busif(io))
358                 return 0;
359 
360         rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 0);
361 
362         if (--ssiu->usrcnt)
363                 return 0;
364 
365         if (rsnd_ssi_multi_secondaries_runtime(io))
366                 rsnd_mod_write(mod, SSI_CONTROL, 0);
367 
368         return 0;
369 }
370 
371 static int rsnd_ssiu_id(struct rsnd_mod *mod)
372 {
373         struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
374 
375         /* see rsnd_ssiu_probe() */
376         return ssiu->id;
377 }
378 
379 static int rsnd_ssiu_id_sub(struct rsnd_mod *mod)
380 {
381         struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
382 
383         /* see rsnd_ssiu_probe() */
384         return ssiu->id_sub;
385 }
386 
387 static struct dma_chan *rsnd_ssiu_dma_req(struct rsnd_dai_stream *io,
388                                           struct rsnd_mod *mod)
389 {
390         struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
391         int is_play = rsnd_io_is_play(io);
392         char *name;
393 
394         /*
395          * It should use "rcar_sound,ssiu" on DT.
396          * But, we need to keep compatibility for old version.
397          *
398          * If it has "rcar_sound.ssiu", it will be used.
399          * If not, "rcar_sound.ssi" will be used.
400          * see
401          *      rsnd_ssi_dma_req()
402          *      rsnd_dma_of_path()
403          */
404 
405         name = is_play ? "rx" : "tx";
406 
407         return rsnd_dma_request_channel(rsnd_ssiu_of_node(priv),
408                                         SSIU_NAME, mod, name);
409 }
410 
411 #ifdef CONFIG_DEBUG_FS
412 static void rsnd_ssiu_debug_info(struct seq_file *m,
413                                  struct rsnd_dai_stream *io,
414                                 struct rsnd_mod *mod)
415 {
416         rsnd_debugfs_mod_reg_show(m, mod, RSND_BASE_SSIU,
417                                   rsnd_mod_id(mod) * 0x80, 0x80);
418 }
419 #define DEBUG_INFO .debug_info = rsnd_ssiu_debug_info
420 #else
421 #define DEBUG_INFO
422 #endif
423 
424 static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
425         .name           = SSIU_NAME,
426         .dma_req        = rsnd_ssiu_dma_req,
427         .init           = rsnd_ssiu_init_gen2,
428         .quit           = rsnd_ssiu_quit,
429         .start          = rsnd_ssiu_start_gen2,
430         .stop           = rsnd_ssiu_stop_gen2,
431         .get_status     = rsnd_ssiu_get_status,
432         DEBUG_INFO
433 };
434 
435 static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
436 {
437         if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv)))
438                 id = 0;
439 
440         return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
441 }
442 
443 static void rsnd_parse_connect_ssiu_compatible(struct rsnd_priv *priv,
444                                                struct rsnd_dai_stream *io)
445 {
446         struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
447         struct rsnd_ssiu *ssiu;
448         int is_dma_mode;
449         int i;
450 
451         if (!ssi_mod)
452                 return;
453 
454         is_dma_mode = rsnd_ssi_is_dma_mode(ssi_mod);
455 
456         /* select BUSIF0 */
457         for_each_rsnd_ssiu(ssiu, priv, i) {
458                 struct rsnd_mod *mod = rsnd_mod_get(ssiu);
459 
460                 if (is_dma_mode &&
461                     (rsnd_mod_id(ssi_mod) == rsnd_mod_id(mod)) &&
462                     (rsnd_mod_id_sub(mod) == 0)) {
463                         rsnd_dai_connect(mod, io, mod->type);
464                         return;
465                 }
466         }
467 }
468 
469 void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
470                              struct device_node *playback,
471                              struct device_node *capture)
472 {
473         struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
474         struct device *dev = rsnd_priv_to_dev(priv);
475         struct device_node *node = rsnd_ssiu_of_node(priv);
476         struct rsnd_dai_stream *io_p = &rdai->playback;
477         struct rsnd_dai_stream *io_c = &rdai->capture;
478 
479         /* use rcar_sound,ssiu if exist */
480         if (node) {
481                 struct device_node *np;
482                 int i = 0;
483 
484                 for_each_child_of_node(node, np) {
485                         struct rsnd_mod *mod;
486 
487                         i = rsnd_node_fixed_index(dev, np, SSIU_NAME, i);
488                         if (i < 0) {
489                                 of_node_put(np);
490                                 break;
491                         }
492 
493                         mod = rsnd_ssiu_mod_get(priv, i);
494 
495                         if (np == playback)
496                                 rsnd_dai_connect(mod, io_p, mod->type);
497                         if (np == capture)
498                                 rsnd_dai_connect(mod, io_c, mod->type);
499                         i++;
500                 }
501 
502                 of_node_put(node);
503         }
504 
505         /* Keep DT compatibility */
506         if (!rsnd_io_to_mod_ssiu(io_p))
507                 rsnd_parse_connect_ssiu_compatible(priv, io_p);
508         if (!rsnd_io_to_mod_ssiu(io_c))
509                 rsnd_parse_connect_ssiu_compatible(priv, io_c);
510 }
511 
512 int rsnd_ssiu_probe(struct rsnd_priv *priv)
513 {
514         struct device *dev = rsnd_priv_to_dev(priv);
515         struct device_node *node;
516         struct rsnd_ssiu *ssiu;
517         struct rsnd_mod_ops *ops;
518         const int *list = NULL;
519         int i, nr;
520 
521         /*
522          * Keep DT compatibility.
523          * if it has "rcar_sound,ssiu", use it.
524          * if not, use "rcar_sound,ssi"
525          * see
526          *      rsnd_ssiu_bufsif_to_id()
527          */
528         node = rsnd_ssiu_of_node(priv);
529         if (node)
530                 nr = rsnd_node_count(priv, node, SSIU_NAME);
531         else
532                 nr = priv->ssi_nr;
533 
534         if (!nr)
535                 return -EINVAL;
536 
537         ssiu    = devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL);
538         if (!ssiu)
539                 return -ENOMEM;
540 
541         priv->ssiu      = ssiu;
542         priv->ssiu_nr   = nr;
543 
544         if (rsnd_is_gen1(priv))
545                 ops = &rsnd_ssiu_ops_gen1;
546         else
547                 ops = &rsnd_ssiu_ops_gen2;
548 
549         /* Keep compatibility */
550         nr = 0;
551         if ((node) &&
552             (ops == &rsnd_ssiu_ops_gen2)) {
553                 ops->id         = rsnd_ssiu_id;
554                 ops->id_sub     = rsnd_ssiu_id_sub;
555 
556                 if (rsnd_is_gen2(priv)) {
557                         list    = gen2_id;
558                         nr      = ARRAY_SIZE(gen2_id);
559                 } else if (rsnd_is_gen3(priv)) {
560                         list    = gen3_id;
561                         nr      = ARRAY_SIZE(gen3_id);
562                 } else if (rsnd_is_gen4(priv)) {
563                         list    = gen4_id;
564                         nr      = ARRAY_SIZE(gen4_id);
565                 } else {
566                         dev_err(dev, "unknown SSIU\n");
567                         return -ENODEV;
568                 }
569         }
570 
571         for_each_rsnd_ssiu(ssiu, priv, i) {
572                 int ret;
573 
574                 if (node) {
575                         int j;
576 
577                         /*
578                          * see
579                          *      rsnd_ssiu_get_id()
580                          *      rsnd_ssiu_get_id_sub()
581                          */
582                         for (j = 0; j < nr; j++) {
583                                 if (list[j] > i)
584                                         break;
585                                 ssiu->id        = j;
586                                 ssiu->id_sub    = i - list[ssiu->id];
587                         }
588                 } else {
589                         ssiu->id = i;
590                 }
591 
592                 ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
593                                     ops, NULL, RSND_MOD_SSIU, i);
594                 if (ret)
595                         return ret;
596         }
597 
598         return 0;
599 }
600 
601 void rsnd_ssiu_remove(struct rsnd_priv *priv)
602 {
603         struct rsnd_ssiu *ssiu;
604         int i;
605 
606         for_each_rsnd_ssiu(ssiu, priv, i) {
607                 rsnd_mod_quit(rsnd_mod_get(ssiu));
608         }
609 }
610 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php