Loading drivers/rpmsg/qcom_smd.c +59 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/sizes.h> #include <linux/slab.h> #include <linux/soc/qcom/smem.h> #include <linux/termios.h> #include <linux/wait.h> #include <linux/rpmsg.h> #include <linux/rpmsg/qcom_smd.h> Loading Loading @@ -226,6 +227,7 @@ struct qcom_smd_channel { void *drvdata; struct list_head list; u32 rsigs; }; /* Loading Loading @@ -288,6 +290,14 @@ struct smd_channel_info_word_pair { channel->info->rx.param); \ }) #define GET_RX_CHANNEL_SIGNAL(channel) \ ({ \ (GET_RX_CHANNEL_FLAG(channel, fDSR) ? TIOCM_DSR : 0) | \ (GET_RX_CHANNEL_FLAG(channel, fCTS) ? TIOCM_CTS : 0) | \ (GET_RX_CHANNEL_FLAG(channel, fCD) ? TIOCM_CD : 0) | \ (GET_RX_CHANNEL_FLAG(channel, fRI) ? TIOCM_RI : 0); \ }) #define SET_RX_CHANNEL_FLAG(channel, param, value) \ ({ \ BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \ Loading Loading @@ -575,9 +585,11 @@ static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel) */ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel) { struct rpmsg_endpoint *ept = &channel->qsept->ept; bool need_state_scan = false; int remote_state; __le32 pktlen; u32 rsig = 0; int avail; int ret; Loading @@ -600,6 +612,14 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel) if (channel->state != SMD_CHANNEL_OPENED) goto out; /* Check if any signal updated */ rsig = GET_RX_CHANNEL_SIGNAL(channel); if ((ept->sig_cb) && (channel->rsigs != rsig)) { ept->sig_cb(ept->rpdev, channel->rsigs, rsig); channel->rsigs = rsig; } /* Indicate that we've seen the new data */ SET_RX_CHANNEL_FLAG(channel, fHEAD, 0); Loading @@ -621,7 +641,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel) } /* Indicate that we have seen and updated tail */ SET_RX_CHANNEL_FLAG(channel, fTAIL, 1); SET_TX_CHANNEL_FLAG(channel, fTAIL, 1); /* Signal the remote that we've consumed the data (if requested) */ if (!GET_RX_CHANNEL_FLAG(channel, fBLOCKREADINTR)) { Loading Loading @@ -820,9 +840,9 @@ static int qcom_smd_channel_open(struct qcom_smd_channel *channel, int ret; /* * Packets are maximum 4k, but reduce if the fifo is smaller * Packets are maximum 8k, but reduce if the fifo is smaller */ bb_size = min(channel->fifo_size, SZ_4K); bb_size = min(channel->fifo_size, SZ_8K); channel->bounce_buffer = kmalloc(bb_size, GFP_KERNEL); if (!channel->bounce_buffer) return -ENOMEM; Loading Loading @@ -989,6 +1009,39 @@ static __poll_t qcom_smd_poll(struct rpmsg_endpoint *ept, return mask; } static int qcom_smd_get_sigs(struct rpmsg_endpoint *ept, u32 *lsigs, u32 *rsigs) { struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept); struct qcom_smd_channel *channel = qsept->qsch; *lsigs = 0; *rsigs = 0; *rsigs = GET_RX_CHANNEL_SIGNAL(channel); return 0; } static int qcom_smd_set_sigs(struct rpmsg_endpoint *ept, u32 sigs) { struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept); struct qcom_smd_channel *channel = qsept->qsch; if (sigs & TIOCM_DTR) SET_TX_CHANNEL_FLAG(channel, fDSR, 1); else SET_TX_CHANNEL_FLAG(channel, fDSR, 0); if (sigs & TIOCM_RTS) SET_TX_CHANNEL_FLAG(channel, fCTS, 1); else SET_TX_CHANNEL_FLAG(channel, fDSR, 0); SET_TX_CHANNEL_FLAG(channel, fSTATE, 1); qcom_smd_signal_channel(channel); return 0; } /* * Finds the device_node for the smd child interested in this channel. */ Loading Loading @@ -1040,6 +1093,8 @@ static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = { .send = qcom_smd_send, .trysend = qcom_smd_trysend, .poll = qcom_smd_poll, .get_sigs = qcom_smd_get_sigs, .set_sigs = qcom_smd_set_sigs, }; static void qcom_smd_release_device(struct device *dev) Loading Loading @@ -1590,7 +1645,7 @@ static int __init qcom_smd_init(void) { return platform_driver_register(&qcom_smd_driver); } subsys_initcall(qcom_smd_init); postcore_initcall(qcom_smd_init); static void __exit qcom_smd_exit(void) { Loading Loading
drivers/rpmsg/qcom_smd.c +59 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/sizes.h> #include <linux/slab.h> #include <linux/soc/qcom/smem.h> #include <linux/termios.h> #include <linux/wait.h> #include <linux/rpmsg.h> #include <linux/rpmsg/qcom_smd.h> Loading Loading @@ -226,6 +227,7 @@ struct qcom_smd_channel { void *drvdata; struct list_head list; u32 rsigs; }; /* Loading Loading @@ -288,6 +290,14 @@ struct smd_channel_info_word_pair { channel->info->rx.param); \ }) #define GET_RX_CHANNEL_SIGNAL(channel) \ ({ \ (GET_RX_CHANNEL_FLAG(channel, fDSR) ? TIOCM_DSR : 0) | \ (GET_RX_CHANNEL_FLAG(channel, fCTS) ? TIOCM_CTS : 0) | \ (GET_RX_CHANNEL_FLAG(channel, fCD) ? TIOCM_CD : 0) | \ (GET_RX_CHANNEL_FLAG(channel, fRI) ? TIOCM_RI : 0); \ }) #define SET_RX_CHANNEL_FLAG(channel, param, value) \ ({ \ BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \ Loading Loading @@ -575,9 +585,11 @@ static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel) */ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel) { struct rpmsg_endpoint *ept = &channel->qsept->ept; bool need_state_scan = false; int remote_state; __le32 pktlen; u32 rsig = 0; int avail; int ret; Loading @@ -600,6 +612,14 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel) if (channel->state != SMD_CHANNEL_OPENED) goto out; /* Check if any signal updated */ rsig = GET_RX_CHANNEL_SIGNAL(channel); if ((ept->sig_cb) && (channel->rsigs != rsig)) { ept->sig_cb(ept->rpdev, channel->rsigs, rsig); channel->rsigs = rsig; } /* Indicate that we've seen the new data */ SET_RX_CHANNEL_FLAG(channel, fHEAD, 0); Loading @@ -621,7 +641,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel) } /* Indicate that we have seen and updated tail */ SET_RX_CHANNEL_FLAG(channel, fTAIL, 1); SET_TX_CHANNEL_FLAG(channel, fTAIL, 1); /* Signal the remote that we've consumed the data (if requested) */ if (!GET_RX_CHANNEL_FLAG(channel, fBLOCKREADINTR)) { Loading Loading @@ -820,9 +840,9 @@ static int qcom_smd_channel_open(struct qcom_smd_channel *channel, int ret; /* * Packets are maximum 4k, but reduce if the fifo is smaller * Packets are maximum 8k, but reduce if the fifo is smaller */ bb_size = min(channel->fifo_size, SZ_4K); bb_size = min(channel->fifo_size, SZ_8K); channel->bounce_buffer = kmalloc(bb_size, GFP_KERNEL); if (!channel->bounce_buffer) return -ENOMEM; Loading Loading @@ -989,6 +1009,39 @@ static __poll_t qcom_smd_poll(struct rpmsg_endpoint *ept, return mask; } static int qcom_smd_get_sigs(struct rpmsg_endpoint *ept, u32 *lsigs, u32 *rsigs) { struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept); struct qcom_smd_channel *channel = qsept->qsch; *lsigs = 0; *rsigs = 0; *rsigs = GET_RX_CHANNEL_SIGNAL(channel); return 0; } static int qcom_smd_set_sigs(struct rpmsg_endpoint *ept, u32 sigs) { struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept); struct qcom_smd_channel *channel = qsept->qsch; if (sigs & TIOCM_DTR) SET_TX_CHANNEL_FLAG(channel, fDSR, 1); else SET_TX_CHANNEL_FLAG(channel, fDSR, 0); if (sigs & TIOCM_RTS) SET_TX_CHANNEL_FLAG(channel, fCTS, 1); else SET_TX_CHANNEL_FLAG(channel, fDSR, 0); SET_TX_CHANNEL_FLAG(channel, fSTATE, 1); qcom_smd_signal_channel(channel); return 0; } /* * Finds the device_node for the smd child interested in this channel. */ Loading Loading @@ -1040,6 +1093,8 @@ static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = { .send = qcom_smd_send, .trysend = qcom_smd_trysend, .poll = qcom_smd_poll, .get_sigs = qcom_smd_get_sigs, .set_sigs = qcom_smd_set_sigs, }; static void qcom_smd_release_device(struct device *dev) Loading Loading @@ -1590,7 +1645,7 @@ static int __init qcom_smd_init(void) { return platform_driver_register(&qcom_smd_driver); } subsys_initcall(qcom_smd_init); postcore_initcall(qcom_smd_init); static void __exit qcom_smd_exit(void) { Loading