linux/drivers/rpmsg/qcom_glink_native.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2016-2017, Linaro Ltd
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 and
   6 * only version 2 as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 */
  13
  14#include <linux/idr.h>
  15#include <linux/interrupt.h>
  16#include <linux/io.h>
  17#include <linux/list.h>
  18#include <linux/mfd/syscon.h>
  19#include <linux/module.h>
  20#include <linux/of.h>
  21#include <linux/of_address.h>
  22#include <linux/of_irq.h>
  23#include <linux/platform_device.h>
  24#include <linux/regmap.h>
  25#include <linux/rpmsg.h>
  26#include <linux/sizes.h>
  27#include <linux/slab.h>
  28#include <linux/workqueue.h>
  29#include <linux/mailbox_client.h>
  30
  31#include "rpmsg_internal.h"
  32#include "qcom_glink_native.h"
  33
  34#define GLINK_NAME_SIZE         32
  35#define GLINK_VERSION_1         1
  36
  37#define RPM_GLINK_CID_MIN       1
  38#define RPM_GLINK_CID_MAX       65536
  39
  40struct glink_msg {
  41        __le16 cmd;
  42        __le16 param1;
  43        __le32 param2;
  44        u8 data[];
  45} __packed;
  46
  47/**
  48 * struct glink_defer_cmd - deferred incoming control message
  49 * @node:       list node
  50 * @msg:        message header
  51 * data:        payload of the message
  52 *
  53 * Copy of a received control message, to be added to @rx_queue and processed
  54 * by @rx_work of @qcom_glink.
  55 */
  56struct glink_defer_cmd {
  57        struct list_head node;
  58
  59        struct glink_msg msg;
  60        u8 data[];
  61};
  62
  63/**
  64 * struct glink_core_rx_intent - RX intent
  65 * RX intent
  66 *
  67 * data: pointer to the data (may be NULL for zero-copy)
  68 * id: remote or local intent ID
  69 * size: size of the original intent (do not modify)
  70 * reuse: To mark if the intent can be reused after first use
  71 * in_use: To mark if intent is already in use for the channel
  72 * offset: next write offset (initially 0)
  73 */
  74struct glink_core_rx_intent {
  75        void *data;
  76        u32 id;
  77        size_t size;
  78        bool reuse;
  79        bool in_use;
  80        u32 offset;
  81
  82        struct list_head node;
  83};
  84
  85/**
  86 * struct qcom_glink - driver context, relates to one remote subsystem
  87 * @dev:        reference to the associated struct device
  88 * @mbox_client: mailbox client
  89 * @mbox_chan:  mailbox channel
  90 * @rx_pipe:    pipe object for receive FIFO
  91 * @tx_pipe:    pipe object for transmit FIFO
  92 * @irq:        IRQ for signaling incoming events
  93 * @rx_work:    worker for handling received control messages
  94 * @rx_lock:    protects the @rx_queue
  95 * @rx_queue:   queue of received control messages to be processed in @rx_work
  96 * @tx_lock:    synchronizes operations on the tx fifo
  97 * @idr_lock:   synchronizes @lcids and @rcids modifications
  98 * @lcids:      idr of all channels with a known local channel id
  99 * @rcids:      idr of all channels with a known remote channel id
 100 */
 101struct qcom_glink {
 102        struct device *dev;
 103
 104        struct mbox_client mbox_client;
 105        struct mbox_chan *mbox_chan;
 106
 107        struct qcom_glink_pipe *rx_pipe;
 108        struct qcom_glink_pipe *tx_pipe;
 109
 110        int irq;
 111
 112        struct work_struct rx_work;
 113        spinlock_t rx_lock;
 114        struct list_head rx_queue;
 115
 116        struct mutex tx_lock;
 117
 118        spinlock_t idr_lock;
 119        struct idr lcids;
 120        struct idr rcids;
 121        unsigned long features;
 122
 123        bool intentless;
 124};
 125
 126enum {
 127        GLINK_STATE_CLOSED,
 128        GLINK_STATE_OPENING,
 129        GLINK_STATE_OPEN,
 130        GLINK_STATE_CLOSING,
 131};
 132
 133/**
 134 * struct glink_channel - internal representation of a channel
 135 * @rpdev:      rpdev reference, only used for primary endpoints
 136 * @ept:        rpmsg endpoint this channel is associated with
 137 * @glink:      qcom_glink context handle
 138 * @refcount:   refcount for the channel object
 139 * @recv_lock:  guard for @ept.cb
 140 * @name:       unique channel name/identifier
 141 * @lcid:       channel id, in local space
 142 * @rcid:       channel id, in remote space
 143 * @intent_lock: lock for protection of @liids, @riids
 144 * @liids:      idr of all local intents
 145 * @riids:      idr of all remote intents
 146 * @intent_work: worker responsible for transmitting rx_done packets
 147 * @done_intents: list of intents that needs to be announced rx_done
 148 * @buf:        receive buffer, for gathering fragments
 149 * @buf_offset: write offset in @buf
 150 * @buf_size:   size of current @buf
 151 * @open_ack:   completed once remote has acked the open-request
 152 * @open_req:   completed once open-request has been received
 153 * @intent_req_lock: Synchronises multiple intent requests
 154 * @intent_req_result: Result of intent request
 155 * @intent_req_comp: Completion for intent_req signalling
 156 */
 157struct glink_channel {
 158        struct rpmsg_endpoint ept;
 159
 160        struct rpmsg_device *rpdev;
 161        struct qcom_glink *glink;
 162
 163        struct kref refcount;
 164
 165        spinlock_t recv_lock;
 166
 167        char *name;
 168        unsigned int lcid;
 169        unsigned int rcid;
 170
 171        spinlock_t intent_lock;
 172        struct idr liids;
 173        struct idr riids;
 174        struct work_struct intent_work;
 175        struct list_head done_intents;
 176
 177        struct glink_core_rx_intent *buf;
 178        int buf_offset;
 179        int buf_size;
 180
 181        struct completion open_ack;
 182        struct completion open_req;
 183
 184        struct mutex intent_req_lock;
 185        bool intent_req_result;
 186        struct completion intent_req_comp;
 187};
 188
 189#define to_glink_channel(_ept) container_of(_ept, struct glink_channel, ept)
 190
 191static const struct rpmsg_endpoint_ops glink_endpoint_ops;
 192
 193#define RPM_CMD_VERSION                 0
 194#define RPM_CMD_VERSION_ACK             1
 195#define RPM_CMD_OPEN                    2
 196#define RPM_CMD_CLOSE                   3
 197#define RPM_CMD_OPEN_ACK                4
 198#define RPM_CMD_INTENT                  5
 199#define RPM_CMD_RX_DONE                 6
 200#define RPM_CMD_RX_INTENT_REQ           7
 201#define RPM_CMD_RX_INTENT_REQ_ACK       8
 202#define RPM_CMD_TX_DATA                 9
 203#define RPM_CMD_CLOSE_ACK               11
 204#define RPM_CMD_TX_DATA_CONT            12
 205#define RPM_CMD_READ_NOTIF              13
 206#define RPM_CMD_RX_DONE_W_REUSE         14
 207
 208#define GLINK_FEATURE_INTENTLESS        BIT(1)
 209
 210static void qcom_glink_rx_done_work(struct work_struct *work);
 211
 212static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
 213                                                      const char *name)
 214{
 215        struct glink_channel *channel;
 216
 217        channel = kzalloc(sizeof(*channel), GFP_KERNEL);
 218        if (!channel)
 219                return ERR_PTR(-ENOMEM);
 220
 221        /* Setup glink internal glink_channel data */
 222        spin_lock_init(&channel->recv_lock);
 223        spin_lock_init(&channel->intent_lock);
 224
 225        channel->glink = glink;
 226        channel->name = kstrdup(name, GFP_KERNEL);
 227
 228        init_completion(&channel->open_req);
 229        init_completion(&channel->open_ack);
 230        init_completion(&channel->intent_req_comp);
 231
 232        INIT_LIST_HEAD(&channel->done_intents);
 233        INIT_WORK(&channel->intent_work, qcom_glink_rx_done_work);
 234
 235        idr_init(&channel->liids);
 236        idr_init(&channel->riids);
 237        kref_init(&channel->refcount);
 238
 239        return channel;
 240}
 241
 242static void qcom_glink_channel_release(struct kref *ref)
 243{
 244        struct glink_channel *channel = container_of(ref, struct glink_channel,
 245                                                     refcount);
 246        unsigned long flags;
 247
 248        spin_lock_irqsave(&channel->intent_lock, flags);
 249        idr_destroy(&channel->liids);
 250        idr_destroy(&channel->riids);
 251        spin_unlock_irqrestore(&channel->intent_lock, flags);
 252
 253        kfree(channel->name);
 254        kfree(channel);
 255}
 256
 257static size_t qcom_glink_rx_avail(struct qcom_glink *glink)
 258{
 259        return glink->rx_pipe->avail(glink->rx_pipe);
 260}
 261
 262static void qcom_glink_rx_peak(struct qcom_glink *glink,
 263                               void *data, unsigned int offset, size_t count)
 264{
 265        glink->rx_pipe->peak(glink->rx_pipe, data, offset, count);
 266}
 267
 268static void qcom_glink_rx_advance(struct qcom_glink *glink, size_t count)
 269{
 270        glink->rx_pipe->advance(glink->rx_pipe, count);
 271}
 272
 273static size_t qcom_glink_tx_avail(struct qcom_glink *glink)
 274{
 275        return glink->tx_pipe->avail(glink->tx_pipe);
 276}
 277
 278static void qcom_glink_tx_write(struct qcom_glink *glink,
 279                                const void *hdr, size_t hlen,
 280                                const void *data, size_t dlen)
 281{
 282        glink->tx_pipe->write(glink->tx_pipe, hdr, hlen, data, dlen);
 283}
 284
 285static int qcom_glink_tx(struct qcom_glink *glink,
 286                         const void *hdr, size_t hlen,
 287                         const void *data, size_t dlen, bool wait)
 288{
 289        unsigned int tlen = hlen + dlen;
 290        int ret;
 291
 292        /* Reject packets that are too big */
 293        if (tlen >= glink->tx_pipe->length)
 294                return -EINVAL;
 295
 296        ret = mutex_lock_interruptible(&glink->tx_lock);
 297        if (ret)
 298                return ret;
 299
 300        while (qcom_glink_tx_avail(glink) < tlen) {
 301                if (!wait) {
 302                        ret = -EAGAIN;
 303                        goto out;
 304                }
 305
 306                usleep_range(10000, 15000);
 307        }
 308
 309        qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
 310
 311        mbox_send_message(glink->mbox_chan, NULL);
 312        mbox_client_txdone(glink->mbox_chan, 0);
 313
 314out:
 315        mutex_unlock(&glink->tx_lock);
 316
 317        return ret;
 318}
 319
 320static int qcom_glink_send_version(struct qcom_glink *glink)
 321{
 322        struct glink_msg msg;
 323
 324        msg.cmd = cpu_to_le16(RPM_CMD_VERSION);
 325        msg.param1 = cpu_to_le16(GLINK_VERSION_1);
 326        msg.param2 = cpu_to_le32(glink->features);
 327
 328        return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
 329}
 330
 331static void qcom_glink_send_version_ack(struct qcom_glink *glink)
 332{
 333        struct glink_msg msg;
 334
 335        msg.cmd = cpu_to_le16(RPM_CMD_VERSION_ACK);
 336        msg.param1 = cpu_to_le16(GLINK_VERSION_1);
 337        msg.param2 = cpu_to_le32(glink->features);
 338
 339        qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
 340}
 341
 342static void qcom_glink_send_open_ack(struct qcom_glink *glink,
 343                                     struct glink_channel *channel)
 344{
 345        struct glink_msg msg;
 346
 347        msg.cmd = cpu_to_le16(RPM_CMD_OPEN_ACK);
 348        msg.param1 = cpu_to_le16(channel->rcid);
 349        msg.param2 = cpu_to_le32(0);
 350
 351        qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
 352}
 353
 354static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink,
 355                                             unsigned int cid, bool granted)
 356{
 357        struct glink_channel *channel;
 358        unsigned long flags;
 359
 360        spin_lock_irqsave(&glink->idr_lock, flags);
 361        channel = idr_find(&glink->rcids, cid);
 362        spin_unlock_irqrestore(&glink->idr_lock, flags);
 363        if (!channel) {
 364                dev_err(glink->dev, "unable to find channel\n");
 365                return;
 366        }
 367
 368        channel->intent_req_result = granted;
 369        complete(&channel->intent_req_comp);
 370}
 371
 372/**
 373 * qcom_glink_send_open_req() - send a RPM_CMD_OPEN request to the remote
 374 * @glink: Ptr to the glink edge
 375 * @channel: Ptr to the channel that the open req is sent
 376 *
 377 * Allocates a local channel id and sends a RPM_CMD_OPEN message to the remote.
 378 * Will return with refcount held, regardless of outcome.
 379 *
 380 * Returns 0 on success, negative errno otherwise.
 381 */
 382static int qcom_glink_send_open_req(struct qcom_glink *glink,
 383                                    struct glink_channel *channel)
 384{
 385        struct {
 386                struct glink_msg msg;
 387                u8 name[GLINK_NAME_SIZE];
 388        } __packed req;
 389        int name_len = strlen(channel->name) + 1;
 390        int req_len = ALIGN(sizeof(req.msg) + name_len, 8);
 391        int ret;
 392        unsigned long flags;
 393
 394        kref_get(&channel->refcount);
 395
 396        spin_lock_irqsave(&glink->idr_lock, flags);
 397        ret = idr_alloc_cyclic(&glink->lcids, channel,
 398                               RPM_GLINK_CID_MIN, RPM_GLINK_CID_MAX,
 399                               GFP_ATOMIC);
 400        spin_unlock_irqrestore(&glink->idr_lock, flags);
 401        if (ret < 0)
 402                return ret;
 403
 404        channel->lcid = ret;
 405
 406        req.msg.cmd = cpu_to_le16(RPM_CMD_OPEN);
 407        req.msg.param1 = cpu_to_le16(channel->lcid);
 408        req.msg.param2 = cpu_to_le32(name_len);
 409        strcpy(req.name, channel->name);
 410
 411        ret = qcom_glink_tx(glink, &req, req_len, NULL, 0, true);
 412        if (ret)
 413                goto remove_idr;
 414
 415        return 0;
 416
 417remove_idr:
 418        spin_lock_irqsave(&glink->idr_lock, flags);
 419        idr_remove(&glink->lcids, channel->lcid);
 420        channel->lcid = 0;
 421        spin_unlock_irqrestore(&glink->idr_lock, flags);
 422
 423        return ret;
 424}
 425
 426static void qcom_glink_send_close_req(struct qcom_glink *glink,
 427                                      struct glink_channel *channel)
 428{
 429        struct glink_msg req;
 430
 431        req.cmd = cpu_to_le16(RPM_CMD_CLOSE);
 432        req.param1 = cpu_to_le16(channel->lcid);
 433        req.param2 = 0;
 434
 435        qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true);
 436}
 437
 438static void qcom_glink_send_close_ack(struct qcom_glink *glink,
 439                                      unsigned int rcid)
 440{
 441        struct glink_msg req;
 442
 443        req.cmd = cpu_to_le16(RPM_CMD_CLOSE_ACK);
 444        req.param1 = cpu_to_le16(rcid);
 445        req.param2 = 0;
 446
 447        qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true);
 448}
 449
 450static void qcom_glink_rx_done_work(struct work_struct *work)
 451{
 452        struct glink_channel *channel = container_of(work, struct glink_channel,
 453                                                     intent_work);
 454        struct qcom_glink *glink = channel->glink;
 455        struct glink_core_rx_intent *intent, *tmp;
 456        struct {
 457                u16 id;
 458                u16 lcid;
 459                u32 liid;
 460        } __packed cmd;
 461
 462        unsigned int cid = channel->lcid;
 463        unsigned int iid;
 464        bool reuse;
 465        unsigned long flags;
 466
 467        spin_lock_irqsave(&channel->intent_lock, flags);
 468        list_for_each_entry_safe(intent, tmp, &channel->done_intents, node) {
 469                list_del(&intent->node);
 470                spin_unlock_irqrestore(&channel->intent_lock, flags);
 471                iid = intent->id;
 472                reuse = intent->reuse;
 473
 474                cmd.id = reuse ? RPM_CMD_RX_DONE_W_REUSE : RPM_CMD_RX_DONE;
 475                cmd.lcid = cid;
 476                cmd.liid = iid;
 477
 478                qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true);
 479                if (!reuse) {
 480                        kfree(intent->data);
 481                        kfree(intent);
 482                }
 483                spin_lock_irqsave(&channel->intent_lock, flags);
 484        }
 485        spin_unlock_irqrestore(&channel->intent_lock, flags);
 486}
 487
 488static void qcom_glink_rx_done(struct qcom_glink *glink,
 489                               struct glink_channel *channel,
 490                               struct glink_core_rx_intent *intent)
 491{
 492        /* We don't send RX_DONE to intentless systems */
 493        if (glink->intentless) {
 494                kfree(intent->data);
 495                kfree(intent);
 496                return;
 497        }
 498
 499        /* Take it off the tree of receive intents */
 500        if (!intent->reuse) {
 501                spin_lock(&channel->intent_lock);
 502                idr_remove(&channel->liids, intent->id);
 503                spin_unlock(&channel->intent_lock);
 504        }
 505
 506        /* Schedule the sending of a rx_done indication */
 507        spin_lock(&channel->intent_lock);
 508        list_add_tail(&intent->node, &channel->done_intents);
 509        spin_unlock(&channel->intent_lock);
 510
 511        schedule_work(&channel->intent_work);
 512}
 513
 514/**
 515 * qcom_glink_receive_version() - receive version/features from remote system
 516 *
 517 * @glink:      pointer to transport interface
 518 * @r_version:  remote version
 519 * @r_features: remote features
 520 *
 521 * This function is called in response to a remote-initiated version/feature
 522 * negotiation sequence.
 523 */
 524static void qcom_glink_receive_version(struct qcom_glink *glink,
 525                                       u32 version,
 526                                       u32 features)
 527{
 528        switch (version) {
 529        case 0:
 530                break;
 531        case GLINK_VERSION_1:
 532                glink->features &= features;
 533                /* FALLTHROUGH */
 534        default:
 535                qcom_glink_send_version_ack(glink);
 536                break;
 537        }
 538}
 539
 540/**
 541 * qcom_glink_receive_version_ack() - receive negotiation ack from remote system
 542 *
 543 * @glink:      pointer to transport interface
 544 * @r_version:  remote version response
 545 * @r_features: remote features response
 546 *
 547 * This function is called in response to a local-initiated version/feature
 548 * negotiation sequence and is the counter-offer from the remote side based
 549 * upon the initial version and feature set requested.
 550 */
 551static void qcom_glink_receive_version_ack(struct qcom_glink *glink,
 552                                           u32 version,
 553                                           u32 features)
 554{
 555        switch (version) {
 556        case 0:
 557                /* Version negotiation failed */
 558                break;
 559        case GLINK_VERSION_1:
 560                if (features == glink->features)
 561                        break;
 562
 563                glink->features &= features;
 564                /* FALLTHROUGH */
 565        default:
 566                qcom_glink_send_version(glink);
 567                break;
 568        }
 569}
 570
 571/**
 572 * qcom_glink_send_intent_req_ack() - convert an rx intent request ack cmd to
 573                                      wire format and transmit
 574 * @glink:      The transport to transmit on.
 575 * @channel:    The glink channel
 576 * @granted:    The request response to encode.
 577 *
 578 * Return: 0 on success or standard Linux error code.
 579 */
 580static int qcom_glink_send_intent_req_ack(struct qcom_glink *glink,
 581                                          struct glink_channel *channel,
 582                                          bool granted)
 583{
 584        struct glink_msg msg;
 585
 586        msg.cmd = cpu_to_le16(RPM_CMD_RX_INTENT_REQ_ACK);
 587        msg.param1 = cpu_to_le16(channel->lcid);
 588        msg.param2 = cpu_to_le32(granted);
 589
 590        qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
 591
 592        return 0;
 593}
 594
 595/**
 596 * qcom_glink_advertise_intent - convert an rx intent cmd to wire format and
 597 *                         transmit
 598 * @glink:      The transport to transmit on.
 599 * @channel:    The local channel
 600 * @size:       The intent to pass on to remote.
 601 *
 602 * Return: 0 on success or standard Linux error code.
 603 */
 604static int qcom_glink_advertise_intent(struct qcom_glink *glink,
 605                                       struct glink_channel *channel,
 606                                       struct glink_core_rx_intent *intent)
 607{
 608        struct command {
 609                u16 id;
 610                u16 lcid;
 611                u32 count;
 612                u32 size;
 613                u32 liid;
 614        } __packed;
 615        struct command cmd;
 616
 617        cmd.id = cpu_to_le16(RPM_CMD_INTENT);
 618        cmd.lcid = cpu_to_le16(channel->lcid);
 619        cmd.count = cpu_to_le32(1);
 620        cmd.size = cpu_to_le32(intent->size);
 621        cmd.liid = cpu_to_le32(intent->id);
 622
 623        qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true);
 624
 625        return 0;
 626}
 627
 628static struct glink_core_rx_intent *
 629qcom_glink_alloc_intent(struct qcom_glink *glink,
 630                        struct glink_channel *channel,
 631                        size_t size,
 632                        bool reuseable)
 633{
 634        struct glink_core_rx_intent *intent;
 635        int ret;
 636        unsigned long flags;
 637
 638        intent = kzalloc(sizeof(*intent), GFP_KERNEL);
 639        if (!intent)
 640                return NULL;
 641
 642        intent->data = kzalloc(size, GFP_KERNEL);
 643        if (!intent->data)
 644                goto free_intent;
 645
 646        spin_lock_irqsave(&channel->intent_lock, flags);
 647        ret = idr_alloc_cyclic(&channel->liids, intent, 1, -1, GFP_ATOMIC);
 648        if (ret < 0) {
 649                spin_unlock_irqrestore(&channel->intent_lock, flags);
 650                goto free_data;
 651        }
 652        spin_unlock_irqrestore(&channel->intent_lock, flags);
 653
 654        intent->id = ret;
 655        intent->size = size;
 656        intent->reuse = reuseable;
 657
 658        return intent;
 659
 660free_data:
 661        kfree(intent->data);
 662free_intent:
 663        kfree(intent);
 664        return NULL;
 665}
 666
 667static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
 668                                      u32 cid, uint32_t iid,
 669                                      bool reuse)
 670{
 671        struct glink_core_rx_intent *intent;
 672        struct glink_channel *channel;
 673        unsigned long flags;
 674
 675        spin_lock_irqsave(&glink->idr_lock, flags);
 676        channel = idr_find(&glink->rcids, cid);
 677        spin_unlock_irqrestore(&glink->idr_lock, flags);
 678        if (!channel) {
 679                dev_err(glink->dev, "invalid channel id received\n");
 680                return;
 681        }
 682
 683        spin_lock_irqsave(&channel->intent_lock, flags);
 684        intent = idr_find(&channel->riids, iid);
 685
 686        if (!intent) {
 687                spin_unlock_irqrestore(&channel->intent_lock, flags);
 688                dev_err(glink->dev, "invalid intent id received\n");
 689                return;
 690        }
 691
 692        intent->in_use = false;
 693
 694        if (!reuse) {
 695                idr_remove(&channel->riids, intent->id);
 696                kfree(intent);
 697        }
 698        spin_unlock_irqrestore(&channel->intent_lock, flags);
 699}
 700
 701/**
 702 * qcom_glink_handle_intent_req() - Receive a request for rx_intent
 703 *                                          from remote side
 704 * if_ptr:      Pointer to the transport interface
 705 * rcid:        Remote channel ID
 706 * size:        size of the intent
 707 *
 708 * The function searches for the local channel to which the request for
 709 * rx_intent has arrived and allocates and notifies the remote back
 710 */
 711static void qcom_glink_handle_intent_req(struct qcom_glink *glink,
 712                                         u32 cid, size_t size)
 713{
 714        struct glink_core_rx_intent *intent;
 715        struct glink_channel *channel;
 716        unsigned long flags;
 717
 718        spin_lock_irqsave(&glink->idr_lock, flags);
 719        channel = idr_find(&glink->rcids, cid);
 720        spin_unlock_irqrestore(&glink->idr_lock, flags);
 721
 722        if (!channel) {
 723                pr_err("%s channel not found for cid %d\n", __func__, cid);
 724                return;
 725        }
 726
 727        intent = qcom_glink_alloc_intent(glink, channel, size, false);
 728        if (intent)
 729                qcom_glink_advertise_intent(glink, channel, intent);
 730
 731        qcom_glink_send_intent_req_ack(glink, channel, !!intent);
 732}
 733
 734static int qcom_glink_rx_defer(struct qcom_glink *glink, size_t extra)
 735{
 736        struct glink_defer_cmd *dcmd;
 737
 738        extra = ALIGN(extra, 8);
 739
 740        if (qcom_glink_rx_avail(glink) < sizeof(struct glink_msg) + extra) {
 741                dev_dbg(glink->dev, "Insufficient data in rx fifo");
 742                return -ENXIO;
 743        }
 744
 745        dcmd = kzalloc(sizeof(*dcmd) + extra, GFP_ATOMIC);
 746        if (!dcmd)
 747                return -ENOMEM;
 748
 749        INIT_LIST_HEAD(&dcmd->node);
 750
 751        qcom_glink_rx_peak(glink, &dcmd->msg, 0, sizeof(dcmd->msg) + extra);
 752
 753        spin_lock(&glink->rx_lock);
 754        list_add_tail(&dcmd->node, &glink->rx_queue);
 755        spin_unlock(&glink->rx_lock);
 756
 757        schedule_work(&glink->rx_work);
 758        qcom_glink_rx_advance(glink, sizeof(dcmd->msg) + extra);
 759
 760        return 0;
 761}
 762
 763static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
 764{
 765        struct glink_core_rx_intent *intent;
 766        struct glink_channel *channel;
 767        struct {
 768                struct glink_msg msg;
 769                __le32 chunk_size;
 770                __le32 left_size;
 771        } __packed hdr;
 772        unsigned int chunk_size;
 773        unsigned int left_size;
 774        unsigned int rcid;
 775        unsigned int liid;
 776        int ret = 0;
 777        unsigned long flags;
 778
 779        if (avail < sizeof(hdr)) {
 780                dev_dbg(glink->dev, "Not enough data in fifo\n");
 781                return -EAGAIN;
 782        }
 783
 784        qcom_glink_rx_peak(glink, &hdr, 0, sizeof(hdr));
 785        chunk_size = le32_to_cpu(hdr.chunk_size);
 786        left_size = le32_to_cpu(hdr.left_size);
 787
 788        if (avail < sizeof(hdr) + chunk_size) {
 789                dev_dbg(glink->dev, "Payload not yet in fifo\n");
 790                return -EAGAIN;
 791        }
 792
 793        if (WARN(chunk_size % 4, "Incoming data must be word aligned\n"))
 794                return -EINVAL;
 795
 796        rcid = le16_to_cpu(hdr.msg.param1);
 797        spin_lock_irqsave(&glink->idr_lock, flags);
 798        channel = idr_find(&glink->rcids, rcid);
 799        spin_unlock_irqrestore(&glink->idr_lock, flags);
 800        if (!channel) {
 801                dev_dbg(glink->dev, "Data on non-existing channel\n");
 802
 803                /* Drop the message */
 804                goto advance_rx;
 805        }
 806
 807        if (glink->intentless) {
 808                /* Might have an ongoing, fragmented, message to append */
 809                if (!channel->buf) {
 810                        intent = kzalloc(sizeof(*intent), GFP_ATOMIC);
 811                        if (!intent)
 812                                return -ENOMEM;
 813
 814                        intent->data = kmalloc(chunk_size + left_size,
 815                                               GFP_ATOMIC);
 816                        if (!intent->data) {
 817                                kfree(intent);
 818                                return -ENOMEM;
 819                        }
 820
 821                        intent->id = 0xbabababa;
 822                        intent->size = chunk_size + left_size;
 823                        intent->offset = 0;
 824
 825                        channel->buf = intent;
 826                } else {
 827                        intent = channel->buf;
 828                }
 829        } else {
 830                liid = le32_to_cpu(hdr.msg.param2);
 831
 832                spin_lock_irqsave(&channel->intent_lock, flags);
 833                intent = idr_find(&channel->liids, liid);
 834                spin_unlock_irqrestore(&channel->intent_lock, flags);
 835
 836                if (!intent) {
 837                        dev_err(glink->dev,
 838                                "no intent found for channel %s intent %d",
 839                                channel->name, liid);
 840                        goto advance_rx;
 841                }
 842        }
 843
 844        if (intent->size - intent->offset < chunk_size) {
 845                dev_err(glink->dev, "Insufficient space in intent\n");
 846
 847                /* The packet header lied, drop payload */
 848                goto advance_rx;
 849        }
 850
 851        qcom_glink_rx_peak(glink, intent->data + intent->offset,
 852                           sizeof(hdr), chunk_size);
 853        intent->offset += chunk_size;
 854
 855        /* Handle message when no fragments remain to be received */
 856        if (!left_size) {
 857                spin_lock(&channel->recv_lock);
 858                if (channel->ept.cb) {
 859                        channel->ept.cb(channel->ept.rpdev,
 860                                        intent->data,
 861                                        intent->offset,
 862                                        channel->ept.priv,
 863                                        RPMSG_ADDR_ANY);
 864                }
 865                spin_unlock(&channel->recv_lock);
 866
 867                intent->offset = 0;
 868                channel->buf = NULL;
 869
 870                qcom_glink_rx_done(glink, channel, intent);
 871        }
 872
 873advance_rx:
 874        qcom_glink_rx_advance(glink, ALIGN(sizeof(hdr) + chunk_size, 8));
 875
 876        return ret;
 877}
 878
 879static void qcom_glink_handle_intent(struct qcom_glink *glink,
 880                                     unsigned int cid,
 881                                     unsigned int count,
 882                                     size_t avail)
 883{
 884        struct glink_core_rx_intent *intent;
 885        struct glink_channel *channel;
 886        struct intent_pair {
 887                __le32 size;
 888                __le32 iid;
 889        };
 890
 891        struct {
 892                struct glink_msg msg;
 893                struct intent_pair intents[];
 894        } __packed * msg;
 895
 896        const size_t msglen = sizeof(*msg) + sizeof(struct intent_pair) * count;
 897        int ret;
 898        int i;
 899        unsigned long flags;
 900
 901        if (avail < msglen) {
 902                dev_dbg(glink->dev, "Not enough data in fifo\n");
 903                return;
 904        }
 905
 906        spin_lock_irqsave(&glink->idr_lock, flags);
 907        channel = idr_find(&glink->rcids, cid);
 908        spin_unlock_irqrestore(&glink->idr_lock, flags);
 909        if (!channel) {
 910                dev_err(glink->dev, "intents for non-existing channel\n");
 911                return;
 912        }
 913
 914        msg = kmalloc(msglen, GFP_ATOMIC);
 915        if (!msg)
 916                return;
 917
 918        qcom_glink_rx_peak(glink, msg, 0, msglen);
 919
 920        for (i = 0; i < count; ++i) {
 921                intent = kzalloc(sizeof(*intent), GFP_ATOMIC);
 922                if (!intent)
 923                        break;
 924
 925                intent->id = le32_to_cpu(msg->intents[i].iid);
 926                intent->size = le32_to_cpu(msg->intents[i].size);
 927
 928                spin_lock_irqsave(&channel->intent_lock, flags);
 929                ret = idr_alloc(&channel->riids, intent,
 930                                intent->id, intent->id + 1, GFP_ATOMIC);
 931                spin_unlock_irqrestore(&channel->intent_lock, flags);
 932
 933                if (ret < 0)
 934                        dev_err(glink->dev, "failed to store remote intent\n");
 935        }
 936
 937        kfree(msg);
 938        qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
 939}
 940
 941static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
 942{
 943        struct glink_channel *channel;
 944
 945        spin_lock(&glink->idr_lock);
 946        channel = idr_find(&glink->lcids, lcid);
 947        spin_unlock(&glink->idr_lock);
 948        if (!channel) {
 949                dev_err(glink->dev, "Invalid open ack packet\n");
 950                return -EINVAL;
 951        }
 952
 953        complete(&channel->open_ack);
 954
 955        return 0;
 956}
 957
 958static irqreturn_t qcom_glink_native_intr(int irq, void *data)
 959{
 960        struct qcom_glink *glink = data;
 961        struct glink_msg msg;
 962        unsigned int param1;
 963        unsigned int param2;
 964        unsigned int avail;
 965        unsigned int cmd;
 966        int ret = 0;
 967
 968        for (;;) {
 969                avail = qcom_glink_rx_avail(glink);
 970                if (avail < sizeof(msg))
 971                        break;
 972
 973                qcom_glink_rx_peak(glink, &msg, 0, sizeof(msg));
 974
 975                cmd = le16_to_cpu(msg.cmd);
 976                param1 = le16_to_cpu(msg.param1);
 977                param2 = le32_to_cpu(msg.param2);
 978
 979                switch (cmd) {
 980                case RPM_CMD_VERSION:
 981                case RPM_CMD_VERSION_ACK:
 982                case RPM_CMD_CLOSE:
 983                case RPM_CMD_CLOSE_ACK:
 984                case RPM_CMD_RX_INTENT_REQ:
 985                        ret = qcom_glink_rx_defer(glink, 0);
 986                        break;
 987                case RPM_CMD_OPEN_ACK:
 988                        ret = qcom_glink_rx_open_ack(glink, param1);
 989                        qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
 990                        break;
 991                case RPM_CMD_OPEN:
 992                        ret = qcom_glink_rx_defer(glink, param2);
 993                        break;
 994                case RPM_CMD_TX_DATA:
 995                case RPM_CMD_TX_DATA_CONT:
 996                        ret = qcom_glink_rx_data(glink, avail);
 997                        break;
 998                case RPM_CMD_READ_NOTIF:
 999                        qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
1000
1001                        mbox_send_message(glink->mbox_chan, NULL);
1002                        mbox_client_txdone(glink->mbox_chan, 0);
1003                        break;
1004                case RPM_CMD_INTENT:
1005                        qcom_glink_handle_intent(glink, param1, param2, avail);
1006                        break;
1007                case RPM_CMD_RX_DONE:
1008                        qcom_glink_handle_rx_done(glink, param1, param2, false);
1009                        qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
1010                        break;
1011                case RPM_CMD_RX_DONE_W_REUSE:
1012                        qcom_glink_handle_rx_done(glink, param1, param2, true);
1013                        qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
1014                        break;
1015                case RPM_CMD_RX_INTENT_REQ_ACK:
1016                        qcom_glink_handle_intent_req_ack(glink, param1, param2);
1017                        qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
1018                        break;
1019                default:
1020                        dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd);
1021                        ret = -EINVAL;
1022                        break;
1023                }
1024
1025                if (ret)
1026                        break;
1027        }
1028
1029        return IRQ_HANDLED;
1030}
1031
1032/* Locally initiated rpmsg_create_ept */
1033static struct glink_channel *qcom_glink_create_local(struct qcom_glink *glink,
1034                                                     const char *name)
1035{
1036        struct glink_channel *channel;
1037        int ret;
1038        unsigned long flags;
1039
1040        channel = qcom_glink_alloc_channel(glink, name);
1041        if (IS_ERR(channel))
1042                return ERR_CAST(channel);
1043
1044        ret = qcom_glink_send_open_req(glink, channel);
1045        if (ret)
1046                goto release_channel;
1047
1048        ret = wait_for_completion_timeout(&channel->open_ack, 5 * HZ);
1049        if (!ret)
1050                goto err_timeout;
1051
1052        ret = wait_for_completion_timeout(&channel->open_req, 5 * HZ);
1053        if (!ret)
1054                goto err_timeout;
1055
1056        qcom_glink_send_open_ack(glink, channel);
1057
1058        return channel;
1059
1060err_timeout:
1061        /* qcom_glink_send_open_req() did register the channel in lcids*/
1062        spin_lock_irqsave(&glink->idr_lock, flags);
1063        idr_remove(&glink->lcids, channel->lcid);
1064        spin_unlock_irqrestore(&glink->idr_lock, flags);
1065
1066release_channel:
1067        /* Release qcom_glink_send_open_req() reference */
1068        kref_put(&channel->refcount, qcom_glink_channel_release);
1069        /* Release qcom_glink_alloc_channel() reference */
1070        kref_put(&channel->refcount, qcom_glink_channel_release);
1071
1072        return ERR_PTR(-ETIMEDOUT);
1073}
1074
1075/* Remote initiated rpmsg_create_ept */
1076static int qcom_glink_create_remote(struct qcom_glink *glink,
1077                                    struct glink_channel *channel)
1078{
1079        int ret;
1080
1081        qcom_glink_send_open_ack(glink, channel);
1082
1083        ret = qcom_glink_send_open_req(glink, channel);
1084        if (ret)
1085                goto close_link;
1086
1087        ret = wait_for_completion_timeout(&channel->open_ack, 5 * HZ);
1088        if (!ret) {
1089                ret = -ETIMEDOUT;
1090                goto close_link;
1091        }
1092
1093        return 0;
1094
1095close_link:
1096        /*
1097         * Send a close request to "undo" our open-ack. The close-ack will
1098         * release the last reference.
1099         */
1100        qcom_glink_send_close_req(glink, channel);
1101
1102        /* Release qcom_glink_send_open_req() reference */
1103        kref_put(&channel->refcount, qcom_glink_channel_release);
1104
1105        return ret;
1106}
1107
1108static struct rpmsg_endpoint *qcom_glink_create_ept(struct rpmsg_device *rpdev,
1109                                                    rpmsg_rx_cb_t cb,
1110                                                    void *priv,
1111                                                    struct rpmsg_channel_info
1112                                                                        chinfo)
1113{
1114        struct glink_channel *parent = to_glink_channel(rpdev->ept);
1115        struct glink_channel *channel;
1116        struct qcom_glink *glink = parent->glink;
1117        struct rpmsg_endpoint *ept;
1118        const char *name = chinfo.name;
1119        int cid;
1120        int ret;
1121        unsigned long flags;
1122
1123        spin_lock_irqsave(&glink->idr_lock, flags);
1124        idr_for_each_entry(&glink->rcids, channel, cid) {
1125                if (!strcmp(channel->name, name))
1126                        break;
1127        }
1128        spin_unlock_irqrestore(&glink->idr_lock, flags);
1129
1130        if (!channel) {
1131                channel = qcom_glink_create_local(glink, name);
1132                if (IS_ERR(channel))
1133                        return NULL;
1134        } else {
1135                ret = qcom_glink_create_remote(glink, channel);
1136                if (ret)
1137                        return NULL;
1138        }
1139
1140        ept = &channel->ept;
1141        ept->rpdev = rpdev;
1142        ept->cb = cb;
1143        ept->priv = priv;
1144        ept->ops = &glink_endpoint_ops;
1145
1146        return ept;
1147}
1148
1149static int qcom_glink_announce_create(struct rpmsg_device *rpdev)
1150{
1151        struct glink_channel *channel = to_glink_channel(rpdev->ept);
1152        struct device_node *np = rpdev->dev.of_node;
1153        struct qcom_glink *glink = channel->glink;
1154        struct glink_core_rx_intent *intent;
1155        const struct property *prop = NULL;
1156        __be32 defaults[] = { cpu_to_be32(SZ_1K), cpu_to_be32(5) };
1157        int num_intents;
1158        int num_groups = 1;
1159        __be32 *val = defaults;
1160        int size;
1161
1162        if (glink->intentless)
1163                return 0;
1164
1165        prop = of_find_property(np, "qcom,intents", NULL);
1166        if (prop) {
1167                val = prop->value;
1168                num_groups = prop->length / sizeof(u32) / 2;
1169        }
1170
1171        /* Channel is now open, advertise base set of intents */
1172        while (num_groups--) {
1173                size = be32_to_cpup(val++);
1174                num_intents = be32_to_cpup(val++);
1175                while (num_intents--) {
1176                        intent = qcom_glink_alloc_intent(glink, channel, size,
1177                                                         true);
1178                        if (!intent)
1179                                break;
1180
1181                        qcom_glink_advertise_intent(glink, channel, intent);
1182                }
1183        }
1184        return 0;
1185}
1186
1187static void qcom_glink_destroy_ept(struct rpmsg_endpoint *ept)
1188{
1189        struct glink_channel *channel = to_glink_channel(ept);
1190        struct qcom_glink *glink = channel->glink;
1191        unsigned long flags;
1192
1193        spin_lock_irqsave(&channel->recv_lock, flags);
1194        channel->ept.cb = NULL;
1195        spin_unlock_irqrestore(&channel->recv_lock, flags);
1196
1197        /* Decouple the potential rpdev from the channel */
1198        channel->rpdev = NULL;
1199
1200        qcom_glink_send_close_req(glink, channel);
1201}
1202
1203static int qcom_glink_request_intent(struct qcom_glink *glink,
1204                                     struct glink_channel *channel,
1205                                     size_t size)
1206{
1207        struct {
1208                u16 id;
1209                u16 cid;
1210                u32 size;
1211        } __packed cmd;
1212
1213        int ret;
1214
1215        mutex_lock(&channel->intent_req_lock);
1216
1217        reinit_completion(&channel->intent_req_comp);
1218
1219        cmd.id = RPM_CMD_RX_INTENT_REQ;
1220        cmd.cid = channel->lcid;
1221        cmd.size = size;
1222
1223        ret = qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true);
1224        if (ret)
1225                goto unlock;
1226
1227        ret = wait_for_completion_timeout(&channel->intent_req_comp, 10 * HZ);
1228        if (!ret) {
1229                dev_err(glink->dev, "intent request timed out\n");
1230                ret = -ETIMEDOUT;
1231        } else {
1232                ret = channel->intent_req_result ? 0 : -ECANCELED;
1233        }
1234
1235unlock:
1236        mutex_unlock(&channel->intent_req_lock);
1237        return ret;
1238}
1239
1240static int __qcom_glink_send(struct glink_channel *channel,
1241                             void *data, int len, bool wait)
1242{
1243        struct qcom_glink *glink = channel->glink;
1244        struct glink_core_rx_intent *intent = NULL;
1245        struct glink_core_rx_intent *tmp;
1246        int iid = 0;
1247        struct {
1248                struct glink_msg msg;
1249                __le32 chunk_size;
1250                __le32 left_size;
1251        } __packed req;
1252        int ret;
1253        unsigned long flags;
1254
1255        if (!glink->intentless) {
1256                while (!intent) {
1257                        spin_lock_irqsave(&channel->intent_lock, flags);
1258                        idr_for_each_entry(&channel->riids, tmp, iid) {
1259                                if (tmp->size >= len && !tmp->in_use) {
1260                                        if (!intent)
1261                                                intent = tmp;
1262                                        else if (intent->size > tmp->size)
1263                                                intent = tmp;
1264                                        if (intent->size == len)
1265                                                break;
1266                                }
1267                        }
1268                        if (intent)
1269                                intent->in_use = true;
1270                        spin_unlock_irqrestore(&channel->intent_lock, flags);
1271
1272                        /* We found an available intent */
1273                        if (intent)
1274                                break;
1275
1276                        if (!wait)
1277                                return -EBUSY;
1278
1279                        ret = qcom_glink_request_intent(glink, channel, len);
1280                        if (ret < 0)
1281                                return ret;
1282                }
1283
1284                iid = intent->id;
1285        }
1286
1287        req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA);
1288        req.msg.param1 = cpu_to_le16(channel->lcid);
1289        req.msg.param2 = cpu_to_le32(iid);
1290        req.chunk_size = cpu_to_le32(len);
1291        req.left_size = cpu_to_le32(0);
1292
1293        ret = qcom_glink_tx(glink, &req, sizeof(req), data, len, wait);
1294
1295        /* Mark intent available if we failed */
1296        if (ret && intent)
1297                intent->in_use = false;
1298
1299        return ret;
1300}
1301
1302static int qcom_glink_send(struct rpmsg_endpoint *ept, void *data, int len)
1303{
1304        struct glink_channel *channel = to_glink_channel(ept);
1305
1306        return __qcom_glink_send(channel, data, len, true);
1307}
1308
1309static int qcom_glink_trysend(struct rpmsg_endpoint *ept, void *data, int len)
1310{
1311        struct glink_channel *channel = to_glink_channel(ept);
1312
1313        return __qcom_glink_send(channel, data, len, false);
1314}
1315
1316/*
1317 * Finds the device_node for the glink child interested in this channel.
1318 */
1319static struct device_node *qcom_glink_match_channel(struct device_node *node,
1320                                                    const char *channel)
1321{
1322        struct device_node *child;
1323        const char *name;
1324        const char *key;
1325        int ret;
1326
1327        for_each_available_child_of_node(node, child) {
1328                key = "qcom,glink-channels";
1329                ret = of_property_read_string(child, key, &name);
1330                if (ret)
1331                        continue;
1332
1333                if (strcmp(name, channel) == 0)
1334                        return child;
1335        }
1336
1337        return NULL;
1338}
1339
1340static const struct rpmsg_device_ops glink_device_ops = {
1341        .create_ept = qcom_glink_create_ept,
1342        .announce_create = qcom_glink_announce_create,
1343};
1344
1345static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
1346        .destroy_ept = qcom_glink_destroy_ept,
1347        .send = qcom_glink_send,
1348        .trysend = qcom_glink_trysend,
1349};
1350
1351static void qcom_glink_rpdev_release(struct device *dev)
1352{
1353        struct rpmsg_device *rpdev = to_rpmsg_device(dev);
1354        struct glink_channel *channel = to_glink_channel(rpdev->ept);
1355
1356        channel->rpdev = NULL;
1357        kfree(rpdev);
1358}
1359
1360static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid,
1361                              char *name)
1362{
1363        struct glink_channel *channel;
1364        struct rpmsg_device *rpdev;
1365        bool create_device = false;
1366        struct device_node *node;
1367        int lcid;
1368        int ret;
1369        unsigned long flags;
1370
1371        spin_lock_irqsave(&glink->idr_lock, flags);
1372        idr_for_each_entry(&glink->lcids, channel, lcid) {
1373                if (!strcmp(channel->name, name))
1374                        break;
1375        }
1376        spin_unlock_irqrestore(&glink->idr_lock, flags);
1377
1378        if (!channel) {
1379                channel = qcom_glink_alloc_channel(glink, name);
1380                if (IS_ERR(channel))
1381                        return PTR_ERR(channel);
1382
1383                /* The opening dance was initiated by the remote */
1384                create_device = true;
1385        }
1386
1387        spin_lock_irqsave(&glink->idr_lock, flags);
1388        ret = idr_alloc(&glink->rcids, channel, rcid, rcid + 1, GFP_ATOMIC);
1389        if (ret < 0) {
1390                dev_err(glink->dev, "Unable to insert channel into rcid list\n");
1391                spin_unlock_irqrestore(&glink->idr_lock, flags);
1392                goto free_channel;
1393        }
1394        channel->rcid = ret;
1395        spin_unlock_irqrestore(&glink->idr_lock, flags);
1396
1397        complete(&channel->open_req);
1398
1399        if (create_device) {
1400                rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL);
1401                if (!rpdev) {
1402                        ret = -ENOMEM;
1403                        goto rcid_remove;
1404                }
1405
1406                rpdev->ept = &channel->ept;
1407                strncpy(rpdev->id.name, name, RPMSG_NAME_SIZE);
1408                rpdev->src = RPMSG_ADDR_ANY;
1409                rpdev->dst = RPMSG_ADDR_ANY;
1410                rpdev->ops = &glink_device_ops;
1411
1412                node = qcom_glink_match_channel(glink->dev->of_node, name);
1413                rpdev->dev.of_node = node;
1414                rpdev->dev.parent = glink->dev;
1415                rpdev->dev.release = qcom_glink_rpdev_release;
1416
1417                ret = rpmsg_register_device(rpdev);
1418                if (ret)
1419                        goto free_rpdev;
1420
1421                channel->rpdev = rpdev;
1422        }
1423
1424        return 0;
1425
1426free_rpdev:
1427        kfree(rpdev);
1428rcid_remove:
1429        spin_lock_irqsave(&glink->idr_lock, flags);
1430        idr_remove(&glink->rcids, channel->rcid);
1431        channel->rcid = 0;
1432        spin_unlock_irqrestore(&glink->idr_lock, flags);
1433free_channel:
1434        /* Release the reference, iff we took it */
1435        if (create_device)
1436                kref_put(&channel->refcount, qcom_glink_channel_release);
1437
1438        return ret;
1439}
1440
1441static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid)
1442{
1443        struct rpmsg_channel_info chinfo;
1444        struct glink_channel *channel;
1445        unsigned long flags;
1446
1447        spin_lock_irqsave(&glink->idr_lock, flags);
1448        channel = idr_find(&glink->rcids, rcid);
1449        spin_unlock_irqrestore(&glink->idr_lock, flags);
1450        if (WARN(!channel, "close request on unknown channel\n"))
1451                return;
1452
1453        /* cancel pending rx_done work */
1454        cancel_work_sync(&channel->intent_work);
1455
1456        if (channel->rpdev) {
1457                strncpy(chinfo.name, channel->name, sizeof(chinfo.name));
1458                chinfo.src = RPMSG_ADDR_ANY;
1459                chinfo.dst = RPMSG_ADDR_ANY;
1460
1461                rpmsg_unregister_device(glink->dev, &chinfo);
1462        }
1463
1464        qcom_glink_send_close_ack(glink, channel->rcid);
1465
1466        spin_lock_irqsave(&glink->idr_lock, flags);
1467        idr_remove(&glink->rcids, channel->rcid);
1468        channel->rcid = 0;
1469        spin_unlock_irqrestore(&glink->idr_lock, flags);
1470
1471        kref_put(&channel->refcount, qcom_glink_channel_release);
1472}
1473
1474static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid)
1475{
1476        struct glink_channel *channel;
1477        unsigned long flags;
1478
1479        spin_lock_irqsave(&glink->idr_lock, flags);
1480        channel = idr_find(&glink->lcids, lcid);
1481        if (WARN(!channel, "close ack on unknown channel\n")) {
1482                spin_unlock_irqrestore(&glink->idr_lock, flags);
1483                return;
1484        }
1485
1486        idr_remove(&glink->lcids, channel->lcid);
1487        channel->lcid = 0;
1488        spin_unlock_irqrestore(&glink->idr_lock, flags);
1489
1490        kref_put(&channel->refcount, qcom_glink_channel_release);
1491}
1492
1493static void qcom_glink_work(struct work_struct *work)
1494{
1495        struct qcom_glink *glink = container_of(work, struct qcom_glink,
1496                                                rx_work);
1497        struct glink_defer_cmd *dcmd;
1498        struct glink_msg *msg;
1499        unsigned long flags;
1500        unsigned int param1;
1501        unsigned int param2;
1502        unsigned int cmd;
1503
1504        for (;;) {
1505                spin_lock_irqsave(&glink->rx_lock, flags);
1506                if (list_empty(&glink->rx_queue)) {
1507                        spin_unlock_irqrestore(&glink->rx_lock, flags);
1508                        break;
1509                }
1510                dcmd = list_first_entry(&glink->rx_queue,
1511                                        struct glink_defer_cmd, node);
1512                list_del(&dcmd->node);
1513                spin_unlock_irqrestore(&glink->rx_lock, flags);
1514
1515                msg = &dcmd->msg;
1516                cmd = le16_to_cpu(msg->cmd);
1517                param1 = le16_to_cpu(msg->param1);
1518                param2 = le32_to_cpu(msg->param2);
1519
1520                switch (cmd) {
1521                case RPM_CMD_VERSION:
1522                        qcom_glink_receive_version(glink, param1, param2);
1523                        break;
1524                case RPM_CMD_VERSION_ACK:
1525                        qcom_glink_receive_version_ack(glink, param1, param2);
1526                        break;
1527                case RPM_CMD_OPEN:
1528                        qcom_glink_rx_open(glink, param1, msg->data);
1529                        break;
1530                case RPM_CMD_CLOSE:
1531                        qcom_glink_rx_close(glink, param1);
1532                        break;
1533                case RPM_CMD_CLOSE_ACK:
1534                        qcom_glink_rx_close_ack(glink, param1);
1535                        break;
1536                case RPM_CMD_RX_INTENT_REQ:
1537                        qcom_glink_handle_intent_req(glink, param1, param2);
1538                        break;
1539                default:
1540                        WARN(1, "Unknown defer object %d\n", cmd);
1541                        break;
1542                }
1543
1544                kfree(dcmd);
1545        }
1546}
1547
1548struct qcom_glink *qcom_glink_native_probe(struct device *dev,
1549                                           unsigned long features,
1550                                           struct qcom_glink_pipe *rx,
1551                                           struct qcom_glink_pipe *tx,
1552                                           bool intentless)
1553{
1554        int irq;
1555        int ret;
1556        struct qcom_glink *glink;
1557
1558        glink = devm_kzalloc(dev, sizeof(*glink), GFP_KERNEL);
1559        if (!glink)
1560                return ERR_PTR(-ENOMEM);
1561
1562        glink->dev = dev;
1563        glink->tx_pipe = tx;
1564        glink->rx_pipe = rx;
1565
1566        glink->features = features;
1567        glink->intentless = intentless;
1568
1569        mutex_init(&glink->tx_lock);
1570        spin_lock_init(&glink->rx_lock);
1571        INIT_LIST_HEAD(&glink->rx_queue);
1572        INIT_WORK(&glink->rx_work, qcom_glink_work);
1573
1574        spin_lock_init(&glink->idr_lock);
1575        idr_init(&glink->lcids);
1576        idr_init(&glink->rcids);
1577
1578        glink->mbox_client.dev = dev;
1579        glink->mbox_client.knows_txdone = true;
1580        glink->mbox_chan = mbox_request_channel(&glink->mbox_client, 0);
1581        if (IS_ERR(glink->mbox_chan)) {
1582                if (PTR_ERR(glink->mbox_chan) != -EPROBE_DEFER)
1583                        dev_err(dev, "failed to acquire IPC channel\n");
1584                return ERR_CAST(glink->mbox_chan);
1585        }
1586
1587        irq = of_irq_get(dev->of_node, 0);
1588        ret = devm_request_irq(dev, irq,
1589                               qcom_glink_native_intr,
1590                               IRQF_NO_SUSPEND | IRQF_SHARED,
1591                               "glink-native", glink);
1592        if (ret) {
1593                dev_err(dev, "failed to request IRQ\n");
1594                return ERR_PTR(ret);
1595        }
1596
1597        glink->irq = irq;
1598
1599        ret = qcom_glink_send_version(glink);
1600        if (ret)
1601                return ERR_PTR(ret);
1602
1603        return glink;
1604}
1605EXPORT_SYMBOL_GPL(qcom_glink_native_probe);
1606
1607static int qcom_glink_remove_device(struct device *dev, void *data)
1608{
1609        device_unregister(dev);
1610
1611        return 0;
1612}
1613
1614void qcom_glink_native_remove(struct qcom_glink *glink)
1615{
1616        struct glink_channel *channel;
1617        int cid;
1618        int ret;
1619        unsigned long flags;
1620
1621        disable_irq(glink->irq);
1622        cancel_work_sync(&glink->rx_work);
1623
1624        ret = device_for_each_child(glink->dev, NULL, qcom_glink_remove_device);
1625        if (ret)
1626                dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret);
1627
1628        spin_lock_irqsave(&glink->idr_lock, flags);
1629        /* Release any defunct local channels, waiting for close-ack */
1630        idr_for_each_entry(&glink->lcids, channel, cid)
1631                kref_put(&channel->refcount, qcom_glink_channel_release);
1632
1633        idr_destroy(&glink->lcids);
1634        idr_destroy(&glink->rcids);
1635        spin_unlock_irqrestore(&glink->idr_lock, flags);
1636        mbox_free_channel(glink->mbox_chan);
1637}
1638EXPORT_SYMBOL_GPL(qcom_glink_native_remove);
1639
1640void qcom_glink_native_unregister(struct qcom_glink *glink)
1641{
1642        device_unregister(glink->dev);
1643}
1644EXPORT_SYMBOL_GPL(qcom_glink_native_unregister);
1645
1646MODULE_DESCRIPTION("Qualcomm GLINK driver");
1647MODULE_LICENSE("GPL v2");
1648