0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "ctsrc.h"
0016 #include "cthardware.h"
0017 #include <linux/slab.h>
0018
0019 #define SRC_RESOURCE_NUM 256
0020 #define SRCIMP_RESOURCE_NUM 256
0021
0022 static unsigned int conj_mask;
0023
0024 static int src_default_config_memrd(struct src *src);
0025 static int src_default_config_memwr(struct src *src);
0026 static int src_default_config_arcrw(struct src *src);
0027
0028 static int (*src_default_config[3])(struct src *) = {
0029 [MEMRD] = src_default_config_memrd,
0030 [MEMWR] = src_default_config_memwr,
0031 [ARCRW] = src_default_config_arcrw
0032 };
0033
0034 static int src_set_state(struct src *src, unsigned int state)
0035 {
0036 struct hw *hw;
0037
0038 hw = src->rsc.hw;
0039 hw->src_set_state(src->rsc.ctrl_blk, state);
0040
0041 return 0;
0042 }
0043
0044 static int src_set_bm(struct src *src, unsigned int bm)
0045 {
0046 struct hw *hw;
0047
0048 hw = src->rsc.hw;
0049 hw->src_set_bm(src->rsc.ctrl_blk, bm);
0050
0051 return 0;
0052 }
0053
0054 static int src_set_sf(struct src *src, unsigned int sf)
0055 {
0056 struct hw *hw;
0057
0058 hw = src->rsc.hw;
0059 hw->src_set_sf(src->rsc.ctrl_blk, sf);
0060
0061 return 0;
0062 }
0063
0064 static int src_set_pm(struct src *src, unsigned int pm)
0065 {
0066 struct hw *hw;
0067
0068 hw = src->rsc.hw;
0069 hw->src_set_pm(src->rsc.ctrl_blk, pm);
0070
0071 return 0;
0072 }
0073
0074 static int src_set_rom(struct src *src, unsigned int rom)
0075 {
0076 struct hw *hw;
0077
0078 hw = src->rsc.hw;
0079 hw->src_set_rom(src->rsc.ctrl_blk, rom);
0080
0081 return 0;
0082 }
0083
0084 static int src_set_vo(struct src *src, unsigned int vo)
0085 {
0086 struct hw *hw;
0087
0088 hw = src->rsc.hw;
0089 hw->src_set_vo(src->rsc.ctrl_blk, vo);
0090
0091 return 0;
0092 }
0093
0094 static int src_set_st(struct src *src, unsigned int st)
0095 {
0096 struct hw *hw;
0097
0098 hw = src->rsc.hw;
0099 hw->src_set_st(src->rsc.ctrl_blk, st);
0100
0101 return 0;
0102 }
0103
0104 static int src_set_bp(struct src *src, unsigned int bp)
0105 {
0106 struct hw *hw;
0107
0108 hw = src->rsc.hw;
0109 hw->src_set_bp(src->rsc.ctrl_blk, bp);
0110
0111 return 0;
0112 }
0113
0114 static int src_set_cisz(struct src *src, unsigned int cisz)
0115 {
0116 struct hw *hw;
0117
0118 hw = src->rsc.hw;
0119 hw->src_set_cisz(src->rsc.ctrl_blk, cisz);
0120
0121 return 0;
0122 }
0123
0124 static int src_set_ca(struct src *src, unsigned int ca)
0125 {
0126 struct hw *hw;
0127
0128 hw = src->rsc.hw;
0129 hw->src_set_ca(src->rsc.ctrl_blk, ca);
0130
0131 return 0;
0132 }
0133
0134 static int src_set_sa(struct src *src, unsigned int sa)
0135 {
0136 struct hw *hw;
0137
0138 hw = src->rsc.hw;
0139 hw->src_set_sa(src->rsc.ctrl_blk, sa);
0140
0141 return 0;
0142 }
0143
0144 static int src_set_la(struct src *src, unsigned int la)
0145 {
0146 struct hw *hw;
0147
0148 hw = src->rsc.hw;
0149 hw->src_set_la(src->rsc.ctrl_blk, la);
0150
0151 return 0;
0152 }
0153
0154 static int src_set_pitch(struct src *src, unsigned int pitch)
0155 {
0156 struct hw *hw;
0157
0158 hw = src->rsc.hw;
0159 hw->src_set_pitch(src->rsc.ctrl_blk, pitch);
0160
0161 return 0;
0162 }
0163
0164 static int src_set_clear_zbufs(struct src *src)
0165 {
0166 struct hw *hw;
0167
0168 hw = src->rsc.hw;
0169 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
0170
0171 return 0;
0172 }
0173
0174 static int src_commit_write(struct src *src)
0175 {
0176 struct hw *hw;
0177 int i;
0178 unsigned int dirty = 0;
0179
0180 hw = src->rsc.hw;
0181 src->rsc.ops->master(&src->rsc);
0182 if (src->rsc.msr > 1) {
0183
0184 dirty = hw->src_get_dirty(src->rsc.ctrl_blk) & conj_mask;
0185 }
0186 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
0187 src->rsc.ctrl_blk);
0188
0189
0190 if (MEMWR == src->mode)
0191 return 0;
0192
0193 for (i = 1; i < src->rsc.msr; i++) {
0194 src->rsc.ops->next_conj(&src->rsc);
0195 hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
0196 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
0197 src->rsc.ctrl_blk);
0198 }
0199 src->rsc.ops->master(&src->rsc);
0200
0201 return 0;
0202 }
0203
0204 static int src_get_ca(struct src *src)
0205 {
0206 struct hw *hw;
0207
0208 hw = src->rsc.hw;
0209 return hw->src_get_ca(hw, src->rsc.ops->index(&src->rsc),
0210 src->rsc.ctrl_blk);
0211 }
0212
0213 static int src_init(struct src *src)
0214 {
0215 src_default_config[src->mode](src);
0216
0217 return 0;
0218 }
0219
0220 static struct src *src_next_interleave(struct src *src)
0221 {
0222 return src->intlv;
0223 }
0224
0225 static int src_default_config_memrd(struct src *src)
0226 {
0227 struct hw *hw = src->rsc.hw;
0228 unsigned int rsr, msr;
0229
0230 hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
0231 hw->src_set_bm(src->rsc.ctrl_blk, 1);
0232 for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
0233 rsr++;
0234
0235 hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
0236 hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
0237 hw->src_set_wr(src->rsc.ctrl_blk, 0);
0238 hw->src_set_pm(src->rsc.ctrl_blk, 0);
0239 hw->src_set_rom(src->rsc.ctrl_blk, 0);
0240 hw->src_set_vo(src->rsc.ctrl_blk, 0);
0241 hw->src_set_st(src->rsc.ctrl_blk, 0);
0242 hw->src_set_ilsz(src->rsc.ctrl_blk, src->multi - 1);
0243 hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
0244 hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
0245 hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
0246 hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
0247 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
0248 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
0249
0250 src->rsc.ops->master(&src->rsc);
0251 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
0252 src->rsc.ctrl_blk);
0253
0254 for (msr = 1; msr < src->rsc.msr; msr++) {
0255 src->rsc.ops->next_conj(&src->rsc);
0256 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
0257 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
0258 src->rsc.ctrl_blk);
0259 }
0260 src->rsc.ops->master(&src->rsc);
0261
0262 return 0;
0263 }
0264
0265 static int src_default_config_memwr(struct src *src)
0266 {
0267 struct hw *hw = src->rsc.hw;
0268
0269 hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
0270 hw->src_set_bm(src->rsc.ctrl_blk, 1);
0271 hw->src_set_rsr(src->rsc.ctrl_blk, 0);
0272 hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
0273 hw->src_set_wr(src->rsc.ctrl_blk, 1);
0274 hw->src_set_pm(src->rsc.ctrl_blk, 0);
0275 hw->src_set_rom(src->rsc.ctrl_blk, 0);
0276 hw->src_set_vo(src->rsc.ctrl_blk, 0);
0277 hw->src_set_st(src->rsc.ctrl_blk, 0);
0278 hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
0279 hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
0280 hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
0281 hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
0282 hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
0283 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
0284 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
0285
0286 src->rsc.ops->master(&src->rsc);
0287 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
0288 src->rsc.ctrl_blk);
0289
0290 return 0;
0291 }
0292
0293 static int src_default_config_arcrw(struct src *src)
0294 {
0295 struct hw *hw = src->rsc.hw;
0296 unsigned int rsr, msr;
0297 unsigned int dirty;
0298
0299 hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
0300 hw->src_set_bm(src->rsc.ctrl_blk, 0);
0301 for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
0302 rsr++;
0303
0304 hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
0305 hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_F32);
0306 hw->src_set_wr(src->rsc.ctrl_blk, 0);
0307 hw->src_set_pm(src->rsc.ctrl_blk, 0);
0308 hw->src_set_rom(src->rsc.ctrl_blk, 0);
0309 hw->src_set_vo(src->rsc.ctrl_blk, 0);
0310 hw->src_set_st(src->rsc.ctrl_blk, 0);
0311 hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
0312 hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
0313 hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
0314
0315 hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
0316
0317 hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
0318 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
0319 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
0320
0321 dirty = hw->src_get_dirty(src->rsc.ctrl_blk);
0322 src->rsc.ops->master(&src->rsc);
0323 for (msr = 0; msr < src->rsc.msr; msr++) {
0324 hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
0325 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
0326 src->rsc.ctrl_blk);
0327 src->rsc.ops->next_conj(&src->rsc);
0328 }
0329 src->rsc.ops->master(&src->rsc);
0330
0331 return 0;
0332 }
0333
0334 static const struct src_rsc_ops src_rsc_ops = {
0335 .set_state = src_set_state,
0336 .set_bm = src_set_bm,
0337 .set_sf = src_set_sf,
0338 .set_pm = src_set_pm,
0339 .set_rom = src_set_rom,
0340 .set_vo = src_set_vo,
0341 .set_st = src_set_st,
0342 .set_bp = src_set_bp,
0343 .set_cisz = src_set_cisz,
0344 .set_ca = src_set_ca,
0345 .set_sa = src_set_sa,
0346 .set_la = src_set_la,
0347 .set_pitch = src_set_pitch,
0348 .set_clr_zbufs = src_set_clear_zbufs,
0349 .commit_write = src_commit_write,
0350 .get_ca = src_get_ca,
0351 .init = src_init,
0352 .next_interleave = src_next_interleave,
0353 };
0354
0355 static int
0356 src_rsc_init(struct src *src, u32 idx,
0357 const struct src_desc *desc, struct src_mgr *mgr)
0358 {
0359 int err;
0360 int i, n;
0361 struct src *p;
0362
0363 n = (MEMRD == desc->mode) ? desc->multi : 1;
0364 for (i = 0, p = src; i < n; i++, p++) {
0365 err = rsc_init(&p->rsc, idx + i, SRC, desc->msr, mgr->mgr.hw);
0366 if (err)
0367 goto error1;
0368
0369
0370 p->ops = &src_rsc_ops;
0371 p->multi = (0 == i) ? desc->multi : 1;
0372 p->mode = desc->mode;
0373 src_default_config[desc->mode](p);
0374 mgr->src_enable(mgr, p);
0375 p->intlv = p + 1;
0376 }
0377 (--p)->intlv = NULL;
0378
0379 mgr->commit_write(mgr);
0380
0381 return 0;
0382
0383 error1:
0384 for (i--, p--; i >= 0; i--, p--) {
0385 mgr->src_disable(mgr, p);
0386 rsc_uninit(&p->rsc);
0387 }
0388 mgr->commit_write(mgr);
0389 return err;
0390 }
0391
0392 static int src_rsc_uninit(struct src *src, struct src_mgr *mgr)
0393 {
0394 int i, n;
0395 struct src *p;
0396
0397 n = (MEMRD == src->mode) ? src->multi : 1;
0398 for (i = 0, p = src; i < n; i++, p++) {
0399 mgr->src_disable(mgr, p);
0400 rsc_uninit(&p->rsc);
0401 p->multi = 0;
0402 p->ops = NULL;
0403 p->mode = NUM_SRCMODES;
0404 p->intlv = NULL;
0405 }
0406 mgr->commit_write(mgr);
0407
0408 return 0;
0409 }
0410
0411 static int
0412 get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc)
0413 {
0414 unsigned int idx = SRC_RESOURCE_NUM;
0415 int err;
0416 struct src *src;
0417 unsigned long flags;
0418
0419 *rsrc = NULL;
0420
0421
0422 spin_lock_irqsave(&mgr->mgr_lock, flags);
0423 if (MEMRD == desc->mode)
0424 err = mgr_get_resource(&mgr->mgr, desc->multi, &idx);
0425 else
0426 err = mgr_get_resource(&mgr->mgr, 1, &idx);
0427
0428 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
0429 if (err) {
0430 dev_err(mgr->card->dev,
0431 "Can't meet SRC resource request!\n");
0432 return err;
0433 }
0434
0435
0436 if (MEMRD == desc->mode)
0437 src = kcalloc(desc->multi, sizeof(*src), GFP_KERNEL);
0438 else
0439 src = kzalloc(sizeof(*src), GFP_KERNEL);
0440
0441 if (!src) {
0442 err = -ENOMEM;
0443 goto error1;
0444 }
0445
0446 err = src_rsc_init(src, idx, desc, mgr);
0447 if (err)
0448 goto error2;
0449
0450 *rsrc = src;
0451
0452 return 0;
0453
0454 error2:
0455 kfree(src);
0456 error1:
0457 spin_lock_irqsave(&mgr->mgr_lock, flags);
0458 if (MEMRD == desc->mode)
0459 mgr_put_resource(&mgr->mgr, desc->multi, idx);
0460 else
0461 mgr_put_resource(&mgr->mgr, 1, idx);
0462
0463 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
0464 return err;
0465 }
0466
0467 static int put_src_rsc(struct src_mgr *mgr, struct src *src)
0468 {
0469 unsigned long flags;
0470
0471 spin_lock_irqsave(&mgr->mgr_lock, flags);
0472 src->rsc.ops->master(&src->rsc);
0473 if (MEMRD == src->mode)
0474 mgr_put_resource(&mgr->mgr, src->multi,
0475 src->rsc.ops->index(&src->rsc));
0476 else
0477 mgr_put_resource(&mgr->mgr, 1, src->rsc.ops->index(&src->rsc));
0478
0479 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
0480 src_rsc_uninit(src, mgr);
0481 kfree(src);
0482
0483 return 0;
0484 }
0485
0486 static int src_enable_s(struct src_mgr *mgr, struct src *src)
0487 {
0488 struct hw *hw = mgr->mgr.hw;
0489 int i;
0490
0491 src->rsc.ops->master(&src->rsc);
0492 for (i = 0; i < src->rsc.msr; i++) {
0493 hw->src_mgr_enbs_src(mgr->mgr.ctrl_blk,
0494 src->rsc.ops->index(&src->rsc));
0495 src->rsc.ops->next_conj(&src->rsc);
0496 }
0497 src->rsc.ops->master(&src->rsc);
0498
0499 return 0;
0500 }
0501
0502 static int src_enable(struct src_mgr *mgr, struct src *src)
0503 {
0504 struct hw *hw = mgr->mgr.hw;
0505 int i;
0506
0507 src->rsc.ops->master(&src->rsc);
0508 for (i = 0; i < src->rsc.msr; i++) {
0509 hw->src_mgr_enb_src(mgr->mgr.ctrl_blk,
0510 src->rsc.ops->index(&src->rsc));
0511 src->rsc.ops->next_conj(&src->rsc);
0512 }
0513 src->rsc.ops->master(&src->rsc);
0514
0515 return 0;
0516 }
0517
0518 static int src_disable(struct src_mgr *mgr, struct src *src)
0519 {
0520 struct hw *hw = mgr->mgr.hw;
0521 int i;
0522
0523 src->rsc.ops->master(&src->rsc);
0524 for (i = 0; i < src->rsc.msr; i++) {
0525 hw->src_mgr_dsb_src(mgr->mgr.ctrl_blk,
0526 src->rsc.ops->index(&src->rsc));
0527 src->rsc.ops->next_conj(&src->rsc);
0528 }
0529 src->rsc.ops->master(&src->rsc);
0530
0531 return 0;
0532 }
0533
0534 static int src_mgr_commit_write(struct src_mgr *mgr)
0535 {
0536 struct hw *hw = mgr->mgr.hw;
0537
0538 hw->src_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
0539
0540 return 0;
0541 }
0542
0543 int src_mgr_create(struct hw *hw, struct src_mgr **rsrc_mgr)
0544 {
0545 int err, i;
0546 struct src_mgr *src_mgr;
0547
0548 *rsrc_mgr = NULL;
0549 src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL);
0550 if (!src_mgr)
0551 return -ENOMEM;
0552
0553 err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw);
0554 if (err)
0555 goto error1;
0556
0557 spin_lock_init(&src_mgr->mgr_lock);
0558 conj_mask = hw->src_dirty_conj_mask();
0559
0560 src_mgr->get_src = get_src_rsc;
0561 src_mgr->put_src = put_src_rsc;
0562 src_mgr->src_enable_s = src_enable_s;
0563 src_mgr->src_enable = src_enable;
0564 src_mgr->src_disable = src_disable;
0565 src_mgr->commit_write = src_mgr_commit_write;
0566 src_mgr->card = hw->card;
0567
0568
0569 for (i = 0; i < 256; i++)
0570 hw->src_mgr_dsb_src(src_mgr->mgr.ctrl_blk, i);
0571
0572 hw->src_mgr_commit_write(hw, src_mgr->mgr.ctrl_blk);
0573
0574 *rsrc_mgr = src_mgr;
0575
0576 return 0;
0577
0578 error1:
0579 kfree(src_mgr);
0580 return err;
0581 }
0582
0583 int src_mgr_destroy(struct src_mgr *src_mgr)
0584 {
0585 rsc_mgr_uninit(&src_mgr->mgr);
0586 kfree(src_mgr);
0587
0588 return 0;
0589 }
0590
0591
0592
0593 static void srcimp_master(struct rsc *rsc)
0594 {
0595 rsc->conj = 0;
0596 rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0];
0597 }
0598
0599 static void srcimp_next_conj(struct rsc *rsc)
0600 {
0601 rsc->conj++;
0602 }
0603
0604 static int srcimp_index(const struct rsc *rsc)
0605 {
0606 return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
0607 }
0608
0609 static const struct rsc_ops srcimp_basic_rsc_ops = {
0610 .master = srcimp_master,
0611 .next_conj = srcimp_next_conj,
0612 .index = srcimp_index,
0613 .output_slot = NULL,
0614 };
0615
0616 static int srcimp_map(struct srcimp *srcimp, struct src *src, struct rsc *input)
0617 {
0618 struct imapper *entry;
0619 int i;
0620
0621 srcimp->rsc.ops->master(&srcimp->rsc);
0622 src->rsc.ops->master(&src->rsc);
0623 input->ops->master(input);
0624
0625
0626 for (i = 0; i < srcimp->rsc.msr; i++) {
0627 entry = &srcimp->imappers[i];
0628 entry->slot = input->ops->output_slot(input);
0629 entry->user = src->rsc.ops->index(&src->rsc);
0630 entry->addr = srcimp->rsc.ops->index(&srcimp->rsc);
0631 srcimp->mgr->imap_add(srcimp->mgr, entry);
0632 srcimp->mapped |= (0x1 << i);
0633
0634 srcimp->rsc.ops->next_conj(&srcimp->rsc);
0635 input->ops->next_conj(input);
0636 }
0637
0638 srcimp->rsc.ops->master(&srcimp->rsc);
0639 input->ops->master(input);
0640
0641 return 0;
0642 }
0643
0644 static int srcimp_unmap(struct srcimp *srcimp)
0645 {
0646 int i;
0647
0648
0649 for (i = 0; i < srcimp->rsc.msr; i++) {
0650 if (srcimp->mapped & (0x1 << i)) {
0651 srcimp->mgr->imap_delete(srcimp->mgr,
0652 &srcimp->imappers[i]);
0653 srcimp->mapped &= ~(0x1 << i);
0654 }
0655 }
0656
0657 return 0;
0658 }
0659
0660 static const struct srcimp_rsc_ops srcimp_ops = {
0661 .map = srcimp_map,
0662 .unmap = srcimp_unmap
0663 };
0664
0665 static int srcimp_rsc_init(struct srcimp *srcimp,
0666 const struct srcimp_desc *desc,
0667 struct srcimp_mgr *mgr)
0668 {
0669 int err;
0670
0671 err = rsc_init(&srcimp->rsc, srcimp->idx[0],
0672 SRCIMP, desc->msr, mgr->mgr.hw);
0673 if (err)
0674 return err;
0675
0676
0677 srcimp->imappers = kcalloc(desc->msr, sizeof(struct imapper),
0678 GFP_KERNEL);
0679 if (!srcimp->imappers) {
0680 err = -ENOMEM;
0681 goto error1;
0682 }
0683
0684
0685 srcimp->rsc.ops = &srcimp_basic_rsc_ops;
0686 srcimp->ops = &srcimp_ops;
0687 srcimp->mgr = mgr;
0688
0689 srcimp->rsc.ops->master(&srcimp->rsc);
0690
0691 return 0;
0692
0693 error1:
0694 rsc_uninit(&srcimp->rsc);
0695 return err;
0696 }
0697
0698 static int srcimp_rsc_uninit(struct srcimp *srcimp)
0699 {
0700 kfree(srcimp->imappers);
0701 srcimp->imappers = NULL;
0702 srcimp->ops = NULL;
0703 srcimp->mgr = NULL;
0704 rsc_uninit(&srcimp->rsc);
0705
0706 return 0;
0707 }
0708
0709 static int get_srcimp_rsc(struct srcimp_mgr *mgr,
0710 const struct srcimp_desc *desc,
0711 struct srcimp **rsrcimp)
0712 {
0713 int err, i;
0714 unsigned int idx;
0715 struct srcimp *srcimp;
0716 unsigned long flags;
0717
0718 *rsrcimp = NULL;
0719
0720
0721 srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL);
0722 if (!srcimp)
0723 return -ENOMEM;
0724
0725
0726 err = 0;
0727 spin_lock_irqsave(&mgr->mgr_lock, flags);
0728 for (i = 0; i < desc->msr; i++) {
0729 err = mgr_get_resource(&mgr->mgr, 1, &idx);
0730 if (err)
0731 break;
0732
0733 srcimp->idx[i] = idx;
0734 }
0735 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
0736 if (err) {
0737 dev_err(mgr->card->dev,
0738 "Can't meet SRCIMP resource request!\n");
0739 goto error1;
0740 }
0741
0742 err = srcimp_rsc_init(srcimp, desc, mgr);
0743 if (err)
0744 goto error1;
0745
0746 *rsrcimp = srcimp;
0747
0748 return 0;
0749
0750 error1:
0751 spin_lock_irqsave(&mgr->mgr_lock, flags);
0752 for (i--; i >= 0; i--)
0753 mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
0754
0755 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
0756 kfree(srcimp);
0757 return err;
0758 }
0759
0760 static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp)
0761 {
0762 unsigned long flags;
0763 int i;
0764
0765 spin_lock_irqsave(&mgr->mgr_lock, flags);
0766 for (i = 0; i < srcimp->rsc.msr; i++)
0767 mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
0768
0769 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
0770 srcimp_rsc_uninit(srcimp);
0771 kfree(srcimp);
0772
0773 return 0;
0774 }
0775
0776 static int srcimp_map_op(void *data, struct imapper *entry)
0777 {
0778 struct rsc_mgr *mgr = &((struct srcimp_mgr *)data)->mgr;
0779 struct hw *hw = mgr->hw;
0780
0781 hw->srcimp_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
0782 hw->srcimp_mgr_set_imapuser(mgr->ctrl_blk, entry->user);
0783 hw->srcimp_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
0784 hw->srcimp_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
0785 hw->srcimp_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
0786
0787 return 0;
0788 }
0789
0790 static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry)
0791 {
0792 unsigned long flags;
0793 int err;
0794
0795 spin_lock_irqsave(&mgr->imap_lock, flags);
0796 if ((0 == entry->addr) && (mgr->init_imap_added)) {
0797 input_mapper_delete(&mgr->imappers,
0798 mgr->init_imap, srcimp_map_op, mgr);
0799 mgr->init_imap_added = 0;
0800 }
0801 err = input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr);
0802 spin_unlock_irqrestore(&mgr->imap_lock, flags);
0803
0804 return err;
0805 }
0806
0807 static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry)
0808 {
0809 unsigned long flags;
0810 int err;
0811
0812 spin_lock_irqsave(&mgr->imap_lock, flags);
0813 err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr);
0814 if (list_empty(&mgr->imappers)) {
0815 input_mapper_add(&mgr->imappers, mgr->init_imap,
0816 srcimp_map_op, mgr);
0817 mgr->init_imap_added = 1;
0818 }
0819 spin_unlock_irqrestore(&mgr->imap_lock, flags);
0820
0821 return err;
0822 }
0823
0824 int srcimp_mgr_create(struct hw *hw, struct srcimp_mgr **rsrcimp_mgr)
0825 {
0826 int err;
0827 struct srcimp_mgr *srcimp_mgr;
0828 struct imapper *entry;
0829
0830 *rsrcimp_mgr = NULL;
0831 srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL);
0832 if (!srcimp_mgr)
0833 return -ENOMEM;
0834
0835 err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw);
0836 if (err)
0837 goto error1;
0838
0839 spin_lock_init(&srcimp_mgr->mgr_lock);
0840 spin_lock_init(&srcimp_mgr->imap_lock);
0841 INIT_LIST_HEAD(&srcimp_mgr->imappers);
0842 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
0843 if (!entry) {
0844 err = -ENOMEM;
0845 goto error2;
0846 }
0847 entry->slot = entry->addr = entry->next = entry->user = 0;
0848 list_add(&entry->list, &srcimp_mgr->imappers);
0849 srcimp_mgr->init_imap = entry;
0850 srcimp_mgr->init_imap_added = 1;
0851
0852 srcimp_mgr->get_srcimp = get_srcimp_rsc;
0853 srcimp_mgr->put_srcimp = put_srcimp_rsc;
0854 srcimp_mgr->imap_add = srcimp_imap_add;
0855 srcimp_mgr->imap_delete = srcimp_imap_delete;
0856 srcimp_mgr->card = hw->card;
0857
0858 *rsrcimp_mgr = srcimp_mgr;
0859
0860 return 0;
0861
0862 error2:
0863 rsc_mgr_uninit(&srcimp_mgr->mgr);
0864 error1:
0865 kfree(srcimp_mgr);
0866 return err;
0867 }
0868
0869 int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr)
0870 {
0871 unsigned long flags;
0872
0873
0874 spin_lock_irqsave(&srcimp_mgr->imap_lock, flags);
0875 free_input_mapper_list(&srcimp_mgr->imappers);
0876 spin_unlock_irqrestore(&srcimp_mgr->imap_lock, flags);
0877
0878 rsc_mgr_uninit(&srcimp_mgr->mgr);
0879 kfree(srcimp_mgr);
0880
0881 return 0;
0882 }