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

Commit f9ecdee0 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: ipc_router_mhi_xprt: Code Refactor to handle interface changes"

parents 3228f122 69ce41bf
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -600,6 +600,16 @@ config MSM_IPC_ROUTER_GLINK_XPRT
	  this layer registers a transport with IPC Router and enable
	  message exchange.

config MSM_IPC_ROUTER_MHI_XPRT
	depends on MSM_MHI
	depends on IPC_ROUTER
	bool "MSM MHI XPRT Layer"
	help
	  MHI Transport Layer that enables off-chip communication of
	  IPC Router. When the MHI endpoint becomes available, this layer
	  registers the transport with IPC Router and enable message
	  exchange.

config MSM_SYSTEM_HEALTH_MONITOR
	bool "System Health Monitor"
	depends on MSM_QMI_INTERFACE && MSM_SUBSYSTEM_RESTART
+37 −68
Original line number Diff line number Diff line
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -39,18 +39,15 @@ if (ipc_router_mhi_xprt_debug_mask) \
#define IPC_ROUTER_MHI_XPRT_NUM_TRBS 10

/**
 * ipc_router_mhi_addr_map - DMA to virtual address mapping for an IPC Router
 *				packet.
 * ipc_router_mhi_addr_map - Struct for virtual address to IPC Router
 *				packet mapping.
 * @list_node: Address mapping list node used by mhi transport map list.
 * @virt_addr: The virtual address in mapping.
 * @dma_addr: The dma address in mapping.
 * @pkt: The IPC Router packet for which the virtual address of skbs are mapped
 *	to DMA address during TX/RX operations.
 * @pkt: The IPC Router packet for the virtual address
 */
struct ipc_router_mhi_addr_map {
	struct list_head list_node;
	void *virt_addr;
	dma_addr_t dma_addr;
	struct rr_packet *pkt;
};

@@ -109,10 +106,10 @@ struct ipc_router_mhi_channel {
 * @xprt_option: XPRT specific options to be handled by IPC Router.
 * @tx_addr_map_list_lock: The lock to protect the address mapping list for TX
 *			operations.
 * @tx_addr_map_list: DMA to virtual address mapping list for TX operations.
 * @tx_addr_map_list: Virtual address mapping list for TX operations.
 * @rx_addr_map_list_lock: The lock to protect the address mapping list for RX
 *			operations.
 * @rx_addr_map_list: DMA to virtual address mapping list for RX operations.
 * @rx_addr_map_list: Virtual address mapping list for RX operations.
 */
struct ipc_router_mhi_xprt {
	struct list_head list;
@@ -177,13 +174,13 @@ void ipc_router_mhi_release_pkt(struct kref *ref)
 * ipc_router_mhi_xprt_find_addr_map() - Search the mapped virtual address
 * @addr_map_list: The list of address mappings.
 * @addr_map_list_lock: Reference to the lock that protects the @addr_map_list.
 * @addr: The dma address for which mapped virtual address need to be found.
 * @addr: The virtual address that needs to be found.
 *
 * Return: The mapped virtual Address if found, NULL otherwise.
 */
void *ipc_router_mhi_xprt_find_addr_map(struct list_head *addr_map_list,
				struct mutex *addr_map_list_lock,
				dma_addr_t addr)
				void *addr)
{
	struct ipc_router_mhi_addr_map *addr_mapping;
	struct ipc_router_mhi_addr_map *tmp_addr_mapping;
@@ -194,7 +191,7 @@ void *ipc_router_mhi_xprt_find_addr_map(struct list_head *addr_map_list,
	mutex_lock(addr_map_list_lock);
	list_for_each_entry_safe(addr_mapping, tmp_addr_mapping,
				addr_map_list, list_node) {
		if (addr_mapping->dma_addr == addr) {
		if (addr_mapping->virt_addr == addr) {
			virt_addr = addr_mapping->virt_addr;
			list_del(&addr_mapping->list_node);
			if (addr_mapping->pkt)
@@ -207,26 +204,23 @@ void *ipc_router_mhi_xprt_find_addr_map(struct list_head *addr_map_list,
	}
	mutex_unlock(addr_map_list_lock);
	IPC_RTR_ERR(
		"%s: Virtual address mapping for DMA addr [%p] not found\n",
		"%s: Virtual address mapping [%p] not found\n",
		__func__, (void *)addr);
	return NULL;
}

/*
 * ipc_router_mhi_xprt_add_addr_map() - Add a mapping of virtual address to dma
 *					address
 * ipc_router_mhi_xprt_add_addr_map() - Add a virtual address mapping structure
 * @addr_map_list: The list of address mappings.
 * @addr_map_list_lock: Reference to the lock that protects the @addr_map_list.
 * @pkt: The IPC Router packet that contains the virtual address in skbs.
 * @addr: The virtual address which needs to be added.
 * @dma_addr: The dma address which needs to be added.
 * @virt_addr: The virtual address which needs to be added.
 *
 * Return: 0 on success, standard Linux error code otherwise.
 */
int ipc_router_mhi_xprt_add_addr_map(struct list_head *addr_map_list,
				struct mutex *addr_map_list_lock,
				struct rr_packet *pkt, void *virt_addr,
				dma_addr_t dma_addr)
				struct rr_packet *pkt, void *virt_addr)
{
	struct ipc_router_mhi_addr_map *addr_mapping;

@@ -236,7 +230,6 @@ int ipc_router_mhi_xprt_add_addr_map(struct list_head *addr_map_list,
	if (!addr_mapping)
		return -ENOMEM;
	addr_mapping->virt_addr = virt_addr;
	addr_mapping->dma_addr = dma_addr;
	addr_mapping->pkt = pkt;
	mutex_lock(addr_map_list_lock);
	if (addr_mapping->pkt)
@@ -258,9 +251,8 @@ int mhi_xprt_queue_in_buffers(struct ipc_router_mhi_xprt *mhi_xprtp,
{
	int i;
	struct sk_buff *skb;
	dma_addr_t dma_addr;
	uint32_t buf_size = mhi_xprtp->ch_hndl.max_packet_size;
	enum MHI_STATUS rc_val = MHI_STATUS_SUCCESS;
	int rc_val = 0;

	for (i = 0; i < num_trbs; i++) {
		skb = alloc_skb(buf_size, GFP_KERNEL);
@@ -269,31 +261,21 @@ int mhi_xprt_queue_in_buffers(struct ipc_router_mhi_xprt *mhi_xprtp,
				    __func__, (i + 1));
			break;
		}
		dma_addr = dma_map_single(NULL, skb->data,
				buf_size, DMA_BIDIRECTIONAL);
		if (dma_mapping_error(NULL, dma_addr)) {
			IPC_RTR_ERR("%s: Failed to map DMA for SKB # %d\n",
				    __func__, (i + 1));
			kfree_skb(skb);
			break;
		}
		if (ipc_router_mhi_xprt_add_addr_map(
					&mhi_xprtp->rx_addr_map_list,
					&mhi_xprtp->rx_addr_map_list_lock, NULL,
					skb->data, dma_addr) < 0) {
			IPC_RTR_ERR("%s: Could not map %d SKB->DMA address\n",
					skb->data) < 0) {
			IPC_RTR_ERR("%s: Could not map %d SKB address\n",
					__func__, (i + 1));
			break;
		}
		mutex_lock(&mhi_xprtp->ch_hndl.in_skbq_lock);
		rc_val = mhi_queue_xfer(mhi_xprtp->ch_hndl.in_handle,
					 dma_addr, buf_size, MHI_EOT);
		if (rc_val != MHI_STATUS_SUCCESS) {
					skb->data, buf_size, MHI_EOT);
		if (rc_val) {
			mutex_unlock(&mhi_xprtp->ch_hndl.in_skbq_lock);
			IPC_RTR_ERR("%s: Failed to queue TRB # %d into MHI\n",
				    __func__, (i + 1));
			dma_unmap_single(NULL, dma_addr,
					 buf_size, DMA_TO_DEVICE);
			kfree_skb(skb);
			break;
		}
@@ -388,7 +370,6 @@ static int ipc_router_mhi_write_skb(struct ipc_router_mhi_xprt *mhi_xprtp,
	size_t sz_to_write = 0;
	size_t offset = 0;
	int rc;
	dma_addr_t dma_addr;

	while (offset < skb->len) {
		wait_event(mhi_xprtp->write_wait_q,
@@ -404,29 +385,20 @@ static int ipc_router_mhi_write_skb(struct ipc_router_mhi_xprt *mhi_xprtp,

		sz_to_write = min((size_t)(skb->len - offset),
				(size_t)IPC_ROUTER_MHI_XPRT_MAX_PKT_SIZE);
		dma_addr = dma_map_single(NULL, skb->data + offset,
					  sz_to_write, DMA_TO_DEVICE);
		if (dma_mapping_error(NULL, dma_addr)) {
			mutex_unlock(&mhi_xprtp->ch_hndl.state_lock);
			IPC_RTR_ERR("%s: Failed to map DMA 0x%zx\n",
				    __func__, sz_to_write);
			return -ENOMEM;
		}
		if (ipc_router_mhi_xprt_add_addr_map(
					&mhi_xprtp->tx_addr_map_list,
					&mhi_xprtp->tx_addr_map_list_lock, pkt,
					skb->data + offset, dma_addr) < 0) {
			IPC_RTR_ERR("%s: Could not map SKB->DMA address\n",
					skb->data + offset) < 0) {
			IPC_RTR_ERR("%s: Could not map SKB address\n",
					__func__);
			break;
		}

		rc = mhi_queue_xfer(mhi_xprtp->ch_hndl.out_handle,
				     dma_addr, sz_to_write, MHI_EOT | MHI_EOB);
		if (rc != 0) {
				    skb->data + offset, sz_to_write,
				    MHI_EOT | MHI_EOB);
		if (rc) {
			mutex_unlock(&mhi_xprtp->ch_hndl.state_lock);
			dma_unmap_single(NULL, dma_addr, sz_to_write,
					 DMA_TO_DEVICE);
			IPC_RTR_ERR("%s: Error queueing mhi_xfer 0x%zx\n",
				    __func__, sz_to_write);
			return -EFAULT;
@@ -496,7 +468,7 @@ static int ipc_router_mhi_write(void *data,
 */
static void mhi_xprt_read_data(struct work_struct *work)
{
	dma_addr_t data_addr;
	void *data_addr;
	ssize_t data_sz;
	void *skb_data;
	struct sk_buff *skb;
@@ -520,15 +492,15 @@ static void mhi_xprt_read_data(struct work_struct *work)

	while (1) {
		rc = mhi_poll_inbound(mhi_xprtp->ch_hndl.in_handle, &result);
		if (rc || !result.payload_buf || !result.bytes_xferd) {
			if (rc != MHI_STATUS_RING_EMPTY)
		if (rc || !result.buf_addr || !result.bytes_xferd) {
			if (rc != -ENODATA)
				IPC_RTR_ERR("%s: Poll failed %s:%d:%p:%u\n",
					__func__, mhi_xprtp->xprt_name, rc,
					(void *)result.payload_buf,
					result.bytes_xferd);
					result.buf_addr,
					(unsigned int) result.bytes_xferd);
			break;
		}
		data_addr = result.payload_buf;
		data_addr = result.buf_addr;
		data_sz = result.bytes_xferd;

		/* Create a new rr_packet, if first fragment */
@@ -547,7 +519,6 @@ static void mhi_xprt_read_data(struct work_struct *work)
					&mhi_xprtp->rx_addr_map_list_lock,
					data_addr);

		dma_unmap_single(NULL, data_addr, data_sz, DMA_BIDIRECTIONAL);
		if (!skb_data)
			continue;
		mutex_lock(&mhi_xprtp->ch_hndl.in_skbq_lock);
@@ -638,7 +609,7 @@ static void mhi_xprt_enable_event(struct work_struct *work)

	if (xprt_work->chan_id == mhi_xprtp->ch_hndl.out_chan_id) {
		rc = mhi_open_channel(mhi_xprtp->ch_hndl.out_handle);
		if (rc != MHI_STATUS_SUCCESS) {
		if (rc) {
			IPC_RTR_ERR("%s Failed to open chan 0x%x, rc %d\n",
				__func__, mhi_xprtp->ch_hndl.out_chan_id, rc);
			goto out_enable_event;
@@ -650,7 +621,7 @@ static void mhi_xprt_enable_event(struct work_struct *work)
		mutex_unlock(&mhi_xprtp->ch_hndl.state_lock);
	} else if (xprt_work->chan_id == mhi_xprtp->ch_hndl.in_chan_id) {
		rc = mhi_open_channel(mhi_xprtp->ch_hndl.in_handle);
		if (rc != MHI_STATUS_SUCCESS) {
		if (rc) {
			IPC_RTR_ERR("%s Failed to open chan 0x%x, rc %d\n",
				__func__, mhi_xprtp->ch_hndl.in_chan_id, rc);
			goto out_enable_event;
@@ -743,17 +714,15 @@ static void mhi_xprt_disable_event(struct work_struct *work)
static void mhi_xprt_xfer_event(struct mhi_cb_info *cb_info)
{
	struct ipc_router_mhi_xprt *mhi_xprtp;
	dma_addr_t out_dma_addr;
	void *out_addr;

	mhi_xprtp = (struct ipc_router_mhi_xprt *)(cb_info->result->user_data);
	if (cb_info->chan == mhi_xprtp->ch_hndl.out_chan_id) {
		out_dma_addr = (dma_addr_t)cb_info->result->payload_buf;
		dma_unmap_single(NULL, out_dma_addr,
				cb_info->result->bytes_xferd, DMA_TO_DEVICE);
		out_addr = cb_info->result->buf_addr;
		mutex_lock(&mhi_xprtp->ch_hndl.state_lock);
		ipc_router_mhi_xprt_find_addr_map(&mhi_xprtp->tx_addr_map_list,
					&mhi_xprtp->tx_addr_map_list_lock,
					out_dma_addr);
					out_addr);
		wake_up(&mhi_xprtp->write_wait_q);
		mutex_unlock(&mhi_xprtp->ch_hndl.state_lock);
	} else if (cb_info->chan == mhi_xprtp->ch_hndl.in_chan_id) {
@@ -821,13 +790,13 @@ static void ipc_router_mhi_xprt_cb(struct mhi_cb_info *cb_info)
static int ipc_router_mhi_driver_register(
		struct ipc_router_mhi_xprt *mhi_xprtp)
{
	enum MHI_STATUS rc_status;
	int rc_status;

	rc_status = mhi_register_channel(&mhi_xprtp->ch_hndl.out_handle,
				mhi_xprtp->ch_hndl.out_chan_id, 0,
				&mhi_xprtp->ch_hndl.out_clnt_info,
				(void *)mhi_xprtp);
	if (rc_status != MHI_STATUS_SUCCESS) {
	if (rc_status) {
		IPC_RTR_ERR("%s: Error %d registering out_chan for %s\n",
			    __func__, rc_status, mhi_xprtp->xprt_name);
		return -EFAULT;
@@ -837,7 +806,7 @@ static int ipc_router_mhi_driver_register(
				mhi_xprtp->ch_hndl.in_chan_id, 0,
				&mhi_xprtp->ch_hndl.in_clnt_info,
				(void *)mhi_xprtp);
	if (rc_status != MHI_STATUS_SUCCESS) {
	if (rc_status) {
		mhi_deregister_channel(mhi_xprtp->ch_hndl.out_handle);
		IPC_RTR_ERR("%s: Error %d registering in_chan for %s\n",
			    __func__, rc_status, mhi_xprtp->xprt_name);