msm_cooling_device.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/err.h>
  6. #include <linux/slab.h>
  7. #include "msm_cooling_device.h"
  8. static int sde_cdev_get_max_brightness(struct thermal_cooling_device *cdev,
  9. unsigned long *state)
  10. {
  11. struct sde_cdev *disp_cdev = (struct sde_cdev *)cdev->devdata;
  12. *state = disp_cdev->bd->props.max_brightness;
  13. return 0;
  14. }
  15. static int sde_cdev_get_cur_brightness(struct thermal_cooling_device *cdev,
  16. unsigned long *state)
  17. {
  18. struct sde_cdev *disp_cdev = (struct sde_cdev *)cdev->devdata;
  19. *state = disp_cdev->bd->props.max_brightness - disp_cdev->thermal_state;
  20. return 0;
  21. }
  22. static int sde_cdev_set_cur_brightness(struct thermal_cooling_device *cdev,
  23. unsigned long state)
  24. {
  25. struct sde_cdev *disp_cdev = (struct sde_cdev *)cdev->devdata;
  26. unsigned long brightness_lvl = 0;
  27. if (state > disp_cdev->bd->props.max_brightness)
  28. return -EINVAL;
  29. brightness_lvl = disp_cdev->bd->props.max_brightness - state;
  30. if (brightness_lvl == disp_cdev->thermal_state)
  31. return 0;
  32. disp_cdev->thermal_state = brightness_lvl;
  33. blocking_notifier_call_chain(&disp_cdev->notifier_head,
  34. brightness_lvl, (void *)disp_cdev->bd);
  35. return 0;
  36. }
  37. static struct thermal_cooling_device_ops sde_cdev_ops = {
  38. .get_max_state = sde_cdev_get_max_brightness,
  39. .get_cur_state = sde_cdev_get_cur_brightness,
  40. .set_cur_state = sde_cdev_set_cur_brightness,
  41. };
  42. struct sde_cdev *backlight_cdev_register(struct device *dev,
  43. struct backlight_device *bd,
  44. struct notifier_block *n)
  45. {
  46. struct sde_cdev *disp_cdev = NULL;
  47. if (!dev || !bd || !n)
  48. return ERR_PTR(-EINVAL);
  49. if (!of_find_property(dev->of_node, "#cooling-cells", NULL))
  50. return ERR_PTR(-ENODEV);
  51. disp_cdev = devm_kzalloc(dev, sizeof(*disp_cdev), GFP_KERNEL);
  52. if (!disp_cdev)
  53. return ERR_PTR(-ENOMEM);
  54. disp_cdev->thermal_state = 0;
  55. disp_cdev->bd = bd;
  56. disp_cdev->cdev = thermal_of_cooling_device_register(dev->of_node,
  57. (char *)dev_name(&bd->dev), disp_cdev,
  58. &sde_cdev_ops);
  59. if (IS_ERR_OR_NULL(disp_cdev->cdev)) {
  60. pr_err("cooling device register failed\n");
  61. return (void *)disp_cdev->cdev;
  62. }
  63. BLOCKING_INIT_NOTIFIER_HEAD(&disp_cdev->notifier_head);
  64. blocking_notifier_chain_register(&disp_cdev->notifier_head, n);
  65. return disp_cdev;
  66. }
  67. void backlight_cdev_unregister(struct sde_cdev *cdev)
  68. {
  69. if (!cdev)
  70. return;
  71. thermal_cooling_device_unregister(cdev->cdev);
  72. }