Skip to content

Commit 5e05be7

Browse files
lumagrobclark
authored andcommitted
drm/msm/dsi: free TX buffer in unbind
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: 8f59ee9 ("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>
1 parent 69b321b commit 5e05be7

3 files changed

Lines changed: 11 additions & 6 deletions

File tree

drivers/gpu/drm/msm/dsi/dsi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ static void dsi_unbind(struct device *dev, struct device *master,
131131
struct msm_drm_private *priv = dev_get_drvdata(master);
132132
struct msm_dsi *msm_dsi = dev_get_drvdata(dev);
133133

134+
msm_dsi_tx_buf_free(msm_dsi->host);
134135
priv->dsi[msm_dsi->id] = NULL;
135136
}
136137

drivers/gpu/drm/msm/dsi/dsi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
124124
void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
125125
void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host);
126126
void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host);
127+
void msm_dsi_tx_buf_free(struct mipi_dsi_host *mipi_host);
127128
int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova);
128129
int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
129130
int dsi_clk_init_v2(struct msm_dsi_host *msm_host);

drivers/gpu/drm/msm/dsi/dsi_host.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ struct msm_dsi_host {
147147

148148
/* DSI 6G TX buffer*/
149149
struct drm_gem_object *tx_gem_obj;
150+
struct msm_gem_address_space *aspace;
150151

151152
/* DSI v2 TX buffer */
152153
void *tx_buf;
@@ -1134,8 +1135,10 @@ int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
11341135
uint64_t iova;
11351136
u8 *data;
11361137

1138+
msm_host->aspace = msm_gem_address_space_get(priv->kms->aspace);
1139+
11371140
data = msm_gem_kernel_new(dev, size, MSM_BO_WC,
1138-
priv->kms->aspace,
1141+
msm_host->aspace,
11391142
&msm_host->tx_gem_obj, &iova);
11401143

11411144
if (IS_ERR(data)) {
@@ -1164,10 +1167,10 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
11641167
return 0;
11651168
}
11661169

1167-
static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
1170+
void msm_dsi_tx_buf_free(struct mipi_dsi_host *host)
11681171
{
1172+
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
11691173
struct drm_device *dev = msm_host->dev;
1170-
struct msm_drm_private *priv;
11711174

11721175
/*
11731176
* This is possible if we're tearing down before we've had a chance to
@@ -1178,10 +1181,11 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
11781181
if (!dev)
11791182
return;
11801183

1181-
priv = dev->dev_private;
11821184
if (msm_host->tx_gem_obj) {
1183-
msm_gem_kernel_put(msm_host->tx_gem_obj, priv->kms->aspace);
1185+
msm_gem_kernel_put(msm_host->tx_gem_obj, msm_host->aspace);
1186+
msm_gem_address_space_put(msm_host->aspace);
11841187
msm_host->tx_gem_obj = NULL;
1188+
msm_host->aspace = NULL;
11851189
}
11861190

11871191
if (msm_host->tx_buf)
@@ -1967,7 +1971,6 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host)
19671971
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
19681972

19691973
DBG("");
1970-
dsi_tx_buf_free(msm_host);
19711974
if (msm_host->workqueue) {
19721975
destroy_workqueue(msm_host->workqueue);
19731976
msm_host->workqueue = NULL;

0 commit comments

Comments
 (0)