Forráskód Böngészése

display: msm: sde: Add display cooling device interface

Add display cooling device interface, which will enable to register a
cooling device and send a blocking notifier call when there is a new
mitigation request.

Change-Id: I59e4a7190f637fba7f63e47ff495242718cc3c9b
Signed-off-by: Ram Chandrasekar <[email protected]>
Ram Chandrasekar 5 éve
szülő
commit
132fd3941e
3 módosított fájl, 127 hozzáadás és 0 törlés
  1. 1 0
      msm/Makefile
  2. 89 0
      msm/msm_cooling_device.c
  3. 37 0
      msm/msm_cooling_device.h

+ 1 - 0
msm/Makefile

@@ -127,6 +127,7 @@ msm_drm-$(CONFIG_DRM_MSM) += \
 	msm_gem_prime.o \
 	msm_gem_vma.o \
 	msm_smmu.o \
+	msm_cooling_device.o \
 	msm_prop.o
 
 msm_drm-$(CONFIG_HDCP_QSEECOM) += ../hdcp/msm_hdcp.o \

+ 89 - 0
msm/msm_cooling_device.c

@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+#include <linux/err.h>
+#include <linux/slab.h>
+#include "msm_cooling_device.h"
+
+static int sde_cdev_get_max_brightness(struct thermal_cooling_device *cdev,
+					unsigned long *state)
+{
+	struct sde_cdev *disp_cdev = (struct sde_cdev *)cdev->devdata;
+
+	*state = disp_cdev->bd->props.max_brightness;
+
+	return 0;
+}
+
+static int sde_cdev_get_cur_brightness(struct thermal_cooling_device *cdev,
+					unsigned long *state)
+{
+	struct sde_cdev *disp_cdev = (struct sde_cdev *)cdev->devdata;
+
+	*state = disp_cdev->bd->props.max_brightness - disp_cdev->thermal_state;
+
+	return 0;
+}
+
+static int sde_cdev_set_cur_brightness(struct thermal_cooling_device *cdev,
+					unsigned long state)
+{
+	struct sde_cdev *disp_cdev = (struct sde_cdev *)cdev->devdata;
+	unsigned long brightness_lvl = 0;
+
+	if (state > disp_cdev->bd->props.max_brightness)
+		return -EINVAL;
+
+	brightness_lvl = disp_cdev->bd->props.max_brightness - state;
+	if (brightness_lvl == disp_cdev->thermal_state)
+		return 0;
+	disp_cdev->thermal_state = brightness_lvl;
+	blocking_notifier_call_chain(&disp_cdev->notifier_head,
+					brightness_lvl, (void *)disp_cdev->bd);
+
+	return 0;
+}
+
+static struct thermal_cooling_device_ops sde_cdev_ops = {
+	.get_max_state = sde_cdev_get_max_brightness,
+	.get_cur_state = sde_cdev_get_cur_brightness,
+	.set_cur_state = sde_cdev_set_cur_brightness,
+};
+
+struct sde_cdev *backlight_cdev_register(struct device *dev,
+					struct backlight_device *bd,
+					struct notifier_block *n)
+{
+	struct sde_cdev *disp_cdev = NULL;
+
+	if (!dev || !bd || !n)
+		return ERR_PTR(-EINVAL);
+	if (!of_find_property(dev->of_node, "#cooling-cells", NULL))
+		return ERR_PTR(-ENODEV);
+
+	disp_cdev = devm_kzalloc(dev, sizeof(*disp_cdev), GFP_KERNEL);
+	if (!disp_cdev)
+		return ERR_PTR(-ENOMEM);
+	disp_cdev->thermal_state = 0;
+	disp_cdev->bd = bd;
+	disp_cdev->cdev = thermal_of_cooling_device_register(dev->of_node,
+				(char *)dev_name(&bd->dev), disp_cdev,
+				&sde_cdev_ops);
+	if (IS_ERR_OR_NULL(disp_cdev->cdev)) {
+		pr_err("cooling device register failed\n");
+		return (void *)disp_cdev->cdev;
+	}
+	BLOCKING_INIT_NOTIFIER_HEAD(&disp_cdev->notifier_head);
+	blocking_notifier_chain_register(&disp_cdev->notifier_head, n);
+
+	return disp_cdev;
+}
+
+void backlight_cdev_unregister(struct sde_cdev *cdev)
+{
+	if (!cdev)
+		return;
+
+	thermal_cooling_device_unregister(cdev->cdev);
+}

+ 37 - 0
msm/msm_cooling_device.h

@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __SDE_THERMAL_CORE_H__
+#define __SDE_THERMAL_CORE_H__
+
+#include <linux/device.h>
+#include <linux/backlight.h>
+#include <linux/thermal.h>
+#include <linux/notifier.h>
+
+struct sde_cdev {
+	struct blocking_notifier_head notifier_head;
+	struct thermal_cooling_device *cdev;
+	struct backlight_device *bd;
+	unsigned long thermal_state;
+};
+
+#ifdef CONFIG_THERMAL_OF
+struct sde_cdev *backlight_cdev_register(struct device *dev,
+					struct backlight_device *bd,
+					struct notifier_block *n);
+void backlight_cdev_unregister(struct sde_cdev *cdev);
+#else
+static inline struct sde_cdev *
+backlight_cdev_register(struct device *dev,
+			struct backlight_device *bd, struct notifier_block *n)
+{
+	return NULL;
+}
+static inline void backlight_cdev_unregister(struct sde_cdev *cdev)
+{ }
+#endif
+
+#endif