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