[PATCH v3] drm/gem: Fix GEM handle release errors

2022-08-19 Thread Jeffy Chen
Currently we are assuming a one to one mapping between dmabuf and
GEM handle when releasing GEM handles.

But that is not always true, since we would create extra handles for the
GEM obj in cases like gem_open() and getfb{,2}().

A similar issue was reported at:
https://lore.kernel.org/all/20211105083308.392156-1-jay...@rock-chips.com/

Another problem is that the imported dmabuf might not always have
gem_obj->dma_buf set, which would cause leaks in
drm_gem_remove_prime_handles().

Let's fix these for now by using handle to find the exact map to remove.

Signed-off-by: Jeffy Chen 
Reviewed-by: Christian König 

---

Changes in v3:
Rewrite commit message a bit.

Changes in v2:
Fix a typo of rbtree.

 drivers/gpu/drm/drm_gem.c  | 17 +
 drivers/gpu/drm/drm_internal.h |  4 ++--
 drivers/gpu/drm/drm_prime.c| 20 
 3 files changed, 15 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index eb0c2d041f13..ed39da383570 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -168,21 +168,6 @@ void drm_gem_private_object_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_gem_private_object_init);
 
-static void
-drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp)
-{
-   /*
-* Note: obj->dma_buf can't disappear as long as we still hold a
-* handle reference in obj->handle_count.
-*/
-   mutex_lock(>prime.lock);
-   if (obj->dma_buf) {
-   drm_prime_remove_buf_handle_locked(>prime,
-  obj->dma_buf);
-   }
-   mutex_unlock(>prime.lock);
-}
-
 /**
  * drm_gem_object_handle_free - release resources bound to userspace handles
  * @obj: GEM object to clean up.
@@ -253,7 +238,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
if (obj->funcs->close)
obj->funcs->close(obj, file_priv);
 
-   drm_gem_remove_prime_handles(obj, file_priv);
+   drm_prime_remove_buf_handle(_priv->prime, id);
drm_vma_node_revoke(>vma_node, file_priv);
 
drm_gem_object_handle_put_unlocked(obj);
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 1fbbc19f1ac0..7bb98e6a446d 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -74,8 +74,8 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void 
*data,
 
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv);
 void drm_prime_destroy_file_private(struct drm_prime_file_private 
*prime_fpriv);
-void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private 
*prime_fpriv,
-   struct dma_buf *dma_buf);
+void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
+uint32_t handle);
 
 /* drm_drv.c */
 struct drm_minor *drm_minor_acquire(unsigned int minor_id);
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index e3f09f18110c..bd5366b16381 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -190,29 +190,33 @@ static int drm_prime_lookup_buf_handle(struct 
drm_prime_file_private *prime_fpri
return -ENOENT;
 }
 
-void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private 
*prime_fpriv,
-   struct dma_buf *dma_buf)
+void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
+uint32_t handle)
 {
struct rb_node *rb;
 
-   rb = prime_fpriv->dmabufs.rb_node;
+   mutex_lock(_fpriv->lock);
+
+   rb = prime_fpriv->handles.rb_node;
while (rb) {
struct drm_prime_member *member;
 
-   member = rb_entry(rb, struct drm_prime_member, dmabuf_rb);
-   if (member->dma_buf == dma_buf) {
+   member = rb_entry(rb, struct drm_prime_member, handle_rb);
+   if (member->handle == handle) {
rb_erase(>handle_rb, _fpriv->handles);
rb_erase(>dmabuf_rb, _fpriv->dmabufs);
 
-   dma_buf_put(dma_buf);
+   dma_buf_put(member->dma_buf);
kfree(member);
-   return;
-   } else if (member->dma_buf < dma_buf) {
+   break;
+   } else if (member->handle < handle) {
rb = rb->rb_right;
} else {
rb = rb->rb_left;
}
}
+
+   mutex_unlock(_fpriv->lock);
 }
 
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv)
-- 
2.20.1



[PATCH v2] drm/gem: Fix GEM handle release errors

2022-08-03 Thread Jeffy Chen
Currently we are assuming a one to one mapping between dmabuf and handle
when releasing GEM handles.

But that is not always true, since we would create extra handles for the
GEM obj in cases like gem_open() and getfb{,2}().

A similar issue was reported at:
https://lore.kernel.org/all/20211105083308.392156-1-jay...@rock-chips.com/

Another problem is that the drm_gem_remove_prime_handles() now only
remove handle to the exported dmabuf (gem_obj->dma_buf), so the imported
ones would leak:
WARNING: CPU: 2 PID: 236 at drivers/gpu/drm/drm_prime.c:228 
drm_prime_destroy_file_private+0x18/0x24

Let's fix these by using handle to find the exact map to remove.

Signed-off-by: Jeffy Chen 
---

Changes in v2:
Fix a typo of rbtree.

 drivers/gpu/drm/drm_gem.c  | 17 +
 drivers/gpu/drm/drm_internal.h |  4 ++--
 drivers/gpu/drm/drm_prime.c| 20 
 3 files changed, 15 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index eb0c2d041f13..ed39da383570 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -168,21 +168,6 @@ void drm_gem_private_object_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_gem_private_object_init);
 
-static void
-drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp)
-{
-   /*
-* Note: obj->dma_buf can't disappear as long as we still hold a
-* handle reference in obj->handle_count.
-*/
-   mutex_lock(>prime.lock);
-   if (obj->dma_buf) {
-   drm_prime_remove_buf_handle_locked(>prime,
-  obj->dma_buf);
-   }
-   mutex_unlock(>prime.lock);
-}
-
 /**
  * drm_gem_object_handle_free - release resources bound to userspace handles
  * @obj: GEM object to clean up.
@@ -253,7 +238,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
if (obj->funcs->close)
obj->funcs->close(obj, file_priv);
 
-   drm_gem_remove_prime_handles(obj, file_priv);
+   drm_prime_remove_buf_handle(_priv->prime, id);
drm_vma_node_revoke(>vma_node, file_priv);
 
drm_gem_object_handle_put_unlocked(obj);
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 1fbbc19f1ac0..7bb98e6a446d 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -74,8 +74,8 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void 
*data,
 
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv);
 void drm_prime_destroy_file_private(struct drm_prime_file_private 
*prime_fpriv);
-void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private 
*prime_fpriv,
-   struct dma_buf *dma_buf);
+void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
+uint32_t handle);
 
 /* drm_drv.c */
 struct drm_minor *drm_minor_acquire(unsigned int minor_id);
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index e3f09f18110c..bd5366b16381 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -190,29 +190,33 @@ static int drm_prime_lookup_buf_handle(struct 
drm_prime_file_private *prime_fpri
return -ENOENT;
 }
 
-void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private 
*prime_fpriv,
-   struct dma_buf *dma_buf)
+void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
+uint32_t handle)
 {
struct rb_node *rb;
 
-   rb = prime_fpriv->dmabufs.rb_node;
+   mutex_lock(_fpriv->lock);
+
+   rb = prime_fpriv->handles.rb_node;
while (rb) {
struct drm_prime_member *member;
 
-   member = rb_entry(rb, struct drm_prime_member, dmabuf_rb);
-   if (member->dma_buf == dma_buf) {
+   member = rb_entry(rb, struct drm_prime_member, handle_rb);
+   if (member->handle == handle) {
rb_erase(>handle_rb, _fpriv->handles);
rb_erase(>dmabuf_rb, _fpriv->dmabufs);
 
-   dma_buf_put(dma_buf);
+   dma_buf_put(member->dma_buf);
kfree(member);
-   return;
-   } else if (member->dma_buf < dma_buf) {
+   break;
+   } else if (member->handle < handle) {
rb = rb->rb_right;
} else {
rb = rb->rb_left;
}
}
+
+   mutex_unlock(_fpriv->lock);
 }
 
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv)
-- 
2.20.1



[PATCH] drm/gem: Fix GEM handle release errors

2022-08-02 Thread Jeffy Chen
Currently we are assuming a one to one mapping between dmabuf and handle
when releasing GEM handles.

But that is not always true, since we would create extra handles for the
GEM obj in cases like gem_open() and getfb{,2}().

A similar issue was reported at:
https://lore.kernel.org/all/20211105083308.392156-1-jay...@rock-chips.com/

Another problem is that the drm_gem_remove_prime_handles() now only
remove handle to the exported dmabuf (gem_obj->dma_buf), so the imported
ones would leak:
WARNING: CPU: 2 PID: 236 at drivers/gpu/drm/drm_prime.c:228 
drm_prime_destroy_file_private+0x18/0x24

Let's fix these by using handle to find the exact map to remove.

Signed-off-by: Jeffy Chen 
---

 drivers/gpu/drm/drm_gem.c  | 17 +
 drivers/gpu/drm/drm_internal.h |  4 ++--
 drivers/gpu/drm/drm_prime.c| 16 ++--
 3 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index eb0c2d041f13..ed39da383570 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -168,21 +168,6 @@ void drm_gem_private_object_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_gem_private_object_init);
 
-static void
-drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp)
-{
-   /*
-* Note: obj->dma_buf can't disappear as long as we still hold a
-* handle reference in obj->handle_count.
-*/
-   mutex_lock(>prime.lock);
-   if (obj->dma_buf) {
-   drm_prime_remove_buf_handle_locked(>prime,
-  obj->dma_buf);
-   }
-   mutex_unlock(>prime.lock);
-}
-
 /**
  * drm_gem_object_handle_free - release resources bound to userspace handles
  * @obj: GEM object to clean up.
@@ -253,7 +238,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
if (obj->funcs->close)
obj->funcs->close(obj, file_priv);
 
-   drm_gem_remove_prime_handles(obj, file_priv);
+   drm_prime_remove_buf_handle(_priv->prime, id);
drm_vma_node_revoke(>vma_node, file_priv);
 
drm_gem_object_handle_put_unlocked(obj);
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 1fbbc19f1ac0..7bb98e6a446d 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -74,8 +74,8 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void 
*data,
 
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv);
 void drm_prime_destroy_file_private(struct drm_prime_file_private 
*prime_fpriv);
-void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private 
*prime_fpriv,
-   struct dma_buf *dma_buf);
+void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
+uint32_t handle);
 
 /* drm_drv.c */
 struct drm_minor *drm_minor_acquire(unsigned int minor_id);
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index e3f09f18110c..c28518ab62d0 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -190,29 +190,33 @@ static int drm_prime_lookup_buf_handle(struct 
drm_prime_file_private *prime_fpri
return -ENOENT;
 }
 
-void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private 
*prime_fpriv,
-   struct dma_buf *dma_buf)
+void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
+uint32_t handle)
 {
struct rb_node *rb;
 
+   mutex_lock(_fpriv->lock);
+
rb = prime_fpriv->dmabufs.rb_node;
while (rb) {
struct drm_prime_member *member;
 
member = rb_entry(rb, struct drm_prime_member, dmabuf_rb);
-   if (member->dma_buf == dma_buf) {
+   if (member->handle == handle) {
rb_erase(>handle_rb, _fpriv->handles);
rb_erase(>dmabuf_rb, _fpriv->dmabufs);
 
-   dma_buf_put(dma_buf);
+   dma_buf_put(member->dma_buf);
kfree(member);
-   return;
-   } else if (member->dma_buf < dma_buf) {
+   break;
+   } else if (member->handle < handle) {
rb = rb->rb_right;
} else {
rb = rb->rb_left;
}
}
+
+   mutex_unlock(_fpriv->lock);
 }
 
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv)
-- 
2.20.1



[PATCH] drm/bridge/synopsys: dw-hdmi: Fix memleak in __dw_hdmi_remove

2018-03-04 Thread Jeffy Chen
The platform_device_register_full() will allocate dma_mask for
hdmi->audio, so we should free before platform_device_unregister().

Reported by kmemleak:
unreferenced object 0xffc0ef70ff00 (size 128):
  comm "kworker/4:1", pid 123, jiffies 4294670080 (age 189.604s)
  hex dump (first 32 bytes):
ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
  backtrace:
[<21946f44>] kmemleak_alloc+0x58/0x8c
[<9c43890d>] kmem_cache_alloc_memcg_trace+0x18c/0x25c
[<0e17cd06>] platform_device_register_full+0x64/0x108
[<418a0882>] __dw_hdmi_probe+0xb9c/0xcc0
[<e0b720fd>] dw_hdmi_bind+0x30/0x88
[<9af347f6>] dw_hdmi_rockchip_bind+0x260/0x2e8

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index f9802399cc0d..d9afdc59d4f4 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2567,8 +2567,10 @@ __dw_hdmi_probe(struct platform_device *pdev,
 
 static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
 {
-   if (hdmi->audio && !IS_ERR(hdmi->audio))
+   if (hdmi->audio && !IS_ERR(hdmi->audio)) {
+   kfree(hdmi->audio->dev.dma_mask);
platform_device_unregister(hdmi->audio);
+   }
if (!IS_ERR(hdmi->cec))
platform_device_unregister(hdmi->cec);
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/rockchip: vop: Init vskiplines in scl_vop_cal_scale()

2018-02-22 Thread Jeffy Chen
Currently we are calling scl_vop_cal_scale() to get vskiplines for yrgb
and cbcr. So the cbcr's vskiplines might be an unexpected value if the
second scl_vop_cal_scale() didn't update it.

Init vskiplines in scl_vop_cal_scale() to avoid that.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 7715853ef90a..9b03c51903ab 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -259,6 +259,9 @@ static uint16_t scl_vop_cal_scale(enum scale_mode mode, 
uint32_t src,
 {
uint16_t val = 1 << SCL_FT_DEFAULT_FIXPOINT_SHIFT;
 
+   if (vskiplines)
+   *vskiplines = 0;
+
if (is_horizontal) {
if (mode == SCALE_UP)
val = GET_SCL_FT_BIC(src, dst);
@@ -299,7 +302,7 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const 
struct vop_win_data *win,
uint16_t vsu_mode;
uint16_t lb_mode;
uint32_t val;
-   int vskiplines = 0;
+   int vskiplines;
 
if (dst_w > 3840) {
DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 09/10] drm/bridge/synopsys: dw-hdmi: Do not use device's drvdata

2017-10-18 Thread Jeffy Chen
Let plat drivers own the drvdata, so that they could cleanup resources
in their unbind().

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Neil Armstrong <narmstr...@baylibre.com>
---

Changes in v6: None
Changes in v5: None

 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 43 ++---
 drivers/gpu/drm/imx/dw_hdmi-imx.c   | 22 +--
 drivers/gpu/drm/meson/meson_dw_hdmi.c   | 20 ++
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c  | 14 --
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 23 ---
 include/drm/bridge/dw_hdmi.h| 17 ++--
 6 files changed, 77 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index ff1b3d2b5d06..6fbfafc5832b 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2072,7 +2072,7 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
return ret;
 }
 
-void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
+void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
 {
mutex_lock(>mutex);
 
@@ -2098,13 +2098,6 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool 
hpd, bool rx_sense)
}
mutex_unlock(>mutex);
 }
-
-void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense)
-{
-   struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
-   __dw_hdmi_setup_rx_sense(hdmi, hpd, rx_sense);
-}
 EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
 
 static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
@@ -2140,9 +2133,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 */
if (intr_stat &
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
-   __dw_hdmi_setup_rx_sense(hdmi,
-phy_stat & HDMI_PHY_HPD,
-phy_stat & HDMI_PHY_RX_SENSE);
+   dw_hdmi_setup_rx_sense(hdmi, phy_stat & HDMI_PHY_HPD,
+  phy_stat & HDMI_PHY_RX_SENSE);
 
if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
cec_notifier_set_phys_addr(hdmi->cec_notifier,
@@ -2512,8 +2504,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
 
-   platform_set_drvdata(pdev, hdmi);
-
return hdmi;
 
 err_iahb:
@@ -2559,25 +2549,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
 /* 
-
  * Probe/remove API, used from platforms based on the DRM bridge API.
  */
-int dw_hdmi_probe(struct platform_device *pdev,
- const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
+ const struct dw_hdmi_plat_data *plat_data)
 {
struct dw_hdmi *hdmi;
 
hdmi = __dw_hdmi_probe(pdev, plat_data);
if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
 
drm_bridge_add(>bridge);
 
-   return 0;
+   return hdmi;
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_probe);
 
-void dw_hdmi_remove(struct platform_device *pdev)
+void dw_hdmi_remove(struct dw_hdmi *hdmi)
 {
-   struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
-
drm_bridge_remove(>bridge);
 
__dw_hdmi_remove(hdmi);
@@ -2587,31 +2575,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
 /* 
-
  * Bind/unbind API, used from platforms based on the component framework.
  */
-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
-const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
+   struct drm_encoder *encoder,
+   const struct dw_hdmi_plat_data *plat_data)
 {
struct dw_hdmi *hdmi;
int ret;
 
hdmi = __dw_hdmi_probe(pdev, plat_data);
if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
 
ret = drm_bridge_attach(encoder, >bridge, NULL);
if (ret) {
__dw_hdmi_remove(hdmi);
DRM_ERROR("Failed to initialize bridge with drm\n");
-   return ret;
+   return ERR_PTR(ret);
}
 
-   return 0;
+   return hdmi;
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_bind);
 
-void dw_hdmi_unbind(struct device *dev)
+void dw_hdmi_unbind(struct dw_hdmi *hdmi)
 {
-   struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
__dw_hdmi_remove(hdmi);
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index b62763aa8706

[PATCH v6 10/10] drm/rockchip: dw_hdmi: Fix error handling path

2017-10-18 Thread Jeffy Chen
Add missing clk_disable_unprepare() in bind()'s error handling path and
unbind().

Also inline clk_prepare_enable() with bind().

Fixes: 12b9f204e804 ("drm: bridge/dw_hdmi: add rockchip rk3288 support")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v6: None
Changes in v5:
Add disable to unbind(), and inline clk_prepare_enable() with bind().

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 791ab938f998..e936dfe6c03d 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -193,13 +193,6 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return PTR_ERR(hdmi->grf_clk);
}
 
-   ret = clk_prepare_enable(hdmi->vpll_clk);
-   if (ret) {
-   DRM_DEV_ERROR(hdmi->dev,
- "Failed to enable HDMI vpll: %d\n", ret);
-   return ret;
-   }
-
return 0;
 }
 
@@ -374,6 +367,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, 
struct device *master,
return ret;
}
 
+   ret = clk_prepare_enable(hdmi->vpll_clk);
+   if (ret) {
+   DRM_DEV_ERROR(hdmi->dev,
+ "Failed to enable HDMI vpll: %d\n", ret);
+   return ret;
+   }
+
drm_encoder_helper_add(encoder, _hdmi_rockchip_encoder_helper_funcs);
drm_encoder_init(drm, encoder, _hdmi_rockchip_encoder_funcs,
 DRM_MODE_ENCODER_TMDS, NULL);
@@ -381,6 +381,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct 
device *master,
hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
if (IS_ERR(hdmi->hdmi)) {
encoder->funcs->destroy(encoder);
+   clk_disable_unprepare(hdmi->vpll_clk);
return PTR_ERR(hdmi->hdmi);
}
 
@@ -396,6 +397,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, 
struct device *master,
 
dw_hdmi_unbind(hdmi->hdmi);
hdmi->encoder.funcs->destroy(>encoder);
+   clk_disable_unprepare(hdmi->vpll_clk);
 }
 
 static const struct component_ops dw_hdmi_rockchip_ops = {
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 05/10] drm/rockchip: analogix_dp: Add a sanity check for rockchip_drm_psr_register()

2017-10-18 Thread Jeffy Chen
The rockchip_drm_psr_register() can fail, so add a sanity check for that.

Also reorder the calls in unbind() to match bind().

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v6: None
Changes in v5: None

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 117585df73e1..bd3567ad8b53 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -356,15 +356,22 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE;
INIT_WORK(>psr_work, analogix_dp_psr_work);
 
-   rockchip_drm_psr_register(>encoder, analogix_dp_psr_set);
+   ret = rockchip_drm_psr_register(>encoder, analogix_dp_psr_set);
+   if (ret < 0)
+   goto err_cleanup_encoder;
 
dp->adp = analogix_dp_bind(dev, dp->drm_dev, >plat_data);
if (IS_ERR(dp->adp)) {
-   dp->encoder.funcs->destroy(>encoder);
-   return PTR_ERR(dp->adp);
+   ret = PTR_ERR(dp->adp);
+   goto err_unreg_psr;
}
 
return 0;
+err_unreg_psr:
+   rockchip_drm_psr_unregister(>encoder);
+err_cleanup_encoder:
+   dp->encoder.funcs->destroy(>encoder);
+   return ret;
 }
 
 static void rockchip_dp_unbind(struct device *dev, struct device *master,
@@ -372,8 +379,8 @@ static void rockchip_dp_unbind(struct device *dev, struct 
device *master,
 {
struct rockchip_dp_device *dp = dev_get_drvdata(dev);
 
-   rockchip_drm_psr_unregister(>encoder);
analogix_dp_unbind(dp->adp);
+   rockchip_drm_psr_unregister(>encoder);
dp->encoder.funcs->destroy(>encoder);
 }
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 06/10] drm/rockchip: dw-mipi-dsi: Fix error handling path

2017-10-18 Thread Jeffy Chen
Add missing pm_runtime_disable() in bind()'s error handling path.

Also cleanup encoder & connector in unbind().

Fixes: 80a9a059d4e4 ("drm/rockchip/dsi: add dw-mipi power domain support")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v6: None
Changes in v5:
Call the destroy hook in the error handling path like in unbind().

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index b15755b6129c..e72d4e2b61aa 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -1282,7 +1282,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = dw_mipi_dsi_register(drm, dsi);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register mipi_dsi: %d\n", ret);
-   goto err_pllref;
+   goto err_disable_pllref;
}
 
pm_runtime_enable(dev);
@@ -1292,23 +1292,24 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = mipi_dsi_host_register(>dsi_host);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
-   goto err_cleanup;
+   goto err_disable_pm_runtime;
}
 
if (!dsi->panel) {
ret = -EPROBE_DEFER;
-   goto err_mipi_dsi_host;
+   goto err_unreg_mipi_dsi_host;
}
 
dev_set_drvdata(dev, dsi);
return 0;
 
-err_mipi_dsi_host:
+err_unreg_mipi_dsi_host:
mipi_dsi_host_unregister(>dsi_host);
-err_cleanup:
-   drm_encoder_cleanup(>encoder);
-   drm_connector_cleanup(>connector);
-err_pllref:
+err_disable_pm_runtime:
+   pm_runtime_disable(dev);
+   dsi->connector.funcs->destroy(>connector);
+   dsi->encoder.funcs->destroy(>encoder);
+err_disable_pllref:
clk_disable_unprepare(dsi->pllref_clk);
return ret;
 }
@@ -1320,6 +1321,10 @@ static void dw_mipi_dsi_unbind(struct device *dev, 
struct device *master,
 
mipi_dsi_host_unregister(>dsi_host);
pm_runtime_disable(dev);
+
+   dsi->connector.funcs->destroy(>connector);
+   dsi->encoder.funcs->destroy(>encoder);
+
clk_disable_unprepare(dsi->pllref_clk);
 }
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 07/10] drm/rockchip: inno_hdmi: Fix error handling path

2017-10-18 Thread Jeffy Chen
Add missing error handling in bind().

Fixes: 412d4ae6b7a5 ("drm/rockchip: hdmi: add Innosilicon HDMI support")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v6: None
Changes in v5:
Call the destroy hook in the error handling path like in unbind().
Update cleanup order in unbind().

 drivers/gpu/drm/rockchip/inno_hdmi.c | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index ee584d87111f..9a96ff6b022b 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -851,8 +851,10 @@ static int inno_hdmi_bind(struct device *dev, struct 
device *master,
}
 
irq = platform_get_irq(pdev, 0);
-   if (irq < 0)
-   return irq;
+   if (irq < 0) {
+   ret = irq;
+   goto err_disable_clk;
+   }
 
inno_hdmi_reset(hdmi);
 
@@ -860,7 +862,7 @@ static int inno_hdmi_bind(struct device *dev, struct device 
*master,
if (IS_ERR(hdmi->ddc)) {
ret = PTR_ERR(hdmi->ddc);
hdmi->ddc = NULL;
-   return ret;
+   goto err_disable_clk;
}
 
/*
@@ -874,7 +876,7 @@ static int inno_hdmi_bind(struct device *dev, struct device 
*master,
 
ret = inno_hdmi_register(drm, hdmi);
if (ret)
-   return ret;
+   goto err_put_adapter;
 
dev_set_drvdata(dev, hdmi);
 
@@ -884,7 +886,17 @@ static int inno_hdmi_bind(struct device *dev, struct 
device *master,
ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
inno_hdmi_irq, IRQF_SHARED,
dev_name(dev), hdmi);
+   if (ret < 0)
+   goto err_cleanup_hdmi;
 
+   return 0;
+err_cleanup_hdmi:
+   hdmi->connector.funcs->destroy(>connector);
+   hdmi->encoder.funcs->destroy(>encoder);
+err_put_adapter:
+   i2c_put_adapter(hdmi->ddc);
+err_disable_clk:
+   clk_disable_unprepare(hdmi->pclk);
return ret;
 }
 
@@ -896,8 +908,8 @@ static void inno_hdmi_unbind(struct device *dev, struct 
device *master,
hdmi->connector.funcs->destroy(>connector);
hdmi->encoder.funcs->destroy(>encoder);
 
-   clk_disable_unprepare(hdmi->pclk);
i2c_put_adapter(hdmi->ddc);
+   clk_disable_unprepare(hdmi->pclk);
 }
 
 static const struct component_ops inno_hdmi_ops = {
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 03/10] drm/bridge: analogix: Do not use device's drvdata

2017-10-18 Thread Jeffy Chen
The driver that instantiates the bridge should own the drvdata, as all
driver model callbacks (probe, remove, shutdown, PM ops, etc.) are also
owned by its driver struct. Moreover, storing two different pointer
types in driver data depending on driver initialization status is barely
a good practice and in fact has led to many bugs in this driver.

Let's clean up this mess and change Analogix entry points to simply
accept some opaque struct pointer, adjusting their users at the same
time to avoid breaking the compilation.

Signed-off-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Reviewed-by: Sean Paul <seanp...@chromium.org>
Acked-by: Jingoo Han <jingooh...@gmail.com>
Acked-by: Archit Taneja <arch...@codeaurora.org>
---

Changes in v6: None
Changes in v5: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 +-
 drivers/gpu/drm/exynos/exynos_dp.c | 26 ++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 49 -
 include/drm/bridge/analogix_dp.h   | 19 
 4 files changed, 74 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5dd3f1cd074a..74d274b6d31d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,17 +98,15 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
 }
 
-int analogix_dp_psr_supported(struct device *dev)
+int analogix_dp_psr_supported(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
 
return dp->psr_support;
 }
 EXPORT_SYMBOL_GPL(analogix_dp_psr_supported);
 
-int analogix_dp_enable_psr(struct device *dev)
+int analogix_dp_enable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
 
if (!dp->psr_support)
@@ -129,9 +127,8 @@ int analogix_dp_enable_psr(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
 
-int analogix_dp_disable_psr(struct device *dev)
+int analogix_dp_disable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
int ret;
 
@@ -1281,8 +1278,9 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux 
*aux,
return analogix_dp_transfer(dp, msg);
 }
 
-int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
-struct analogix_dp_plat_data *plat_data)
+struct analogix_dp_device *
+analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
+struct analogix_dp_plat_data *plat_data)
 {
struct platform_device *pdev = to_platform_device(dev);
struct analogix_dp_device *dp;
@@ -1292,14 +1290,12 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
if (!plat_data) {
dev_err(dev, "Invalided input plat_data\n");
-   return -EINVAL;
+   return ERR_PTR(-EINVAL);
}
 
dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL);
if (!dp)
-   return -ENOMEM;
-
-   dev_set_drvdata(dev, dp);
+   return ERR_PTR(-ENOMEM);
 
dp->dev = >dev;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1316,7 +1312,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
ret = analogix_dp_dt_parse_pdata(dp);
if (ret)
-   return ret;
+   return ERR_PTR(ret);
 
dp->phy = devm_phy_get(dp->dev, "dp");
if (IS_ERR(dp->phy)) {
@@ -1330,14 +1326,14 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
if (ret == -ENOSYS || ret == -ENODEV)
dp->phy = NULL;
else
-   return ret;
+   return ERR_PTR(ret);
}
}
 
dp->clock = devm_clk_get(>dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(>dev, "failed to get clock\n");
-   return PTR_ERR(dp->clock);
+   return ERR_CAST(dp->clock);
}
 
clk_prepare_enable(dp->clock);
@@ -1346,7 +1342,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
dp->reg_base = devm_ioremap_resource(>dev, res);
if (IS_ERR(dp->reg_base))
-   return PTR_ERR(dp->reg_base);
+   return ERR_CAST(dp->reg_base);
 
dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
 
@@ -1367,7 +1363,

[PATCH v6 02/10] drm/rockchip: analogix_dp: Remove unnecessary init code

2017-10-18 Thread Jeffy Chen
Remove unnecessary init code, since we would do it in the power_on()
callback.

Also move of parse code to probe().

Fixes: 9e32e16e9e98 ("drm: rockchip: dp: add rockchip platform dp driver")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v6: None
Changes in v5: None

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 27 ++---
 1 file changed, 6 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 4d3f6ad0abdd..8cae5ad926cd 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -269,7 +269,7 @@ static struct drm_encoder_funcs rockchip_dp_encoder_funcs = 
{
.destroy = rockchip_dp_drm_encoder_destroy,
 };
 
-static int rockchip_dp_init(struct rockchip_dp_device *dp)
+static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
 {
struct device *dev = dp->dev;
struct device_node *np = dev->of_node;
@@ -303,19 +303,6 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp)
return PTR_ERR(dp->rst);
}
 
-   ret = clk_prepare_enable(dp->pclk);
-   if (ret < 0) {
-   DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
-   return ret;
-   }
-
-   ret = rockchip_dp_pre_init(dp);
-   if (ret < 0) {
-   DRM_DEV_ERROR(dp->dev, "failed to pre init %d\n", ret);
-   clk_disable_unprepare(dp->pclk);
-   return ret;
-   }
-
return 0;
 }
 
@@ -361,10 +348,6 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
if (!dp_data)
return -ENODEV;
 
-   ret = rockchip_dp_init(dp);
-   if (ret < 0)
-   return ret;
-
dp->data = dp_data;
dp->drm_dev = drm_dev;
 
@@ -398,7 +381,6 @@ static void rockchip_dp_unbind(struct device *dev, struct 
device *master,
rockchip_drm_psr_unregister(>encoder);
 
analogix_dp_unbind(dev, master, data);
-   clk_disable_unprepare(dp->pclk);
 }
 
 static const struct component_ops rockchip_dp_component_ops = {
@@ -414,7 +396,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
int ret;
 
ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, , NULL);
-   if (ret)
+   if (ret < 0)
return ret;
 
dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
@@ -422,9 +404,12 @@ static int rockchip_dp_probe(struct platform_device *pdev)
return -ENOMEM;
 
dp->dev = dev;
-
dp->plat_data.panel = panel;
 
+   ret = rockchip_dp_of_probe(dp);
+   if (ret < 0)
+   return ret;
+
/*
 * We just use the drvdata until driver run into component
 * add function, and then we would set drvdata to null, so
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 08/10] drm/bridge/synopsys: dw-hdmi: Add missing bridge detach

2017-10-18 Thread Jeffy Chen
We inited connector in attach(), so need a detach() to cleanup.

Also fix wrong use of dw_hdmi_remove() in bind().

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v6: None
Changes in v5: None

 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index bf14214fa464..ff1b3d2b5d06 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1966,6 +1966,13 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
*bridge)
return 0;
 }
 
+static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
+{
+   struct dw_hdmi *hdmi = bridge->driver_private;
+
+   drm_connector_cleanup(>connector);
+}
+
 static enum drm_mode_status
 dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
  const struct drm_display_mode *mode)
@@ -2022,6 +2029,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge 
*bridge)
 
 static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
.attach = dw_hdmi_bridge_attach,
+   .detach = dw_hdmi_bridge_detach,
.enable = dw_hdmi_bridge_enable,
.disable = dw_hdmi_bridge_disable,
.mode_set = dw_hdmi_bridge_mode_set,
@@ -2591,7 +2599,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct 
drm_encoder *encoder,
 
ret = drm_bridge_attach(encoder, >bridge, NULL);
if (ret) {
-   dw_hdmi_remove(pdev);
+   __dw_hdmi_remove(hdmi);
DRM_ERROR("Failed to initialize bridge with drm\n");
return ret;
}
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 04/10] drm/bridge: analogix_dp: Fix connector and encoder cleanup

2017-10-18 Thread Jeffy Chen
Since we are initing connector in the core driver and encoder in the
plat driver, let's clean them up in the right places.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
---

Changes in v6:
Don't change order of rockchip_drm_psr_register().

Changes in v5: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  2 --
 drivers/gpu/drm/exynos/exynos_dp.c |  7 +--
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 12 +---
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 74d274b6d31d..3f910ab36ff6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1409,7 +1409,6 @@ analogix_dp_bind(struct device *dev, struct drm_device 
*drm_dev,
ret = analogix_dp_create_bridge(drm_dev, dp);
if (ret) {
DRM_ERROR("failed to create bridge (%d)\n", ret);
-   drm_encoder_cleanup(dp->encoder);
goto err_disable_pm_runtime;
}
 
@@ -1432,7 +1431,6 @@ void analogix_dp_unbind(struct analogix_dp_device *dp)
 {
analogix_dp_bridge_disable(dp->bridge);
dp->connector.funcs->destroy(>connector);
-   dp->encoder->funcs->destroy(dp->encoder);
 
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c 
b/drivers/gpu/drm/exynos/exynos_dp.c
index f7e5b2c405ed..33319a858f3a 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -185,8 +185,10 @@ static int exynos_dp_bind(struct device *dev, struct 
device *master, void *data)
dp->plat_data.encoder = encoder;
 
dp->adp = analogix_dp_bind(dev, dp->drm_dev, >plat_data);
-   if (IS_ERR(dp->adp))
+   if (IS_ERR(dp->adp)) {
+   dp->encoder.funcs->destroy(>encoder);
return PTR_ERR(dp->adp);
+   }
 
return 0;
 }
@@ -196,7 +198,8 @@ static void exynos_dp_unbind(struct device *dev, struct 
device *master,
 {
struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-   return analogix_dp_unbind(dp->adp);
+   analogix_dp_unbind(dp->adp);
+   dp->encoder.funcs->destroy(>encoder);
 }
 
 static const struct component_ops exynos_dp_ops = {
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index fa0365de31d2..117585df73e1 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -261,13 +261,8 @@ static struct drm_encoder_helper_funcs 
rockchip_dp_encoder_helper_funcs = {
.atomic_check = rockchip_dp_drm_encoder_atomic_check,
 };
 
-static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
-{
-   drm_encoder_cleanup(encoder);
-}
-
 static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
-   .destroy = rockchip_dp_drm_encoder_destroy,
+   .destroy = drm_encoder_cleanup,
 };
 
 static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
@@ -364,8 +359,10 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
rockchip_drm_psr_register(>encoder, analogix_dp_psr_set);
 
dp->adp = analogix_dp_bind(dev, dp->drm_dev, >plat_data);
-   if (IS_ERR(dp->adp))
+   if (IS_ERR(dp->adp)) {
+   dp->encoder.funcs->destroy(>encoder);
return PTR_ERR(dp->adp);
+   }
 
return 0;
 }
@@ -377,6 +374,7 @@ static void rockchip_dp_unbind(struct device *dev, struct 
device *master,
 
rockchip_drm_psr_unregister(>encoder);
analogix_dp_unbind(dp->adp);
+   dp->encoder.funcs->destroy(>encoder);
 }
 
 static const struct component_ops rockchip_dp_component_ops = {
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 00/10] rockchip: kevin: Enable edp display

2017-10-18 Thread Jeffy Chen

Make edp display works on chromebook kevin(at least for boot animation).

Also solve some issues i meet during the bringup.

Changes in v6:
Don't change order of rockchip_drm_psr_register().

Changes in v5:
Call the destroy hook in the error handling path like in unbind().
Call the destroy hook in the error handling path like in unbind().
Update cleanup order in unbind().
Add disable to unbind(), and inline clk_prepare_enable() with bind().

Jeffy Chen (10):
  arm64: dts: rockchip: Enable edp disaplay on kevin
  drm/rockchip: analogix_dp: Remove unnecessary init code
  drm/bridge: analogix: Do not use device's drvdata
  drm/bridge: analogix_dp: Fix connector and encoder cleanup
  drm/rockchip: analogix_dp: Add a sanity check for
rockchip_drm_psr_register()
  drm/rockchip: dw-mipi-dsi: Fix error handling path
  drm/rockchip: inno_hdmi: Fix error handling path
  drm/bridge/synopsys: dw-hdmi: Add missing bridge detach
  drm/bridge/synopsys: dw-hdmi: Do not use device's drvdata
  drm/rockchip: dw_hdmi: Fix error handling path

 arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts  | 29 +++
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi   | 16 
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 52 +---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c  | 53 ++--
 drivers/gpu/drm/exynos/exynos_dp.c | 29 ---
 drivers/gpu/drm/imx/dw_hdmi-imx.c  | 22 +++--
 drivers/gpu/drm/meson/meson_dw_hdmi.c  | 20 +++--
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 14 +++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 95 +++---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 21 +++--
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 39 +
 drivers/gpu/drm/rockchip/inno_hdmi.c   | 22 +++--
 include/drm/bridge/analogix_dp.h   | 19 +++--
 include/drm/bridge/dw_hdmi.h   | 17 ++--
 14 files changed, 265 insertions(+), 183 deletions(-)

-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 8/9] drm/bridge/synopsys: dw-hdmi: Do not use device's drvdata

2017-10-18 Thread Jeffy Chen
Let plat drivers own the drvdata, so that they could cleanup resources
in their unbind().

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None

 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 43 ++---
 drivers/gpu/drm/imx/dw_hdmi-imx.c   | 22 +--
 drivers/gpu/drm/meson/meson_dw_hdmi.c   | 20 ++
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c  | 14 --
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 23 ---
 include/drm/bridge/dw_hdmi.h| 17 ++--
 6 files changed, 77 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index ff1b3d2b5d06..6fbfafc5832b 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2072,7 +2072,7 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
return ret;
 }
 
-void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
+void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
 {
mutex_lock(>mutex);
 
@@ -2098,13 +2098,6 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool 
hpd, bool rx_sense)
}
mutex_unlock(>mutex);
 }
-
-void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense)
-{
-   struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
-   __dw_hdmi_setup_rx_sense(hdmi, hpd, rx_sense);
-}
 EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
 
 static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
@@ -2140,9 +2133,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 */
if (intr_stat &
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
-   __dw_hdmi_setup_rx_sense(hdmi,
-phy_stat & HDMI_PHY_HPD,
-phy_stat & HDMI_PHY_RX_SENSE);
+   dw_hdmi_setup_rx_sense(hdmi, phy_stat & HDMI_PHY_HPD,
+  phy_stat & HDMI_PHY_RX_SENSE);
 
if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
cec_notifier_set_phys_addr(hdmi->cec_notifier,
@@ -2512,8 +2504,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
 
-   platform_set_drvdata(pdev, hdmi);
-
return hdmi;
 
 err_iahb:
@@ -2559,25 +2549,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
 /* 
-
  * Probe/remove API, used from platforms based on the DRM bridge API.
  */
-int dw_hdmi_probe(struct platform_device *pdev,
- const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
+ const struct dw_hdmi_plat_data *plat_data)
 {
struct dw_hdmi *hdmi;
 
hdmi = __dw_hdmi_probe(pdev, plat_data);
if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
 
drm_bridge_add(>bridge);
 
-   return 0;
+   return hdmi;
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_probe);
 
-void dw_hdmi_remove(struct platform_device *pdev)
+void dw_hdmi_remove(struct dw_hdmi *hdmi)
 {
-   struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
-
drm_bridge_remove(>bridge);
 
__dw_hdmi_remove(hdmi);
@@ -2587,31 +2575,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
 /* 
-
  * Bind/unbind API, used from platforms based on the component framework.
  */
-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
-const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
+   struct drm_encoder *encoder,
+   const struct dw_hdmi_plat_data *plat_data)
 {
struct dw_hdmi *hdmi;
int ret;
 
hdmi = __dw_hdmi_probe(pdev, plat_data);
if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
 
ret = drm_bridge_attach(encoder, >bridge, NULL);
if (ret) {
__dw_hdmi_remove(hdmi);
DRM_ERROR("Failed to initialize bridge with drm\n");
-   return ret;
+   return ERR_PTR(ret);
}
 
-   return 0;
+   return hdmi;
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_bind);
 
-void dw_hdmi_unbind(struct device *dev)
+void dw_hdmi_unbind(struct dw_hdmi *hdmi)
 {
-   struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
__dw_hdmi_remove(hdmi);
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index b62763aa8706..b01d03e02ce0 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/driver

[PATCH v5 9/9] drm/rockchip: dw_hdmi: Fix error handling path

2017-10-18 Thread Jeffy Chen
Add missing clk_disable_unprepare() in bind()'s error handling path and
unbind().

Also inline clk_prepare_enable() with bind().

Fixes: 12b9f204e804 ("drm: bridge/dw_hdmi: add rockchip rk3288 support")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5:
Add disable to unbind(), and inline clk_prepare_enable() with bind().

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 791ab938f998..e936dfe6c03d 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -193,13 +193,6 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return PTR_ERR(hdmi->grf_clk);
}
 
-   ret = clk_prepare_enable(hdmi->vpll_clk);
-   if (ret) {
-   DRM_DEV_ERROR(hdmi->dev,
- "Failed to enable HDMI vpll: %d\n", ret);
-   return ret;
-   }
-
return 0;
 }
 
@@ -374,6 +367,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, 
struct device *master,
return ret;
}
 
+   ret = clk_prepare_enable(hdmi->vpll_clk);
+   if (ret) {
+   DRM_DEV_ERROR(hdmi->dev,
+ "Failed to enable HDMI vpll: %d\n", ret);
+   return ret;
+   }
+
drm_encoder_helper_add(encoder, _hdmi_rockchip_encoder_helper_funcs);
drm_encoder_init(drm, encoder, _hdmi_rockchip_encoder_funcs,
 DRM_MODE_ENCODER_TMDS, NULL);
@@ -381,6 +381,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct 
device *master,
hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
if (IS_ERR(hdmi->hdmi)) {
encoder->funcs->destroy(encoder);
+   clk_disable_unprepare(hdmi->vpll_clk);
return PTR_ERR(hdmi->hdmi);
}
 
@@ -396,6 +397,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, 
struct device *master,
 
dw_hdmi_unbind(hdmi->hdmi);
hdmi->encoder.funcs->destroy(>encoder);
+   clk_disable_unprepare(hdmi->vpll_clk);
 }
 
 static const struct component_ops dw_hdmi_rockchip_ops = {
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 6/9] drm/rockchip: inno_hdmi: Fix error handling path

2017-10-18 Thread Jeffy Chen
Add missing error handling in bind().

Fixes: 412d4ae6b7a5 ("drm/rockchip: hdmi: add Innosilicon HDMI support")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5:
Call the destroy hook in the error handling path like in unbind().
Update cleanup order in unbind().

 drivers/gpu/drm/rockchip/inno_hdmi.c | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index ee584d87111f..9a96ff6b022b 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -851,8 +851,10 @@ static int inno_hdmi_bind(struct device *dev, struct 
device *master,
}
 
irq = platform_get_irq(pdev, 0);
-   if (irq < 0)
-   return irq;
+   if (irq < 0) {
+   ret = irq;
+   goto err_disable_clk;
+   }
 
inno_hdmi_reset(hdmi);
 
@@ -860,7 +862,7 @@ static int inno_hdmi_bind(struct device *dev, struct device 
*master,
if (IS_ERR(hdmi->ddc)) {
ret = PTR_ERR(hdmi->ddc);
hdmi->ddc = NULL;
-   return ret;
+   goto err_disable_clk;
}
 
/*
@@ -874,7 +876,7 @@ static int inno_hdmi_bind(struct device *dev, struct device 
*master,
 
ret = inno_hdmi_register(drm, hdmi);
if (ret)
-   return ret;
+   goto err_put_adapter;
 
dev_set_drvdata(dev, hdmi);
 
@@ -884,7 +886,17 @@ static int inno_hdmi_bind(struct device *dev, struct 
device *master,
ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
inno_hdmi_irq, IRQF_SHARED,
dev_name(dev), hdmi);
+   if (ret < 0)
+   goto err_cleanup_hdmi;
 
+   return 0;
+err_cleanup_hdmi:
+   hdmi->connector.funcs->destroy(>connector);
+   hdmi->encoder.funcs->destroy(>encoder);
+err_put_adapter:
+   i2c_put_adapter(hdmi->ddc);
+err_disable_clk:
+   clk_disable_unprepare(hdmi->pclk);
return ret;
 }
 
@@ -896,8 +908,8 @@ static void inno_hdmi_unbind(struct device *dev, struct 
device *master,
hdmi->connector.funcs->destroy(>connector);
hdmi->encoder.funcs->destroy(>encoder);
 
-   clk_disable_unprepare(hdmi->pclk);
i2c_put_adapter(hdmi->ddc);
+   clk_disable_unprepare(hdmi->pclk);
 }
 
 static const struct component_ops inno_hdmi_ops = {
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 7/9] drm/bridge/synopsys: dw-hdmi: Add missing bridge detach

2017-10-18 Thread Jeffy Chen
We inited connector in attach(), so need a detach() to cleanup.

Also fix wrong use of dw_hdmi_remove() in bind().

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None

 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index bf14214fa464..ff1b3d2b5d06 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1966,6 +1966,13 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
*bridge)
return 0;
 }
 
+static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
+{
+   struct dw_hdmi *hdmi = bridge->driver_private;
+
+   drm_connector_cleanup(>connector);
+}
+
 static enum drm_mode_status
 dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
  const struct drm_display_mode *mode)
@@ -2022,6 +2029,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge 
*bridge)
 
 static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
.attach = dw_hdmi_bridge_attach,
+   .detach = dw_hdmi_bridge_detach,
.enable = dw_hdmi_bridge_enable,
.disable = dw_hdmi_bridge_disable,
.mode_set = dw_hdmi_bridge_mode_set,
@@ -2591,7 +2599,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct 
drm_encoder *encoder,
 
ret = drm_bridge_attach(encoder, >bridge, NULL);
if (ret) {
-   dw_hdmi_remove(pdev);
+   __dw_hdmi_remove(hdmi);
DRM_ERROR("Failed to initialize bridge with drm\n");
return ret;
}
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 2/9] drm/rockchip: analogix_dp: Remove unnecessary init code

2017-10-18 Thread Jeffy Chen
Remove unnecessary init code, since we would do it in the power_on()
callback.

Also move of parse code to probe().

Fixes: 9e32e16e9e98 ("drm: rockchip: dp: add rockchip platform dp driver")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 27 ++---
 1 file changed, 6 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 4d3f6ad0abdd..8cae5ad926cd 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -269,7 +269,7 @@ static struct drm_encoder_funcs rockchip_dp_encoder_funcs = 
{
.destroy = rockchip_dp_drm_encoder_destroy,
 };
 
-static int rockchip_dp_init(struct rockchip_dp_device *dp)
+static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
 {
struct device *dev = dp->dev;
struct device_node *np = dev->of_node;
@@ -303,19 +303,6 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp)
return PTR_ERR(dp->rst);
}
 
-   ret = clk_prepare_enable(dp->pclk);
-   if (ret < 0) {
-   DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
-   return ret;
-   }
-
-   ret = rockchip_dp_pre_init(dp);
-   if (ret < 0) {
-   DRM_DEV_ERROR(dp->dev, "failed to pre init %d\n", ret);
-   clk_disable_unprepare(dp->pclk);
-   return ret;
-   }
-
return 0;
 }
 
@@ -361,10 +348,6 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
if (!dp_data)
return -ENODEV;
 
-   ret = rockchip_dp_init(dp);
-   if (ret < 0)
-   return ret;
-
dp->data = dp_data;
dp->drm_dev = drm_dev;
 
@@ -398,7 +381,6 @@ static void rockchip_dp_unbind(struct device *dev, struct 
device *master,
rockchip_drm_psr_unregister(>encoder);
 
analogix_dp_unbind(dev, master, data);
-   clk_disable_unprepare(dp->pclk);
 }
 
 static const struct component_ops rockchip_dp_component_ops = {
@@ -414,7 +396,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
int ret;
 
ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, , NULL);
-   if (ret)
+   if (ret < 0)
return ret;
 
dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
@@ -422,9 +404,12 @@ static int rockchip_dp_probe(struct platform_device *pdev)
return -ENOMEM;
 
dp->dev = dev;
-
dp->plat_data.panel = panel;
 
+   ret = rockchip_dp_of_probe(dp);
+   if (ret < 0)
+   return ret;
+
/*
 * We just use the drvdata until driver run into component
 * add function, and then we would set drvdata to null, so
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 0/9] rockchip: kevin: Enable edp display

2017-10-18 Thread Jeffy Chen

Make edp display works on chromebook kevin(at least for boot animation).

Also solve some issues i meet during the bringup.

Changes in v5:
Call the destroy hook in the error handling path like in unbind().
Call the destroy hook in the error handling path like in unbind().
Update cleanup order in unbind().
Add disable to unbind(), and inline clk_prepare_enable() with bind().

Jeffy Chen (9):
  arm64: dts: rockchip: Enable edp disaplay on kevin
  drm/rockchip: analogix_dp: Remove unnecessary init code
  drm/bridge: analogix: Do not use device's drvdata
  drm/bridge: analogix_dp: Fix connector & encoder cleanup
  drm/rockchip: dw-mipi-dsi: Fix error handling path
  drm/rockchip: inno_hdmi: Fix error handling path
  drm/bridge/synopsys: dw-hdmi: Add missing bridge detach
  drm/bridge/synopsys: dw-hdmi: Do not use device's drvdata
  drm/rockchip: dw_hdmi: Fix error handling path

 arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts  | 29 
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi   | 16 
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 52 +
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c  | 53 ++---
 drivers/gpu/drm/exynos/exynos_dp.c | 29 +---
 drivers/gpu/drm/imx/dw_hdmi-imx.c  | 22 +++---
 drivers/gpu/drm/meson/meson_dw_hdmi.c  | 20 +++--
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 14 +++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 87 ++
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 21 --
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 39 +-
 drivers/gpu/drm/rockchip/inno_hdmi.c   | 22 --
 include/drm/bridge/analogix_dp.h   | 19 +++--
 include/drm/bridge/dw_hdmi.h   | 17 +++--
 14 files changed, 257 insertions(+), 183 deletions(-)

-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 5/9] drm/rockchip: dw-mipi-dsi: Fix error handling path

2017-10-18 Thread Jeffy Chen
Add missing pm_runtime_disable() in bind()'s error handling path.

Also cleanup encoder & connector in unbind().

Fixes: 80a9a059d4e4 ("drm/rockchip/dsi: add dw-mipi power domain support")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5:
Call the destroy hook in the error handling path like in unbind().

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index b15755b6129c..e72d4e2b61aa 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -1282,7 +1282,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = dw_mipi_dsi_register(drm, dsi);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register mipi_dsi: %d\n", ret);
-   goto err_pllref;
+   goto err_disable_pllref;
}
 
pm_runtime_enable(dev);
@@ -1292,23 +1292,24 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = mipi_dsi_host_register(>dsi_host);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
-   goto err_cleanup;
+   goto err_disable_pm_runtime;
}
 
if (!dsi->panel) {
ret = -EPROBE_DEFER;
-   goto err_mipi_dsi_host;
+   goto err_unreg_mipi_dsi_host;
}
 
dev_set_drvdata(dev, dsi);
return 0;
 
-err_mipi_dsi_host:
+err_unreg_mipi_dsi_host:
mipi_dsi_host_unregister(>dsi_host);
-err_cleanup:
-   drm_encoder_cleanup(>encoder);
-   drm_connector_cleanup(>connector);
-err_pllref:
+err_disable_pm_runtime:
+   pm_runtime_disable(dev);
+   dsi->connector.funcs->destroy(>connector);
+   dsi->encoder.funcs->destroy(>encoder);
+err_disable_pllref:
clk_disable_unprepare(dsi->pllref_clk);
return ret;
 }
@@ -1320,6 +1321,10 @@ static void dw_mipi_dsi_unbind(struct device *dev, 
struct device *master,
 
mipi_dsi_host_unregister(>dsi_host);
pm_runtime_disable(dev);
+
+   dsi->connector.funcs->destroy(>connector);
+   dsi->encoder.funcs->destroy(>encoder);
+
clk_disable_unprepare(dsi->pllref_clk);
 }
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 4/9] drm/bridge: analogix_dp: Fix connector & encoder cleanup

2017-10-18 Thread Jeffy Chen
Since we are initing connector in the core driver and encoder in the
plat driver, let's clean them up in the right places.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  2 --
 drivers/gpu/drm/exynos/exynos_dp.c |  7 +--
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 15 ++-
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 74d274b6d31d..3f910ab36ff6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1409,7 +1409,6 @@ analogix_dp_bind(struct device *dev, struct drm_device 
*drm_dev,
ret = analogix_dp_create_bridge(drm_dev, dp);
if (ret) {
DRM_ERROR("failed to create bridge (%d)\n", ret);
-   drm_encoder_cleanup(dp->encoder);
goto err_disable_pm_runtime;
}
 
@@ -1432,7 +1431,6 @@ void analogix_dp_unbind(struct analogix_dp_device *dp)
 {
analogix_dp_bridge_disable(dp->bridge);
dp->connector.funcs->destroy(>connector);
-   dp->encoder->funcs->destroy(dp->encoder);
 
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c 
b/drivers/gpu/drm/exynos/exynos_dp.c
index f7e5b2c405ed..33319a858f3a 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -185,8 +185,10 @@ static int exynos_dp_bind(struct device *dev, struct 
device *master, void *data)
dp->plat_data.encoder = encoder;
 
dp->adp = analogix_dp_bind(dev, dp->drm_dev, >plat_data);
-   if (IS_ERR(dp->adp))
+   if (IS_ERR(dp->adp)) {
+   dp->encoder.funcs->destroy(>encoder);
return PTR_ERR(dp->adp);
+   }
 
return 0;
 }
@@ -196,7 +198,8 @@ static void exynos_dp_unbind(struct device *dev, struct 
device *master,
 {
struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-   return analogix_dp_unbind(dp->adp);
+   analogix_dp_unbind(dp->adp);
+   dp->encoder.funcs->destroy(>encoder);
 }
 
 static const struct component_ops exynos_dp_ops = {
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index fa0365de31d2..c0fb3f3748f4 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -261,13 +261,8 @@ static struct drm_encoder_helper_funcs 
rockchip_dp_encoder_helper_funcs = {
.atomic_check = rockchip_dp_drm_encoder_atomic_check,
 };
 
-static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
-{
-   drm_encoder_cleanup(encoder);
-}
-
 static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
-   .destroy = rockchip_dp_drm_encoder_destroy,
+   .destroy = drm_encoder_cleanup,
 };
 
 static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
@@ -361,12 +356,13 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE;
INIT_WORK(>psr_work, analogix_dp_psr_work);
 
-   rockchip_drm_psr_register(>encoder, analogix_dp_psr_set);
-
dp->adp = analogix_dp_bind(dev, dp->drm_dev, >plat_data);
-   if (IS_ERR(dp->adp))
+   if (IS_ERR(dp->adp)) {
+   dp->encoder.funcs->destroy(>encoder);
return PTR_ERR(dp->adp);
+   }
 
+   rockchip_drm_psr_register(>encoder, analogix_dp_psr_set);
return 0;
 }
 
@@ -377,6 +373,7 @@ static void rockchip_dp_unbind(struct device *dev, struct 
device *master,
 
rockchip_drm_psr_unregister(>encoder);
analogix_dp_unbind(dp->adp);
+   dp->encoder.funcs->destroy(>encoder);
 }
 
 static const struct component_ops rockchip_dp_component_ops = {
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 3/9] drm/bridge: analogix: Do not use device's drvdata

2017-10-18 Thread Jeffy Chen
The driver that instantiates the bridge should own the drvdata, as all
driver model callbacks (probe, remove, shutdown, PM ops, etc.) are also
owned by its driver struct. Moreover, storing two different pointer
types in driver data depending on driver initialization status is barely
a good practice and in fact has led to many bugs in this driver.

Let's clean up this mess and change Analogix entry points to simply
accept some opaque struct pointer, adjusting their users at the same
time to avoid breaking the compilation.

Signed-off-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Reviewed-by: Sean Paul <seanp...@chromium.org>
Acked-by: Jingoo Han <jingooh...@gmail.com>
Acked-by: Archit Taneja <arch...@codeaurora.org>
---

Changes in v5: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 +-
 drivers/gpu/drm/exynos/exynos_dp.c | 26 ++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 49 -
 include/drm/bridge/analogix_dp.h   | 19 
 4 files changed, 74 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5dd3f1cd074a..74d274b6d31d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,17 +98,15 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
 }
 
-int analogix_dp_psr_supported(struct device *dev)
+int analogix_dp_psr_supported(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
 
return dp->psr_support;
 }
 EXPORT_SYMBOL_GPL(analogix_dp_psr_supported);
 
-int analogix_dp_enable_psr(struct device *dev)
+int analogix_dp_enable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
 
if (!dp->psr_support)
@@ -129,9 +127,8 @@ int analogix_dp_enable_psr(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
 
-int analogix_dp_disable_psr(struct device *dev)
+int analogix_dp_disable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
int ret;
 
@@ -1281,8 +1278,9 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux 
*aux,
return analogix_dp_transfer(dp, msg);
 }
 
-int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
-struct analogix_dp_plat_data *plat_data)
+struct analogix_dp_device *
+analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
+struct analogix_dp_plat_data *plat_data)
 {
struct platform_device *pdev = to_platform_device(dev);
struct analogix_dp_device *dp;
@@ -1292,14 +1290,12 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
if (!plat_data) {
dev_err(dev, "Invalided input plat_data\n");
-   return -EINVAL;
+   return ERR_PTR(-EINVAL);
}
 
dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL);
if (!dp)
-   return -ENOMEM;
-
-   dev_set_drvdata(dev, dp);
+   return ERR_PTR(-ENOMEM);
 
dp->dev = >dev;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1316,7 +1312,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
ret = analogix_dp_dt_parse_pdata(dp);
if (ret)
-   return ret;
+   return ERR_PTR(ret);
 
dp->phy = devm_phy_get(dp->dev, "dp");
if (IS_ERR(dp->phy)) {
@@ -1330,14 +1326,14 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
if (ret == -ENOSYS || ret == -ENODEV)
dp->phy = NULL;
else
-   return ret;
+   return ERR_PTR(ret);
}
}
 
dp->clock = devm_clk_get(>dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(>dev, "failed to get clock\n");
-   return PTR_ERR(dp->clock);
+   return ERR_CAST(dp->clock);
}
 
clk_prepare_enable(dp->clock);
@@ -1346,7 +1342,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
dp->reg_base = devm_ioremap_resource(>dev, res);
if (IS_ERR(dp->reg_base))
-   return PTR_ERR(dp->reg_base);
+   return ERR_CAST(dp->reg_base);
 
dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
 
@@ -1367,7 +1363,7 @@ int analogix_dp_bind(struct device 

[RFC PATCH v4 8/8] drm/rockchip: Add device links for master and components

2017-10-17 Thread Jeffy Chen
Since we are trying to access components' resources in the master's
suspend/resume PM callbacks(e.g. panel), add device links to correct
the suspend/resume and shutdown ordering.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2:
Use device link to correct the suspend/resume and shutdown ordering,
instead of converting rockchip spi's suspend/resume PM callbacks to
late suspend/resume PM callbacks.

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 76d63de5921d..af18967f699b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -337,6 +337,8 @@ static struct component_match 
*rockchip_drm_match_add(struct device *dev)
 
if (!d)
break;
+
+   device_link_add(dev, d, DL_FLAG_STATELESS);
component_match_add(dev, , compare_dev, d);
} while (true);
}
@@ -406,6 +408,7 @@ static int rockchip_drm_platform_of_probe(struct device 
*dev)
 static int rockchip_drm_platform_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
+   struct device_link *link;
struct component_match *match = NULL;
int ret;
 
@@ -414,16 +417,31 @@ static int rockchip_drm_platform_probe(struct 
platform_device *pdev)
return ret;
 
match = rockchip_drm_match_add(dev);
-   if (IS_ERR(match))
-   return PTR_ERR(match);
+   if (IS_ERR(match)) {
+   ret = PTR_ERR(match);
+   goto err_cleanup_dev_links;
+   }
 
-   return component_master_add_with_match(dev, _drm_ops, match);
+   ret = component_master_add_with_match(dev, _drm_ops, match);
+   if (ret < 0)
+   goto err_cleanup_dev_links;
+
+   return 0;
+err_cleanup_dev_links:
+   list_for_each_entry(link, >links.consumers, s_node)
+   device_link_del(link);
+   return ret;
 }
 
 static int rockchip_drm_platform_remove(struct platform_device *pdev)
 {
+   struct device_link *link;
+
component_master_del(>dev, _drm_ops);
 
+   list_for_each_entry(link, >dev.links.consumers, s_node)
+   device_link_del(link);
+
return 0;
 }
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH v4 4/8] drm/rockchip: dw_hdmi: Fix error handling path

2017-10-17 Thread Jeffy Chen
Add missing clk_disable_unprepare() in bind()'s error handling path.

Fixes: 12b9f204e804 ("drm: bridge/dw_hdmi: add rockchip rk3288 support")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 1eb02a82fd91..582283da7861 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -383,8 +383,10 @@ static int dw_hdmi_rockchip_bind(struct device *dev, 
struct device *master,
 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
 * which would have called the encoder cleanup.  Do it manually.
 */
-   if (ret)
+   if (ret) {
drm_encoder_cleanup(encoder);
+   clk_disable_unprepare(hdmi->vpll_clk);
+   }
 
return ret;
 }
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH v4 6/8] drm/bridge/analogix: Do not use device's drvdata

2017-10-17 Thread Jeffy Chen
From: Tomasz Figa <tf...@chromium.org>

The driver that instantiates the bridge should own the drvdata, as all
driver model callbacks (probe, remove, shutdown, PM ops, etc.) are also
owned by its driver struct. Moreover, storing two different pointer
types in driver data depending on driver initialization status is barely
a good practice and in fact has led to many bugs in this driver.

Let's clean up this mess and change Analogix entry points to simply
accept some opaque struct pointer, adjusting their users at the same
time to avoid breaking the compilation.

Signed-off-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 +-
 drivers/gpu/drm/exynos/exynos_dp.c | 26 ++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 47 +++-
 include/drm/bridge/analogix_dp.h   | 19 
 4 files changed, 73 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5dd3f1cd074a..74d274b6d31d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,17 +98,15 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
 }
 
-int analogix_dp_psr_supported(struct device *dev)
+int analogix_dp_psr_supported(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
 
return dp->psr_support;
 }
 EXPORT_SYMBOL_GPL(analogix_dp_psr_supported);
 
-int analogix_dp_enable_psr(struct device *dev)
+int analogix_dp_enable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
 
if (!dp->psr_support)
@@ -129,9 +127,8 @@ int analogix_dp_enable_psr(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
 
-int analogix_dp_disable_psr(struct device *dev)
+int analogix_dp_disable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
int ret;
 
@@ -1281,8 +1278,9 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux 
*aux,
return analogix_dp_transfer(dp, msg);
 }
 
-int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
-struct analogix_dp_plat_data *plat_data)
+struct analogix_dp_device *
+analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
+struct analogix_dp_plat_data *plat_data)
 {
struct platform_device *pdev = to_platform_device(dev);
struct analogix_dp_device *dp;
@@ -1292,14 +1290,12 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
if (!plat_data) {
dev_err(dev, "Invalided input plat_data\n");
-   return -EINVAL;
+   return ERR_PTR(-EINVAL);
}
 
dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL);
if (!dp)
-   return -ENOMEM;
-
-   dev_set_drvdata(dev, dp);
+   return ERR_PTR(-ENOMEM);
 
dp->dev = >dev;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1316,7 +1312,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
ret = analogix_dp_dt_parse_pdata(dp);
if (ret)
-   return ret;
+   return ERR_PTR(ret);
 
dp->phy = devm_phy_get(dp->dev, "dp");
if (IS_ERR(dp->phy)) {
@@ -1330,14 +1326,14 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
if (ret == -ENOSYS || ret == -ENODEV)
dp->phy = NULL;
else
-   return ret;
+   return ERR_PTR(ret);
}
}
 
dp->clock = devm_clk_get(>dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(>dev, "failed to get clock\n");
-   return PTR_ERR(dp->clock);
+   return ERR_CAST(dp->clock);
}
 
clk_prepare_enable(dp->clock);
@@ -1346,7 +1342,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
dp->reg_base = devm_ioremap_resource(>dev, res);
if (IS_ERR(dp->reg_base))
-   return PTR_ERR(dp->reg_base);
+   return ERR_CAST(dp->reg_base);
 
dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
 
@@ -1367,7 +1363,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
  

[RFC PATCH v4 5/8] drm/rockchip: inno_hdmi: Fix error handling path

2017-10-17 Thread Jeffy Chen
Add missing error handling in bind().

Fixes: 412d4ae6b7a5 ("drm/rockchip: hdmi: add Innosilicon HDMI support")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/inno_hdmi.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index ee584d87111f..9c258b05dfa5 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -851,8 +851,10 @@ static int inno_hdmi_bind(struct device *dev, struct 
device *master,
}
 
irq = platform_get_irq(pdev, 0);
-   if (irq < 0)
-   return irq;
+   if (irq < 0) {
+   ret = irq;
+   goto err_disable_clk;
+   }
 
inno_hdmi_reset(hdmi);
 
@@ -860,7 +862,7 @@ static int inno_hdmi_bind(struct device *dev, struct device 
*master,
if (IS_ERR(hdmi->ddc)) {
ret = PTR_ERR(hdmi->ddc);
hdmi->ddc = NULL;
-   return ret;
+   goto err_disable_clk;
}
 
/*
@@ -874,7 +876,7 @@ static int inno_hdmi_bind(struct device *dev, struct device 
*master,
 
ret = inno_hdmi_register(drm, hdmi);
if (ret)
-   return ret;
+   goto err_put_adapter;
 
dev_set_drvdata(dev, hdmi);
 
@@ -884,7 +886,17 @@ static int inno_hdmi_bind(struct device *dev, struct 
device *master,
ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
inno_hdmi_irq, IRQF_SHARED,
dev_name(dev), hdmi);
+   if (ret < 0)
+   goto err_cleanup_hdmi;
 
+   return 0;
+err_cleanup_hdmi:
+   drm_connector_cleanup(>connector);
+   drm_encoder_cleanup(>encoder);
+err_put_adapter:
+   i2c_put_adapter(hdmi->ddc);
+err_disable_clk:
+   clk_disable_unprepare(hdmi->pclk);
return ret;
 }
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH v4 0/8] rockchip: kevin: Enable edp display

2017-10-17 Thread Jeffy Chen

Make edp display works on chromebook kevin(at least for boot animation).

Also solve some issues i meet during the bringup.

Changes in v4:
Fix compile warning.

Changes in v3:
Assign orphan pwms to dummy pwmchip instead of adding device link in the
customer driver.

Changes in v2:
Use device link to correct the suspend/resume and shutdown ordering,
instead of converting rockchip spi's suspend/resume PM callbacks to
late suspend/resume PM callbacks.

Jeffy Chen (7):
  arm64: dts: rockchip: Enable edp disaplay on kevin
  drm/rockchip: analogix_dp: Fix error handling path
  drm/rockchip: dw-mipi-dsi: Fix error handling path
  drm/rockchip: dw_hdmi: Fix error handling path
  drm/rockchip: inno_hdmi: Fix error handling path
  pwm: Add dummy pwmchip for orphan pwms
  drm/rockchip: Add device links for master and components

Tomasz Figa (1):
  drm/bridge/analogix: Do not use device's drvdata

 arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts  | 29 
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi   | 16 +
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 ++---
 drivers/gpu/drm/exynos/exynos_dp.c | 26 ---
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 57 +--
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 17 +++--
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c|  4 +-
 drivers/gpu/drm/rockchip/inno_hdmi.c   | 20 --
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c| 24 ++-
 drivers/pwm/core.c | 81 --
 include/drm/bridge/analogix_dp.h   | 19 ++---
 11 files changed, 254 insertions(+), 89 deletions(-)

-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH v4 2/8] drm/rockchip: analogix_dp: Fix error handling path

2017-10-17 Thread Jeffy Chen
Add missing error handling in rockchip_dp_bind().

Fixes: 9e32e16e9e98 ("drm: rockchip: dp: add rockchip platform dp driver")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 4d3f6ad0abdd..4b689c0f3fc1 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -371,7 +371,7 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
ret = rockchip_dp_drm_create_encoder(dp);
if (ret) {
DRM_ERROR("failed to create drm encoder\n");
-   return ret;
+   goto err_disable_pclk;
}
 
dp->plat_data.encoder = >encoder;
@@ -387,7 +387,17 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
 
rockchip_drm_psr_register(>encoder, analogix_dp_psr_set);
 
-   return analogix_dp_bind(dev, dp->drm_dev, >plat_data);
+   ret = analogix_dp_bind(dev, dp->drm_dev, >plat_data);
+   if (ret < 0)
+   goto err_unreg_psr;
+   return 0;
+
+err_unreg_psr:
+   rockchip_drm_psr_unregister(>encoder);
+   rockchip_dp_drm_encoder_destroy(>encoder);
+err_disable_pclk:
+   clk_disable_unprepare(dp->pclk);
+   return ret;
 }
 
 static void rockchip_dp_unbind(struct device *dev, struct device *master,
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH v4 3/8] drm/rockchip: dw-mipi-dsi: Fix error handling path

2017-10-17 Thread Jeffy Chen
Add missing pm_runtime_disable() in bind()'s error handling path.

Also cleanup encoder & connector in unbind().

Fixes: 80a9a059d4e4 ("drm/rockchip/dsi: add dw-mipi power domain support")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index b15755b6129c..a17ff0f6f489 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -1282,7 +1282,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = dw_mipi_dsi_register(drm, dsi);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register mipi_dsi: %d\n", ret);
-   goto err_pllref;
+   goto err_disable_pllref;
}
 
pm_runtime_enable(dev);
@@ -1292,23 +1292,24 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = mipi_dsi_host_register(>dsi_host);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
-   goto err_cleanup;
+   goto err_disable_pm_runtime;
}
 
if (!dsi->panel) {
ret = -EPROBE_DEFER;
-   goto err_mipi_dsi_host;
+   goto err_unreg_mipi_dsi_host;
}
 
dev_set_drvdata(dev, dsi);
return 0;
 
-err_mipi_dsi_host:
+err_unreg_mipi_dsi_host:
mipi_dsi_host_unregister(>dsi_host);
-err_cleanup:
+err_disable_pm_runtime:
+   pm_runtime_disable(dev);
drm_encoder_cleanup(>encoder);
drm_connector_cleanup(>connector);
-err_pllref:
+err_disable_pllref:
clk_disable_unprepare(dsi->pllref_clk);
return ret;
 }
@@ -1320,6 +1321,10 @@ static void dw_mipi_dsi_unbind(struct device *dev, 
struct device *master,
 
mipi_dsi_host_unregister(>dsi_host);
pm_runtime_disable(dev);
+
+   dsi->connector.funcs->destroy(>connector);
+   dsi->encoder.funcs->destroy(>encoder);
+
clk_disable_unprepare(dsi->pllref_clk);
 }
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH v3 2/5] drm/rockchip: Fix error handling path in rockchip_dp_bind()

2017-10-17 Thread Jeffy Chen
Add missing error handling in rockchip_dp_bind().

Fixes: 9e32e16e9e98 ("drm: rockchip: dp: add rockchip platform dp driver")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 4d3f6ad0abdd..cb8941e8bcdd 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -371,7 +371,7 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
ret = rockchip_dp_drm_create_encoder(dp);
if (ret) {
DRM_ERROR("failed to create drm encoder\n");
-   return ret;
+   goto err_deinit_dp;
}
 
dp->plat_data.encoder = >encoder;
@@ -387,7 +387,17 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
 
rockchip_drm_psr_register(>encoder, analogix_dp_psr_set);
 
-   return analogix_dp_bind(dev, dp->drm_dev, >plat_data);
+   ret = analogix_dp_bind(dev, dp->drm_dev, >plat_data);
+   if (ret < 0)
+   goto err_unreg_psr;
+   return 0;
+
+err_unreg_psr:
+   rockchip_drm_psr_unregister(>encoder);
+   rockchip_dp_drm_encoder_destroy(>encoder);
+err_deinit_dp:
+   clk_disable_unprepare(dp->pclk);
+   return ret;
 }
 
 static void rockchip_dp_unbind(struct device *dev, struct device *master,
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH v3 5/5] drm/rockchip: Add device links for master and components

2017-10-17 Thread Jeffy Chen
Since we are trying to access components' resources in the master's
suspend/resume PM callbacks(e.g. panel), add device links to correct
the suspend/resume and shutdown ordering.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3: None
Changes in v2:
Use device link to correct the suspend/resume and shutdown ordering,
instead of converting rockchip spi's suspend/resume PM callbacks to
late suspend/resume PM callbacks.

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 76d63de5921d..af18967f699b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -337,6 +337,8 @@ static struct component_match 
*rockchip_drm_match_add(struct device *dev)
 
if (!d)
break;
+
+   device_link_add(dev, d, DL_FLAG_STATELESS);
component_match_add(dev, , compare_dev, d);
} while (true);
}
@@ -406,6 +408,7 @@ static int rockchip_drm_platform_of_probe(struct device 
*dev)
 static int rockchip_drm_platform_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
+   struct device_link *link;
struct component_match *match = NULL;
int ret;
 
@@ -414,16 +417,31 @@ static int rockchip_drm_platform_probe(struct 
platform_device *pdev)
return ret;
 
match = rockchip_drm_match_add(dev);
-   if (IS_ERR(match))
-   return PTR_ERR(match);
+   if (IS_ERR(match)) {
+   ret = PTR_ERR(match);
+   goto err_cleanup_dev_links;
+   }
 
-   return component_master_add_with_match(dev, _drm_ops, match);
+   ret = component_master_add_with_match(dev, _drm_ops, match);
+   if (ret < 0)
+   goto err_cleanup_dev_links;
+
+   return 0;
+err_cleanup_dev_links:
+   list_for_each_entry(link, >links.consumers, s_node)
+   device_link_del(link);
+   return ret;
 }
 
 static int rockchip_drm_platform_remove(struct platform_device *pdev)
 {
+   struct device_link *link;
+
component_master_del(>dev, _drm_ops);
 
+   list_for_each_entry(link, >dev.links.consumers, s_node)
+   device_link_del(link);
+
return 0;
 }
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC PATCH v3 3/5] drm/bridge/analogix: Do not use device's drvdata

2017-10-17 Thread Jeffy Chen
From: Tomasz Figa <tf...@chromium.org>

The driver that instantiates the bridge should own the drvdata, as all
driver model callbacks (probe, remove, shutdown, PM ops, etc.) are also
owned by its driver struct. Moreover, storing two different pointer
types in driver data depending on driver initialization status is barely
a good practice and in fact has led to many bugs in this driver.

Let's clean up this mess and change Analogix entry points to simply
accept some opaque struct pointer, adjusting their users at the same
time to avoid breaking the compilation.

Signed-off-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
---

Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 +-
 drivers/gpu/drm/exynos/exynos_dp.c | 26 ++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 47 +++-
 include/drm/bridge/analogix_dp.h   | 19 
 4 files changed, 73 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5dd3f1cd074a..74d274b6d31d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,17 +98,15 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
 }
 
-int analogix_dp_psr_supported(struct device *dev)
+int analogix_dp_psr_supported(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
 
return dp->psr_support;
 }
 EXPORT_SYMBOL_GPL(analogix_dp_psr_supported);
 
-int analogix_dp_enable_psr(struct device *dev)
+int analogix_dp_enable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
 
if (!dp->psr_support)
@@ -129,9 +127,8 @@ int analogix_dp_enable_psr(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
 
-int analogix_dp_disable_psr(struct device *dev)
+int analogix_dp_disable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
int ret;
 
@@ -1281,8 +1278,9 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux 
*aux,
return analogix_dp_transfer(dp, msg);
 }
 
-int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
-struct analogix_dp_plat_data *plat_data)
+struct analogix_dp_device *
+analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
+struct analogix_dp_plat_data *plat_data)
 {
struct platform_device *pdev = to_platform_device(dev);
struct analogix_dp_device *dp;
@@ -1292,14 +1290,12 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
if (!plat_data) {
dev_err(dev, "Invalided input plat_data\n");
-   return -EINVAL;
+   return ERR_PTR(-EINVAL);
}
 
dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL);
if (!dp)
-   return -ENOMEM;
-
-   dev_set_drvdata(dev, dp);
+   return ERR_PTR(-ENOMEM);
 
dp->dev = >dev;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1316,7 +1312,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
ret = analogix_dp_dt_parse_pdata(dp);
if (ret)
-   return ret;
+   return ERR_PTR(ret);
 
dp->phy = devm_phy_get(dp->dev, "dp");
if (IS_ERR(dp->phy)) {
@@ -1330,14 +1326,14 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
if (ret == -ENOSYS || ret == -ENODEV)
dp->phy = NULL;
else
-   return ret;
+   return ERR_PTR(ret);
}
}
 
dp->clock = devm_clk_get(>dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(>dev, "failed to get clock\n");
-   return PTR_ERR(dp->clock);
+   return ERR_CAST(dp->clock);
}
 
clk_prepare_enable(dp->clock);
@@ -1346,7 +1342,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
dp->reg_base = devm_ioremap_resource(>dev, res);
if (IS_ERR(dp->reg_base))
-   return PTR_ERR(dp->reg_base);
+   return ERR_CAST(dp->reg_base);
 
dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
 
@@ -1367,7 +1363,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
  

[RFC PATCH v3 0/5] rockchip: kevin: Enable edp display

2017-10-17 Thread Jeffy Chen

Make edp display works on chromebook kevin(at least for boot animation).

Also solve some issues i meet during the bringup.

Changes in v3:
Assign orphan pwms to dummy pwmchip instead of adding device link in the
customer driver.

Changes in v2:
Use device link to correct the suspend/resume and shutdown ordering,
instead of converting rockchip spi's suspend/resume PM callbacks to
late suspend/resume PM callbacks.

Jeffy Chen (4):
  arm64: dts: rockchip: Enable edp disaplay on kevin
  drm/rockchip: Fix error handling path in rockchip_dp_bind()
  pwm: Add dummy pwmchip for orphan pwms
  drm/rockchip: Add device links for master and components

Tomasz Figa (1):
  drm/bridge/analogix: Do not use device's drvdata

 arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts  | 29 
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi   | 16 +
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 ++---
 drivers/gpu/drm/exynos/exynos_dp.c | 26 ---
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 57 +--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c| 24 ++-
 drivers/pwm/core.c | 84 --
 include/drm/bridge/analogix_dp.h   | 19 ++---
 8 files changed, 226 insertions(+), 79 deletions(-)

-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RESEND PATCH v2 5/5] drm/rockchip: Add device links for master and components

2017-10-16 Thread Jeffy Chen
Since we are trying to access components' resources in the master's
suspend/resume PM callbacks(e.g. panel), add device links to correct
the suspend/resume and shutdown ordering.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2:
Use device link to correct the suspend/resume and shutdown ordering,
instead of converting rockchip spi's suspend/resume PM callbacks to
late suspend/resume PM callbacks.

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 76d63de5921d..af18967f699b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -337,6 +337,8 @@ static struct component_match 
*rockchip_drm_match_add(struct device *dev)
 
if (!d)
break;
+
+   device_link_add(dev, d, DL_FLAG_STATELESS);
component_match_add(dev, , compare_dev, d);
} while (true);
}
@@ -406,6 +408,7 @@ static int rockchip_drm_platform_of_probe(struct device 
*dev)
 static int rockchip_drm_platform_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
+   struct device_link *link;
struct component_match *match = NULL;
int ret;
 
@@ -414,16 +417,31 @@ static int rockchip_drm_platform_probe(struct 
platform_device *pdev)
return ret;
 
match = rockchip_drm_match_add(dev);
-   if (IS_ERR(match))
-   return PTR_ERR(match);
+   if (IS_ERR(match)) {
+   ret = PTR_ERR(match);
+   goto err_cleanup_dev_links;
+   }
 
-   return component_master_add_with_match(dev, _drm_ops, match);
+   ret = component_master_add_with_match(dev, _drm_ops, match);
+   if (ret < 0)
+   goto err_cleanup_dev_links;
+
+   return 0;
+err_cleanup_dev_links:
+   list_for_each_entry(link, >links.consumers, s_node)
+   device_link_del(link);
+   return ret;
 }
 
 static int rockchip_drm_platform_remove(struct platform_device *pdev)
 {
+   struct device_link *link;
+
component_master_del(>dev, _drm_ops);
 
+   list_for_each_entry(link, >dev.links.consumers, s_node)
+   device_link_del(link);
+
return 0;
 }
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RESEND PATCH v2 2/5] backlight: pwm_bl: Add device link for pwm_bl and pwm

2017-10-16 Thread Jeffy Chen
When the pwm driver is unbound, the pwm_bl driver would still hold a
reference to that pwm, and crash the kernel later(if someone trying
to access that invalid pwm).

Add a device link to avoid this.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2: None

 drivers/video/backlight/pwm_bl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 9bd17682655a..a76f147a26e7 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -328,6 +328,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
goto err_alloc;
}
 
+   device_link_add(>dev, pb->pwm->chip->dev, DL_FLAG_AUTOREMOVE);
+
dev_dbg(>dev, "got pwm for backlight\n");
 
/*
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RESEND PATCH v2 3/5] drm/rockchip: Fix error handling path in rockchip_dp_bind()

2017-10-16 Thread Jeffy Chen
Add missing error handling in rockchip_dp_bind().

Fixes: 9e32e16e9e98 ("drm: rockchip: dp: add rockchip platform dp driver")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2: None

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 4d3f6ad0abdd..cb8941e8bcdd 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -371,7 +371,7 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
ret = rockchip_dp_drm_create_encoder(dp);
if (ret) {
DRM_ERROR("failed to create drm encoder\n");
-   return ret;
+   goto err_deinit_dp;
}
 
dp->plat_data.encoder = >encoder;
@@ -387,7 +387,17 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
 
rockchip_drm_psr_register(>encoder, analogix_dp_psr_set);
 
-   return analogix_dp_bind(dev, dp->drm_dev, >plat_data);
+   ret = analogix_dp_bind(dev, dp->drm_dev, >plat_data);
+   if (ret < 0)
+   goto err_unreg_psr;
+   return 0;
+
+err_unreg_psr:
+   rockchip_drm_psr_unregister(>encoder);
+   rockchip_dp_drm_encoder_destroy(>encoder);
+err_deinit_dp:
+   clk_disable_unprepare(dp->pclk);
+   return ret;
 }
 
 static void rockchip_dp_unbind(struct device *dev, struct device *master,
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RESEND PATCH v2 4/5] drm/bridge/analogix: Do not use device's drvdata

2017-10-16 Thread Jeffy Chen
From: Tomasz Figa <tf...@chromium.org>

The driver that instantiates the bridge should own the drvdata, as all
driver model callbacks (probe, remove, shutdown, PM ops, etc.) are also
owned by its driver struct. Moreover, storing two different pointer
types in driver data depending on driver initialization status is barely
a good practice and in fact has led to many bugs in this driver.

Let's clean up this mess and change Analogix entry points to simply
accept some opaque struct pointer, adjusting their users at the same
time to avoid breaking the compilation.

Signed-off-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 +-
 drivers/gpu/drm/exynos/exynos_dp.c | 26 ++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 47 +++-
 include/drm/bridge/analogix_dp.h   | 19 
 4 files changed, 73 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5dd3f1cd074a..74d274b6d31d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,17 +98,15 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
 }
 
-int analogix_dp_psr_supported(struct device *dev)
+int analogix_dp_psr_supported(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
 
return dp->psr_support;
 }
 EXPORT_SYMBOL_GPL(analogix_dp_psr_supported);
 
-int analogix_dp_enable_psr(struct device *dev)
+int analogix_dp_enable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
 
if (!dp->psr_support)
@@ -129,9 +127,8 @@ int analogix_dp_enable_psr(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
 
-int analogix_dp_disable_psr(struct device *dev)
+int analogix_dp_disable_psr(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
struct edp_vsc_psr psr_vsc;
int ret;
 
@@ -1281,8 +1278,9 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux 
*aux,
return analogix_dp_transfer(dp, msg);
 }
 
-int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
-struct analogix_dp_plat_data *plat_data)
+struct analogix_dp_device *
+analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
+struct analogix_dp_plat_data *plat_data)
 {
struct platform_device *pdev = to_platform_device(dev);
struct analogix_dp_device *dp;
@@ -1292,14 +1290,12 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
if (!plat_data) {
dev_err(dev, "Invalided input plat_data\n");
-   return -EINVAL;
+   return ERR_PTR(-EINVAL);
}
 
dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL);
if (!dp)
-   return -ENOMEM;
-
-   dev_set_drvdata(dev, dp);
+   return ERR_PTR(-ENOMEM);
 
dp->dev = >dev;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1316,7 +1312,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
ret = analogix_dp_dt_parse_pdata(dp);
if (ret)
-   return ret;
+   return ERR_PTR(ret);
 
dp->phy = devm_phy_get(dp->dev, "dp");
if (IS_ERR(dp->phy)) {
@@ -1330,14 +1326,14 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
if (ret == -ENOSYS || ret == -ENODEV)
dp->phy = NULL;
else
-   return ret;
+   return ERR_PTR(ret);
}
}
 
dp->clock = devm_clk_get(>dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(>dev, "failed to get clock\n");
-   return PTR_ERR(dp->clock);
+   return ERR_CAST(dp->clock);
}
 
clk_prepare_enable(dp->clock);
@@ -1346,7 +1342,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
 
dp->reg_base = devm_ioremap_resource(>dev, res);
if (IS_ERR(dp->reg_base))
-   return PTR_ERR(dp->reg_base);
+   return ERR_CAST(dp->reg_base);
 
dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
 
@@ -1367,7 +1363,7 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
"hpd_gpio");
if (ret) {
dev_err(>dev, &

[RESEND PATCH v2 0/5] rockchip: kevin: Enable edp display

2017-10-16 Thread Jeffy Chen

Make edp display works on chromebook kevin(at least for boot animation).

Also solve some issues i meet during the bringup.

Changes in v2:
Use device link to correct the suspend/resume and shutdown ordering,
instead of converting rockchip spi's suspend/resume PM callbacks to
late suspend/resume PM callbacks.

Jeffy Chen (4):
  arm64: dts: rockchip: Enable edp disaplay on kevin
  backlight: pwm_bl: Add device link for pwm_bl and pwm
  drm/rockchip: Fix error handling path in rockchip_dp_bind()
  drm/rockchip: Add device links for master and components

Tomasz Figa (1):
  drm/bridge/analogix: Do not use device's drvdata

 arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts  | 29 +++
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi   | 16 ++
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 ---
 drivers/gpu/drm/exynos/exynos_dp.c | 26 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 57 ++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c| 24 +++--
 drivers/video/backlight/pwm_bl.c   |  2 +
 include/drm/bridge/analogix_dp.h   | 19 +---
 8 files changed, 151 insertions(+), 72 deletions(-)

-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 0/5] rockchip: kevin: Enable edp display

2017-10-16 Thread Jeffy Chen

Make edp display works on chromebook kevin(at least for boot animation).

Also solve some issues i meet during the bringup.


Jeffy Chen (4):
  arm64: dts: rockchip: Enable edp disaplay on kevin
  backlight: pwm_bl: Add device link for pwm_bl and pwm
  drm/rockchip: Fix error handling path in rockchip_dp_bind()
  drm/rockchip: Add device links for master and components

Tomasz Figa (1):
  drm/bridge/analogix: Do not use device's drvdata

 arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts  | 29 +++
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi   | 16 ++
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 50 ---
 drivers/gpu/drm/exynos/exynos_dp.c | 26 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 57 ++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c| 24 +++--
 drivers/video/backlight/pwm_bl.c   |  2 +
 include/drm/bridge/analogix_dp.h   | 19 +---
 8 files changed, 151 insertions(+), 72 deletions(-)

-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm/atomic: Unref duplicated drm_atomic_state in drm_atomic_helper_resume()

2017-10-09 Thread Jeffy Chen
Kmemleak reported memory leak after suspend and resume:
unreferenced object 0xffc0e31d8880 (size 128):
  comm "bash", pid 181, jiffies 4294763583 (age 24.694s)
  hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 00 20 a2 eb c0 ff ff ff  . ..
01 00 00 00 00 00 00 00 80 87 1d e3 c0 ff ff ff  
  backtrace:
[] __save_stack_trace+0x48/0x6c
[] create_object+0x138/0x254
[] kmemleak_alloc+0x58/0x8c
[] kmem_cache_alloc_trace+0x188/0x254
[] drm_atomic_state_alloc+0x3c/0x88
[] drm_atomic_helper_duplicate_state+0x28/0x158
[] drm_atomic_helper_suspend+0x5c/0xf0

Problem here is that we are duplicating the drm_atomic_state in
drm_atomic_helper_suspend(), but not unreference it in the resume path.

Fixes: 1494276000db ("drm/atomic-helper: Implement subsystem-level 
suspend/resume")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2:
Unref duplicated drm_atomic_state in drm_atomic_helper_resume() instead
of specific drivers.

 drivers/gpu/drm/drm_atomic_helper.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 01c34bc5b5b0..4a262380c631 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3052,6 +3052,7 @@ int drm_atomic_helper_resume(struct drm_device *dev,
drm_modeset_backoff();
}
 
+   drm_atomic_state_put(state);
drm_modeset_drop_locks();
drm_modeset_acquire_fini();
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/rockchip: Fix memory leak in rockchip_drm_sys_resume()

2017-09-27 Thread Jeffy Chen
Free the drm_atomic_state allocated by drm_atomic_helper_suspend().

Fixes: 5a5873830972 ("drm/rockchip: Use atomic PM helpers")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 76d63de5921d..80235b672deb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -15,6 +15,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -299,6 +300,7 @@ static int rockchip_drm_sys_resume(struct device *dev)
 
priv = drm->dev_private;
drm_atomic_helper_resume(drm, priv->state);
+   drm_atomic_state_put(priv->state);
rockchip_drm_fb_resume(drm);
drm_kms_helper_poll_enable(drm);
 
-- 
2.11.0


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: Add missing field copy in compat_drm_version

2017-07-12 Thread Jeffy Chen
DRM_IOCTL_VERSION is supposed to update the name_len/date_len/desc_len
fields to user.

Fixes: 012c6741c6aa("switch compat_drm_version() to drm_ioctl_kernel()")
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>

---

 drivers/gpu/drm/drm_ioc32.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index 94acf51..2789356 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -112,6 +112,9 @@ static int compat_drm_version(struct file *file, unsigned 
int cmd,
v32.version_major = v.version_major;
v32.version_minor = v.version_minor;
v32.version_patchlevel = v.version_patchlevel;
+   v32.name_len = v.name_len;
+   v32.date_len = v.date_len;
+   v32.desc_len = v.desc_len;
if (copy_to_user((void __user *)arg, , sizeof(v32)))
return -EFAULT;
return 0;
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/rockchip: Don't allow zero sized gem buffer

2017-05-23 Thread Jeffy Chen
The system would crash when trying to alloc zero sized gem buffer:
[6.712435] Unable to handle kernel NULL pointer dereference at virtual 
address 0010 <--ZERO_SIZE_PTR
...
[6.757502] PC is at sg_alloc_table_from_pages+0x170/0x1ec

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index df9e570..8917922 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -315,6 +315,11 @@ struct rockchip_gem_object *
struct drm_gem_object *obj;
int ret;
 
+   if (!size) {
+   DRM_ERROR("gem buffer size is zero\n");
+   return ERR_PTR(-EINVAL);
+   }
+
size = round_up(size, PAGE_SIZE);
 
rk_obj = kzalloc(sizeof(*rk_obj), GFP_KERNEL);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/rockchip: analogix_dp: Remove unused check and variables

2017-04-29 Thread Jeffy Chen
Remove unused check and variables after:
drm/rockchip: Set line flag config register in vop_crtc_enable

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>

---

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 9bfdbc6..1bccd82 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -104,17 +104,9 @@ static void analogix_dp_psr_work(struct work_struct *work)
 {
struct rockchip_dp_device *dp =
container_of(work, typeof(*dp), psr_work);
-   struct drm_crtc *crtc = dp->encoder.crtc;
-   int psr_state = dp->psr_state;
-   int vact_end;
int ret;
unsigned long flags;
 
-   if (!crtc)
-   return;
-
-   vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + 
crtc->mode.vdisplay;
-
ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret) {
@@ -123,7 +115,7 @@ static void analogix_dp_psr_work(struct work_struct *work)
}
 
spin_lock_irqsave(>psr_lock, flags);
-   if (psr_state == EDP_VSC_PSR_STATE_ACTIVE)
+   if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE)
analogix_dp_enable_psr(dp->dev);
else
analogix_dp_disable_psr(dp->dev);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm/rockchip: Set line flag config register in vop_crtc_enable

2017-04-28 Thread Jeffy Chen
We need to set vop config done after update line flag config, it's a
new requirement for chips newer than rk3368.

Since we would only use line flag irq for vact_end, let's move it to
vop_crtc_enable.

v2: Remove unused check and variables.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>

---

Changes in v2:
Remove unused check and variables.

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 14 +++---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  3 +--
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 +---
 3 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index d8fa7a9..1bccd82 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -104,26 +104,18 @@ static void analogix_dp_psr_work(struct work_struct *work)
 {
struct rockchip_dp_device *dp =
container_of(work, typeof(*dp), psr_work);
-   struct drm_crtc *crtc = dp->encoder.crtc;
-   int psr_state = dp->psr_state;
-   int vact_end;
int ret;
unsigned long flags;
 
-   if (!crtc)
-   return;
-
-   vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + 
crtc->mode.vdisplay;
-
-   ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end,
- PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
+   ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
+PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret) {
dev_err(dp->dev, "line flag interrupt did not arrive\n");
return;
}
 
spin_lock_irqsave(>psr_lock, flags);
-   if (psr_state == EDP_VSC_PSR_STATE_ACTIVE)
+   if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE)
analogix_dp_enable_psr(dp->dev);
else
analogix_dp_disable_psr(dp->dev);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index a48fcce..47905fa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -62,8 +62,7 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
   struct device *dev);
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev);
-int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
-   unsigned int mstimeout);
+int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout);
 
 extern struct platform_driver cdn_dp_driver;
 extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 3f7a82d..40a5e6e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -468,7 +468,7 @@ static bool vop_line_flag_irq_is_enabled(struct vop *vop)
return !!line_flag_irq;
 }
 
-static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
+static void vop_line_flag_irq_enable(struct vop *vop)
 {
unsigned long flags;
 
@@ -477,7 +477,6 @@ static void vop_line_flag_irq_enable(struct vop *vop, int 
line_num)
 
spin_lock_irqsave(>irq_lock, flags);
 
-   VOP_CTRL_SET(vop, line_flag_num[0], line_num);
VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
 
@@ -981,6 +980,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
VOP_CTRL_SET(vop, vact_st_end, val);
VOP_CTRL_SET(vop, vpost_st_end, val);
 
+   VOP_CTRL_SET(vop, line_flag_num[0], vact_end);
+
clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
 
VOP_CTRL_SET(vop, standby, 0);
@@ -1507,19 +1508,16 @@ static void vop_win_init(struct vop *vop)
 }
 
 /**
- * rockchip_drm_wait_line_flag - acqiure the give line flag event
+ * rockchip_drm_wait_vact_end
  * @crtc: CRTC to enable line flag
- * @line_num: interested line number
  * @mstimeout: millisecond for timeout
  *
- * Driver would hold here until the interested line flag interrupt have
- * happened or timeout to wait.
+ * Wait for vact_end line flag irq or timeout.
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
-   unsigned int mstimeout)
+int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
 {
struct vop *vop = to_vop(crtc);
unsigned long jiffies_left;
@@ -1527,14 +1525,14 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, 
unsigned int line_num,
if (!crtc || !vop->is_enable

[PATCH] drm/rockchip: Set line flag config register in vop_crtc_enable

2017-04-27 Thread Jeffy Chen
We need to set vop config done after update line flag config, it's a
new requirement for chips newer than rk3368.

Since we would only use line flag irq for vact_end, let's move it to
vop_crtc_enable.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>

---

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  4 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  3 +--
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 +---
 3 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index d8fa7a9..9bfdbc6 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -115,8 +115,8 @@ static void analogix_dp_psr_work(struct work_struct *work)
 
vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + 
crtc->mode.vdisplay;
 
-   ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end,
- PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
+   ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
+PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret) {
dev_err(dp->dev, "line flag interrupt did not arrive\n");
return;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index a48fcce..47905fa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -62,8 +62,7 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
   struct device *dev);
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev);
-int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
-   unsigned int mstimeout);
+int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout);
 
 extern struct platform_driver cdn_dp_driver;
 extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 3f7a82d..40a5e6e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -468,7 +468,7 @@ static bool vop_line_flag_irq_is_enabled(struct vop *vop)
return !!line_flag_irq;
 }
 
-static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
+static void vop_line_flag_irq_enable(struct vop *vop)
 {
unsigned long flags;
 
@@ -477,7 +477,6 @@ static void vop_line_flag_irq_enable(struct vop *vop, int 
line_num)
 
spin_lock_irqsave(>irq_lock, flags);
 
-   VOP_CTRL_SET(vop, line_flag_num[0], line_num);
VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
 
@@ -981,6 +980,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
VOP_CTRL_SET(vop, vact_st_end, val);
VOP_CTRL_SET(vop, vpost_st_end, val);
 
+   VOP_CTRL_SET(vop, line_flag_num[0], vact_end);
+
clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
 
VOP_CTRL_SET(vop, standby, 0);
@@ -1507,19 +1508,16 @@ static void vop_win_init(struct vop *vop)
 }
 
 /**
- * rockchip_drm_wait_line_flag - acqiure the give line flag event
+ * rockchip_drm_wait_vact_end
  * @crtc: CRTC to enable line flag
- * @line_num: interested line number
  * @mstimeout: millisecond for timeout
  *
- * Driver would hold here until the interested line flag interrupt have
- * happened or timeout to wait.
+ * Wait for vact_end line flag irq or timeout.
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
-   unsigned int mstimeout)
+int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
 {
struct vop *vop = to_vop(crtc);
unsigned long jiffies_left;
@@ -1527,14 +1525,14 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, 
unsigned int line_num,
if (!crtc || !vop->is_enabled)
return -ENODEV;
 
-   if (line_num > crtc->mode.vtotal || mstimeout <= 0)
+   if (mstimeout <= 0)
return -EINVAL;
 
if (vop_line_flag_irq_is_enabled(vop))
return -EBUSY;
 
reinit_completion(>line_flag_completion);
-   vop_line_flag_irq_enable(vop, line_num);
+   vop_line_flag_irq_enable(vop);
 
jiffies_left = wait_for_completion_timeout(>line_flag_completion,
   msecs_to_jiffies(mstimeout));
@@ -1547,7 +1545,7 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, 
unsigned int line_num,
 
return 0;
 }
-EXPORT_SYMBOL(rockchip_drm_wait_line_flag);
+E

[PATCH v11] drm: Unplug drm device when unregistering it (v8)

2017-04-13 Thread Jeffy Chen
After unbinding drm, the user space may still owns the drm dev fd, and
may still be able to call drm ioctl.

We're using an unplugged state to prevent something like that, so let's
reuse it here.

Also drop drm_unplug_dev, because it would be unused after other changes.

Verified on rk3399 chromebook kevin(with cros 4.4 kernel), no more crashes
when unbinding drm with ui service still running.

v2: Fix some commit messages.
v3: Reuse unplug status.
v4: Add drm_device_set_plug_state helper.
v5: Fix hang when unregistering drm dev with open_count 0.
v6: Move drm_device_set_plug_state into drm_drv.
v7: Add missing drm_dev_unref in udl_drv.
v8: Fix compiler errors after enable udl.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>

---

 drivers/gpu/drm/drm_drv.c | 26 ++
 drivers/gpu/drm/udl/udl_drv.c |  3 ++-
 include/drm/drmP.h|  6 --
 include/drm/drm_drv.h |  1 -
 4 files changed, 12 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index b5c6bb4..e1da4d1 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -355,22 +355,6 @@ void drm_put_dev(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_put_dev);
 
-void drm_unplug_dev(struct drm_device *dev)
-{
-   /* for a USB device */
-   drm_dev_unregister(dev);
-
-   mutex_lock(_global_mutex);
-
-   drm_device_set_unplugged(dev);
-
-   if (dev->open_count == 0) {
-   drm_put_dev(dev);
-   }
-   mutex_unlock(_global_mutex);
-}
-EXPORT_SYMBOL(drm_unplug_dev);
-
 /*
  * DRM internal mount
  * We want to be able to allocate our own "struct address_space" to control
@@ -733,6 +717,13 @@ static void remove_compat_control_link(struct drm_device 
*dev)
kfree(name);
 }
 
+static inline void drm_device_set_plug_state(struct drm_device *dev,
+bool plugged)
+{
+   smp_wmb();
+   atomic_set(>unplugged, !plugged);
+}
+
 /**
  * drm_dev_register - Register DRM device
  * @dev: Device to register
@@ -787,6 +778,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_register_all(dev);
 
+   drm_device_set_plug_state(dev, true);
+
ret = 0;
 
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
@@ -826,6 +819,7 @@ void drm_dev_unregister(struct drm_device *dev)
drm_lastclose(dev);
 
dev->registered = false;
+   drm_device_set_plug_state(dev, false);
 
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_unregister_all(dev);
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index cd8b017..fc73e24 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -108,7 +108,8 @@ static void udl_usb_disconnect(struct usb_interface 
*interface)
drm_kms_helper_poll_disable(dev);
udl_fbdev_unplug(dev);
udl_drop_usb(dev);
-   drm_unplug_dev(dev);
+   drm_dev_unregister(dev);
+   drm_dev_unref(dev);
 }
 
 /*
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 3bfafcd..980a204 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -488,12 +488,6 @@ static __inline__ int drm_core_check_feature(struct 
drm_device *dev,
return ((dev->driver->driver_features & feature) ? 1 : 0);
 }
 
-static inline void drm_device_set_unplugged(struct drm_device *dev)
-{
-   smp_wmb();
-   atomic_set(>unplugged, 1);
-}
-
 static inline int drm_device_is_unplugged(struct drm_device *dev)
 {
int ret = atomic_read(>unplugged);
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 0fefc3f..eb63078 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -544,7 +544,6 @@ void drm_dev_unregister(struct drm_device *dev);
 void drm_dev_ref(struct drm_device *dev);
 void drm_dev_unref(struct drm_device *dev);
 void drm_put_dev(struct drm_device *dev);
-void drm_unplug_dev(struct drm_device *dev);
 
 int drm_dev_set_unique(struct drm_device *dev, const char *name);
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v9] drm: Unplug drm device when unregistering it

2017-04-12 Thread Jeffy Chen
After unbinding drm, the user space may still owns the drm dev fd, and
may still be able to call drm ioctl.

We're using an unplugged state to prevent something like that, so let's
reuse it here.

Also drop drm_unplug_dev, because it would be unused after other changes.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>

Changes in v9:
Move drm_device_set_plug_state into drm_drv.c .

Changes in v8:
Fix hang when unregistering drm dev with open_count 0.

Changes in v7:
Add drm_device_set_plug_state helper.

Changes in v6:
Reuse unplug status.

Changes in v5:
Fix wrong git account.

Changes in v2:
Fix some commit messages.

---
 drivers/gpu/drm/drm_drv.c | 26 ++
 drivers/gpu/drm/udl/udl_drv.c |  2 +-
 include/drm/drmP.h|  6 --
 include/drm/drm_drv.h |  1 -
 4 files changed, 11 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index b5c6bb4..e1da4d1 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -355,22 +355,6 @@ void drm_put_dev(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_put_dev);
 
-void drm_unplug_dev(struct drm_device *dev)
-{
-   /* for a USB device */
-   drm_dev_unregister(dev);
-
-   mutex_lock(_global_mutex);
-
-   drm_device_set_unplugged(dev);
-
-   if (dev->open_count == 0) {
-   drm_put_dev(dev);
-   }
-   mutex_unlock(_global_mutex);
-}
-EXPORT_SYMBOL(drm_unplug_dev);
-
 /*
  * DRM internal mount
  * We want to be able to allocate our own "struct address_space" to control
@@ -733,6 +717,13 @@ static void remove_compat_control_link(struct drm_device 
*dev)
kfree(name);
 }
 
+static inline void drm_device_set_plug_state(struct drm_device *dev,
+bool plugged)
+{
+   smp_wmb();
+   atomic_set(>unplugged, !plugged);
+}
+
 /**
  * drm_dev_register - Register DRM device
  * @dev: Device to register
@@ -787,6 +778,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_register_all(dev);
 
+   drm_device_set_plug_state(dev, true);
+
ret = 0;
 
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
@@ -826,6 +819,7 @@ void drm_dev_unregister(struct drm_device *dev)
drm_lastclose(dev);
 
dev->registered = false;
+   drm_device_set_plug_state(dev, false);
 
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_unregister_all(dev);
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index cd8b017..5dbd916 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -108,7 +108,7 @@ static void udl_usb_disconnect(struct usb_interface 
*interface)
drm_kms_helper_poll_disable(dev);
udl_fbdev_unplug(dev);
udl_drop_usb(dev);
-   drm_unplug_dev(dev);
+   drm_dev_unregister(dev);
 }
 
 /*
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 3bfafcd..980a204 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -488,12 +488,6 @@ static __inline__ int drm_core_check_feature(struct 
drm_device *dev,
return ((dev->driver->driver_features & feature) ? 1 : 0);
 }
 
-static inline void drm_device_set_unplugged(struct drm_device *dev)
-{
-   smp_wmb();
-   atomic_set(>unplugged, 1);
-}
-
 static inline int drm_device_is_unplugged(struct drm_device *dev)
 {
int ret = atomic_read(>unplugged);
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 0fefc3f..eb63078 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -544,7 +544,6 @@ void drm_dev_unregister(struct drm_device *dev);
 void drm_dev_ref(struct drm_device *dev);
 void drm_dev_unref(struct drm_device *dev);
 void drm_put_dev(struct drm_device *dev);
-void drm_unplug_dev(struct drm_device *dev);
 
 int drm_dev_set_unique(struct drm_device *dev, const char *name);
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v8 1/2] drm: Unplug drm device when unregistering it

2017-04-12 Thread Jeffy Chen
After unbinding drm, the user space may still owns the drm dev fd, and
may still be able to call drm ioctl.

We're using an unplugged state to prevent something like that, so let's
reuse it here.

Also drop drm_unplug_dev, because it would be unused after other changes.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Sean Paul <seanp...@chromium.org>

---

Changes in v8:
Fix hang when unregistering drm dev with open_count 0

Changes in v7:
Address Sean Paul <seanp...@chromium.org>'s comments.

Changes in v6:
Address Daniel Vetter <dan...@ffwll.ch>'s comments.

Changes in v5:
Fix wrong git account.

Changes in v2:
Fix some commit messages.

 drivers/gpu/drm/drm_drv.c | 19 +++
 drivers/gpu/drm/udl/udl_drv.c |  2 +-
 include/drm/drmP.h|  5 +++--
 include/drm/drm_drv.h |  1 -
 4 files changed, 7 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index b5c6bb4..cc2d018 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -355,22 +355,6 @@ void drm_put_dev(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_put_dev);
 
-void drm_unplug_dev(struct drm_device *dev)
-{
-   /* for a USB device */
-   drm_dev_unregister(dev);
-
-   mutex_lock(_global_mutex);
-
-   drm_device_set_unplugged(dev);
-
-   if (dev->open_count == 0) {
-   drm_put_dev(dev);
-   }
-   mutex_unlock(_global_mutex);
-}
-EXPORT_SYMBOL(drm_unplug_dev);
-
 /*
  * DRM internal mount
  * We want to be able to allocate our own "struct address_space" to control
@@ -787,6 +771,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_register_all(dev);
 
+   drm_device_set_plug_state(dev, true);
+
ret = 0;
 
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
@@ -826,6 +812,7 @@ void drm_dev_unregister(struct drm_device *dev)
drm_lastclose(dev);
 
dev->registered = false;
+   drm_device_set_plug_state(dev, false);
 
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_unregister_all(dev);
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index cd8b017..5dbd916 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -108,7 +108,7 @@ static void udl_usb_disconnect(struct usb_interface 
*interface)
drm_kms_helper_poll_disable(dev);
udl_fbdev_unplug(dev);
udl_drop_usb(dev);
-   drm_unplug_dev(dev);
+   drm_dev_unregister(dev);
 }
 
 /*
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 3bfafcd..a9a5a64 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -488,10 +488,11 @@ static __inline__ int drm_core_check_feature(struct 
drm_device *dev,
return ((dev->driver->driver_features & feature) ? 1 : 0);
 }
 
-static inline void drm_device_set_unplugged(struct drm_device *dev)
+static inline void drm_device_set_plug_state(struct drm_device *dev,
+bool plugged)
 {
smp_wmb();
-   atomic_set(>unplugged, 1);
+   atomic_set(>unplugged, !plugged);
 }
 
 static inline int drm_device_is_unplugged(struct drm_device *dev)
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 0fefc3f..eb63078 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -544,7 +544,6 @@ void drm_dev_unregister(struct drm_device *dev);
 void drm_dev_ref(struct drm_device *dev);
 void drm_dev_unref(struct drm_device *dev);
 void drm_put_dev(struct drm_device *dev);
-void drm_unplug_dev(struct drm_device *dev);
 
 int drm_dev_set_unique(struct drm_device *dev, const char *name);
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v8 0/2] drm: rockchip: Fix rockchip drm unbind crash error

2017-04-12 Thread Jeffy Chen

Verified on rk3399 chromebook kevin(with cros 4.4 kernel), no more crashes 
during unbind/bind drm with/out ui service running.

Changes in v8:
Fix hang when unregistering drm dev with open_count 0

Changes in v7:
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.

Changes in v6:
Address Daniel Vetter <dan...@ffwll.ch>'s comments.

Changes in v5:
Fix wrong git account.

Changes in v2:
Fix some commit messages.

Jeffy Chen (2):
  drm: Unplug drm device when unregistering it
  drm: Prevent release fb after cleanup drm_mode_config

 drivers/gpu/drm/drm_drv.c | 19 +++
 drivers/gpu/drm/drm_framebuffer.c |  5 +
 drivers/gpu/drm/udl/udl_drv.c |  2 +-
 include/drm/drmP.h|  5 +++--
 include/drm/drm_drv.h |  1 -
 5 files changed, 12 insertions(+), 20 deletions(-)

-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v9 0/1] drm: rockchip: Fix rockchip drm unbind crash error

2017-04-12 Thread Jeffy Chen

Verified on rk3399 chromebook kevin(with cros 4.4 kernel), no more crashes 
during unbind/bind drm with/out ui service running.

Changes in v9:
Move drm_device_set_plug_state into drm_drv.c .

Changes in v8:
Fix hang when unregistering drm dev with open_count 0.

Changes in v7:
Add drm_device_set_plug_state helper.

Changes in v6:
Reuse unplug status.

Changes in v5:
Fix wrong git account.

Changes in v2:
Fix some commit messages.

Jeffy Chen (1):
  drm: Unplug drm device when unregistering it

 drivers/gpu/drm/drm_drv.c | 26 ++
 drivers/gpu/drm/udl/udl_drv.c |  2 +-
 include/drm/drmP.h|  6 --
 include/drm/drm_drv.h |  1 -
 4 files changed, 11 insertions(+), 24 deletions(-)

-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v8 2/2] drm: Prevent release fb after cleanup drm_mode_config

2017-04-12 Thread Jeffy Chen
We are freeing all framebuffers in drm_mode_config_cleanup without
sync the drm_file's fbs list.

So if someone try to unbind drm before release drm dev fd, the fbs
list would remain some invalid fb references. And that would cause
crash later in drm_fb_release.

Add a sanity check to prevent that.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>

---

Changes in v8: None
Changes in v7:
Update commit message.

Changes in v6: None
Changes in v5: None
Changes in v2: None

 drivers/gpu/drm/drm_framebuffer.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_framebuffer.c 
b/drivers/gpu/drm/drm_framebuffer.c
index e8f9c13..03c1632 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -583,6 +583,11 @@ void drm_fb_release(struct drm_file *priv)
 {
struct drm_framebuffer *fb, *tfb;
struct drm_mode_rmfb_work arg;
+   struct drm_minor *minor = priv->minor;
+   struct drm_device *dev = minor->dev;
+
+   if (WARN_ON(!dev->mode_config.num_fb && !list_empty(>fbs)))
+   return;
 
INIT_LIST_HEAD();
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v7 1/2] drm: Unplug drm device when unregistering it

2017-04-11 Thread Jeffy Chen
After unbinding drm, the user space may still owns the drm dev fd,
and may still be able to call drm ioctl.

We're using an unplugged state to prevent something like that, so
let's reuse it here.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Sean Paul <seanp...@chromium.org>

---

Changes in v7:
Address Sean Paul <seanp...@chromium.org>'s comments.

Changes in v6:
Address Daniel Vetter <dan...@ffwll.ch>'s comments.

Changes in v5:
Fix wrong git account.

Changes in v2:
Fix some commit messages.

 drivers/gpu/drm/drm_drv.c | 8 
 drivers/gpu/drm/udl/udl_drv.c | 2 +-
 include/drm/drmP.h| 5 +++--
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index b5c6bb4..ad13e20 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -357,12 +357,9 @@ EXPORT_SYMBOL(drm_put_dev);
 
 void drm_unplug_dev(struct drm_device *dev)
 {
-   /* for a USB device */
-   drm_dev_unregister(dev);
-
mutex_lock(_global_mutex);
 
-   drm_device_set_unplugged(dev);
+   drm_device_set_plug_state(dev, false);
 
if (dev->open_count == 0) {
drm_put_dev(dev);
@@ -787,6 +784,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_register_all(dev);
 
+   drm_device_set_plug_state(dev, true);
+
ret = 0;
 
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
@@ -826,6 +825,7 @@ void drm_dev_unregister(struct drm_device *dev)
drm_lastclose(dev);
 
dev->registered = false;
+   drm_unplug_dev(dev);
 
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_unregister_all(dev);
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index cd8b017..5dbd916 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -108,7 +108,7 @@ static void udl_usb_disconnect(struct usb_interface 
*interface)
drm_kms_helper_poll_disable(dev);
udl_fbdev_unplug(dev);
udl_drop_usb(dev);
-   drm_unplug_dev(dev);
+   drm_dev_unregister(dev);
 }
 
 /*
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 3bfafcd..a9a5a64 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -488,10 +488,11 @@ static __inline__ int drm_core_check_feature(struct 
drm_device *dev,
return ((dev->driver->driver_features & feature) ? 1 : 0);
 }
 
-static inline void drm_device_set_unplugged(struct drm_device *dev)
+static inline void drm_device_set_plug_state(struct drm_device *dev,
+bool plugged)
 {
smp_wmb();
-   atomic_set(>unplugged, 1);
+   atomic_set(>unplugged, !plugged);
 }
 
 static inline int drm_device_is_unplugged(struct drm_device *dev)
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: Fixup hang when unregistering drm dev with open_count 0

2017-04-11 Thread Jeffy Chen
My previous patch (c5d8fac2bf  drm: Unplug drm device when unregistering
it) calls drm_unplug_dev when unregistering drm dev. But if open_count
is 0, the unplug will try to unregister the drm dev again and cause
deadlock.

Fix it by dropping drm_unplug_dev and use drm_device_set_plug_state
directly.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>

---

 drivers/gpu/drm/drm_drv.c | 15 +--
 include/drm/drm_drv.h |  1 -
 2 files changed, 1 insertion(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index ad13e20..cc2d018 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -355,19 +355,6 @@ void drm_put_dev(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_put_dev);
 
-void drm_unplug_dev(struct drm_device *dev)
-{
-   mutex_lock(_global_mutex);
-
-   drm_device_set_plug_state(dev, false);
-
-   if (dev->open_count == 0) {
-   drm_put_dev(dev);
-   }
-   mutex_unlock(_global_mutex);
-}
-EXPORT_SYMBOL(drm_unplug_dev);
-
 /*
  * DRM internal mount
  * We want to be able to allocate our own "struct address_space" to control
@@ -825,7 +812,7 @@ void drm_dev_unregister(struct drm_device *dev)
drm_lastclose(dev);
 
dev->registered = false;
-   drm_unplug_dev(dev);
+   drm_device_set_plug_state(dev, false);
 
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_unregister_all(dev);
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 0fefc3f..eb63078 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -544,7 +544,6 @@ void drm_dev_unregister(struct drm_device *dev);
 void drm_dev_ref(struct drm_device *dev);
 void drm_dev_unref(struct drm_device *dev);
 void drm_put_dev(struct drm_device *dev);
-void drm_unplug_dev(struct drm_device *dev);
 
 int drm_dev_set_unique(struct drm_device *dev, const char *name);
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v7 0/2] drm: rockchip: Fix rockchip drm unbind crash error

2017-04-11 Thread Jeffy Chen

Verified on rk3399 chromebook kevin(with cros 4.4 kernel), no more crashes 
during unbind/bind drm.

Changes in v7:
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.

Changes in v6:
Address Daniel Vetter <dan...@ffwll.ch>'s comments.

Changes in v5:
Fix wrong git account.

Changes in v2:
Fix some commit messages.

Jeffy Chen (2):
  drm: Unplug drm device when unregistering it
  drm: Prevent release fb after cleanup drm_mode_config

 drivers/gpu/drm/drm_drv.c | 8 
 drivers/gpu/drm/drm_framebuffer.c | 5 +
 drivers/gpu/drm/udl/udl_drv.c | 2 +-
 include/drm/drmP.h| 5 +++--
 4 files changed, 13 insertions(+), 7 deletions(-)

-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v7 2/2] drm: Prevent release fb after cleanup drm_mode_config

2017-04-11 Thread Jeffy Chen
We are freeing all framebuffers in drm_mode_config_cleanup without
sync the drm_file's fbs list.

So if someone try to unbind drm before release drm dev fd, the fbs
list would remain some invalid fb references. And that would cause
crash later in drm_fb_release.

Add a sanity check to prevent that.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>

---

Changes in v7:
Update commit message.

Changes in v6: None
Changes in v5: None
Changes in v2: None

 drivers/gpu/drm/drm_framebuffer.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_framebuffer.c 
b/drivers/gpu/drm/drm_framebuffer.c
index e8f9c13..03c1632 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -583,6 +583,11 @@ void drm_fb_release(struct drm_file *priv)
 {
struct drm_framebuffer *fb, *tfb;
struct drm_mode_rmfb_work arg;
+   struct drm_minor *minor = priv->minor;
+   struct drm_device *dev = minor->dev;
+
+   if (WARN_ON(!dev->mode_config.num_fb && !list_empty(>fbs)))
+   return;
 
INIT_LIST_HEAD();
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 2/2] drm: Prevent release fb after cleanup mode config

2017-04-10 Thread Jeffy Chen
After unbinding drm, the user space may still owns the drm dev fd,
and may trigger fb release after cleanup mode config.

Add a sanity check to prevent that.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v6: None
Changes in v5: None
Changes in v2: None

 drivers/gpu/drm/drm_framebuffer.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_framebuffer.c 
b/drivers/gpu/drm/drm_framebuffer.c
index e8f9c13..03c1632 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -583,6 +583,11 @@ void drm_fb_release(struct drm_file *priv)
 {
struct drm_framebuffer *fb, *tfb;
struct drm_mode_rmfb_work arg;
+   struct drm_minor *minor = priv->minor;
+   struct drm_device *dev = minor->dev;
+
+   if (WARN_ON(!dev->mode_config.num_fb && !list_empty(>fbs)))
+   return;
 
INIT_LIST_HEAD();
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 0/2] drm: rockchip: Fix rockchip drm unbind crash error

2017-04-10 Thread Jeffy Chen

Verified on rk3399 chromebook kevin, no more crashes during unbind/bind drm.

Changes in v6:
Address Daniel Vetter <dan...@ffwll.ch>'s comments.

Changes in v5:
Fix wrong git account.

Changes in v2:
Fix some commit messages.

Jeffy Chen (2):
  drm: Unplug drm device when unregistering it
  drm: Prevent release fb after cleanup mode config

 drivers/gpu/drm/drm_drv.c | 6 +++---
 drivers/gpu/drm/drm_framebuffer.c | 5 +
 drivers/gpu/drm/udl/udl_drv.c | 2 +-
 include/drm/drmP.h| 6 ++
 4 files changed, 15 insertions(+), 4 deletions(-)

-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 1/2] drm: Unplug drm device when unregistering it

2017-04-10 Thread Jeffy Chen
After unbinding drm, the user space may still owns the drm dev fd,
and may still be able to call drm ioctl.

We're using an unplugged state to prevent something like that, so
let's reuse it here.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v6:
Address Daniel Vetter <dan...@ffwll.ch>'s comments.

Changes in v5:
Fix wrong git account.

Changes in v2:
Fix some commit messages.

 drivers/gpu/drm/drm_drv.c | 6 +++---
 drivers/gpu/drm/udl/udl_drv.c | 2 +-
 include/drm/drmP.h| 6 ++
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index b5c6bb4..f38de26 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -357,9 +357,6 @@ EXPORT_SYMBOL(drm_put_dev);
 
 void drm_unplug_dev(struct drm_device *dev)
 {
-   /* for a USB device */
-   drm_dev_unregister(dev);
-
mutex_lock(_global_mutex);
 
drm_device_set_unplugged(dev);
@@ -787,6 +784,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_register_all(dev);
 
+   drm_device_set_plugged(dev);
+
ret = 0;
 
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
@@ -826,6 +825,7 @@ void drm_dev_unregister(struct drm_device *dev)
drm_lastclose(dev);
 
dev->registered = false;
+   drm_unplug_dev(dev);
 
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_unregister_all(dev);
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index cd8b017..5dbd916 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -108,7 +108,7 @@ static void udl_usb_disconnect(struct usb_interface 
*interface)
drm_kms_helper_poll_disable(dev);
udl_fbdev_unplug(dev);
udl_drop_usb(dev);
-   drm_unplug_dev(dev);
+   drm_dev_unregister(dev);
 }
 
 /*
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 3bfafcd..c930a77 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -488,6 +488,12 @@ static __inline__ int drm_core_check_feature(struct 
drm_device *dev,
return ((dev->driver->driver_features & feature) ? 1 : 0);
 }
 
+static inline void drm_device_set_plugged(struct drm_device *dev)
+{
+   smp_wmb();
+   atomic_set(>unplugged, 0);
+}
+
 static inline void drm_device_set_unplugged(struct drm_device *dev)
 {
smp_wmb();
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 10/12] drm/rockchip: Reoder drm bind/unbind sequence

2017-04-06 Thread Jeffy Chen
Current drm bind/unbind sequence would cause some memory issues.
For example we should not cleanup iommu before cleanup mode config.

Reorder bind/unbind sequence, follow exynos drm.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3:
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 49 +++--
 1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index cd7d02e1..f24968f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -136,21 +136,24 @@ static int rockchip_drm_bind(struct device *dev)
INIT_LIST_HEAD(>psr_list);
spin_lock_init(>psr_list_lock);
 
+   ret = rockchip_drm_init_iommu(drm_dev);
+   if (ret)
+   goto err_free;
+
drm_mode_config_init(drm_dev);
 
rockchip_drm_mode_config_init(drm_dev);
 
-   ret = rockchip_drm_init_iommu(drm_dev);
-   if (ret)
-   goto err_config_cleanup;
-
/* Try to bind all sub drivers. */
ret = component_bind_all(dev, drm_dev);
if (ret)
-   goto err_iommu_cleanup;
+   goto err_mode_config_cleanup;
 
-   /* init kms poll for handling hpd */
-   drm_kms_helper_poll_init(drm_dev);
+   ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
+   if (ret)
+   goto err_unbind_all;
+
+   drm_mode_config_reset(drm_dev);
 
/*
 * enable drm irq mode.
@@ -158,15 +161,12 @@ static int rockchip_drm_bind(struct device *dev)
 */
drm_dev->irq_enabled = true;
 
-   ret = drm_vblank_init(drm_dev, ROCKCHIP_MAX_CRTC);
-   if (ret)
-   goto err_kms_helper_poll_fini;
-
-   drm_mode_config_reset(drm_dev);
+   /* init kms poll for handling hpd */
+   drm_kms_helper_poll_init(drm_dev);
 
ret = rockchip_drm_fbdev_init(drm_dev);
if (ret)
-   goto err_vblank_cleanup;
+   goto err_kms_helper_poll_fini;
 
ret = drm_dev_register(drm_dev, 0);
if (ret)
@@ -175,17 +175,17 @@ static int rockchip_drm_bind(struct device *dev)
return 0;
 err_fbdev_fini:
rockchip_drm_fbdev_fini(drm_dev);
-err_vblank_cleanup:
-   drm_vblank_cleanup(drm_dev);
 err_kms_helper_poll_fini:
drm_kms_helper_poll_fini(drm_dev);
+   drm_vblank_cleanup(drm_dev);
+err_unbind_all:
component_unbind_all(dev, drm_dev);
-err_iommu_cleanup:
-   rockchip_iommu_cleanup(drm_dev);
-err_config_cleanup:
+err_mode_config_cleanup:
drm_mode_config_cleanup(drm_dev);
-   drm_dev->dev_private = NULL;
+   rockchip_iommu_cleanup(drm_dev);
 err_free:
+   drm_dev->dev_private = NULL;
+   dev_set_drvdata(dev, NULL);
drm_dev_unref(drm_dev);
return ret;
 }
@@ -194,16 +194,19 @@ static void rockchip_drm_unbind(struct device *dev)
 {
struct drm_device *drm_dev = dev_get_drvdata(dev);
 
+   drm_dev_unregister(drm_dev);
+
rockchip_drm_fbdev_fini(drm_dev);
-   drm_vblank_cleanup(drm_dev);
drm_kms_helper_poll_fini(drm_dev);
+
+   drm_vblank_cleanup(drm_dev);
component_unbind_all(dev, drm_dev);
-   rockchip_iommu_cleanup(drm_dev);
drm_mode_config_cleanup(drm_dev);
+   rockchip_iommu_cleanup(drm_dev);
+
drm_dev->dev_private = NULL;
-   drm_dev_unregister(drm_dev);
-   drm_dev_unref(drm_dev);
dev_set_drvdata(dev, NULL);
+   drm_dev_unref(drm_dev);
 }
 
 static void rockchip_drm_lastclose(struct drm_device *dev)
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 01/12] drm: bridge: analogix: Detach panel when unbinding analogix dp

2017-04-06 Thread Jeffy Chen
The panel is attached when binding analogix dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
---

Changes in v5:
Fix wrong git account.

Changes in v4: None
Changes in v3: None
Changes in v2:
Fix some commit messages.

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index c26997a..28144a1 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1443,6 +1443,8 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
DRM_ERROR("failed to turnoff the panel\n");
+   if (drm_panel_detach(dp->plat_data->panel))
+   DRM_ERROR("failed to detach the panel\n");
}
 
pm_runtime_disable(dev);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 03/12] drm: bridge: analogix: Disable clock when unbinding

2017-04-06 Thread Jeffy Chen
The clock is enabled when binding analogix dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 7b75f82..d05ade4 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1449,6 +1449,7 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
 
drm_dp_aux_unregister(>aux);
pm_runtime_disable(dev);
+   clk_disable_unprepare(dp->clock);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_unbind);
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 08/12] drm/rockchip: vop: Unprepare clocks when unbinding

2017-04-06 Thread Jeffy Chen
The clocks are prepared when binding vop.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index b65b296..3f7a82d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1634,6 +1634,10 @@ static void vop_unbind(struct device *dev, struct device 
*master, void *data)
 
pm_runtime_disable(dev);
vop_destroy_crtc(vop);
+
+   clk_unprepare(vop->aclk);
+   clk_unprepare(vop->hclk);
+   clk_unprepare(vop->dclk);
 }
 
 const struct component_ops vop_component_ops = {
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 07/12] drm/rockchip: vop: Enable pm domain before vop_initial

2017-04-06 Thread Jeffy Chen
We're trying to access vop registers here, so need to make sure
the pm domain is on.

Normally it should be enabled by the bootloader, but there's no
guarantee of it. And if we wanna do unbind/bind, it would also
cause the device to hang.

And this patch also does these:
1/ move vop_initial to the end of vop_bind for eaiser error handling.
2/ correct the err_put_pm_runtime of vop_enable.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3:
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 2151e1c..b65b296 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -506,7 +506,7 @@ static int vop_enable(struct drm_crtc *crtc)
ret = pm_runtime_get_sync(vop->dev);
if (ret < 0) {
dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
-   goto err_put_pm_runtime;
+   return ret;
}
 
ret = clk_enable(vop->hclk);
@@ -1405,10 +1405,16 @@ static int vop_initial(struct vop *vop)
return PTR_ERR(vop->dclk);
}
 
+   ret = pm_runtime_get_sync(vop->dev);
+   if (ret < 0) {
+   dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
+   return ret;
+   }
+
ret = clk_prepare(vop->dclk);
if (ret < 0) {
dev_err(vop->dev, "failed to prepare dclk\n");
-   return ret;
+   goto err_put_pm_runtime;
}
 
/* Enable both the hclk and aclk to setup the vop */
@@ -1468,6 +1474,8 @@ static int vop_initial(struct vop *vop)
 
vop->is_enabled = false;
 
+   pm_runtime_put_sync(vop->dev);
+
return 0;
 
 err_disable_aclk:
@@ -1476,6 +1484,8 @@ static int vop_initial(struct vop *vop)
clk_disable_unprepare(vop->hclk);
 err_unprepare_dclk:
clk_unprepare(vop->dclk);
+err_put_pm_runtime:
+   pm_runtime_put_sync(vop->dev);
return ret;
 }
 
@@ -1576,12 +1586,6 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
if (!vop->regsbak)
return -ENOMEM;
 
-   ret = vop_initial(vop);
-   if (ret < 0) {
-   dev_err(>dev, "cannot initial vop dev - err %d\n", ret);
-   return ret;
-   }
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "cannot find irq for vop\n");
@@ -1608,8 +1612,17 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
 
pm_runtime_enable(>dev);
 
+   ret = vop_initial(vop);
+   if (ret < 0) {
+   dev_err(>dev, "cannot initial vop dev - err %d\n", ret);
+   goto err_disable_pm_runtime;
+   }
+
return 0;
 
+err_disable_pm_runtime:
+   pm_runtime_disable(>dev);
+   vop_destroy_crtc(vop);
 err_enable_irq:
enable_irq(vop->irq); /* To balance out the disable_irq above */
return ret;
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 06/12] drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding

2017-04-06 Thread Jeffy Chen
After snd_soc_unregister_codec, the dai link would remain bound to
the invalid codec. That would cause crashes after unbind dp driver.

Let's unregister audio codec when removing dp driver to prevent that.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3:
Update commit message.

Changes in v2: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index ee4195d..a2169dd 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1092,8 +1092,6 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
goto err_free_connector;
}
 
-   cdn_dp_audio_codec_init(dp, dev);
-
for (i = 0; i < dp->ports; i++) {
port = dp->port[i];
 
@@ -1128,7 +1126,6 @@ static void cdn_dp_unbind(struct device *dev, struct 
device *master, void *data)
struct drm_connector *connector = >connector;
 
cancel_work_sync(>event_work);
-   platform_device_unregister(dp->audio_pdev);
cdn_dp_encoder_disable(encoder);
encoder->funcs->destroy(encoder);
connector->funcs->destroy(connector);
@@ -1221,6 +1218,8 @@ static int cdn_dp_probe(struct platform_device *pdev)
mutex_init(>lock);
dev_set_drvdata(dev, dp);
 
+   cdn_dp_audio_codec_init(dp, dev);
+
return component_add(dev, _dp_component_ops);
 }
 
@@ -1228,6 +1227,7 @@ static int cdn_dp_remove(struct platform_device *pdev)
 {
struct cdn_dp_device *dp = platform_get_drvdata(pdev);
 
+   platform_device_unregister(dp->audio_pdev);
cdn_dp_suspend(dp->dev);
component_del(>dev, _dp_component_ops);
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 11/12] drm/rockchip: Shutdown all crtcs when unbinding drm

2017-04-06 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3:
Address Daniel Vetter <dan...@ffwll.ch>'s comments.
Update commit message.

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index f24968f..c6b1b7f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -199,6 +199,7 @@ static void rockchip_drm_unbind(struct device *dev)
rockchip_drm_fbdev_fini(drm_dev);
drm_kms_helper_poll_fini(drm_dev);
 
+   drm_atomic_helper_shutdown(drm_dev);
drm_vblank_cleanup(drm_dev);
component_unbind_all(dev, drm_dev);
drm_mode_config_cleanup(drm_dev);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 09/12] drm/rockchip: analogix_dp: Disable clock when unbinding

2017-04-06 Thread Jeffy Chen
The clock is enabled when binding cdn dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 91ebe5c..c3b9f1d 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -417,7 +417,8 @@ static void rockchip_dp_unbind(struct device *dev, struct 
device *master,
 
rockchip_drm_psr_unregister(>encoder);
 
-   return analogix_dp_unbind(dev, master, data);
+   analogix_dp_unbind(dev, master, data);
+   clk_disable_unprepare(dp->pclk);
 }
 
 static const struct component_ops rockchip_dp_component_ops = {
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 00/12] drm: rockchip: Fix rockchip drm unbind crash error

2017-04-06 Thread Jeffy Chen

Verified on rk3399 chromebook kevin:
1/ stop ui && pkill -9 frecon
2/ unbind/bind drm

Changes in v5:
Fix wrong git account.

Changes in v4:
Address Andrzej Hajda <a.ha...@samsung.com>'s comments.

Changes in v3:
Update commit message.
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.
Address Daniel Vetter <dan...@ffwll.ch>'s comments.
Update commit message.

Changes in v2:
Fix some commit messages.

Jeffy Chen (12):
  drm: bridge: analogix: Detach panel when unbinding analogix dp
  drm: bridge: analogix: Unregister dp aux when unbinding
  drm: bridge: analogix: Disable clock when unbinding
  drm: bridge: analogix: Destroy connector & encoder when unbinding
  drm/rockchip: cdn-dp: Don't try to release firmware when not loaded
  drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding
  drm/rockchip: vop: Enable pm domain before vop_initial
  drm/rockchip: vop: Unprepare clocks when unbinding
  drm/rockchip: analogix_dp: Disable clock when unbinding
  drm/rockchip: Reoder drm bind/unbind sequence
  drm/rockchip: Shutdown all crtcs when unbinding drm
  drm/drm_ioctl.c: Break ioctl when drm device not registered

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  6 +++
 drivers/gpu/drm/drm_ioctl.c|  2 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  3 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 10 +++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c| 50 --
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c| 33 ++
 6 files changed, 67 insertions(+), 37 deletions(-)

-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 04/12] drm: bridge: analogix: Destroy connector & encoder when unbinding

2017-04-06 Thread Jeffy Chen
Normally we do this in drm_mode_config_cleanup. But:
1/ analogix dp's connector is allocated in bind, and freed after unbind.
So we need to destroy it in unbind to avoid further access.
2/ the drm bridge is attached in bind, and detached in encoder cleanup.
So we need to destroy encoder in unbind.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4:
Address Andrzej Hajda <a.ha...@samsung.com>'s comments.

Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index d05ade4..4c758ed 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1439,6 +1439,8 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
struct analogix_dp_device *dp = dev_get_drvdata(dev);
 
analogix_dp_bridge_disable(dp->bridge);
+   dp->connector.funcs->destroy(>connector);
+   dp->encoder->funcs->destroy(dp->encoder);
 
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 12/12] drm/drm_ioctl.c: Break ioctl when drm device not registered

2017-04-06 Thread Jeffy Chen
After unbinding drm, the user space may still owns the drm dev fd,
and may still be able to call drm ioctl.

Add a sanity check here to prevent that from happening.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/drm_ioctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 7d6deaa..15beb11 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -674,7 +674,7 @@ long drm_ioctl(struct file *filp,
 
dev = file_priv->minor->dev;
 
-   if (drm_device_is_unplugged(dev))
+   if (drm_device_is_unplugged(dev) || !dev->registered)
return -ENODEV;
 
is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END;
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 02/12] drm: bridge: analogix: Unregister dp aux when unbinding

2017-04-06 Thread Jeffy Chen
The dp aux is registered when binding analogix dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 28144a1..7b75f82 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1447,6 +1447,7 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
DRM_ERROR("failed to detach the panel\n");
}
 
+   drm_dp_aux_unregister(>aux);
pm_runtime_disable(dev);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_unbind);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 05/12] drm/rockchip: cdn-dp: Don't try to release firmware when not loaded

2017-04-06 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 4e55d63..ee4195d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1053,6 +1053,7 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
dp->connected = false;
dp->active = false;
dp->active_port = -1;
+   dp->fw_loaded = false;
 
INIT_WORK(>event_work, cdn_dp_pd_event_work);
 
@@ -1133,7 +1134,8 @@ static void cdn_dp_unbind(struct device *dev, struct 
device *master, void *data)
connector->funcs->destroy(connector);
 
pm_runtime_disable(dev);
-   release_firmware(dp->fw);
+   if (dp->fw_loaded)
+   release_firmware(dp->fw);
kfree(dp->edid);
dp->edid = NULL;
 }
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 0/9] drm: rockchip: Fix rockchip drm unbind crash error

2017-04-05 Thread Jeffy Chen

Verified on rk3399 chromebook kevin:
1/ stop ui && pkill -9 frecon
2/ unbind/bind drm

Changes in v3:
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.
Address Daniel Vetter <dan...@ffwll.ch>'s comments.
Update commit message.
Address Daniel Vetter <dan...@ffwll.ch>'s comments.
Update commit message.
Update commit message.

Changes in v2:
Fix some commit messages.

Jeffy Chen (9):
  drm: bridge: analogix: Detach panel when unbinding analogix dp
  drm: bridge: analogix: Unregister dp aux when unbinding
  drm: bridge: analogix: Destroy connector when unbinding
  drm/rockchip: cdn-dp: Don't try to release firmware when not loaded
  drm/rockchip: vop: Enable pm domain before vop_initial
  drm/rockchip: Reoder drm bind/unbind sequence
  drm/rockchip: Shutdown all crtcs when unbinding drm
  drm/rockchip: gem: Don't alloc/free gem buf when dev_private is
invalid
  drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  4 ++
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 10 +++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c| 50 --
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c|  8 
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c| 29 +
 5 files changed, 66 insertions(+), 35 deletions(-)

-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 2/9] drm: bridge: analogix: Unregister dp aux when unbinding

2017-04-05 Thread Jeffy Chen
The dp aux is registered when binding analogix dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 28144a1..7b75f82 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1447,6 +1447,7 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
DRM_ERROR("failed to detach the panel\n");
}
 
+   drm_dp_aux_unregister(>aux);
pm_runtime_disable(dev);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_unbind);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 8/9] drm/rockchip: gem: Don't alloc/free gem buf when dev_private is invalid

2017-04-05 Thread Jeffy Chen
After unbinding drm, the userspace may still has a chance to access
gem buf.

Add a sanity check for a NULL dev_private to prevent that from
happening.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3:
Address Daniel Vetter <dan...@ffwll.ch>'s comments.
Update commit message.

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index df9e570..205a3dc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -184,6 +184,9 @@ static int rockchip_gem_alloc_buf(struct 
rockchip_gem_object *rk_obj,
struct drm_device *drm = obj->dev;
struct rockchip_drm_private *private = drm->dev_private;
 
+   if (!private)
+   return -ENODEV;
+
if (private->domain)
return rockchip_gem_alloc_iommu(rk_obj, alloc_kmap);
else
@@ -208,6 +211,11 @@ static void rockchip_gem_free_dma(struct 
rockchip_gem_object *rk_obj)
 
 static void rockchip_gem_free_buf(struct rockchip_gem_object *rk_obj)
 {
+   struct drm_device *drm = rk_obj->base.dev;
+
+   if (!drm->dev_private)
+   return;
+
if (rk_obj->pages)
rockchip_gem_free_iommu(rk_obj);
else
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 9/9] drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding

2017-04-05 Thread Jeffy Chen
After snd_soc_unregister_codec, the dai link would remain bound to
the invalid codec. That would cause crashes after unbind dp driver.

Let's unregister audio codec when removing dp driver to prevent that.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3:
Update commit message.

Changes in v2: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index ee4195d..a2169dd 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1092,8 +1092,6 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
goto err_free_connector;
}
 
-   cdn_dp_audio_codec_init(dp, dev);
-
for (i = 0; i < dp->ports; i++) {
port = dp->port[i];
 
@@ -1128,7 +1126,6 @@ static void cdn_dp_unbind(struct device *dev, struct 
device *master, void *data)
struct drm_connector *connector = >connector;
 
cancel_work_sync(>event_work);
-   platform_device_unregister(dp->audio_pdev);
cdn_dp_encoder_disable(encoder);
encoder->funcs->destroy(encoder);
connector->funcs->destroy(connector);
@@ -1221,6 +1218,8 @@ static int cdn_dp_probe(struct platform_device *pdev)
mutex_init(>lock);
dev_set_drvdata(dev, dp);
 
+   cdn_dp_audio_codec_init(dp, dev);
+
return component_add(dev, _dp_component_ops);
 }
 
@@ -1228,6 +1227,7 @@ static int cdn_dp_remove(struct platform_device *pdev)
 {
struct cdn_dp_device *dp = platform_get_drvdata(pdev);
 
+   platform_device_unregister(dp->audio_pdev);
cdn_dp_suspend(dp->dev);
component_del(>dev, _dp_component_ops);
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 7/9] drm/rockchip: Shutdown all crtcs when unbinding drm

2017-04-05 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3:
Address Daniel Vetter <dan...@ffwll.ch>'s comments.
Update commit message.

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index f24968f..c6b1b7f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -199,6 +199,7 @@ static void rockchip_drm_unbind(struct device *dev)
rockchip_drm_fbdev_fini(drm_dev);
drm_kms_helper_poll_fini(drm_dev);
 
+   drm_atomic_helper_shutdown(drm_dev);
drm_vblank_cleanup(drm_dev);
component_unbind_all(dev, drm_dev);
drm_mode_config_cleanup(drm_dev);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 5/9] drm/rockchip: vop: Enable pm domain before vop_initial

2017-04-05 Thread Jeffy Chen
We're trying to access vop registers here, so need to make sure
the pm domain is on.

Normally it should be enabled by the bootloader, but there's no
guarantee of it. And if we wanna do unbind/bind, it would also
cause the device to hang.

And this patch also does these:
1/ move vop_initial to the end of vop_bind for eaiser error handling.
2/ correct the err_put_pm_runtime of vop_enable.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3:
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 2151e1c..b65b296 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -506,7 +506,7 @@ static int vop_enable(struct drm_crtc *crtc)
ret = pm_runtime_get_sync(vop->dev);
if (ret < 0) {
dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
-   goto err_put_pm_runtime;
+   return ret;
}
 
ret = clk_enable(vop->hclk);
@@ -1405,10 +1405,16 @@ static int vop_initial(struct vop *vop)
return PTR_ERR(vop->dclk);
}
 
+   ret = pm_runtime_get_sync(vop->dev);
+   if (ret < 0) {
+   dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
+   return ret;
+   }
+
ret = clk_prepare(vop->dclk);
if (ret < 0) {
dev_err(vop->dev, "failed to prepare dclk\n");
-   return ret;
+   goto err_put_pm_runtime;
}
 
/* Enable both the hclk and aclk to setup the vop */
@@ -1468,6 +1474,8 @@ static int vop_initial(struct vop *vop)
 
vop->is_enabled = false;
 
+   pm_runtime_put_sync(vop->dev);
+
return 0;
 
 err_disable_aclk:
@@ -1476,6 +1484,8 @@ static int vop_initial(struct vop *vop)
clk_disable_unprepare(vop->hclk);
 err_unprepare_dclk:
clk_unprepare(vop->dclk);
+err_put_pm_runtime:
+   pm_runtime_put_sync(vop->dev);
return ret;
 }
 
@@ -1576,12 +1586,6 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
if (!vop->regsbak)
return -ENOMEM;
 
-   ret = vop_initial(vop);
-   if (ret < 0) {
-   dev_err(>dev, "cannot initial vop dev - err %d\n", ret);
-   return ret;
-   }
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "cannot find irq for vop\n");
@@ -1608,8 +1612,17 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
 
pm_runtime_enable(>dev);
 
+   ret = vop_initial(vop);
+   if (ret < 0) {
+   dev_err(>dev, "cannot initial vop dev - err %d\n", ret);
+   goto err_disable_pm_runtime;
+   }
+
return 0;
 
+err_disable_pm_runtime:
+   pm_runtime_disable(>dev);
+   vop_destroy_crtc(vop);
 err_enable_irq:
enable_irq(vop->irq); /* To balance out the disable_irq above */
return ret;
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 3/9] drm: bridge: analogix: Destroy connector when unbinding

2017-04-05 Thread Jeffy Chen
Normally we do this in drm_mode_config_cleanup. But analogix dp's
connector is allocated in bind, and freed after unbind. So we need
to destroy it in unbind to avoid further access.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 7b75f82..a96fd55 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1439,6 +1439,7 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
struct analogix_dp_device *dp = dev_get_drvdata(dev);
 
analogix_dp_bridge_disable(dp->bridge);
+   dp->connector.funcs->destroy(>connector);
 
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 4/9] drm/rockchip: cdn-dp: Don't try to release firmware when not loaded

2017-04-05 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 4e55d63..ee4195d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1053,6 +1053,7 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
dp->connected = false;
dp->active = false;
dp->active_port = -1;
+   dp->fw_loaded = false;
 
INIT_WORK(>event_work, cdn_dp_pd_event_work);
 
@@ -1133,7 +1134,8 @@ static void cdn_dp_unbind(struct device *dev, struct 
device *master, void *data)
connector->funcs->destroy(connector);
 
pm_runtime_disable(dev);
-   release_firmware(dp->fw);
+   if (dp->fw_loaded)
+   release_firmware(dp->fw);
kfree(dp->edid);
dp->edid = NULL;
 }
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 6/9] drm/rockchip: Reoder drm bind/unbind sequence

2017-04-05 Thread Jeffy Chen
Current drm bind/unbind sequence would cause some memory issues.
For example we should not cleanup iommu before cleanup mode config.

Reorder bind/unbind sequence, follow exynos drm.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3:
Address Sean Paul <seanp...@chromium.org>'s comments.
Update commit message.

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 49 +++--
 1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index cd7d02e1..f24968f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -136,21 +136,24 @@ static int rockchip_drm_bind(struct device *dev)
INIT_LIST_HEAD(>psr_list);
spin_lock_init(>psr_list_lock);
 
+   ret = rockchip_drm_init_iommu(drm_dev);
+   if (ret)
+   goto err_free;
+
drm_mode_config_init(drm_dev);
 
rockchip_drm_mode_config_init(drm_dev);
 
-   ret = rockchip_drm_init_iommu(drm_dev);
-   if (ret)
-   goto err_config_cleanup;
-
/* Try to bind all sub drivers. */
ret = component_bind_all(dev, drm_dev);
if (ret)
-   goto err_iommu_cleanup;
+   goto err_mode_config_cleanup;
 
-   /* init kms poll for handling hpd */
-   drm_kms_helper_poll_init(drm_dev);
+   ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
+   if (ret)
+   goto err_unbind_all;
+
+   drm_mode_config_reset(drm_dev);
 
/*
 * enable drm irq mode.
@@ -158,15 +161,12 @@ static int rockchip_drm_bind(struct device *dev)
 */
drm_dev->irq_enabled = true;
 
-   ret = drm_vblank_init(drm_dev, ROCKCHIP_MAX_CRTC);
-   if (ret)
-   goto err_kms_helper_poll_fini;
-
-   drm_mode_config_reset(drm_dev);
+   /* init kms poll for handling hpd */
+   drm_kms_helper_poll_init(drm_dev);
 
ret = rockchip_drm_fbdev_init(drm_dev);
if (ret)
-   goto err_vblank_cleanup;
+   goto err_kms_helper_poll_fini;
 
ret = drm_dev_register(drm_dev, 0);
if (ret)
@@ -175,17 +175,17 @@ static int rockchip_drm_bind(struct device *dev)
return 0;
 err_fbdev_fini:
rockchip_drm_fbdev_fini(drm_dev);
-err_vblank_cleanup:
-   drm_vblank_cleanup(drm_dev);
 err_kms_helper_poll_fini:
drm_kms_helper_poll_fini(drm_dev);
+   drm_vblank_cleanup(drm_dev);
+err_unbind_all:
component_unbind_all(dev, drm_dev);
-err_iommu_cleanup:
-   rockchip_iommu_cleanup(drm_dev);
-err_config_cleanup:
+err_mode_config_cleanup:
drm_mode_config_cleanup(drm_dev);
-   drm_dev->dev_private = NULL;
+   rockchip_iommu_cleanup(drm_dev);
 err_free:
+   drm_dev->dev_private = NULL;
+   dev_set_drvdata(dev, NULL);
drm_dev_unref(drm_dev);
return ret;
 }
@@ -194,16 +194,19 @@ static void rockchip_drm_unbind(struct device *dev)
 {
struct drm_device *drm_dev = dev_get_drvdata(dev);
 
+   drm_dev_unregister(drm_dev);
+
rockchip_drm_fbdev_fini(drm_dev);
-   drm_vblank_cleanup(drm_dev);
drm_kms_helper_poll_fini(drm_dev);
+
+   drm_vblank_cleanup(drm_dev);
component_unbind_all(dev, drm_dev);
-   rockchip_iommu_cleanup(drm_dev);
drm_mode_config_cleanup(drm_dev);
+   rockchip_iommu_cleanup(drm_dev);
+
drm_dev->dev_private = NULL;
-   drm_dev_unregister(drm_dev);
-   drm_dev_unref(drm_dev);
dev_set_drvdata(dev, NULL);
+   drm_dev_unref(drm_dev);
 }
 
 static void rockchip_drm_lastclose(struct drm_device *dev)
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 1/9] drm: bridge: analogix: Detach panel when unbinding analogix dp

2017-04-05 Thread Jeffy Chen
The panel is attached when binding analogix dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v3: None
Changes in v2:
Fix some commit messages.

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index c26997a..28144a1 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1443,6 +1443,8 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
DRM_ERROR("failed to turnoff the panel\n");
+   if (drm_panel_detach(dp->plat_data->panel))
+   DRM_ERROR("failed to detach the panel\n");
}
 
pm_runtime_disable(dev);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/9] drm: bridge: analogix: Detach panel when unbinding analogix dp

2017-04-01 Thread Jeffy Chen
The panel is attached when binding analogix dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index e7cd105..a3db290 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1443,6 +1443,8 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
DRM_ERROR("failed to turnoff the panel\n");
+   if (drm_panel_detach(dp->plat_data->panel))
+   DRM_ERROR("failed to detach the panel\n");
}
 
pm_runtime_disable(dev);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 4/9] drm/rockchip: cdn-dp: Don't try to release firmware when not loaded

2017-04-01 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index fd79a70..a97f3f4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1052,6 +1052,7 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
dp->connected = false;
dp->active = false;
dp->active_port = -1;
+   dp->fw_loaded = false;
 
INIT_WORK(>event_work, cdn_dp_pd_event_work);
 
@@ -1132,7 +1133,8 @@ static void cdn_dp_unbind(struct device *dev, struct 
device *master, void *data)
connector->funcs->destroy(connector);
 
pm_runtime_disable(dev);
-   release_firmware(dp->fw);
+   if (dp->fw_loaded)
+   release_firmware(dp->fw);
kfree(dp->edid);
dp->edid = NULL;
 }
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 8/9] drm/rockchip: gem: Don't alloc/free gem buf before drm dev registered

2017-04-01 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index df9e570..2bf8024 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -184,6 +184,9 @@ static int rockchip_gem_alloc_buf(struct 
rockchip_gem_object *rk_obj,
struct drm_device *drm = obj->dev;
struct rockchip_drm_private *private = drm->dev_private;
 
+   if (!drm->registered)
+   return -ENODEV;
+
if (private->domain)
return rockchip_gem_alloc_iommu(rk_obj, alloc_kmap);
else
@@ -208,6 +211,11 @@ static void rockchip_gem_free_dma(struct 
rockchip_gem_object *rk_obj)
 
 static void rockchip_gem_free_buf(struct rockchip_gem_object *rk_obj)
 {
+   struct drm_device *drm = rk_obj->base.dev;
+
+   if (!drm->registered)
+   return;
+
if (rk_obj->pages)
rockchip_gem_free_iommu(rk_obj);
else
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 0/9] drm: rockchip: Fix rockchip drm unbind crash error

2017-04-01 Thread Jeffy Chen

Verified on rk3399 chromebook kevin:
1/ stop ui && pkill -9 frecon
2/ unbind/bind drm


Jeffy Chen (9):
  drm: bridge: analogix: Detach panel when unbinding analogix dp
  drm: bridge: analogix: Unregister dp aux when unbinding
  drm: bridge: analogix: Destroy connector when unbinding
  drm/rockchip: cdn-dp: Don't try to release firmware when not loaded
  drm/rockchip: vop: Enable pm domain when resetting vop
  drm/rockchip: Reoder unload sequence
  drm/rockchip: Force disable all crtc when unload
  drm/rockchip: gem: Don't alloc/free gem buf before drm dev registered
  drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  4 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 10 ---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c|  7 +++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c|  8 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c| 31 +++---
 5 files changed, 44 insertions(+), 16 deletions(-)

-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 5/9] drm/rockchip: vop: Enable pm domain when resetting vop

2017-04-01 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 31 +++--
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 76c79ac..1d85319 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1365,6 +1365,12 @@ static int vop_initial(struct vop *vop)
return ret;
}
 
+   ret = pm_runtime_get_sync(vop->dev);
+   if (ret < 0) {
+   dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
+   goto err_put_pm_runtime;
+   }
+
/* Enable both the hclk and aclk to setup the vop */
ret = clk_prepare_enable(vop->hclk);
if (ret < 0) {
@@ -1422,6 +1428,8 @@ static int vop_initial(struct vop *vop)
 
vop->is_enabled = false;
 
+   pm_runtime_put_sync(vop->dev);
+
return 0;
 
 err_disable_aclk:
@@ -1430,6 +1438,8 @@ static int vop_initial(struct vop *vop)
clk_disable_unprepare(vop->hclk);
 err_unprepare_dclk:
clk_unprepare(vop->dclk);
+err_put_pm_runtime:
+   pm_runtime_put_sync(vop->dev);
return ret;
 }
 
@@ -1530,12 +1540,6 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
if (!vop->regsbak)
return -ENOMEM;
 
-   ret = vop_initial(vop);
-   if (ret < 0) {
-   dev_err(>dev, "cannot initial vop dev - err %d\n", ret);
-   return ret;
-   }
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "cannot find irq for vop\n");
@@ -1556,15 +1560,22 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
/* IRQ is initially disabled; it gets enabled in power_on */
disable_irq(vop->irq);
 
+   pm_runtime_enable(>dev);
+
+   ret = vop_initial(vop);
+   if (ret < 0) {
+   dev_err(>dev, "cannot initial vop dev - err %d\n", ret);
+   goto err_disable_pm_runtime;
+   }
+
ret = vop_create_crtc(vop);
if (ret)
-   goto err_enable_irq;
-
-   pm_runtime_enable(>dev);
+   goto err_disable_pm_runtime;
 
return 0;
 
-err_enable_irq:
+err_disable_pm_runtime:
+   pm_runtime_disable(>dev);
enable_irq(vop->irq); /* To balance out the disable_irq above */
return ret;
 }
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 7/9] drm/rockchip: Force disable all crtc when unload

2017-04-01 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index a5d83cb..5dbf011 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -246,6 +246,7 @@ static void rockchip_drm_unbind(struct device *dev)
rockchip_drm_fbdev_fini(drm_dev);
drm_kms_helper_poll_fini(drm_dev);
 
+   drm_crtc_force_disable_all(drm_dev);
drm_vblank_cleanup(drm_dev);
component_unbind_all(dev, drm_dev);
drm_mode_config_cleanup(drm_dev);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 2/9] drm: bridge: analogix: Unregister dp aux when unbinding

2017-04-01 Thread Jeffy Chen
The dp aux is registered when binding analogix dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index a3db290..ec47fc2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1447,6 +1447,7 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
DRM_ERROR("failed to detach the panel\n");
}
 
+   drm_dp_aux_unregister(>aux);
pm_runtime_disable(dev);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_unbind);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 3/9] drm: bridge: analogix: Destroy connector when unbinding

2017-04-01 Thread Jeffy Chen
Normally we do this in drm_mode_config_cleanup. But analogix dp's
connector is allocated when binding, and would be freed after unbind.

So we need to destroy it when unbinding, to avoid further access.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index ec47fc2..084ee8f 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1439,6 +1439,7 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
struct analogix_dp_device *dp = dev_get_drvdata(dev);
 
analogix_dp_bridge_disable(dp->bridge);
+   dp->connector.funcs->destroy(>connector);
 
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 9/9] drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding

2017-04-01 Thread Jeffy Chen
In current sound framework, there's no way to unbind dai link after
unregister codec.

So don't unregister the codec when unbinding for now.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index a97f3f4..1deab9f 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1091,8 +1091,6 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
goto err_free_connector;
}
 
-   cdn_dp_audio_codec_init(dp, dev);
-
for (i = 0; i < dp->ports; i++) {
port = dp->port[i];
 
@@ -1127,7 +1125,6 @@ static void cdn_dp_unbind(struct device *dev, struct 
device *master, void *data)
struct drm_connector *connector = >connector;
 
cancel_work_sync(>event_work);
-   platform_device_unregister(dp->audio_pdev);
cdn_dp_encoder_disable(encoder);
encoder->funcs->destroy(encoder);
connector->funcs->destroy(connector);
@@ -1220,6 +1217,8 @@ static int cdn_dp_probe(struct platform_device *pdev)
mutex_init(>lock);
dev_set_drvdata(dev, dp);
 
+   cdn_dp_audio_codec_init(dp, dev);
+
return component_add(dev, _dp_component_ops);
 }
 
@@ -1227,6 +1226,7 @@ static int cdn_dp_remove(struct platform_device *pdev)
 {
struct cdn_dp_device *dp = platform_get_drvdata(pdev);
 
+   platform_device_unregister(dp->audio_pdev);
cdn_dp_suspend(dp->dev);
component_del(>dev, _dp_component_ops);
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 7/9] drm/rockchip: Force disable all crtc when unload

2017-04-01 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index a5d83cb..5dbf011 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -246,6 +246,7 @@ static void rockchip_drm_unbind(struct device *dev)
rockchip_drm_fbdev_fini(drm_dev);
drm_kms_helper_poll_fini(drm_dev);
 
+   drm_crtc_force_disable_all(drm_dev);
drm_vblank_cleanup(drm_dev);
component_unbind_all(dev, drm_dev);
drm_mode_config_cleanup(drm_dev);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 5/9] drm/rockchip: vop: Enable pm domain when resetting vop

2017-04-01 Thread Jeffy Chen
Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 31 +++--
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 76c79ac..1d85319 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1365,6 +1365,12 @@ static int vop_initial(struct vop *vop)
return ret;
}
 
+   ret = pm_runtime_get_sync(vop->dev);
+   if (ret < 0) {
+   dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
+   goto err_put_pm_runtime;
+   }
+
/* Enable both the hclk and aclk to setup the vop */
ret = clk_prepare_enable(vop->hclk);
if (ret < 0) {
@@ -1422,6 +1428,8 @@ static int vop_initial(struct vop *vop)
 
vop->is_enabled = false;
 
+   pm_runtime_put_sync(vop->dev);
+
return 0;
 
 err_disable_aclk:
@@ -1430,6 +1438,8 @@ static int vop_initial(struct vop *vop)
clk_disable_unprepare(vop->hclk);
 err_unprepare_dclk:
clk_unprepare(vop->dclk);
+err_put_pm_runtime:
+   pm_runtime_put_sync(vop->dev);
return ret;
 }
 
@@ -1530,12 +1540,6 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
if (!vop->regsbak)
return -ENOMEM;
 
-   ret = vop_initial(vop);
-   if (ret < 0) {
-   dev_err(>dev, "cannot initial vop dev - err %d\n", ret);
-   return ret;
-   }
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "cannot find irq for vop\n");
@@ -1556,15 +1560,22 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
/* IRQ is initially disabled; it gets enabled in power_on */
disable_irq(vop->irq);
 
+   pm_runtime_enable(>dev);
+
+   ret = vop_initial(vop);
+   if (ret < 0) {
+   dev_err(>dev, "cannot initial vop dev - err %d\n", ret);
+   goto err_disable_pm_runtime;
+   }
+
ret = vop_create_crtc(vop);
if (ret)
-   goto err_enable_irq;
-
-   pm_runtime_enable(>dev);
+   goto err_disable_pm_runtime;
 
return 0;
 
-err_enable_irq:
+err_disable_pm_runtime:
+   pm_runtime_disable(>dev);
enable_irq(vop->irq); /* To balance out the disable_irq above */
return ret;
 }
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 0/9] drm: rockchip: Fix rockchip drm unbind crash error

2017-04-01 Thread Jeffy Chen

Verified on rk3399 chromebook kevin:
1/ stop ui && pkill -9 frecon
2/ unbind/bind drm

Changes in v2:
Fix some commit messages.

Jeffy Chen (9):
  drm: bridge: analogix: Detach panel when unbinding analogix dp
  drm: bridge: analogix: Unregister dp aux when unbinding
  drm: bridge: analogix: Destroy connector when unbinding
  drm/rockchip: cdn-dp: Don't try to release firmware when not loaded
  drm/rockchip: vop: Enable pm domain when resetting vop
  drm/rockchip: Reoder unload sequence
  drm/rockchip: Force disable all crtc when unload
  drm/rockchip: gem: Don't alloc/free gem buf before drm dev registered
  drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  4 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 10 ---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c|  7 +++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c|  8 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c| 31 +++---
 5 files changed, 44 insertions(+), 16 deletions(-)

-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 3/9] drm: bridge: analogix: Destroy connector when unbinding

2017-04-01 Thread Jeffy Chen
Normally we do this in drm_mode_config_cleanup. But analogix dp's
connector is allocated in bind, and freed after unbind. So we need
to destroy it in unbind to avoid further access.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index ec47fc2..084ee8f 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1439,6 +1439,7 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
struct analogix_dp_device *dp = dev_get_drvdata(dev);
 
analogix_dp_bridge_disable(dp->bridge);
+   dp->connector.funcs->destroy(>connector);
 
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/9] drm: bridge: analogix: Unregister dp aux when unbinding

2017-04-01 Thread Jeffy Chen
The dp aux is registered when binding analogix dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index a3db290..ec47fc2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1447,6 +1447,7 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
DRM_ERROR("failed to detach the panel\n");
}
 
+   drm_dp_aux_unregister(>aux);
pm_runtime_disable(dev);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_unbind);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 1/9] drm: bridge: analogix: Detach panel when unbinding analogix dp

2017-04-01 Thread Jeffy Chen
The panel is attached when binding analogix dp.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2:
Fix some commit messages.

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index e7cd105..a3db290 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1443,6 +1443,8 @@ void analogix_dp_unbind(struct device *dev, struct device 
*master,
if (dp->plat_data->panel) {
if (drm_panel_unprepare(dp->plat_data->panel))
DRM_ERROR("failed to turnoff the panel\n");
+   if (drm_panel_detach(dp->plat_data->panel))
+   DRM_ERROR("failed to detach the panel\n");
}
 
pm_runtime_disable(dev);
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 9/9] drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding

2017-04-01 Thread Jeffy Chen
In current sound framework, there's no way to unbind dai link after
unregister codec.

So move unregister codec to driver remove for now.

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
---

Changes in v2: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index a97f3f4..1deab9f 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1091,8 +1091,6 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
goto err_free_connector;
}
 
-   cdn_dp_audio_codec_init(dp, dev);
-
for (i = 0; i < dp->ports; i++) {
port = dp->port[i];
 
@@ -1127,7 +1125,6 @@ static void cdn_dp_unbind(struct device *dev, struct 
device *master, void *data)
struct drm_connector *connector = >connector;
 
cancel_work_sync(>event_work);
-   platform_device_unregister(dp->audio_pdev);
cdn_dp_encoder_disable(encoder);
encoder->funcs->destroy(encoder);
connector->funcs->destroy(connector);
@@ -1220,6 +1217,8 @@ static int cdn_dp_probe(struct platform_device *pdev)
mutex_init(>lock);
dev_set_drvdata(dev, dp);
 
+   cdn_dp_audio_codec_init(dp, dev);
+
return component_add(dev, _dp_component_ops);
 }
 
@@ -1227,6 +1226,7 @@ static int cdn_dp_remove(struct platform_device *pdev)
 {
struct cdn_dp_device *dp = platform_get_drvdata(pdev);
 
+   platform_device_unregister(dp->audio_pdev);
cdn_dp_suspend(dp->dev);
component_del(>dev, _dp_component_ops);
 
-- 
2.1.4


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


  1   2   >