/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2018 Google, LLC
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include <linux/of.h>
#include <linux/delay.h>
#include <linux/ktime.h>
#include <linux/math64.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
#include <linux/thermal.h>
#include <misc/gvotable.h>
#include "gbms_power_supply.h"
#include "google_psy.h"

#define USB_OVERHEAT_MITIGATION_VOTER	"USB_OVERHEAT_MITIGATION_VOTER"

enum {
	USB_NO_LIMIT = 0,
	USB_OVERHEAT_THROTTLE = 1,
	USB_MAX_THROTTLE_STATE = USB_OVERHEAT_THROTTLE,
};

static bool mitigation_enabled = true;
module_param_named(
	enable, mitigation_enabled, bool, 0600
);

struct overheat_event_stats {
	int plug_temp;
	int max_temp;
	int trip_time;
	int hysteresis_time;
	int cleared_time;
};

struct overheat_info {
	struct device              *dev;
	struct power_supply        *usb_psy;
	struct gvotable_election   *usb_icl_votable;
	struct gvotable_election   *disable_power_role_switch;
	struct notifier_block      psy_nb;
	struct delayed_work        port_overheat_work;
	struct wakeup_source	   *overheat_ws;
	struct overheat_event_stats stats;
	struct thermal_cooling_device *cooling_dev;

	bool usb_connected;
	bool accessory_connected;
	bool usb_replug;
	bool overheat_mitigation;
	bool overheat_work_running;

	int temp;
	int plug_temp;
	int max_temp;
	ktime_t plug_time;
	ktime_t trip_time;
	ktime_t hysteresis_time;

	int begin_temp;
	int clear_temp;
	int overheat_work_delay_ms;
	int polling_freq;
	int check_status;
	unsigned long throttle_state;
};

#define OVH_ATTR(_name)							\
static ssize_t _name##_show(struct device *dev,				\
				     struct device_attribute *attr,	\
				     char *buf)				\
{									\
	struct overheat_info *ovh_info = dev_get_drvdata(dev);		\
									\
	return scnprintf(buf, PAGE_SIZE, "%d\n", ovh_info->stats._name);\
}									\
static DEVICE_ATTR_RO(_name);

OVH_ATTR(max_temp);
OVH_ATTR(plug_temp);
OVH_ATTR(trip_time);
OVH_ATTR(hysteresis_time);
OVH_ATTR(cleared_time);

static struct attribute *ovh_attr[] = {
	&dev_attr_max_temp.attr,
	&dev_attr_plug_temp.attr,
	&dev_attr_hysteresis_time.attr,
	&dev_attr_trip_time.attr,
	&dev_attr_cleared_time.attr,
	NULL,
};

static const struct attribute_group ovh_attr_group = {
	.attrs = ovh_attr,
};

static inline ktime_t get_seconds_since_boot(void)
{
	return div_u64(ktime_to_ns(ktime_get_boottime()), NSEC_PER_SEC);
}

static inline int get_dts_vars(struct overheat_info *ovh_info)
{
	struct device *dev = ovh_info->dev;
	struct device_node *node = dev->of_node;
	int ret;

	ret = of_property_read_u32(node, "google,begin-mitigation-temp",
				   &ovh_info->begin_temp);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"cannot read begin-mitigation-temp, ret=%d\n", ret);
		return ret;
	}

	ret = of_property_read_u32(node, "google,end-mitigation-temp",
				   &ovh_info->clear_temp);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"cannot read end-mitigation-temp, ret=%d\n", ret);
		return ret;
	}

	ret = of_property_read_u32(node, "google,port-overheat-work-interval",
				   &ovh_info->overheat_work_delay_ms);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"cannot read port-overheat-work-interval, ret=%d\n",
			ret);
		return ret;
	}

	ret = of_property_read_u32(node, "google,polling-freq",
				   &ovh_info->polling_freq);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"cannot read polling-freq, ret=%d\n", ret);
		return ret;
	}

	return 0;
}

static int suspend_usb(struct overheat_info *ovh_info)
{
	int ret;

	ovh_info->usb_replug = false;

	/* disable USB */
	ret = gvotable_cast_bool_vote(ovh_info->disable_power_role_switch,
				      USB_OVERHEAT_MITIGATION_VOTER, true);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"Couldn't vote for disable_power_role_switch ret=%d\n",
			ret);
		return ret;
	}

	/* suspend charging */
	ret = gvotable_cast_int_vote(ovh_info->usb_icl_votable,
				     USB_OVERHEAT_MITIGATION_VOTER, 0, true);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"Couldn't vote for USB ICL ret=%d\n", ret);
		return ret;
	}

	ovh_info->trip_time = get_seconds_since_boot();
	ovh_info->overheat_mitigation = true;
	return ret;
}

static int resume_usb(struct overheat_info *ovh_info)
{
	int ret;

	/* Fill out stats so userspace can read them. */
	ovh_info->stats.max_temp = ovh_info->max_temp;
	ovh_info->stats.plug_temp = ovh_info->plug_temp;
	ovh_info->stats.trip_time =
		(int) (ovh_info->trip_time - ovh_info->plug_time);
	ovh_info->stats.hysteresis_time =
		(int) (ovh_info->hysteresis_time - ovh_info->trip_time);
	ovh_info->stats.cleared_time =
		(int) (get_seconds_since_boot() - ovh_info->hysteresis_time);

	/* enable charging */
	ret = gvotable_cast_int_vote(ovh_info->usb_icl_votable,
				     USB_OVERHEAT_MITIGATION_VOTER, 0, false);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"Couldn't un-vote for USB ICL ret=%d\n", ret);
		return ret;
	}

	/* enable USB */
	ret = gvotable_cast_bool_vote(ovh_info->disable_power_role_switch,
				      USB_OVERHEAT_MITIGATION_VOTER, false);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"Couldn't un-vote for disable_power_role_switch ret=%d\n",
			ret);
		return ret;
	}

	/* Notify userspace to read the stats. */
	kobject_uevent(&ovh_info->dev->kobj, KOBJ_CHANGE);

	ovh_info->max_temp = INT_MIN;
	ovh_info->plug_temp = INT_MIN;
	ovh_info->plug_time = 0;
	ovh_info->trip_time = 0;
	ovh_info->hysteresis_time = 0;
	ovh_info->overheat_mitigation = false;
	ovh_info->usb_replug = false;
	return ret;
}

/*
 * Update usb_connected, accessory_connected, usb_replug, and plug_temp
 * status in overheat_info struct.
 */
static int update_usb_status(struct overheat_info *ovh_info)
{
	int ret;
	bool prev_state = ovh_info->usb_connected ||
		ovh_info->accessory_connected;
	bool curr_state;
	int *check_status = &ovh_info->check_status;
	int mode;

	/* Port is too hot to safely check the connected status. */
	if (ovh_info->overheat_mitigation &&
	    ovh_info->temp > ovh_info->clear_temp)
		return -EBUSY;

	if (ovh_info->overheat_mitigation) {
		if (!ovh_info->hysteresis_time)
			ovh_info->hysteresis_time = get_seconds_since_boot();
		// Only check USB status every polling_freq instances
		*check_status = (*check_status + 1) % ovh_info->polling_freq;
		if (*check_status > 0)
			return 0;
		ret = gvotable_cast_bool_vote(ovh_info->disable_power_role_switch,
					      USB_OVERHEAT_MITIGATION_VOTER, false);
		if (ret < 0) {
			dev_err(ovh_info->dev,
				"Couldn't un-vote for disable_power_role_switch ret=%d\n",
				ret);
			return ret;
		}
		msleep(200);
	}

	dev_dbg(ovh_info->dev, "Updating USB connected status\n");

	/*
	 * Update USB present status to determine if USB has been disconnected.
	 * If we use USB online status to determine replug, we will need to
	 * extend the delay between re-enabling CC detection and checking the
	 * USB online status.
	 */
	ret = GPSY_GET_PROP(ovh_info->usb_psy, POWER_SUPPLY_PROP_PRESENT);
	if (ret < 0)
		return ret;
	ovh_info->usb_connected = ret;

#ifdef CONFIG_USB_ONLINE_IS_TYPEC_MODE
	ret = GPSY_GET_INT_PROP(ovh_info->usb_psy, POWER_SUPPLY_PROP_TYPEC_MODE, &mode);
#else
	ret = GPSY_GET_INT_PROP(ovh_info->usb_psy, POWER_SUPPLY_PROP_ONLINE, &mode);
#endif
	pr_debug("%s: TYPEC mode=%d ret=%d\n", __func__, mode, ret);
	if (ret < 0)
		return ret;

	ovh_info->accessory_connected = (mode == POWER_SUPPLY_TYPEC_SINK) ||
			(mode == POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE);

	curr_state = ovh_info->usb_connected || ovh_info->accessory_connected;
	if (curr_state && !prev_state) {
		ovh_info->plug_time = get_seconds_since_boot();
		ovh_info->plug_temp = ovh_info->temp;
	}

	if (ovh_info->overheat_mitigation) {
		ret = gvotable_cast_bool_vote(ovh_info->disable_power_role_switch,
					      USB_OVERHEAT_MITIGATION_VOTER, true);
		if (ret < 0) {
			dev_err(ovh_info->dev,
				"Couldn't vote for disable_power_role_switch ret=%d\n",
				ret);
			return ret;
		}
	}

	if (curr_state != prev_state)
		dev_info(ovh_info->dev,
			 "USB is %sconnected",
			 curr_state ? "" : "dis");

	// USB should be disconnected for two cycles before replug is acked
	if (ovh_info->overheat_mitigation && !curr_state && !prev_state)
		ovh_info->usb_replug = true;

	return 0;
}

static inline int get_usb_port_temp(struct overheat_info *ovh_info)
{
	int temp;

	temp = GPSY_GET_PROP(ovh_info->usb_psy, POWER_SUPPLY_PROP_TEMP);

	if (temp == -EINVAL || temp == -ENODATA)
		return temp;

	dev_info(ovh_info->dev, "Update USB port temp:%d\n", temp);
	if (temp > ovh_info->max_temp)
		ovh_info->max_temp = temp;

	ovh_info->temp = temp;
	return 0;
}

static int psy_changed(struct notifier_block *nb, unsigned long action,
		       void *data)
{
	struct power_supply *psy = data;
	struct overheat_info *ovh_info =
			container_of(nb, struct overheat_info, psy_nb);

	if ((action != PSY_EVENT_PROP_CHANGED) || (psy == NULL) ||
	    (psy->desc == NULL) || (psy->desc->name == NULL))
		return NOTIFY_OK;

	if (action == PSY_EVENT_PROP_CHANGED &&
	    !strcmp(psy->desc->name, "usb")) {
		dev_dbg(ovh_info->dev, "name=usb evt=%lu\n", action);
		if (!ovh_info->overheat_work_running)
			schedule_delayed_work(&ovh_info->port_overheat_work, 0);
	}
	return NOTIFY_OK;
}

static void port_overheat_work(struct work_struct *work)
{
	struct overheat_info *ovh_info =
			container_of(work, struct overheat_info,
				     port_overheat_work.work);
	int ret = 0;

	// Take a wake lock to ensure we poll the temp regularly
	if (!ovh_info->overheat_work_running)
		__pm_stay_awake(ovh_info->overheat_ws);
	ovh_info->overheat_work_running = true;

	if (get_usb_port_temp(ovh_info) < 0)
		goto rerun;

	ret = update_usb_status(ovh_info);
	if (ret < 0)
		goto rerun;

	if (ovh_info->overheat_mitigation && (!mitigation_enabled ||
	    (ovh_info->temp < ovh_info->clear_temp && ovh_info->usb_replug))) {
		dev_err(ovh_info->dev, "Port overheat mitigated\n");
		resume_usb(ovh_info);
	} else if (!ovh_info->overheat_mitigation &&
		 mitigation_enabled && ovh_info->temp > ovh_info->begin_temp) {
		dev_err(ovh_info->dev, "Port overheat triggered\n");
		suspend_usb(ovh_info);
		goto rerun;
	}

	if (ovh_info->overheat_mitigation || ovh_info->throttle_state)
		goto rerun;
	// Do not run again, USB port isn't overheated
	ovh_info->overheat_work_running = false;
	__pm_relax(ovh_info->overheat_ws);
	return;

rerun:
	schedule_delayed_work(
			&ovh_info->port_overheat_work,
			msecs_to_jiffies(ovh_info->overheat_work_delay_ms));
}

static int usb_get_cur_state(struct thermal_cooling_device *cooling_dev,
							unsigned long *state)
{
	struct overheat_info *ovh_info = cooling_dev->devdata;

	if (!ovh_info)
		return -EINVAL;

	*state = ovh_info->throttle_state;

	return 0;
}

static int usb_get_max_state(struct thermal_cooling_device *cooling_dev,
							unsigned long *state)
{
	*state = USB_MAX_THROTTLE_STATE;

	return 0;
}

static int usb_set_cur_state(struct thermal_cooling_device *cooling_dev,
							unsigned long state)
{
	struct overheat_info *ovh_info = cooling_dev->devdata;
	unsigned long current_state;

	if (!ovh_info)
		return -EINVAL;

	if (state > USB_MAX_THROTTLE_STATE)
		return -EINVAL;

	current_state = ovh_info->throttle_state;
	ovh_info->throttle_state = state;

	if (current_state != state) {
		dev_info(ovh_info->dev, "usb overheat throttle state=%lu\n",
			 state);
		mod_delayed_work(system_wq, &ovh_info->port_overheat_work, 0);
	}
	return 0;
}

static const struct thermal_cooling_device_ops usb_cooling_ops = {
	.get_max_state = usb_get_max_state,
	.get_cur_state = usb_get_cur_state,
	.set_cur_state = usb_set_cur_state,
};

static int ovh_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct overheat_info *ovh_info;
	struct power_supply  *usb_psy;
	struct gvotable_election *usb_icl_votable;
	struct gvotable_election *disable_power_role_switch;

	usb_psy = power_supply_get_by_name("usb");
	if (!usb_psy)
		return -EPROBE_DEFER;

	usb_icl_votable = gvotable_election_get_handle("USB_ICL");
	if (usb_icl_votable == NULL) {
		pr_err("Couldn't find USB_ICL votable\n");
		return -EPROBE_DEFER;
	}

	disable_power_role_switch =
		gvotable_election_get_handle("DISABLE_POWER_ROLE_SWITCH");
	if (disable_power_role_switch == NULL) {
		pr_err("Couldn't find DISABLE_POWER_ROLE_SWITCH votable\n");
		return -EPROBE_DEFER;
	}

	ovh_info = devm_kzalloc(&pdev->dev, sizeof(*ovh_info), GFP_KERNEL);
	if (!ovh_info)
		return -ENOMEM;

	ovh_info->dev = &pdev->dev;
	ovh_info->usb_icl_votable = usb_icl_votable;
	ovh_info->disable_power_role_switch = disable_power_role_switch;
	ovh_info->usb_psy = usb_psy;
	ovh_info->max_temp = INT_MIN;
	ovh_info->plug_temp = INT_MIN;

	ret = get_dts_vars(ovh_info);
	if (ret < 0)
		return -ENODEV;

	// initialize votables
	gvotable_cast_int_vote(ovh_info->usb_icl_votable,
			       USB_OVERHEAT_MITIGATION_VOTER, 0, false);
	gvotable_cast_bool_vote(ovh_info->disable_power_role_switch,
				USB_OVERHEAT_MITIGATION_VOTER, false);

	ovh_info->overheat_ws = wakeup_source_register(NULL, "overheat_mitigation");
	if (!ovh_info->overheat_ws) {
		dev_err(ovh_info->dev, "%s: failed to get wakeup source\n",
				__func__);
		return -ENODEV;
	}
	INIT_DELAYED_WORK(&ovh_info->port_overheat_work, port_overheat_work);

	// register power supply change notifier to update usb metric data
	ovh_info->psy_nb.notifier_call = psy_changed;
	ret = power_supply_reg_notifier(&ovh_info->psy_nb);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"Cannot register power supply notifer, ret=%d\n", ret);
		return ret;
	}

	/* Register cooling device */
	ovh_info->cooling_dev = thermal_of_cooling_device_register(
				dev_of_node(ovh_info->dev), "usb-port",
				ovh_info, &usb_cooling_ops);

	if (IS_ERR(ovh_info->cooling_dev)) {
		ret = PTR_ERR(ovh_info->cooling_dev);
		dev_err(ovh_info->dev, "%s: failed to register cooling device: %d\n",
				__func__, ret);
		return ret;
	}

	platform_set_drvdata(pdev, ovh_info);
	ret = sysfs_create_group(&ovh_info->dev->kobj, &ovh_attr_group);
	if (ret < 0) {
		dev_err(ovh_info->dev,
			"Cannot create sysfs group, ret=%d\n", ret);
	}

	return 0;
}

static int ovh_remove(struct platform_device *pdev)
{
	struct overheat_info *ovh_info = platform_get_drvdata(pdev);
	if (ovh_info) {
		power_supply_unreg_notifier(&ovh_info->psy_nb);
		sysfs_remove_group(&ovh_info->dev->kobj, &ovh_attr_group);
		wakeup_source_unregister(ovh_info->overheat_ws);
	}
	return 0;
}

static const struct of_device_id match_table[] = {
	{
		.compatible = "google,overheat_mitigation",
	},
	{},
};

static struct platform_driver ovh_driver = {
	.driver = {
		.name = "google,overheat_mitigation",
		.owner = THIS_MODULE,
		.of_match_table = match_table,
	},
	.probe = ovh_probe,
	.remove = ovh_remove,
};

module_platform_driver(ovh_driver);
MODULE_DESCRIPTION("USB port overheat mitigation driver");
MODULE_AUTHOR("Maggie White <maggiewhite@google.com>");
MODULE_LICENSE("GPL v2");
