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