Loading drivers/soc/qcom/glink.c +47 −9 Original line number Diff line number Diff line Loading @@ -371,10 +371,10 @@ static struct channel_ctx *ch_name_to_ch_ctx_create( const char *name); static void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t riid); uint32_t riid, void *cookie); static int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t *riid_ptr, size_t *intent_size); uint32_t *riid_ptr, size_t *intent_size, void **cookie); static struct glink_core_rx_intent *ch_push_local_rx_intent( struct channel_ctx *ctx, const void *pkt_priv, size_t size); Loading Loading @@ -1138,11 +1138,12 @@ bool ch_check_duplicate_riid(struct channel_ctx *ctx, int riid) * @ctx: Local channel context * @size: Size of Intent * @riid_ptr: Pointer to return value of remote intent ID * @cookie: Transport-specific cookie to return * * This functions searches for an RX intent that is >= to the requested size. */ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t *riid_ptr, size_t *intent_size) uint32_t *riid_ptr, size_t *intent_size, void **cookie) { struct glink_core_rx_intent *intent; struct glink_core_rx_intent *intent_tmp; Loading Loading @@ -1186,6 +1187,7 @@ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, best_intent->intent_size); *riid_ptr = best_intent->id; *intent_size = best_intent->intent_size; *cookie = best_intent->cookie; kfree(best_intent); spin_unlock_irqrestore( &ctx->rmt_rx_intent_lst_lock_lhc2, flags); Loading @@ -1200,11 +1202,12 @@ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, * @ctx: Local channel context * @size: Size of Intent * @riid: Remote intent ID * @cookie: Transport-specific cookie to cache * * This functions adds a remote RX intent to the remote RX intent list. */ void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t riid) uint32_t riid, void *cookie) { struct glink_core_rx_intent *intent; unsigned long flags; Loading Loading @@ -1233,6 +1236,7 @@ void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size, } intent->id = riid; intent->intent_size = size; intent->cookie = cookie; spin_lock_irqsave(&ctx->rmt_rx_intent_lst_lock_lhc2, flags); list_add_tail(&intent->list, &ctx->rmt_rx_intent_list); Loading Loading @@ -2802,6 +2806,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, bool is_atomic = tx_flags & (GLINK_TX_SINGLE_THREADED | GLINK_TX_ATOMIC); unsigned long flags; void *cookie = NULL; if (!size) return -EINVAL; Loading Loading @@ -2834,7 +2839,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, } /* find matching rx intent (best-fit algorithm for now) */ if (ch_pop_remote_rx_intent(ctx, size, &riid, &intent_size)) { if (ch_pop_remote_rx_intent(ctx, size, &riid, &intent_size, &cookie)) { if (!(tx_flags & GLINK_TX_REQ_INTENT)) { /* no rx intent available */ GLINK_ERR_CH(ctx, Loading Loading @@ -2864,7 +2869,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, } while (ch_pop_remote_rx_intent(ctx, size, &riid, &intent_size)) { &intent_size, &cookie)) { rwref_get(&ctx->ch_state_lhb2); rwref_read_put(&ctx->ch_state_lhb2); if (is_atomic) { Loading Loading @@ -2936,7 +2941,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, is_atomic ? GFP_ATOMIC : GFP_KERNEL); if (!tx_info) { GLINK_ERR_CH(ctx, "%s: No memory for allocation\n", __func__); ch_push_remote_rx_intent(ctx, intent_size, riid); ch_push_remote_rx_intent(ctx, intent_size, riid, cookie); rwref_read_put(&ctx->ch_state_lhb2); return -ENOMEM; } Loading @@ -2954,6 +2959,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, tx_info->vprovider = vbuf_provider; tx_info->pprovider = pbuf_provider; tx_info->intent_size = intent_size; tx_info->cookie = cookie; /* schedule packet for transmit */ if ((tx_flags & GLINK_TX_SINGLE_THREADED) && Loading Loading @@ -4873,7 +4879,35 @@ static void glink_core_remote_rx_intent_put(struct glink_transport_if *if_ptr, return; } ch_push_remote_rx_intent(ctx, size, riid); ch_push_remote_rx_intent(ctx, size, riid, NULL); rwref_put(&ctx->ch_state_lhb2); } /** * glink_core_remote_rx_intent_put_cookie() - Receive remove intent * * @if_ptr: Pointer to transport instance * @rcid: Remote Channel ID * @riid: Remote Intent ID * @size: Size of the remote intent ID * @cookie: Transport-specific cookie to cache */ static void glink_core_remote_rx_intent_put_cookie( struct glink_transport_if *if_ptr, uint32_t rcid, uint32_t riid, size_t size, void *cookie) { struct channel_ctx *ctx; ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid); if (!ctx) { /* unknown rcid received - this shouldn't happen */ GLINK_ERR_XPRT(if_ptr->glink_core_priv, "%s: invalid rcid received %u\n", __func__, (unsigned)rcid); return; } ch_push_remote_rx_intent(ctx, size, riid, cookie); rwref_put(&ctx->ch_state_lhb2); } Loading Loading @@ -5079,6 +5113,7 @@ void glink_core_rx_cmd_tx_done(struct glink_transport_if *if_ptr, struct glink_core_tx_pkt *tx_pkt; unsigned long flags; size_t intent_size; void *cookie; ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid); if (!ctx) { Loading Loading @@ -5111,11 +5146,12 @@ void glink_core_rx_cmd_tx_done(struct glink_transport_if *if_ptr, ctx->notify_tx_done(ctx, ctx->user_priv, tx_pkt->pkt_priv, tx_pkt->data ? tx_pkt->data : tx_pkt->iovec); intent_size = tx_pkt->intent_size; cookie = tx_pkt->cookie; ch_remove_tx_pending_remote_done(ctx, tx_pkt); spin_unlock_irqrestore(&ctx->tx_lists_lock_lhc3, flags); if (reuse) ch_push_remote_rx_intent(ctx, intent_size, riid); ch_push_remote_rx_intent(ctx, intent_size, riid, cookie); rwref_put(&ctx->ch_state_lhb2); } Loading Loading @@ -5573,6 +5609,8 @@ static struct glink_core_if core_impl = { .rx_get_pkt_ctx = glink_core_rx_get_pkt_ctx, .rx_put_pkt_ctx = glink_core_rx_put_pkt_ctx, .rx_cmd_remote_rx_intent_put = glink_core_remote_rx_intent_put, .rx_cmd_remote_rx_intent_put_cookie = glink_core_remote_rx_intent_put_cookie, .rx_cmd_remote_rx_intent_req = glink_core_rx_cmd_remote_rx_intent_req, .rx_cmd_rx_intent_req_ack = glink_core_rx_cmd_rx_intent_req_ack, .rx_cmd_tx_done = glink_core_rx_cmd_tx_done, Loading drivers/soc/qcom/glink_core_if.h +6 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -64,6 +64,7 @@ struct glink_core_version { * iovec: Pointer to vector buffer if the transport passes a vector buffer * vprovider: Virtual address-space buffer provider for a vector buffer * pprovider: Physical address-space buffer provider for a vector buffer * cookie: Private transport specific cookie * pkt_priv: G-Link core owned packet-private data * list: G-Link core owned list node * bounce_buf: Pointer to the temporary/internal bounce buffer Loading @@ -78,6 +79,7 @@ struct glink_core_rx_intent { void *iovec; void * (*vprovider)(void *iovec, size_t offset, size_t *size); void * (*pprovider)(void *iovec, size_t offset, size_t *size); void *cookie; /* G-Link-Core-owned elements - please ignore */ struct list_head list; Loading Loading @@ -151,6 +153,9 @@ struct glink_core_if { struct glink_core_rx_intent *intent_ptr, bool complete); void (*rx_cmd_remote_rx_intent_put)(struct glink_transport_if *if_ptr, uint32_t rcid, uint32_t riid, size_t size); void (*rx_cmd_remote_rx_intent_put_cookie)( struct glink_transport_if *if_ptr, uint32_t rcid, uint32_t riid, size_t size, void *cookie); void (*rx_cmd_tx_done)(struct glink_transport_if *if_ptr, uint32_t rcid, uint32_t riid, bool reuse); void (*rx_cmd_remote_rx_intent_req)(struct glink_transport_if *if_ptr, Loading drivers/soc/qcom/glink_xprt_if.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -56,6 +56,7 @@ enum xprt_ids { * @iovec: Pointer to the vector buffer packet. * @vprovider: Packet-specific virtual buffer provider function. * @pprovider: Packet-specific physical buffer provider function. * @cookie: Transport-specific cookie * @pkt_ref: Active references to the packet. */ struct glink_core_tx_pkt { Loading @@ -73,6 +74,7 @@ struct glink_core_tx_pkt { void *iovec; void * (*vprovider)(void *iovec, size_t offset, size_t *size); void * (*pprovider)(void *iovec, size_t offset, size_t *size); void *cookie; struct rwref_lock pkt_ref; }; Loading Loading
drivers/soc/qcom/glink.c +47 −9 Original line number Diff line number Diff line Loading @@ -371,10 +371,10 @@ static struct channel_ctx *ch_name_to_ch_ctx_create( const char *name); static void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t riid); uint32_t riid, void *cookie); static int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t *riid_ptr, size_t *intent_size); uint32_t *riid_ptr, size_t *intent_size, void **cookie); static struct glink_core_rx_intent *ch_push_local_rx_intent( struct channel_ctx *ctx, const void *pkt_priv, size_t size); Loading Loading @@ -1138,11 +1138,12 @@ bool ch_check_duplicate_riid(struct channel_ctx *ctx, int riid) * @ctx: Local channel context * @size: Size of Intent * @riid_ptr: Pointer to return value of remote intent ID * @cookie: Transport-specific cookie to return * * This functions searches for an RX intent that is >= to the requested size. */ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t *riid_ptr, size_t *intent_size) uint32_t *riid_ptr, size_t *intent_size, void **cookie) { struct glink_core_rx_intent *intent; struct glink_core_rx_intent *intent_tmp; Loading Loading @@ -1186,6 +1187,7 @@ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, best_intent->intent_size); *riid_ptr = best_intent->id; *intent_size = best_intent->intent_size; *cookie = best_intent->cookie; kfree(best_intent); spin_unlock_irqrestore( &ctx->rmt_rx_intent_lst_lock_lhc2, flags); Loading @@ -1200,11 +1202,12 @@ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, * @ctx: Local channel context * @size: Size of Intent * @riid: Remote intent ID * @cookie: Transport-specific cookie to cache * * This functions adds a remote RX intent to the remote RX intent list. */ void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t riid) uint32_t riid, void *cookie) { struct glink_core_rx_intent *intent; unsigned long flags; Loading Loading @@ -1233,6 +1236,7 @@ void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size, } intent->id = riid; intent->intent_size = size; intent->cookie = cookie; spin_lock_irqsave(&ctx->rmt_rx_intent_lst_lock_lhc2, flags); list_add_tail(&intent->list, &ctx->rmt_rx_intent_list); Loading Loading @@ -2802,6 +2806,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, bool is_atomic = tx_flags & (GLINK_TX_SINGLE_THREADED | GLINK_TX_ATOMIC); unsigned long flags; void *cookie = NULL; if (!size) return -EINVAL; Loading Loading @@ -2834,7 +2839,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, } /* find matching rx intent (best-fit algorithm for now) */ if (ch_pop_remote_rx_intent(ctx, size, &riid, &intent_size)) { if (ch_pop_remote_rx_intent(ctx, size, &riid, &intent_size, &cookie)) { if (!(tx_flags & GLINK_TX_REQ_INTENT)) { /* no rx intent available */ GLINK_ERR_CH(ctx, Loading Loading @@ -2864,7 +2869,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, } while (ch_pop_remote_rx_intent(ctx, size, &riid, &intent_size)) { &intent_size, &cookie)) { rwref_get(&ctx->ch_state_lhb2); rwref_read_put(&ctx->ch_state_lhb2); if (is_atomic) { Loading Loading @@ -2936,7 +2941,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, is_atomic ? GFP_ATOMIC : GFP_KERNEL); if (!tx_info) { GLINK_ERR_CH(ctx, "%s: No memory for allocation\n", __func__); ch_push_remote_rx_intent(ctx, intent_size, riid); ch_push_remote_rx_intent(ctx, intent_size, riid, cookie); rwref_read_put(&ctx->ch_state_lhb2); return -ENOMEM; } Loading @@ -2954,6 +2959,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, tx_info->vprovider = vbuf_provider; tx_info->pprovider = pbuf_provider; tx_info->intent_size = intent_size; tx_info->cookie = cookie; /* schedule packet for transmit */ if ((tx_flags & GLINK_TX_SINGLE_THREADED) && Loading Loading @@ -4873,7 +4879,35 @@ static void glink_core_remote_rx_intent_put(struct glink_transport_if *if_ptr, return; } ch_push_remote_rx_intent(ctx, size, riid); ch_push_remote_rx_intent(ctx, size, riid, NULL); rwref_put(&ctx->ch_state_lhb2); } /** * glink_core_remote_rx_intent_put_cookie() - Receive remove intent * * @if_ptr: Pointer to transport instance * @rcid: Remote Channel ID * @riid: Remote Intent ID * @size: Size of the remote intent ID * @cookie: Transport-specific cookie to cache */ static void glink_core_remote_rx_intent_put_cookie( struct glink_transport_if *if_ptr, uint32_t rcid, uint32_t riid, size_t size, void *cookie) { struct channel_ctx *ctx; ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid); if (!ctx) { /* unknown rcid received - this shouldn't happen */ GLINK_ERR_XPRT(if_ptr->glink_core_priv, "%s: invalid rcid received %u\n", __func__, (unsigned)rcid); return; } ch_push_remote_rx_intent(ctx, size, riid, cookie); rwref_put(&ctx->ch_state_lhb2); } Loading Loading @@ -5079,6 +5113,7 @@ void glink_core_rx_cmd_tx_done(struct glink_transport_if *if_ptr, struct glink_core_tx_pkt *tx_pkt; unsigned long flags; size_t intent_size; void *cookie; ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid); if (!ctx) { Loading Loading @@ -5111,11 +5146,12 @@ void glink_core_rx_cmd_tx_done(struct glink_transport_if *if_ptr, ctx->notify_tx_done(ctx, ctx->user_priv, tx_pkt->pkt_priv, tx_pkt->data ? tx_pkt->data : tx_pkt->iovec); intent_size = tx_pkt->intent_size; cookie = tx_pkt->cookie; ch_remove_tx_pending_remote_done(ctx, tx_pkt); spin_unlock_irqrestore(&ctx->tx_lists_lock_lhc3, flags); if (reuse) ch_push_remote_rx_intent(ctx, intent_size, riid); ch_push_remote_rx_intent(ctx, intent_size, riid, cookie); rwref_put(&ctx->ch_state_lhb2); } Loading Loading @@ -5573,6 +5609,8 @@ static struct glink_core_if core_impl = { .rx_get_pkt_ctx = glink_core_rx_get_pkt_ctx, .rx_put_pkt_ctx = glink_core_rx_put_pkt_ctx, .rx_cmd_remote_rx_intent_put = glink_core_remote_rx_intent_put, .rx_cmd_remote_rx_intent_put_cookie = glink_core_remote_rx_intent_put_cookie, .rx_cmd_remote_rx_intent_req = glink_core_rx_cmd_remote_rx_intent_req, .rx_cmd_rx_intent_req_ack = glink_core_rx_cmd_rx_intent_req_ack, .rx_cmd_tx_done = glink_core_rx_cmd_tx_done, Loading
drivers/soc/qcom/glink_core_if.h +6 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -64,6 +64,7 @@ struct glink_core_version { * iovec: Pointer to vector buffer if the transport passes a vector buffer * vprovider: Virtual address-space buffer provider for a vector buffer * pprovider: Physical address-space buffer provider for a vector buffer * cookie: Private transport specific cookie * pkt_priv: G-Link core owned packet-private data * list: G-Link core owned list node * bounce_buf: Pointer to the temporary/internal bounce buffer Loading @@ -78,6 +79,7 @@ struct glink_core_rx_intent { void *iovec; void * (*vprovider)(void *iovec, size_t offset, size_t *size); void * (*pprovider)(void *iovec, size_t offset, size_t *size); void *cookie; /* G-Link-Core-owned elements - please ignore */ struct list_head list; Loading Loading @@ -151,6 +153,9 @@ struct glink_core_if { struct glink_core_rx_intent *intent_ptr, bool complete); void (*rx_cmd_remote_rx_intent_put)(struct glink_transport_if *if_ptr, uint32_t rcid, uint32_t riid, size_t size); void (*rx_cmd_remote_rx_intent_put_cookie)( struct glink_transport_if *if_ptr, uint32_t rcid, uint32_t riid, size_t size, void *cookie); void (*rx_cmd_tx_done)(struct glink_transport_if *if_ptr, uint32_t rcid, uint32_t riid, bool reuse); void (*rx_cmd_remote_rx_intent_req)(struct glink_transport_if *if_ptr, Loading
drivers/soc/qcom/glink_xprt_if.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -56,6 +56,7 @@ enum xprt_ids { * @iovec: Pointer to the vector buffer packet. * @vprovider: Packet-specific virtual buffer provider function. * @pprovider: Packet-specific physical buffer provider function. * @cookie: Transport-specific cookie * @pkt_ref: Active references to the packet. */ struct glink_core_tx_pkt { Loading @@ -73,6 +74,7 @@ struct glink_core_tx_pkt { void *iovec; void * (*vprovider)(void *iovec, size_t offset, size_t *size); void * (*pprovider)(void *iovec, size_t offset, size_t *size); void *cookie; struct rwref_lock pkt_ref; }; Loading