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