2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
11 * This file contains the implementation of the Sample Rate Convertor
12 * resource management object.
20 #include "cthardware.h"
21 #include <linux/slab.h>
23 #define SRC_RESOURCE_NUM 256
24 #define SRCIMP_RESOURCE_NUM 256
26 static unsigned int conj_mask
;
28 static int src_default_config_memrd(struct src
*src
);
29 static int src_default_config_memwr(struct src
*src
);
30 static int src_default_config_arcrw(struct src
*src
);
32 static int (*src_default_config
[3])(struct src
*) = {
33 [MEMRD
] = src_default_config_memrd
,
34 [MEMWR
] = src_default_config_memwr
,
35 [ARCRW
] = src_default_config_arcrw
38 static int src_set_state(struct src
*src
, unsigned int state
)
43 hw
->src_set_state(src
->rsc
.ctrl_blk
, state
);
48 static int src_set_bm(struct src
*src
, unsigned int bm
)
53 hw
->src_set_bm(src
->rsc
.ctrl_blk
, bm
);
58 static int src_set_sf(struct src
*src
, unsigned int sf
)
63 hw
->src_set_sf(src
->rsc
.ctrl_blk
, sf
);
68 static int src_set_pm(struct src
*src
, unsigned int pm
)
73 hw
->src_set_pm(src
->rsc
.ctrl_blk
, pm
);
78 static int src_set_rom(struct src
*src
, unsigned int rom
)
83 hw
->src_set_rom(src
->rsc
.ctrl_blk
, rom
);
88 static int src_set_vo(struct src
*src
, unsigned int vo
)
93 hw
->src_set_vo(src
->rsc
.ctrl_blk
, vo
);
98 static int src_set_st(struct src
*src
, unsigned int st
)
103 hw
->src_set_st(src
->rsc
.ctrl_blk
, st
);
108 static int src_set_bp(struct src
*src
, unsigned int bp
)
113 hw
->src_set_bp(src
->rsc
.ctrl_blk
, bp
);
118 static int src_set_cisz(struct src
*src
, unsigned int cisz
)
123 hw
->src_set_cisz(src
->rsc
.ctrl_blk
, cisz
);
128 static int src_set_ca(struct src
*src
, unsigned int ca
)
133 hw
->src_set_ca(src
->rsc
.ctrl_blk
, ca
);
138 static int src_set_sa(struct src
*src
, unsigned int sa
)
143 hw
->src_set_sa(src
->rsc
.ctrl_blk
, sa
);
148 static int src_set_la(struct src
*src
, unsigned int la
)
153 hw
->src_set_la(src
->rsc
.ctrl_blk
, la
);
158 static int src_set_pitch(struct src
*src
, unsigned int pitch
)
163 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, pitch
);
168 static int src_set_clear_zbufs(struct src
*src
)
173 hw
->src_set_clear_zbufs(src
->rsc
.ctrl_blk
, 1);
178 static int src_commit_write(struct src
*src
)
182 unsigned int dirty
= 0;
185 src
->rsc
.ops
->master(&src
->rsc
);
186 if (src
->rsc
.msr
> 1) {
187 /* Save dirty flags for conjugate resource programming */
188 dirty
= hw
->src_get_dirty(src
->rsc
.ctrl_blk
) & conj_mask
;
190 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
193 /* Program conjugate parameter mixer resources */
194 if (MEMWR
== src
->mode
)
197 for (i
= 1; i
< src
->rsc
.msr
; i
++) {
198 src
->rsc
.ops
->next_conj(&src
->rsc
);
199 hw
->src_set_dirty(src
->rsc
.ctrl_blk
, dirty
);
200 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
203 src
->rsc
.ops
->master(&src
->rsc
);
208 static int src_get_ca(struct src
*src
)
213 return hw
->src_get_ca(hw
, src
->rsc
.ops
->index(&src
->rsc
),
217 static int src_init(struct src
*src
)
219 src_default_config
[src
->mode
](src
);
224 static struct src
*src_next_interleave(struct src
*src
)
229 static int src_default_config_memrd(struct src
*src
)
231 struct hw
*hw
= src
->rsc
.hw
;
232 unsigned int rsr
, msr
;
234 hw
->src_set_state(src
->rsc
.ctrl_blk
, SRC_STATE_OFF
);
235 hw
->src_set_bm(src
->rsc
.ctrl_blk
, 1);
236 for (rsr
= 0, msr
= src
->rsc
.msr
; msr
> 1; msr
>>= 1)
239 hw
->src_set_rsr(src
->rsc
.ctrl_blk
, rsr
);
240 hw
->src_set_sf(src
->rsc
.ctrl_blk
, SRC_SF_S16
);
241 hw
->src_set_wr(src
->rsc
.ctrl_blk
, 0);
242 hw
->src_set_pm(src
->rsc
.ctrl_blk
, 0);
243 hw
->src_set_rom(src
->rsc
.ctrl_blk
, 0);
244 hw
->src_set_vo(src
->rsc
.ctrl_blk
, 0);
245 hw
->src_set_st(src
->rsc
.ctrl_blk
, 0);
246 hw
->src_set_ilsz(src
->rsc
.ctrl_blk
, src
->multi
- 1);
247 hw
->src_set_cisz(src
->rsc
.ctrl_blk
, 0x80);
248 hw
->src_set_sa(src
->rsc
.ctrl_blk
, 0x0);
249 hw
->src_set_la(src
->rsc
.ctrl_blk
, 0x1000);
250 hw
->src_set_ca(src
->rsc
.ctrl_blk
, 0x80);
251 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, 0x1000000);
252 hw
->src_set_clear_zbufs(src
->rsc
.ctrl_blk
, 1);
254 src
->rsc
.ops
->master(&src
->rsc
);
255 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
258 for (msr
= 1; msr
< src
->rsc
.msr
; msr
++) {
259 src
->rsc
.ops
->next_conj(&src
->rsc
);
260 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, 0x1000000);
261 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
264 src
->rsc
.ops
->master(&src
->rsc
);
269 static int src_default_config_memwr(struct src
*src
)
271 struct hw
*hw
= src
->rsc
.hw
;
273 hw
->src_set_state(src
->rsc
.ctrl_blk
, SRC_STATE_OFF
);
274 hw
->src_set_bm(src
->rsc
.ctrl_blk
, 1);
275 hw
->src_set_rsr(src
->rsc
.ctrl_blk
, 0);
276 hw
->src_set_sf(src
->rsc
.ctrl_blk
, SRC_SF_S16
);
277 hw
->src_set_wr(src
->rsc
.ctrl_blk
, 1);
278 hw
->src_set_pm(src
->rsc
.ctrl_blk
, 0);
279 hw
->src_set_rom(src
->rsc
.ctrl_blk
, 0);
280 hw
->src_set_vo(src
->rsc
.ctrl_blk
, 0);
281 hw
->src_set_st(src
->rsc
.ctrl_blk
, 0);
282 hw
->src_set_ilsz(src
->rsc
.ctrl_blk
, 0);
283 hw
->src_set_cisz(src
->rsc
.ctrl_blk
, 0x80);
284 hw
->src_set_sa(src
->rsc
.ctrl_blk
, 0x0);
285 hw
->src_set_la(src
->rsc
.ctrl_blk
, 0x1000);
286 hw
->src_set_ca(src
->rsc
.ctrl_blk
, 0x80);
287 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, 0x1000000);
288 hw
->src_set_clear_zbufs(src
->rsc
.ctrl_blk
, 1);
290 src
->rsc
.ops
->master(&src
->rsc
);
291 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
297 static int src_default_config_arcrw(struct src
*src
)
299 struct hw
*hw
= src
->rsc
.hw
;
300 unsigned int rsr
, msr
;
303 hw
->src_set_state(src
->rsc
.ctrl_blk
, SRC_STATE_OFF
);
304 hw
->src_set_bm(src
->rsc
.ctrl_blk
, 0);
305 for (rsr
= 0, msr
= src
->rsc
.msr
; msr
> 1; msr
>>= 1)
308 hw
->src_set_rsr(src
->rsc
.ctrl_blk
, rsr
);
309 hw
->src_set_sf(src
->rsc
.ctrl_blk
, SRC_SF_F32
);
310 hw
->src_set_wr(src
->rsc
.ctrl_blk
, 0);
311 hw
->src_set_pm(src
->rsc
.ctrl_blk
, 0);
312 hw
->src_set_rom(src
->rsc
.ctrl_blk
, 0);
313 hw
->src_set_vo(src
->rsc
.ctrl_blk
, 0);
314 hw
->src_set_st(src
->rsc
.ctrl_blk
, 0);
315 hw
->src_set_ilsz(src
->rsc
.ctrl_blk
, 0);
316 hw
->src_set_cisz(src
->rsc
.ctrl_blk
, 0x80);
317 hw
->src_set_sa(src
->rsc
.ctrl_blk
, 0x0);
318 /*hw->src_set_sa(src->rsc.ctrl_blk, 0x100);*/
319 hw
->src_set_la(src
->rsc
.ctrl_blk
, 0x1000);
320 /*hw->src_set_la(src->rsc.ctrl_blk, 0x03ffffe0);*/
321 hw
->src_set_ca(src
->rsc
.ctrl_blk
, 0x80);
322 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, 0x1000000);
323 hw
->src_set_clear_zbufs(src
->rsc
.ctrl_blk
, 1);
325 dirty
= hw
->src_get_dirty(src
->rsc
.ctrl_blk
);
326 src
->rsc
.ops
->master(&src
->rsc
);
327 for (msr
= 0; msr
< src
->rsc
.msr
; msr
++) {
328 hw
->src_set_dirty(src
->rsc
.ctrl_blk
, dirty
);
329 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
331 src
->rsc
.ops
->next_conj(&src
->rsc
);
333 src
->rsc
.ops
->master(&src
->rsc
);
338 static struct src_rsc_ops src_rsc_ops
= {
339 .set_state
= src_set_state
,
340 .set_bm
= src_set_bm
,
341 .set_sf
= src_set_sf
,
342 .set_pm
= src_set_pm
,
343 .set_rom
= src_set_rom
,
344 .set_vo
= src_set_vo
,
345 .set_st
= src_set_st
,
346 .set_bp
= src_set_bp
,
347 .set_cisz
= src_set_cisz
,
348 .set_ca
= src_set_ca
,
349 .set_sa
= src_set_sa
,
350 .set_la
= src_set_la
,
351 .set_pitch
= src_set_pitch
,
352 .set_clr_zbufs
= src_set_clear_zbufs
,
353 .commit_write
= src_commit_write
,
354 .get_ca
= src_get_ca
,
356 .next_interleave
= src_next_interleave
,
360 src_rsc_init(struct src
*src
, u32 idx
,
361 const struct src_desc
*desc
, struct src_mgr
*mgr
)
367 n
= (MEMRD
== desc
->mode
) ? desc
->multi
: 1;
368 for (i
= 0, p
= src
; i
< n
; i
++, p
++) {
369 err
= rsc_init(&p
->rsc
, idx
+ i
, SRC
, desc
->msr
, mgr
->mgr
.hw
);
373 /* Initialize src specific rsc operations */
374 p
->ops
= &src_rsc_ops
;
375 p
->multi
= (0 == i
) ? desc
->multi
: 1;
376 p
->mode
= desc
->mode
;
377 src_default_config
[desc
->mode
](p
);
378 mgr
->src_enable(mgr
, p
);
381 (--p
)->intlv
= NULL
; /* Set @intlv of the last SRC to NULL */
383 mgr
->commit_write(mgr
);
388 for (i
--, p
--; i
>= 0; i
--, p
--) {
389 mgr
->src_disable(mgr
, p
);
392 mgr
->commit_write(mgr
);
396 static int src_rsc_uninit(struct src
*src
, struct src_mgr
*mgr
)
401 n
= (MEMRD
== src
->mode
) ? src
->multi
: 1;
402 for (i
= 0, p
= src
; i
< n
; i
++, p
++) {
403 mgr
->src_disable(mgr
, p
);
407 p
->mode
= NUM_SRCMODES
;
410 mgr
->commit_write(mgr
);
416 get_src_rsc(struct src_mgr
*mgr
, const struct src_desc
*desc
, struct src
**rsrc
)
418 unsigned int idx
= SRC_RESOURCE_NUM
;
425 /* Check whether there are sufficient src resources to meet request. */
426 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
427 if (MEMRD
== desc
->mode
)
428 err
= mgr_get_resource(&mgr
->mgr
, desc
->multi
, &idx
);
430 err
= mgr_get_resource(&mgr
->mgr
, 1, &idx
);
432 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
434 printk(KERN_ERR
"ctxfi: Can't meet SRC resource request!\n");
438 /* Allocate mem for master src resource */
439 if (MEMRD
== desc
->mode
)
440 src
= kcalloc(desc
->multi
, sizeof(*src
), GFP_KERNEL
);
442 src
= kzalloc(sizeof(*src
), GFP_KERNEL
);
449 err
= src_rsc_init(src
, idx
, desc
, mgr
);
460 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
461 if (MEMRD
== desc
->mode
)
462 mgr_put_resource(&mgr
->mgr
, desc
->multi
, idx
);
464 mgr_put_resource(&mgr
->mgr
, 1, idx
);
466 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
470 static int put_src_rsc(struct src_mgr
*mgr
, struct src
*src
)
474 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
475 src
->rsc
.ops
->master(&src
->rsc
);
476 if (MEMRD
== src
->mode
)
477 mgr_put_resource(&mgr
->mgr
, src
->multi
,
478 src
->rsc
.ops
->index(&src
->rsc
));
480 mgr_put_resource(&mgr
->mgr
, 1, src
->rsc
.ops
->index(&src
->rsc
));
482 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
483 src_rsc_uninit(src
, mgr
);
489 static int src_enable_s(struct src_mgr
*mgr
, struct src
*src
)
491 struct hw
*hw
= mgr
->mgr
.hw
;
494 src
->rsc
.ops
->master(&src
->rsc
);
495 for (i
= 0; i
< src
->rsc
.msr
; i
++) {
496 hw
->src_mgr_enbs_src(mgr
->mgr
.ctrl_blk
,
497 src
->rsc
.ops
->index(&src
->rsc
));
498 src
->rsc
.ops
->next_conj(&src
->rsc
);
500 src
->rsc
.ops
->master(&src
->rsc
);
505 static int src_enable(struct src_mgr
*mgr
, struct src
*src
)
507 struct hw
*hw
= mgr
->mgr
.hw
;
510 src
->rsc
.ops
->master(&src
->rsc
);
511 for (i
= 0; i
< src
->rsc
.msr
; i
++) {
512 hw
->src_mgr_enb_src(mgr
->mgr
.ctrl_blk
,
513 src
->rsc
.ops
->index(&src
->rsc
));
514 src
->rsc
.ops
->next_conj(&src
->rsc
);
516 src
->rsc
.ops
->master(&src
->rsc
);
521 static int src_disable(struct src_mgr
*mgr
, struct src
*src
)
523 struct hw
*hw
= mgr
->mgr
.hw
;
526 src
->rsc
.ops
->master(&src
->rsc
);
527 for (i
= 0; i
< src
->rsc
.msr
; i
++) {
528 hw
->src_mgr_dsb_src(mgr
->mgr
.ctrl_blk
,
529 src
->rsc
.ops
->index(&src
->rsc
));
530 src
->rsc
.ops
->next_conj(&src
->rsc
);
532 src
->rsc
.ops
->master(&src
->rsc
);
537 static int src_mgr_commit_write(struct src_mgr
*mgr
)
539 struct hw
*hw
= mgr
->mgr
.hw
;
541 hw
->src_mgr_commit_write(hw
, mgr
->mgr
.ctrl_blk
);
546 int src_mgr_create(void *hw
, struct src_mgr
**rsrc_mgr
)
549 struct src_mgr
*src_mgr
;
552 src_mgr
= kzalloc(sizeof(*src_mgr
), GFP_KERNEL
);
556 err
= rsc_mgr_init(&src_mgr
->mgr
, SRC
, SRC_RESOURCE_NUM
, hw
);
560 spin_lock_init(&src_mgr
->mgr_lock
);
561 conj_mask
= ((struct hw
*)hw
)->src_dirty_conj_mask();
563 src_mgr
->get_src
= get_src_rsc
;
564 src_mgr
->put_src
= put_src_rsc
;
565 src_mgr
->src_enable_s
= src_enable_s
;
566 src_mgr
->src_enable
= src_enable
;
567 src_mgr
->src_disable
= src_disable
;
568 src_mgr
->commit_write
= src_mgr_commit_write
;
570 /* Disable all SRC resources. */
571 for (i
= 0; i
< 256; i
++)
572 ((struct hw
*)hw
)->src_mgr_dsb_src(src_mgr
->mgr
.ctrl_blk
, i
);
574 ((struct hw
*)hw
)->src_mgr_commit_write(hw
, src_mgr
->mgr
.ctrl_blk
);
585 int src_mgr_destroy(struct src_mgr
*src_mgr
)
587 rsc_mgr_uninit(&src_mgr
->mgr
);
593 /* SRCIMP resource manager operations */
595 static int srcimp_master(struct rsc
*rsc
)
598 return rsc
->idx
= container_of(rsc
, struct srcimp
, rsc
)->idx
[0];
601 static int srcimp_next_conj(struct rsc
*rsc
)
604 return container_of(rsc
, struct srcimp
, rsc
)->idx
[rsc
->conj
];
607 static int srcimp_index(const struct rsc
*rsc
)
609 return container_of(rsc
, struct srcimp
, rsc
)->idx
[rsc
->conj
];
612 static struct rsc_ops srcimp_basic_rsc_ops
= {
613 .master
= srcimp_master
,
614 .next_conj
= srcimp_next_conj
,
615 .index
= srcimp_index
,
619 static int srcimp_map(struct srcimp
*srcimp
, struct src
*src
, struct rsc
*input
)
621 struct imapper
*entry
;
624 srcimp
->rsc
.ops
->master(&srcimp
->rsc
);
625 src
->rsc
.ops
->master(&src
->rsc
);
626 input
->ops
->master(input
);
628 /* Program master and conjugate resources */
629 for (i
= 0; i
< srcimp
->rsc
.msr
; i
++) {
630 entry
= &srcimp
->imappers
[i
];
631 entry
->slot
= input
->ops
->output_slot(input
);
632 entry
->user
= src
->rsc
.ops
->index(&src
->rsc
);
633 entry
->addr
= srcimp
->rsc
.ops
->index(&srcimp
->rsc
);
634 srcimp
->mgr
->imap_add(srcimp
->mgr
, entry
);
635 srcimp
->mapped
|= (0x1 << i
);
637 srcimp
->rsc
.ops
->next_conj(&srcimp
->rsc
);
638 input
->ops
->next_conj(input
);
641 srcimp
->rsc
.ops
->master(&srcimp
->rsc
);
642 input
->ops
->master(input
);
647 static int srcimp_unmap(struct srcimp
*srcimp
)
651 /* Program master and conjugate resources */
652 for (i
= 0; i
< srcimp
->rsc
.msr
; i
++) {
653 if (srcimp
->mapped
& (0x1 << i
)) {
654 srcimp
->mgr
->imap_delete(srcimp
->mgr
,
655 &srcimp
->imappers
[i
]);
656 srcimp
->mapped
&= ~(0x1 << i
);
663 static struct srcimp_rsc_ops srcimp_ops
= {
665 .unmap
= srcimp_unmap
668 static int srcimp_rsc_init(struct srcimp
*srcimp
,
669 const struct srcimp_desc
*desc
,
670 struct srcimp_mgr
*mgr
)
674 err
= rsc_init(&srcimp
->rsc
, srcimp
->idx
[0],
675 SRCIMP
, desc
->msr
, mgr
->mgr
.hw
);
679 /* Reserve memory for imapper nodes */
680 srcimp
->imappers
= kzalloc(sizeof(struct imapper
)*desc
->msr
,
682 if (!srcimp
->imappers
) {
687 /* Set srcimp specific operations */
688 srcimp
->rsc
.ops
= &srcimp_basic_rsc_ops
;
689 srcimp
->ops
= &srcimp_ops
;
692 srcimp
->rsc
.ops
->master(&srcimp
->rsc
);
697 rsc_uninit(&srcimp
->rsc
);
701 static int srcimp_rsc_uninit(struct srcimp
*srcimp
)
703 if (NULL
!= srcimp
->imappers
) {
704 kfree(srcimp
->imappers
);
705 srcimp
->imappers
= NULL
;
709 rsc_uninit(&srcimp
->rsc
);
714 static int get_srcimp_rsc(struct srcimp_mgr
*mgr
,
715 const struct srcimp_desc
*desc
,
716 struct srcimp
**rsrcimp
)
720 struct srcimp
*srcimp
;
725 /* Allocate mem for SRCIMP resource */
726 srcimp
= kzalloc(sizeof(*srcimp
), GFP_KERNEL
);
730 /* Check whether there are sufficient SRCIMP resources. */
732 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
733 for (i
= 0; i
< desc
->msr
; i
++) {
734 err
= mgr_get_resource(&mgr
->mgr
, 1, &idx
);
738 srcimp
->idx
[i
] = idx
;
740 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
742 printk(KERN_ERR
"ctxfi: Can't meet SRCIMP resource request!\n");
746 err
= srcimp_rsc_init(srcimp
, desc
, mgr
);
755 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
756 for (i
--; i
>= 0; i
--)
757 mgr_put_resource(&mgr
->mgr
, 1, srcimp
->idx
[i
]);
759 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
764 static int put_srcimp_rsc(struct srcimp_mgr
*mgr
, struct srcimp
*srcimp
)
769 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
770 for (i
= 0; i
< srcimp
->rsc
.msr
; i
++)
771 mgr_put_resource(&mgr
->mgr
, 1, srcimp
->idx
[i
]);
773 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
774 srcimp_rsc_uninit(srcimp
);
780 static int srcimp_map_op(void *data
, struct imapper
*entry
)
782 struct rsc_mgr
*mgr
= &((struct srcimp_mgr
*)data
)->mgr
;
783 struct hw
*hw
= mgr
->hw
;
785 hw
->srcimp_mgr_set_imaparc(mgr
->ctrl_blk
, entry
->slot
);
786 hw
->srcimp_mgr_set_imapuser(mgr
->ctrl_blk
, entry
->user
);
787 hw
->srcimp_mgr_set_imapnxt(mgr
->ctrl_blk
, entry
->next
);
788 hw
->srcimp_mgr_set_imapaddr(mgr
->ctrl_blk
, entry
->addr
);
789 hw
->srcimp_mgr_commit_write(mgr
->hw
, mgr
->ctrl_blk
);
794 static int srcimp_imap_add(struct srcimp_mgr
*mgr
, struct imapper
*entry
)
799 spin_lock_irqsave(&mgr
->imap_lock
, flags
);
800 if ((0 == entry
->addr
) && (mgr
->init_imap_added
)) {
801 input_mapper_delete(&mgr
->imappers
,
802 mgr
->init_imap
, srcimp_map_op
, mgr
);
803 mgr
->init_imap_added
= 0;
805 err
= input_mapper_add(&mgr
->imappers
, entry
, srcimp_map_op
, mgr
);
806 spin_unlock_irqrestore(&mgr
->imap_lock
, flags
);
811 static int srcimp_imap_delete(struct srcimp_mgr
*mgr
, struct imapper
*entry
)
816 spin_lock_irqsave(&mgr
->imap_lock
, flags
);
817 err
= input_mapper_delete(&mgr
->imappers
, entry
, srcimp_map_op
, mgr
);
818 if (list_empty(&mgr
->imappers
)) {
819 input_mapper_add(&mgr
->imappers
, mgr
->init_imap
,
821 mgr
->init_imap_added
= 1;
823 spin_unlock_irqrestore(&mgr
->imap_lock
, flags
);
828 int srcimp_mgr_create(void *hw
, struct srcimp_mgr
**rsrcimp_mgr
)
831 struct srcimp_mgr
*srcimp_mgr
;
832 struct imapper
*entry
;
835 srcimp_mgr
= kzalloc(sizeof(*srcimp_mgr
), GFP_KERNEL
);
839 err
= rsc_mgr_init(&srcimp_mgr
->mgr
, SRCIMP
, SRCIMP_RESOURCE_NUM
, hw
);
843 spin_lock_init(&srcimp_mgr
->mgr_lock
);
844 spin_lock_init(&srcimp_mgr
->imap_lock
);
845 INIT_LIST_HEAD(&srcimp_mgr
->imappers
);
846 entry
= kzalloc(sizeof(*entry
), GFP_KERNEL
);
851 entry
->slot
= entry
->addr
= entry
->next
= entry
->user
= 0;
852 list_add(&entry
->list
, &srcimp_mgr
->imappers
);
853 srcimp_mgr
->init_imap
= entry
;
854 srcimp_mgr
->init_imap_added
= 1;
856 srcimp_mgr
->get_srcimp
= get_srcimp_rsc
;
857 srcimp_mgr
->put_srcimp
= put_srcimp_rsc
;
858 srcimp_mgr
->imap_add
= srcimp_imap_add
;
859 srcimp_mgr
->imap_delete
= srcimp_imap_delete
;
861 *rsrcimp_mgr
= srcimp_mgr
;
866 rsc_mgr_uninit(&srcimp_mgr
->mgr
);
872 int srcimp_mgr_destroy(struct srcimp_mgr
*srcimp_mgr
)
876 /* free src input mapper list */
877 spin_lock_irqsave(&srcimp_mgr
->imap_lock
, flags
);
878 free_input_mapper_list(&srcimp_mgr
->imappers
);
879 spin_unlock_irqrestore(&srcimp_mgr
->imap_lock
, flags
);
881 rsc_mgr_uninit(&srcimp_mgr
->mgr
);