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