From 3451ee0a5838c77dc7d013348cfec391edd739bd Mon Sep 17 00:00:00 2001 From: Amandeep Singh Date: Tue, 4 Jun 2019 11:35:03 +0530 Subject: [PATCH 1/2] soc: qcom: Add ipc router plugin for sdio transport This snapshot is taken as of msm-4.4 commit dc86ce0faae2 ("soc: qcom: ipc_rtr_xprt: Add support to set version in transport"). Change-Id: I729d3c910372d2c3c0bbaaae74a42150c9929732 Signed-off-by: Amandeep Singh --- drivers/soc/qcom/ipc_router_sdio_xprt.c | 783 ++++++++++++++++++++++++ 1 file changed, 783 insertions(+) create mode 100644 drivers/soc/qcom/ipc_router_sdio_xprt.c diff --git a/drivers/soc/qcom/ipc_router_sdio_xprt.c b/drivers/soc/qcom/ipc_router_sdio_xprt.c new file mode 100644 index 000000000000..a9ad2a140a5a --- /dev/null +++ b/drivers/soc/qcom/ipc_router_sdio_xprt.c @@ -0,0 +1,783 @@ +/* Copyright (c) 2019 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * IPC ROUTER HSIC XPRT module. + */ +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static int msm_ipc_router_hsic_xprt_debug_mask; +module_param_named(debug_mask, msm_ipc_router_hsic_xprt_debug_mask, + int, S_IRUGO | S_IWUSR | S_IWGRP); + +#if defined(DEBUG) +#define D(x...) do { \ +if (msm_ipc_router_hsic_xprt_debug_mask) \ + pr_info(x); \ +} while (0) +#else +#define D(x...) do { } while (0) +#endif + +#define NUM_HSIC_XPRTS 1 +#define XPRT_NAME_LEN 32 + +/** + * msm_ipc_router_hsic_xprt - IPC Router's HSIC XPRT structure + * @list: IPC router's HSIC XPRTs list. + * @ch_name: Name of the HSIC endpoint exported by ipc_bridge driver. + * @xprt_name: Name of the XPRT to be registered with IPC Router. + * @driver: Platform drivers register by this XPRT. + * @xprt: IPC Router XPRT structure to contain HSIC XPRT specific info. + * @pdev: Platform device registered by IPC Bridge function driver. + * @hsic_xprt_wq: Workqueue to queue read & other XPRT related works. + * @read_work: Read Work to perform read operation from HSIC's ipc_bridge. + * @in_pkt: Pointer to any partially read packet. + * @ss_reset_lock: Lock to protect access to the ss_reset flag. + * @ss_reset: flag used to check SSR state. + * @sft_close_complete: Variable to indicate completion of SSR handling + * by IPC Router. + * @xprt_version: IPC Router header version supported by this XPRT. + * @xprt_option: XPRT specific options to be handled by IPC Router. + */ +struct msm_ipc_router_hsic_xprt { + struct list_head list; + char ch_name[XPRT_NAME_LEN]; + char xprt_name[XPRT_NAME_LEN]; + struct platform_driver driver; + struct msm_ipc_router_xprt xprt; + struct platform_device *pdev; + struct workqueue_struct *hsic_xprt_wq; + struct delayed_work read_work; + struct rr_packet *in_pkt; + struct mutex ss_reset_lock; + int ss_reset; + struct completion sft_close_complete; + unsigned xprt_version; + unsigned xprt_option; +}; + +struct msm_ipc_router_hsic_xprt_work { + struct msm_ipc_router_xprt *xprt; + struct work_struct work; +}; + +static void hsic_xprt_read_data(struct work_struct *work); + +/** + * msm_ipc_router_hsic_xprt_config - Config. Info. of each HSIC XPRT + * @ch_name: Name of the HSIC endpoint exported by ipc_bridge driver. + * @xprt_name: Name of the XPRT to be registered with IPC Router. + * @hsic_pdev_id: ID to differentiate among multiple ipc_bridge endpoints. + * @link_id: Network Cluster ID to which this XPRT belongs to. + * @xprt_version: IPC Router header version supported by this XPRT. + */ +struct msm_ipc_router_hsic_xprt_config { + char ch_name[XPRT_NAME_LEN]; + char xprt_name[XPRT_NAME_LEN]; + int hsic_pdev_id; + uint32_t link_id; + unsigned xprt_version; +}; + +struct msm_ipc_router_hsic_xprt_config hsic_xprt_cfg[] = { + {"ipc_bridge", "ipc_rtr_ipc_bridge1", 1, 1, 3}, +}; + +#define MODULE_NAME "ipc_router_hsic_xprt" +#define IPC_ROUTER_HSIC_XPRT_WAIT_TIMEOUT 3000 +static int ipc_router_hsic_xprt_probe_done; +static struct delayed_work ipc_router_hsic_xprt_probe_work; +static DEFINE_MUTEX(hsic_remote_xprt_list_lock_lha1); +static LIST_HEAD(hsic_remote_xprt_list); + +/** + * find_hsic_xprt_list() - Find xprt item specific to an HSIC endpoint + * @name: Name of the platform device to find in list + * + * @return: pointer to msm_ipc_router_hsic_xprt if matching endpoint is found, + * else NULL. + * + * This function is used to find specific xprt item from the global xprt list + */ +static struct msm_ipc_router_hsic_xprt * + find_hsic_xprt_list(const char *name) +{ + struct msm_ipc_router_hsic_xprt *hsic_xprtp; + + mutex_lock(&hsic_remote_xprt_list_lock_lha1); + list_for_each_entry(hsic_xprtp, &hsic_remote_xprt_list, list) { + if (!strcmp(name, hsic_xprtp->ch_name)) { + mutex_unlock(&hsic_remote_xprt_list_lock_lha1); + return hsic_xprtp; + } + } + mutex_unlock(&hsic_remote_xprt_list_lock_lha1); + return NULL; +} + +/** + * ipc_router_hsic_set_xprt_version() - Set IPC Router header version + * in the transport + * @xprt: Reference to the transport structure. + * @version: The version to be set in transport. + */ +static void ipc_router_hsic_set_xprt_version( + struct msm_ipc_router_xprt *xprt, unsigned version) +{ + struct msm_ipc_router_hsic_xprt *hsic_xprtp; + + if (!xprt) + return; + hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + hsic_xprtp->xprt_version = version; +} + +/** + * msm_ipc_router_hsic_get_xprt_version() - Get IPC Router header version + * supported by the XPRT + * @xprt: XPRT for which the version information is required. + * + * @return: IPC Router header version supported by the XPRT. + */ +static int msm_ipc_router_hsic_get_xprt_version( + struct msm_ipc_router_xprt *xprt) +{ + struct msm_ipc_router_hsic_xprt *hsic_xprtp; + + if (!xprt) + return -EINVAL; + hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + + return (int)hsic_xprtp->xprt_version; +} + +/** + * msm_ipc_router_hsic_get_xprt_option() - Get XPRT options + * @xprt: XPRT for which the option information is required. + * + * @return: Options supported by the XPRT. + */ +static int msm_ipc_router_hsic_get_xprt_option( + struct msm_ipc_router_xprt *xprt) +{ + struct msm_ipc_router_hsic_xprt *hsic_xprtp; + + if (!xprt) + return -EINVAL; + hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + + return (int)hsic_xprtp->xprt_option; +} + +/** + * msm_ipc_router_hsic_remote_write_avail() - Get available write space + * @xprt: XPRT for which the available write space info. is required. + * + * @return: Write space in bytes on success, 0 on SSR. + */ +static int msm_ipc_router_hsic_remote_write_avail( + struct msm_ipc_router_xprt *xprt) +{ + struct ipc_bridge_platform_data *pdata; + int write_avail; + struct msm_ipc_router_hsic_xprt *hsic_xprtp = + container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + + mutex_lock(&hsic_xprtp->ss_reset_lock); + if (hsic_xprtp->ss_reset || !hsic_xprtp->pdev) { + write_avail = 0; + } else { + pdata = hsic_xprtp->pdev->dev.platform_data; + write_avail = pdata->max_write_size; + } + mutex_unlock(&hsic_xprtp->ss_reset_lock); + return write_avail; +} + +/** + * msm_ipc_router_hsic_remote_write() - Write to XPRT + * @data: Data to be written to the XPRT. + * @len: Length of the data to be written. + * @xprt: XPRT to which the data has to be written. + * + * @return: Data Length on success, standard Linux error codes on failure. + */ +static int msm_ipc_router_hsic_remote_write(void *data, + uint32_t len, struct msm_ipc_router_xprt *xprt) +{ + struct rr_packet *pkt = (struct rr_packet *)data; + struct sk_buff *skb; + struct ipc_bridge_platform_data *pdata; + struct msm_ipc_router_hsic_xprt *hsic_xprtp; + int ret; + uint32_t bytes_written = 0; + uint32_t bytes_to_write; + unsigned char *tx_data; + + if (!pkt || pkt->length != len || !xprt) { + IPC_RTR_ERR("%s: Invalid input parameters\n", __func__); + return -EINVAL; + } + + hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + mutex_lock(&hsic_xprtp->ss_reset_lock); + if (hsic_xprtp->ss_reset) { + IPC_RTR_ERR("%s: Trying to write on a reset link\n", __func__); + mutex_unlock(&hsic_xprtp->ss_reset_lock); + return -ENETRESET; + } + + if (!hsic_xprtp->pdev) { + IPC_RTR_ERR("%s: Trying to write on a closed link\n", __func__); + mutex_unlock(&hsic_xprtp->ss_reset_lock); + return -ENODEV; + } + + pdata = hsic_xprtp->pdev->dev.platform_data; + if (!pdata || !pdata->write) { + IPC_RTR_ERR("%s on a uninitialized link\n", __func__); + mutex_unlock(&hsic_xprtp->ss_reset_lock); + return -EFAULT; + } + + skb = skb_peek(pkt->pkt_fragment_q); + if (!skb) { + IPC_RTR_ERR("%s SKB is NULL\n", __func__); + mutex_unlock(&hsic_xprtp->ss_reset_lock); + return -EINVAL; + } + D("%s: About to write %d bytes\n", __func__, len); + + while (bytes_written < len) { + bytes_to_write = min_t(uint32_t, (skb->len - bytes_written), + pdata->max_write_size); + tx_data = skb->data + bytes_written; + ret = pdata->write(hsic_xprtp->pdev, tx_data, bytes_to_write); + if (ret < 0) { + IPC_RTR_ERR("%s: Error writing data %d\n", + __func__, ret); + break; + } + if (ret != bytes_to_write) + IPC_RTR_ERR("%s: Partial write %d < %d, retrying...\n", + __func__, ret, bytes_to_write); + bytes_written += bytes_to_write; + } + if (bytes_written == len) { + ret = bytes_written; + } else if (ret > 0 && bytes_written != len) { + IPC_RTR_ERR("%s: Fault writing data %d != %d\n", + __func__, bytes_written, len); + ret = -EFAULT; + } + D("%s: Finished writing %d bytes\n", __func__, len); + mutex_unlock(&hsic_xprtp->ss_reset_lock); + return ret; +} + +/** + * msm_ipc_router_hsic_remote_close() - Close the XPRT + * @xprt: XPRT which needs to be closed. + * + * @return: 0 on success, standard Linux error codes on failure. + */ +static int msm_ipc_router_hsic_remote_close( + struct msm_ipc_router_xprt *xprt) +{ + struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct ipc_bridge_platform_data *pdata; + + if (!xprt) + return -EINVAL; + hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + + mutex_lock(&hsic_xprtp->ss_reset_lock); + hsic_xprtp->ss_reset = 1; + mutex_unlock(&hsic_xprtp->ss_reset_lock); + flush_workqueue(hsic_xprtp->hsic_xprt_wq); + destroy_workqueue(hsic_xprtp->hsic_xprt_wq); + pdata = hsic_xprtp->pdev->dev.platform_data; + if (pdata && pdata->close) + pdata->close(hsic_xprtp->pdev); + hsic_xprtp->pdev = NULL; + return 0; +} + +/** + * hsic_xprt_read_data() - Read work to read from the XPRT + * @work: Read work to be executed. + * + * This function is a read work item queued on a XPRT specific workqueue. + * The work parameter contains information regarding the XPRT on which this + * read work has to be performed. The work item keeps reading from the HSIC + * endpoint, until the endpoint returns an error. + */ +static void hsic_xprt_read_data(struct work_struct *work) +{ + int bytes_to_read; + int bytes_read; + int skb_size; + struct sk_buff *skb = NULL; + struct ipc_bridge_platform_data *pdata; + struct delayed_work *rwork = to_delayed_work(work); + struct msm_ipc_router_hsic_xprt *hsic_xprtp = + container_of(rwork, struct msm_ipc_router_hsic_xprt, read_work); + + while (1) { + mutex_lock(&hsic_xprtp->ss_reset_lock); + if (hsic_xprtp->ss_reset) { + mutex_unlock(&hsic_xprtp->ss_reset_lock); + break; + } + pdata = hsic_xprtp->pdev->dev.platform_data; + mutex_unlock(&hsic_xprtp->ss_reset_lock); + while (!hsic_xprtp->in_pkt) { + hsic_xprtp->in_pkt = create_pkt(NULL); + if (hsic_xprtp->in_pkt) + break; + IPC_RTR_ERR("%s: packet allocation failure\n", + __func__); + msleep(100); + } + D("%s: Allocated rr_packet\n", __func__); + + bytes_to_read = 0; + skb_size = pdata->max_read_size; + do { + do { + skb = alloc_skb(skb_size, GFP_KERNEL); + if (skb) + break; + IPC_RTR_ERR("%s: Couldn't alloc SKB\n", + __func__); + msleep(100); + } while (!skb); + bytes_read = pdata->read(hsic_xprtp->pdev, skb->data, + pdata->max_read_size); + if (bytes_read < 0) { + IPC_RTR_ERR("%s: Error %d @ read operation\n", + __func__, bytes_read); + kfree_skb(skb); + goto out_read_data; + } + if (!bytes_to_read) { + bytes_to_read = ipc_router_peek_pkt_size( + skb->data); + if (bytes_to_read < 0) { + IPC_RTR_ERR("%s: Invalid size %d\n", + __func__, bytes_to_read); + kfree_skb(skb); + goto out_read_data; + } + } + bytes_to_read -= bytes_read; + skb_put(skb, bytes_read); + skb_queue_tail(hsic_xprtp->in_pkt->pkt_fragment_q, skb); + hsic_xprtp->in_pkt->length += bytes_read; + skb_size = min_t(uint32_t, pdata->max_read_size, + (uint32_t)bytes_to_read); + } while (bytes_to_read > 0); + + D("%s: Packet size read %d\n", + __func__, hsic_xprtp->in_pkt->length); + msm_ipc_router_xprt_notify(&hsic_xprtp->xprt, + IPC_ROUTER_XPRT_EVENT_DATA, (void *)hsic_xprtp->in_pkt); + release_pkt(hsic_xprtp->in_pkt); + hsic_xprtp->in_pkt = NULL; + } +out_read_data: + release_pkt(hsic_xprtp->in_pkt); + hsic_xprtp->in_pkt = NULL; +} + +/** + * hsic_xprt_sft_close_done() - Completion of XPRT reset + * @xprt: XPRT on which the reset operation is complete. + * + * This function is used by IPC Router to signal this HSIC XPRT Abstraction + * Layer(XAL) that the reset of XPRT is completely handled by IPC Router. + */ +static void hsic_xprt_sft_close_done(struct msm_ipc_router_xprt *xprt) +{ + struct msm_ipc_router_hsic_xprt *hsic_xprtp = + container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + + complete_all(&hsic_xprtp->sft_close_complete); +} + +/** + * msm_ipc_router_hsic_remote_remove() - Remove an HSIC endpoint + * @pdev: Platform device corresponding to HSIC endpoint. + * + * @return: 0 on success, standard Linux error codes on error. + * + * This function is called when the underlying ipc_bridge driver unregisters + * a platform device, mapped to an HSIC endpoint, during SSR. + */ +static int msm_ipc_router_hsic_remote_remove(struct platform_device *pdev) +{ + struct ipc_bridge_platform_data *pdata; + struct msm_ipc_router_hsic_xprt *hsic_xprtp; + + hsic_xprtp = find_hsic_xprt_list(pdev->name); + if (!hsic_xprtp) { + IPC_RTR_ERR("%s No device with name %s\n", + __func__, pdev->name); + return -ENODEV; + } + + mutex_lock(&hsic_xprtp->ss_reset_lock); + hsic_xprtp->ss_reset = 1; + mutex_unlock(&hsic_xprtp->ss_reset_lock); + flush_workqueue(hsic_xprtp->hsic_xprt_wq); + destroy_workqueue(hsic_xprtp->hsic_xprt_wq); + init_completion(&hsic_xprtp->sft_close_complete); + msm_ipc_router_xprt_notify(&hsic_xprtp->xprt, + IPC_ROUTER_XPRT_EVENT_CLOSE, NULL); + D("%s: Notified IPC Router of %s CLOSE\n", + __func__, hsic_xprtp->xprt.name); + wait_for_completion(&hsic_xprtp->sft_close_complete); + hsic_xprtp->pdev = NULL; + pdata = pdev->dev.platform_data; + if (pdata && pdata->close) + pdata->close(pdev); + return 0; +} + +/** + * msm_ipc_router_hsic_remote_probe() - Probe an HSIC endpoint + * @pdev: Platform device corresponding to HSIC endpoint. + * + * @return: 0 on success, standard Linux error codes on error. + * + * This function is called when the underlying ipc_bridge driver registers + * a platform device, mapped to an HSIC endpoint. + */ +static int msm_ipc_router_hsic_remote_probe(struct platform_device *pdev) +{ + int rc; + struct ipc_bridge_platform_data *pdata; + struct msm_ipc_router_hsic_xprt *hsic_xprtp; + + pdata = pdev->dev.platform_data; + if (!pdata || !pdata->open || !pdata->read || + !pdata->write || !pdata->close) { + IPC_RTR_ERR("%s: pdata or pdata->operations is NULL\n", + __func__); + return -EINVAL; + } + + hsic_xprtp = find_hsic_xprt_list(pdev->name); + if (!hsic_xprtp) { + IPC_RTR_ERR("%s No device with name %s\n", + __func__, pdev->name); + return -ENODEV; + } + + hsic_xprtp->hsic_xprt_wq = + create_singlethread_workqueue(pdev->name); + if (!hsic_xprtp->hsic_xprt_wq) { + IPC_RTR_ERR("%s: WQ creation failed for %s\n", + __func__, pdev->name); + return -EFAULT; + } + + rc = pdata->open(pdev); + if (rc < 0) { + IPC_RTR_ERR("%s: Channel open failed for %s.%d\n", + __func__, pdev->name, pdev->id); + destroy_workqueue(hsic_xprtp->hsic_xprt_wq); + return rc; + } + hsic_xprtp->pdev = pdev; + mutex_lock(&hsic_xprtp->ss_reset_lock); + hsic_xprtp->ss_reset = 0; + mutex_unlock(&hsic_xprtp->ss_reset_lock); + msm_ipc_router_xprt_notify(&hsic_xprtp->xprt, + IPC_ROUTER_XPRT_EVENT_OPEN, NULL); + D("%s: Notified IPC Router of %s OPEN\n", + __func__, hsic_xprtp->xprt.name); + queue_delayed_work(hsic_xprtp->hsic_xprt_wq, + &hsic_xprtp->read_work, 0); + return 0; +} + +/** + * msm_ipc_router_hsic_driver_register() - register HSIC XPRT drivers + * + * @hsic_xprtp: pointer to IPC router hsic xprt structure. + * + * @return: 0 on success, standard Linux error codes on error. + * + * This function is called when a new XPRT is added to register platform + * drivers for new XPRT. + */ +static int msm_ipc_router_hsic_driver_register( + struct msm_ipc_router_hsic_xprt *hsic_xprtp) +{ + int ret; + struct msm_ipc_router_hsic_xprt *hsic_xprtp_item; + + hsic_xprtp_item = find_hsic_xprt_list(hsic_xprtp->ch_name); + + mutex_lock(&hsic_remote_xprt_list_lock_lha1); + list_add(&hsic_xprtp->list, &hsic_remote_xprt_list); + mutex_unlock(&hsic_remote_xprt_list_lock_lha1); + + if (!hsic_xprtp_item) { + hsic_xprtp->driver.driver.name = hsic_xprtp->ch_name; + hsic_xprtp->driver.driver.owner = THIS_MODULE; + hsic_xprtp->driver.probe = msm_ipc_router_hsic_remote_probe; + hsic_xprtp->driver.remove = msm_ipc_router_hsic_remote_remove; + + ret = platform_driver_register(&hsic_xprtp->driver); + if (ret) { + IPC_RTR_ERR( + "%s: Failed to register platform driver[%s]\n", + __func__, hsic_xprtp->ch_name); + return ret; + } + } else { + IPC_RTR_ERR("%s Already driver registered %s\n", + __func__, hsic_xprtp->ch_name); + } + + return 0; +} + +/** + * msm_ipc_router_hsic_config_init() - init HSIC xprt configs + * + * @hsic_xprt_config: pointer to HSIC xprt configurations. + * + * @return: 0 on success, standard Linux error codes on error. + * + * This function is called to initialize the HSIC XPRT pointer with + * the HSIC XPRT configurations either from device tree or static arrays. + */ +static int msm_ipc_router_hsic_config_init( + struct msm_ipc_router_hsic_xprt_config *hsic_xprt_config) +{ + struct msm_ipc_router_hsic_xprt *hsic_xprtp; + + hsic_xprtp = kzalloc(sizeof(struct msm_ipc_router_hsic_xprt), + GFP_KERNEL); + if (IS_ERR_OR_NULL(hsic_xprtp)) { + IPC_RTR_ERR("%s: kzalloc() failed for hsic_xprtp id:%s\n", + __func__, hsic_xprt_config->ch_name); + return -ENOMEM; + } + + hsic_xprtp->xprt.link_id = hsic_xprt_config->link_id; + hsic_xprtp->xprt_version = hsic_xprt_config->xprt_version; + + strlcpy(hsic_xprtp->ch_name, hsic_xprt_config->ch_name, + XPRT_NAME_LEN); + + strlcpy(hsic_xprtp->xprt_name, hsic_xprt_config->xprt_name, + XPRT_NAME_LEN); + hsic_xprtp->xprt.name = hsic_xprtp->xprt_name; + + hsic_xprtp->xprt.set_version = + ipc_router_hsic_set_xprt_version; + hsic_xprtp->xprt.get_version = + msm_ipc_router_hsic_get_xprt_version; + hsic_xprtp->xprt.get_option = + msm_ipc_router_hsic_get_xprt_option; + hsic_xprtp->xprt.read_avail = NULL; + hsic_xprtp->xprt.read = NULL; + hsic_xprtp->xprt.write_avail = + msm_ipc_router_hsic_remote_write_avail; + hsic_xprtp->xprt.write = msm_ipc_router_hsic_remote_write; + hsic_xprtp->xprt.close = msm_ipc_router_hsic_remote_close; + hsic_xprtp->xprt.sft_close_done = hsic_xprt_sft_close_done; + hsic_xprtp->xprt.priv = NULL; + + hsic_xprtp->in_pkt = NULL; + INIT_DELAYED_WORK(&hsic_xprtp->read_work, hsic_xprt_read_data); + mutex_init(&hsic_xprtp->ss_reset_lock); + hsic_xprtp->ss_reset = 0; + hsic_xprtp->xprt_option = 0; + + msm_ipc_router_hsic_driver_register(hsic_xprtp); + return 0; + +} + +/** + * parse_devicetree() - parse device tree binding + * + * @node: pointer to device tree node + * @hsic_xprt_config: pointer to HSIC XPRT configurations + * + * @return: 0 on success, -ENODEV on failure. + */ +static int parse_devicetree(struct device_node *node, + struct msm_ipc_router_hsic_xprt_config *hsic_xprt_config) +{ + int ret; + int link_id; + int version; + char *key; + const char *ch_name; + const char *remote_ss; + + key = "qcom,ch-name"; + ch_name = of_get_property(node, key, NULL); + if (!ch_name) + goto error; + strlcpy(hsic_xprt_config->ch_name, ch_name, XPRT_NAME_LEN); + + key = "qcom,xprt-remote"; + remote_ss = of_get_property(node, key, NULL); + if (!remote_ss) + goto error; + + key = "qcom,xprt-linkid"; + ret = of_property_read_u32(node, key, &link_id); + if (ret) + goto error; + hsic_xprt_config->link_id = link_id; + + key = "qcom,xprt-version"; + ret = of_property_read_u32(node, key, &version); + if (ret) + goto error; + hsic_xprt_config->xprt_version = version; + + scnprintf(hsic_xprt_config->xprt_name, XPRT_NAME_LEN, "%s_%s", + remote_ss, hsic_xprt_config->ch_name); + + return 0; + +error: + IPC_RTR_ERR("%s: missing key: %s\n", __func__, key); + return -ENODEV; +} + +/** + * msm_ipc_router_hsic_xprt_probe() - Probe an HSIC xprt + * @pdev: Platform device corresponding to HSIC xprt. + * + * @return: 0 on success, standard Linux error codes on error. + * + * This function is called when the underlying device tree driver registers + * a platform device, mapped to an HSIC transport. + */ +static int msm_ipc_router_hsic_xprt_probe( + struct platform_device *pdev) +{ + int ret; + struct msm_ipc_router_hsic_xprt_config hsic_xprt_config; + + if (pdev && pdev->dev.of_node) { + mutex_lock(&hsic_remote_xprt_list_lock_lha1); + ipc_router_hsic_xprt_probe_done = 1; + mutex_unlock(&hsic_remote_xprt_list_lock_lha1); + + ret = parse_devicetree(pdev->dev.of_node, + &hsic_xprt_config); + if (ret) { + IPC_RTR_ERR("%s: Failed to parse device tree\n", + __func__); + return ret; + } + + ret = msm_ipc_router_hsic_config_init( + &hsic_xprt_config); + if (ret) { + IPC_RTR_ERR(" %s init failed\n", __func__); + return ret; + } + } + return ret; +} + +/** + * ipc_router_hsic_xprt_probe_worker() - probe worker for non DT configurations + * + * @work: work item to process + * + * This function is called by schedule_delay_work after 3sec and check if + * device tree probe is done or not. If device tree probe fails the default + * configurations read from static array. + */ +static void ipc_router_hsic_xprt_probe_worker(struct work_struct *work) +{ + int i, ret; + + BUG_ON(ARRAY_SIZE(hsic_xprt_cfg) != NUM_HSIC_XPRTS); + + mutex_lock(&hsic_remote_xprt_list_lock_lha1); + if (!ipc_router_hsic_xprt_probe_done) { + mutex_unlock(&hsic_remote_xprt_list_lock_lha1); + for (i = 0; i < ARRAY_SIZE(hsic_xprt_cfg); i++) { + ret = msm_ipc_router_hsic_config_init( + &hsic_xprt_cfg[i]); + if (ret) + IPC_RTR_ERR(" %s init failed config idx %d\n", + __func__, i); + } + mutex_lock(&hsic_remote_xprt_list_lock_lha1); + } + mutex_unlock(&hsic_remote_xprt_list_lock_lha1); +} + +static const struct of_device_id msm_ipc_router_hsic_xprt_match_table[] = { + { .compatible = "qcom,ipc_router_hsic_xprt" }, + {}, +}; + +static struct platform_driver msm_ipc_router_hsic_xprt_driver = { + .probe = msm_ipc_router_hsic_xprt_probe, + .driver = { + .name = MODULE_NAME, + .owner = THIS_MODULE, + .of_match_table = msm_ipc_router_hsic_xprt_match_table, + }, +}; + +static int __init msm_ipc_router_hsic_xprt_init(void) +{ + int rc; + + rc = platform_driver_register(&msm_ipc_router_hsic_xprt_driver); + if (rc) { + IPC_RTR_ERR( + "%s: msm_ipc_router_hsic_xprt_driver register failed %d\n", + __func__, rc); + return rc; + } + + INIT_DELAYED_WORK(&ipc_router_hsic_xprt_probe_work, + ipc_router_hsic_xprt_probe_worker); + schedule_delayed_work(&ipc_router_hsic_xprt_probe_work, + msecs_to_jiffies(IPC_ROUTER_HSIC_XPRT_WAIT_TIMEOUT)); + return 0; +} + +module_init(msm_ipc_router_hsic_xprt_init); +MODULE_DESCRIPTION("IPC Router HSIC XPRT"); +MODULE_LICENSE("GPL v2"); From c83973e117d29dbf3ab48d9ece77be30aed5f8fa Mon Sep 17 00:00:00 2001 From: Amandeep Singh Date: Wed, 3 Jul 2019 11:47:52 +0530 Subject: [PATCH 2/2] soc: qcom: Update ipc router sdio transport plugin Update ipc router sdio plugin initial snapshot to support peripheral device over sdio transport. Change-Id: I097ad755b3bd2270cda74738bed409e88dee343c Signed-off-by: Amandeep Singh --- .../arm/msm/msm_ipc_router_sdio_xprt.txt | 19 + drivers/soc/qcom/ipc_router_sdio_xprt.c | 523 +++++++++--------- 2 files changed, 284 insertions(+), 258 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/msm/msm_ipc_router_sdio_xprt.txt diff --git a/Documentation/devicetree/bindings/arm/msm/msm_ipc_router_sdio_xprt.txt b/Documentation/devicetree/bindings/arm/msm/msm_ipc_router_sdio_xprt.txt new file mode 100644 index 000000000000..97827fd9dde2 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/msm_ipc_router_sdio_xprt.txt @@ -0,0 +1,19 @@ +IPC Router SDIO Transport + +Required properties: +-compatible: should be "qcom,ipc_router_sdio_xprt" +-qcom,ch-name: the SDIO channel name used by the SDIO transport +-qcom,xprt-remote: string that defines the edge of the transport (PIL Name) +-qcom,xprt-linkid: unique integer to identify the tier to which the link + belongs to in the network and is used to avoid the + routing loops while forwarding the broadcast messages +-qcom,xprt-version: unique version ID used by SDIO transport header + +Example: + qcom,ipc_router_external_modem_xprt { + compatible = "qcom,ipc_router_sdio_xprt"; + qcom,ch-name = "ipc_bridge_sdio"; + qcom,xprt-remote = "external-modem"; + qcom,xprt-linkid = <1>; + qcom,xprt-version = <3>; + }; diff --git a/drivers/soc/qcom/ipc_router_sdio_xprt.c b/drivers/soc/qcom/ipc_router_sdio_xprt.c index a9ad2a140a5a..c30e37516ec2 100644 --- a/drivers/soc/qcom/ipc_router_sdio_xprt.c +++ b/drivers/soc/qcom/ipc_router_sdio_xprt.c @@ -11,7 +11,7 @@ */ /* - * IPC ROUTER HSIC XPRT module. + * IPC ROUTER SDIO XPRT module. */ #define DEBUG @@ -25,34 +25,32 @@ #include #include -#include - -static int msm_ipc_router_hsic_xprt_debug_mask; -module_param_named(debug_mask, msm_ipc_router_hsic_xprt_debug_mask, +static int msm_ipc_router_sdio_xprt_debug_mask = 1; +module_param_named(debug_mask, msm_ipc_router_sdio_xprt_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); #if defined(DEBUG) #define D(x...) do { \ -if (msm_ipc_router_hsic_xprt_debug_mask) \ - pr_info(x); \ +if (msm_ipc_router_sdio_xprt_debug_mask) \ + pr_err(x); \ } while (0) #else #define D(x...) do { } while (0) #endif -#define NUM_HSIC_XPRTS 1 +#define NUM_SDIO_XPRTS 1 #define XPRT_NAME_LEN 32 /** - * msm_ipc_router_hsic_xprt - IPC Router's HSIC XPRT structure - * @list: IPC router's HSIC XPRTs list. - * @ch_name: Name of the HSIC endpoint exported by ipc_bridge driver. + * msm_ipc_router_sdio_xprt - IPC Router's SDIO XPRT structure + * @list: IPC router's SDIO XPRTs list. + * @ch_name: Name of the SDIO endpoint exported by ipc_bridge driver. * @xprt_name: Name of the XPRT to be registered with IPC Router. * @driver: Platform drivers register by this XPRT. - * @xprt: IPC Router XPRT structure to contain HSIC XPRT specific info. + * @xprt: IPC Router XPRT structure to contain SDIO XPRT specific info. * @pdev: Platform device registered by IPC Bridge function driver. - * @hsic_xprt_wq: Workqueue to queue read & other XPRT related works. - * @read_work: Read Work to perform read operation from HSIC's ipc_bridge. + * @sdio_xprt_wq: Workqueue to queue read & other XPRT related works. + * @read_work: Read Work to perform read operation from SDIO's ipc_bridge. * @in_pkt: Pointer to any partially read packet. * @ss_reset_lock: Lock to protect access to the ss_reset flag. * @ss_reset: flag used to check SSR state. @@ -61,14 +59,14 @@ if (msm_ipc_router_hsic_xprt_debug_mask) \ * @xprt_version: IPC Router header version supported by this XPRT. * @xprt_option: XPRT specific options to be handled by IPC Router. */ -struct msm_ipc_router_hsic_xprt { +struct msm_ipc_router_sdio_xprt { struct list_head list; char ch_name[XPRT_NAME_LEN]; char xprt_name[XPRT_NAME_LEN]; struct platform_driver driver; struct msm_ipc_router_xprt xprt; struct platform_device *pdev; - struct workqueue_struct *hsic_xprt_wq; + struct workqueue_struct *sdio_xprt_wq; struct delayed_work read_work; struct rr_packet *in_pkt; struct mutex ss_reset_lock; @@ -78,159 +76,168 @@ struct msm_ipc_router_hsic_xprt { unsigned xprt_option; }; -struct msm_ipc_router_hsic_xprt_work { +struct ipc_bridge_platform_data { + unsigned int max_read_size; + unsigned int max_write_size; + int (*open)(int id, void *ops); + int (*read)(int id, char *buf, size_t count); + int (*write)(int id, char *buf, size_t count); + int (*close)(int id); +}; + +struct msm_ipc_router_sdio_xprt_work { struct msm_ipc_router_xprt *xprt; struct work_struct work; }; -static void hsic_xprt_read_data(struct work_struct *work); +static void sdio_xprt_read_data(struct work_struct *work); /** - * msm_ipc_router_hsic_xprt_config - Config. Info. of each HSIC XPRT - * @ch_name: Name of the HSIC endpoint exported by ipc_bridge driver. + * msm_ipc_router_sdio_xprt_config - Config. Info. of each SDIO XPRT + * @ch_name: Name of the SDIO endpoint exported by ipc_bridge driver. * @xprt_name: Name of the XPRT to be registered with IPC Router. - * @hsic_pdev_id: ID to differentiate among multiple ipc_bridge endpoints. + * @sdio_pdev_id: ID to differentiate among multiple ipc_bridge endpoints. * @link_id: Network Cluster ID to which this XPRT belongs to. * @xprt_version: IPC Router header version supported by this XPRT. */ -struct msm_ipc_router_hsic_xprt_config { +struct msm_ipc_router_sdio_xprt_config { char ch_name[XPRT_NAME_LEN]; char xprt_name[XPRT_NAME_LEN]; - int hsic_pdev_id; + int sdio_pdev_id; uint32_t link_id; unsigned xprt_version; }; -struct msm_ipc_router_hsic_xprt_config hsic_xprt_cfg[] = { - {"ipc_bridge", "ipc_rtr_ipc_bridge1", 1, 1, 3}, +struct msm_ipc_router_sdio_xprt_config sdio_xprt_cfg[] = { + {"ipc_bridge_sdio", "ipc_rtr_ipc_bridge_sdio", 1, 1, 3}, }; -#define MODULE_NAME "ipc_router_hsic_xprt" -#define IPC_ROUTER_HSIC_XPRT_WAIT_TIMEOUT 3000 -static int ipc_router_hsic_xprt_probe_done; -static struct delayed_work ipc_router_hsic_xprt_probe_work; -static DEFINE_MUTEX(hsic_remote_xprt_list_lock_lha1); -static LIST_HEAD(hsic_remote_xprt_list); +#define MODULE_NAME "ipc_router_sdio_xprt" +#define IPC_ROUTER_SDIO_XPRT_WAIT_TIMEOUT 3000 +static int ipc_router_sdio_xprt_probe_done; +static struct delayed_work ipc_router_sdio_xprt_probe_work; +static DEFINE_MUTEX(sdio_remote_xprt_list_lock_lha1); +static LIST_HEAD(sdio_remote_xprt_list); /** - * find_hsic_xprt_list() - Find xprt item specific to an HSIC endpoint + * find_sdio_xprt_list() - Find xprt item specific to an SDIO endpoint * @name: Name of the platform device to find in list * - * @return: pointer to msm_ipc_router_hsic_xprt if matching endpoint is found, + * @return: pointer to msm_ipc_router_sdio_xprt if matching endpoint is found, * else NULL. * * This function is used to find specific xprt item from the global xprt list */ -static struct msm_ipc_router_hsic_xprt * - find_hsic_xprt_list(const char *name) +static struct msm_ipc_router_sdio_xprt * + find_sdio_xprt_list(const char *name) { - struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct msm_ipc_router_sdio_xprt *sdio_xprtp; - mutex_lock(&hsic_remote_xprt_list_lock_lha1); - list_for_each_entry(hsic_xprtp, &hsic_remote_xprt_list, list) { - if (!strcmp(name, hsic_xprtp->ch_name)) { - mutex_unlock(&hsic_remote_xprt_list_lock_lha1); - return hsic_xprtp; + mutex_lock(&sdio_remote_xprt_list_lock_lha1); + list_for_each_entry(sdio_xprtp, &sdio_remote_xprt_list, list) { + if (!strcmp(name, sdio_xprtp->ch_name)) { + mutex_unlock(&sdio_remote_xprt_list_lock_lha1); + return sdio_xprtp; } } - mutex_unlock(&hsic_remote_xprt_list_lock_lha1); + mutex_unlock(&sdio_remote_xprt_list_lock_lha1); return NULL; } /** - * ipc_router_hsic_set_xprt_version() - Set IPC Router header version + * ipc_router_sdio_set_xprt_version() - Set IPC Router header version * in the transport * @xprt: Reference to the transport structure. * @version: The version to be set in transport. */ -static void ipc_router_hsic_set_xprt_version( +static void ipc_router_sdio_set_xprt_version( struct msm_ipc_router_xprt *xprt, unsigned version) { - struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct msm_ipc_router_sdio_xprt *sdio_xprtp; if (!xprt) return; - hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); - hsic_xprtp->xprt_version = version; + sdio_xprtp = container_of(xprt, struct msm_ipc_router_sdio_xprt, xprt); + sdio_xprtp->xprt_version = version; } /** - * msm_ipc_router_hsic_get_xprt_version() - Get IPC Router header version + * msm_ipc_router_sdio_get_xprt_version() - Get IPC Router header version * supported by the XPRT * @xprt: XPRT for which the version information is required. * * @return: IPC Router header version supported by the XPRT. */ -static int msm_ipc_router_hsic_get_xprt_version( +static int msm_ipc_router_sdio_get_xprt_version( struct msm_ipc_router_xprt *xprt) { - struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct msm_ipc_router_sdio_xprt *sdio_xprtp; if (!xprt) return -EINVAL; - hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + sdio_xprtp = container_of(xprt, struct msm_ipc_router_sdio_xprt, xprt); - return (int)hsic_xprtp->xprt_version; + return (int)sdio_xprtp->xprt_version; } /** - * msm_ipc_router_hsic_get_xprt_option() - Get XPRT options + * msm_ipc_router_sdio_get_xprt_option() - Get XPRT options * @xprt: XPRT for which the option information is required. * * @return: Options supported by the XPRT. */ -static int msm_ipc_router_hsic_get_xprt_option( +static int msm_ipc_router_sdio_get_xprt_option( struct msm_ipc_router_xprt *xprt) { - struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct msm_ipc_router_sdio_xprt *sdio_xprtp; if (!xprt) return -EINVAL; - hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + sdio_xprtp = container_of(xprt, struct msm_ipc_router_sdio_xprt, xprt); - return (int)hsic_xprtp->xprt_option; + return (int)sdio_xprtp->xprt_option; } /** - * msm_ipc_router_hsic_remote_write_avail() - Get available write space + * msm_ipc_router_sdio_remote_write_avail() - Get available write space * @xprt: XPRT for which the available write space info. is required. * * @return: Write space in bytes on success, 0 on SSR. */ -static int msm_ipc_router_hsic_remote_write_avail( +static int msm_ipc_router_sdio_remote_write_avail( struct msm_ipc_router_xprt *xprt) { struct ipc_bridge_platform_data *pdata; int write_avail; - struct msm_ipc_router_hsic_xprt *hsic_xprtp = - container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + struct msm_ipc_router_sdio_xprt *sdio_xprtp = + container_of(xprt, struct msm_ipc_router_sdio_xprt, xprt); - mutex_lock(&hsic_xprtp->ss_reset_lock); - if (hsic_xprtp->ss_reset || !hsic_xprtp->pdev) { + mutex_lock(&sdio_xprtp->ss_reset_lock); + if (sdio_xprtp->ss_reset || !sdio_xprtp->pdev) { write_avail = 0; } else { - pdata = hsic_xprtp->pdev->dev.platform_data; + pdata = sdio_xprtp->pdev->dev.platform_data; write_avail = pdata->max_write_size; } - mutex_unlock(&hsic_xprtp->ss_reset_lock); + mutex_unlock(&sdio_xprtp->ss_reset_lock); return write_avail; } /** - * msm_ipc_router_hsic_remote_write() - Write to XPRT + * msm_ipc_router_sdio_remote_write() - Write to XPRT * @data: Data to be written to the XPRT. * @len: Length of the data to be written. * @xprt: XPRT to which the data has to be written. * * @return: Data Length on success, standard Linux error codes on failure. */ -static int msm_ipc_router_hsic_remote_write(void *data, +static int msm_ipc_router_sdio_remote_write(void *data, uint32_t len, struct msm_ipc_router_xprt *xprt) { struct rr_packet *pkt = (struct rr_packet *)data; struct sk_buff *skb; struct ipc_bridge_platform_data *pdata; - struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct msm_ipc_router_sdio_xprt *sdio_xprtp; int ret; uint32_t bytes_written = 0; uint32_t bytes_to_write; @@ -241,31 +248,32 @@ static int msm_ipc_router_hsic_remote_write(void *data, return -EINVAL; } - hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); - mutex_lock(&hsic_xprtp->ss_reset_lock); - if (hsic_xprtp->ss_reset) { + sdio_xprtp = container_of(xprt, struct msm_ipc_router_sdio_xprt, xprt); + + mutex_lock(&sdio_xprtp->ss_reset_lock); + if (sdio_xprtp->ss_reset) { IPC_RTR_ERR("%s: Trying to write on a reset link\n", __func__); - mutex_unlock(&hsic_xprtp->ss_reset_lock); + mutex_unlock(&sdio_xprtp->ss_reset_lock); return -ENETRESET; } - if (!hsic_xprtp->pdev) { + if (!sdio_xprtp->pdev) { IPC_RTR_ERR("%s: Trying to write on a closed link\n", __func__); - mutex_unlock(&hsic_xprtp->ss_reset_lock); + mutex_unlock(&sdio_xprtp->ss_reset_lock); return -ENODEV; } - pdata = hsic_xprtp->pdev->dev.platform_data; + pdata = sdio_xprtp->pdev->dev.platform_data; if (!pdata || !pdata->write) { IPC_RTR_ERR("%s on a uninitialized link\n", __func__); - mutex_unlock(&hsic_xprtp->ss_reset_lock); + mutex_unlock(&sdio_xprtp->ss_reset_lock); return -EFAULT; } skb = skb_peek(pkt->pkt_fragment_q); if (!skb) { IPC_RTR_ERR("%s SKB is NULL\n", __func__); - mutex_unlock(&hsic_xprtp->ss_reset_lock); + mutex_unlock(&sdio_xprtp->ss_reset_lock); return -EINVAL; } D("%s: About to write %d bytes\n", __func__, len); @@ -274,7 +282,8 @@ static int msm_ipc_router_hsic_remote_write(void *data, bytes_to_write = min_t(uint32_t, (skb->len - bytes_written), pdata->max_write_size); tx_data = skb->data + bytes_written; - ret = pdata->write(hsic_xprtp->pdev, tx_data, bytes_to_write); + ret = pdata->write(sdio_xprtp->pdev->id, tx_data, + bytes_to_write); if (ret < 0) { IPC_RTR_ERR("%s: Error writing data %d\n", __func__, ret); @@ -293,48 +302,48 @@ static int msm_ipc_router_hsic_remote_write(void *data, ret = -EFAULT; } D("%s: Finished writing %d bytes\n", __func__, len); - mutex_unlock(&hsic_xprtp->ss_reset_lock); + mutex_unlock(&sdio_xprtp->ss_reset_lock); return ret; } /** - * msm_ipc_router_hsic_remote_close() - Close the XPRT + * msm_ipc_router_sdio_remote_close() - Close the XPRT * @xprt: XPRT which needs to be closed. * * @return: 0 on success, standard Linux error codes on failure. */ -static int msm_ipc_router_hsic_remote_close( +static int msm_ipc_router_sdio_remote_close( struct msm_ipc_router_xprt *xprt) { - struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct msm_ipc_router_sdio_xprt *sdio_xprtp; struct ipc_bridge_platform_data *pdata; if (!xprt) return -EINVAL; - hsic_xprtp = container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + sdio_xprtp = container_of(xprt, struct msm_ipc_router_sdio_xprt, xprt); - mutex_lock(&hsic_xprtp->ss_reset_lock); - hsic_xprtp->ss_reset = 1; - mutex_unlock(&hsic_xprtp->ss_reset_lock); - flush_workqueue(hsic_xprtp->hsic_xprt_wq); - destroy_workqueue(hsic_xprtp->hsic_xprt_wq); - pdata = hsic_xprtp->pdev->dev.platform_data; + mutex_lock(&sdio_xprtp->ss_reset_lock); + sdio_xprtp->ss_reset = 1; + mutex_unlock(&sdio_xprtp->ss_reset_lock); + flush_workqueue(sdio_xprtp->sdio_xprt_wq); + destroy_workqueue(sdio_xprtp->sdio_xprt_wq); + pdata = sdio_xprtp->pdev->dev.platform_data; if (pdata && pdata->close) - pdata->close(hsic_xprtp->pdev); - hsic_xprtp->pdev = NULL; + pdata->close(sdio_xprtp->pdev->id); + sdio_xprtp->pdev = NULL; return 0; } /** - * hsic_xprt_read_data() - Read work to read from the XPRT + * sdio_xprt_read_data() - Read work to read from the XPRT * @work: Read work to be executed. * * This function is a read work item queued on a XPRT specific workqueue. * The work parameter contains information regarding the XPRT on which this - * read work has to be performed. The work item keeps reading from the HSIC + * read work has to be performed. The work item keeps reading from the SDIO * endpoint, until the endpoint returns an error. */ -static void hsic_xprt_read_data(struct work_struct *work) +static void sdio_xprt_read_data(struct work_struct *work) { int bytes_to_read; int bytes_read; @@ -342,20 +351,20 @@ static void hsic_xprt_read_data(struct work_struct *work) struct sk_buff *skb = NULL; struct ipc_bridge_platform_data *pdata; struct delayed_work *rwork = to_delayed_work(work); - struct msm_ipc_router_hsic_xprt *hsic_xprtp = - container_of(rwork, struct msm_ipc_router_hsic_xprt, read_work); + struct msm_ipc_router_sdio_xprt *sdio_xprtp = + container_of(rwork, struct msm_ipc_router_sdio_xprt, read_work); while (1) { - mutex_lock(&hsic_xprtp->ss_reset_lock); - if (hsic_xprtp->ss_reset) { - mutex_unlock(&hsic_xprtp->ss_reset_lock); + mutex_lock(&sdio_xprtp->ss_reset_lock); + if (sdio_xprtp->ss_reset) { + mutex_unlock(&sdio_xprtp->ss_reset_lock); break; } - pdata = hsic_xprtp->pdev->dev.platform_data; - mutex_unlock(&hsic_xprtp->ss_reset_lock); - while (!hsic_xprtp->in_pkt) { - hsic_xprtp->in_pkt = create_pkt(NULL); - if (hsic_xprtp->in_pkt) + pdata = sdio_xprtp->pdev->dev.platform_data; + mutex_unlock(&sdio_xprtp->ss_reset_lock); + while (!sdio_xprtp->in_pkt) { + sdio_xprtp->in_pkt = create_pkt(NULL); + if (sdio_xprtp->in_pkt) break; IPC_RTR_ERR("%s: packet allocation failure\n", __func__); @@ -374,8 +383,8 @@ static void hsic_xprt_read_data(struct work_struct *work) __func__); msleep(100); } while (!skb); - bytes_read = pdata->read(hsic_xprtp->pdev, skb->data, - pdata->max_read_size); + bytes_read = pdata->read(sdio_xprtp->pdev->id, + skb->data, pdata->max_read_size); if (bytes_read < 0) { IPC_RTR_ERR("%s: Error %d @ read operation\n", __func__, bytes_read); @@ -394,92 +403,92 @@ static void hsic_xprt_read_data(struct work_struct *work) } bytes_to_read -= bytes_read; skb_put(skb, bytes_read); - skb_queue_tail(hsic_xprtp->in_pkt->pkt_fragment_q, skb); - hsic_xprtp->in_pkt->length += bytes_read; + skb_queue_tail(sdio_xprtp->in_pkt->pkt_fragment_q, skb); + sdio_xprtp->in_pkt->length += bytes_read; skb_size = min_t(uint32_t, pdata->max_read_size, (uint32_t)bytes_to_read); } while (bytes_to_read > 0); D("%s: Packet size read %d\n", - __func__, hsic_xprtp->in_pkt->length); - msm_ipc_router_xprt_notify(&hsic_xprtp->xprt, - IPC_ROUTER_XPRT_EVENT_DATA, (void *)hsic_xprtp->in_pkt); - release_pkt(hsic_xprtp->in_pkt); - hsic_xprtp->in_pkt = NULL; + __func__, sdio_xprtp->in_pkt->length); + msm_ipc_router_xprt_notify(&sdio_xprtp->xprt, + IPC_ROUTER_XPRT_EVENT_DATA, (void *)sdio_xprtp->in_pkt); + release_pkt(sdio_xprtp->in_pkt); + sdio_xprtp->in_pkt = NULL; } out_read_data: - release_pkt(hsic_xprtp->in_pkt); - hsic_xprtp->in_pkt = NULL; + release_pkt(sdio_xprtp->in_pkt); + sdio_xprtp->in_pkt = NULL; } /** - * hsic_xprt_sft_close_done() - Completion of XPRT reset + * sdio_xprt_sft_close_done() - Completion of XPRT reset * @xprt: XPRT on which the reset operation is complete. * - * This function is used by IPC Router to signal this HSIC XPRT Abstraction + * This function is used by IPC Router to signal this SDIO XPRT Abstraction * Layer(XAL) that the reset of XPRT is completely handled by IPC Router. */ -static void hsic_xprt_sft_close_done(struct msm_ipc_router_xprt *xprt) +static void sdio_xprt_sft_close_done(struct msm_ipc_router_xprt *xprt) { - struct msm_ipc_router_hsic_xprt *hsic_xprtp = - container_of(xprt, struct msm_ipc_router_hsic_xprt, xprt); + struct msm_ipc_router_sdio_xprt *sdio_xprtp = + container_of(xprt, struct msm_ipc_router_sdio_xprt, xprt); - complete_all(&hsic_xprtp->sft_close_complete); + complete_all(&sdio_xprtp->sft_close_complete); } /** - * msm_ipc_router_hsic_remote_remove() - Remove an HSIC endpoint - * @pdev: Platform device corresponding to HSIC endpoint. + * msm_ipc_router_sdio_remote_remove() - Remove an SDIO endpoint + * @pdev: Platform device corresponding to SDIO endpoint. * * @return: 0 on success, standard Linux error codes on error. * * This function is called when the underlying ipc_bridge driver unregisters - * a platform device, mapped to an HSIC endpoint, during SSR. + * a platform device, mapped to an SDIO endpoint, during SSR. */ -static int msm_ipc_router_hsic_remote_remove(struct platform_device *pdev) +static int msm_ipc_router_sdio_remote_remove(struct platform_device *pdev) { struct ipc_bridge_platform_data *pdata; - struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct msm_ipc_router_sdio_xprt *sdio_xprtp; - hsic_xprtp = find_hsic_xprt_list(pdev->name); - if (!hsic_xprtp) { + sdio_xprtp = find_sdio_xprt_list(pdev->name); + if (!sdio_xprtp) { IPC_RTR_ERR("%s No device with name %s\n", __func__, pdev->name); return -ENODEV; } - mutex_lock(&hsic_xprtp->ss_reset_lock); - hsic_xprtp->ss_reset = 1; - mutex_unlock(&hsic_xprtp->ss_reset_lock); - flush_workqueue(hsic_xprtp->hsic_xprt_wq); - destroy_workqueue(hsic_xprtp->hsic_xprt_wq); - init_completion(&hsic_xprtp->sft_close_complete); - msm_ipc_router_xprt_notify(&hsic_xprtp->xprt, + mutex_lock(&sdio_xprtp->ss_reset_lock); + sdio_xprtp->ss_reset = 1; + mutex_unlock(&sdio_xprtp->ss_reset_lock); + flush_workqueue(sdio_xprtp->sdio_xprt_wq); + destroy_workqueue(sdio_xprtp->sdio_xprt_wq); + init_completion(&sdio_xprtp->sft_close_complete); + msm_ipc_router_xprt_notify(&sdio_xprtp->xprt, IPC_ROUTER_XPRT_EVENT_CLOSE, NULL); - D("%s: Notified IPC Router of %s CLOSE\n", - __func__, hsic_xprtp->xprt.name); - wait_for_completion(&hsic_xprtp->sft_close_complete); - hsic_xprtp->pdev = NULL; + D("%s: Notified IPC Router of %s CLOSE\n", __func__, + sdio_xprtp->xprt.name); + wait_for_completion(&sdio_xprtp->sft_close_complete); + sdio_xprtp->pdev = NULL; pdata = pdev->dev.platform_data; if (pdata && pdata->close) - pdata->close(pdev); + pdata->close(pdev->id); return 0; } /** - * msm_ipc_router_hsic_remote_probe() - Probe an HSIC endpoint - * @pdev: Platform device corresponding to HSIC endpoint. + * msm_ipc_router_sdio_remote_probe() - Probe an SDIO endpoint + * @pdev: Platform device corresponding to SDIO endpoint. * * @return: 0 on success, standard Linux error codes on error. * * This function is called when the underlying ipc_bridge driver registers - * a platform device, mapped to an HSIC endpoint. + * a platform device, mapped to an SDIO endpoint. */ -static int msm_ipc_router_hsic_remote_probe(struct platform_device *pdev) +static int msm_ipc_router_sdio_remote_probe(struct platform_device *pdev) { int rc; struct ipc_bridge_platform_data *pdata; - struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct msm_ipc_router_sdio_xprt *sdio_xprtp; pdata = pdev->dev.platform_data; if (!pdata || !pdata->open || !pdata->read || @@ -489,139 +498,139 @@ static int msm_ipc_router_hsic_remote_probe(struct platform_device *pdev) return -EINVAL; } - hsic_xprtp = find_hsic_xprt_list(pdev->name); - if (!hsic_xprtp) { + sdio_xprtp = find_sdio_xprt_list(pdev->name); + if (!sdio_xprtp) { IPC_RTR_ERR("%s No device with name %s\n", __func__, pdev->name); return -ENODEV; } - hsic_xprtp->hsic_xprt_wq = + sdio_xprtp->sdio_xprt_wq = create_singlethread_workqueue(pdev->name); - if (!hsic_xprtp->hsic_xprt_wq) { + if (!sdio_xprtp->sdio_xprt_wq) { IPC_RTR_ERR("%s: WQ creation failed for %s\n", __func__, pdev->name); return -EFAULT; } - rc = pdata->open(pdev); + rc = pdata->open(pdev->id, NULL); if (rc < 0) { IPC_RTR_ERR("%s: Channel open failed for %s.%d\n", __func__, pdev->name, pdev->id); - destroy_workqueue(hsic_xprtp->hsic_xprt_wq); + destroy_workqueue(sdio_xprtp->sdio_xprt_wq); return rc; } - hsic_xprtp->pdev = pdev; - mutex_lock(&hsic_xprtp->ss_reset_lock); - hsic_xprtp->ss_reset = 0; - mutex_unlock(&hsic_xprtp->ss_reset_lock); - msm_ipc_router_xprt_notify(&hsic_xprtp->xprt, + sdio_xprtp->pdev = pdev; + mutex_lock(&sdio_xprtp->ss_reset_lock); + sdio_xprtp->ss_reset = 0; + mutex_unlock(&sdio_xprtp->ss_reset_lock); + msm_ipc_router_xprt_notify(&sdio_xprtp->xprt, IPC_ROUTER_XPRT_EVENT_OPEN, NULL); D("%s: Notified IPC Router of %s OPEN\n", - __func__, hsic_xprtp->xprt.name); - queue_delayed_work(hsic_xprtp->hsic_xprt_wq, - &hsic_xprtp->read_work, 0); + __func__, sdio_xprtp->xprt.name); + queue_delayed_work(sdio_xprtp->sdio_xprt_wq, + &sdio_xprtp->read_work, 0); return 0; } /** - * msm_ipc_router_hsic_driver_register() - register HSIC XPRT drivers + * msm_ipc_router_sdio_driver_register() - register SDIO XPRT drivers * - * @hsic_xprtp: pointer to IPC router hsic xprt structure. + * @sdio_xprtp: pointer to IPC router sdio xprt structure. * * @return: 0 on success, standard Linux error codes on error. * * This function is called when a new XPRT is added to register platform * drivers for new XPRT. */ -static int msm_ipc_router_hsic_driver_register( - struct msm_ipc_router_hsic_xprt *hsic_xprtp) +static int msm_ipc_router_sdio_driver_register( + struct msm_ipc_router_sdio_xprt *sdio_xprtp) { int ret; - struct msm_ipc_router_hsic_xprt *hsic_xprtp_item; + struct msm_ipc_router_sdio_xprt *sdio_xprtp_item; - hsic_xprtp_item = find_hsic_xprt_list(hsic_xprtp->ch_name); + sdio_xprtp_item = find_sdio_xprt_list(sdio_xprtp->ch_name); - mutex_lock(&hsic_remote_xprt_list_lock_lha1); - list_add(&hsic_xprtp->list, &hsic_remote_xprt_list); - mutex_unlock(&hsic_remote_xprt_list_lock_lha1); + mutex_lock(&sdio_remote_xprt_list_lock_lha1); + list_add(&sdio_xprtp->list, &sdio_remote_xprt_list); + mutex_unlock(&sdio_remote_xprt_list_lock_lha1); - if (!hsic_xprtp_item) { - hsic_xprtp->driver.driver.name = hsic_xprtp->ch_name; - hsic_xprtp->driver.driver.owner = THIS_MODULE; - hsic_xprtp->driver.probe = msm_ipc_router_hsic_remote_probe; - hsic_xprtp->driver.remove = msm_ipc_router_hsic_remote_remove; + if (!sdio_xprtp_item) { + sdio_xprtp->driver.driver.name = sdio_xprtp->ch_name; + sdio_xprtp->driver.driver.owner = THIS_MODULE; + sdio_xprtp->driver.probe = msm_ipc_router_sdio_remote_probe; + sdio_xprtp->driver.remove = msm_ipc_router_sdio_remote_remove; - ret = platform_driver_register(&hsic_xprtp->driver); + ret = platform_driver_register(&sdio_xprtp->driver); if (ret) { IPC_RTR_ERR( "%s: Failed to register platform driver[%s]\n", - __func__, hsic_xprtp->ch_name); + __func__, sdio_xprtp->ch_name); return ret; } } else { IPC_RTR_ERR("%s Already driver registered %s\n", - __func__, hsic_xprtp->ch_name); + __func__, sdio_xprtp->ch_name); } return 0; } /** - * msm_ipc_router_hsic_config_init() - init HSIC xprt configs + * msm_ipc_router_sdio_config_init() - init SDIO xprt configs * - * @hsic_xprt_config: pointer to HSIC xprt configurations. + * @sdio_xprt_config: pointer to SDIO xprt configurations. * * @return: 0 on success, standard Linux error codes on error. * - * This function is called to initialize the HSIC XPRT pointer with - * the HSIC XPRT configurations either from device tree or static arrays. + * This function is called to initialize the SDIO XPRT pointer with + * the SDIO XPRT configurations either from device tree or static arrays. */ -static int msm_ipc_router_hsic_config_init( - struct msm_ipc_router_hsic_xprt_config *hsic_xprt_config) +static int msm_ipc_router_sdio_config_init( + struct msm_ipc_router_sdio_xprt_config *sdio_xprt_config) { - struct msm_ipc_router_hsic_xprt *hsic_xprtp; + struct msm_ipc_router_sdio_xprt *sdio_xprtp; - hsic_xprtp = kzalloc(sizeof(struct msm_ipc_router_hsic_xprt), + sdio_xprtp = kzalloc(sizeof(struct msm_ipc_router_sdio_xprt), GFP_KERNEL); - if (IS_ERR_OR_NULL(hsic_xprtp)) { - IPC_RTR_ERR("%s: kzalloc() failed for hsic_xprtp id:%s\n", - __func__, hsic_xprt_config->ch_name); + if (IS_ERR_OR_NULL(sdio_xprtp)) { + IPC_RTR_ERR("%s: kzalloc() failed for sdio_xprtp id:%s\n", + __func__, sdio_xprt_config->ch_name); return -ENOMEM; } - hsic_xprtp->xprt.link_id = hsic_xprt_config->link_id; - hsic_xprtp->xprt_version = hsic_xprt_config->xprt_version; + sdio_xprtp->xprt.link_id = sdio_xprt_config->link_id; + sdio_xprtp->xprt_version = sdio_xprt_config->xprt_version; - strlcpy(hsic_xprtp->ch_name, hsic_xprt_config->ch_name, + strlcpy(sdio_xprtp->ch_name, sdio_xprt_config->ch_name, XPRT_NAME_LEN); - strlcpy(hsic_xprtp->xprt_name, hsic_xprt_config->xprt_name, + strlcpy(sdio_xprtp->xprt_name, sdio_xprt_config->xprt_name, XPRT_NAME_LEN); - hsic_xprtp->xprt.name = hsic_xprtp->xprt_name; + sdio_xprtp->xprt.name = sdio_xprtp->xprt_name; - hsic_xprtp->xprt.set_version = - ipc_router_hsic_set_xprt_version; - hsic_xprtp->xprt.get_version = - msm_ipc_router_hsic_get_xprt_version; - hsic_xprtp->xprt.get_option = - msm_ipc_router_hsic_get_xprt_option; - hsic_xprtp->xprt.read_avail = NULL; - hsic_xprtp->xprt.read = NULL; - hsic_xprtp->xprt.write_avail = - msm_ipc_router_hsic_remote_write_avail; - hsic_xprtp->xprt.write = msm_ipc_router_hsic_remote_write; - hsic_xprtp->xprt.close = msm_ipc_router_hsic_remote_close; - hsic_xprtp->xprt.sft_close_done = hsic_xprt_sft_close_done; - hsic_xprtp->xprt.priv = NULL; + sdio_xprtp->xprt.set_version = + ipc_router_sdio_set_xprt_version; + sdio_xprtp->xprt.get_version = + msm_ipc_router_sdio_get_xprt_version; + sdio_xprtp->xprt.get_option = + msm_ipc_router_sdio_get_xprt_option; + sdio_xprtp->xprt.read_avail = NULL; + sdio_xprtp->xprt.read = NULL; + sdio_xprtp->xprt.write_avail = + msm_ipc_router_sdio_remote_write_avail; + sdio_xprtp->xprt.write = msm_ipc_router_sdio_remote_write; + sdio_xprtp->xprt.close = msm_ipc_router_sdio_remote_close; + sdio_xprtp->xprt.sft_close_done = sdio_xprt_sft_close_done; + sdio_xprtp->xprt.priv = NULL; - hsic_xprtp->in_pkt = NULL; - INIT_DELAYED_WORK(&hsic_xprtp->read_work, hsic_xprt_read_data); - mutex_init(&hsic_xprtp->ss_reset_lock); - hsic_xprtp->ss_reset = 0; - hsic_xprtp->xprt_option = 0; + sdio_xprtp->in_pkt = NULL; + INIT_DELAYED_WORK(&sdio_xprtp->read_work, sdio_xprt_read_data); + mutex_init(&sdio_xprtp->ss_reset_lock); + sdio_xprtp->ss_reset = 0; + sdio_xprtp->xprt_option = 0; - msm_ipc_router_hsic_driver_register(hsic_xprtp); + msm_ipc_router_sdio_driver_register(sdio_xprtp); return 0; } @@ -630,12 +639,12 @@ static int msm_ipc_router_hsic_config_init( * parse_devicetree() - parse device tree binding * * @node: pointer to device tree node - * @hsic_xprt_config: pointer to HSIC XPRT configurations + * @sdio_xprt_config: pointer to SDIO XPRT configurations * * @return: 0 on success, -ENODEV on failure. */ static int parse_devicetree(struct device_node *node, - struct msm_ipc_router_hsic_xprt_config *hsic_xprt_config) + struct msm_ipc_router_sdio_xprt_config *sdio_xprt_config) { int ret; int link_id; @@ -648,7 +657,7 @@ static int parse_devicetree(struct device_node *node, ch_name = of_get_property(node, key, NULL); if (!ch_name) goto error; - strlcpy(hsic_xprt_config->ch_name, ch_name, XPRT_NAME_LEN); + strlcpy(sdio_xprt_config->ch_name, ch_name, XPRT_NAME_LEN); key = "qcom,xprt-remote"; remote_ss = of_get_property(node, key, NULL); @@ -659,16 +668,16 @@ static int parse_devicetree(struct device_node *node, ret = of_property_read_u32(node, key, &link_id); if (ret) goto error; - hsic_xprt_config->link_id = link_id; + sdio_xprt_config->link_id = link_id; key = "qcom,xprt-version"; ret = of_property_read_u32(node, key, &version); if (ret) goto error; - hsic_xprt_config->xprt_version = version; + sdio_xprt_config->xprt_version = version; - scnprintf(hsic_xprt_config->xprt_name, XPRT_NAME_LEN, "%s_%s", - remote_ss, hsic_xprt_config->ch_name); + scnprintf(sdio_xprt_config->xprt_name, XPRT_NAME_LEN, "%s_%s", + remote_ss, sdio_xprt_config->ch_name); return 0; @@ -678,37 +687,36 @@ error: } /** - * msm_ipc_router_hsic_xprt_probe() - Probe an HSIC xprt - * @pdev: Platform device corresponding to HSIC xprt. + * msm_ipc_router_sdio_xprt_probe() - Probe an SDIO xprt + * @pdev: Platform device corresponding to SDIO xprt. * * @return: 0 on success, standard Linux error codes on error. * * This function is called when the underlying device tree driver registers - * a platform device, mapped to an HSIC transport. + * a platform device, mapped to an SDIO transport. */ -static int msm_ipc_router_hsic_xprt_probe( - struct platform_device *pdev) +static int msm_ipc_router_sdio_xprt_probe(struct platform_device *pdev) { int ret; - struct msm_ipc_router_hsic_xprt_config hsic_xprt_config; + struct msm_ipc_router_sdio_xprt_config sdio_xprt_config; if (pdev && pdev->dev.of_node) { - mutex_lock(&hsic_remote_xprt_list_lock_lha1); - ipc_router_hsic_xprt_probe_done = 1; - mutex_unlock(&hsic_remote_xprt_list_lock_lha1); + mutex_lock(&sdio_remote_xprt_list_lock_lha1); + ipc_router_sdio_xprt_probe_done = 1; + mutex_unlock(&sdio_remote_xprt_list_lock_lha1); ret = parse_devicetree(pdev->dev.of_node, - &hsic_xprt_config); + &sdio_xprt_config); if (ret) { IPC_RTR_ERR("%s: Failed to parse device tree\n", __func__); return ret; } - ret = msm_ipc_router_hsic_config_init( - &hsic_xprt_config); + ret = msm_ipc_router_sdio_config_init( + &sdio_xprt_config); if (ret) { - IPC_RTR_ERR(" %s init failed\n", __func__); + IPC_RTR_ERR("%s init failed\n", __func__); return ret; } } @@ -716,7 +724,7 @@ static int msm_ipc_router_hsic_xprt_probe( } /** - * ipc_router_hsic_xprt_probe_worker() - probe worker for non DT configurations + * ipc_router_sdio_xprt_probe_worker() - probe worker for non DT configurations * * @work: work item to process * @@ -724,60 +732,59 @@ static int msm_ipc_router_hsic_xprt_probe( * device tree probe is done or not. If device tree probe fails the default * configurations read from static array. */ -static void ipc_router_hsic_xprt_probe_worker(struct work_struct *work) +static void ipc_router_sdio_xprt_probe_worker(struct work_struct *work) { int i, ret; - BUG_ON(ARRAY_SIZE(hsic_xprt_cfg) != NUM_HSIC_XPRTS); + BUG_ON(ARRAY_SIZE(sdio_xprt_cfg) != NUM_SDIO_XPRTS); - mutex_lock(&hsic_remote_xprt_list_lock_lha1); - if (!ipc_router_hsic_xprt_probe_done) { - mutex_unlock(&hsic_remote_xprt_list_lock_lha1); - for (i = 0; i < ARRAY_SIZE(hsic_xprt_cfg); i++) { - ret = msm_ipc_router_hsic_config_init( - &hsic_xprt_cfg[i]); + mutex_lock(&sdio_remote_xprt_list_lock_lha1); + if (!ipc_router_sdio_xprt_probe_done) { + mutex_unlock(&sdio_remote_xprt_list_lock_lha1); + for (i = 0; i < ARRAY_SIZE(sdio_xprt_cfg); i++) { + ret = msm_ipc_router_sdio_config_init( + &sdio_xprt_cfg[i]); if (ret) - IPC_RTR_ERR(" %s init failed config idx %d\n", + D("%s init failed config idx %d\n", __func__, i); } - mutex_lock(&hsic_remote_xprt_list_lock_lha1); + mutex_lock(&sdio_remote_xprt_list_lock_lha1); } - mutex_unlock(&hsic_remote_xprt_list_lock_lha1); + mutex_unlock(&sdio_remote_xprt_list_lock_lha1); } -static const struct of_device_id msm_ipc_router_hsic_xprt_match_table[] = { - { .compatible = "qcom,ipc_router_hsic_xprt" }, +static const struct of_device_id msm_ipc_router_sdio_xprt_match_table[] = { + { .compatible = "qcom,ipc_router_sdio_xprt" }, {}, }; -static struct platform_driver msm_ipc_router_hsic_xprt_driver = { - .probe = msm_ipc_router_hsic_xprt_probe, +static struct platform_driver msm_ipc_router_sdio_xprt_driver = { + .probe = msm_ipc_router_sdio_xprt_probe, .driver = { .name = MODULE_NAME, .owner = THIS_MODULE, - .of_match_table = msm_ipc_router_hsic_xprt_match_table, + .of_match_table = msm_ipc_router_sdio_xprt_match_table, }, }; -static int __init msm_ipc_router_hsic_xprt_init(void) +static int __init msm_ipc_router_sdio_xprt_init(void) { int rc; - rc = platform_driver_register(&msm_ipc_router_hsic_xprt_driver); + rc = platform_driver_register(&msm_ipc_router_sdio_xprt_driver); if (rc) { IPC_RTR_ERR( - "%s: msm_ipc_router_hsic_xprt_driver register failed %d\n", + "%s: msm_ipc_router_sdio_xprt_driver register failed %d\n", __func__, rc); return rc; } - INIT_DELAYED_WORK(&ipc_router_hsic_xprt_probe_work, - ipc_router_hsic_xprt_probe_worker); - schedule_delayed_work(&ipc_router_hsic_xprt_probe_work, - msecs_to_jiffies(IPC_ROUTER_HSIC_XPRT_WAIT_TIMEOUT)); + INIT_DELAYED_WORK(&ipc_router_sdio_xprt_probe_work, + ipc_router_sdio_xprt_probe_worker); + schedule_delayed_work(&ipc_router_sdio_xprt_probe_work, + msecs_to_jiffies(IPC_ROUTER_SDIO_XPRT_WAIT_TIMEOUT)); return 0; } -module_init(msm_ipc_router_hsic_xprt_init); -MODULE_DESCRIPTION("IPC Router HSIC XPRT"); +module_init(msm_ipc_router_sdio_xprt_init); MODULE_LICENSE("GPL v2");