950-0476-drm-vc4-Release-workaround-buffer-and-DMA-in-error-p.patch 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. From 51f5523151d8de2b1476482e575bb5989e55ba16 Mon Sep 17 00:00:00 2001
  2. From: Dave Stevenson <[email protected]>
  3. Date: Tue, 6 Jul 2021 18:53:28 +0100
  4. Subject: [PATCH] drm/vc4: Release workaround buffer and DMA in error
  5. paths and unbind
  6. On Pi0-3 the driver allocates a buffer and requests a DMA channel
  7. because the ARM can't write to DSI1's registers directly.
  8. However unbind and the error paths in bind don't release the buffer or
  9. the DMA channel.
  10. Signed-off-by: Dave Stevenson <[email protected]>
  11. ---
  12. drivers/gpu/drm/vc4/vc4_dsi.c | 51 ++++++++++++++++++++++++++---------
  13. 1 file changed, 39 insertions(+), 12 deletions(-)
  14. --- a/drivers/gpu/drm/vc4/vc4_dsi.c
  15. +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
  16. @@ -1612,7 +1612,7 @@ static int vc4_dsi_bind(struct device *d
  17. if (ret != -EPROBE_DEFER)
  18. DRM_ERROR("Failed to get DMA channel: %d\n",
  19. ret);
  20. - return ret;
  21. + goto err_free_dma_mem;
  22. }
  23. /* Get the physical address of the device's registers. The
  24. @@ -1641,7 +1641,7 @@ static int vc4_dsi_bind(struct device *d
  25. if (ret) {
  26. if (ret != -EPROBE_DEFER)
  27. dev_err(dev, "Failed to get interrupt: %d\n", ret);
  28. - return ret;
  29. + goto err_free_dma;
  30. }
  31. dsi->escape_clock = devm_clk_get(dev, "escape");
  32. @@ -1649,7 +1649,7 @@ static int vc4_dsi_bind(struct device *d
  33. ret = PTR_ERR(dsi->escape_clock);
  34. if (ret != -EPROBE_DEFER)
  35. dev_err(dev, "Failed to get escape clock: %d\n", ret);
  36. - return ret;
  37. + goto err_free_dma;
  38. }
  39. dsi->pll_phy_clock = devm_clk_get(dev, "phy");
  40. @@ -1657,7 +1657,7 @@ static int vc4_dsi_bind(struct device *d
  41. ret = PTR_ERR(dsi->pll_phy_clock);
  42. if (ret != -EPROBE_DEFER)
  43. dev_err(dev, "Failed to get phy clock: %d\n", ret);
  44. - return ret;
  45. + goto err_free_dma;
  46. }
  47. dsi->pixel_clock = devm_clk_get(dev, "pixel");
  48. @@ -1665,7 +1665,7 @@ static int vc4_dsi_bind(struct device *d
  49. ret = PTR_ERR(dsi->pixel_clock);
  50. if (ret != -EPROBE_DEFER)
  51. dev_err(dev, "Failed to get pixel clock: %d\n", ret);
  52. - return ret;
  53. + goto err_free_dma;
  54. }
  55. ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
  56. @@ -1680,33 +1680,37 @@ static int vc4_dsi_bind(struct device *d
  57. if (ret == -ENODEV)
  58. return 0;
  59. - return ret;
  60. + goto err_free_dma;
  61. }
  62. if (panel) {
  63. dsi->bridge = devm_drm_panel_bridge_add_typed(dev, panel,
  64. DRM_MODE_CONNECTOR_DSI);
  65. - if (IS_ERR(dsi->bridge))
  66. - return PTR_ERR(dsi->bridge);
  67. + if (IS_ERR(dsi->bridge)) {
  68. + ret = PTR_ERR(dsi->bridge);
  69. + goto err_free_dma;
  70. + }
  71. }
  72. /* The esc clock rate is supposed to always be 100Mhz. */
  73. ret = clk_set_rate(dsi->escape_clock, 100 * 1000000);
  74. if (ret) {
  75. dev_err(dev, "Failed to set esc clock: %d\n", ret);
  76. - return ret;
  77. + goto err_free_dma;
  78. }
  79. ret = vc4_dsi_init_phy_clocks(dsi);
  80. if (ret)
  81. - return ret;
  82. + goto err_free_dma;
  83. drm_simple_encoder_init(drm, dsi->encoder, DRM_MODE_ENCODER_DSI);
  84. drm_encoder_helper_add(dsi->encoder, &vc4_dsi_encoder_helper_funcs);
  85. ret = drm_bridge_attach(dsi->encoder, dsi->bridge, NULL, 0);
  86. - if (ret)
  87. - return ret;
  88. + if (ret) {
  89. + dev_err(dev, "bridge attach failed: %d\n", ret);
  90. + goto err_free_dma;
  91. + }
  92. /* Disable the atomic helper calls into the bridge. We
  93. * manually call the bridge pre_enable / enable / etc. calls
  94. * from our driver, since we need to sequence them within the
  95. @@ -1719,6 +1723,19 @@ static int vc4_dsi_bind(struct device *d
  96. pm_runtime_enable(dev);
  97. return 0;
  98. +
  99. +err_free_dma:
  100. + if (dsi->reg_dma_chan) {
  101. + dma_release_channel(dsi->reg_dma_chan);
  102. + dsi->reg_dma_chan = NULL;
  103. + }
  104. +err_free_dma_mem:
  105. + if (dsi->reg_dma_mem) {
  106. + dma_free_coherent(dev, 4, dsi->reg_dma_mem, dsi->reg_dma_paddr);
  107. + dsi->reg_dma_mem = NULL;
  108. + }
  109. +
  110. + return ret;
  111. }
  112. static void vc4_dsi_unbind(struct device *dev, struct device *master,
  113. @@ -1735,6 +1752,16 @@ static void vc4_dsi_unbind(struct device
  114. */
  115. list_splice_init(&dsi->bridge_chain, &dsi->encoder->bridge_chain);
  116. drm_encoder_cleanup(dsi->encoder);
  117. +
  118. + if (dsi->reg_dma_chan) {
  119. + dma_release_channel(dsi->reg_dma_chan);
  120. + dsi->reg_dma_chan = NULL;
  121. + }
  122. +
  123. + if (dsi->reg_dma_mem) {
  124. + dma_free_coherent(dev, 4, dsi->reg_dma_mem, dsi->reg_dma_paddr);
  125. + dsi->reg_dma_mem = NULL;
  126. + }
  127. }
  128. static const struct component_ops vc4_dsi_ops = {