cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

imx-audio-rpmsg.c (3464B)


      1// SPDX-License-Identifier: GPL-2.0+
      2// Copyright 2017-2020 NXP
      3
      4#include <linux/module.h>
      5#include <linux/rpmsg.h>
      6#include "imx-pcm-rpmsg.h"
      7
      8/*
      9 * struct imx_audio_rpmsg: private data
     10 *
     11 * @rpmsg_pdev: pointer of platform device
     12 */
     13struct imx_audio_rpmsg {
     14	struct platform_device *rpmsg_pdev;
     15};
     16
     17static int imx_audio_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
     18			      void *priv, u32 src)
     19{
     20	struct imx_audio_rpmsg *rpmsg = dev_get_drvdata(&rpdev->dev);
     21	struct rpmsg_r_msg *r_msg = (struct rpmsg_r_msg *)data;
     22	struct rpmsg_info *info;
     23	struct rpmsg_msg *msg;
     24	unsigned long flags;
     25
     26	if (!rpmsg->rpmsg_pdev)
     27		return 0;
     28
     29	info = platform_get_drvdata(rpmsg->rpmsg_pdev);
     30
     31	dev_dbg(&rpdev->dev, "get from%d: cmd:%d. %d\n",
     32		src, r_msg->header.cmd, r_msg->param.resp);
     33
     34	switch (r_msg->header.type) {
     35	case MSG_TYPE_C:
     36		/* TYPE C is notification from M core */
     37		switch (r_msg->header.cmd) {
     38		case TX_PERIOD_DONE:
     39			spin_lock_irqsave(&info->lock[TX], flags);
     40			msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
     41			msg->r_msg.param.buffer_tail =
     42						r_msg->param.buffer_tail;
     43			msg->r_msg.param.buffer_tail %= info->num_period[TX];
     44			spin_unlock_irqrestore(&info->lock[TX], flags);
     45			info->callback[TX](info->callback_param[TX]);
     46			break;
     47		case RX_PERIOD_DONE:
     48			spin_lock_irqsave(&info->lock[RX], flags);
     49			msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
     50			msg->r_msg.param.buffer_tail =
     51						r_msg->param.buffer_tail;
     52			msg->r_msg.param.buffer_tail %= info->num_period[1];
     53			spin_unlock_irqrestore(&info->lock[RX], flags);
     54			info->callback[RX](info->callback_param[RX]);
     55			break;
     56		default:
     57			dev_warn(&rpdev->dev, "unknown msg command\n");
     58			break;
     59		}
     60		break;
     61	case MSG_TYPE_B:
     62		/* TYPE B is response msg */
     63		memcpy(&info->r_msg, r_msg, sizeof(struct rpmsg_r_msg));
     64		complete(&info->cmd_complete);
     65		break;
     66	default:
     67		dev_warn(&rpdev->dev, "unknown msg type\n");
     68		break;
     69	}
     70
     71	return 0;
     72}
     73
     74static int imx_audio_rpmsg_probe(struct rpmsg_device *rpdev)
     75{
     76	struct imx_audio_rpmsg *data;
     77	int ret = 0;
     78
     79	dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
     80		 rpdev->src, rpdev->dst);
     81
     82	data = devm_kzalloc(&rpdev->dev, sizeof(*data), GFP_KERNEL);
     83	if (!data)
     84		return -ENOMEM;
     85
     86	dev_set_drvdata(&rpdev->dev, data);
     87
     88	/* Register platform driver for rpmsg routine */
     89	data->rpmsg_pdev = platform_device_register_data(&rpdev->dev,
     90							 IMX_PCM_DRV_NAME,
     91							 PLATFORM_DEVID_NONE,
     92							 NULL, 0);
     93	if (IS_ERR(data->rpmsg_pdev)) {
     94		dev_err(&rpdev->dev, "failed to register rpmsg platform.\n");
     95		ret = PTR_ERR(data->rpmsg_pdev);
     96	}
     97
     98	return ret;
     99}
    100
    101static void imx_audio_rpmsg_remove(struct rpmsg_device *rpdev)
    102{
    103	struct imx_audio_rpmsg *data = dev_get_drvdata(&rpdev->dev);
    104
    105	if (data->rpmsg_pdev)
    106		platform_device_unregister(data->rpmsg_pdev);
    107
    108	dev_info(&rpdev->dev, "audio rpmsg driver is removed\n");
    109}
    110
    111static struct rpmsg_device_id imx_audio_rpmsg_id_table[] = {
    112	{ .name	= "rpmsg-audio-channel" },
    113	{ },
    114};
    115
    116static struct rpmsg_driver imx_audio_rpmsg_driver = {
    117	.drv.name	= "imx_audio_rpmsg",
    118	.drv.owner	= THIS_MODULE,
    119	.id_table	= imx_audio_rpmsg_id_table,
    120	.probe		= imx_audio_rpmsg_probe,
    121	.callback	= imx_audio_rpmsg_cb,
    122	.remove		= imx_audio_rpmsg_remove,
    123};
    124
    125module_rpmsg_driver(imx_audio_rpmsg_driver);
    126
    127MODULE_DESCRIPTION("Freescale SoC Audio RPMSG interface");
    128MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");
    129MODULE_ALIAS("platform:imx_audio_rpmsg");
    130MODULE_LICENSE("GPL v2");