Loading Documentation/devicetree/bindings/qdsp/msm-fastrpc.txt +9 −5 Original line number Original line Diff line number Diff line Loading @@ -9,10 +9,13 @@ other tasks. Required properties: Required properties: - compatible : Must be "qcom,msm-fastrpc-adsp" - compatible : Must be "qcom,msm-fastrpc-adsp" Optional properties: - qcom,fastrpc-glink: Flag to use glink instead of smd for IPC Optional subnodes: Optional subnodes: - qcom,msm_fastrpc_compute_cb : Child nodes representing the compute context - qcom,msm_fastrpc_compute_cb : Child nodes representing the compute context banks banks Subnode properties: Subnode Required properties: - compatible : Must be "qcom,msm-fastrpc-compute-cb" - compatible : Must be "qcom,msm-fastrpc-compute-cb" - label: Label describing the channel this context bank belongs to - label: Label describing the channel this context bank belongs to - iommus : A list of phandle and IOMMU specifier pairs that describe the - iommus : A list of phandle and IOMMU specifier pairs that describe the Loading @@ -21,6 +24,7 @@ Subnode properties: Example: Example: qcom,msm_fastrpc { qcom,msm_fastrpc { compatible = "qcom,msm-fastrpc-adsp"; compatible = "qcom,msm-fastrpc-adsp"; qcom,fastrpc-glink; qcom,msm_fastrpc_compute_cb_1 { qcom,msm_fastrpc_compute_cb_1 { compatible = "qcom,msm-fastrpc-compute-cb"; compatible = "qcom,msm-fastrpc-compute-cb"; Loading arch/arm/boot/dts/qcom/msmcobalt.dtsi +46 −0 Original line number Original line Diff line number Diff line Loading @@ -929,6 +929,52 @@ }; }; }; }; qcom,msm_fastrpc { compatible = "qcom,msm-fastrpc-adsp"; qcom,fastrpc-glink; qcom,msm_fastrpc_compute_cb1 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 8>; }; qcom,msm_fastrpc_compute_cb2 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 9>; }; qcom,msm_fastrpc_compute_cb3 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 10>; }; qcom,msm_fastrpc_compute_cb4 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 11>; }; qcom,msm_fastrpc_compute_cb5 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 12>; }; qcom,msm_fastrpc_compute_cb6 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 5>; }; qcom,msm_fastrpc_compute_cb7 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 6>; }; qcom,msm_fastrpc_compute_cb8 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 7>; }; }; rpm_bus: qcom,rpm-smd { rpm_bus: qcom,rpm-smd { compatible = "qcom,rpm-glink"; compatible = "qcom,rpm-glink"; qcom,glink-edge = "rpm"; qcom,glink-edge = "rpm"; Loading drivers/char/adsprpc.c +160 −29 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <linux/msm_ion.h> #include <linux/msm_ion.h> #include <soc/qcom/secure_buffer.h> #include <soc/qcom/secure_buffer.h> #include <soc/qcom/smd.h> #include <soc/qcom/smd.h> #include <soc/qcom/glink.h> #include <soc/qcom/subsystem_notif.h> #include <soc/qcom/subsystem_notif.h> #include <soc/qcom/subsystem_restart.h> #include <soc/qcom/subsystem_restart.h> #include <linux/scatterlist.h> #include <linux/scatterlist.h> Loading Loading @@ -137,6 +138,7 @@ struct smq_invoke_ctx { uint32_t sc; uint32_t sc; struct overlap *overs; struct overlap *overs; struct overlap **overps; struct overlap **overps; struct smq_msg msg; }; }; struct fastrpc_ctx_lst { struct fastrpc_ctx_lst { Loading @@ -159,7 +161,7 @@ struct fastrpc_session_ctx { struct fastrpc_channel_ctx { struct fastrpc_channel_ctx { char *name; char *name; char *subsys; char *subsys; smd_channel_t *chan; void *chan; struct device *dev; struct device *dev; struct fastrpc_session_ctx session[NUM_SESSIONS]; struct fastrpc_session_ctx session[NUM_SESSIONS]; struct completion work; struct completion work; Loading @@ -174,6 +176,10 @@ struct fastrpc_channel_ctx { int vmid; int vmid; int ramdumpenabled; int ramdumpenabled; void *remoteheap_ramdump_dev; void *remoteheap_ramdump_dev; struct glink_link_info link_info; void *link_notify_handle; struct glink_open_config cfg; char *edge; }; }; struct fastrpc_apps { struct fastrpc_apps { Loading @@ -189,6 +195,7 @@ struct fastrpc_apps { spinlock_t hlock; spinlock_t hlock; struct ion_client *client; struct ion_client *client; struct device *dev; struct device *dev; bool glink; }; }; struct fastrpc_mmap { struct fastrpc_mmap { Loading Loading @@ -231,14 +238,15 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = { .name = "adsprpc-smd", .name = "adsprpc-smd", .subsys = "adsp", .subsys = "adsp", .channel = SMD_APPS_QDSP, .channel = SMD_APPS_QDSP, .edge = "lpass", }, }, { { .name = "sdsprpc-smd", .name = "sdsprpc-smd", .subsys = "dsps", .subsys = "dsps", .channel = SMD_APPS_DSPS, .channel = SMD_APPS_DSPS, .edge = "dsps", .vmid = VMID_SSC_Q6, .vmid = VMID_SSC_Q6, }, }, }; }; static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache) static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache) Loading Loading @@ -1164,31 +1172,40 @@ static void inv_args(struct smq_invoke_ctx *ctx) static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, uint32_t kernel, uint32_t handle) uint32_t kernel, uint32_t handle) { { struct smq_msg msg = {0}; struct smq_msg *msg = &ctx->msg; struct fastrpc_file *fl = ctx->fl; struct fastrpc_file *fl = ctx->fl; int err = 0, len; int err = 0, len; VERIFY(err, 0 != fl->apps->channel[fl->cid].chan); VERIFY(err, 0 != fl->apps->channel[fl->cid].chan); if (err) if (err) goto bail; goto bail; msg.pid = current->tgid; msg->pid = current->tgid; msg.tid = current->pid; msg->tid = current->pid; if (kernel) if (kernel) msg.pid = 0; msg->pid = 0; msg.invoke.header.ctx = ptr_to_uint64(ctx); msg->invoke.header.ctx = ptr_to_uint64(ctx); msg.invoke.header.handle = handle; msg->invoke.header.handle = handle; msg.invoke.header.sc = ctx->sc; msg->invoke.header.sc = ctx->sc; msg.invoke.page.addr = ctx->buf ? ctx->buf->phys : 0; msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0; msg.invoke.page.size = buf_page_size(ctx->used); msg->invoke.page.size = buf_page_size(ctx->used); if (fl->apps->glink) { err = glink_tx(fl->apps->channel[fl->cid].chan, (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg), GLINK_TX_REQ_INTENT); } else { spin_lock(&fl->apps->hlock); spin_lock(&fl->apps->hlock); len = smd_write(fl->apps->channel[fl->cid].chan, &msg, sizeof(msg)); len = smd_write((smd_channel_t *) fl->apps->channel[fl->cid].chan, msg, sizeof(*msg)); spin_unlock(&fl->apps->hlock); spin_unlock(&fl->apps->hlock); VERIFY(err, len == sizeof(msg)); VERIFY(err, len == sizeof(*msg)); } bail: bail: return err; return err; } } static void fastrpc_read_handler(int cid) static void fastrpc_smd_read_handler(int cid) { { struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa; struct smq_invoke_rsp rsp = {0}; struct smq_invoke_rsp rsp = {0}; Loading Loading @@ -1216,7 +1233,7 @@ static void smd_event_handler(void *priv, unsigned event) fastrpc_notify_drivers(me, cid); fastrpc_notify_drivers(me, cid); break; break; case SMD_EVENT_DATA: case SMD_EVENT_DATA: fastrpc_read_handler(cid); fastrpc_smd_read_handler(cid); break; break; } } } } Loading Loading @@ -1334,7 +1351,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, int pageslen; int pageslen; } inbuf; } inbuf; inbuf.pgid = current->tgid; inbuf.pgid = current->tgid; inbuf.namelen = strlen(current->comm); inbuf.namelen = strlen(current->comm) + 1; inbuf.filelen = init->filelen; inbuf.filelen = init->filelen; VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, init->file, VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, init->file, init->filelen, mflags, &file)); init->filelen, mflags, &file)); Loading Loading @@ -1632,7 +1649,12 @@ static void fastrpc_channel_close(struct kref *kref) int cid; int cid; ctx = container_of(kref, struct fastrpc_channel_ctx, kref); ctx = container_of(kref, struct fastrpc_channel_ctx, kref); if (!me->glink) { smd_close(ctx->chan); smd_close(ctx->chan); } else { glink_unregister_link_state_cb(ctx->link_notify_handle); glink_close(ctx->chan); } ctx->chan = 0; ctx->chan = 0; mutex_unlock(&me->smd_mutex); mutex_unlock(&me->smd_mutex); cid = ctx - &gcinfo[0]; cid = ctx - &gcinfo[0]; Loading Loading @@ -1707,6 +1729,49 @@ static int fastrpc_session_free(struct fastrpc_channel_ctx *chan, int session) return err; return err; } } bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv, size_t size) { if (0 != glink_queue_rx_intent(h, NULL, size)) return false; return true; } void fastrpc_glink_notify_tx_done(void *handle, const void *priv, const void *pkt_priv, const void *ptr) { } void fastrpc_glink_notify_rx(void *handle, const void *priv, const void *pkt_priv, const void *ptr, size_t size) { struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr; int len = size; while (len >= sizeof(*rsp) && rsp) { context_notify_user(uint64_to_ptr(rsp->ctx), rsp->retval); rsp++; len = len - sizeof(*rsp); } glink_rx_done(handle, ptr, true); } void fastrpc_glink_notify_state(void *handle, const void *priv, unsigned event) { struct fastrpc_apps *me = &gfa; int cid = (int)(uintptr_t)priv; switch (event) { case GLINK_CONNECTED: complete(&me->channel[cid].work); break; case GLINK_LOCAL_DISCONNECTED: break; case GLINK_REMOTE_DISCONNECTED: fastrpc_notify_drivers(me, cid); break; } } static int fastrpc_device_release(struct inode *inode, struct file *file) static int fastrpc_device_release(struct inode *inode, struct file *file) { { struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa; Loading @@ -1725,6 +1790,55 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) return 0; return 0; } } static void fastrpc_glink_register_cb(struct glink_link_state_cb_info *cb_info, void *priv) { switch (cb_info->link_state) { case GLINK_LINK_STATE_UP: if (priv) complete(priv); break; case GLINK_LINK_STATE_DOWN: break; default: pr_err("adsprpc: unknown glnk state %d\n", cb_info->link_state); break; } } static int fastrpc_glink_open(int cid, struct fastrpc_apps *me) { int err = 0; struct glink_open_config *cfg = &me->channel[cid].cfg; struct glink_link_info *link_info = &me->channel[cid].link_info; link_info->edge = gcinfo[cid].edge; link_info->transport = "smem"; link_info->glink_link_state_notif_cb = fastrpc_glink_register_cb; me->channel[cid].link_notify_handle = glink_register_link_state_cb( &me->channel[cid].link_info, (void *)(&me->channel[cid].work)); VERIFY(err, !IS_ERR_OR_NULL(me->channel[cid].link_notify_handle)); if (err) goto bail; VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work, RPC_TIMEOUT)); if (err) goto bail; cfg->priv = (void *)(uintptr_t)cid; cfg->edge = gcinfo[cid].edge; cfg->name = FASTRPC_GLINK_GUID; cfg->notify_rx = fastrpc_glink_notify_rx; cfg->notify_tx_done = fastrpc_glink_notify_tx_done; cfg->notify_state = fastrpc_glink_notify_state; cfg->notify_rx_intent_req = fastrpc_glink_notify_rx_intent_req; VERIFY(err, 0 != (me->channel[cid].chan = glink_open(cfg))); bail: return err; } static int fastrpc_device_open(struct inode *inode, struct file *filp) static int fastrpc_device_open(struct inode *inode, struct file *filp) { { int cid = MINOR(inode->i_rdev); int cid = MINOR(inode->i_rdev); Loading Loading @@ -1756,17 +1870,24 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->ssrcount = me->channel[cid].ssrcount; fl->ssrcount = me->channel[cid].ssrcount; if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) || if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) || (me->channel[cid].chan == 0)) { (me->channel[cid].chan == 0)) { if (me->glink) { VERIFY(err, 0 == fastrpc_glink_open(cid, me)); } else { VERIFY(err, !smd_named_open_on_edge(FASTRPC_SMD_GUID, VERIFY(err, !smd_named_open_on_edge(FASTRPC_SMD_GUID, gcinfo[cid].channel, gcinfo[cid].channel, &me->channel[cid].chan, (smd_channel_t **)&me->channel[cid].chan, (void *)(uintptr_t)cid, (void *)(uintptr_t)cid, smd_event_handler)); smd_event_handler)); } if (err) if (err) goto bail; goto bail; VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work, VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work, RPC_TIMEOUT)); RPC_TIMEOUT)); if (err) if (err) { me->channel[cid].chan = 0; goto bail; goto bail; } kref_init(&me->channel[cid].kref); kref_init(&me->channel[cid].kref); pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name, pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name, MAJOR(me->dev_no), cid); MAJOR(me->dev_no), cid); Loading Loading @@ -1884,10 +2005,16 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, mutex_lock(&me->smd_mutex); mutex_lock(&me->smd_mutex); ctx->ssrcount++; ctx->ssrcount++; if (ctx->chan) { if (ctx->chan) { if (me->glink) { glink_unregister_link_state_cb( ctx->link_notify_handle); glink_close(ctx->chan); } else { smd_close(ctx->chan); smd_close(ctx->chan); } ctx->chan = 0; ctx->chan = 0; pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name, pr_info("'restart notifier: closed /dev/%s c %d %d'\n", MAJOR(me->dev_no), cid); gcinfo[cid].name, MAJOR(me->dev_no), cid); } } mutex_unlock(&me->smd_mutex); mutex_unlock(&me->smd_mutex); fastrpc_notify_drivers(me, cid); fastrpc_notify_drivers(me, cid); Loading Loading @@ -1956,6 +2083,7 @@ static int fastrpc_cb_probe(struct device *dev) VERIFY(err, chan->sesscount < NUM_SESSIONS); VERIFY(err, chan->sesscount < NUM_SESSIONS); if (err) if (err) goto bail; goto bail; VERIFY(err, !of_parse_phandle_with_args(dev->of_node, "iommus", VERIFY(err, !of_parse_phandle_with_args(dev->of_node, "iommus", "#iommu-cells", 0, &iommuspec)); "#iommu-cells", 0, &iommuspec)); if (err) if (err) Loading Loading @@ -2096,6 +2224,9 @@ static int fastrpc_probe(struct platform_device *pdev) return 0; return 0; } } me->glink = of_property_read_bool(dev->of_node, "qcom,fastrpc-glink"); pr_info("adsprpc: channel link type: %d\n", me->glink); VERIFY(err, !of_platform_populate(pdev->dev.of_node, VERIFY(err, !of_platform_populate(pdev->dev.of_node, fastrpc_match_table, fastrpc_match_table, NULL, &pdev->dev)); NULL, &pdev->dev)); Loading drivers/char/adsprpc_shared.h +2 −1 Original line number Original line Diff line number Diff line /* /* * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading @@ -22,6 +22,7 @@ #define FASTRPC_IOCTL_INVOKE_FD _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd) #define FASTRPC_IOCTL_INVOKE_FD _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd) #define FASTRPC_IOCTL_SETMODE _IOWR('R', 5, uint32_t) #define FASTRPC_IOCTL_SETMODE _IOWR('R', 5, uint32_t) #define FASTRPC_IOCTL_INIT _IOWR('R', 6, struct fastrpc_ioctl_init) #define FASTRPC_IOCTL_INIT _IOWR('R', 6, struct fastrpc_ioctl_init) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" #define DEVICE_NAME "adsprpc-smd" #define DEVICE_NAME "adsprpc-smd" Loading Loading
Documentation/devicetree/bindings/qdsp/msm-fastrpc.txt +9 −5 Original line number Original line Diff line number Diff line Loading @@ -9,10 +9,13 @@ other tasks. Required properties: Required properties: - compatible : Must be "qcom,msm-fastrpc-adsp" - compatible : Must be "qcom,msm-fastrpc-adsp" Optional properties: - qcom,fastrpc-glink: Flag to use glink instead of smd for IPC Optional subnodes: Optional subnodes: - qcom,msm_fastrpc_compute_cb : Child nodes representing the compute context - qcom,msm_fastrpc_compute_cb : Child nodes representing the compute context banks banks Subnode properties: Subnode Required properties: - compatible : Must be "qcom,msm-fastrpc-compute-cb" - compatible : Must be "qcom,msm-fastrpc-compute-cb" - label: Label describing the channel this context bank belongs to - label: Label describing the channel this context bank belongs to - iommus : A list of phandle and IOMMU specifier pairs that describe the - iommus : A list of phandle and IOMMU specifier pairs that describe the Loading @@ -21,6 +24,7 @@ Subnode properties: Example: Example: qcom,msm_fastrpc { qcom,msm_fastrpc { compatible = "qcom,msm-fastrpc-adsp"; compatible = "qcom,msm-fastrpc-adsp"; qcom,fastrpc-glink; qcom,msm_fastrpc_compute_cb_1 { qcom,msm_fastrpc_compute_cb_1 { compatible = "qcom,msm-fastrpc-compute-cb"; compatible = "qcom,msm-fastrpc-compute-cb"; Loading
arch/arm/boot/dts/qcom/msmcobalt.dtsi +46 −0 Original line number Original line Diff line number Diff line Loading @@ -929,6 +929,52 @@ }; }; }; }; qcom,msm_fastrpc { compatible = "qcom,msm-fastrpc-adsp"; qcom,fastrpc-glink; qcom,msm_fastrpc_compute_cb1 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 8>; }; qcom,msm_fastrpc_compute_cb2 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 9>; }; qcom,msm_fastrpc_compute_cb3 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 10>; }; qcom,msm_fastrpc_compute_cb4 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 11>; }; qcom,msm_fastrpc_compute_cb5 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 12>; }; qcom,msm_fastrpc_compute_cb6 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 5>; }; qcom,msm_fastrpc_compute_cb7 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 6>; }; qcom,msm_fastrpc_compute_cb8 { compatible = "qcom,msm-fastrpc-compute-cb"; label = "adsprpc-smd"; iommus = <&lpass_q6_smmu 7>; }; }; rpm_bus: qcom,rpm-smd { rpm_bus: qcom,rpm-smd { compatible = "qcom,rpm-glink"; compatible = "qcom,rpm-glink"; qcom,glink-edge = "rpm"; qcom,glink-edge = "rpm"; Loading
drivers/char/adsprpc.c +160 −29 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <linux/msm_ion.h> #include <linux/msm_ion.h> #include <soc/qcom/secure_buffer.h> #include <soc/qcom/secure_buffer.h> #include <soc/qcom/smd.h> #include <soc/qcom/smd.h> #include <soc/qcom/glink.h> #include <soc/qcom/subsystem_notif.h> #include <soc/qcom/subsystem_notif.h> #include <soc/qcom/subsystem_restart.h> #include <soc/qcom/subsystem_restart.h> #include <linux/scatterlist.h> #include <linux/scatterlist.h> Loading Loading @@ -137,6 +138,7 @@ struct smq_invoke_ctx { uint32_t sc; uint32_t sc; struct overlap *overs; struct overlap *overs; struct overlap **overps; struct overlap **overps; struct smq_msg msg; }; }; struct fastrpc_ctx_lst { struct fastrpc_ctx_lst { Loading @@ -159,7 +161,7 @@ struct fastrpc_session_ctx { struct fastrpc_channel_ctx { struct fastrpc_channel_ctx { char *name; char *name; char *subsys; char *subsys; smd_channel_t *chan; void *chan; struct device *dev; struct device *dev; struct fastrpc_session_ctx session[NUM_SESSIONS]; struct fastrpc_session_ctx session[NUM_SESSIONS]; struct completion work; struct completion work; Loading @@ -174,6 +176,10 @@ struct fastrpc_channel_ctx { int vmid; int vmid; int ramdumpenabled; int ramdumpenabled; void *remoteheap_ramdump_dev; void *remoteheap_ramdump_dev; struct glink_link_info link_info; void *link_notify_handle; struct glink_open_config cfg; char *edge; }; }; struct fastrpc_apps { struct fastrpc_apps { Loading @@ -189,6 +195,7 @@ struct fastrpc_apps { spinlock_t hlock; spinlock_t hlock; struct ion_client *client; struct ion_client *client; struct device *dev; struct device *dev; bool glink; }; }; struct fastrpc_mmap { struct fastrpc_mmap { Loading Loading @@ -231,14 +238,15 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = { .name = "adsprpc-smd", .name = "adsprpc-smd", .subsys = "adsp", .subsys = "adsp", .channel = SMD_APPS_QDSP, .channel = SMD_APPS_QDSP, .edge = "lpass", }, }, { { .name = "sdsprpc-smd", .name = "sdsprpc-smd", .subsys = "dsps", .subsys = "dsps", .channel = SMD_APPS_DSPS, .channel = SMD_APPS_DSPS, .edge = "dsps", .vmid = VMID_SSC_Q6, .vmid = VMID_SSC_Q6, }, }, }; }; static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache) static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache) Loading Loading @@ -1164,31 +1172,40 @@ static void inv_args(struct smq_invoke_ctx *ctx) static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, uint32_t kernel, uint32_t handle) uint32_t kernel, uint32_t handle) { { struct smq_msg msg = {0}; struct smq_msg *msg = &ctx->msg; struct fastrpc_file *fl = ctx->fl; struct fastrpc_file *fl = ctx->fl; int err = 0, len; int err = 0, len; VERIFY(err, 0 != fl->apps->channel[fl->cid].chan); VERIFY(err, 0 != fl->apps->channel[fl->cid].chan); if (err) if (err) goto bail; goto bail; msg.pid = current->tgid; msg->pid = current->tgid; msg.tid = current->pid; msg->tid = current->pid; if (kernel) if (kernel) msg.pid = 0; msg->pid = 0; msg.invoke.header.ctx = ptr_to_uint64(ctx); msg->invoke.header.ctx = ptr_to_uint64(ctx); msg.invoke.header.handle = handle; msg->invoke.header.handle = handle; msg.invoke.header.sc = ctx->sc; msg->invoke.header.sc = ctx->sc; msg.invoke.page.addr = ctx->buf ? ctx->buf->phys : 0; msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0; msg.invoke.page.size = buf_page_size(ctx->used); msg->invoke.page.size = buf_page_size(ctx->used); if (fl->apps->glink) { err = glink_tx(fl->apps->channel[fl->cid].chan, (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg), GLINK_TX_REQ_INTENT); } else { spin_lock(&fl->apps->hlock); spin_lock(&fl->apps->hlock); len = smd_write(fl->apps->channel[fl->cid].chan, &msg, sizeof(msg)); len = smd_write((smd_channel_t *) fl->apps->channel[fl->cid].chan, msg, sizeof(*msg)); spin_unlock(&fl->apps->hlock); spin_unlock(&fl->apps->hlock); VERIFY(err, len == sizeof(msg)); VERIFY(err, len == sizeof(*msg)); } bail: bail: return err; return err; } } static void fastrpc_read_handler(int cid) static void fastrpc_smd_read_handler(int cid) { { struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa; struct smq_invoke_rsp rsp = {0}; struct smq_invoke_rsp rsp = {0}; Loading Loading @@ -1216,7 +1233,7 @@ static void smd_event_handler(void *priv, unsigned event) fastrpc_notify_drivers(me, cid); fastrpc_notify_drivers(me, cid); break; break; case SMD_EVENT_DATA: case SMD_EVENT_DATA: fastrpc_read_handler(cid); fastrpc_smd_read_handler(cid); break; break; } } } } Loading Loading @@ -1334,7 +1351,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, int pageslen; int pageslen; } inbuf; } inbuf; inbuf.pgid = current->tgid; inbuf.pgid = current->tgid; inbuf.namelen = strlen(current->comm); inbuf.namelen = strlen(current->comm) + 1; inbuf.filelen = init->filelen; inbuf.filelen = init->filelen; VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, init->file, VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, init->file, init->filelen, mflags, &file)); init->filelen, mflags, &file)); Loading Loading @@ -1632,7 +1649,12 @@ static void fastrpc_channel_close(struct kref *kref) int cid; int cid; ctx = container_of(kref, struct fastrpc_channel_ctx, kref); ctx = container_of(kref, struct fastrpc_channel_ctx, kref); if (!me->glink) { smd_close(ctx->chan); smd_close(ctx->chan); } else { glink_unregister_link_state_cb(ctx->link_notify_handle); glink_close(ctx->chan); } ctx->chan = 0; ctx->chan = 0; mutex_unlock(&me->smd_mutex); mutex_unlock(&me->smd_mutex); cid = ctx - &gcinfo[0]; cid = ctx - &gcinfo[0]; Loading Loading @@ -1707,6 +1729,49 @@ static int fastrpc_session_free(struct fastrpc_channel_ctx *chan, int session) return err; return err; } } bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv, size_t size) { if (0 != glink_queue_rx_intent(h, NULL, size)) return false; return true; } void fastrpc_glink_notify_tx_done(void *handle, const void *priv, const void *pkt_priv, const void *ptr) { } void fastrpc_glink_notify_rx(void *handle, const void *priv, const void *pkt_priv, const void *ptr, size_t size) { struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr; int len = size; while (len >= sizeof(*rsp) && rsp) { context_notify_user(uint64_to_ptr(rsp->ctx), rsp->retval); rsp++; len = len - sizeof(*rsp); } glink_rx_done(handle, ptr, true); } void fastrpc_glink_notify_state(void *handle, const void *priv, unsigned event) { struct fastrpc_apps *me = &gfa; int cid = (int)(uintptr_t)priv; switch (event) { case GLINK_CONNECTED: complete(&me->channel[cid].work); break; case GLINK_LOCAL_DISCONNECTED: break; case GLINK_REMOTE_DISCONNECTED: fastrpc_notify_drivers(me, cid); break; } } static int fastrpc_device_release(struct inode *inode, struct file *file) static int fastrpc_device_release(struct inode *inode, struct file *file) { { struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa; Loading @@ -1725,6 +1790,55 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) return 0; return 0; } } static void fastrpc_glink_register_cb(struct glink_link_state_cb_info *cb_info, void *priv) { switch (cb_info->link_state) { case GLINK_LINK_STATE_UP: if (priv) complete(priv); break; case GLINK_LINK_STATE_DOWN: break; default: pr_err("adsprpc: unknown glnk state %d\n", cb_info->link_state); break; } } static int fastrpc_glink_open(int cid, struct fastrpc_apps *me) { int err = 0; struct glink_open_config *cfg = &me->channel[cid].cfg; struct glink_link_info *link_info = &me->channel[cid].link_info; link_info->edge = gcinfo[cid].edge; link_info->transport = "smem"; link_info->glink_link_state_notif_cb = fastrpc_glink_register_cb; me->channel[cid].link_notify_handle = glink_register_link_state_cb( &me->channel[cid].link_info, (void *)(&me->channel[cid].work)); VERIFY(err, !IS_ERR_OR_NULL(me->channel[cid].link_notify_handle)); if (err) goto bail; VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work, RPC_TIMEOUT)); if (err) goto bail; cfg->priv = (void *)(uintptr_t)cid; cfg->edge = gcinfo[cid].edge; cfg->name = FASTRPC_GLINK_GUID; cfg->notify_rx = fastrpc_glink_notify_rx; cfg->notify_tx_done = fastrpc_glink_notify_tx_done; cfg->notify_state = fastrpc_glink_notify_state; cfg->notify_rx_intent_req = fastrpc_glink_notify_rx_intent_req; VERIFY(err, 0 != (me->channel[cid].chan = glink_open(cfg))); bail: return err; } static int fastrpc_device_open(struct inode *inode, struct file *filp) static int fastrpc_device_open(struct inode *inode, struct file *filp) { { int cid = MINOR(inode->i_rdev); int cid = MINOR(inode->i_rdev); Loading Loading @@ -1756,17 +1870,24 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->ssrcount = me->channel[cid].ssrcount; fl->ssrcount = me->channel[cid].ssrcount; if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) || if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) || (me->channel[cid].chan == 0)) { (me->channel[cid].chan == 0)) { if (me->glink) { VERIFY(err, 0 == fastrpc_glink_open(cid, me)); } else { VERIFY(err, !smd_named_open_on_edge(FASTRPC_SMD_GUID, VERIFY(err, !smd_named_open_on_edge(FASTRPC_SMD_GUID, gcinfo[cid].channel, gcinfo[cid].channel, &me->channel[cid].chan, (smd_channel_t **)&me->channel[cid].chan, (void *)(uintptr_t)cid, (void *)(uintptr_t)cid, smd_event_handler)); smd_event_handler)); } if (err) if (err) goto bail; goto bail; VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work, VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work, RPC_TIMEOUT)); RPC_TIMEOUT)); if (err) if (err) { me->channel[cid].chan = 0; goto bail; goto bail; } kref_init(&me->channel[cid].kref); kref_init(&me->channel[cid].kref); pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name, pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name, MAJOR(me->dev_no), cid); MAJOR(me->dev_no), cid); Loading Loading @@ -1884,10 +2005,16 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, mutex_lock(&me->smd_mutex); mutex_lock(&me->smd_mutex); ctx->ssrcount++; ctx->ssrcount++; if (ctx->chan) { if (ctx->chan) { if (me->glink) { glink_unregister_link_state_cb( ctx->link_notify_handle); glink_close(ctx->chan); } else { smd_close(ctx->chan); smd_close(ctx->chan); } ctx->chan = 0; ctx->chan = 0; pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name, pr_info("'restart notifier: closed /dev/%s c %d %d'\n", MAJOR(me->dev_no), cid); gcinfo[cid].name, MAJOR(me->dev_no), cid); } } mutex_unlock(&me->smd_mutex); mutex_unlock(&me->smd_mutex); fastrpc_notify_drivers(me, cid); fastrpc_notify_drivers(me, cid); Loading Loading @@ -1956,6 +2083,7 @@ static int fastrpc_cb_probe(struct device *dev) VERIFY(err, chan->sesscount < NUM_SESSIONS); VERIFY(err, chan->sesscount < NUM_SESSIONS); if (err) if (err) goto bail; goto bail; VERIFY(err, !of_parse_phandle_with_args(dev->of_node, "iommus", VERIFY(err, !of_parse_phandle_with_args(dev->of_node, "iommus", "#iommu-cells", 0, &iommuspec)); "#iommu-cells", 0, &iommuspec)); if (err) if (err) Loading Loading @@ -2096,6 +2224,9 @@ static int fastrpc_probe(struct platform_device *pdev) return 0; return 0; } } me->glink = of_property_read_bool(dev->of_node, "qcom,fastrpc-glink"); pr_info("adsprpc: channel link type: %d\n", me->glink); VERIFY(err, !of_platform_populate(pdev->dev.of_node, VERIFY(err, !of_platform_populate(pdev->dev.of_node, fastrpc_match_table, fastrpc_match_table, NULL, &pdev->dev)); NULL, &pdev->dev)); Loading
drivers/char/adsprpc_shared.h +2 −1 Original line number Original line Diff line number Diff line /* /* * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading @@ -22,6 +22,7 @@ #define FASTRPC_IOCTL_INVOKE_FD _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd) #define FASTRPC_IOCTL_INVOKE_FD _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd) #define FASTRPC_IOCTL_SETMODE _IOWR('R', 5, uint32_t) #define FASTRPC_IOCTL_SETMODE _IOWR('R', 5, uint32_t) #define FASTRPC_IOCTL_INIT _IOWR('R', 6, struct fastrpc_ioctl_init) #define FASTRPC_IOCTL_INIT _IOWR('R', 6, struct fastrpc_ioctl_init) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" #define DEVICE_NAME "adsprpc-smd" #define DEVICE_NAME "adsprpc-smd" Loading