xref: /openbmc/linux/sound/pci/ctxfi/ctdaio.c (revision cabc5c0f7fa1342049042d6e147db5a73773955b)
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 	/* 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;
200 	struct daio *daio = &dao->daio;
201 	int i;
202 
203 	entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL);
204 	if (!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;
228 	struct daio *daio = &dao->daio;
229 	int i;
230 
231 	if (!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;
252 	struct daio *daio = &dao->daio;
253 	int i;
254 
255 	if (!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;
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;
344 	unsigned int idx_l, idx_r;
345 
346 	switch (((struct hw *)hw)->chip_type) {
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)->chip_type) {
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;
404 	int err;
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 (!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 (dao->imappers) {
446 		if (dao->imappers[0])
447 			dao_clear_left_input(dao);
448 
449 		if (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;
479 	struct hw *hw = mgr->mgr.hw;
480 	unsigned int rsr, msr;
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;
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 (!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 (!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 (dao)
587 		kfree(dao);
588 	else if (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;
664 
665 	spin_lock_irqsave(&mgr->imap_lock, flags);
666 	if (!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;
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, i;
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 (!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 (!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 
770