From 80399ef7927dd01152d03e4e2555297764c78b95 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 21 Jun 2016 22:22:55 -0700 Subject: [PATCH] 4.6-stable patches added patches: drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch gpio-zynq-fix-the-error-path.patch gpio-zynq-initialize-clock-even-without-config_pm.patch --- ...-not-preserve-framebuffer-on-rmfb-v4.patch | 143 ++++++++++++++++++ queue-4.6/gpio-zynq-fix-the-error-path.patch | 42 +++++ ...tialize-clock-even-without-config_pm.patch | 51 +++++++ queue-4.6/series | 3 + 4 files changed, 239 insertions(+) create mode 100644 queue-4.6/drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch create mode 100644 queue-4.6/gpio-zynq-fix-the-error-path.patch create mode 100644 queue-4.6/gpio-zynq-initialize-clock-even-without-config_pm.patch diff --git a/queue-4.6/drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch b/queue-4.6/drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch new file mode 100644 index 00000000000..692df794163 --- /dev/null +++ b/queue-4.6/drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch @@ -0,0 +1,143 @@ +From f2d580b9a8149735cbc4b59c4a8df60173658140 Mon Sep 17 00:00:00 2001 +From: Maarten Lankhorst +Date: Wed, 4 May 2016 14:38:26 +0200 +Subject: drm/core: Do not preserve framebuffer on rmfb, v4. + +From: Maarten Lankhorst + +commit f2d580b9a8149735cbc4b59c4a8df60173658140 upstream. + +It turns out that preserving framebuffers after the rmfb call breaks +vmwgfx userspace. This was originally introduced because it was thought +nobody relied on the behavior, but unfortunately it seems there are +exceptions. + +drm_framebuffer_remove may fail with -EINTR now, so a straight revert +is impossible. There is no way to remove the framebuffer from the lists +and active planes without introducing a race because of the different +locking requirements. Instead call drm_framebuffer_remove from a +workqueue, which is unaffected by signals. + +Changes since v1: +- Add comment. +Changes since v2: +- Add fastpath for refcount = 1. (danvet) +Changes since v3: +- Rebased. +- Restore lastclose framebuffer removal too. + +Fixes: 13803132818c ("drm/core: Preserve the framebuffer after removing it.") +Testcase: kms_rmfb_basic +References: https://lists.freedesktop.org/archives/dri-devel/2016-March/102876.html +Cc: Thomas Hellstrom +Cc: David Herrmann +Reviewed-by: Daniel Vetter +Tested-by: Thomas Hellstrom #v3 +Tested-by: Tvrtko Ursulin +Signed-off-by: Daniel Vetter +Link: http://patchwork.freedesktop.org/patch/msgid/6c63ca37-0e7e-ac7f-a6d2-c7822e3d611f@linux.intel.com +Signed-off-by: Hans de Goede +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_crtc.c | 60 +++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 55 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -3434,6 +3434,24 @@ int drm_mode_addfb2(struct drm_device *d + return 0; + } + ++struct drm_mode_rmfb_work { ++ struct work_struct work; ++ struct list_head fbs; ++}; ++ ++static void drm_mode_rmfb_work_fn(struct work_struct *w) ++{ ++ struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work); ++ ++ while (!list_empty(&arg->fbs)) { ++ struct drm_framebuffer *fb = ++ list_first_entry(&arg->fbs, typeof(*fb), filp_head); ++ ++ list_del_init(&fb->filp_head); ++ drm_framebuffer_remove(fb); ++ } ++} ++ + /** + * drm_mode_rmfb - remove an FB from the configuration + * @dev: drm device for the ioctl +@@ -3474,7 +3492,25 @@ int drm_mode_rmfb(struct drm_device *dev + mutex_unlock(&dev->mode_config.fb_lock); + mutex_unlock(&file_priv->fbs_lock); + +- drm_framebuffer_unreference(fb); ++ /* ++ * we now own the reference that was stored in the fbs list ++ * ++ * drm_framebuffer_remove may fail with -EINTR on pending signals, ++ * so run this in a separate stack as there's no way to correctly ++ * handle this after the fb is already removed from the lookup table. ++ */ ++ if (atomic_read(&fb->refcount.refcount) > 1) { ++ struct drm_mode_rmfb_work arg; ++ ++ INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn); ++ INIT_LIST_HEAD(&arg.fbs); ++ list_add_tail(&fb->filp_head, &arg.fbs); ++ ++ schedule_work(&arg.work); ++ flush_work(&arg.work); ++ destroy_work_on_stack(&arg.work); ++ } else ++ drm_framebuffer_unreference(fb); + + return 0; + +@@ -3627,7 +3663,6 @@ out_err1: + return ret; + } + +- + /** + * drm_fb_release - remove and free the FBs on this file + * @priv: drm file for the ioctl +@@ -3642,6 +3677,9 @@ out_err1: + void drm_fb_release(struct drm_file *priv) + { + struct drm_framebuffer *fb, *tfb; ++ struct drm_mode_rmfb_work arg; ++ ++ INIT_LIST_HEAD(&arg.fbs); + + /* + * When the file gets released that means no one else can access the fb +@@ -3654,10 +3692,22 @@ void drm_fb_release(struct drm_file *pri + * at it any more. + */ + list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { +- list_del_init(&fb->filp_head); ++ if (atomic_read(&fb->refcount.refcount) > 1) { ++ list_move_tail(&fb->filp_head, &arg.fbs); ++ } else { ++ list_del_init(&fb->filp_head); + +- /* This drops the fpriv->fbs reference. */ +- drm_framebuffer_unreference(fb); ++ /* This drops the fpriv->fbs reference. */ ++ drm_framebuffer_unreference(fb); ++ } ++ } ++ ++ if (!list_empty(&arg.fbs)) { ++ INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn); ++ ++ schedule_work(&arg.work); ++ flush_work(&arg.work); ++ destroy_work_on_stack(&arg.work); + } + } + diff --git a/queue-4.6/gpio-zynq-fix-the-error-path.patch b/queue-4.6/gpio-zynq-fix-the-error-path.patch new file mode 100644 index 00000000000..5b9ca64b016 --- /dev/null +++ b/queue-4.6/gpio-zynq-fix-the-error-path.patch @@ -0,0 +1,42 @@ +From 615d23f80efc60f8c5146223f305d19207c742e4 Mon Sep 17 00:00:00 2001 +From: Shubhrajyoti Datta +Date: Mon, 4 Apr 2016 23:44:06 +0530 +Subject: gpio: zynq: Fix the error path + +From: Shubhrajyoti Datta + +commit 615d23f80efc60f8c5146223f305d19207c742e4 upstream. + +pm_runtime_disable is called only in remove it is missed +out in the error path. +Fix the same. + +Signed-off-by: Shubhrajyoti Datta +Signed-off-by: Linus Walleij +Cc: Helmut Grohne +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpio-zynq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/gpio/gpio-zynq.c ++++ b/drivers/gpio/gpio-zynq.c +@@ -713,7 +713,7 @@ static int zynq_gpio_probe(struct platfo + pm_runtime_enable(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) +- return ret; ++ goto err_pm_dis; + + /* report a bug if gpio chip registration fails */ + ret = gpiochip_add_data(chip, gpio); +@@ -745,6 +745,8 @@ err_rm_gpiochip: + gpiochip_remove(chip); + err_pm_put: + pm_runtime_put(&pdev->dev); ++err_pm_dis: ++ pm_runtime_disable(&pdev->dev); + + return ret; + } diff --git a/queue-4.6/gpio-zynq-initialize-clock-even-without-config_pm.patch b/queue-4.6/gpio-zynq-initialize-clock-even-without-config_pm.patch new file mode 100644 index 00000000000..65796ff70eb --- /dev/null +++ b/queue-4.6/gpio-zynq-initialize-clock-even-without-config_pm.patch @@ -0,0 +1,51 @@ +From 0f84f29ff30bdb1bca23017b118b4ea3999cac32 Mon Sep 17 00:00:00 2001 +From: Helmut Grohne +Date: Fri, 3 Jun 2016 14:15:32 +0200 +Subject: gpio: zynq: initialize clock even without CONFIG_PM + +From: Helmut Grohne + +commit 0f84f29ff30bdb1bca23017b118b4ea3999cac32 upstream. + +When the PM initialization was moved in the commit referenced below, the +code enabling the clock was removed from the probe function. On +CONFIG_PM=y kernels, this is not a problem as the pm resume hook enables +the clock, but when power management is disabled, all those pm_* +functions are noops and the clock is never enabled resulting in a +dysfunctional gpio controller. + +Put the clock initialization back to support CONFIG_PM=n. + +Signed-off-by: Helmut Grohne +Fixes: 3773c195d387 ("gpio: zynq: Do PM initialization earlier to support gpio hogs") +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpio-zynq.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/gpio/gpio-zynq.c ++++ b/drivers/gpio/gpio-zynq.c +@@ -709,7 +709,13 @@ static int zynq_gpio_probe(struct platfo + dev_err(&pdev->dev, "input clock not found.\n"); + return PTR_ERR(gpio->clk); + } ++ ret = clk_prepare_enable(gpio->clk); ++ if (ret) { ++ dev_err(&pdev->dev, "Unable to enable clock.\n"); ++ return ret; ++ } + ++ pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) +@@ -747,6 +753,7 @@ err_pm_put: + pm_runtime_put(&pdev->dev); + err_pm_dis: + pm_runtime_disable(&pdev->dev); ++ clk_disable_unprepare(gpio->clk); + + return ret; + } diff --git a/queue-4.6/series b/queue-4.6/series index ff0c26fb18a..a497f00ad2e 100644 --- a/queue-4.6/series +++ b/queue-4.6/series @@ -65,3 +65,6 @@ sparc64-reduce-tlb-flushes-during-hugepte-changes.patch sparc64-take-ctx_alloc_lock-properly-in-hugetlb_setup.patch sparc-harden-signal-return-frame-checks.patch sparc64-fix-return-from-trap-window-fill-crashes.patch +gpio-zynq-fix-the-error-path.patch +gpio-zynq-initialize-clock-even-without-config_pm.patch +drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch -- 2.47.3