mirror of
https://github.com/torvalds/linux.git
synced 2026-06-05 13:06:59 +02:00
drm/msm/dsi: free TX buffer in unbind
[ Upstream commit5e05be7826] If the drm/msm init code gets an error during output modeset initialisation, the kernel will report an error regarding DRM memory manager not being clean during shutdown. This is because msm_dsi_modeset_init() allocates a piece of GEM memory for the TX buffer, but destruction of the buffer happens only at msm_dsi_host_destroy(), which is called during DSI driver's remove() time, much later than the DRM MM shutdown. To solve this issue, move the TX buffer destruction to dsi_unbind(), so that the buffer is destructed at the correct time. Note, we also have to store a reference to the address space, because priv->kms->aspace is cleared before components are unbound. Reported-by: Bjorn Andersson <andersson@kernel.org> Fixes:8f59ee9a57("drm/msm/dsi: Adjust probe order") Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Patchwork: https://patchwork.freedesktop.org/patch/562238/ Signed-off-by: Rob Clark <robdclark@chromium.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
b8953fce22
commit
0d3ec0a19f
|
|
@ -126,6 +126,7 @@ static void dsi_unbind(struct device *dev, struct device *master,
|
|||
struct msm_drm_private *priv = dev_get_drvdata(master);
|
||||
struct msm_dsi *msm_dsi = dev_get_drvdata(dev);
|
||||
|
||||
msm_dsi_tx_buf_free(msm_dsi->host);
|
||||
priv->dsi[msm_dsi->id] = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
|
|||
void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
|
||||
void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host);
|
||||
void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host);
|
||||
void msm_dsi_tx_buf_free(struct mipi_dsi_host *mipi_host);
|
||||
int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova);
|
||||
int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
|
||||
int dsi_clk_init_v2(struct msm_dsi_host *msm_host);
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ struct msm_dsi_host {
|
|||
|
||||
/* DSI 6G TX buffer*/
|
||||
struct drm_gem_object *tx_gem_obj;
|
||||
struct msm_gem_address_space *aspace;
|
||||
|
||||
/* DSI v2 TX buffer */
|
||||
void *tx_buf;
|
||||
|
|
@ -1111,8 +1112,10 @@ int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
|
|||
uint64_t iova;
|
||||
u8 *data;
|
||||
|
||||
msm_host->aspace = msm_gem_address_space_get(priv->kms->aspace);
|
||||
|
||||
data = msm_gem_kernel_new(dev, size, MSM_BO_WC,
|
||||
priv->kms->aspace,
|
||||
msm_host->aspace,
|
||||
&msm_host->tx_gem_obj, &iova);
|
||||
|
||||
if (IS_ERR(data)) {
|
||||
|
|
@ -1141,10 +1144,10 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
|
||||
void msm_dsi_tx_buf_free(struct mipi_dsi_host *host)
|
||||
{
|
||||
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
|
||||
struct drm_device *dev = msm_host->dev;
|
||||
struct msm_drm_private *priv;
|
||||
|
||||
/*
|
||||
* This is possible if we're tearing down before we've had a chance to
|
||||
|
|
@ -1155,10 +1158,11 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
|
|||
if (!dev)
|
||||
return;
|
||||
|
||||
priv = dev->dev_private;
|
||||
if (msm_host->tx_gem_obj) {
|
||||
msm_gem_kernel_put(msm_host->tx_gem_obj, priv->kms->aspace);
|
||||
msm_gem_kernel_put(msm_host->tx_gem_obj, msm_host->aspace);
|
||||
msm_gem_address_space_put(msm_host->aspace);
|
||||
msm_host->tx_gem_obj = NULL;
|
||||
msm_host->aspace = NULL;
|
||||
}
|
||||
|
||||
if (msm_host->tx_buf)
|
||||
|
|
@ -1944,7 +1948,6 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host)
|
|||
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
|
||||
|
||||
DBG("");
|
||||
dsi_tx_buf_free(msm_host);
|
||||
if (msm_host->workqueue) {
|
||||
destroy_workqueue(msm_host->workqueue);
|
||||
msm_host->workqueue = NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user