diff --git a/drivers/soc/qcom/ipc_router_mhi_xprt.c b/drivers/soc/qcom/ipc_router_mhi_xprt.c index faf01c8aa013..9a0624804c21 100644 --- a/drivers/soc/qcom/ipc_router_mhi_xprt.c +++ b/drivers/soc/qcom/ipc_router_mhi_xprt.c @@ -1,4 +1,4 @@ -/* 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);