Loading drivers/soc/qcom/spcom.c +50 −31 Original line number Diff line number Diff line Loading @@ -93,8 +93,6 @@ /* SPCOM driver name */ #define DEVICE_NAME "spcom" #define SPCOM_MAX_CHANNELS 0x20 /* maximum ION buffers should be >= SPCOM_MAX_CHANNELS */ #define SPCOM_MAX_ION_BUF_PER_CH (SPCOM_MAX_CHANNELS + 4) Loading Loading @@ -195,6 +193,7 @@ struct spcom_channel { * glink state: CONNECTED / LOCAL_DISCONNECTED, REMOTE_DISCONNECTED */ unsigned int glink_state; bool is_closing; /* Events notification */ struct completion connect; Loading Loading @@ -244,7 +243,7 @@ struct spcom_device { int channel_count; /* private */ struct mutex lock; struct mutex cmd_lock; /* Link state */ struct completion link_state_changed; Loading Loading @@ -483,7 +482,17 @@ static void spcom_notify_state(void *handle, const void *priv, switch (event) { case GLINK_CONNECTED: pr_debug("GLINK_CONNECTED, ch name [%s].\n", ch->name); mutex_lock(&ch->lock); if (ch->is_closing) { pr_err("Unexpected CONNECTED while closing [%s].\n", ch->name); mutex_unlock(&ch->lock); return; } ch->glink_state = event; /* * if spcom_notify_state() is called within glink_open() * then ch->glink_handle is not updated yet. Loading @@ -493,17 +502,28 @@ static void spcom_notify_state(void *handle, const void *priv, ch->glink_handle = handle; } /* prepare default rx buffer after connected */ /* signal before unlock mutex & before calling glink */ complete_all(&ch->connect); /* * Prepare default rx buffer. * glink_queue_rx_intent() can be called only AFTER connected. * We do it here, ASAP, to allow rx data. */ pr_debug("call glink_queue_rx_intent() ch [%s].\n", ch->name); ret = glink_queue_rx_intent(ch->glink_handle, ch, ch->rx_buf_size); if (ret) { pr_err("glink_queue_rx_intent() err [%d]\n", ret); } else { pr_debug("rx buf is ready, size [%zu].\n", pr_debug("rx buf is ready, size [%zu]\n", ch->rx_buf_size); ch->rx_buf_ready = true; } complete_all(&ch->connect); pr_debug("GLINK_CONNECTED, ch name [%s] done.\n", ch->name); mutex_unlock(&ch->lock); break; case GLINK_LOCAL_DISCONNECTED: /* Loading Loading @@ -556,9 +576,7 @@ static void spcom_notify_state(void *handle, const void *priv, static bool spcom_notify_rx_intent_req(void *handle, const void *priv, size_t req_size) { struct spcom_channel *ch = (struct spcom_channel *) priv; pr_err("Unexpected intent request for ch [%s].\n", ch->name); pr_err("Unexpected intent request\n"); return false; } Loading Loading @@ -670,6 +688,13 @@ static int spcom_init_channel(struct spcom_channel *ch, const char *name) ch->glink_state = GLINK_LOCAL_DISCONNECTED; ch->actual_rx_size = 0; ch->rx_buf_size = SPCOM_RX_BUF_SIZE; ch->is_closing = false; ch->glink_handle = NULL; ch->ref_count = 0; ch->rx_abort = false; ch->tx_abort = false; ch->txn_id = INITIAL_TXN_ID; /* use non-zero nonce for debug */ ch->pid = 0; return 0; } Loading Loading @@ -739,6 +764,8 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec) /* init completion before calling glink_open() */ reinit_completion(&ch->connect); ch->is_closing = false; handle = glink_open(&cfg); if (IS_ERR_OR_NULL(handle)) { pr_err("glink_open failed.\n"); Loading @@ -753,6 +780,8 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec) ch->pid = current_pid(); ch->txn_id = INITIAL_TXN_ID; mutex_unlock(&ch->lock); pr_debug("Wait for connection on channel [%s] timeout_msec [%d].\n", name, timeout_msec); Loading @@ -769,8 +798,6 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec) pr_debug("Channel [%s] opened, no timeout.\n", name); } mutex_unlock(&ch->lock); return 0; exit_err: mutex_unlock(&ch->lock); Loading @@ -797,6 +824,8 @@ static int spcom_close(struct spcom_channel *ch) return 0; } ch->is_closing = true; ret = glink_close(ch->glink_handle); if (ret) pr_err("glink_close() fail, ret [%d].\n", ret); Loading @@ -812,6 +841,7 @@ static int spcom_close(struct spcom_channel *ch) ch->pid = 0; pr_debug("Channel closed [%s].\n", ch->name); mutex_unlock(&ch->lock); return 0; Loading Loading @@ -1923,18 +1953,6 @@ static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch, return ret; } /** * spcom_handle_fake_ssr_command() - Handle fake ssr command from user space. */ static int spcom_handle_fake_ssr_command(struct spcom_channel *ch, int arg) { pr_debug("Start Fake glink SSR subsystem [%s].\n", spcom_edge); glink_ssr(spcom_edge); pr_debug("Fake glink SSR subsystem [%s] done.\n", spcom_edge); return 0; } /** * spcom_handle_write() - Handle user space write commands. * Loading Loading @@ -1964,6 +1982,8 @@ static int spcom_handle_write(struct spcom_channel *ch, swap_id = htonl(cmd->cmd_id); memcpy(cmd_name, &swap_id, sizeof(int)); mutex_lock(&spcom_dev->cmd_lock); pr_debug("cmd_id [0x%x] cmd_name [%s].\n", cmd_id, cmd_name); switch (cmd_id) { Loading @@ -1979,17 +1999,16 @@ static int spcom_handle_write(struct spcom_channel *ch, case SPCOM_CMD_UNLOCK_ION_BUF: ret = spcom_handle_unlock_ion_buf_command(ch, buf, buf_size); break; case SPCOM_CMD_FSSR: ret = spcom_handle_fake_ssr_command(ch, cmd->arg); break; case SPCOM_CMD_CREATE_CHANNEL: ret = spcom_handle_create_channel_command(buf, buf_size); break; default: pr_err("Invalid Command Id [0x%x].\n", (int) cmd->cmd_id); return -EINVAL; ret = -EINVAL; } mutex_unlock(&spcom_dev->cmd_lock); return ret; } Loading Loading @@ -2690,7 +2709,7 @@ static int spcom_probe(struct platform_device *pdev) return -ENOMEM; spcom_dev = dev; mutex_init(&dev->lock); mutex_init(&spcom_dev->cmd_lock); init_completion(&dev->link_state_changed); spcom_dev->link_state = GLINK_LINK_STATE_DOWN; Loading Loading @@ -2763,7 +2782,7 @@ static int __init spcom_init(void) { int ret; pr_info("spcom driver Ver 1.0 23-Nov-2015.\n"); pr_info("spcom driver version 1.1 17-July-2017.\n"); ret = platform_driver_register(&spcom_driver); if (ret) Loading include/uapi/linux/spcom.h +6 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,12 @@ * with special size SPCOM_GET_NEXT_REQUEST_SIZE. */ /* * Maximum number of channel between Secure Processor and HLOS. * including predefined channels, like "sp_kernel". */ #define SPCOM_MAX_CHANNELS 0x20 /* Maximum size (including null) for channel names */ #define SPCOM_CHANNEL_NAME_SIZE 32 Loading Loading
drivers/soc/qcom/spcom.c +50 −31 Original line number Diff line number Diff line Loading @@ -93,8 +93,6 @@ /* SPCOM driver name */ #define DEVICE_NAME "spcom" #define SPCOM_MAX_CHANNELS 0x20 /* maximum ION buffers should be >= SPCOM_MAX_CHANNELS */ #define SPCOM_MAX_ION_BUF_PER_CH (SPCOM_MAX_CHANNELS + 4) Loading Loading @@ -195,6 +193,7 @@ struct spcom_channel { * glink state: CONNECTED / LOCAL_DISCONNECTED, REMOTE_DISCONNECTED */ unsigned int glink_state; bool is_closing; /* Events notification */ struct completion connect; Loading Loading @@ -244,7 +243,7 @@ struct spcom_device { int channel_count; /* private */ struct mutex lock; struct mutex cmd_lock; /* Link state */ struct completion link_state_changed; Loading Loading @@ -483,7 +482,17 @@ static void spcom_notify_state(void *handle, const void *priv, switch (event) { case GLINK_CONNECTED: pr_debug("GLINK_CONNECTED, ch name [%s].\n", ch->name); mutex_lock(&ch->lock); if (ch->is_closing) { pr_err("Unexpected CONNECTED while closing [%s].\n", ch->name); mutex_unlock(&ch->lock); return; } ch->glink_state = event; /* * if spcom_notify_state() is called within glink_open() * then ch->glink_handle is not updated yet. Loading @@ -493,17 +502,28 @@ static void spcom_notify_state(void *handle, const void *priv, ch->glink_handle = handle; } /* prepare default rx buffer after connected */ /* signal before unlock mutex & before calling glink */ complete_all(&ch->connect); /* * Prepare default rx buffer. * glink_queue_rx_intent() can be called only AFTER connected. * We do it here, ASAP, to allow rx data. */ pr_debug("call glink_queue_rx_intent() ch [%s].\n", ch->name); ret = glink_queue_rx_intent(ch->glink_handle, ch, ch->rx_buf_size); if (ret) { pr_err("glink_queue_rx_intent() err [%d]\n", ret); } else { pr_debug("rx buf is ready, size [%zu].\n", pr_debug("rx buf is ready, size [%zu]\n", ch->rx_buf_size); ch->rx_buf_ready = true; } complete_all(&ch->connect); pr_debug("GLINK_CONNECTED, ch name [%s] done.\n", ch->name); mutex_unlock(&ch->lock); break; case GLINK_LOCAL_DISCONNECTED: /* Loading Loading @@ -556,9 +576,7 @@ static void spcom_notify_state(void *handle, const void *priv, static bool spcom_notify_rx_intent_req(void *handle, const void *priv, size_t req_size) { struct spcom_channel *ch = (struct spcom_channel *) priv; pr_err("Unexpected intent request for ch [%s].\n", ch->name); pr_err("Unexpected intent request\n"); return false; } Loading Loading @@ -670,6 +688,13 @@ static int spcom_init_channel(struct spcom_channel *ch, const char *name) ch->glink_state = GLINK_LOCAL_DISCONNECTED; ch->actual_rx_size = 0; ch->rx_buf_size = SPCOM_RX_BUF_SIZE; ch->is_closing = false; ch->glink_handle = NULL; ch->ref_count = 0; ch->rx_abort = false; ch->tx_abort = false; ch->txn_id = INITIAL_TXN_ID; /* use non-zero nonce for debug */ ch->pid = 0; return 0; } Loading Loading @@ -739,6 +764,8 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec) /* init completion before calling glink_open() */ reinit_completion(&ch->connect); ch->is_closing = false; handle = glink_open(&cfg); if (IS_ERR_OR_NULL(handle)) { pr_err("glink_open failed.\n"); Loading @@ -753,6 +780,8 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec) ch->pid = current_pid(); ch->txn_id = INITIAL_TXN_ID; mutex_unlock(&ch->lock); pr_debug("Wait for connection on channel [%s] timeout_msec [%d].\n", name, timeout_msec); Loading @@ -769,8 +798,6 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec) pr_debug("Channel [%s] opened, no timeout.\n", name); } mutex_unlock(&ch->lock); return 0; exit_err: mutex_unlock(&ch->lock); Loading @@ -797,6 +824,8 @@ static int spcom_close(struct spcom_channel *ch) return 0; } ch->is_closing = true; ret = glink_close(ch->glink_handle); if (ret) pr_err("glink_close() fail, ret [%d].\n", ret); Loading @@ -812,6 +841,7 @@ static int spcom_close(struct spcom_channel *ch) ch->pid = 0; pr_debug("Channel closed [%s].\n", ch->name); mutex_unlock(&ch->lock); return 0; Loading Loading @@ -1923,18 +1953,6 @@ static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch, return ret; } /** * spcom_handle_fake_ssr_command() - Handle fake ssr command from user space. */ static int spcom_handle_fake_ssr_command(struct spcom_channel *ch, int arg) { pr_debug("Start Fake glink SSR subsystem [%s].\n", spcom_edge); glink_ssr(spcom_edge); pr_debug("Fake glink SSR subsystem [%s] done.\n", spcom_edge); return 0; } /** * spcom_handle_write() - Handle user space write commands. * Loading Loading @@ -1964,6 +1982,8 @@ static int spcom_handle_write(struct spcom_channel *ch, swap_id = htonl(cmd->cmd_id); memcpy(cmd_name, &swap_id, sizeof(int)); mutex_lock(&spcom_dev->cmd_lock); pr_debug("cmd_id [0x%x] cmd_name [%s].\n", cmd_id, cmd_name); switch (cmd_id) { Loading @@ -1979,17 +1999,16 @@ static int spcom_handle_write(struct spcom_channel *ch, case SPCOM_CMD_UNLOCK_ION_BUF: ret = spcom_handle_unlock_ion_buf_command(ch, buf, buf_size); break; case SPCOM_CMD_FSSR: ret = spcom_handle_fake_ssr_command(ch, cmd->arg); break; case SPCOM_CMD_CREATE_CHANNEL: ret = spcom_handle_create_channel_command(buf, buf_size); break; default: pr_err("Invalid Command Id [0x%x].\n", (int) cmd->cmd_id); return -EINVAL; ret = -EINVAL; } mutex_unlock(&spcom_dev->cmd_lock); return ret; } Loading Loading @@ -2690,7 +2709,7 @@ static int spcom_probe(struct platform_device *pdev) return -ENOMEM; spcom_dev = dev; mutex_init(&dev->lock); mutex_init(&spcom_dev->cmd_lock); init_completion(&dev->link_state_changed); spcom_dev->link_state = GLINK_LINK_STATE_DOWN; Loading Loading @@ -2763,7 +2782,7 @@ static int __init spcom_init(void) { int ret; pr_info("spcom driver Ver 1.0 23-Nov-2015.\n"); pr_info("spcom driver version 1.1 17-July-2017.\n"); ret = platform_driver_register(&spcom_driver); if (ret) Loading
include/uapi/linux/spcom.h +6 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,12 @@ * with special size SPCOM_GET_NEXT_REQUEST_SIZE. */ /* * Maximum number of channel between Secure Processor and HLOS. * including predefined channels, like "sp_kernel". */ #define SPCOM_MAX_CHANNELS 0x20 /* Maximum size (including null) for channel names */ #define SPCOM_CHANNEL_NAME_SIZE 32 Loading