Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5d85696 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "rpmsg: glink: Update signals interface"

parents ca81e969 790be8ba
Loading
Loading
Loading
Loading
+141 −173

File changed.

Preview size limit exceeded, changes collapsed.

+2 −2
Original line number Diff line number Diff line
@@ -1924,11 +1924,11 @@
  rpmh_write_batch
  rpmsg_create_ept
  rpmsg_destroy_ept
  rpmsg_get_sigs
  rpmsg_get_signals
  rpmsg_poll
  rpmsg_register_device
  rpmsg_send
  rpmsg_set_sigs
  rpmsg_set_signals
  rpmsg_trysend
  rpmsg_unregister_device
  rtc_class_close
+64 −17
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2016-2017, Linaro Ltd
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/idr.h>
@@ -18,6 +18,7 @@
#include <linux/rpmsg.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/termios.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
#include <linux/mailbox_client.h>
@@ -177,6 +178,8 @@ enum {
 * @intent_req_result: Result of intent request
 * @intent_req_comp: Status of intent request completion
 * @intent_req_event: Waitqueue for @intent_req_comp
 * @lsigs:	local side signals
 * @rsigs:	remote side signals
 */
struct glink_channel {
	struct rpmsg_endpoint ept;
@@ -202,9 +205,6 @@ struct glink_channel {
	int buf_offset;
	int buf_size;

	unsigned int lsigs;
	unsigned int rsigs;

	struct completion open_ack;
	struct completion open_req;

@@ -212,6 +212,9 @@ struct glink_channel {
	bool intent_req_result;
	atomic_t intent_req_comp;
	wait_queue_head_t intent_req_event;

	unsigned int lsigs;
	unsigned int rsigs;
};

#define to_glink_channel(_ept) container_of(_ept, struct glink_channel, ept)
@@ -236,6 +239,11 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops;

#define GLINK_FEATURE_INTENTLESS	BIT(1)

#define NATIVE_DTR_SIG			BIT(31)
#define NATIVE_CTS_SIG			BIT(30)
#define NATIVE_CD_SIG			BIT(29)
#define NATIVE_RI_SIG			BIT(28)

static void qcom_glink_rx_done_work(struct kthread_work *work);

static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
@@ -1102,6 +1110,17 @@ static int qcom_glink_send_signals(struct qcom_glink *glink,
{
	struct glink_msg msg;

	/* convert signals from TIOCM to NATIVE */
	sigs &= 0x0fff;
	if (sigs & TIOCM_DTR)
		sigs |= NATIVE_DTR_SIG;
	if (sigs & TIOCM_RTS)
		sigs |= NATIVE_CTS_SIG;
	if (sigs & TIOCM_CD)
		sigs |= NATIVE_CD_SIG;
	if (sigs & TIOCM_RI)
		sigs |= NATIVE_RI_SIG;

	msg.cmd = cpu_to_le16(RPM_CMD_SIGNALS);
	msg.param1 = cpu_to_le16(channel->lcid);
	msg.param2 = cpu_to_le32(sigs);
@@ -1126,12 +1145,25 @@ static int qcom_glink_handle_signals(struct qcom_glink *glink,
	}

	old = channel->rsigs;
	channel->rsigs = signals;

	if (channel->ept.sig_cb)
		channel->ept.sig_cb(channel->ept.rpdev, old, channel->rsigs);
	/* convert signals from NATIVE to TIOCM */
	if (signals & NATIVE_DTR_SIG)
		signals |= TIOCM_DSR;
	if (signals & NATIVE_CTS_SIG)
		signals |= TIOCM_CTS;
	if (signals & NATIVE_CD_SIG)
		signals |= TIOCM_CD;
	if (signals & NATIVE_RI_SIG)
		signals |= TIOCM_RI;
	signals &= 0x0fff;

	channel->rsigs = signals;

	CH_INFO(channel, "old:%d new:%d\n", old, channel->rsigs);
	if (channel->ept.sig_cb) {
		channel->ept.sig_cb(channel->ept.rpdev, channel->ept.priv,
				    old, channel->rsigs);
	}

	return 0;
}
@@ -1546,21 +1578,36 @@ static int qcom_glink_trysend(struct rpmsg_endpoint *ept, void *data, int len)
	return __qcom_glink_send(channel, data, len, false);
}

static int qcom_glink_get_sigs(struct rpmsg_endpoint *ept,
			       u32 *lsigs, u32 *rsigs)
static int qcom_glink_get_sigs(struct rpmsg_endpoint *ept)
{
	struct glink_channel *channel = to_glink_channel(ept);

	*lsigs = channel->lsigs;
	*rsigs = channel->rsigs;

	return 0;
	return channel->rsigs;
}

static int qcom_glink_set_sigs(struct rpmsg_endpoint *ept, u32 sigs)
static int qcom_glink_set_sigs(struct rpmsg_endpoint *ept, u32 set, u32 clear)
{
	struct glink_channel *channel = to_glink_channel(ept);
	struct qcom_glink *glink = channel->glink;
	u32 sigs = channel->lsigs;

	if (set & TIOCM_DTR)
		sigs |= TIOCM_DTR;
	if (set & TIOCM_RTS)
		sigs |= TIOCM_RTS;
	if (set & TIOCM_CD)
		sigs |= TIOCM_CD;
	if (set & TIOCM_RI)
		sigs |= TIOCM_RI;

	if (clear & TIOCM_DTR)
		sigs &= ~TIOCM_DTR;
	if (clear & TIOCM_RTS)
		sigs &= ~TIOCM_RTS;
	if (clear & TIOCM_CD)
		sigs &= ~TIOCM_CD;
	if (clear & TIOCM_RI)
		sigs &= ~TIOCM_RI;

	channel->lsigs = sigs;

@@ -1600,8 +1647,8 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
	.destroy_ept = qcom_glink_destroy_ept,
	.send = qcom_glink_send,
	.trysend = qcom_glink_trysend,
	.get_sigs = qcom_glink_get_sigs,
	.set_sigs = qcom_glink_set_sigs,
	.get_signals = qcom_glink_get_sigs,
	.set_signals = qcom_glink_set_sigs,
};

static void qcom_glink_rpdev_release(struct device *dev)
+14 −14
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
 *
 * Copyright (C) 2011 Texas Instruments, Inc.
 * Copyright (C) 2011 Google, Inc.
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 *
 * Ohad Ben-Cohen <ohad@wizery.com>
 * Brian Swetland <swetland@google.com>
@@ -285,40 +285,40 @@ int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
EXPORT_SYMBOL(rpmsg_trysend_offchannel);

/**
 * rpmsg_get_sigs() - get the signals for this endpoint
 * rpmsg_get_signals() - get the signals for this endpoint
 * @ept:	the rpmsg endpoint
 * @sigs:	serial signals bitmask
 *
 * Returns 0 on success and an appropriate error value on failure.
 * Returns signal bits on success and an appropriate error value on failure.
 */
int rpmsg_get_sigs(struct rpmsg_endpoint *ept, u32 *lsigs, u32 *rsigs)
int rpmsg_get_signals(struct rpmsg_endpoint *ept)
{
	if (WARN_ON(!ept))
		return -EINVAL;
	if (!ept->ops->get_sigs)
	if (!ept->ops->get_signals)
		return -ENXIO;

	return ept->ops->get_sigs(ept, lsigs, rsigs);
	return ept->ops->get_signals(ept);
}
EXPORT_SYMBOL(rpmsg_get_sigs);
EXPORT_SYMBOL(rpmsg_get_signals);

/**
 * rpmsg_set_sigs() - set the remote signals for this endpoint
 * rpmsg_set_signals() - set the remote signals for this endpoint
 * @ept:	the rpmsg endpoint
 * @sigs:	serial signals bitmask
 * @set:	set mask for signals
 * @clear:	clear mask for signals
 *
 * Returns 0 on success and an appropriate error value on failure.
 */
int rpmsg_set_sigs(struct rpmsg_endpoint *ept, u32 sigs)
int rpmsg_set_signals(struct rpmsg_endpoint *ept, u32 set, u32 clear)
{
	if (WARN_ON(!ept))
		return -EINVAL;
	if (!ept->ops->set_sigs)
	if (!ept->ops->set_signals)
		return -ENXIO;

	return ept->ops->set_sigs(ept, sigs);
	return ept->ops->set_signals(ept, set, clear);
}
EXPORT_SYMBOL(rpmsg_set_sigs);
EXPORT_SYMBOL(rpmsg_set_signals);

/*
 * match an rpmsg channel with a channel info struct.
+5 −5
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
 *
 * Copyright (C) 2011 Texas Instruments, Inc.
 * Copyright (C) 2011 Google, Inc.
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 *
 * Ohad Ben-Cohen <ohad@wizery.com>
 * Brian Swetland <swetland@google.com>
@@ -48,8 +48,8 @@ struct rpmsg_device_ops {
 * @trysendto:		see @rpmsg_trysendto(), optional
 * @trysend_offchannel:	see @rpmsg_trysend_offchannel(), optional
 * @poll:		see @rpmsg_poll(), optional
 * @get_sigs:		see @rpmsg_get_sigs(), optional
 * @set_sigs:		see @rpmsg_set_sigs(), optional
 * @get_signals:	see @rpmsg_get_signals(), optional
 * @set_signals:	see @rpmsg_set_signals(), optional
 *
 * Indirection table for the operations that a rpmsg backend should implement.
 * In addition to @destroy_ept, the backend must at least implement @send and
@@ -69,8 +69,8 @@ struct rpmsg_endpoint_ops {
			     void *data, int len);
	__poll_t (*poll)(struct rpmsg_endpoint *ept, struct file *filp,
			     poll_table *wait);
	int (*get_sigs)(struct rpmsg_endpoint *ept, u32 *lsigs, u32 *rsigs);
	int (*set_sigs)(struct rpmsg_endpoint *ept, u32 sigs);
	int (*get_signals)(struct rpmsg_endpoint *ept);
	int (*set_signals)(struct rpmsg_endpoint *ept, u32 set, u32 clear);
};

int rpmsg_register_device(struct rpmsg_device *rpdev);
Loading