diff options
| author | Linux Build Service Account <lnxbuild@quicinc.com> | 2018-01-13 03:50:14 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-01-13 03:50:13 -0800 |
| commit | 879163d5997e9dbb89f086db857ab98f86ab680c (patch) | |
| tree | 75201aec39bca675aa1af9b3fd2ca1cae56aa4fe | |
| parent | ee6f57508906453501cb8c1ce0017e007bae4fbd (diff) | |
| parent | f43f0483211fd5389879a624c171973d8084f1e3 (diff) | |
Merge "soc: qcom: glink: Add sub system up notification in glink"
| -rw-r--r-- | drivers/soc/qcom/glink.c | 36 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_private.h | 10 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_smem_native_xprt.c | 32 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_ssr.c | 13 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_xprt_if.h | 3 |
5 files changed, 81 insertions, 13 deletions
diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index f21e9c4c4f4e..813c97bb4a50 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.c @@ -455,6 +455,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 diff --git a/drivers/soc/qcom/glink_private.h b/drivers/soc/qcom/glink_private.h index e91ad30f73ab..c94ca7d57b2f 100644 --- a/drivers/soc/qcom/glink_private.h +++ b/drivers/soc/qcom/glink_private.h @@ -1,4 +1,4 @@ -/* 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 @@ -817,6 +817,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 diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c index a678e03235c0..4407dfbc45df 100644 --- a/drivers/soc/qcom/glink_smem_native_xprt.c +++ b/drivers/soc/qcom/glink_smem_native_xprt.c @@ -1,4 +1,4 @@ -/* 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 @@ -876,15 +876,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; @@ -1487,6 +1478,24 @@ static void tx_cmd_ch_remote_close_ack(struct glink_transport_if *if_ptr, } /** + * 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 * @@ -2166,6 +2175,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; @@ -2437,6 +2447,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__, @@ -2941,6 +2952,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); diff --git a/drivers/soc/qcom/glink_ssr.c b/drivers/soc/qcom/glink_ssr.c index fb003bd5d35b..fe7fb1e5b925 100644 --- a/drivers/soc/qcom/glink_ssr.c +++ b/drivers/soc/qcom/glink_ssr.c @@ -1,4 +1,4 @@ -/* 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 @@ -490,6 +490,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; } diff --git a/drivers/soc/qcom/glink_xprt_if.h b/drivers/soc/qcom/glink_xprt_if.h index 47c15807e379..1902152d91cb 100644 --- a/drivers/soc/qcom/glink_xprt_if.h +++ b/drivers/soc/qcom/glink_xprt_if.h @@ -1,4 +1,4 @@ -/* 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 @@ -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, |
