diff --git a/abi_gki_aarch64_a200ad52ff.xml b/abi_gki_aarch64_a200ad52ff.xml index e3215c5f540c..1b9cc62a4ede 100644 --- a/abi_gki_aarch64_a200ad52ff.xml +++ b/abi_gki_aarch64_a200ad52ff.xml @@ -1884,11 +1884,11 @@ - + - + @@ -2773,7 +2773,7 @@ - + @@ -23863,7 +23863,7 @@ - + @@ -43856,6 +43856,16 @@ + + + + + + + + + + @@ -43874,16 +43884,6 @@ - - - - - - - - - - @@ -46141,10 +46141,10 @@ - + - - + + @@ -46199,7 +46199,7 @@ - + @@ -46226,10 +46226,10 @@ - + - + @@ -46260,7 +46260,7 @@ - + @@ -46270,11 +46270,11 @@ - - + + + - @@ -46314,15 +46314,14 @@ - - - - + + - + - + + @@ -46347,12 +46346,6 @@ - - - - - - @@ -46361,8 +46354,20 @@ - + + + + + + + + + + + + + @@ -46374,12 +46379,6 @@ - - - - - - @@ -49510,78 +49509,78 @@ - - - - - - + + + + + + - - - - - + + + + + - - - - - + + + + + - - + + - - - + + + - - + + - - - - - - + + + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - + + - - + + - - + + @@ -56404,20 +56403,20 @@ - + - + - + - + @@ -56438,22 +56437,22 @@ - + - + - + - + @@ -58210,16 +58209,6 @@ - - - - - - - - - - @@ -58542,7 +58531,7 @@ - + @@ -58825,7 +58814,7 @@ - + @@ -59074,7 +59063,7 @@ - + @@ -59089,7 +59078,7 @@ - + @@ -59149,41 +59138,21 @@ - - - - - - - - - - - - - - - - - - - - - + - + - + - + @@ -59194,8 +59163,7 @@ - - + @@ -60179,7 +60147,7 @@ - + @@ -60188,7 +60156,7 @@ - + @@ -67395,7 +67363,7 @@ - + @@ -69545,7 +69513,7 @@ - + @@ -70445,7 +70413,7 @@ - + @@ -70509,7 +70477,7 @@ - + @@ -72026,7 +71994,7 @@ - + @@ -72212,7 +72180,7 @@ - + @@ -77371,7 +77339,7 @@ - + @@ -77836,7 +77804,7 @@ - + @@ -77881,7 +77849,7 @@ - + @@ -78696,7 +78664,7 @@ - + @@ -79781,7 +79749,7 @@ - + @@ -79790,7 +79758,7 @@ - + @@ -80872,10 +80840,10 @@ - + - + @@ -82554,7 +82522,7 @@ - + @@ -85723,7 +85691,7 @@ - + @@ -85815,7 +85783,7 @@ - + @@ -86054,7 +86022,7 @@ - + @@ -86659,7 +86627,7 @@ - + @@ -89189,7 +89157,7 @@ - + @@ -94722,10 +94690,10 @@ - + - + @@ -95368,7 +95336,7 @@ - + @@ -95579,7 +95547,7 @@ - + @@ -96136,7 +96104,7 @@ - + @@ -97274,7 +97242,6 @@ - @@ -97900,10 +97867,10 @@ - + - + @@ -99632,7 +99599,6 @@ - @@ -100369,7 +100335,8 @@ - + + @@ -100391,6 +100358,7 @@ + @@ -101069,7 +101037,7 @@ - + diff --git a/abi_gki_aarch64_qcom_whitelist b/abi_gki_aarch64_qcom_whitelist index cde8cbe988fe..dd438b3387eb 100644 --- a/abi_gki_aarch64_qcom_whitelist +++ b/abi_gki_aarch64_qcom_whitelist @@ -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 diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index fb5146d536d3..c12fd609c882 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1,7 +1,7 @@ // 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 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -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, @@ -1089,7 +1097,7 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid) } /** - * qcom_glink_send_signals() - convert a signal cmd to wire format and transmit + * qcom_glink_send_signals() - convert a signal cmd to wire format and transmit * @glink: The transport to transmit on. * @channel: The glink channel * @sigs: The signals to encode. @@ -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; + + /* 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; - if (channel->ept.sig_cb) - channel->ept.sig_cb(channel->ept.rpdev, old, channel->rsigs); - 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) diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index dae34f089770..f3541a507451 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -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 * Brian Swetland @@ -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. diff --git a/drivers/rpmsg/rpmsg_internal.h b/drivers/rpmsg/rpmsg_internal.h index 47f7d65f422b..6587d416722b 100644 --- a/drivers/rpmsg/rpmsg_internal.h +++ b/drivers/rpmsg/rpmsg_internal.h @@ -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 * Brian Swetland @@ -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); diff --git a/drivers/soc/qcom/glink_pkt.c b/drivers/soc/qcom/glink_pkt.c index dea073de0f6f..146485b3c578 100644 --- a/drivers/soc/qcom/glink_pkt.c +++ b/drivers/soc/qcom/glink_pkt.c @@ -33,37 +33,6 @@ do { \ ##__VA_ARGS__);\ } while (0) -#define SMD_DTR_SIG BIT(31) -#define SMD_CTS_SIG BIT(30) -#define SMD_CD_SIG BIT(29) -#define SMD_RI_SIG BIT(28) - -#define to_smd_signal(sigs) \ -do { \ - sigs &= 0x0fff; \ - if (sigs & TIOCM_DTR) \ - sigs |= SMD_DTR_SIG; \ - if (sigs & TIOCM_RTS) \ - sigs |= SMD_CTS_SIG; \ - if (sigs & TIOCM_CD) \ - sigs |= SMD_CD_SIG; \ - if (sigs & TIOCM_RI) \ - sigs |= SMD_RI_SIG; \ -} while (0) - -#define from_smd_signal(sigs) \ -do { \ - if (sigs & SMD_DTR_SIG) \ - sigs |= TIOCM_DSR; \ - if (sigs & SMD_CTS_SIG) \ - sigs |= TIOCM_CTS; \ - if (sigs & SMD_CD_SIG) \ - sigs |= TIOCM_CD; \ - if (sigs & SMD_RI_SIG) \ - sigs |= TIOCM_RI; \ - sigs &= 0x0fff; \ -} while (0) - #define GLINK_PKT_IOCTL_MAGIC (0xC3) #define GLINK_PKT_IOCTL_QUEUE_RX_INTENT \ @@ -195,7 +164,8 @@ static int glink_pkt_rpdev_cb(struct rpmsg_device *rpdev, void *buf, int len, return 0; } -static int glink_pkt_rpdev_sigs(struct rpmsg_device *rpdev, u32 old, u32 new) +static int glink_pkt_rpdev_sigs(struct rpmsg_device *rpdev, void *priv, + u32 old, u32 new) { struct device_driver *drv = rpdev->dev.driver; struct rpmsg_driver *rpdrv = drv_to_rpdrv(drv); @@ -493,35 +463,33 @@ static __poll_t glink_pkt_poll(struct file *file, poll_table *wait) * TIOCMBIC and TICOMSET. */ static int glink_pkt_tiocmset(struct glink_pkt_device *gpdev, unsigned int cmd, - unsigned long arg) + int __user *arg) { - u32 lsigs, rsigs, val; + u32 set, clear, val; int ret; - ret = get_user(val, (u32 *)arg); + ret = get_user(val, arg); if (ret) return ret; - - to_smd_signal(val); - ret = rpmsg_get_sigs(gpdev->rpdev->ept, &lsigs, &rsigs); - if (ret < 0) { - GLINK_PKT_ERR("%s: Get signals failed[%d]\n", __func__, ret); - return ret; - } + set = clear = 0; switch (cmd) { case TIOCMBIS: - lsigs |= val; + set = val; break; case TIOCMBIC: - lsigs &= ~val; + clear = val; break; case TIOCMSET: - lsigs = val; + set = val; + clear = ~val; break; } - ret = rpmsg_set_sigs(gpdev->rpdev->ept, lsigs); - GLINK_PKT_INFO("sigs[0x%x] ret[%d]\n", lsigs, ret); - return ret; + + set &= TIOCM_DTR | TIOCM_RTS | TIOCM_CD | TIOCM_RI; + clear &= TIOCM_DTR | TIOCM_RTS | TIOCM_CD | TIOCM_RI; + GLINK_PKT_INFO("set[0x%x] clear[0x%x]\n", set, clear); + + return rpmsg_set_signals(gpdev->rpdev->ept, set, clear); } /** @@ -539,7 +507,6 @@ static long glink_pkt_ioctl(struct file *file, unsigned int cmd, { struct glink_pkt_device *gpdev; unsigned long flags; - u32 lsigs, rsigs; int ret; gpdev = file->private_data; @@ -562,15 +529,14 @@ static long glink_pkt_ioctl(struct file *file, unsigned int cmd, gpdev->sig_change = false; spin_unlock_irqrestore(&gpdev->queue_lock, flags); - ret = rpmsg_get_sigs(gpdev->rpdev->ept, &lsigs, &rsigs); - from_smd_signal(rsigs); - if (!ret) - ret = put_user(rsigs, (uint32_t *)arg); + ret = rpmsg_get_signals(gpdev->rpdev->ept); + if (ret >= 0) + ret = put_user(ret, (int __user *)arg); break; case TIOCMSET: case TIOCMBIS: case TIOCMBIC: - ret = glink_pkt_tiocmset(gpdev, cmd, arg); + ret = glink_pkt_tiocmset(gpdev, cmd, (int __user *)arg); break; case GLINK_PKT_IOCTL_QUEUE_RX_INTENT: /* Return success to not break userspace client logic */ diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index f8b12665012f..4caa941e194a 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h @@ -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. * All rights reserved. */ @@ -61,15 +61,15 @@ struct rpmsg_device { }; typedef int (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32); -typedef int (*rpmsg_rx_sig_t)(struct rpmsg_device *, u32, u32); +typedef int (*rpmsg_rx_sig_t)(struct rpmsg_device *, void *, u32, u32); /** * struct rpmsg_endpoint - binds a local rpmsg address to its user * @rpdev: rpmsg channel device * @refcount: when this drops to zero, the ept is deallocated * @cb: rx callback handler - * @sig_cb: rx serial signal handler * @cb_lock: must be taken before accessing/changing @cb + * @sig_cb: rx serial signal handler * @addr: local rpmsg address * @priv: private data for the driver's use * @@ -91,8 +91,8 @@ struct rpmsg_endpoint { struct rpmsg_device *rpdev; struct kref refcount; rpmsg_rx_cb_t cb; - rpmsg_rx_sig_t sig_cb; struct mutex cb_lock; + rpmsg_rx_sig_t sig_cb; u32 addr; void *priv; @@ -114,7 +114,8 @@ struct rpmsg_driver { int (*probe)(struct rpmsg_device *dev); void (*remove)(struct rpmsg_device *dev); int (*callback)(struct rpmsg_device *, void *, int, void *, u32); - int (*signals)(struct rpmsg_device *rpdev, u32 old, u32 new); + int (*signals)(struct rpmsg_device *rpdev, + void *priv, u32 old, u32 new); }; #if IS_ENABLED(CONFIG_RPMSG) @@ -141,8 +142,8 @@ int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst, __poll_t rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp, poll_table *wait); -int rpmsg_get_sigs(struct rpmsg_endpoint *ept, u32 *lsigs, u32 *rsigs); -int rpmsg_set_sigs(struct rpmsg_endpoint *ept, u32 sigs); +int rpmsg_get_signals(struct rpmsg_endpoint *ept); +int rpmsg_set_signals(struct rpmsg_endpoint *ept, u32 set, u32 clear); #else @@ -251,8 +252,7 @@ static inline __poll_t rpmsg_poll(struct rpmsg_endpoint *ept, return 0; } -static inline int rpmsg_get_sigs(struct rpmsg_endpoint *ept, u32 *lsigs, - u32 *rsigs) +static inline int rpmsg_get_signals(struct rpmsg_endpoint *ept) { /* This shouldn't be possible */ WARN_ON(1); @@ -260,7 +260,8 @@ static inline int rpmsg_get_sigs(struct rpmsg_endpoint *ept, u32 *lsigs, return -ENXIO; } -static inline int rpmsg_set_sigs(struct rpmsg_endpoint *ept, u32 sigs) +static inline int rpmsg_set_signals(struct rpmsg_endpoint *ept, + u32 set, u32 clear) { /* This shouldn't be possible */ WARN_ON(1);