Loading drivers/soc/qcom/glink.c +36 −0 Original line number Diff line number Diff line Loading @@ -457,6 +457,42 @@ static void glink_put_ch_ctx(struct channel_ctx *ctx) rwref_put(&ctx->ch_state_lhb2); } /** * glink_subsys_up() - Inform transport about remote subsystem up. * @subsystem: The name of the subsystem * * Call into the transport using the subsys_up(if_ptr) function to allow it to * initialize any necessary structures. * * Return: Standard error codes. */ int glink_subsys_up(const char *subsystem) { int ret = 0; bool transport_found = false; struct glink_core_xprt_ctx *xprt_ctx = NULL; mutex_lock(&transport_list_lock_lha0); list_for_each_entry(xprt_ctx, &transport_list, list_node) { if (!strcmp(subsystem, xprt_ctx->edge) && !xprt_is_fully_opened(xprt_ctx)) { GLINK_INFO_XPRT(xprt_ctx, "%s: %s Subsystem up\n", __func__, subsystem); if (xprt_ctx->ops->subsys_up) xprt_ctx->ops->subsys_up(xprt_ctx->ops); transport_found = true; } } mutex_unlock(&transport_list_lock_lha0); if (!transport_found) ret = -ENODEV; return ret; } EXPORT_SYMBOL(glink_subsys_up); /** * glink_ssr() - Clean up locally for SSR by simulating remote close * @subsystem: The name of the subsystem being restarted Loading drivers/soc/qcom/glink_private.h +9 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 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 @@ -824,6 +824,14 @@ uint32_t glink_ssr_get_seq_num(void); */ int glink_ssr(const char *subsystem); /* * glink_subsys_up() - SSR sub system up function. * @subsystem: Constant string for name of remote subsystem. * * Return: Standard error code. */ int glink_subsys_up(const char *subsystem); /** * notify for subsystem() - Notify other subsystems that a subsystem is being * restarted Loading drivers/soc/qcom/glink_smem_native_xprt.c +21 −9 Original line number Diff line number Diff line Loading @@ -947,15 +947,6 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx) rcu_id = srcu_read_lock(&einfo->use_ref); if (unlikely(!einfo->rx_fifo) && atomic_ctx) { if (!get_rx_fifo(einfo)) { srcu_read_unlock(&einfo->use_ref, rcu_id); return; } einfo->in_ssr = false; einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if); } if (einfo->in_ssr) { srcu_read_unlock(&einfo->use_ref, rcu_id); return; Loading Loading @@ -1568,6 +1559,24 @@ static void tx_cmd_ch_remote_close_ack(struct glink_transport_if *if_ptr, srcu_read_unlock(&einfo->use_ref, rcu_id); } /** * subsys_up() - process a subsystem up notification * @if_ptr: The transport which is up * */ static void subsys_up(struct glink_transport_if *if_ptr) { struct edge_info *einfo; einfo = container_of(if_ptr, struct edge_info, xprt_if); if (!einfo->rx_fifo) { if (!get_rx_fifo(einfo)) return; einfo->in_ssr = false; einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if); } } /** * ssr() - process a subsystem restart notification of a transport * @if_ptr: The transport to restart Loading Loading @@ -2261,6 +2270,7 @@ static void init_xprt_if(struct edge_info *einfo) einfo->xprt_if.tx_cmd_ch_remote_open_ack = tx_cmd_ch_remote_open_ack; einfo->xprt_if.tx_cmd_ch_remote_close_ack = tx_cmd_ch_remote_close_ack; einfo->xprt_if.ssr = ssr; einfo->xprt_if.subsys_up = subsys_up; einfo->xprt_if.allocate_rx_intent = allocate_rx_intent; einfo->xprt_if.deallocate_rx_intent = deallocate_rx_intent; einfo->xprt_if.tx_cmd_local_rx_intent = tx_cmd_local_rx_intent; Loading Loading @@ -2555,6 +2565,7 @@ static int glink_smem_native_probe(struct platform_device *pdev) rc); goto request_irq_fail; } einfo->in_ssr = true; rc = enable_irq_wake(irq_line); if (rc < 0) pr_err("%s: enable_irq_wake() failed on %d\n", __func__, Loading Loading @@ -3102,6 +3113,7 @@ static int glink_mailbox_probe(struct platform_device *pdev) cfg_p_addr = smem_virt_to_phys(mbox_cfg); writel_relaxed(lower_32_bits(cfg_p_addr), mbox_loc); writel_relaxed(upper_32_bits(cfg_p_addr), mbox_loc + 4); einfo->in_ssr = true; send_irq(einfo); iounmap(mbox_size); iounmap(mbox_loc); Loading drivers/soc/qcom/glink_ssr.c +11 −0 Original line number Diff line number Diff line Loading @@ -488,6 +488,17 @@ static int glink_ssr_restart_notifier_cb(struct notifier_block *this, "Subsystem notification failed", ret); return ret; } } else if (code == SUBSYS_AFTER_POWERUP) { GLINK_SSR_LOG("<SSR> %s: %s: subsystem restart for %s\n", __func__, "SUBSYS_AFTER_POWERUP", notifier->subsystem); ss_info = get_info_for_subsystem(notifier->subsystem); if (ss_info == NULL) { GLINK_SSR_ERR("<SSR> %s: ss_info is NULL\n", __func__); return -EINVAL; } glink_subsys_up(ss_info->edge); } return NOTIFY_DONE; } Loading drivers/soc/qcom/glink_xprt_if.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 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 @@ -105,6 +105,7 @@ struct glink_transport_if { void (*tx_cmd_ch_remote_close_ack)(struct glink_transport_if *if_ptr, uint32_t rcid); int (*ssr)(struct glink_transport_if *if_ptr); void (*subsys_up)(struct glink_transport_if *if_ptr); /* channel data */ int (*allocate_rx_intent)(struct glink_transport_if *if_ptr, Loading Loading
drivers/soc/qcom/glink.c +36 −0 Original line number Diff line number Diff line Loading @@ -457,6 +457,42 @@ static void glink_put_ch_ctx(struct channel_ctx *ctx) rwref_put(&ctx->ch_state_lhb2); } /** * glink_subsys_up() - Inform transport about remote subsystem up. * @subsystem: The name of the subsystem * * Call into the transport using the subsys_up(if_ptr) function to allow it to * initialize any necessary structures. * * Return: Standard error codes. */ int glink_subsys_up(const char *subsystem) { int ret = 0; bool transport_found = false; struct glink_core_xprt_ctx *xprt_ctx = NULL; mutex_lock(&transport_list_lock_lha0); list_for_each_entry(xprt_ctx, &transport_list, list_node) { if (!strcmp(subsystem, xprt_ctx->edge) && !xprt_is_fully_opened(xprt_ctx)) { GLINK_INFO_XPRT(xprt_ctx, "%s: %s Subsystem up\n", __func__, subsystem); if (xprt_ctx->ops->subsys_up) xprt_ctx->ops->subsys_up(xprt_ctx->ops); transport_found = true; } } mutex_unlock(&transport_list_lock_lha0); if (!transport_found) ret = -ENODEV; return ret; } EXPORT_SYMBOL(glink_subsys_up); /** * glink_ssr() - Clean up locally for SSR by simulating remote close * @subsystem: The name of the subsystem being restarted Loading
drivers/soc/qcom/glink_private.h +9 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 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 @@ -824,6 +824,14 @@ uint32_t glink_ssr_get_seq_num(void); */ int glink_ssr(const char *subsystem); /* * glink_subsys_up() - SSR sub system up function. * @subsystem: Constant string for name of remote subsystem. * * Return: Standard error code. */ int glink_subsys_up(const char *subsystem); /** * notify for subsystem() - Notify other subsystems that a subsystem is being * restarted Loading
drivers/soc/qcom/glink_smem_native_xprt.c +21 −9 Original line number Diff line number Diff line Loading @@ -947,15 +947,6 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx) rcu_id = srcu_read_lock(&einfo->use_ref); if (unlikely(!einfo->rx_fifo) && atomic_ctx) { if (!get_rx_fifo(einfo)) { srcu_read_unlock(&einfo->use_ref, rcu_id); return; } einfo->in_ssr = false; einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if); } if (einfo->in_ssr) { srcu_read_unlock(&einfo->use_ref, rcu_id); return; Loading Loading @@ -1568,6 +1559,24 @@ static void tx_cmd_ch_remote_close_ack(struct glink_transport_if *if_ptr, srcu_read_unlock(&einfo->use_ref, rcu_id); } /** * subsys_up() - process a subsystem up notification * @if_ptr: The transport which is up * */ static void subsys_up(struct glink_transport_if *if_ptr) { struct edge_info *einfo; einfo = container_of(if_ptr, struct edge_info, xprt_if); if (!einfo->rx_fifo) { if (!get_rx_fifo(einfo)) return; einfo->in_ssr = false; einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if); } } /** * ssr() - process a subsystem restart notification of a transport * @if_ptr: The transport to restart Loading Loading @@ -2261,6 +2270,7 @@ static void init_xprt_if(struct edge_info *einfo) einfo->xprt_if.tx_cmd_ch_remote_open_ack = tx_cmd_ch_remote_open_ack; einfo->xprt_if.tx_cmd_ch_remote_close_ack = tx_cmd_ch_remote_close_ack; einfo->xprt_if.ssr = ssr; einfo->xprt_if.subsys_up = subsys_up; einfo->xprt_if.allocate_rx_intent = allocate_rx_intent; einfo->xprt_if.deallocate_rx_intent = deallocate_rx_intent; einfo->xprt_if.tx_cmd_local_rx_intent = tx_cmd_local_rx_intent; Loading Loading @@ -2555,6 +2565,7 @@ static int glink_smem_native_probe(struct platform_device *pdev) rc); goto request_irq_fail; } einfo->in_ssr = true; rc = enable_irq_wake(irq_line); if (rc < 0) pr_err("%s: enable_irq_wake() failed on %d\n", __func__, Loading Loading @@ -3102,6 +3113,7 @@ static int glink_mailbox_probe(struct platform_device *pdev) cfg_p_addr = smem_virt_to_phys(mbox_cfg); writel_relaxed(lower_32_bits(cfg_p_addr), mbox_loc); writel_relaxed(upper_32_bits(cfg_p_addr), mbox_loc + 4); einfo->in_ssr = true; send_irq(einfo); iounmap(mbox_size); iounmap(mbox_loc); Loading
drivers/soc/qcom/glink_ssr.c +11 −0 Original line number Diff line number Diff line Loading @@ -488,6 +488,17 @@ static int glink_ssr_restart_notifier_cb(struct notifier_block *this, "Subsystem notification failed", ret); return ret; } } else if (code == SUBSYS_AFTER_POWERUP) { GLINK_SSR_LOG("<SSR> %s: %s: subsystem restart for %s\n", __func__, "SUBSYS_AFTER_POWERUP", notifier->subsystem); ss_info = get_info_for_subsystem(notifier->subsystem); if (ss_info == NULL) { GLINK_SSR_ERR("<SSR> %s: ss_info is NULL\n", __func__); return -EINVAL; } glink_subsys_up(ss_info->edge); } return NOTIFY_DONE; } Loading
drivers/soc/qcom/glink_xprt_if.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 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 @@ -105,6 +105,7 @@ struct glink_transport_if { void (*tx_cmd_ch_remote_close_ack)(struct glink_transport_if *if_ptr, uint32_t rcid); int (*ssr)(struct glink_transport_if *if_ptr); void (*subsys_up)(struct glink_transport_if *if_ptr); /* channel data */ int (*allocate_rx_intent)(struct glink_transport_if *if_ptr, Loading