^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * @File ctresource.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * @Brief
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file contains the implementation of some generic helper functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * @Author Liu Chun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * @Date May 15 2008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "ctresource.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "cthardware.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define AUDIO_SLOT_BLOCK_NUM 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* Resource allocation based on bit-map management mechanism */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) get_resource(u8 *rscs, unsigned int amount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned int multi, unsigned int *ridx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int i, j, k, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Check whether there are sufficient resources to meet request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) for (i = 0, n = multi; i < amount; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) j = i / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) k = i % 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (rscs[j] & ((u8)1 << k)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) n = multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (!(--n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) break; /* found sufficient contiguous resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (i >= amount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Can not find sufficient contiguous resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Mark the contiguous bits in resource bit-map as used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) for (n = multi; n > 0; n--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) j = i / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) k = i % 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) rscs[j] |= ((u8)1 << k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *ridx = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int put_resource(u8 *rscs, unsigned int multi, unsigned int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int i, j, k, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Mark the contiguous bits in resource bit-map as used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) for (n = multi, i = idx; n > 0; n--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) j = i / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) k = i % 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) rscs[j] &= ~((u8)1 << k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int mgr_get_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int *ridx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (n > mgr->avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) err = get_resource(mgr->rscs, mgr->amount, n, ridx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mgr->avail -= n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int mgr_put_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) put_resource(mgr->rscs, n, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mgr->avail += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static const unsigned char offset_in_audio_slot_block[NUM_RSCTYP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* SRC channel is at Audio Ring slot 1 every 16 slots. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) [SRC] = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) [AMIXER] = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) [SUM] = 0xc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int rsc_index(const struct rsc *rsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return rsc->conj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int audio_ring_slot(const struct rsc *rsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return (rsc->conj << 4) + offset_in_audio_slot_block[rsc->type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void rsc_next_conj(struct rsc *rsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) for (i = 0; (i < 8) && (!(rsc->msr & (0x1 << i))); )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) rsc->conj += (AUDIO_SLOT_BLOCK_NUM >> i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static void rsc_master(struct rsc *rsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) rsc->conj = rsc->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static const struct rsc_ops rsc_generic_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .index = rsc_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .output_slot = audio_ring_slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .master = rsc_master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .next_conj = rsc_next_conj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, struct hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) rsc->idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) rsc->conj = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) rsc->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) rsc->msr = msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) rsc->hw = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) rsc->ops = &rsc_generic_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (!hw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) rsc->ctrl_blk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) case SRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) err = hw->src_rsc_get_ctrl_blk(&rsc->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) case AMIXER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) err = hw->amixer_rsc_get_ctrl_blk(&rsc->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case SRCIMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case SUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case DAIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) dev_err(((struct hw *)hw)->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) "Invalid resource type value %d!\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) dev_err(((struct hw *)hw)->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) "Failed to get resource control block!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int rsc_uninit(struct rsc *rsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if ((NULL != rsc->hw) && (NULL != rsc->ctrl_blk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) switch (rsc->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case SRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) rsc->hw->src_rsc_put_ctrl_blk(rsc->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case AMIXER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) rsc->hw->amixer_rsc_put_ctrl_blk(rsc->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case SUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) case DAIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dev_err(((struct hw *)rsc->hw)->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) "Invalid resource type value %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) rsc->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) rsc->hw = rsc->ctrl_blk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) rsc->idx = rsc->conj = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) rsc->type = NUM_RSCTYP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) rsc->msr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned int amount, struct hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) mgr->type = NUM_RSCTYP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (!mgr->rscs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case SRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) err = hw->src_mgr_get_ctrl_blk(&mgr->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case SRCIMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) err = hw->srcimp_mgr_get_ctrl_blk(&mgr->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) case AMIXER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) err = hw->amixer_mgr_get_ctrl_blk(&mgr->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case DAIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) err = hw->daio_mgr_get_ctrl_blk(hw, &mgr->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case SUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dev_err(hw->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) "Invalid resource type value %d!\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) dev_err(hw->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) "Failed to get manager control block!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) mgr->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) mgr->avail = mgr->amount = amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mgr->hw = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) kfree(mgr->rscs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int rsc_mgr_uninit(struct rsc_mgr *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) kfree(mgr->rscs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) mgr->rscs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if ((NULL != mgr->hw) && (NULL != mgr->ctrl_blk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) switch (mgr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case SRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) mgr->hw->src_mgr_put_ctrl_blk(mgr->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case SRCIMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) mgr->hw->srcimp_mgr_put_ctrl_blk(mgr->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case AMIXER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) mgr->hw->amixer_mgr_put_ctrl_blk(mgr->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case DAIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) mgr->hw->daio_mgr_put_ctrl_blk(mgr->ctrl_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case SUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dev_err(((struct hw *)mgr->hw)->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) "Invalid resource type value %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) mgr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mgr->hw = mgr->ctrl_blk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mgr->type = NUM_RSCTYP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mgr->avail = mgr->amount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }