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