Merge "defconfig: Enable glink pkt and probe for pineapple"

This commit is contained in:
qctecmdr 2022-11-23 09:47:54 -08:00 committed by Gerrit - the friendly Code Review server
commit 03fbda6c39
8 changed files with 201 additions and 34 deletions

View File

@ -104,6 +104,8 @@ CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE=y
CONFIG_QCOM_DMABUF_HEAPS_UBWCP=y
CONFIG_QCOM_EUD=m
CONFIG_QCOM_GDSC_REGULATOR=m
CONFIG_QCOM_GLINK=m
CONFIG_QCOM_GLINK_PKT=m
CONFIG_QCOM_IOMMU_DEBUG=m
CONFIG_QCOM_IOMMU_UTIL=m
# CONFIG_QCOM_IPA is not set

View File

@ -76,6 +76,15 @@ config RPMSG_QCOM_GLINK_SPSS
region with the remote proc by writing the smem descriptor location
and size into shared registers.
config QCOM_GLINK_PKT
tristate "Enable device interface for GLINK packet channels"
depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SLATECOM
help
G-link packet driver provides the interface for the userspace
clients to communicate over G-Link via device nodes.
This enable the userspace clients to read and write to
some glink packets channel.
config RPMSG_QCOM_SMD
tristate "Qualcomm Shared Memory Driver (SMD)"
depends on MAILBOX

View File

@ -10,4 +10,5 @@ obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o
obj-$(CONFIG_RPMSG_QCOM_GLINK_SMEM) += qcom_glink_smem.o
obj-$(CONFIG_RPMSG_QCOM_GLINK_SPSS) += qcom_glink_spss.o
obj-$(CONFIG_RPMSG_QCOM_SMD) += qcom_smd.o
obj-$(CONFIG_QCOM_GLINK_PKT) += glink_pkt.o
obj-$(CONFIG_RPMSG_VIRTIO) += virtio_rpmsg_bus.o

View File

@ -17,6 +17,8 @@
#include <linux/uaccess.h>
#include <linux/termios.h>
#include "qcom_glink_native.h"
/* Define IPC Logging Macros */
#define GLINK_PKT_IPC_LOG_PAGE_CNT 2
static void *glink_pkt_ilctxt;
@ -132,22 +134,6 @@ static ssize_t open_timeout_show(struct device *dev,
static DEVICE_ATTR_RW(open_timeout);
static int glink_pkt_rpdev_probe(struct rpmsg_device *rpdev)
{
struct device_driver *drv = rpdev->dev.driver;
struct rpmsg_driver *rpdrv = drv_to_rpdrv(drv);
struct glink_pkt_device *gpdev = rpdrv_to_gpdev(rpdrv);
mutex_lock(&gpdev->lock);
gpdev->rpdev = rpdev;
mutex_unlock(&gpdev->lock);
dev_set_drvdata(&rpdev->dev, gpdev);
complete_all(&gpdev->ch_open);
return 0;
}
static int glink_pkt_rpdev_cb(struct rpmsg_device *rpdev, void *buf, int len,
void *priv, u32 addr)
{
@ -194,6 +180,23 @@ static int glink_pkt_rpdev_sigs(struct rpmsg_device *rpdev, void *priv,
return 0;
}
static int glink_pkt_rpdev_probe(struct rpmsg_device *rpdev)
{
struct device_driver *drv = rpdev->dev.driver;
struct rpmsg_driver *rpdrv = drv_to_rpdrv(drv);
struct glink_pkt_device *gpdev = rpdrv_to_gpdev(rpdrv);
mutex_lock(&gpdev->lock);
gpdev->rpdev = rpdev;
qcom_glink_register_signals_cb(rpdev->ept, glink_pkt_rpdev_sigs);
mutex_unlock(&gpdev->lock);
dev_set_drvdata(&rpdev->dev, gpdev);
complete_all(&gpdev->ch_open);
return 0;
}
static void glink_pkt_rpdev_remove(struct rpmsg_device *rpdev)
{
struct device_driver *drv = rpdev->dev.driver;
@ -558,7 +561,7 @@ static int glink_pkt_tiocmset(struct glink_pkt_device *gpdev, unsigned int cmd,
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);
return qcom_glink_set_signals(gpdev->rpdev->ept, set, clear);
}
/**
@ -598,7 +601,7 @@ 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_signals(gpdev->rpdev->ept);
ret = qcom_glink_get_signals(gpdev->rpdev->ept);
if (ret >= 0)
ret = put_user(ret, (int __user *)arg);
break;
@ -727,7 +730,6 @@ static int glink_pkt_init_rpmsg(struct glink_pkt_device *gpdev)
rpdrv->probe = glink_pkt_rpdev_probe;
rpdrv->remove = glink_pkt_rpdev_remove;
rpdrv->callback = glink_pkt_rpdev_cb;
rpdrv->signals = glink_pkt_rpdev_sigs;
rpdrv->id_table = match;
rpdrv->drv.name = drv_name;

View File

@ -22,6 +22,7 @@
#include <linux/kthread.h>
#include <linux/mailbox_client.h>
#include <linux/suspend.h>
#include <linux/termios.h>
#include <linux/ipc_logging.h>
#include "rpmsg_internal.h"
@ -200,6 +201,9 @@ enum {
* @intent_req_completed: Status of intent request completion
* @intent_req_ack: Waitqueue for @intent_req_acked
* @intent_req_comp: Waitqueue for @intent_req_completed
* @local_signals: local side signals
* @remote_sigalss: remote side signals
* @signals_cb: client callback for notifying signal change
*/
struct glink_channel {
struct rpmsg_endpoint ept;
@ -235,6 +239,10 @@ struct glink_channel {
atomic_t intent_req_completed;
wait_queue_head_t intent_req_ack;
wait_queue_head_t intent_req_comp;
unsigned int local_signals;
unsigned int remote_signals;
int (*signals_cb)(struct rpmsg_device *dev, void *priv, u32 old, u32 new);
};
#define to_glink_channel(_ept) container_of(_ept, struct glink_channel, ept)
@ -255,9 +263,15 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops;
#define RPM_CMD_TX_DATA_CONT 12
#define RPM_CMD_READ_NOTIF 13
#define RPM_CMD_RX_DONE_W_REUSE 14
#define RPM_CMD_SIGNALS 15
#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,
@ -422,7 +436,8 @@ static int qcom_glink_tx(struct qcom_glink *glink,
spin_unlock_irqrestore(&glink->tx_lock, flags);
wait_event_timeout(glink->tx_avail_notify,
qcom_glink_tx_avail(glink) >= tlen, 10 * HZ);
qcom_glink_tx_avail(glink) >= tlen ||
atomic_read(&glink->in_reset), 10 * HZ);
spin_lock_irqsave(&glink->tx_lock, flags);
@ -642,6 +657,7 @@ static void qcom_glink_rx_done(struct qcom_glink *glink,
struct glink_channel *channel,
struct glink_core_rx_intent *intent)
{
unsigned long flags;
int ret = -EAGAIN;
/* We don't send RX_DONE to intentless systems */
@ -653,13 +669,13 @@ static void qcom_glink_rx_done(struct qcom_glink *glink,
/* Take it off the tree of receive intents */
if (!intent->reuse) {
spin_lock(&channel->intent_lock);
spin_lock_irqsave(&channel->intent_lock, flags);
idr_remove(&channel->liids, intent->id);
spin_unlock(&channel->intent_lock);
spin_unlock_irqrestore(&channel->intent_lock, flags);
}
/* Schedule the sending of a rx_done indication */
spin_lock(&channel->intent_lock);
spin_lock_irqsave(&channel->intent_lock, flags);
if (list_empty(&channel->done_intents))
ret = __qcom_glink_rx_done(glink, channel, intent, false);
@ -667,7 +683,7 @@ static void qcom_glink_rx_done(struct qcom_glink *glink,
list_add_tail(&intent->node, &channel->done_intents);
kthread_queue_work(&glink->kworker, &channel->intent_work);
}
spin_unlock(&channel->intent_lock);
spin_unlock_irqrestore(&channel->intent_lock, flags);
}
/**
@ -1181,6 +1197,77 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
return 0;
}
/**
* qcom_glink_send_signals() - convert a signal cmd to wire format and transmit
* @glink: The transport to transmit on.
* @channel: The glink channel
* @signals: The signals to encode.
*
* Return: 0 on success or standard Linux error code.
*/
static int qcom_glink_send_signals(struct qcom_glink *glink,
struct glink_channel *channel,
u32 signals)
{
struct glink_msg msg;
/* convert signals from TIOCM to NATIVE */
signals &= 0x0fff;
if (signals & TIOCM_DTR)
signals |= NATIVE_DTR_SIG;
if (signals & TIOCM_RTS)
signals |= NATIVE_CTS_SIG;
if (signals & TIOCM_CD)
signals |= NATIVE_CD_SIG;
if (signals & TIOCM_RI)
signals |= NATIVE_RI_SIG;
msg.cmd = cpu_to_le16(RPM_CMD_SIGNALS);
msg.param1 = cpu_to_le16(channel->lcid);
msg.param2 = cpu_to_le32(signals);
GLINK_INFO(glink->ilc, "signals:%d\n", signals);
return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
}
static int qcom_glink_handle_signals(struct qcom_glink *glink,
unsigned int rcid, unsigned int signals)
{
struct glink_channel *channel;
unsigned long flags;
u32 old;
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, rcid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
if (!channel) {
dev_err(glink->dev, "signal for non-existing channel\n");
return -EINVAL;
}
old = channel->remote_signals;
/* 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->remote_signals = signals;
CH_INFO(channel, "old:%d new:%d\n", old, channel->remote_signals);
if (channel->signals_cb)
channel->signals_cb(channel->ept.rpdev, channel->ept.priv,
old, channel->remote_signals);
return 0;
}
static int qcom_glink_native_rx(struct qcom_glink *glink, int iterations)
{
struct glink_msg msg;
@ -1261,6 +1348,10 @@ static int qcom_glink_native_rx(struct qcom_glink *glink, int iterations)
qcom_glink_handle_intent_req_ack(glink, param1, param2);
qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
break;
case RPM_CMD_SIGNALS:
qcom_glink_handle_signals(glink, param1, param2);
qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
break;
default:
dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd);
ret = -EINVAL;
@ -1691,6 +1782,70 @@ static int qcom_glink_trysendto(struct rpmsg_endpoint *ept, void *data, int len,
return __qcom_glink_send(channel, data, len, false);
}
int qcom_glink_get_signals(struct rpmsg_endpoint *ept)
{
struct glink_channel *channel;
if (!ept)
return 0;
channel = to_glink_channel(ept);
return channel->remote_signals;
}
EXPORT_SYMBOL(qcom_glink_get_signals);
int qcom_glink_set_signals(struct rpmsg_endpoint *ept, u32 set, u32 clear)
{
struct glink_channel *channel;
struct qcom_glink *glink;
u32 signals;
if (!ept)
return -EINVAL;
channel = to_glink_channel(ept);
glink = channel->glink;
signals = channel->local_signals;
if (set & TIOCM_DTR)
signals |= TIOCM_DTR;
if (set & TIOCM_RTS)
signals |= TIOCM_RTS;
if (set & TIOCM_CD)
signals |= TIOCM_CD;
if (set & TIOCM_RI)
signals |= TIOCM_RI;
if (clear & TIOCM_DTR)
signals &= ~TIOCM_DTR;
if (clear & TIOCM_RTS)
signals &= ~TIOCM_RTS;
if (clear & TIOCM_CD)
signals &= ~TIOCM_CD;
if (clear & TIOCM_RI)
signals &= ~TIOCM_RI;
channel->local_signals = signals;
return qcom_glink_send_signals(glink, channel, signals);
}
EXPORT_SYMBOL(qcom_glink_set_signals);
int qcom_glink_register_signals_cb(struct rpmsg_endpoint *ept,
int (*cb)(struct rpmsg_device *, void *, u32, u32))
{
struct glink_channel *channel;
if (!ept || !cb)
return -EINVAL;
channel = to_glink_channel(ept);
channel->signals_cb = cb;
return 0;
}
EXPORT_SYMBOL(qcom_glink_register_signals_cb);
/*
* Finds the device_node for the glink child interested in this channel.
*/

View File

@ -6,6 +6,8 @@
#ifndef __QCOM_GLINK_NATIVE_H__
#define __QCOM_GLINK_NATIVE_H__
#include <linux/rpmsg.h>
#define GLINK_FEATURE_INTENT_REUSE BIT(0)
#define GLINK_FEATURE_MIGRATION BIT(1)
#define GLINK_FEATURE_TRACER_PKT BIT(2)
@ -38,4 +40,10 @@ int qcom_glink_native_start(struct qcom_glink *glink);
void qcom_glink_native_remove(struct qcom_glink *glink);
void qcom_glink_native_unregister(struct qcom_glink *glink);
/* These operations are temporarily exposing signal interfaces */
int qcom_glink_get_signals(struct rpmsg_endpoint *ept);
int qcom_glink_set_signals(struct rpmsg_endpoint *ept, u32 set, u32 clear);
int qcom_glink_register_signals_cb(struct rpmsg_endpoint *ept,
int (*signals_cb)(struct rpmsg_device *dev, void *priv, u32 old, u32 new));
#endif

View File

@ -369,15 +369,6 @@ config QCOM_GLINK
all the edges present in the device.
Say M if you want to enable this module.
config QCOM_GLINK_PKT
tristate "Enable device interface for GLINK packet channels"
depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SLATECOM
help
G-link packet driver provides the interface for the userspace
clients to communicate over G-Link via device nodes.
This enable the userspace clients to read and write to
some glink packets channel.
config QTI_PMIC_GLINK
tristate "Enable support for PMIC GLINK"
depends on RPMSG

View File

@ -24,7 +24,6 @@ obj-$(CONFIG_QCOM_SMSM) += smsm.o
obj-$(CONFIG_QCOM_SMP2P_SLEEPSTATE) += smp2p_sleepstate.o
obj-$(CONFIG_QSEE_IPC_IRQ_BRIDGE) += qsee_ipc_irq_bridge.o
obj-$(CONFIG_QCOM_GLINK) += glink_probe.o
obj-$(CONFIG_QCOM_GLINK_PKT) += glink_pkt.o
obj-$(CONFIG_QTI_PMIC_GLINK) += pmic_glink.o
obj-$(CONFIG_QTI_BATTERY_GLINK_DEBUG) += qti_battery_debug.o
obj-$(CONFIG_QTI_CHARGER_ULOG_GLINK) += charger-ulog-glink.o