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_obj(*src_mgr); 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 = kzalloc_objs(struct imapper, desc->msr); 673 if (!srcimp->imappers) { 674 err = -ENOMEM; 675 goto error1; 676 } 677 678 /* Set srcimp specific operations */ 679 srcimp->rsc.ops = &srcimp_basic_rsc_ops; 680 srcimp->ops = &srcimp_ops; 681 srcimp->mgr = mgr; 682 683 srcimp->rsc.ops->master(&srcimp->rsc); 684 685 return 0; 686 687 error1: 688 rsc_uninit(&srcimp->rsc); 689 return err; 690 } 691 692 static int srcimp_rsc_uninit(struct srcimp *srcimp) 693 { 694 kfree(srcimp->imappers); 695 srcimp->imappers = NULL; 696 srcimp->ops = NULL; 697 srcimp->mgr = NULL; 698 rsc_uninit(&srcimp->rsc); 699 700 return 0; 701 } 702 703 static int get_srcimp_rsc(struct srcimp_mgr *mgr, 704 const struct srcimp_desc *desc, 705 struct srcimp **rsrcimp) 706 { 707 int err, i; 708 unsigned int idx; 709 struct srcimp *srcimp; 710 711 *rsrcimp = NULL; 712 713 /* Allocate mem for SRCIMP resource */ 714 srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL); 715 if (!srcimp) 716 return -ENOMEM; 717 718 /* Check whether there are sufficient SRCIMP resources. */ 719 err = 0; 720 scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { 721 for (i = 0; i < desc->msr; i++) { 722 err = mgr_get_resource(&mgr->mgr, 1, &idx); 723 if (err) 724 break; 725 726 srcimp->idx[i] = idx; 727 } 728 } 729 if (err) { 730 dev_err(mgr->card->dev, 731 "Can't meet SRCIMP resource request!\n"); 732 goto error1; 733 } 734 735 err = srcimp_rsc_init(srcimp, desc, mgr); 736 if (err) 737 goto error1; 738 739 *rsrcimp = srcimp; 740 741 return 0; 742 743 error1: 744 scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { 745 for (i--; i >= 0; i--) 746 mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]); 747 } 748 kfree(srcimp); 749 return err; 750 } 751 752 static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp) 753 { 754 int i; 755 756 scoped_guard(spinlock_irqsave, &mgr->mgr_lock) { 757 for (i = 0; i < srcimp->rsc.msr; i++) 758 mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]); 759 } 760 srcimp_rsc_uninit(srcimp); 761 kfree(srcimp); 762 763 return 0; 764 } 765 766 static int srcimp_map_op(void *data, struct imapper *entry) 767 { 768 struct rsc_mgr *mgr = &((struct srcimp_mgr *)data)->mgr; 769 struct hw *hw = mgr->hw; 770 771 hw->srcimp_mgr_set_imaparc(mgr->ctrl_blk, entry->slot); 772 hw->srcimp_mgr_set_imapuser(mgr->ctrl_blk, entry->user); 773 hw->srcimp_mgr_set_imapnxt(mgr->ctrl_blk, entry->next); 774 hw->srcimp_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr); 775 hw->srcimp_mgr_commit_write(mgr->hw, mgr->ctrl_blk); 776 777 return 0; 778 } 779 780 static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry) 781 { 782 guard(spinlock_irqsave)(&mgr->imap_lock); 783 if ((0 == entry->addr) && (mgr->init_imap_added)) { 784 input_mapper_delete(&mgr->imappers, 785 mgr->init_imap, srcimp_map_op, mgr); 786 mgr->init_imap_added = 0; 787 } 788 return input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr); 789 } 790 791 static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry) 792 { 793 int err; 794 795 guard(spinlock_irqsave)(&mgr->imap_lock); 796 err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr); 797 if (list_empty(&mgr->imappers)) { 798 input_mapper_add(&mgr->imappers, mgr->init_imap, 799 srcimp_map_op, mgr); 800 mgr->init_imap_added = 1; 801 } 802 803 return err; 804 } 805 806 int srcimp_mgr_create(struct hw *hw, void **rsrcimp_mgr) 807 { 808 int err; 809 struct srcimp_mgr *srcimp_mgr; 810 struct imapper *entry; 811 812 *rsrcimp_mgr = NULL; 813 srcimp_mgr = kzalloc_obj(*srcimp_mgr); 814 if (!srcimp_mgr) 815 return -ENOMEM; 816 817 err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw); 818 if (err) 819 goto error1; 820 821 spin_lock_init(&srcimp_mgr->mgr_lock); 822 spin_lock_init(&srcimp_mgr->imap_lock); 823 INIT_LIST_HEAD(&srcimp_mgr->imappers); 824 entry = kzalloc_obj(*entry); 825 if (!entry) { 826 err = -ENOMEM; 827 goto error2; 828 } 829 entry->slot = entry->addr = entry->next = entry->user = 0; 830 list_add(&entry->list, &srcimp_mgr->imappers); 831 srcimp_mgr->init_imap = entry; 832 srcimp_mgr->init_imap_added = 1; 833 834 srcimp_mgr->get_srcimp = get_srcimp_rsc; 835 srcimp_mgr->put_srcimp = put_srcimp_rsc; 836 srcimp_mgr->imap_add = srcimp_imap_add; 837 srcimp_mgr->imap_delete = srcimp_imap_delete; 838 srcimp_mgr->card = hw->card; 839 840 *rsrcimp_mgr = srcimp_mgr; 841 842 return 0; 843 844 error2: 845 rsc_mgr_uninit(&srcimp_mgr->mgr); 846 error1: 847 kfree(srcimp_mgr); 848 return err; 849 } 850 851 int srcimp_mgr_destroy(void *ptr) 852 { 853 struct srcimp_mgr *srcimp_mgr = ptr; 854 855 /* free src input mapper list */ 856 scoped_guard(spinlock_irqsave, &srcimp_mgr->imap_lock) { 857 free_input_mapper_list(&srcimp_mgr->imappers); 858 } 859 860 rsc_mgr_uninit(&srcimp_mgr->mgr); 861 kfree(srcimp_mgr); 862 863 return 0; 864 } 865