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

Commit c8eecff1 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "icnss2: Add thermal mitigation support"

parents 83662f68 66c9ad13
Loading
Loading
Loading
Loading
+108 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <linux/of_irq.h>
#include <linux/soc/qcom/qmi.h>
#include <linux/sysfs.h>
#include <linux/thermal.h>
#include <soc/qcom/memory_dump.h>
#include <soc/qcom/secure_buffer.h>
#include <soc/qcom/subsystem_notif.h>
@@ -1798,6 +1799,113 @@ static int icnss_enable_recovery(struct icnss_priv *priv)
	return 0;
}

static int icnss_tcdev_get_max_state(struct thermal_cooling_device *tcdev,
					unsigned long *thermal_state)
{
	struct icnss_priv *priv = tcdev->devdata;

	*thermal_state = priv->max_thermal_state;

	return 0;
}

static int icnss_tcdev_get_cur_state(struct thermal_cooling_device *tcdev,
					unsigned long *thermal_state)
{
	struct icnss_priv *priv = tcdev->devdata;

	*thermal_state = priv->curr_thermal_state;

	return 0;
}

static int icnss_tcdev_set_cur_state(struct thermal_cooling_device *tcdev,
					unsigned long thermal_state)
{
	struct icnss_priv *priv = tcdev->devdata;
	struct device *dev = &priv->pdev->dev;
	int ret = 0;

	priv->curr_thermal_state = thermal_state;

	if (!priv->ops || !priv->ops->set_therm_state)
		return 0;

	icnss_pr_vdbg("Cooling device set current state: %ld",
							thermal_state);

	ret = priv->ops->set_therm_state(dev, thermal_state);

	if (ret)
		icnss_pr_err("Setting Current Thermal State Failed: %d\n", ret);

	return 0;
}

static struct thermal_cooling_device_ops icnss_cooling_ops = {
	.get_max_state = icnss_tcdev_get_max_state,
	.get_cur_state = icnss_tcdev_get_cur_state,
	.set_cur_state = icnss_tcdev_set_cur_state,
};

int icnss_thermal_register(struct device *dev, unsigned long max_state)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);
	int ret = 0;

	priv->max_thermal_state = max_state;

	if (of_find_property(dev->of_node, "#cooling-cells", NULL)) {
		priv->tcdev = thermal_of_cooling_device_register(dev->of_node,
						"icnss", priv,
						&icnss_cooling_ops);
		if (IS_ERR_OR_NULL(priv->tcdev)) {
			ret = PTR_ERR(priv->tcdev);
			icnss_pr_err("Cooling device register failed: %d\n",
								ret);
		} else {
			icnss_pr_vdbg("Cooling device registered");
		}
	} else {
		icnss_pr_dbg("Cooling device registration not supported");
		ret = -EOPNOTSUPP;
	}

	return ret;
}
EXPORT_SYMBOL(icnss_thermal_register);

void icnss_thermal_unregister(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);

	if (!IS_ERR_OR_NULL(priv->tcdev))
		thermal_cooling_device_unregister(priv->tcdev);

	priv->tcdev = NULL;
}
EXPORT_SYMBOL(icnss_thermal_unregister);

int icnss_get_curr_therm_state(struct device *dev,
					unsigned long *thermal_state)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);
	int ret = 0;

	if (IS_ERR_OR_NULL(priv->tcdev)) {
		ret = PTR_ERR(priv->tcdev);
		icnss_pr_err("Get current thermal state failed: %d\n", ret);
		return ret;
	}

	icnss_pr_vdbg("Cooling device current state: %ld",
					priv->curr_thermal_state);

	*thermal_state = priv->curr_thermal_state;
	return ret;
}
EXPORT_SYMBOL(icnss_get_curr_therm_state);

int icnss_qmi_send(struct device *dev, int type, void *cmd,
		  int cmd_len, void *cb_ctx,
		  int (*cb)(void *ctx, void *event, int event_len))
+3 −0
Original line number Diff line number Diff line
@@ -371,6 +371,9 @@ struct icnss_priv {
	void *get_info_cb_ctx;
	int (*get_info_cb)(void *ctx, void *event, int event_len);
	atomic_t soc_wake_ref_count;
	struct thermal_cooling_device *tcdev;
	unsigned long curr_thermal_state;
	unsigned long max_thermal_state;
};

struct icnss_reg_info {
+5 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ struct icnss_driver_ops {
	int (*uevent)(struct device *dev, struct icnss_uevent_data *uevent);
	int (*idle_shutdown)(struct device *dev);
	int (*idle_restart)(struct device *dev);
	int (*set_therm_state)(struct device *dev, unsigned long thermal_state);
};


@@ -170,4 +171,8 @@ extern int icnss_qmi_send(struct device *dev, int type, void *cmd,
extern int icnss_force_wake_request(struct device *dev);
extern int icnss_force_wake_release(struct device *dev);
extern int icnss_is_device_awake(struct device *dev);
extern int icnss_thermal_register(struct device *dev, unsigned long max_state);
extern void icnss_thermal_unregister(struct device *dev);
extern int icnss_get_curr_therm_state(struct device *dev,
				      unsigned long *thermal_state);
#endif /* _ICNSS_WLAN_H_ */