root/net/qrtr/smd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qcom_smd_qrtr_callback
  2. qcom_smd_qrtr_send
  3. qcom_smd_qrtr_probe
  4. qcom_smd_qrtr_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2015, Sony Mobile Communications Inc.
   4  * Copyright (c) 2013, The Linux Foundation. All rights reserved.
   5  */
   6 
   7 #include <linux/module.h>
   8 #include <linux/skbuff.h>
   9 #include <linux/rpmsg.h>
  10 
  11 #include "qrtr.h"
  12 
  13 struct qrtr_smd_dev {
  14         struct qrtr_endpoint ep;
  15         struct rpmsg_endpoint *channel;
  16         struct device *dev;
  17 };
  18 
  19 /* from smd to qrtr */
  20 static int qcom_smd_qrtr_callback(struct rpmsg_device *rpdev,
  21                                   void *data, int len, void *priv, u32 addr)
  22 {
  23         struct qrtr_smd_dev *qdev = dev_get_drvdata(&rpdev->dev);
  24         int rc;
  25 
  26         if (!qdev)
  27                 return -EAGAIN;
  28 
  29         rc = qrtr_endpoint_post(&qdev->ep, data, len);
  30         if (rc == -EINVAL) {
  31                 dev_err(qdev->dev, "invalid ipcrouter packet\n");
  32                 /* return 0 to let smd drop the packet */
  33                 rc = 0;
  34         }
  35 
  36         return rc;
  37 }
  38 
  39 /* from qrtr to smd */
  40 static int qcom_smd_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
  41 {
  42         struct qrtr_smd_dev *qdev = container_of(ep, struct qrtr_smd_dev, ep);
  43         int rc;
  44 
  45         rc = skb_linearize(skb);
  46         if (rc)
  47                 goto out;
  48 
  49         rc = rpmsg_send(qdev->channel, skb->data, skb->len);
  50 
  51 out:
  52         if (rc)
  53                 kfree_skb(skb);
  54         else
  55                 consume_skb(skb);
  56         return rc;
  57 }
  58 
  59 static int qcom_smd_qrtr_probe(struct rpmsg_device *rpdev)
  60 {
  61         struct qrtr_smd_dev *qdev;
  62         int rc;
  63 
  64         qdev = devm_kzalloc(&rpdev->dev, sizeof(*qdev), GFP_KERNEL);
  65         if (!qdev)
  66                 return -ENOMEM;
  67 
  68         qdev->channel = rpdev->ept;
  69         qdev->dev = &rpdev->dev;
  70         qdev->ep.xmit = qcom_smd_qrtr_send;
  71 
  72         rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO);
  73         if (rc)
  74                 return rc;
  75 
  76         dev_set_drvdata(&rpdev->dev, qdev);
  77 
  78         dev_dbg(&rpdev->dev, "Qualcomm SMD QRTR driver probed\n");
  79 
  80         return 0;
  81 }
  82 
  83 static void qcom_smd_qrtr_remove(struct rpmsg_device *rpdev)
  84 {
  85         struct qrtr_smd_dev *qdev = dev_get_drvdata(&rpdev->dev);
  86 
  87         qrtr_endpoint_unregister(&qdev->ep);
  88 
  89         dev_set_drvdata(&rpdev->dev, NULL);
  90 }
  91 
  92 static const struct rpmsg_device_id qcom_smd_qrtr_smd_match[] = {
  93         { "IPCRTR" },
  94         {}
  95 };
  96 
  97 static struct rpmsg_driver qcom_smd_qrtr_driver = {
  98         .probe = qcom_smd_qrtr_probe,
  99         .remove = qcom_smd_qrtr_remove,
 100         .callback = qcom_smd_qrtr_callback,
 101         .id_table = qcom_smd_qrtr_smd_match,
 102         .drv = {
 103                 .name = "qcom_smd_qrtr",
 104         },
 105 };
 106 
 107 module_rpmsg_driver(qcom_smd_qrtr_driver);
 108 
 109 MODULE_ALIAS("rpmsg:IPCRTR");
 110 MODULE_DESCRIPTION("Qualcomm IPC-Router SMD interface driver");
 111 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */