Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f4cbe5b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: ipc_router: Add dynamic enable/disable wakeup source feature"

parents eb95a560 74ff856e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ Optional properties:
			by pil. Absence of this property indicates that
			subsystem loading through pil voting is disabled for
			that subsystem.
-qcom,dynamic-wakeup-source:	Boolean property to indicate that G-Link
				transport supports dynamic wakeup source

Example:
	qcom,ipc_router_modem_xprt {
+20 −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
@@ -70,6 +70,7 @@ if (ipc_router_glink_xprt_debug_mask) \
 * @xprt_version: IPC Router header version supported by this XPRT.
 * @xprt_option: XPRT specific options to be handled by IPC Router.
 * @disable_pil_loading: Disable PIL Loading of the subsystem.
 * @dynamic_wakeup_source: Dynamic wakeup source for this subsystem.
 */
struct ipc_router_glink_xprt {
	struct list_head list;
@@ -91,6 +92,7 @@ struct ipc_router_glink_xprt {
	uint32_t cur_lo_intents_cnt;
	uint32_t cur_md_intents_cnt;
	uint32_t cur_hi_intents_cnt;
	bool dynamic_wakeup_source;
};

struct ipc_router_glink_xprt_work {
@@ -127,6 +129,7 @@ static void glink_xprt_close_event(struct work_struct *work);
 * @link_id:		Network Cluster ID to which this XPRT belongs to.
 * @xprt_version:	IPC Router header version supported by this XPRT.
 * @disable_pil_loading:Disable PIL Loading of the subsystem.
 * @dynamic_wakeup_source: Dynamic wakeup source for this subsystem.
 */
struct ipc_router_glink_xprt_config {
	char ch_name[GLINK_NAME_SIZE];
@@ -138,6 +141,7 @@ struct ipc_router_glink_xprt_config {
	unsigned int xprt_version;
	unsigned int xprt_option;
	bool disable_pil_loading;
	bool dynamic_wakeup_source;
};

#define MODULE_NAME "ipc_router_glink_xprt"
@@ -294,6 +298,14 @@ static void glink_xprt_sft_close_done(struct msm_ipc_router_xprt *xprt)
	complete_all(&glink_xprtp->sft_close_complete);
}

static bool ipc_router_glink_xprt_get_ws_info(struct msm_ipc_router_xprt *xprt)
{
	struct ipc_router_glink_xprt *glink_xprtp =
		container_of(xprt, struct ipc_router_glink_xprt, xprt);

	return glink_xprtp->dynamic_wakeup_source;
}

static struct rr_packet *glink_xprt_copy_data(struct read_work *rx_work)
{
	void *buf, *pbuf, *dest_buf;
@@ -706,6 +718,8 @@ static int ipc_router_glink_config_init(
	glink_xprtp->xprt_option = glink_xprt_config->xprt_option;
	glink_xprtp->disable_pil_loading =
				glink_xprt_config->disable_pil_loading;
	glink_xprtp->dynamic_wakeup_source =
				glink_xprt_config->dynamic_wakeup_source;

	if (!glink_xprtp->disable_pil_loading)
		strlcpy(glink_xprtp->pil_edge, glink_xprt_config->pil_edge,
@@ -728,6 +742,7 @@ static int ipc_router_glink_config_init(
	glink_xprtp->xprt.write = ipc_router_glink_xprt_write;
	glink_xprtp->xprt.close = ipc_router_glink_xprt_close;
	glink_xprtp->xprt.sft_close_done = glink_xprt_sft_close_done;
	glink_xprtp->xprt.get_ws_info = ipc_router_glink_xprt_get_ws_info;
	glink_xprtp->xprt.priv = NULL;

	init_rwsem(&glink_xprtp->ss_reset_rwlock);
@@ -822,6 +837,10 @@ static int parse_devicetree(struct device_node *node,
	scnprintf(glink_xprt_config->ipc_rtr_xprt_name, IPC_RTR_XPRT_NAME_LEN,
		  "%s_%s", edge, ch_name);

	key = "qcom,dynamic-wakeup-source";
	glink_xprt_config->dynamic_wakeup_source =
					of_property_read_bool(node, key);

	return 0;

error:
+11 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-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
@@ -269,6 +269,14 @@ int register_ipcrtr_af_init_notifier(struct notifier_block *nb);
 */
int unregister_ipcrtr_af_init_notifier(struct notifier_block *nb);

/**
 * msm_ipc_router_set_ws_allowed() - To Enable/disable the wakeup source allowed
 *					flag
 * @flag: Flag to set/clear the wakeup soruce allowed
 *
 */
void msm_ipc_router_set_ws_allowed(bool flag);

#else

struct msm_ipc_port *msm_ipc_router_create_port(
@@ -341,6 +349,8 @@ int unregister_ipcrtr_af_init_notifier(struct notifier_block *nb)
	return -ENODEV;
}

void msm_ipc_router_set_ws_allowed(bool flag) { }

#endif

#endif
+5 −1
Original line number Diff line number Diff line
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-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
@@ -100,6 +100,7 @@ struct rr_opt_hdr {
 * @pkt_fragment_q: Queue of SKBs containing payload.
 * @length: Length of data in the chain of SKBs
 * @ref: Reference count for the packet.
 * @ws_need: Flag to check wakeup soruce need
 */
struct rr_packet {
	struct list_head list;
@@ -108,6 +109,7 @@ struct rr_packet {
	struct sk_buff_head *pkt_fragment_q;
	uint32_t length;
	struct kref ref;
	bool ws_need;
};

/**
@@ -125,6 +127,7 @@ struct rr_packet {
 * @close: Method to close the XPRT.
 * @sft_close_done: Method to indicate to the XPRT that handling of reset
 *                  event is complete.
 * @get_ws_info: Method to get the wakeup soruce inforamtion of the XPRT
 */
struct msm_ipc_router_xprt {
	char *name;
@@ -143,6 +146,7 @@ struct msm_ipc_router_xprt {
		     struct msm_ipc_router_xprt *xprt);
	int (*close)(struct msm_ipc_router_xprt *xprt);
	void (*sft_close_done)(struct msm_ipc_router_xprt *xprt);
	bool (*get_ws_info)(struct msm_ipc_router_xprt *xprt);
};

void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt,
+25 −3
Original line number Diff line number Diff line
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-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
@@ -148,6 +148,7 @@ struct msm_ipc_router_xprt_info {
	void *log_ctx;
	struct kref ref;
	struct completion ref_complete;
	bool dynamic_ws;
};

#define RT_HASH_SIZE 4
@@ -215,6 +216,13 @@ enum {
	UP,
};

static bool is_wakeup_source_allowed;

void msm_ipc_router_set_ws_allowed(bool flag)
{
	is_wakeup_source_allowed = flag;
}

static void init_routing_table(void)
{
	int i;
@@ -580,6 +588,7 @@ struct rr_packet *clone_pkt(struct rr_packet *pkt)
	}
	cloned_pkt->pkt_fragment_q = pkt_fragment_q;
	cloned_pkt->length = pkt->length;
	cloned_pkt->ws_need = pkt->ws_need;
	return cloned_pkt;

fail_clone:
@@ -1162,6 +1171,7 @@ static int post_pkt_to_port(struct msm_ipc_port *port_ptr,
	}

	mutex_lock(&port_ptr->port_rx_q_lock_lhc3);
	if (pkt->ws_need)
		__pm_stay_awake(port_ptr->port_rx_ws);
	list_add_tail(&temp_pkt->list, &port_ptr->port_rx_q);
	wake_up(&port_ptr->port_rx_wait_q);
@@ -4043,6 +4053,9 @@ static int msm_ipc_router_add_xprt(struct msm_ipc_router_xprt *xprt)
	INIT_LIST_HEAD(&xprt_info->list);
	kref_init(&xprt_info->ref);
	init_completion(&xprt_info->ref_complete);
	xprt_info->dynamic_ws = 0;
	if (xprt->get_ws_info)
		xprt_info->dynamic_ws = xprt->get_ws_info(xprt);

	xprt_info->workqueue = create_singlethread_workqueue(xprt->name);
	if (!xprt_info->workqueue) {
@@ -4193,9 +4206,18 @@ void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt,
	if (!pkt)
		return;

	pkt->ws_need = false;
	mutex_lock(&xprt_info->rx_lock_lhb2);
	list_add_tail(&pkt->list, &xprt_info->pkt_list);
	if (!xprt_info->dynamic_ws) {
		__pm_stay_awake(&xprt_info->ws);
		pkt->ws_need = true;
	} else {
		if (is_wakeup_source_allowed) {
			__pm_stay_awake(&xprt_info->ws);
			pkt->ws_need = true;
		}
	}
	mutex_unlock(&xprt_info->rx_lock_lhb2);
	queue_work(xprt_info->workqueue, &xprt_info->read_data);
}