xref: /openbmc/linux/sound/pci/ctxfi/ctdaio.c (revision 565d76cb)
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 
772