Loading drivers/slimbus/slim-msm-ngd.c +61 −92 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ enum ngd_status { NGD_LADDR = 1 << 1, }; static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf); static int ngd_slim_runtime_resume(struct device *device); static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart); Loading Loading @@ -122,7 +123,7 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) (4 * i)); SLIM_DBG(dev, "REG-RX data: %x\n", rx_buf[i]); } msm_slim_rx_enqueue(dev, rx_buf, len); ngd_slim_rx(dev, (u8 *)rx_buf); writel_relaxed(NGD_INT_RX_MSG_RCVD, ngd + NGD_INT_CLR); /* Loading @@ -132,8 +133,6 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) mb(); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) SLIM_WARN(dev, "direct msg rcvd with RX MSGQs\n"); else complete(&dev->rx_msgq_notify); } if (stat & NGD_INT_RECFG_DONE) { writel_relaxed(NGD_INT_RECFG_DONE, ngd + NGD_INT_CLR); Loading Loading @@ -588,7 +587,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) if (dev->state != MSM_CTRL_DOWN) { msm_slim_disconnect_endp(dev, &dev->tx_msgq, &dev->use_tx_msgqs); msm_slim_connect_endp(dev, &dev->tx_msgq, NULL); msm_slim_connect_endp(dev, &dev->tx_msgq); } } else if (!timeout) { ret = -ETIMEDOUT; Loading Loading @@ -907,8 +906,7 @@ static void ngd_slim_setup_msg_path(struct msm_slim_ctrl *dev) SLIM_WARN(dev, "pipe setup when RX msgq enabled?"); goto setup_tx_msg_path; } msm_slim_connect_endp(dev, &dev->rx_msgq, &dev->rx_msgq_notify); msm_slim_connect_endp(dev, &dev->rx_msgq); setup_tx_msg_path: if (dev->use_tx_msgqs == MSM_MSGQ_DISABLED) Loading @@ -917,74 +915,21 @@ setup_tx_msg_path: SLIM_WARN(dev, "pipe setup when TX msgq enabled?"); return; } msm_slim_connect_endp(dev, &dev->tx_msgq, NULL); msm_slim_connect_endp(dev, &dev->tx_msgq); } } static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf) { u8 mc, mt, len; int ret; u32 msgq_en = 1; len = buf[0] & 0x1F; mt = (buf[0] >> 5) & 0x7; mc = buf[1]; if (mc == SLIM_USR_MC_MASTER_CAPABILITY && mt == SLIM_MSG_MT_SRC_REFERRED_USER) { struct slim_msg_txn txn; int retries = 0; u8 wbuf[8]; txn.dt = SLIM_MSG_DEST_LOGICALADDR; txn.ec = 0; txn.rbuf = NULL; txn.mc = SLIM_USR_MC_REPORT_SATELLITE; txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER; txn.la = SLIM_LA_MGR; wbuf[0] = SAT_MAGIC_LSB; wbuf[1] = SAT_MAGIC_MSB; wbuf[2] = SAT_MSG_VER; wbuf[3] = SAT_MSG_PROT; txn.wbuf = wbuf; txn.len = 4; SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n"); if (dev->state >= MSM_CTRL_ASLEEP) { ngd_slim_setup_msg_path(dev); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) msgq_en |= NGD_CFG_RX_MSGQ_EN; if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED) msgq_en |= NGD_CFG_TX_MSGQ_EN; writel_relaxed(msgq_en, dev->base + NGD_BASE(dev->ctrl.nr, dev->ver)); /* make sure NGD MSG-Q config goes through */ mb(); } capability_retry: txn.rl = 8; ret = ngd_xfer_msg(&dev->ctrl, &txn); if (!ret) { enum msm_ctrl_state prev_state = dev->state; SLIM_INFO(dev, "SLIM SAT: capability exchange successful\n"); if (prev_state >= MSM_CTRL_ASLEEP) complete(&dev->reconf); else SLIM_ERR(dev, "SLIM: unexpected capability, state:%d\n", prev_state); /* ADSP SSR, send device_up notifications */ if (prev_state == MSM_CTRL_DOWN) complete(&dev->qmi.slave_notify); } else if (ret == -EIO) { SLIM_WARN(dev, "capability message NACKed, retrying\n"); if (retries < INIT_MX_RETRIES) { msleep(DEF_RETRY_MS); retries++; goto capability_retry; } } } mt == SLIM_MSG_MT_SRC_REFERRED_USER) complete(&dev->rx_msgq_notify); if (mc == SLIM_MSG_MC_REPLY_INFORMATION || mc == SLIM_MSG_MC_REPLY_VALUE) { u8 tid = buf[3]; Loading Loading @@ -1193,43 +1138,66 @@ static int ngd_slim_rx_msgq_thread(void *data) { struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)data; struct completion *notify = &dev->rx_msgq_notify; int ret = 0, index = 0; u32 mc = 0; u32 mt = 0; u32 buffer[10]; u8 msg_len = 0; int ret = 0; u32 msgq_en = 1; while (!kthread_should_stop()) { struct slim_msg_txn txn; int retries = 0; u8 wbuf[8]; set_current_state(TASK_INTERRUPTIBLE); wait_for_completion(notify); /* 1 irq notification per message */ if (dev->use_rx_msgqs != MSM_MSGQ_ENABLED) { msm_slim_rx_dequeue(dev, (u8 *)buffer); ngd_slim_rx(dev, (u8 *)buffer); continue; } do { ret = msm_slim_rx_msgq_get(dev, buffer, index); if (ret) { SLIM_ERR(dev, "rx_msgq_get() failed 0x%x\n", ret); break; txn.dt = SLIM_MSG_DEST_LOGICALADDR; txn.ec = 0; txn.rbuf = NULL; txn.mc = SLIM_USR_MC_REPORT_SATELLITE; txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER; txn.la = SLIM_LA_MGR; wbuf[0] = SAT_MAGIC_LSB; wbuf[1] = SAT_MAGIC_MSB; wbuf[2] = SAT_MSG_VER; wbuf[3] = SAT_MSG_PROT; txn.wbuf = wbuf; txn.len = 4; SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n"); if (dev->state >= MSM_CTRL_ASLEEP) { ngd_slim_setup_msg_path(dev); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) msgq_en |= NGD_CFG_RX_MSGQ_EN; if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED) msgq_en |= NGD_CFG_TX_MSGQ_EN; writel_relaxed(msgq_en, dev->base + NGD_BASE(dev->ctrl.nr, dev->ver)); /* make sure NGD MSG-Q config goes through */ mb(); } capability_retry: txn.rl = 8; ret = ngd_xfer_msg(&dev->ctrl, &txn); if (!ret) { enum msm_ctrl_state prev_state = dev->state; /* Traverse first byte of message for message length */ if (index++ == 0) { msg_len = *buffer & 0x1F; mt = (buffer[0] >> 5) & 0x7; mc = (buffer[0] >> 8) & 0xff; dev_dbg(dev->dev, "MC: %x, MT: %x\n", mc, mt); SLIM_INFO(dev, "SLIM SAT: capability exchange successful\n"); if (prev_state >= MSM_CTRL_ASLEEP) complete(&dev->reconf); else SLIM_ERR(dev, "SLIM: unexpected capability, state:%d\n", prev_state); /* ADSP SSR, send device_up notifications */ if (prev_state == MSM_CTRL_DOWN) complete(&dev->qmi.slave_notify); } else if (ret == -EIO) { SLIM_WARN(dev, "capability message NACKed, retrying\n"); if (retries < INIT_MX_RETRIES) { msleep(DEF_RETRY_MS); retries++; goto capability_retry; } msg_len = (msg_len < 4) ? 0 : (msg_len - 4); } while (msg_len); if (!msg_len) { index = 0; ngd_slim_rx(dev, (u8 *)buffer); } continue; } return 0; } Loading Loading @@ -1459,6 +1427,7 @@ static int ngd_slim_probe(struct platform_device *pdev) dev->ctrl.port_xfer = msm_slim_port_xfer; dev->ctrl.port_xfer_status = msm_slim_port_xfer_status; dev->bam_mem = bam_mem; dev->rx_slim = ngd_slim_rx; init_completion(&dev->reconf); init_completion(&dev->ctrl_up); Loading drivers/slimbus/slim-msm.c +45 −25 Original line number Diff line number Diff line Loading @@ -578,33 +578,55 @@ u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len, static void msm_slim_rx_msgq_event(struct msm_slim_ctrl *dev, struct sps_event_notify *ev) { u32 *buf = ev->data.transfer.user; struct sps_iovec *iovec = &ev->data.transfer.iovec; /* * Note the virtual address needs to be offset by the same index * as the physical address or just pass in the actual virtual address * if the sps_mem_buffer is not needed. Note that if completion is * used, the virtual address won't be available and will need to be * calculated based on the offset of the physical address */ if (ev->event_id == SPS_EVENT_DESC_DONE) { pr_debug("buf = 0x%p, data = 0x%x\n", buf, *buf); if (ev->event_id == SPS_EVENT_DESC_DONE) complete(&dev->rx_msgq_notify); else dev_err(dev->dev, "%s: unknown event %d\n", __func__, ev->event_id); } pr_debug("iovec = (0x%x 0x%x 0x%x)\n", iovec->addr, iovec->size, iovec->flags); static void msm_slim_handle_rx(struct msm_slim_ctrl *dev, struct sps_event_notify *ev) { int ret = 0, index = 0; u32 mc = 0; u32 mt = 0; u32 buffer[10]; u8 msg_len = 0; } else { if (ev->event_id != SPS_EVENT_EOT) { dev_err(dev->dev, "%s: unknown event %d\n", __func__, ev->event_id); return; } do { ret = msm_slim_rx_msgq_get(dev, buffer, index); if (ret) { SLIM_ERR(dev, "rx_msgq_get() failed 0x%x\n", ret); return; } /* Traverse first byte of message for message length */ if (index++ == 0) { msg_len = *buffer & 0x1F; mt = (buffer[0] >> 5) & 0x7; mc = (buffer[0] >> 8) & 0xff; dev_dbg(dev->dev, "MC: %x, MT: %x\n", mc, mt); } msg_len = (msg_len < 4) ? 0 : (msg_len - 4); } while (msg_len); dev->rx_slim(dev, (u8 *)buffer); } static void msm_slim_rx_msgq_cb(struct sps_event_notify *notify) { struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)notify->user; /* is this manager controller or NGD controller? */ if (dev->ctrl.wakeup) msm_slim_rx_msgq_event(dev, notify); else msm_slim_handle_rx(dev, notify); } /* Queue up Rx message buffer */ Loading @@ -619,8 +641,6 @@ static int msm_slim_post_rx_msgq(struct msm_slim_ctrl *dev, int ix) u8 *virt_addr = mem->base + (4 * ix); phys_addr_t phys_addr = mem->phys_base + (4 * ix); pr_debug("index:%d, virt:0x%p\n", ix, virt_addr); ret = sps_transfer_one(pipe, phys_addr, 4, virt_addr, 0); if (ret) dev_err(dev->dev, "transfer_one() failed 0x%x, %d\n", ret, ix); Loading Loading @@ -664,8 +684,7 @@ err_exit: } int msm_slim_connect_endp(struct msm_slim_ctrl *dev, struct msm_slim_endp *endpoint, struct completion *notify) struct msm_slim_endp *endpoint) { int i, ret; struct sps_register_event sps_error_event; /* SPS_ERROR */ Loading @@ -680,11 +699,12 @@ int msm_slim_connect_endp(struct msm_slim_ctrl *dev, memset(&sps_descr_event, 0x00, sizeof(sps_descr_event)); if (notify) { if (endpoint == &dev->rx_msgq) { sps_descr_event.mode = SPS_TRIGGER_CALLBACK; sps_descr_event.options = SPS_O_EOT; sps_descr_event.user = (void *)dev; sps_descr_event.xfer_done = notify; sps_descr_event.callback = msm_slim_rx_msgq_cb; sps_descr_event.xfer_done = NULL; ret = sps_register_event(endpoint->sps, &sps_descr_event); if (ret) { Loading Loading @@ -788,7 +808,7 @@ static int msm_slim_init_rx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg) goto alloc_buffer_failed; } ret = msm_slim_connect_endp(dev, endpoint, notify); ret = msm_slim_connect_endp(dev, endpoint); if (!ret) return 0; Loading Loading @@ -851,7 +871,7 @@ static int msm_slim_init_tx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg) dev_err(dev->dev, "dma_alloc_coherent failed\n"); goto alloc_buffer_failed; } ret = msm_slim_connect_endp(dev, endpoint, NULL); ret = msm_slim_connect_endp(dev, endpoint); if (!ret) return 0; Loading drivers/slimbus/slim-msm.h +3 −3 Original line number Diff line number Diff line /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2015, 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 Loading Loading @@ -277,6 +277,7 @@ struct msm_slim_ctrl { int ipc_log_mask; bool sysfs_created; void *ipc_slimbus_log; void (*rx_slim)(struct msm_slim_ctrl *dev, u8 *buf); }; struct msm_sat_chan { Loading Loading @@ -387,8 +388,7 @@ int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem, void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg); int msm_slim_connect_endp(struct msm_slim_ctrl *dev, struct msm_slim_endp *endpoint, struct completion *notify); struct msm_slim_endp *endpoint); void msm_slim_disconnect_endp(struct msm_slim_ctrl *dev, struct msm_slim_endp *endpoint, enum msm_slim_msgq *msgq_flag); Loading Loading
drivers/slimbus/slim-msm-ngd.c +61 −92 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ enum ngd_status { NGD_LADDR = 1 << 1, }; static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf); static int ngd_slim_runtime_resume(struct device *device); static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart); Loading Loading @@ -122,7 +123,7 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) (4 * i)); SLIM_DBG(dev, "REG-RX data: %x\n", rx_buf[i]); } msm_slim_rx_enqueue(dev, rx_buf, len); ngd_slim_rx(dev, (u8 *)rx_buf); writel_relaxed(NGD_INT_RX_MSG_RCVD, ngd + NGD_INT_CLR); /* Loading @@ -132,8 +133,6 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) mb(); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) SLIM_WARN(dev, "direct msg rcvd with RX MSGQs\n"); else complete(&dev->rx_msgq_notify); } if (stat & NGD_INT_RECFG_DONE) { writel_relaxed(NGD_INT_RECFG_DONE, ngd + NGD_INT_CLR); Loading Loading @@ -588,7 +587,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) if (dev->state != MSM_CTRL_DOWN) { msm_slim_disconnect_endp(dev, &dev->tx_msgq, &dev->use_tx_msgqs); msm_slim_connect_endp(dev, &dev->tx_msgq, NULL); msm_slim_connect_endp(dev, &dev->tx_msgq); } } else if (!timeout) { ret = -ETIMEDOUT; Loading Loading @@ -907,8 +906,7 @@ static void ngd_slim_setup_msg_path(struct msm_slim_ctrl *dev) SLIM_WARN(dev, "pipe setup when RX msgq enabled?"); goto setup_tx_msg_path; } msm_slim_connect_endp(dev, &dev->rx_msgq, &dev->rx_msgq_notify); msm_slim_connect_endp(dev, &dev->rx_msgq); setup_tx_msg_path: if (dev->use_tx_msgqs == MSM_MSGQ_DISABLED) Loading @@ -917,74 +915,21 @@ setup_tx_msg_path: SLIM_WARN(dev, "pipe setup when TX msgq enabled?"); return; } msm_slim_connect_endp(dev, &dev->tx_msgq, NULL); msm_slim_connect_endp(dev, &dev->tx_msgq); } } static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf) { u8 mc, mt, len; int ret; u32 msgq_en = 1; len = buf[0] & 0x1F; mt = (buf[0] >> 5) & 0x7; mc = buf[1]; if (mc == SLIM_USR_MC_MASTER_CAPABILITY && mt == SLIM_MSG_MT_SRC_REFERRED_USER) { struct slim_msg_txn txn; int retries = 0; u8 wbuf[8]; txn.dt = SLIM_MSG_DEST_LOGICALADDR; txn.ec = 0; txn.rbuf = NULL; txn.mc = SLIM_USR_MC_REPORT_SATELLITE; txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER; txn.la = SLIM_LA_MGR; wbuf[0] = SAT_MAGIC_LSB; wbuf[1] = SAT_MAGIC_MSB; wbuf[2] = SAT_MSG_VER; wbuf[3] = SAT_MSG_PROT; txn.wbuf = wbuf; txn.len = 4; SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n"); if (dev->state >= MSM_CTRL_ASLEEP) { ngd_slim_setup_msg_path(dev); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) msgq_en |= NGD_CFG_RX_MSGQ_EN; if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED) msgq_en |= NGD_CFG_TX_MSGQ_EN; writel_relaxed(msgq_en, dev->base + NGD_BASE(dev->ctrl.nr, dev->ver)); /* make sure NGD MSG-Q config goes through */ mb(); } capability_retry: txn.rl = 8; ret = ngd_xfer_msg(&dev->ctrl, &txn); if (!ret) { enum msm_ctrl_state prev_state = dev->state; SLIM_INFO(dev, "SLIM SAT: capability exchange successful\n"); if (prev_state >= MSM_CTRL_ASLEEP) complete(&dev->reconf); else SLIM_ERR(dev, "SLIM: unexpected capability, state:%d\n", prev_state); /* ADSP SSR, send device_up notifications */ if (prev_state == MSM_CTRL_DOWN) complete(&dev->qmi.slave_notify); } else if (ret == -EIO) { SLIM_WARN(dev, "capability message NACKed, retrying\n"); if (retries < INIT_MX_RETRIES) { msleep(DEF_RETRY_MS); retries++; goto capability_retry; } } } mt == SLIM_MSG_MT_SRC_REFERRED_USER) complete(&dev->rx_msgq_notify); if (mc == SLIM_MSG_MC_REPLY_INFORMATION || mc == SLIM_MSG_MC_REPLY_VALUE) { u8 tid = buf[3]; Loading Loading @@ -1193,43 +1138,66 @@ static int ngd_slim_rx_msgq_thread(void *data) { struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)data; struct completion *notify = &dev->rx_msgq_notify; int ret = 0, index = 0; u32 mc = 0; u32 mt = 0; u32 buffer[10]; u8 msg_len = 0; int ret = 0; u32 msgq_en = 1; while (!kthread_should_stop()) { struct slim_msg_txn txn; int retries = 0; u8 wbuf[8]; set_current_state(TASK_INTERRUPTIBLE); wait_for_completion(notify); /* 1 irq notification per message */ if (dev->use_rx_msgqs != MSM_MSGQ_ENABLED) { msm_slim_rx_dequeue(dev, (u8 *)buffer); ngd_slim_rx(dev, (u8 *)buffer); continue; } do { ret = msm_slim_rx_msgq_get(dev, buffer, index); if (ret) { SLIM_ERR(dev, "rx_msgq_get() failed 0x%x\n", ret); break; txn.dt = SLIM_MSG_DEST_LOGICALADDR; txn.ec = 0; txn.rbuf = NULL; txn.mc = SLIM_USR_MC_REPORT_SATELLITE; txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER; txn.la = SLIM_LA_MGR; wbuf[0] = SAT_MAGIC_LSB; wbuf[1] = SAT_MAGIC_MSB; wbuf[2] = SAT_MSG_VER; wbuf[3] = SAT_MSG_PROT; txn.wbuf = wbuf; txn.len = 4; SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n"); if (dev->state >= MSM_CTRL_ASLEEP) { ngd_slim_setup_msg_path(dev); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) msgq_en |= NGD_CFG_RX_MSGQ_EN; if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED) msgq_en |= NGD_CFG_TX_MSGQ_EN; writel_relaxed(msgq_en, dev->base + NGD_BASE(dev->ctrl.nr, dev->ver)); /* make sure NGD MSG-Q config goes through */ mb(); } capability_retry: txn.rl = 8; ret = ngd_xfer_msg(&dev->ctrl, &txn); if (!ret) { enum msm_ctrl_state prev_state = dev->state; /* Traverse first byte of message for message length */ if (index++ == 0) { msg_len = *buffer & 0x1F; mt = (buffer[0] >> 5) & 0x7; mc = (buffer[0] >> 8) & 0xff; dev_dbg(dev->dev, "MC: %x, MT: %x\n", mc, mt); SLIM_INFO(dev, "SLIM SAT: capability exchange successful\n"); if (prev_state >= MSM_CTRL_ASLEEP) complete(&dev->reconf); else SLIM_ERR(dev, "SLIM: unexpected capability, state:%d\n", prev_state); /* ADSP SSR, send device_up notifications */ if (prev_state == MSM_CTRL_DOWN) complete(&dev->qmi.slave_notify); } else if (ret == -EIO) { SLIM_WARN(dev, "capability message NACKed, retrying\n"); if (retries < INIT_MX_RETRIES) { msleep(DEF_RETRY_MS); retries++; goto capability_retry; } msg_len = (msg_len < 4) ? 0 : (msg_len - 4); } while (msg_len); if (!msg_len) { index = 0; ngd_slim_rx(dev, (u8 *)buffer); } continue; } return 0; } Loading Loading @@ -1459,6 +1427,7 @@ static int ngd_slim_probe(struct platform_device *pdev) dev->ctrl.port_xfer = msm_slim_port_xfer; dev->ctrl.port_xfer_status = msm_slim_port_xfer_status; dev->bam_mem = bam_mem; dev->rx_slim = ngd_slim_rx; init_completion(&dev->reconf); init_completion(&dev->ctrl_up); Loading
drivers/slimbus/slim-msm.c +45 −25 Original line number Diff line number Diff line Loading @@ -578,33 +578,55 @@ u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len, static void msm_slim_rx_msgq_event(struct msm_slim_ctrl *dev, struct sps_event_notify *ev) { u32 *buf = ev->data.transfer.user; struct sps_iovec *iovec = &ev->data.transfer.iovec; /* * Note the virtual address needs to be offset by the same index * as the physical address or just pass in the actual virtual address * if the sps_mem_buffer is not needed. Note that if completion is * used, the virtual address won't be available and will need to be * calculated based on the offset of the physical address */ if (ev->event_id == SPS_EVENT_DESC_DONE) { pr_debug("buf = 0x%p, data = 0x%x\n", buf, *buf); if (ev->event_id == SPS_EVENT_DESC_DONE) complete(&dev->rx_msgq_notify); else dev_err(dev->dev, "%s: unknown event %d\n", __func__, ev->event_id); } pr_debug("iovec = (0x%x 0x%x 0x%x)\n", iovec->addr, iovec->size, iovec->flags); static void msm_slim_handle_rx(struct msm_slim_ctrl *dev, struct sps_event_notify *ev) { int ret = 0, index = 0; u32 mc = 0; u32 mt = 0; u32 buffer[10]; u8 msg_len = 0; } else { if (ev->event_id != SPS_EVENT_EOT) { dev_err(dev->dev, "%s: unknown event %d\n", __func__, ev->event_id); return; } do { ret = msm_slim_rx_msgq_get(dev, buffer, index); if (ret) { SLIM_ERR(dev, "rx_msgq_get() failed 0x%x\n", ret); return; } /* Traverse first byte of message for message length */ if (index++ == 0) { msg_len = *buffer & 0x1F; mt = (buffer[0] >> 5) & 0x7; mc = (buffer[0] >> 8) & 0xff; dev_dbg(dev->dev, "MC: %x, MT: %x\n", mc, mt); } msg_len = (msg_len < 4) ? 0 : (msg_len - 4); } while (msg_len); dev->rx_slim(dev, (u8 *)buffer); } static void msm_slim_rx_msgq_cb(struct sps_event_notify *notify) { struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)notify->user; /* is this manager controller or NGD controller? */ if (dev->ctrl.wakeup) msm_slim_rx_msgq_event(dev, notify); else msm_slim_handle_rx(dev, notify); } /* Queue up Rx message buffer */ Loading @@ -619,8 +641,6 @@ static int msm_slim_post_rx_msgq(struct msm_slim_ctrl *dev, int ix) u8 *virt_addr = mem->base + (4 * ix); phys_addr_t phys_addr = mem->phys_base + (4 * ix); pr_debug("index:%d, virt:0x%p\n", ix, virt_addr); ret = sps_transfer_one(pipe, phys_addr, 4, virt_addr, 0); if (ret) dev_err(dev->dev, "transfer_one() failed 0x%x, %d\n", ret, ix); Loading Loading @@ -664,8 +684,7 @@ err_exit: } int msm_slim_connect_endp(struct msm_slim_ctrl *dev, struct msm_slim_endp *endpoint, struct completion *notify) struct msm_slim_endp *endpoint) { int i, ret; struct sps_register_event sps_error_event; /* SPS_ERROR */ Loading @@ -680,11 +699,12 @@ int msm_slim_connect_endp(struct msm_slim_ctrl *dev, memset(&sps_descr_event, 0x00, sizeof(sps_descr_event)); if (notify) { if (endpoint == &dev->rx_msgq) { sps_descr_event.mode = SPS_TRIGGER_CALLBACK; sps_descr_event.options = SPS_O_EOT; sps_descr_event.user = (void *)dev; sps_descr_event.xfer_done = notify; sps_descr_event.callback = msm_slim_rx_msgq_cb; sps_descr_event.xfer_done = NULL; ret = sps_register_event(endpoint->sps, &sps_descr_event); if (ret) { Loading Loading @@ -788,7 +808,7 @@ static int msm_slim_init_rx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg) goto alloc_buffer_failed; } ret = msm_slim_connect_endp(dev, endpoint, notify); ret = msm_slim_connect_endp(dev, endpoint); if (!ret) return 0; Loading Loading @@ -851,7 +871,7 @@ static int msm_slim_init_tx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg) dev_err(dev->dev, "dma_alloc_coherent failed\n"); goto alloc_buffer_failed; } ret = msm_slim_connect_endp(dev, endpoint, NULL); ret = msm_slim_connect_endp(dev, endpoint); if (!ret) return 0; Loading
drivers/slimbus/slim-msm.h +3 −3 Original line number Diff line number Diff line /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2015, 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 Loading Loading @@ -277,6 +277,7 @@ struct msm_slim_ctrl { int ipc_log_mask; bool sysfs_created; void *ipc_slimbus_log; void (*rx_slim)(struct msm_slim_ctrl *dev, u8 *buf); }; struct msm_sat_chan { Loading Loading @@ -387,8 +388,7 @@ int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem, void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg); int msm_slim_connect_endp(struct msm_slim_ctrl *dev, struct msm_slim_endp *endpoint, struct completion *notify); struct msm_slim_endp *endpoint); void msm_slim_disconnect_endp(struct msm_slim_ctrl *dev, struct msm_slim_endp *endpoint, enum msm_slim_msgq *msgq_flag); Loading