Merge branch 'topic/ctxfi-fix' into topic/ctxfi
[linux-2.6] / 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 = 0x70, .right = 0x71},
61         [LINEO3] = {.left = 0x50, .right = 0x51},
62         [LINEO4] = {.left = 0x60, .right = 0x61},
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->get_chip_type(hw)) {
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 = NULL;
172         struct daio *daio = &dao->daio;
173         int i = 0;
174
175         entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL);
176         if (NULL == entry)
177                 return -ENOMEM;
178
179         /* Program master and conjugate resources */
180         input->ops->master(input);
181         daio->rscl.ops->master(&daio->rscl);
182         for (i = 0; i < daio->rscl.msr; i++, entry++) {
183                 entry->slot = input->ops->output_slot(input);
184                 entry->user = entry->addr = daio->rscl.ops->index(&daio->rscl);
185                 dao->mgr->imap_add(dao->mgr, entry);
186                 dao->imappers[i] = entry;
187
188                 input->ops->next_conj(input);
189                 daio->rscl.ops->next_conj(&daio->rscl);
190         }
191         input->ops->master(input);
192         daio->rscl.ops->master(&daio->rscl);
193
194         return 0;
195 }
196
197 static int dao_set_right_input(struct dao *dao, struct rsc *input)
198 {
199         struct imapper *entry = NULL;
200         struct daio *daio = &dao->daio;
201         int i = 0;
202
203         entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL);
204         if (NULL == entry)
205                 return -ENOMEM;
206
207         /* Program master and conjugate resources */
208         input->ops->master(input);
209         daio->rscr.ops->master(&daio->rscr);
210         for (i = 0; i < daio->rscr.msr; i++, entry++) {
211                 entry->slot = input->ops->output_slot(input);
212                 entry->user = entry->addr = daio->rscr.ops->index(&daio->rscr);
213                 dao->mgr->imap_add(dao->mgr, entry);
214                 dao->imappers[daio->rscl.msr + i] = entry;
215
216                 input->ops->next_conj(input);
217                 daio->rscr.ops->next_conj(&daio->rscr);
218         }
219         input->ops->master(input);
220         daio->rscr.ops->master(&daio->rscr);
221
222         return 0;
223 }
224
225 static int dao_clear_left_input(struct dao *dao)
226 {
227         struct imapper *entry = NULL;
228         struct daio *daio = &dao->daio;
229         int i = 0;
230
231         if (NULL == dao->imappers[0])
232                 return 0;
233
234         entry = dao->imappers[0];
235         dao->mgr->imap_delete(dao->mgr, entry);
236         /* Program conjugate resources */
237         for (i = 1; i < daio->rscl.msr; i++) {
238                 entry = dao->imappers[i];
239                 dao->mgr->imap_delete(dao->mgr, entry);
240                 dao->imappers[i] = NULL;
241         }
242
243         kfree(dao->imappers[0]);
244         dao->imappers[0] = NULL;
245
246         return 0;
247 }
248
249 static int dao_clear_right_input(struct dao *dao)
250 {
251         struct imapper *entry = NULL;
252         struct daio *daio = &dao->daio;
253         int i = 0;
254
255         if (NULL == dao->imappers[daio->rscl.msr])
256                 return 0;
257
258         entry = dao->imappers[daio->rscl.msr];
259         dao->mgr->imap_delete(dao->mgr, entry);
260         /* Program conjugate resources */
261         for (i = 1; i < daio->rscr.msr; i++) {
262                 entry = dao->imappers[daio->rscl.msr + i];
263                 dao->mgr->imap_delete(dao->mgr, entry);
264                 dao->imappers[daio->rscl.msr + i] = NULL;
265         }
266
267         kfree(dao->imappers[daio->rscl.msr]);
268         dao->imappers[daio->rscl.msr] = NULL;
269
270         return 0;
271 }
272
273 static struct dao_rsc_ops dao_ops = {
274         .set_spos               = dao_spdif_set_spos,
275         .commit_write           = dao_commit_write,
276         .get_spos               = dao_spdif_get_spos,
277         .reinit                 = dao_rsc_reinit,
278         .set_left_input         = dao_set_left_input,
279         .set_right_input        = dao_set_right_input,
280         .clear_left_input       = dao_clear_left_input,
281         .clear_right_input      = dao_clear_right_input,
282 };
283
284 static int dai_set_srt_srcl(struct dai *dai, struct rsc *src)
285 {
286         src->ops->master(src);
287         ((struct hw *)dai->hw)->dai_srt_set_srcm(dai->ctrl_blk,
288                                                 src->ops->index(src));
289         return 0;
290 }
291
292 static int dai_set_srt_srcr(struct dai *dai, struct rsc *src)
293 {
294         src->ops->master(src);
295         ((struct hw *)dai->hw)->dai_srt_set_srco(dai->ctrl_blk,
296                                                 src->ops->index(src));
297         return 0;
298 }
299
300 static int dai_set_srt_msr(struct dai *dai, unsigned int msr)
301 {
302         unsigned int rsr = 0;
303
304         for (rsr = 0; msr > 1; msr >>= 1)
305                 rsr++;
306
307         ((struct hw *)dai->hw)->dai_srt_set_rsr(dai->ctrl_blk, rsr);
308         return 0;
309 }
310
311 static int dai_set_enb_src(struct dai *dai, unsigned int enb)
312 {
313         ((struct hw *)dai->hw)->dai_srt_set_ec(dai->ctrl_blk, enb);
314         return 0;
315 }
316
317 static int dai_set_enb_srt(struct dai *dai, unsigned int enb)
318 {
319         ((struct hw *)dai->hw)->dai_srt_set_et(dai->ctrl_blk, enb);
320         return 0;
321 }
322
323 static int dai_commit_write(struct dai *dai)
324 {
325         ((struct hw *)dai->hw)->dai_commit_write(dai->hw,
326                 daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
327         return 0;
328 }
329
330 static struct dai_rsc_ops dai_ops = {
331         .set_srt_srcl           = dai_set_srt_srcl,
332         .set_srt_srcr           = dai_set_srt_srcr,
333         .set_srt_msr            = dai_set_srt_msr,
334         .set_enb_src            = dai_set_enb_src,
335         .set_enb_srt            = dai_set_enb_srt,
336         .commit_write           = dai_commit_write,
337 };
338
339 static int daio_rsc_init(struct daio *daio,
340                          const struct daio_desc *desc,
341                          void *hw)
342 {
343         int err = 0;
344         unsigned int idx_l = 0, idx_r = 0;
345
346         switch (((struct hw *)hw)->get_chip_type(hw)) {
347         case ATC20K1:
348                 idx_l = idx_20k1[desc->type].left;
349                 idx_r = idx_20k1[desc->type].right;
350                 break;
351         case ATC20K2:
352                 idx_l = idx_20k2[desc->type].left;
353                 idx_r = idx_20k2[desc->type].right;
354                 break;
355         default:
356                 return -EINVAL;
357         }
358         err = rsc_init(&daio->rscl, idx_l, DAIO, desc->msr, hw);
359         if (err)
360                 return err;
361
362         err = rsc_init(&daio->rscr, idx_r, DAIO, desc->msr, hw);
363         if (err)
364                 goto error1;
365
366         /* Set daio->rscl/r->ops to daio specific ones */
367         if (desc->type <= DAIO_OUT_MAX) {
368                 daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops;
369         } else {
370                 switch (((struct hw *)hw)->get_chip_type(hw)) {
371                 case ATC20K1:
372                         daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k1;
373                         break;
374                 case ATC20K2:
375                         daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k2;
376                         break;
377                 default:
378                         break;
379                 }
380         }
381         daio->type = desc->type;
382
383         return 0;
384
385 error1:
386         rsc_uninit(&daio->rscl);
387         return err;
388 }
389
390 static int daio_rsc_uninit(struct daio *daio)
391 {
392         rsc_uninit(&daio->rscl);
393         rsc_uninit(&daio->rscr);
394
395         return 0;
396 }
397
398 static int dao_rsc_init(struct dao *dao,
399                         const struct daio_desc *desc,
400                         struct daio_mgr *mgr)
401 {
402         struct hw *hw = mgr->mgr.hw;
403         unsigned int conf = 0;
404         int err = 0;
405
406         err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw);
407         if (err)
408                 return err;
409
410         dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL);
411         if (NULL == dao->imappers) {
412                 err = -ENOMEM;
413                 goto error1;
414         }
415         dao->ops = &dao_ops;
416         dao->mgr = mgr;
417         dao->hw = hw;
418         err = hw->dao_get_ctrl_blk(&dao->ctrl_blk);
419         if (err)
420                 goto error2;
421
422         hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
423                         daio_device_index(dao->daio.type, hw));
424         hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
425
426         conf |= (desc->msr & 0x7) | (desc->passthru << 3);
427         hw->daio_mgr_dao_init(mgr->mgr.ctrl_blk,
428                         daio_device_index(dao->daio.type, hw), conf);
429         hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
430                         daio_device_index(dao->daio.type, hw));
431         hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
432
433         return 0;
434
435 error2:
436         kfree(dao->imappers);
437         dao->imappers = NULL;
438 error1:
439         daio_rsc_uninit(&dao->daio);
440         return err;
441 }
442
443 static int dao_rsc_uninit(struct dao *dao)
444 {
445         if (NULL != dao->imappers) {
446                 if (NULL != dao->imappers[0])
447                         dao_clear_left_input(dao);
448
449                 if (NULL != dao->imappers[dao->daio.rscl.msr])
450                         dao_clear_right_input(dao);
451
452                 kfree(dao->imappers);
453                 dao->imappers = NULL;
454         }
455         ((struct hw *)dao->hw)->dao_put_ctrl_blk(dao->ctrl_blk);
456         dao->hw = dao->ctrl_blk = NULL;
457         daio_rsc_uninit(&dao->daio);
458
459         return 0;
460 }
461
462 static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc)
463 {
464         struct daio_mgr *mgr = dao->mgr;
465         struct daio_desc dsc = {0};
466
467         dsc.type = dao->daio.type;
468         dsc.msr = desc->msr;
469         dsc.passthru = desc->passthru;
470         dao_rsc_uninit(dao);
471         return dao_rsc_init(dao, &dsc, mgr);
472 }
473
474 static int dai_rsc_init(struct dai *dai,
475                         const struct daio_desc *desc,
476                         struct daio_mgr *mgr)
477 {
478         int err = 0;
479         struct hw *hw = mgr->mgr.hw;
480         unsigned int rsr = 0, msr = 0;
481
482         err = daio_rsc_init(&dai->daio, desc, mgr->mgr.hw);
483         if (err)
484                 return err;
485
486         dai->ops = &dai_ops;
487         dai->hw = mgr->mgr.hw;
488         err = hw->dai_get_ctrl_blk(&dai->ctrl_blk);
489         if (err)
490                 goto error1;
491
492         for (rsr = 0, msr = desc->msr; msr > 1; msr >>= 1)
493                 rsr++;
494
495         hw->dai_srt_set_rsr(dai->ctrl_blk, rsr);
496         hw->dai_srt_set_drat(dai->ctrl_blk, 0);
497         /* default to disabling control of a SRC */
498         hw->dai_srt_set_ec(dai->ctrl_blk, 0);
499         hw->dai_srt_set_et(dai->ctrl_blk, 0); /* default to disabling SRT */
500         hw->dai_commit_write(hw,
501                 daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
502
503         return 0;
504
505 error1:
506         daio_rsc_uninit(&dai->daio);
507         return err;
508 }
509
510 static int dai_rsc_uninit(struct dai *dai)
511 {
512         ((struct hw *)dai->hw)->dai_put_ctrl_blk(dai->ctrl_blk);
513         dai->hw = dai->ctrl_blk = NULL;
514         daio_rsc_uninit(&dai->daio);
515         return 0;
516 }
517
518 static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
519 {
520         if (((union daio_usage *)mgr->rscs)->data & (0x1 << type))
521                 return -ENOENT;
522
523         ((union daio_usage *)mgr->rscs)->data |= (0x1 << type);
524
525         return 0;
526 }
527
528 static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
529 {
530         ((union daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
531
532         return 0;
533 }
534
535 static int get_daio_rsc(struct daio_mgr *mgr,
536                         const struct daio_desc *desc,
537                         struct daio **rdaio)
538 {
539         int err = 0;
540         struct dai *dai = NULL;
541         struct dao *dao = NULL;
542         unsigned long flags;
543
544         *rdaio = NULL;
545
546         /* Check whether there are sufficient daio resources to meet request. */
547         spin_lock_irqsave(&mgr->mgr_lock, flags);
548         err = daio_mgr_get_rsc(&mgr->mgr, desc->type);
549         spin_unlock_irqrestore(&mgr->mgr_lock, flags);
550         if (err) {
551                 printk(KERN_ERR "Can't meet DAIO resource request!\n");
552                 return err;
553         }
554
555         /* Allocate mem for daio resource */
556         if (desc->type <= DAIO_OUT_MAX) {
557                 dao = kzalloc(sizeof(*dao), GFP_KERNEL);
558                 if (NULL == dao) {
559                         err = -ENOMEM;
560                         goto error;
561                 }
562                 err = dao_rsc_init(dao, desc, mgr);
563                 if (err)
564                         goto error;
565
566                 *rdaio = &dao->daio;
567         } else {
568                 dai = kzalloc(sizeof(*dai), GFP_KERNEL);
569                 if (NULL == dai) {
570                         err = -ENOMEM;
571                         goto error;
572                 }
573                 err = dai_rsc_init(dai, desc, mgr);
574                 if (err)
575                         goto error;
576
577                 *rdaio = &dai->daio;
578         }
579
580         mgr->daio_enable(mgr, *rdaio);
581         mgr->commit_write(mgr);
582
583         return 0;
584
585 error:
586         if (NULL != dao)
587                 kfree(dao);
588         else if (NULL != dai)
589                 kfree(dai);
590
591         spin_lock_irqsave(&mgr->mgr_lock, flags);
592         daio_mgr_put_rsc(&mgr->mgr, desc->type);
593         spin_unlock_irqrestore(&mgr->mgr_lock, flags);
594         return err;
595 }
596
597 static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio)
598 {
599         unsigned long flags;
600
601         mgr->daio_disable(mgr, daio);
602         mgr->commit_write(mgr);
603
604         spin_lock_irqsave(&mgr->mgr_lock, flags);
605         daio_mgr_put_rsc(&mgr->mgr, daio->type);
606         spin_unlock_irqrestore(&mgr->mgr_lock, flags);
607
608         if (daio->type <= DAIO_OUT_MAX) {
609                 dao_rsc_uninit(container_of(daio, struct dao, daio));
610                 kfree(container_of(daio, struct dao, daio));
611         } else {
612                 dai_rsc_uninit(container_of(daio, struct dai, daio));
613                 kfree(container_of(daio, struct dai, daio));
614         }
615
616         return 0;
617 }
618
619 static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio)
620 {
621         struct hw *hw = mgr->mgr.hw;
622
623         if (DAIO_OUT_MAX >= daio->type) {
624                 hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
625                                 daio_device_index(daio->type, hw));
626         } else {
627                 hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk,
628                                 daio_device_index(daio->type, hw));
629         }
630         return 0;
631 }
632
633 static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio)
634 {
635         struct hw *hw = mgr->mgr.hw;
636
637         if (DAIO_OUT_MAX >= daio->type) {
638                 hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
639                                 daio_device_index(daio->type, hw));
640         } else {
641                 hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk,
642                                 daio_device_index(daio->type, hw));
643         }
644         return 0;
645 }
646
647 static int daio_map_op(void *data, struct imapper *entry)
648 {
649         struct rsc_mgr *mgr = &((struct daio_mgr *)data)->mgr;
650         struct hw *hw = mgr->hw;
651
652         hw->daio_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
653         hw->daio_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
654         hw->daio_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
655         hw->daio_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
656
657         return 0;
658 }
659
660 static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry)
661 {
662         unsigned long flags;
663         int err = 0;
664
665         spin_lock_irqsave(&mgr->imap_lock, flags);
666         if ((0 == entry->addr) && (mgr->init_imap_added)) {
667                 input_mapper_delete(&mgr->imappers, mgr->init_imap,
668                                                         daio_map_op, mgr);
669                 mgr->init_imap_added = 0;
670         }
671         err = input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr);
672         spin_unlock_irqrestore(&mgr->imap_lock, flags);
673
674         return err;
675 }
676
677 static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry)
678 {
679         unsigned long flags;
680         int err = 0;
681
682         spin_lock_irqsave(&mgr->imap_lock, flags);
683         err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr);
684         if (list_empty(&mgr->imappers)) {
685                 input_mapper_add(&mgr->imappers, mgr->init_imap,
686                                                         daio_map_op, mgr);
687                 mgr->init_imap_added = 1;
688         }
689         spin_unlock_irqrestore(&mgr->imap_lock, flags);
690
691         return err;
692 }
693
694 static int daio_mgr_commit_write(struct daio_mgr *mgr)
695 {
696         struct hw *hw = mgr->mgr.hw;
697
698         hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
699         return 0;
700 }
701
702 int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
703 {
704         int err = 0, i = 0;
705         struct daio_mgr *daio_mgr;
706         struct imapper *entry;
707
708         *rdaio_mgr = NULL;
709         daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL);
710         if (NULL == daio_mgr)
711                 return -ENOMEM;
712
713         err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw);
714         if (err)
715                 goto error1;
716
717         spin_lock_init(&daio_mgr->mgr_lock);
718         spin_lock_init(&daio_mgr->imap_lock);
719         INIT_LIST_HEAD(&daio_mgr->imappers);
720         entry = kzalloc(sizeof(*entry), GFP_KERNEL);
721         if (NULL == entry) {
722                 err = -ENOMEM;
723                 goto error2;
724         }
725         entry->slot = entry->addr = entry->next = entry->user = 0;
726         list_add(&entry->list, &daio_mgr->imappers);
727         daio_mgr->init_imap = entry;
728         daio_mgr->init_imap_added = 1;
729
730         daio_mgr->get_daio = get_daio_rsc;
731         daio_mgr->put_daio = put_daio_rsc;
732         daio_mgr->daio_enable = daio_mgr_enb_daio;
733         daio_mgr->daio_disable = daio_mgr_dsb_daio;
734         daio_mgr->imap_add = daio_imap_add;
735         daio_mgr->imap_delete = daio_imap_delete;
736         daio_mgr->commit_write = daio_mgr_commit_write;
737
738         for (i = 0; i < 8; i++) {
739                 ((struct hw *)hw)->daio_mgr_dsb_dao(daio_mgr->mgr.ctrl_blk, i);
740                 ((struct hw *)hw)->daio_mgr_dsb_dai(daio_mgr->mgr.ctrl_blk, i);
741         }
742         ((struct hw *)hw)->daio_mgr_commit_write(hw, daio_mgr->mgr.ctrl_blk);
743
744         *rdaio_mgr = daio_mgr;
745
746         return 0;
747
748 error2:
749         rsc_mgr_uninit(&daio_mgr->mgr);
750 error1:
751         kfree(daio_mgr);
752         return err;
753 }
754
755 int daio_mgr_destroy(struct daio_mgr *daio_mgr)
756 {
757         unsigned long flags;
758
759         /* free daio input mapper list */
760         spin_lock_irqsave(&daio_mgr->imap_lock, flags);
761         free_input_mapper_list(&daio_mgr->imappers);
762         spin_unlock_irqrestore(&daio_mgr->imap_lock, flags);
763
764         rsc_mgr_uninit(&daio_mgr->mgr);
765         kfree(daio_mgr);
766
767         return 0;
768 }
769