// SPDX-License-Identifier: GPL-2.0-only
/*
 *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
 */


#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>

#include <getopt.h>

#include "cpufreq.h"
#include "cpuidle.h"
#include "helpers/helpers.h"

#define NORM_FREQ_LEN 32

static struct option set_opts[] = {
	{"min",		required_argument,	NULL, 'd'},
	{"max",		required_argument,	NULL, 'u'},
	{"governor",	required_argument,	NULL, 'g'},
	{"freq",	required_argument,	NULL, 'f'},
	{"related",	no_argument,		NULL, 'r'},
	{ },
};

static void print_error(void)
{
	printf(_("Error setting new values. Common errors:\n"
			"- Do you have proper administration rights? (super-user?)\n"
			"- Is the governor you requested available and modprobed?\n"
			"- Trying to set an invalid policy?\n"
			"- Trying to set a specific frequency, but userspace governor is not available,\n"
			"   for example because of hardware which cannot be set to a specific frequency\n"
			"   or because the userspace governor isn't loaded?\n"));
};

struct freq_units {
	char		*str_unit;
	int		power_of_ten;
};

const struct freq_units def_units[] = {
	{"hz", -3},
	{"khz", 0}, /* default */
	{"mhz", 3},
	{"ghz", 6},
	{"thz", 9},
	{NULL, 0}
};

static void print_unknown_arg(void)
{
	printf(_("invalid or unknown argument\n"));
}

static unsigned long string_to_frequency(const char *str)
{
	char normalized[NORM_FREQ_LEN];
	const struct freq_units *unit;
	const char *scan;
	char *end;
	unsigned long freq;
	int power = 0, match_count = 0, i, cp, pad;

	while (*str == '0')
		str++;

	for (scan = str; isdigit(*scan) || *scan == '.'; scan++) {
		if (*scan == '.' && match_count == 0)
			match_count = 1;
		else if (*scan == '.' && match_count == 1)
			return 0;
	}

	if (*scan) {
		match_count = 0;
		for (unit = def_units; unit->str_unit; unit++) {
			for (i = 0;
			     scan[i] && tolower(scan[i]) == unit->str_unit[i];
			     ++i)
				continue;
			if (scan[i])
				continue;
			match_count++;
			power = unit->power_of_ten;
		}
		if (match_count != 1)
			return 0;
	}

	/* count the number of digits to be copied */
	for (cp = 0; isdigit(str[cp]); cp++)
		continue;

	if (str[cp] == '.') {
		while (power > -1 && isdigit(str[cp+1])) {
			cp++;
			power--;
		}
	}
	if (power >= -1) {		/* not enough => pad */
		pad = power + 1;
	} else {			/* too much => strip */
		pad = 0;
		cp += power + 1;
	}
	/* check bounds */
	if (cp <= 0 || cp + pad > NORM_FREQ_LEN - 1)
		return 0;

	/* copy digits */
	for (i = 0; i < cp; i++, str++) {
		if (*str == '.')
			str++;
		normalized[i] = *str;
	}
	/* and pad */
	for (; i < cp + pad; i++)
		normalized[i] = '0';

	/* round up, down ? */
	match_count = (normalized[i-1] >= '5');
	/* and drop the decimal part */
	normalized[i-1] = 0; /* cp > 0 && pad >= 0 ==> i > 0 */

	/* final conversion (and applying rounding) */
	errno = 0;
	freq = strtoul(normalized, &end, 10);
	if (errno)
		return 0;
	else {
		if (match_count && freq != ULONG_MAX)
			freq++;
		return freq;
	}
}

static int do_new_policy(unsigned int cpu, struct cpufreq_policy *new_pol)
{
	struct cpufreq_policy *cur_pol = cpufreq_get_policy(cpu);
	int ret;

	if (!cur_pol) {
		printf(_("wrong, unknown or unhandled CPU?\n"));
		return -EINVAL;
	}

	if (!new_pol->min)
		new_pol->min = cur_pol->min;

	if (!new_pol->max)
		new_pol->max = cur_pol->max;

	if (!new_pol->governor)
		new_pol->governor = cur_pol->governor;

	ret = cpufreq_set_policy(cpu, new_pol);

	cpufreq_put_policy(cur_pol);

	return ret;
}


static int do_one_cpu(unsigned int cpu, struct cpufreq_policy *new_pol,
		unsigned long freq, unsigned int pc)
{
	switch (pc) {
	case 0:
		return cpufreq_set_frequency(cpu, freq);

	case 1:
		/* if only one value of a policy is to be changed, we can
		 * use a "fast path".
		 */
		if (new_pol->min)
			return cpufreq_modify_policy_min(cpu, new_pol->min);
		else if (new_pol->max)
			return cpufreq_modify_policy_max(cpu, new_pol->max);
		else if (new_pol->governor)
			return cpufreq_modify_policy_governor(cpu,
							new_pol->governor);

	default:
		/* slow path */
		return do_new_policy(cpu, new_pol);
	}
}

int cmd_freq_set(int argc, char **argv)
{
	extern char *optarg;
	extern int optind, opterr, optopt;
	int ret = 0, cont = 1;
	int double_parm = 0, related = 0, policychange = 0;
	unsigned long freq = 0;
	char gov[20];
	unsigned int cpu;

	struct cpufreq_policy new_pol = {
		.min = 0,
		.max = 0,
		.governor = NULL,
	};

	/* parameter parsing */
	do {
		ret = getopt_long(argc, argv, "d:u:g:f:r", set_opts, NULL);
		switch (ret) {
		case '?':
			print_unknown_arg();
			return -EINVAL;
		case -1:
			cont = 0;
			break;
		case 'r':
			if (related)
				double_parm++;
			related++;
			break;
		case 'd':
			if (new_pol.min)
				double_parm++;
			policychange++;
			new_pol.min = string_to_frequency(optarg);
			if (new_pol.min == 0) {
				print_unknown_arg();
				return -EINVAL;
			}
			break;
		case 'u':
			if (new_pol.max)
				double_parm++;
			policychange++;
			new_pol.max = string_to_frequency(optarg);
			if (new_pol.max == 0) {
				print_unknown_arg();
				return -EINVAL;
			}
			break;
		case 'f':
			if (freq)
				double_parm++;
			freq = string_to_frequency(optarg);
			if (freq == 0) {
				print_unknown_arg();
				return -EINVAL;
			}
			break;
		case 'g':
			if (new_pol.governor)
				double_parm++;
			policychange++;
			if ((strlen(optarg) < 3) || (strlen(optarg) > 18)) {
				print_unknown_arg();
				return -EINVAL;
			}
			if ((sscanf(optarg, "%19s", gov)) != 1) {
				print_unknown_arg();
				return -EINVAL;
			}
			new_pol.governor = gov;
			break;
		}
	} while (cont);

	/* parameter checking */
	if (double_parm) {
		printf("the same parameter was passed more than once\n");
		return -EINVAL;
	}

	if (freq && policychange) {
		printf(_("the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
				"-g/--governor parameters\n"));
		return -EINVAL;
	}

	if (!freq && !policychange) {
		printf(_("At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
				"-g/--governor must be passed\n"));
		return -EINVAL;
	}

	/* Default is: set all CPUs */
	if (bitmask_isallclear(cpus_chosen))
		bitmask_setall(cpus_chosen);

	/* Also set frequency settings for related CPUs if -r is passed */
	if (related) {
		for (cpu = bitmask_first(cpus_chosen);
		     cpu <= bitmask_last(cpus_chosen); cpu++) {
			struct cpufreq_affected_cpus *cpus;

			if (!bitmask_isbitset(cpus_chosen, cpu) ||
			    cpupower_is_cpu_online(cpu) != 1)
				continue;

			cpus = cpufreq_get_related_cpus(cpu);
			if (!cpus)
				break;
			while (cpus->next) {
				bitmask_setbit(cpus_chosen, cpus->cpu);
				cpus = cpus->next;
			}
			/* Set the last cpu in related cpus list */
			bitmask_setbit(cpus_chosen, cpus->cpu);
			cpufreq_put_related_cpus(cpus);
		}
	}

	get_cpustate();

	/* loop over CPUs */
	for (cpu = bitmask_first(cpus_chosen);
	     cpu <= bitmask_last(cpus_chosen); cpu++) {

		if (!bitmask_isbitset(cpus_chosen, cpu) ||
		    cpupower_is_cpu_online(cpu) != 1)
			continue;

		printf(_("Setting cpu: %d\n"), cpu);
		ret = do_one_cpu(cpu, &new_pol, freq, policychange);
		if (ret) {
			print_error();
			return ret;
		}
	}

	print_offline_cpus();

	return 0;
}
