]> git.karo-electronics.de Git - karo-tx-linux.git/blob - sound/pci/ctxfi/ctdaio.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[karo-tx-linux.git] / sound / pci / ctxfi / ctdaio.c
1 /**
2  * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3  *
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.
7  *
8  * @File        ctdaio.c
9  *
10  * @Brief
11  * This file contains the implementation of Digital Audio Input Output
12  * resource management object.
13  *
14  * @Author      Liu Chun
15  * @Date        May 23 2008
16  *
17  */
18
19 #include "ctdaio.h"
20 #include "cthardware.h"
21 #include "ctimap.h"
22 #include <linux/slab.h>
23 #include <linux/kernel.h>
24
25 #define DAIO_RESOURCE_NUM       NUM_DAIOTYP
26 #define DAIO_OUT_MAX            SPDIFOO
27
28 union daio_usage {
29         struct {
30                 unsigned short lineo1:1;
31                 unsigned short lineo2:1;
32                 unsigned short lineo3:1;
33                 unsigned short lineo4:1;
34                 unsigned short spdifoo:1;
35                 unsigned short lineim:1;
36                 unsigned short spdifio:1;
37                 unsigned short spdifi1:1;
38         } bf;
39         unsigned short data;
40 };
41
42 struct daio_rsc_idx {
43         unsigned short left;
44         unsigned short right;
45 };
46
47 struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = {
48         [LINEO1] = {.left = 0x00, .right = 0x01},
49         [LINEO2] = {.left = 0x18, .right = 0x19},
50         [LINEO3] = {.left = 0x08, .right = 0x09},
51         [LINEO4] = {.left = 0x10, .right = 0x11},
52         [LINEIM] = {.left = 0x1b5, .right = 0x1bd},
53         [SPDIFOO] = {.left = 0x20, .right = 0x21},
54         [SPDIFIO] = {.left = 0x15, .right = 0x1d},
55         [SPDIFI1] = {.left = 0x95, .right = 0x9d},
56 };
57
58 struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
59         [LINEO1] = {.left = 0x40, .right = 0x41},
60         [LINEO2] = {.left = 0x60, .right = 0x61},
61         [LINEO3] = {.left = 0x50, .right = 0x51},
62         [LINEO4] = {.left = 0x70, .right = 0x71},
63         [LINEIM] = {.left = 0x45, .right = 0xc5},
64         [SPDIFOO] = {.left = 0x00, .right = 0x01},
65         [SPDIFIO] = {.left = 0x05, .right = 0x85},
66 };
67
68 static int daio_master(struct rsc *rsc)
69 {
70         /* Actually, this is not the resource index of DAIO.
71          * For DAO, it is the input mapper index. And, for DAI,
72          * it is the output time-slot index. */
73         return rsc->conj = rsc->idx;
74 }
75
76 static int daio_index(const struct rsc *rsc)
77 {
78         return rsc->conj;
79 }
80
81 static int daio_out_next_conj(struct rsc *rsc)
82 {
83         return rsc->conj += 2;
84 }
85
86 static int daio_in_next_conj_20k1(struct rsc *rsc)
87 {
88         return rsc->conj += 0x200;
89 }
90
91 static int daio_in_next_conj_20k2(struct rsc *rsc)
92 {
93         return rsc->conj += 0x100;
94 }
95
96 static struct rsc_ops daio_out_rsc_ops = {
97         .master         = daio_master,
98         .next_conj      = daio_out_next_conj,
99         .index          = daio_index,
100         .output_slot    = NULL,
101 };
102
103 static struct rsc_ops daio_in_rsc_ops_20k1 = {
104         .master         = daio_master,
105         .next_conj      = daio_in_next_conj_20k1,
106         .index          = NULL,
107         .output_slot    = daio_index,
108 };
109
110 static struct rsc_ops daio_in_rsc_ops_20k2 = {
111         .master         = daio_master,
112         .next_conj      = daio_in_next_conj_20k2,
113         .index          = NULL,
114         .output_slot    = daio_index,
115 };
116
117 static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
118 {
119         switch (hw->chip_type) {
120         case ATC20K1:
121                 switch (type) {
122                 case SPDIFOO:   return 0;
123                 case SPDIFIO:   return 0;
124                 case SPDIFI1:   return 1;
125                 case LINEO1:    return 4;
126                 case LINEO2:    return 7;
127                 case LINEO3:    return 5;
128                 case LINEO4:    return 6;
129                 case LINEIM:    return 7;
130                 default:        return -EINVAL;
131                 }
132         case ATC20K2:
133                 switch (type) {
134                 case SPDIFOO:   return 0;
135                 case SPDIFIO:   return 0;
136                 case LINEO1:    return 4;
137                 case LINEO2:    return 7;
138                 case LINEO3:    return 5;
139                 case LINEO4:    return 6;
140                 case LINEIM:    return 4;
141                 default:        return -EINVAL;
142                 }
143         default:
144                 return -EINVAL;
145         }
146 }
147
148 static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc);
149
150 static int dao_spdif_get_spos(struct dao *dao, unsigned int *spos)
151 {
152         ((struct hw *)dao->hw)->dao_get_spos(dao->ctrl_blk, spos);
153         return 0;
154 }
155
156 static int dao_spdif_set_spos(struct dao *dao, unsigned int spos)
157 {
158         ((struct hw *)dao->hw)->dao_set_spos(dao->ctrl_blk, spos);
159         return 0;
160 }
161
162 static int dao_commit_write(struct dao *dao)
163 {
164         ((struct hw *)dao->hw)->dao_commit_write(dao->hw,
165                 daio_device_index(dao->daio.type, dao->hw), dao->ctrl_blk);
166         return 0;
167 }
168
169 static int dao_set_left_input(struct dao *dao, struct rsc *input)
170 {
171         struct imapper *entry;
172         struct daio *daio = &dao->daio;
173         int i;
174
175         entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL);
176         if (!entry)
177                 return -ENOMEM;
178
179         dao->ops->clear_left_input(dao);
180         /* Program master and conjugate resources */
181         input->ops->master(input);
182         daio->rscl.ops->master(&daio->rscl);
183         for (i = 0; i < daio->rscl.msr; i++, entry++) {
184                 entry->slot = input->ops->output_slot(input);
185                 entry->user = entry->addr = daio->rscl.ops->index(&daio->rscl);
186                 dao->mgr->imap_add(dao->mgr, entry);
187                 dao->imappers[i] = entry;
188
189                 input->ops->next_conj(input);
190                 daio->rscl.ops->next_conj(&daio->rscl);
191         }
192         input->ops->master(input);
193         daio->rscl.ops->master(&daio->rscl);
194
195         return 0;
196 }
197
198 static int dao_set_right_input(struct dao *dao, struct rsc *input)
199 {
200         struct imapper *entry;
201         struct daio *daio = &dao->daio;
202         int i;
203
204         entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL);
205         if (!entry)
206                 return -ENOMEM;
207
208         dao->ops->clear_right_input(dao);
209         /* Program master and conjugate resources */
210         input->ops->master(input);
211         daio->rscr.ops->master(&daio->rscr);
212         for (i = 0; i < daio->rscr.msr; i++, entry++) {
213                 entry->slot = input->ops->output_slot(input);
214                 entry->user = entry->addr = daio->rscr.ops->index(&daio->rscr);
215                 dao->mgr->imap_add(dao->mgr, entry);
216                 dao->imappers[daio->rscl.msr + i] = entry;
217
218                 input->ops->next_conj(input);
219                 daio->rscr.ops->next_conj(&daio->rscr);
220         }
221         input->ops->master(input);
222         daio->rscr.ops->master(&daio->rscr);
223
224         return 0;
225 }
226
227 static int dao_clear_left_input(struct dao *dao)
228 {
229         struct imapper *entry;
230         struct daio *daio = &dao->daio;
231         int i;
232
233         if (!dao->imappers[0])
234                 return 0;
235
236         entry = dao->imappers[0];
237         dao->mgr->imap_delete(dao->mgr, entry);
238         /* Program conjugate resources */
239         for (i = 1; i < daio->rscl.msr; i++) {
240                 entry = dao->imappers[i];
241                 dao->mgr->imap_delete(dao->mgr, entry);
242                 dao->imappers[i] = NULL;
243         }
244
245         kfree(dao->imappers[0]);
246         dao->imappers[0] = NULL;
247
248         return 0;
249 }
250
251 static int dao_clear_right_input(struct dao *dao)
252 {
253         struct imapper *entry;
254         struct daio *daio = &dao->daio;
255         int i;
256
257         if (!dao->imappers[daio->rscl.msr])
258                 return 0;
259
260         entry = dao->imappers[daio->rscl.msr];
261         dao->mgr->imap_delete(dao->mgr, entry);
262         /* Program conjugate resources */
263         for (i = 1; i < daio->rscr.msr; i++) {
264                 entry = dao->imappers[daio->rscl.msr + i];
265                 dao->mgr->imap_delete(dao->mgr, entry);
266                 dao->imappers[daio->rscl.msr + i] = NULL;
267         }
268
269         kfree(dao->imappers[daio->rscl.msr]);
270         dao->imappers[daio->rscl.msr] = NULL;
271
272         return 0;
273 }
274
275 static struct dao_rsc_ops dao_ops = {
276         .set_spos               = dao_spdif_set_spos,
277         .commit_write           = dao_commit_write,
278         .get_spos               = dao_spdif_get_spos,
279         .reinit                 = dao_rsc_reinit,
280         .set_left_input         = dao_set_left_input,
281         .set_right_input        = dao_set_right_input,
282         .clear_left_input       = dao_clear_left_input,
283         .clear_right_input      = dao_clear_right_input,
284 };
285
286 static int dai_set_srt_srcl(struct dai *dai, struct rsc *src)
287 {
288         src->ops->master(src);
289         ((struct hw *)dai->hw)->dai_srt_set_srcm(dai->ctrl_blk,
290                                                 src->ops->index(src));
291         return 0;
292 }
293
294 static int dai_set_srt_srcr(struct dai *dai, struct rsc *src)
295 {
296         src->ops->master(src);
297         ((struct hw *)dai->hw)->dai_srt_set_srco(dai->ctrl_blk,
298                                                 src->ops->index(src));
299         return 0;
300 }
301
302 static int dai_set_srt_msr(struct dai *dai, unsigned int msr)
303 {
304         unsigned int rsr;
305
306         for (rsr = 0; msr > 1; msr >>= 1)
307                 rsr++;
308
309         ((struct hw *)dai->hw)->dai_srt_set_rsr(dai->ctrl_blk, rsr);
310         return 0;
311 }
312
313 static int dai_set_enb_src(struct dai *dai, unsigned int enb)
314 {
315         ((struct hw *)dai->hw)->dai_srt_set_ec(dai->ctrl_blk, enb);
316         return 0;
317 }
318
319 static int dai_set_enb_srt(struct dai *dai, unsigned int enb)
320 {
321         ((struct hw *)dai->hw)->dai_srt_set_et(dai->ctrl_blk, enb);
322         return 0;
323 }
324
325 static int dai_commit_write(struct dai *dai)
326 {
327         ((struct hw *)dai->hw)->dai_commit_write(dai->hw,
328                 daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
329         return 0;
330 }
331
332 static struct dai_rsc_ops dai_ops = {
333         .set_srt_srcl           = dai_set_srt_srcl,
334         .set_srt_srcr           = dai_set_srt_srcr,
335         .set_srt_msr            = dai_set_srt_msr,
336         .set_enb_src            = dai_set_enb_src,
337         .set_enb_srt            = dai_set_enb_srt,
338         .commit_write           = dai_commit_write,
339 };
340
341 static int daio_rsc_init(struct daio *daio,
342                          const struct daio_desc *desc,
343                          void *hw)
344 {
345         int err;
346         unsigned int idx_l, idx_r;
347
348         switch (((struct hw *)hw)->chip_type) {
349         case ATC20K1:
350                 idx_l = idx_20k1[desc->type].left;
351                 idx_r = idx_20k1[desc->type].right;
352                 break;
353         case ATC20K2:
354                 idx_l = idx_20k2[desc->type].left;
355                 idx_r = idx_20k2[desc->type].right;
356                 break;
357         default:
358                 return -EINVAL;
359         }
360         err = rsc_init(&daio->rscl, idx_l, DAIO, desc->msr, hw);
361         if (err)
362                 return err;
363
364         err = rsc_init(&daio->rscr, idx_r, DAIO, desc->msr, hw);
365         if (err)
366                 goto error1;
367
368         /* Set daio->rscl/r->ops to daio specific ones */
369         if (desc->type <= DAIO_OUT_MAX) {
370                 daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops;
371         } else {
372                 switch (((struct hw *)hw)->chip_type) {
373                 case ATC20K1:
374                         daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k1;
375                         break;
376                 case ATC20K2:
377                         daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k2;
378                         break;
379                 default:
380                         break;
381                 }
382         }
383         daio->type = desc->type;
384
385         return 0;
386
387 error1:
388         rsc_uninit(&daio->rscl);
389         return err;
390 }
391
392 static int daio_rsc_uninit(struct daio *daio)
393 {
394         rsc_uninit(&daio->rscl);
395         rsc_uninit(&daio->rscr);
396
397         return 0;
398 }
399
400 static int dao_rsc_init(struct dao *dao,
401                         const struct daio_desc *desc,
402                         struct daio_mgr *mgr)
403 {
404         struct hw *hw = mgr->mgr.hw;
405         unsigned int conf;
406         int err;
407
408         err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw);
409         if (err)
410                 return err;
411
412         dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL);
413         if (!dao->imappers) {
414                 err = -ENOMEM;
415                 goto error1;
416         }
417         dao->ops = &dao_ops;
418         dao->mgr = mgr;
419         dao->hw = hw;
420         err = hw->dao_get_ctrl_blk(&dao->ctrl_blk);
421         if (err)
422                 goto error2;
423
424         hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
425                         daio_device_index(dao->daio.type, hw));
426         hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
427
428         conf = (desc->msr & 0x7) | (desc->passthru << 3);
429         hw->daio_mgr_dao_init(mgr->mgr.ctrl_blk,
430                         daio_device_index(dao->daio.type, hw), conf);
431         hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
432                         daio_device_index(dao->daio.type, hw));
433         hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
434
435         return 0;
436
437 error2:
438         kfree(dao->imappers);
439         dao->imappers = NULL;
440 error1:
441         daio_rsc_uninit(&dao->daio);
442         return err;
443 }
444
445 static int dao_rsc_uninit(struct dao *dao)
446 {
447         if (dao->imappers) {
448                 if (dao->imappers[0])
449                         dao_clear_left_input(dao);
450
451                 if (dao->imappers[dao->daio.rscl.msr])
452                         dao_clear_right_input(dao);
453
454                 kfree(dao->imappers);
455                 dao->imappers = NULL;
456         }
457         ((struct hw *)dao->hw)->dao_put_ctrl_blk(dao->ctrl_blk);
458         dao->hw = dao->ctrl_blk = NULL;
459         daio_rsc_uninit(&dao->daio);
460
461         return 0;
462 }
463
464 static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc)
465 {
466         struct daio_mgr *mgr = dao->mgr;
467         struct daio_desc dsc = {0};
468
469         dsc.type = dao->daio.type;
470         dsc.msr = desc->msr;
471         dsc.passthru = desc->passthru;
472         dao_rsc_uninit(dao);
473         return dao_rsc_init(dao, &dsc, mgr);
474 }
475
476 static int dai_rsc_init(struct dai *dai,
477                         const struct daio_desc *desc,
478                         struct daio_mgr *mgr)
479 {
480         int err;
481         struct hw *hw = mgr->mgr.hw;
482         unsigned int rsr, msr;
483
484         err = daio_rsc_init(&dai->daio, desc, mgr->mgr.hw);
485         if (err)
486                 return err;
487
488         dai->ops = &dai_ops;
489         dai->hw = mgr->mgr.hw;
490         err = hw->dai_get_ctrl_blk(&dai->ctrl_blk);
491         if (err)
492                 goto error1;
493
494         for (rsr = 0, msr = desc->msr; msr > 1; msr >>= 1)
495                 rsr++;
496
497         hw->dai_srt_set_rsr(dai->ctrl_blk, rsr);
498         hw->dai_srt_set_drat(dai->ctrl_blk, 0);
499         /* default to disabling control of a SRC */
500         hw->dai_srt_set_ec(dai->ctrl_blk, 0);
501         hw->dai_srt_set_et(dai->ctrl_blk, 0); /* default to disabling SRT */
502         hw->dai_commit_write(hw,
503                 daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
504
505         return 0;
506
507 error1:
508         daio_rsc_uninit(&dai->daio);
509         return err;
510 }
511
512 static int dai_rsc_uninit(struct dai *dai)
513 {
514         ((struct hw *)dai->hw)->dai_put_ctrl_blk(dai->ctrl_blk);
515         dai->hw = dai->ctrl_blk = NULL;
516         daio_rsc_uninit(&dai->daio);
517         return 0;
518 }
519
520 static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
521 {
522         if (((union daio_usage *)mgr->rscs)->data & (0x1 << type))
523                 return -ENOENT;
524
525         ((union daio_usage *)mgr->rscs)->data |= (0x1 << type);
526
527         return 0;
528 }
529
530 static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
531 {
532         ((union daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
533
534         return 0;
535 }
536
537 static int get_daio_rsc(struct daio_mgr *mgr,
538                         const struct daio_desc *desc,
539                         struct daio **rdaio)
540 {
541         int err;
542         struct dai *dai = NULL;
543         struct dao *dao = NULL;
544         unsigned long flags;
545
546         *rdaio = NULL;
547
548         /* Check whether there are sufficient daio resources to meet request. */
549         spin_lock_irqsave(&mgr->mgr_lock, flags);
550         err = daio_mgr_get_rsc(&mgr->mgr, desc->type);
551         spin_unlock_irqrestore(&mgr->mgr_lock, flags);
552         if (err) {
553                 printk(KERN_ERR "Can't meet DAIO resource request!\n");
554                 return err;
555         }
556
557         /* Allocate mem for daio resource */
558         if (desc->type <= DAIO_OUT_MAX) {
559                 dao = kzalloc(sizeof(*dao), GFP_KERNEL);
560                 if (!dao) {
561                         err = -ENOMEM;
562                         goto error;
563                 }
564                 err = dao_rsc_init(dao, desc, mgr);
565                 if (err)
566                         goto error;
567
568                 *rdaio = &dao->daio;
569         } else {
570                 dai = kzalloc(sizeof(*dai), GFP_KERNEL);
571                 if (!dai) {
572                         err = -ENOMEM;
573                         goto error;
574                 }
575                 err = dai_rsc_init(dai, desc, mgr);
576                 if (err)
577                         goto error;
578
579                 *rdaio = &dai->daio;
580         }
581
582         mgr->daio_enable(mgr, *rdaio);
583         mgr->commit_write(mgr);
584
585         return 0;
586
587 error:
588         if (dao)
589                 kfree(dao);
590         else if (dai)
591                 kfree(dai);
592
593         spin_lock_irqsave(&mgr->mgr_lock, flags);
594         daio_mgr_put_rsc(&mgr->mgr, desc->type);
595         spin_unlock_irqrestore(&mgr->mgr_lock, flags);
596         return err;
597 }
598
599 static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio)
600 {
601         unsigned long flags;
602
603         mgr->daio_disable(mgr, daio);
604         mgr->commit_write(mgr);
605
606         spin_lock_irqsave(&mgr->mgr_lock, flags);
607         daio_mgr_put_rsc(&mgr->mgr, daio->type);
608         spin_unlock_irqrestore(&mgr->mgr_lock, flags);
609
610         if (daio->type <= DAIO_OUT_MAX) {
611                 dao_rsc_uninit(container_of(daio, struct dao, daio));
612                 kfree(container_of(daio, struct dao, daio));
613         } else {
614                 dai_rsc_uninit(container_of(daio, struct dai, daio));
615                 kfree(container_of(daio, struct dai, daio));
616         }
617
618         return 0;
619 }
620
621 static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio)
622 {
623         struct hw *hw = mgr->mgr.hw;
624
625         if (DAIO_OUT_MAX >= daio->type) {
626                 hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
627                                 daio_device_index(daio->type, hw));
628         } else {
629                 hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk,
630                                 daio_device_index(daio->type, hw));
631         }
632         return 0;
633 }
634
635 static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio)
636 {
637         struct hw *hw = mgr->mgr.hw;
638
639         if (DAIO_OUT_MAX >= daio->type) {
640                 hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
641                                 daio_device_index(daio->type, hw));
642         } else {
643                 hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk,
644                                 daio_device_index(daio->type, hw));
645         }
646         return 0;
647 }
648
649 static int daio_map_op(void *data, struct imapper *entry)
650 {
651         struct rsc_mgr *mgr = &((struct daio_mgr *)data)->mgr;
652         struct hw *hw = mgr->hw;
653
654         hw->daio_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
655         hw->daio_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
656         hw->daio_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
657         hw->daio_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
658
659         return 0;
660 }
661
662 static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry)
663 {
664         unsigned long flags;
665         int err;
666
667         spin_lock_irqsave(&mgr->imap_lock, flags);
668         if (!entry->addr && mgr->init_imap_added) {
669                 input_mapper_delete(&mgr->imappers, mgr->init_imap,
670                                                         daio_map_op, mgr);
671                 mgr->init_imap_added = 0;
672         }
673         err = input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr);
674         spin_unlock_irqrestore(&mgr->imap_lock, flags);
675
676         return err;
677 }
678
679 static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry)
680 {
681         unsigned long flags;
682         int err;
683
684         spin_lock_irqsave(&mgr->imap_lock, flags);
685         err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr);
686         if (list_empty(&mgr->imappers)) {
687                 input_mapper_add(&mgr->imappers, mgr->init_imap,
688                                                         daio_map_op, mgr);
689                 mgr->init_imap_added = 1;
690         }
691         spin_unlock_irqrestore(&mgr->imap_lock, flags);
692
693         return err;
694 }
695
696 static int daio_mgr_commit_write(struct daio_mgr *mgr)
697 {
698         struct hw *hw = mgr->mgr.hw;
699
700         hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
701         return 0;
702 }
703
704 int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
705 {
706         int err, i;
707         struct daio_mgr *daio_mgr;
708         struct imapper *entry;
709
710         *rdaio_mgr = NULL;
711         daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL);
712         if (!daio_mgr)
713                 return -ENOMEM;
714
715         err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw);
716         if (err)
717                 goto error1;
718
719         spin_lock_init(&daio_mgr->mgr_lock);
720         spin_lock_init(&daio_mgr->imap_lock);
721         INIT_LIST_HEAD(&daio_mgr->imappers);
722         entry = kzalloc(sizeof(*entry), GFP_KERNEL);
723         if (!entry) {
724                 err = -ENOMEM;
725                 goto error2;
726         }
727         entry->slot = entry->addr = entry->next = entry->user = 0;
728         list_add(&entry->list, &daio_mgr->imappers);
729         daio_mgr->init_imap = entry;
730         daio_mgr->init_imap_added = 1;
731
732         daio_mgr->get_daio = get_daio_rsc;
733         daio_mgr->put_daio = put_daio_rsc;
734         daio_mgr->daio_enable = daio_mgr_enb_daio;
735         daio_mgr->daio_disable = daio_mgr_dsb_daio;
736         daio_mgr->imap_add = daio_imap_add;
737         daio_mgr->imap_delete = daio_imap_delete;
738         daio_mgr->commit_write = daio_mgr_commit_write;
739
740         for (i = 0; i < 8; i++) {
741                 ((struct hw *)hw)->daio_mgr_dsb_dao(daio_mgr->mgr.ctrl_blk, i);
742                 ((struct hw *)hw)->daio_mgr_dsb_dai(daio_mgr->mgr.ctrl_blk, i);
743         }
744         ((struct hw *)hw)->daio_mgr_commit_write(hw, daio_mgr->mgr.ctrl_blk);
745
746         *rdaio_mgr = daio_mgr;
747
748         return 0;
749
750 error2:
751         rsc_mgr_uninit(&daio_mgr->mgr);
752 error1:
753         kfree(daio_mgr);
754         return err;
755 }
756
757 int daio_mgr_destroy(struct daio_mgr *daio_mgr)
758 {
759         unsigned long flags;
760
761         /* free daio input mapper list */
762         spin_lock_irqsave(&daio_mgr->imap_lock, flags);
763         free_input_mapper_list(&daio_mgr->imappers);
764         spin_unlock_irqrestore(&daio_mgr->imap_lock, flags);
765
766         rsc_mgr_uninit(&daio_mgr->mgr);
767         kfree(daio_mgr);
768
769         return 0;
770 }
771