1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. 4 * 5 * @File ctsrc.c 6 * 7 * @Brief 8 * This file contains the implementation of the Sample Rate Convertor 9 * resource management object. 10 * 11 * @Author Liu Chun 12 * @Date May 13 2008 13 */ 14 15 #include "ctsrc.h" 16 #include "cthardware.h" 17 #include <linux/slab.h> 18 19 #define SRC_RESOURCE_NUM 256 20 #define SRCIMP_RESOURCE_NUM 256 21 22 static unsigned int conj_mask; 23 24 static int src_default_config_memrd(struct src *src); 25 static int src_default_config_memwr(struct src *src); 26 static int src_default_config_arcrw(struct src *src); 27 28 static int (*src_default_config[3])(struct src *) = { 29 [MEMRD] = src_default_config_memrd, 30 [MEMWR] = src_default_config_memwr, 31 [ARCRW] = src_default_config_arcrw 32 }; 33 34 static int src_set_state(struct src *src, unsigned int state) 35 { 36 struct hw *hw; 37 38 hw = src->rsc.hw; 39 hw->src_set_state(src->rsc.ctrl_blk, state); 40 41 return 0; 42 } 43 44 static int src_set_bm(struct src *src, unsigned int bm) 45 { 46 struct hw *hw; 47 48 hw = src->rsc.hw; 49 hw->src_set_bm(src->rsc.ctrl_blk, bm); 50 51 return 0; 52 } 53 54 static int src_set_sf(struct src *src, unsigned int sf) 55 { 56 struct hw *hw; 57 58 hw = src->rsc.hw; 59 hw->src_set_sf(src->rsc.ctrl_blk, sf); 60 61 return 0; 62 } 63 64 static int src_set_pm(struct src *src, unsigned int pm) 65 { 66 struct hw *hw; 67 68 hw = src->rsc.hw; 69 hw->src_set_pm(src->rsc.ctrl_blk, pm); 70 71 return 0; 72 } 73 74 static int src_set_rom(struct src *src, unsigned int rom) 75 { 76 struct hw *hw; 77 78 hw = src->rsc.hw; 79 hw->src_set_rom(src->rsc.ctrl_blk, rom); 80 81 return 0; 82 } 83 84 static int src_set_vo(struct src *src, unsigned int vo) 85 { 86 struct hw *hw; 87 88 hw = src->rsc.hw; 89 hw->src_set_vo(src->rsc.ctrl_blk, vo); 90 91 return 0; 92 } 93 94 static int src_set_st(struct src *src, unsigned int st) 95 { 96 struct hw *hw; 97 98 hw = src->rsc.hw; 99 hw->src_set_st(src->rsc.ctrl_blk, st); 100 101 return 0; 102 } 103 104 static int src_set_bp(struct src *src, unsigned int bp) 105 { 106 struct hw *hw; 107 108 hw = src->rsc.hw; 109 hw->src_set_bp(src->rsc.ctrl_blk, bp); 110 111 return 0; 112 } 113 114 static int src_set_cisz(struct src *src, unsigned int cisz) 115 { 116 struct hw *hw; 117 118 hw = src->rsc.hw; 119 hw->src_set_cisz(src->rsc.ctrl_blk, cisz); 120 121 return 0; 122 } 123 124 static int src_set_ca(struct src *src, unsigned int ca) 125 { 126 struct hw *hw; 127 128 hw = src->rsc.hw; 129 hw->src_set_ca(src->rsc.ctrl_blk, ca); 130 131 return 0; 132 } 133 134 static int src_set_sa(struct src *src, unsigned int sa) 135 { 136 struct hw *hw; 137 138 hw = src->rsc.hw; 139 hw->src_set_sa(src->rsc.ctrl_blk, sa); 140 141 return 0; 142 } 143 144 static int src_set_la(struct src *src, unsigned int la) 145 { 146 struct hw *hw; 147 148 hw = src->rsc.hw; 149 hw->src_set_la(src->rsc.ctrl_blk, la); 150 151 return 0; 152 } 153 154 static int src_set_pitch(struct src *src, unsigned int pitch) 155 { 156 struct hw *hw; 157 158 hw = src->rsc.hw; 159 hw->src_set_pitch(src->rsc.ctrl_blk, pitch); 160 161 return 0; 162 } 163 164 static int src_set_clear_zbufs(struct src *src) 165 { 166 struct hw *hw; 167 168 hw = src->rsc.hw; 169 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1); 170 171 return 0; 172 } 173 174 static int src_commit_write(struct src *src) 175 { 176 struct hw *hw; 177 int i; 178 unsigned int dirty = 0; 179 180 hw = src->rsc.hw; 181 src->rsc.ops->master(&src->rsc); 182 if (src->rsc.msr > 1) { 183 /* Save dirty flags for conjugate resource programming */ 184 dirty = hw->src_get_dirty(src->rsc.ctrl_blk) & conj_mask; 185 } 186 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), 187 src->rsc.ctrl_blk); 188 189 /* Program conjugate parameter mixer resources */ 190 if (MEMWR == src->mode) 191 return 0; 192 193 for (i = 1; i < src->rsc.msr; i++) { 194 src->rsc.ops->next_conj(&src->rsc); 195 hw->src_set_dirty(src->rsc.ctrl_blk, dirty); 196 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), 197 src->rsc.ctrl_blk); 198 } 199 src->rsc.ops->master(&src->rsc); 200 201 return 0; 202 } 203 204 static int src_get_ca(struct src *src) 205 { 206 struct hw *hw; 207 208 hw = src->rsc.hw; 209 return hw->src_get_ca(hw, src->rsc.ops->index(&src->rsc), 210 src->rsc.ctrl_blk); 211 } 212 213 static int src_init(struct src *src) 214 { 215 src_default_config[src->mode](src); 216 217 return 0; 218 } 219 220 static struct src *src_next_interleave(struct src *src) 221 { 222 return src->intlv; 223 } 224 225 static int src_default_config_memrd(struct src *src) 226 { 227 struct hw *hw = src->rsc.hw; 228 unsigned int rsr, msr; 229 230 hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF); 231 hw->src_set_bm(src->rsc.ctrl_blk, 1); 232 for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1) 233 rsr++; 234 235 hw->src_set_rsr(src->rsc.ctrl_blk, rsr); 236 hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16); 237 hw->src_set_wr(src->rsc.ctrl_blk, 0); 238 hw->src_set_pm(src->rsc.ctrl_blk, 0); 239 hw->src_set_rom(src->rsc.ctrl_blk, 0); 240 hw->src_set_vo(src->rsc.ctrl_blk, 0); 241 hw->src_set_st(src->rsc.ctrl_blk, 0); 242 hw->src_set_ilsz(src->rsc.ctrl_blk, src->multi - 1); 243 hw->src_set_cisz(src->rsc.ctrl_blk, 0x80); 244 hw->src_set_sa(src->rsc.ctrl_blk, 0x0); 245 hw->src_set_la(src->rsc.ctrl_blk, 0x1000); 246 hw->src_set_ca(src->rsc.ctrl_blk, 0x80); 247 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000); 248 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1); 249 250 src->rsc.ops->master(&src->rsc); 251 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), 252 src->rsc.ctrl_blk); 253 254 for (msr = 1; msr < src->rsc.msr; msr++) { 255 src->rsc.ops->next_conj(&src->rsc); 256 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000); 257 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), 258 src->rsc.ctrl_blk); 259 } 260 src->rsc.ops->master(&src->rsc); 261 262 return 0; 263 } 264 265 static int src_default_config_memwr(struct src *src) 266 { 267 struct hw *hw = src->rsc.hw; 268 269 hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF); 270 hw->src_set_bm(src->rsc.ctrl_blk, 1); 271 hw->src_set_rsr(src->rsc.ctrl_blk, 0); 272 hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16); 273 hw->src_set_wr(src->rsc.ctrl_blk, 1); 274 hw->src_set_pm(src->rsc.ctrl_blk, 0); 275 hw->src_set_rom(src->rsc.ctrl_blk, 0); 276 hw->src_set_vo(src->rsc.ctrl_blk, 0); 277 hw->src_set_st(src->rsc.ctrl_blk, 0); 278 hw->src_set_ilsz(src->rsc.ctrl_blk, 0); 279 hw->src_set_cisz(src->rsc.ctrl_blk, 0x80); 280 hw->src_set_sa(src->rsc.ctrl_blk, 0x0); 281 hw->src_set_la(src->rsc.ctrl_blk, 0x1000); 282 hw->src_set_ca(src->rsc.ctrl_blk, 0x80); 283 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000); 284 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1); 285 286 src->rsc.ops->master(&src->rsc); 287 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), 288 src->rsc.ctrl_blk); 289 290 return 0; 291 } 292 293 static int src_default_config_arcrw(struct src *src) 294 { 295 struct hw *hw = src->rsc.hw; 296 unsigned int rsr, msr; 297 unsigned int dirty; 298 299 hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF); 300 hw->src_set_bm(src->rsc.ctrl_blk, 0); 301 for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1) 302 rsr++; 303 304 hw->src_set_rsr(src->rsc.ctrl_blk, rsr); 305 hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_F32); 306 hw->src_set_wr(src->rsc.ctrl_blk, 0); 307 hw->src_set_pm(src->rsc.ctrl_blk, 0); 308 hw->src_set_rom(src->rsc.ctrl_blk, 0); 309 hw->src_set_vo(src->rsc.ctrl_blk, 0); 310 hw->src_set_st(src->rsc.ctrl_blk, 0); 311 hw->src_set_ilsz(src->rsc.ctrl_blk, 0); 312 hw->src_set_cisz(src->rsc.ctrl_blk, 0x80); 313 hw->src_set_sa(src->rsc.ctrl_blk, 0x0); 314 /*hw->src_set_sa(src->rsc.ctrl_blk, 0x100);*/ 315 hw->src_set_la(src->rsc.ctrl_blk, 0x1000); 316 /*hw->src_set_la(src->rsc.ctrl_blk, 0x03ffffe0);*/ 317 hw->src_set_ca(src->rsc.ctrl_blk, 0x80); 318 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000); 319 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1); 320 321 dirty = hw->src_get_dirty(src->rsc.ctrl_blk); 322 src->rsc.ops->master(&src->rsc); 323 for (msr = 0; msr < src->rsc.msr; msr++) { 324 hw->src_set_dirty(src->rsc.ctrl_blk, dirty); 325 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), 326 src->rsc.ctrl_blk); 327 src->rsc.ops->next_conj(&src->rsc); 328 } 329 src->rsc.ops->master(&src->rsc); 330 331 return 0; 332 } 333 334 static const struct src_rsc_ops src_rsc_ops = { 335 .set_state = src_set_state, 336 .set_bm = src_set_bm, 337 .set_sf = src_set_sf, 338 .set_pm = src_set_pm, 339 .set_rom = src_set_rom, 340 .set_vo = src_set_vo, 341 .set_st = src_set_st, 342 .set_bp = src_set_bp, 343 .set_cisz = src_set_cisz, 344 .set_ca = src_set_ca, 345 .set_sa = src_set_sa, 346 .set_la = src_set_la, 347 .set_pitch = src_set_pitch, 348 .set_clr_zbufs = src_set_clear_zbufs, 349 .commit_write = src_commit_write, 350 .get_ca = src_get_ca, 351 .init = src_init, 352 .next_interleave = src_next_interleave, 353 }; 354 355 static int 356 src_rsc_init(struct src *src, u32 idx, 357 const struct src_desc *desc, struct src_mgr *mgr) 358 { 359 int err; 360 int i, n; 361 struct src *p; 362 363 n = (MEMRD == desc->mode) ? desc->multi : 1; 364 for (i = 0, p = src; i < n; i++, p++) { 365 err = rsc_init(&p->rsc, idx + i, SRC, desc->msr, mgr->mgr.hw); 366 if (err) 367 goto error1; 368 369 /* Initialize src specific rsc operations */ 370 p->ops = &src_rsc_ops; 371 p->multi = (0 == i) ? desc->multi : 1; 372 p->mode = desc->mode; 373 src_default_config[desc->mode](p); 374 mgr->src_enable(mgr, p); 375 p->intlv = p + 1; 376 } 377 (--p)->intlv = NULL; /* Set @intlv of the last SRC to NULL */ 378 379 mgr->commit_write(mgr); 380 381 return 0; 382 383 error1: 384 for (i--, p--; i >= 0; i--, p--) { 385 mgr->src_disable(mgr, p); 386 rsc_uninit(&p->rsc); 387 } 388 mgr->commit_write(mgr); 389 return err; 390 } 391 392 static int src_rsc_uninit(struct src *src, struct src_mgr *mgr) 393 { 394 int i, n; 395 struct src *p; 396 397 n = (MEMRD == src->mode) ? src->multi : 1; 398 for (i = 0, p = src; i < n; i++, p++) { 399 mgr->src_disable(mgr, p); 400 rsc_uninit(&p->rsc); 401 p->multi = 0; 402 p->ops = NULL; 403 p->mode = NUM_SRCMODES; 404 p->intlv = NULL; 405 } 406 mgr->commit_write(mgr); 407 408 return 0; 409 } 410 411 static int 412 get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc) 413 { 414 unsigned int idx = SRC_RESOURCE_NUM; 415 int err; 416 struct src *src; 417 418 *rsrc = NULL; 419 420 /* Check whether there are sufficient src resources to meet request. */ 421 scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { 422 if (MEMRD == desc->mode) 423 err = mgr_get_resource(&mgr->mgr, desc->multi, &idx); 424 else 425 err = mgr_get_resource(&mgr->mgr, 1, &idx); 426 } 427 if (err) { 428 dev_err(mgr->card->dev, 429 "Can't meet SRC resource request!\n"); 430 return err; 431 } 432 433 /* Allocate mem for master src resource */ 434 if (MEMRD == desc->mode) 435 src = kcalloc(desc->multi, sizeof(*src), GFP_KERNEL); 436 else 437 src = kzalloc(sizeof(*src), GFP_KERNEL); 438 439 if (!src) { 440 err = -ENOMEM; 441 goto error1; 442 } 443 444 err = src_rsc_init(src, idx, desc, mgr); 445 if (err) 446 goto error2; 447 448 *rsrc = src; 449 450 return 0; 451 452 error2: 453 kfree(src); 454 error1: 455 scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { 456 if (MEMRD == desc->mode) 457 mgr_put_resource(&mgr->mgr, desc->multi, idx); 458 else 459 mgr_put_resource(&mgr->mgr, 1, idx); 460 } 461 return err; 462 } 463 464 static int put_src_rsc(struct src_mgr *mgr, struct src *src) 465 { 466 scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { 467 src->rsc.ops->master(&src->rsc); 468 if (MEMRD == src->mode) 469 mgr_put_resource(&mgr->mgr, src->multi, 470 src->rsc.ops->index(&src->rsc)); 471 else 472 mgr_put_resource(&mgr->mgr, 1, src->rsc.ops->index(&src->rsc)); 473 } 474 src_rsc_uninit(src, mgr); 475 kfree(src); 476 477 return 0; 478 } 479 480 static int src_enable_s(struct src_mgr *mgr, struct src *src) 481 { 482 struct hw *hw = mgr->mgr.hw; 483 int i; 484 485 src->rsc.ops->master(&src->rsc); 486 for (i = 0; i < src->rsc.msr; i++) { 487 hw->src_mgr_enbs_src(mgr->mgr.ctrl_blk, 488 src->rsc.ops->index(&src->rsc)); 489 src->rsc.ops->next_conj(&src->rsc); 490 } 491 src->rsc.ops->master(&src->rsc); 492 493 return 0; 494 } 495 496 static int src_enable(struct src_mgr *mgr, struct src *src) 497 { 498 struct hw *hw = mgr->mgr.hw; 499 int i; 500 501 src->rsc.ops->master(&src->rsc); 502 for (i = 0; i < src->rsc.msr; i++) { 503 hw->src_mgr_enb_src(mgr->mgr.ctrl_blk, 504 src->rsc.ops->index(&src->rsc)); 505 src->rsc.ops->next_conj(&src->rsc); 506 } 507 src->rsc.ops->master(&src->rsc); 508 509 return 0; 510 } 511 512 static int src_disable(struct src_mgr *mgr, struct src *src) 513 { 514 struct hw *hw = mgr->mgr.hw; 515 int i; 516 517 src->rsc.ops->master(&src->rsc); 518 for (i = 0; i < src->rsc.msr; i++) { 519 hw->src_mgr_dsb_src(mgr->mgr.ctrl_blk, 520 src->rsc.ops->index(&src->rsc)); 521 src->rsc.ops->next_conj(&src->rsc); 522 } 523 src->rsc.ops->master(&src->rsc); 524 525 return 0; 526 } 527 528 static int src_mgr_commit_write(struct src_mgr *mgr) 529 { 530 struct hw *hw = mgr->mgr.hw; 531 532 hw->src_mgr_commit_write(hw, mgr->mgr.ctrl_blk); 533 534 return 0; 535 } 536 537 int src_mgr_create(struct hw *hw, void **rsrc_mgr) 538 { 539 int err, i; 540 struct src_mgr *src_mgr; 541 542 *rsrc_mgr = NULL; 543 src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL); 544 if (!src_mgr) 545 return -ENOMEM; 546 547 err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw); 548 if (err) 549 goto error1; 550 551 spin_lock_init(&src_mgr->mgr_lock); 552 conj_mask = hw->src_dirty_conj_mask(); 553 554 src_mgr->get_src = get_src_rsc; 555 src_mgr->put_src = put_src_rsc; 556 src_mgr->src_enable_s = src_enable_s; 557 src_mgr->src_enable = src_enable; 558 src_mgr->src_disable = src_disable; 559 src_mgr->commit_write = src_mgr_commit_write; 560 src_mgr->card = hw->card; 561 562 /* Disable all SRC resources. */ 563 for (i = 0; i < 256; i++) 564 hw->src_mgr_dsb_src(src_mgr->mgr.ctrl_blk, i); 565 566 hw->src_mgr_commit_write(hw, src_mgr->mgr.ctrl_blk); 567 568 *rsrc_mgr = src_mgr; 569 570 return 0; 571 572 error1: 573 kfree(src_mgr); 574 return err; 575 } 576 577 int src_mgr_destroy(void *ptr) 578 { 579 struct src_mgr *src_mgr = ptr; 580 rsc_mgr_uninit(&src_mgr->mgr); 581 kfree(src_mgr); 582 583 return 0; 584 } 585 586 /* SRCIMP resource manager operations */ 587 588 static void srcimp_master(struct rsc *rsc) 589 { 590 rsc->conj = 0; 591 rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0]; 592 } 593 594 static void srcimp_next_conj(struct rsc *rsc) 595 { 596 rsc->conj++; 597 } 598 599 static int srcimp_index(const struct rsc *rsc) 600 { 601 return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj]; 602 } 603 604 static const struct rsc_ops srcimp_basic_rsc_ops = { 605 .master = srcimp_master, 606 .next_conj = srcimp_next_conj, 607 .index = srcimp_index, 608 .output_slot = NULL, 609 }; 610 611 static int srcimp_map(struct srcimp *srcimp, struct src *src, struct rsc *input) 612 { 613 struct imapper *entry; 614 int i; 615 616 srcimp->rsc.ops->master(&srcimp->rsc); 617 src->rsc.ops->master(&src->rsc); 618 input->ops->master(input); 619 620 /* Program master and conjugate resources */ 621 for (i = 0; i < srcimp->rsc.msr; i++) { 622 entry = &srcimp->imappers[i]; 623 entry->slot = input->ops->output_slot(input); 624 entry->user = src->rsc.ops->index(&src->rsc); 625 entry->addr = srcimp->rsc.ops->index(&srcimp->rsc); 626 srcimp->mgr->imap_add(srcimp->mgr, entry); 627 srcimp->mapped |= (0x1 << i); 628 629 srcimp->rsc.ops->next_conj(&srcimp->rsc); 630 input->ops->next_conj(input); 631 } 632 633 srcimp->rsc.ops->master(&srcimp->rsc); 634 input->ops->master(input); 635 636 return 0; 637 } 638 639 static int srcimp_unmap(struct srcimp *srcimp) 640 { 641 int i; 642 643 /* Program master and conjugate resources */ 644 for (i = 0; i < srcimp->rsc.msr; i++) { 645 if (srcimp->mapped & (0x1 << i)) { 646 srcimp->mgr->imap_delete(srcimp->mgr, 647 &srcimp->imappers[i]); 648 srcimp->mapped &= ~(0x1 << i); 649 } 650 } 651 652 return 0; 653 } 654 655 static const struct srcimp_rsc_ops srcimp_ops = { 656 .map = srcimp_map, 657 .unmap = srcimp_unmap 658 }; 659 660 static int srcimp_rsc_init(struct srcimp *srcimp, 661 const struct srcimp_desc *desc, 662 struct srcimp_mgr *mgr) 663 { 664 int err; 665 666 err = rsc_init(&srcimp->rsc, srcimp->idx[0], 667 SRCIMP, desc->msr, mgr->mgr.hw); 668 if (err) 669 return err; 670 671 /* Reserve memory for imapper nodes */ 672 srcimp->imappers = kcalloc(desc->msr, sizeof(struct imapper), 673 GFP_KERNEL); 674 if (!srcimp->imappers) { 675 err = -ENOMEM; 676 goto error1; 677 } 678 679 /* Set srcimp specific operations */ 680 srcimp->rsc.ops = &srcimp_basic_rsc_ops; 681 srcimp->ops = &srcimp_ops; 682 srcimp->mgr = mgr; 683 684 srcimp->rsc.ops->master(&srcimp->rsc); 685 686 return 0; 687 688 error1: 689 rsc_uninit(&srcimp->rsc); 690 return err; 691 } 692 693 static int srcimp_rsc_uninit(struct srcimp *srcimp) 694 { 695 kfree(srcimp->imappers); 696 srcimp->imappers = NULL; 697 srcimp->ops = NULL; 698 srcimp->mgr = NULL; 699 rsc_uninit(&srcimp->rsc); 700 701 return 0; 702 } 703 704 static int get_srcimp_rsc(struct srcimp_mgr *mgr, 705 const struct srcimp_desc *desc, 706 struct srcimp **rsrcimp) 707 { 708 int err, i; 709 unsigned int idx; 710 struct srcimp *srcimp; 711 712 *rsrcimp = NULL; 713 714 /* Allocate mem for SRCIMP resource */ 715 srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL); 716 if (!srcimp) 717 return -ENOMEM; 718 719 /* Check whether there are sufficient SRCIMP resources. */ 720 err = 0; 721 scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { 722 for (i = 0; i < desc->msr; i++) { 723 err = mgr_get_resource(&mgr->mgr, 1, &idx); 724 if (err) 725 break; 726 727 srcimp->idx[i] = idx; 728 } 729 } 730 if (err) { 731 dev_err(mgr->card->dev, 732 "Can't meet SRCIMP resource request!\n"); 733 goto error1; 734 } 735 736 err = srcimp_rsc_init(srcimp, desc, mgr); 737 if (err) 738 goto error1; 739 740 *rsrcimp = srcimp; 741 742 return 0; 743 744 error1: 745 scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { 746 for (i--; i >= 0; i--) 747 mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]); 748 } 749 kfree(srcimp); 750 return err; 751 } 752 753 static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp) 754 { 755 int i; 756 757 scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { 758 for (i = 0; i < srcimp->rsc.msr; i++) 759 mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]); 760 } 761 srcimp_rsc_uninit(srcimp); 762 kfree(srcimp); 763 764 return 0; 765 } 766 767 static int srcimp_map_op(void *data, struct imapper *entry) 768 { 769 struct rsc_mgr *mgr = &((struct srcimp_mgr *)data)->mgr; 770 struct hw *hw = mgr->hw; 771 772 hw->srcimp_mgr_set_imaparc(mgr->ctrl_blk, entry->slot); 773 hw->srcimp_mgr_set_imapuser(mgr->ctrl_blk, entry->user); 774 hw->srcimp_mgr_set_imapnxt(mgr->ctrl_blk, entry->next); 775 hw->srcimp_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr); 776 hw->srcimp_mgr_commit_write(mgr->hw, mgr->ctrl_blk); 777 778 return 0; 779 } 780 781 static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry) 782 { 783 guard(spinlock_irqsave)(&mgr->imap_lock); 784 if ((0 == entry->addr) && (mgr->init_imap_added)) { 785 input_mapper_delete(&mgr->imappers, 786 mgr->init_imap, srcimp_map_op, mgr); 787 mgr->init_imap_added = 0; 788 } 789 return input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr); 790 } 791 792 static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry) 793 { 794 int err; 795 796 guard(spinlock_irqsave)(&mgr->imap_lock); 797 err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr); 798 if (list_empty(&mgr->imappers)) { 799 input_mapper_add(&mgr->imappers, mgr->init_imap, 800 srcimp_map_op, mgr); 801 mgr->init_imap_added = 1; 802 } 803 804 return err; 805 } 806 807 int srcimp_mgr_create(struct hw *hw, void **rsrcimp_mgr) 808 { 809 int err; 810 struct srcimp_mgr *srcimp_mgr; 811 struct imapper *entry; 812 813 *rsrcimp_mgr = NULL; 814 srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL); 815 if (!srcimp_mgr) 816 return -ENOMEM; 817 818 err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw); 819 if (err) 820 goto error1; 821 822 spin_lock_init(&srcimp_mgr->mgr_lock); 823 spin_lock_init(&srcimp_mgr->imap_lock); 824 INIT_LIST_HEAD(&srcimp_mgr->imappers); 825 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 826 if (!entry) { 827 err = -ENOMEM; 828 goto error2; 829 } 830 entry->slot = entry->addr = entry->next = entry->user = 0; 831 list_add(&entry->list, &srcimp_mgr->imappers); 832 srcimp_mgr->init_imap = entry; 833 srcimp_mgr->init_imap_added = 1; 834 835 srcimp_mgr->get_srcimp = get_srcimp_rsc; 836 srcimp_mgr->put_srcimp = put_srcimp_rsc; 837 srcimp_mgr->imap_add = srcimp_imap_add; 838 srcimp_mgr->imap_delete = srcimp_imap_delete; 839 srcimp_mgr->card = hw->card; 840 841 *rsrcimp_mgr = srcimp_mgr; 842 843 return 0; 844 845 error2: 846 rsc_mgr_uninit(&srcimp_mgr->mgr); 847 error1: 848 kfree(srcimp_mgr); 849 return err; 850 } 851 852 int srcimp_mgr_destroy(void *ptr) 853 { 854 struct srcimp_mgr *srcimp_mgr = ptr; 855 856 /* free src input mapper list */ 857 scoped_guard(spinlock_irqsave, &srcimp_mgr->imap_lock) { 858 free_input_mapper_list(&srcimp_mgr->imappers); 859 } 860 861 rsc_mgr_uninit(&srcimp_mgr->mgr); 862 kfree(srcimp_mgr); 863 864 return 0; 865 } 866