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

Commit b8442aa8 authored by Perry Randise's avatar Perry Randise Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa3: IPA clock vote ioctl



The ability to vote IPA clock from user space is now required. Given
this, voting for IPA clock can now be done via an ioctl. These changes
implement the ioctl.

Change-Id: Id7e02678e96da98f2a17f35e7f6736fba39ca990
CRs-Fixed: 2592003
Signed-off-by: default avatarPerry Randise <prandise@codeaurora.org>
parent db3244b7
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, 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
@@ -2897,6 +2897,10 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
			retval = -EFAULT;
			break;
		}

	case IPA_IOC_APP_CLOCK_VOTE:
		retval = ipa3_app_clk_vote(
			(enum ipa_app_clock_vote_type) arg);
		break;

	default:
@@ -4834,6 +4838,9 @@ long compat_ipa3_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
	case IPA_IOC_GET_NAT_IN_SRAM_INFO32:
		cmd = IPA_IOC_GET_NAT_IN_SRAM_INFO;
		break;
	case IPA_IOC_APP_CLOCK_VOTE32:
		cmd = IPA_IOC_APP_CLOCK_VOTE;
		break;
	case IPA_IOC_COMMIT_HDR:
	case IPA_IOC_RESET_HDR:
	case IPA_IOC_COMMIT_RT:
@@ -7159,7 +7166,11 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
	/* proxy vote for modem is added in ipa3_post_init() phase */
	if (ipa3_ctx->ipa_hw_type != IPA_HW_v4_0)
		ipa3_proxy_clk_unvote();

	mutex_init(&ipa3_ctx->app_clock_vote.mutex);

	return 0;

fail_cdev_add:
fail_gsi_pre_fw_load_init:
	ipa_eth_exit();
+22 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, 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
@@ -2467,6 +2467,22 @@ static ssize_t ipa3_read_usb_gsi_stats(struct file *file,
	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
}

static ssize_t ipa3_read_app_clk_vote(
	struct file *file,
	char __user *ubuf,
	size_t count,
	loff_t *ppos)
{
	int cnt =
		scnprintf(
			dbg_buff,
			IPA_MAX_MSG_LEN,
			"%u\n",
			ipa3_ctx->app_clock_vote.cnt);

	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
}

static void ipa_dump_status(struct ipahal_pkt_status *status)
{
	IPA_DUMP_STATUS_FIELD(status_opcode);
@@ -2769,7 +2785,11 @@ static const struct ipa3_debugfs_file debugfs_files[] = {
		"usb_gsi_stats", IPA_READ_ONLY_MODE, NULL, {
			.read = ipa3_read_usb_gsi_stats,
		}
	}, {
		"app_clk_vote_cnt", IPA_READ_ONLY_MODE, NULL, {
			.read = ipa3_read_app_clk_vote,
		}
	},
};

void ipa3_debugfs_pre_init(void)
+14 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, 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
@@ -252,6 +252,8 @@ enum {
# define __cpuc_flush_dcache_area __flush_dcache_area
#endif

#define IPA_APP_VOTE_MAX 500

#define IPA_SMP2P_OUT_CLK_RSP_CMPLT_IDX 0
#define IPA_SMP2P_OUT_CLK_VOTE_IDX 1
#define IPA_SMP2P_SMEM_STATE_MASK 3
@@ -443,6 +445,9 @@ enum {
#define IPA_IOC_GET_NAT_IN_SRAM_INFO32 _IOWR(IPA_IOC_MAGIC, \
				IPA_IOCTL_GET_NAT_IN_SRAM_INFO, \
				compat_uptr_t)
#define IPA_IOC_APP_CLOCK_VOTE32 _IOWR(IPA_IOC_MAGIC, \
				IPA_IOCTL_APP_CLOCK_VOTE, \
				compat_uptr_t)
#endif /* #ifdef CONFIG_COMPAT */

#define IPA_TZ_UNLOCK_ATTRIBUTE 0x0C0311
@@ -1724,6 +1729,11 @@ struct ipa3_pc_mbox_data {
	struct mbox_chan *mbox;
};

struct ipa3_app_clock_vote {
	struct mutex mutex;
	u32 cnt;
};

/**
 * struct ipa3_context - IPA context
 * @cdev: cdev context
@@ -1815,6 +1825,7 @@ struct ipa3_pc_mbox_data {
 * @flt_rt_counters: the counters usage info for flt rt stats
 * @wdi3_ctx: IPA wdi3 context
 * @gsi_info: channel/protocol info for GSI offloading uC stats
 * @app_vote: holds userspace application clock vote count
 * IPA context - holds all relevant info about IPA driver and its state
 * @coal_cmd_pyld: holds the coslescing close frame command payload
 */
@@ -1989,6 +2000,7 @@ struct ipa3_context {
	bool ipa_mhi_proxy;
	bool ipa_wan_skb_page;
	struct ipahal_imm_cmd_pyld *coal_cmd_pyld;
	struct ipa3_app_clock_vote app_clock_vote;
};

struct ipa3_plat_drv_res {
@@ -2491,6 +2503,7 @@ int ipa3_del_ipv6ct_table(struct ipa_ioc_nat_ipv6ct_table_del *del);

int ipa3_nat_mdfy_pdn(struct ipa_ioc_nat_pdn_entry *mdfy_pdn);
int ipa3_nat_get_sram_info(struct ipa_nat_in_sram_info *info_ptr);
int ipa3_app_clk_vote(enum ipa_app_clock_vote_type vote_type);

/*
 * Messaging
+46 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, 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
@@ -8846,3 +8846,48 @@ int ipa3_get_prot_id(enum ipa_client_type client)
	return prot_id;
}

int ipa3_app_clk_vote(
	enum ipa_app_clock_vote_type vote_type)
{
	const char *str_ptr = "APP_VOTE";
	int ret = 0;

	IPADBG("In\n");

	mutex_lock(&ipa3_ctx->app_clock_vote.mutex);

	switch (vote_type) {
	case IPA_APP_CLK_VOTE:
		if ((ipa3_ctx->app_clock_vote.cnt + 1) <= IPA_APP_VOTE_MAX) {
			ipa3_ctx->app_clock_vote.cnt++;
			IPA_ACTIVE_CLIENTS_INC_SPECIAL(str_ptr);
		} else {
			IPAERR_RL("App vote count max hit\n");
			ret = -EPERM;
			break;
		}
		break;
	case IPA_APP_CLK_DEVOTE:
		if (ipa3_ctx->app_clock_vote.cnt) {
			ipa3_ctx->app_clock_vote.cnt--;
			IPA_ACTIVE_CLIENTS_DEC_SPECIAL(str_ptr);
		}
		break;
	case IPA_APP_CLK_RESET_VOTE:
		while (ipa3_ctx->app_clock_vote.cnt > 0) {
			IPA_ACTIVE_CLIENTS_DEC_SPECIAL(str_ptr);
			ipa3_ctx->app_clock_vote.cnt--;
		}
		break;
	default:
		IPAERR_RL("Unknown vote_type(%u)\n", vote_type);
		ret = -EPERM;
		break;
	}

	mutex_unlock(&ipa3_ctx->app_clock_vote.mutex);

	IPADBG("Out\n");

	return ret;
}