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