Loading drivers/soc/qcom/glink.c +84 −1 Original line number Diff line number Diff line Loading @@ -232,6 +232,8 @@ static DEFINE_MUTEX(edge_list_lock_lhd0); * @req_rate_kBps: Current QoS request by the channel. * @tx_intent_cnt: Intent count to transmit soon in future. * @tx_cnt: Packets to be picked by tx scheduler. * @rt_vote_on: Number of times RT vote on is called. * @rt_vote_off: Number of times RT vote off is called. */ struct channel_ctx { struct rwref_lock ch_state_lhb2; Loading Loading @@ -311,6 +313,9 @@ struct channel_ctx { unsigned long req_rate_kBps; uint32_t tx_intent_cnt; uint32_t tx_cnt; uint32_t rt_vote_on; uint32_t rt_vote_off; uint32_t magic_number; }; Loading Loading @@ -2417,6 +2422,25 @@ static int dummy_power_unvote(struct glink_transport_if *if_ptr) return -EOPNOTSUPP; } /** * dummy_rx_rt_vote() - Dummy RX Realtime thread vote * @if_ptr: The transport to transmit on. */ static int dummy_rx_rt_vote(struct glink_transport_if *if_ptr) { return -EOPNOTSUPP; } /** * dummy_rx_rt_unvote() - Dummy RX Realtime thread unvote * @if_ptr: The transport to transmit on. */ static int dummy_rx_rt_unvote(struct glink_transport_if *if_ptr) { return -EOPNOTSUPP; } /** * notif_if_up_all_xprts() - Check and notify existing transport state if up * @notif_info: Data structure containing transport information to be notified. Loading Loading @@ -3543,6 +3567,61 @@ unsigned long glink_qos_get_ramp_time(void *handle, size_t pkt_size) } EXPORT_SYMBOL(glink_qos_get_ramp_time); /** * glink_start_rx_rt() - Vote for RT thread priority on RX. * @handle: Channel handle for which transaction are occurring. * * Return: 0 on success, standard Linux error codes on failure */ int glink_start_rx_rt(void *handle) { struct channel_ctx *ctx = (struct channel_ctx *)handle; int ret; ret = glink_get_ch_ctx(ctx); if (ret) return ret; if (!ch_is_fully_opened(ctx)) { GLINK_ERR_CH(ctx, "%s: Channel is not fully opened\n", __func__); glink_put_ch_ctx(ctx, false); return -EBUSY; } ret = ctx->transport_ptr->ops->rx_rt_vote(ctx->transport_ptr->ops); ctx->rt_vote_on++; GLINK_INFO_CH(ctx, "%s: Voting RX Realtime Thread %d", __func__, ret); glink_put_ch_ctx(ctx, false); return ret; } /** * glink_end_rx_rt() - Vote for RT thread priority on RX. * @handle: Channel handle for which transaction are occurring. * * Return: 0 on success, standard Linux error codes on failure */ int glink_end_rx_rt(void *handle) { struct channel_ctx *ctx = (struct channel_ctx *)handle; int ret; ret = glink_get_ch_ctx(ctx); if (ret) return ret; if (!ch_is_fully_opened(ctx)) { GLINK_ERR_CH(ctx, "%s: Channel is not fully opened\n", __func__); glink_put_ch_ctx(ctx, false); return -EBUSY; } ret = ctx->transport_ptr->ops->rx_rt_unvote(ctx->transport_ptr->ops); ctx->rt_vote_off++; GLINK_INFO_CH(ctx, "%s: Unvoting RX Realtime Thread %d", __func__, ret); glink_put_ch_ctx(ctx, false); return ret; } /** * glink_rpm_rx_poll() - Poll and receive any available events * @handle: Channel handle in which this operation is performed. Loading Loading @@ -3950,6 +4029,10 @@ int glink_core_register_transport(struct glink_transport_if *if_ptr, if_ptr->power_vote = dummy_power_vote; if (!if_ptr->power_unvote) if_ptr->power_unvote = dummy_power_unvote; if (!if_ptr->rx_rt_vote) if_ptr->rx_rt_vote = dummy_rx_rt_vote; if (!if_ptr->rx_rt_unvote) if_ptr->rx_rt_unvote = dummy_rx_rt_unvote; xprt_ptr->capabilities = 0; xprt_ptr->ops = if_ptr; spin_lock_init(&xprt_ptr->xprt_ctx_lock_lhb1); Loading drivers/soc/qcom/glink_smem_native_xprt.c +54 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,8 @@ struct mailbox_config_info { * @deferred_cmds: List of deferred commands that need to be * processed in process context. * @deferred_cmds_cnt: Number of deferred commands in queue. * @rt_vote_lock: Serialize access to RT rx votes * @rt_votes: Vote count for RT rx thread priority * @num_pw_states: Size of @ramp_time_us. * @ramp_time_us: Array of ramp times in microseconds where array * index position represents a power state. Loading Loading @@ -221,6 +223,8 @@ struct edge_info { spinlock_t rx_lock; struct list_head deferred_cmds; uint32_t deferred_cmds_cnt; spinlock_t rt_vote_lock; uint32_t rt_votes; uint32_t num_pw_states; unsigned long *ramp_time_us; struct mailbox_config_info *mailbox; Loading Loading @@ -2092,6 +2096,52 @@ static int power_unvote(struct glink_transport_if *if_ptr) return 0; } /** * rx_rt_vote() - Increment and RX thread RT vote * @if_ptr: The transport interface on which power voting is requested. * * Return: 0 on Success, standard error otherwise. */ static int rx_rt_vote(struct glink_transport_if *if_ptr) { struct edge_info *einfo; struct sched_param param = { .sched_priority = 1 }; int ret = 0; unsigned long flags; einfo = container_of(if_ptr, struct edge_info, xprt_if); spin_lock_irqsave(&einfo->rt_vote_lock, flags); if (!einfo->rt_votes) ret = sched_setscheduler_nocheck(einfo->task, SCHED_FIFO, ¶m); einfo->rt_votes++; spin_unlock_irqrestore(&einfo->rt_vote_lock, flags); return ret; } /** * rx_rt_unvote() - Remove a RX thread RT vote * @if_ptr: The transport interface on which power voting is requested. * * Return: 0 on Success, standard error otherwise. */ static int rx_rt_unvote(struct glink_transport_if *if_ptr) { struct edge_info *einfo; struct sched_param param = { .sched_priority = 0 }; int ret = 0; unsigned long flags; einfo = container_of(if_ptr, struct edge_info, xprt_if); spin_lock_irqsave(&einfo->rt_vote_lock, flags); einfo->rt_votes--; if (!einfo->rt_votes) ret = sched_setscheduler_nocheck(einfo->task, SCHED_NORMAL, ¶m); spin_unlock_irqrestore(&einfo->rt_vote_lock, flags); return ret; } /** * negotiate_features_v1() - determine what features of a version can be used * @if_ptr: The transport for which features are negotiated for. Loading Loading @@ -2137,6 +2187,8 @@ static void init_xprt_if(struct edge_info *einfo) einfo->xprt_if.get_power_vote_ramp_time = get_power_vote_ramp_time; einfo->xprt_if.power_vote = power_vote; einfo->xprt_if.power_unvote = power_unvote; einfo->xprt_if.rx_rt_vote = rx_rt_vote; einfo->xprt_if.rx_rt_unvote = rx_rt_unvote; } /** Loading Loading @@ -2310,6 +2362,8 @@ static int glink_smem_native_probe(struct platform_device *pdev) init_srcu_struct(&einfo->use_ref); spin_lock_init(&einfo->rx_lock); INIT_LIST_HEAD(&einfo->deferred_cmds); spin_lock_init(&einfo->rt_vote_lock); einfo->rt_votes = 0; mutex_lock(&probe_lock); if (edge_infos[einfo->remote_proc_id]) { Loading drivers/soc/qcom/glink_xprt_if.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2017, 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 @@ -141,6 +141,8 @@ struct glink_transport_if { struct glink_transport_if *if_ptr, uint32_t state); int (*power_vote)(struct glink_transport_if *if_ptr, uint32_t state); int (*power_unvote)(struct glink_transport_if *if_ptr); int (*rx_rt_vote)(struct glink_transport_if *if_ptr); int (*rx_rt_unvote)(struct glink_transport_if *if_ptr); /* * Keep data pointers at the end of the structure after all function * pointer to allow for in-place initialization. Loading include/soc/qcom/glink.h +28 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2015,2017 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 @@ -339,6 +339,22 @@ int glink_qos_start(void *handle); */ unsigned long glink_qos_get_ramp_time(void *handle, size_t pkt_size); /** * glink_start_rx_rt() - Vote for RT thread priority on RX. * @handle: Channel handle for which transaction are occurring. * * Return: 0 on success, standard Linux error codes on failure */ int glink_start_rx_rt(void *handle); /** * glink_end_rx_rt() - Vote for RT thread priority on RX. * @handle: Channel handle for which transaction are occurring. * * Return: 0 on success, standard Linux error codes on failure */ int glink_end_rx_rt(void *handle); #else /* CONFIG_MSM_GLINK */ static inline void *glink_open(const struct glink_open_config *cfg_ptr) { Loading Loading @@ -427,5 +443,16 @@ static inline unsigned long glink_qos_get_ramp_time(void *handle, { return 0; } static inline int glink_start_rx_rt(void *handle) { return -ENODEV; } static inline int glink_end_rx_rt(void *handle) { return -ENODEV; } #endif /* CONFIG_MSM_GLINK */ #endif /* _SOC_QCOM_GLINK_H_ */ Loading
drivers/soc/qcom/glink.c +84 −1 Original line number Diff line number Diff line Loading @@ -232,6 +232,8 @@ static DEFINE_MUTEX(edge_list_lock_lhd0); * @req_rate_kBps: Current QoS request by the channel. * @tx_intent_cnt: Intent count to transmit soon in future. * @tx_cnt: Packets to be picked by tx scheduler. * @rt_vote_on: Number of times RT vote on is called. * @rt_vote_off: Number of times RT vote off is called. */ struct channel_ctx { struct rwref_lock ch_state_lhb2; Loading Loading @@ -311,6 +313,9 @@ struct channel_ctx { unsigned long req_rate_kBps; uint32_t tx_intent_cnt; uint32_t tx_cnt; uint32_t rt_vote_on; uint32_t rt_vote_off; uint32_t magic_number; }; Loading Loading @@ -2417,6 +2422,25 @@ static int dummy_power_unvote(struct glink_transport_if *if_ptr) return -EOPNOTSUPP; } /** * dummy_rx_rt_vote() - Dummy RX Realtime thread vote * @if_ptr: The transport to transmit on. */ static int dummy_rx_rt_vote(struct glink_transport_if *if_ptr) { return -EOPNOTSUPP; } /** * dummy_rx_rt_unvote() - Dummy RX Realtime thread unvote * @if_ptr: The transport to transmit on. */ static int dummy_rx_rt_unvote(struct glink_transport_if *if_ptr) { return -EOPNOTSUPP; } /** * notif_if_up_all_xprts() - Check and notify existing transport state if up * @notif_info: Data structure containing transport information to be notified. Loading Loading @@ -3543,6 +3567,61 @@ unsigned long glink_qos_get_ramp_time(void *handle, size_t pkt_size) } EXPORT_SYMBOL(glink_qos_get_ramp_time); /** * glink_start_rx_rt() - Vote for RT thread priority on RX. * @handle: Channel handle for which transaction are occurring. * * Return: 0 on success, standard Linux error codes on failure */ int glink_start_rx_rt(void *handle) { struct channel_ctx *ctx = (struct channel_ctx *)handle; int ret; ret = glink_get_ch_ctx(ctx); if (ret) return ret; if (!ch_is_fully_opened(ctx)) { GLINK_ERR_CH(ctx, "%s: Channel is not fully opened\n", __func__); glink_put_ch_ctx(ctx, false); return -EBUSY; } ret = ctx->transport_ptr->ops->rx_rt_vote(ctx->transport_ptr->ops); ctx->rt_vote_on++; GLINK_INFO_CH(ctx, "%s: Voting RX Realtime Thread %d", __func__, ret); glink_put_ch_ctx(ctx, false); return ret; } /** * glink_end_rx_rt() - Vote for RT thread priority on RX. * @handle: Channel handle for which transaction are occurring. * * Return: 0 on success, standard Linux error codes on failure */ int glink_end_rx_rt(void *handle) { struct channel_ctx *ctx = (struct channel_ctx *)handle; int ret; ret = glink_get_ch_ctx(ctx); if (ret) return ret; if (!ch_is_fully_opened(ctx)) { GLINK_ERR_CH(ctx, "%s: Channel is not fully opened\n", __func__); glink_put_ch_ctx(ctx, false); return -EBUSY; } ret = ctx->transport_ptr->ops->rx_rt_unvote(ctx->transport_ptr->ops); ctx->rt_vote_off++; GLINK_INFO_CH(ctx, "%s: Unvoting RX Realtime Thread %d", __func__, ret); glink_put_ch_ctx(ctx, false); return ret; } /** * glink_rpm_rx_poll() - Poll and receive any available events * @handle: Channel handle in which this operation is performed. Loading Loading @@ -3950,6 +4029,10 @@ int glink_core_register_transport(struct glink_transport_if *if_ptr, if_ptr->power_vote = dummy_power_vote; if (!if_ptr->power_unvote) if_ptr->power_unvote = dummy_power_unvote; if (!if_ptr->rx_rt_vote) if_ptr->rx_rt_vote = dummy_rx_rt_vote; if (!if_ptr->rx_rt_unvote) if_ptr->rx_rt_unvote = dummy_rx_rt_unvote; xprt_ptr->capabilities = 0; xprt_ptr->ops = if_ptr; spin_lock_init(&xprt_ptr->xprt_ctx_lock_lhb1); Loading
drivers/soc/qcom/glink_smem_native_xprt.c +54 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,8 @@ struct mailbox_config_info { * @deferred_cmds: List of deferred commands that need to be * processed in process context. * @deferred_cmds_cnt: Number of deferred commands in queue. * @rt_vote_lock: Serialize access to RT rx votes * @rt_votes: Vote count for RT rx thread priority * @num_pw_states: Size of @ramp_time_us. * @ramp_time_us: Array of ramp times in microseconds where array * index position represents a power state. Loading Loading @@ -221,6 +223,8 @@ struct edge_info { spinlock_t rx_lock; struct list_head deferred_cmds; uint32_t deferred_cmds_cnt; spinlock_t rt_vote_lock; uint32_t rt_votes; uint32_t num_pw_states; unsigned long *ramp_time_us; struct mailbox_config_info *mailbox; Loading Loading @@ -2092,6 +2096,52 @@ static int power_unvote(struct glink_transport_if *if_ptr) return 0; } /** * rx_rt_vote() - Increment and RX thread RT vote * @if_ptr: The transport interface on which power voting is requested. * * Return: 0 on Success, standard error otherwise. */ static int rx_rt_vote(struct glink_transport_if *if_ptr) { struct edge_info *einfo; struct sched_param param = { .sched_priority = 1 }; int ret = 0; unsigned long flags; einfo = container_of(if_ptr, struct edge_info, xprt_if); spin_lock_irqsave(&einfo->rt_vote_lock, flags); if (!einfo->rt_votes) ret = sched_setscheduler_nocheck(einfo->task, SCHED_FIFO, ¶m); einfo->rt_votes++; spin_unlock_irqrestore(&einfo->rt_vote_lock, flags); return ret; } /** * rx_rt_unvote() - Remove a RX thread RT vote * @if_ptr: The transport interface on which power voting is requested. * * Return: 0 on Success, standard error otherwise. */ static int rx_rt_unvote(struct glink_transport_if *if_ptr) { struct edge_info *einfo; struct sched_param param = { .sched_priority = 0 }; int ret = 0; unsigned long flags; einfo = container_of(if_ptr, struct edge_info, xprt_if); spin_lock_irqsave(&einfo->rt_vote_lock, flags); einfo->rt_votes--; if (!einfo->rt_votes) ret = sched_setscheduler_nocheck(einfo->task, SCHED_NORMAL, ¶m); spin_unlock_irqrestore(&einfo->rt_vote_lock, flags); return ret; } /** * negotiate_features_v1() - determine what features of a version can be used * @if_ptr: The transport for which features are negotiated for. Loading Loading @@ -2137,6 +2187,8 @@ static void init_xprt_if(struct edge_info *einfo) einfo->xprt_if.get_power_vote_ramp_time = get_power_vote_ramp_time; einfo->xprt_if.power_vote = power_vote; einfo->xprt_if.power_unvote = power_unvote; einfo->xprt_if.rx_rt_vote = rx_rt_vote; einfo->xprt_if.rx_rt_unvote = rx_rt_unvote; } /** Loading Loading @@ -2310,6 +2362,8 @@ static int glink_smem_native_probe(struct platform_device *pdev) init_srcu_struct(&einfo->use_ref); spin_lock_init(&einfo->rx_lock); INIT_LIST_HEAD(&einfo->deferred_cmds); spin_lock_init(&einfo->rt_vote_lock); einfo->rt_votes = 0; mutex_lock(&probe_lock); if (edge_infos[einfo->remote_proc_id]) { Loading
drivers/soc/qcom/glink_xprt_if.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2017, 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 @@ -141,6 +141,8 @@ struct glink_transport_if { struct glink_transport_if *if_ptr, uint32_t state); int (*power_vote)(struct glink_transport_if *if_ptr, uint32_t state); int (*power_unvote)(struct glink_transport_if *if_ptr); int (*rx_rt_vote)(struct glink_transport_if *if_ptr); int (*rx_rt_unvote)(struct glink_transport_if *if_ptr); /* * Keep data pointers at the end of the structure after all function * pointer to allow for in-place initialization. Loading
include/soc/qcom/glink.h +28 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2015,2017 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 @@ -339,6 +339,22 @@ int glink_qos_start(void *handle); */ unsigned long glink_qos_get_ramp_time(void *handle, size_t pkt_size); /** * glink_start_rx_rt() - Vote for RT thread priority on RX. * @handle: Channel handle for which transaction are occurring. * * Return: 0 on success, standard Linux error codes on failure */ int glink_start_rx_rt(void *handle); /** * glink_end_rx_rt() - Vote for RT thread priority on RX. * @handle: Channel handle for which transaction are occurring. * * Return: 0 on success, standard Linux error codes on failure */ int glink_end_rx_rt(void *handle); #else /* CONFIG_MSM_GLINK */ static inline void *glink_open(const struct glink_open_config *cfg_ptr) { Loading Loading @@ -427,5 +443,16 @@ static inline unsigned long glink_qos_get_ramp_time(void *handle, { return 0; } static inline int glink_start_rx_rt(void *handle) { return -ENODEV; } static inline int glink_end_rx_rt(void *handle) { return -ENODEV; } #endif /* CONFIG_MSM_GLINK */ #endif /* _SOC_QCOM_GLINK_H_ */