0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/interrupt.h>
0010 #include <linux/spinlock.h>
0011 #include <linux/mutex.h>
0012 #include <linux/delay.h>
0013 #include <linux/slab.h>
0014 #include <linux/err.h>
0015 #include <linux/module.h>
0016 #include <linux/device.h>
0017 #include <linux/bitops.h>
0018 #include <linux/mailbox_client.h>
0019 #include <linux/mailbox_controller.h>
0020
0021 #include "mailbox.h"
0022
0023 static LIST_HEAD(mbox_cons);
0024 static DEFINE_MUTEX(con_mutex);
0025
0026 static int add_to_rbuf(struct mbox_chan *chan, void *mssg)
0027 {
0028 int idx;
0029 unsigned long flags;
0030
0031 spin_lock_irqsave(&chan->lock, flags);
0032
0033
0034 if (chan->msg_count == MBOX_TX_QUEUE_LEN) {
0035 spin_unlock_irqrestore(&chan->lock, flags);
0036 return -ENOBUFS;
0037 }
0038
0039 idx = chan->msg_free;
0040 chan->msg_data[idx] = mssg;
0041 chan->msg_count++;
0042
0043 if (idx == MBOX_TX_QUEUE_LEN - 1)
0044 chan->msg_free = 0;
0045 else
0046 chan->msg_free++;
0047
0048 spin_unlock_irqrestore(&chan->lock, flags);
0049
0050 return idx;
0051 }
0052
0053 static void msg_submit(struct mbox_chan *chan)
0054 {
0055 unsigned count, idx;
0056 unsigned long flags;
0057 void *data;
0058 int err = -EBUSY;
0059
0060 spin_lock_irqsave(&chan->lock, flags);
0061
0062 if (!chan->msg_count || chan->active_req)
0063 goto exit;
0064
0065 count = chan->msg_count;
0066 idx = chan->msg_free;
0067 if (idx >= count)
0068 idx -= count;
0069 else
0070 idx += MBOX_TX_QUEUE_LEN - count;
0071
0072 data = chan->msg_data[idx];
0073
0074 if (chan->cl->tx_prepare)
0075 chan->cl->tx_prepare(chan->cl, data);
0076
0077 err = chan->mbox->ops->send_data(chan, data);
0078 if (!err) {
0079 chan->active_req = data;
0080 chan->msg_count--;
0081 }
0082 exit:
0083 spin_unlock_irqrestore(&chan->lock, flags);
0084
0085 if (!err && (chan->txdone_method & TXDONE_BY_POLL)) {
0086
0087 spin_lock_irqsave(&chan->mbox->poll_hrt_lock, flags);
0088 hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL);
0089 spin_unlock_irqrestore(&chan->mbox->poll_hrt_lock, flags);
0090 }
0091 }
0092
0093 static void tx_tick(struct mbox_chan *chan, int r)
0094 {
0095 unsigned long flags;
0096 void *mssg;
0097
0098 spin_lock_irqsave(&chan->lock, flags);
0099 mssg = chan->active_req;
0100 chan->active_req = NULL;
0101 spin_unlock_irqrestore(&chan->lock, flags);
0102
0103
0104 msg_submit(chan);
0105
0106 if (!mssg)
0107 return;
0108
0109
0110 if (chan->cl->tx_done)
0111 chan->cl->tx_done(chan->cl, mssg, r);
0112
0113 if (r != -ETIME && chan->cl->tx_block)
0114 complete(&chan->tx_complete);
0115 }
0116
0117 static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer)
0118 {
0119 struct mbox_controller *mbox =
0120 container_of(hrtimer, struct mbox_controller, poll_hrt);
0121 bool txdone, resched = false;
0122 int i;
0123 unsigned long flags;
0124
0125 for (i = 0; i < mbox->num_chans; i++) {
0126 struct mbox_chan *chan = &mbox->chans[i];
0127
0128 if (chan->active_req && chan->cl) {
0129 txdone = chan->mbox->ops->last_tx_done(chan);
0130 if (txdone)
0131 tx_tick(chan, 0);
0132 else
0133 resched = true;
0134 }
0135 }
0136
0137 if (resched) {
0138 spin_lock_irqsave(&mbox->poll_hrt_lock, flags);
0139 if (!hrtimer_is_queued(hrtimer))
0140 hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period));
0141 spin_unlock_irqrestore(&mbox->poll_hrt_lock, flags);
0142
0143 return HRTIMER_RESTART;
0144 }
0145 return HRTIMER_NORESTART;
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)
0159 {
0160
0161 if (chan->cl->rx_callback)
0162 chan->cl->rx_callback(chan->cl, mssg);
0163 }
0164 EXPORT_SYMBOL_GPL(mbox_chan_received_data);
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 void mbox_chan_txdone(struct mbox_chan *chan, int r)
0177 {
0178 if (unlikely(!(chan->txdone_method & TXDONE_BY_IRQ))) {
0179 dev_err(chan->mbox->dev,
0180 "Controller can't run the TX ticker\n");
0181 return;
0182 }
0183
0184 tx_tick(chan, r);
0185 }
0186 EXPORT_SYMBOL_GPL(mbox_chan_txdone);
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 void mbox_client_txdone(struct mbox_chan *chan, int r)
0198 {
0199 if (unlikely(!(chan->txdone_method & TXDONE_BY_ACK))) {
0200 dev_err(chan->mbox->dev, "Client can't run the TX ticker\n");
0201 return;
0202 }
0203
0204 tx_tick(chan, r);
0205 }
0206 EXPORT_SYMBOL_GPL(mbox_client_txdone);
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223 bool mbox_client_peek_data(struct mbox_chan *chan)
0224 {
0225 if (chan->mbox->ops->peek_data)
0226 return chan->mbox->ops->peek_data(chan);
0227
0228 return false;
0229 }
0230 EXPORT_SYMBOL_GPL(mbox_client_peek_data);
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 int mbox_send_message(struct mbox_chan *chan, void *mssg)
0257 {
0258 int t;
0259
0260 if (!chan || !chan->cl)
0261 return -EINVAL;
0262
0263 t = add_to_rbuf(chan, mssg);
0264 if (t < 0) {
0265 dev_err(chan->mbox->dev, "Try increasing MBOX_TX_QUEUE_LEN\n");
0266 return t;
0267 }
0268
0269 msg_submit(chan);
0270
0271 if (chan->cl->tx_block) {
0272 unsigned long wait;
0273 int ret;
0274
0275 if (!chan->cl->tx_tout)
0276 wait = msecs_to_jiffies(3600000);
0277 else
0278 wait = msecs_to_jiffies(chan->cl->tx_tout);
0279
0280 ret = wait_for_completion_timeout(&chan->tx_complete, wait);
0281 if (ret == 0) {
0282 t = -ETIME;
0283 tx_tick(chan, t);
0284 }
0285 }
0286
0287 return t;
0288 }
0289 EXPORT_SYMBOL_GPL(mbox_send_message);
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 int mbox_flush(struct mbox_chan *chan, unsigned long timeout)
0306 {
0307 int ret;
0308
0309 if (!chan->mbox->ops->flush)
0310 return -ENOTSUPP;
0311
0312 ret = chan->mbox->ops->flush(chan, timeout);
0313 if (ret < 0)
0314 tx_tick(chan, ret);
0315
0316 return ret;
0317 }
0318 EXPORT_SYMBOL_GPL(mbox_flush);
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
0338 {
0339 struct device *dev = cl->dev;
0340 struct mbox_controller *mbox;
0341 struct of_phandle_args spec;
0342 struct mbox_chan *chan;
0343 unsigned long flags;
0344 int ret;
0345
0346 if (!dev || !dev->of_node) {
0347 pr_debug("%s: No owner device node\n", __func__);
0348 return ERR_PTR(-ENODEV);
0349 }
0350
0351 mutex_lock(&con_mutex);
0352
0353 if (of_parse_phandle_with_args(dev->of_node, "mboxes",
0354 "#mbox-cells", index, &spec)) {
0355 dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__);
0356 mutex_unlock(&con_mutex);
0357 return ERR_PTR(-ENODEV);
0358 }
0359
0360 chan = ERR_PTR(-EPROBE_DEFER);
0361 list_for_each_entry(mbox, &mbox_cons, node)
0362 if (mbox->dev->of_node == spec.np) {
0363 chan = mbox->of_xlate(mbox, &spec);
0364 if (!IS_ERR(chan))
0365 break;
0366 }
0367
0368 of_node_put(spec.np);
0369
0370 if (IS_ERR(chan)) {
0371 mutex_unlock(&con_mutex);
0372 return chan;
0373 }
0374
0375 if (chan->cl || !try_module_get(mbox->dev->driver->owner)) {
0376 dev_dbg(dev, "%s: mailbox not free\n", __func__);
0377 mutex_unlock(&con_mutex);
0378 return ERR_PTR(-EBUSY);
0379 }
0380
0381 spin_lock_irqsave(&chan->lock, flags);
0382 chan->msg_free = 0;
0383 chan->msg_count = 0;
0384 chan->active_req = NULL;
0385 chan->cl = cl;
0386 init_completion(&chan->tx_complete);
0387
0388 if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
0389 chan->txdone_method = TXDONE_BY_ACK;
0390
0391 spin_unlock_irqrestore(&chan->lock, flags);
0392
0393 if (chan->mbox->ops->startup) {
0394 ret = chan->mbox->ops->startup(chan);
0395
0396 if (ret) {
0397 dev_err(dev, "Unable to startup the chan (%d)\n", ret);
0398 mbox_free_channel(chan);
0399 chan = ERR_PTR(ret);
0400 }
0401 }
0402
0403 mutex_unlock(&con_mutex);
0404 return chan;
0405 }
0406 EXPORT_SYMBOL_GPL(mbox_request_channel);
0407
0408 struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
0409 const char *name)
0410 {
0411 struct device_node *np = cl->dev->of_node;
0412 struct property *prop;
0413 const char *mbox_name;
0414 int index = 0;
0415
0416 if (!np) {
0417 dev_err(cl->dev, "%s() currently only supports DT\n", __func__);
0418 return ERR_PTR(-EINVAL);
0419 }
0420
0421 if (!of_get_property(np, "mbox-names", NULL)) {
0422 dev_err(cl->dev,
0423 "%s() requires an \"mbox-names\" property\n", __func__);
0424 return ERR_PTR(-EINVAL);
0425 }
0426
0427 of_property_for_each_string(np, "mbox-names", prop, mbox_name) {
0428 if (!strncmp(name, mbox_name, strlen(name)))
0429 return mbox_request_channel(cl, index);
0430 index++;
0431 }
0432
0433 dev_err(cl->dev, "%s() could not locate channel named \"%s\"\n",
0434 __func__, name);
0435 return ERR_PTR(-EINVAL);
0436 }
0437 EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
0438
0439
0440
0441
0442
0443
0444 void mbox_free_channel(struct mbox_chan *chan)
0445 {
0446 unsigned long flags;
0447
0448 if (!chan || !chan->cl)
0449 return;
0450
0451 if (chan->mbox->ops->shutdown)
0452 chan->mbox->ops->shutdown(chan);
0453
0454
0455 spin_lock_irqsave(&chan->lock, flags);
0456 chan->cl = NULL;
0457 chan->active_req = NULL;
0458 if (chan->txdone_method == TXDONE_BY_ACK)
0459 chan->txdone_method = TXDONE_BY_POLL;
0460
0461 module_put(chan->mbox->dev->driver->owner);
0462 spin_unlock_irqrestore(&chan->lock, flags);
0463 }
0464 EXPORT_SYMBOL_GPL(mbox_free_channel);
0465
0466 static struct mbox_chan *
0467 of_mbox_index_xlate(struct mbox_controller *mbox,
0468 const struct of_phandle_args *sp)
0469 {
0470 int ind = sp->args[0];
0471
0472 if (ind >= mbox->num_chans)
0473 return ERR_PTR(-EINVAL);
0474
0475 return &mbox->chans[ind];
0476 }
0477
0478
0479
0480
0481
0482
0483
0484 int mbox_controller_register(struct mbox_controller *mbox)
0485 {
0486 int i, txdone;
0487
0488
0489 if (!mbox || !mbox->dev || !mbox->ops || !mbox->num_chans)
0490 return -EINVAL;
0491
0492 if (mbox->txdone_irq)
0493 txdone = TXDONE_BY_IRQ;
0494 else if (mbox->txdone_poll)
0495 txdone = TXDONE_BY_POLL;
0496 else
0497 txdone = TXDONE_BY_ACK;
0498
0499 if (txdone == TXDONE_BY_POLL) {
0500
0501 if (!mbox->ops->last_tx_done) {
0502 dev_err(mbox->dev, "last_tx_done method is absent\n");
0503 return -EINVAL;
0504 }
0505
0506 hrtimer_init(&mbox->poll_hrt, CLOCK_MONOTONIC,
0507 HRTIMER_MODE_REL);
0508 mbox->poll_hrt.function = txdone_hrtimer;
0509 spin_lock_init(&mbox->poll_hrt_lock);
0510 }
0511
0512 for (i = 0; i < mbox->num_chans; i++) {
0513 struct mbox_chan *chan = &mbox->chans[i];
0514
0515 chan->cl = NULL;
0516 chan->mbox = mbox;
0517 chan->txdone_method = txdone;
0518 spin_lock_init(&chan->lock);
0519 }
0520
0521 if (!mbox->of_xlate)
0522 mbox->of_xlate = of_mbox_index_xlate;
0523
0524 mutex_lock(&con_mutex);
0525 list_add_tail(&mbox->node, &mbox_cons);
0526 mutex_unlock(&con_mutex);
0527
0528 return 0;
0529 }
0530 EXPORT_SYMBOL_GPL(mbox_controller_register);
0531
0532
0533
0534
0535
0536 void mbox_controller_unregister(struct mbox_controller *mbox)
0537 {
0538 int i;
0539
0540 if (!mbox)
0541 return;
0542
0543 mutex_lock(&con_mutex);
0544
0545 list_del(&mbox->node);
0546
0547 for (i = 0; i < mbox->num_chans; i++)
0548 mbox_free_channel(&mbox->chans[i]);
0549
0550 if (mbox->txdone_poll)
0551 hrtimer_cancel(&mbox->poll_hrt);
0552
0553 mutex_unlock(&con_mutex);
0554 }
0555 EXPORT_SYMBOL_GPL(mbox_controller_unregister);
0556
0557 static void __devm_mbox_controller_unregister(struct device *dev, void *res)
0558 {
0559 struct mbox_controller **mbox = res;
0560
0561 mbox_controller_unregister(*mbox);
0562 }
0563
0564 static int devm_mbox_controller_match(struct device *dev, void *res, void *data)
0565 {
0566 struct mbox_controller **mbox = res;
0567
0568 if (WARN_ON(!mbox || !*mbox))
0569 return 0;
0570
0571 return *mbox == data;
0572 }
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586 int devm_mbox_controller_register(struct device *dev,
0587 struct mbox_controller *mbox)
0588 {
0589 struct mbox_controller **ptr;
0590 int err;
0591
0592 ptr = devres_alloc(__devm_mbox_controller_unregister, sizeof(*ptr),
0593 GFP_KERNEL);
0594 if (!ptr)
0595 return -ENOMEM;
0596
0597 err = mbox_controller_register(mbox);
0598 if (err < 0) {
0599 devres_free(ptr);
0600 return err;
0601 }
0602
0603 devres_add(dev, ptr);
0604 *ptr = mbox;
0605
0606 return 0;
0607 }
0608 EXPORT_SYMBOL_GPL(devm_mbox_controller_register);
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620 void devm_mbox_controller_unregister(struct device *dev, struct mbox_controller *mbox)
0621 {
0622 WARN_ON(devres_release(dev, __devm_mbox_controller_unregister,
0623 devm_mbox_controller_match, mbox));
0624 }
0625 EXPORT_SYMBOL_GPL(devm_mbox_controller_unregister);