dsi_status_v2.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/workqueue.h>
  13. #include <linux/delay.h>
  14. #include <linux/kobject.h>
  15. #include <linux/string.h>
  16. #include <linux/sysfs.h>
  17. #include "mdss_dsi.h"
  18. #include "mdp3_ctrl.h"
  19. /*
  20. * mdp3_check_dsi_ctrl_status() - Check MDP3 DSI controller status periodically.
  21. * @work : dsi controller status data
  22. * @interval : duration in milliseconds to schedule work queue
  23. *
  24. * This function calls check_status API on DSI controller to send the BTA
  25. * command. If DSI controller fails to acknowledge the BTA command, it sends
  26. * the PANEL_ALIVE=0 status to HAL layer.
  27. */
  28. void mdp3_check_dsi_ctrl_status(struct work_struct *work,
  29. uint32_t interval)
  30. {
  31. struct dsi_status_data *pdsi_status = NULL;
  32. struct mdss_panel_data *pdata = NULL;
  33. struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
  34. struct mdp3_session_data *mdp3_session = NULL;
  35. int ret = 0;
  36. pdsi_status = container_of(to_delayed_work(work),
  37. struct dsi_status_data, check_status);
  38. if (!pdsi_status || !(pdsi_status->mfd)) {
  39. pr_err("%s: mfd not available\n", __func__);
  40. return;
  41. }
  42. pdata = dev_get_platdata(&pdsi_status->mfd->pdev->dev);
  43. if (!pdata) {
  44. pr_err("%s: Panel data not available\n", __func__);
  45. return;
  46. }
  47. ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
  48. panel_data);
  49. if (!ctrl_pdata || !ctrl_pdata->check_status) {
  50. pr_err("%s: DSI ctrl or status_check callback not available\n",
  51. __func__);
  52. return;
  53. }
  54. mdp3_session = pdsi_status->mfd->mdp.private1;
  55. if (!mdp3_session) {
  56. pr_err("%s: Display is off\n", __func__);
  57. return;
  58. }
  59. mutex_lock(&mdp3_session->lock);
  60. if (!mdp3_session->status) {
  61. pr_info("display off already\n");
  62. mutex_unlock(&mdp3_session->lock);
  63. return;
  64. }
  65. if (mdp3_session->wait_for_dma_done)
  66. ret = mdp3_session->wait_for_dma_done(mdp3_session);
  67. if (!ret)
  68. ret = ctrl_pdata->check_status(ctrl_pdata);
  69. else
  70. pr_err("%s: wait_for_dma_done error\n", __func__);
  71. mutex_unlock(&mdp3_session->lock);
  72. if ((pdsi_status->mfd->panel_power_on)) {
  73. if (ret > 0) {
  74. schedule_delayed_work(&pdsi_status->check_status,
  75. msecs_to_jiffies(interval));
  76. } else {
  77. char *envp[2] = {"PANEL_ALIVE=0", NULL};
  78. pdata->panel_info.panel_dead = true;
  79. ret = kobject_uevent_env(
  80. &pdsi_status->mfd->fbi->dev->kobj,
  81. KOBJ_CHANGE, envp);
  82. pr_err("%s: Panel has gone bad, sending uevent - %s\n",
  83. __func__, envp[0]);
  84. }
  85. }
  86. }