From 37cc4b95d13f311c04aa8e9daacca3905ad45ca7 Mon Sep 17 00:00:00 2001 From: Xiyu Yang Date: Sat, 13 Jun 2020 20:28:38 +0800 Subject: drm/ttm: Fix dma_fence refcnt leak in ttm_bo_vm_fault_reserved MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ttm_bo_vm_fault_reserved() invokes dma_fence_get(), which returns a reference of the specified dma_fence object to "moving" with increased refcnt. When ttm_bo_vm_fault_reserved() returns, local variable "moving" becomes invalid, so the refcount should be decreased to keep refcount balanced. The reference counting issue happens in several exception handling paths of ttm_bo_vm_fault_reserved(). When those error scenarios occur such as "err" equals to -EBUSY, the function forgets to decrease the refcnt increased by dma_fence_get(), causing a refcnt leak. Fix this issue by calling dma_fence_put() when no_wait_gpu flag is equals to true. Signed-off-by: Xiyu Yang Signed-off-by: Xin Tan Reviewed-by: Christian König Link: https://patchwork.freedesktop.org/patch/370219/ Signed-off-by: Christian König --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 0ad30b112982..72100b84c7a9 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -300,8 +300,10 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, break; case -EBUSY: case -ERESTARTSYS: + dma_fence_put(moving); return VM_FAULT_NOPAGE; default: + dma_fence_put(moving); return VM_FAULT_SIGBUS; } -- cgit v1.2.3 From 11425c4519e2c974a100fc984867046d905b9380 Mon Sep 17 00:00:00 2001 From: Xiyu Yang Date: Sat, 13 Jun 2020 20:30:25 +0800 Subject: drm/ttm: Fix dma_fence refcnt leak when adding move fence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ttm_bo_add_move_fence() invokes dma_fence_get(), which returns a reference of the specified dma_fence object to "fence" with increased refcnt. When ttm_bo_add_move_fence() returns, local variable "fence" becomes invalid, so the refcount should be decreased to keep refcount balanced. The reference counting issue happens in one exception handling path of ttm_bo_add_move_fence(). When no_wait_gpu flag is equals to true, the function forgets to decrease the refcnt increased by dma_fence_get(), causing a refcnt leak. Fix this issue by calling dma_fence_put() when no_wait_gpu flag is equals to true. Signed-off-by: Xiyu Yang Signed-off-by: Xin Tan Reviewed-by: Christian König Link: https://patchwork.freedesktop.org/patch/370221/ Signed-off-by: Christian König --- drivers/gpu/drm/ttm/ttm_bo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 9e07c3f75156..ef5bc00c73e2 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -881,8 +881,10 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo, if (!fence) return 0; - if (no_wait_gpu) + if (no_wait_gpu) { + dma_fence_put(fence); return -EBUSY; + } dma_resv_add_shared_fence(bo->base.resv, fence); -- cgit v1.2.3 From 109be8b23fb2ec8e2d309325ee3b7a49eab63961 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 26 Apr 2020 21:16:30 +0200 Subject: gpu: host1x: Clean up debugfs in error handling path host1x_debug_init() must be reverted in an error handling path. This is already fixed in the remove function since commit 44156eee91ba ("gpu: host1x: Clean up debugfs on removal") Signed-off-by: Christophe JAILLET Signed-off-by: Thierry Reding --- drivers/gpu/host1x/dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index d24344e91922..3c0f151847ba 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -468,11 +468,12 @@ static int host1x_probe(struct platform_device *pdev) err = host1x_register(host); if (err < 0) - goto deinit_intr; + goto deinit_debugfs; return 0; -deinit_intr: +deinit_debugfs: + host1x_debug_deinit(host); host1x_intr_deinit(host); deinit_syncpt: host1x_syncpt_deinit(host); -- cgit v1.2.3 From ef4e417eb3ec7fe657928f10ac1d2154d8a5fb38 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 19 May 2020 02:03:01 -0700 Subject: drm/tegra: hub: Do not enable orphaned window group Though the unconditional enable/disable code is not a final solution, we don't want to run into a NULL pointer situation when window group doesn't link to its DC parent if the DC is disabled in Device Tree. So this patch simply adds a check to make sure that window group has a valid parent before running into tegra_windowgroup_enable/disable. Signed-off-by: Nicolin Chen Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/hub.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index 8183e617bf6b..a2ef8f218d4e 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -149,7 +149,9 @@ int tegra_display_hub_prepare(struct tegra_display_hub *hub) for (i = 0; i < hub->soc->num_wgrps; i++) { struct tegra_windowgroup *wgrp = &hub->wgrps[i]; - tegra_windowgroup_enable(wgrp); + /* Skip orphaned window group whose parent DC is disabled */ + if (wgrp->parent) + tegra_windowgroup_enable(wgrp); } return 0; @@ -166,7 +168,9 @@ void tegra_display_hub_cleanup(struct tegra_display_hub *hub) for (i = 0; i < hub->soc->num_wgrps; i++) { struct tegra_windowgroup *wgrp = &hub->wgrps[i]; - tegra_windowgroup_disable(wgrp); + /* Skip orphaned window group whose parent DC is disabled */ + if (wgrp->parent) + tegra_windowgroup_disable(wgrp); } } -- cgit v1.2.3 From ca2030d56bb7b73079f834b10de38ced9cac74a3 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 12 Jun 2020 17:00:59 +0200 Subject: gpu: host1x: Register child devices In order to remove the dependency on the simple-bus compatible string, which causes the OF driver core to register all child devices, make the host1x driver explicitly register its children. Signed-off-by: Thierry Reding --- drivers/gpu/host1x/dev.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 3c0f151847ba..d0ebb70e2fdd 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -470,8 +470,14 @@ static int host1x_probe(struct platform_device *pdev) if (err < 0) goto deinit_debugfs; + err = devm_of_platform_populate(&pdev->dev); + if (err < 0) + goto unregister; + return 0; +unregister: + host1x_unregister(host); deinit_debugfs: host1x_debug_deinit(host); host1x_intr_deinit(host); -- cgit v1.2.3 From a101e3dad8a90a840ccb45e492cd2ef7c01199ea Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 12 Jun 2020 17:01:00 +0200 Subject: drm/tegra: hub: Register child devices In order to remove the dependency on the simple-bus compatible string, which causes the OF driver core to register all child devices, make the display-hub driver explicitly register the display controller children. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/hub.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index a2ef8f218d4e..22a03f7ffdc1 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -948,6 +948,15 @@ static int tegra_display_hub_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to register host1x client: %d\n", err); + err = devm_of_platform_populate(&pdev->dev); + if (err < 0) + goto unregister; + + return err; + +unregister: + host1x_client_unregister(&hub->client); + pm_runtime_disable(&pdev->dev); return err; } -- cgit v1.2.3 From d9a0a05bf8c76e6dc79230669a8b5d685b168c30 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 8 Apr 2020 19:38:02 +0200 Subject: gpu: host1x: Detach driver on unregister Currently when a host1x device driver is unregistered, it is not detached from the host1x controller, which means that the device will stay around and when the driver is registered again, it may bind to the old, stale device rather than the new one that was created from scratch upon driver registration. This in turn can cause various weird crashes within the driver core because it is confronted with a device that was already deleted. Fix this by detaching the driver from the host1x controller when it is unregistered. This ensures that the deleted device also is no longer present in the device list that drivers will bind to. Reported-by: Sowjanya Komatineni Signed-off-by: Thierry Reding Tested-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/gpu/host1x/bus.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 6a995db51d6d..e201f62d62c0 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -686,8 +686,17 @@ EXPORT_SYMBOL(host1x_driver_register_full); */ void host1x_driver_unregister(struct host1x_driver *driver) { + struct host1x *host1x; + driver_unregister(&driver->driver); + mutex_lock(&devices_lock); + + list_for_each_entry(host1x, &devices, list) + host1x_detach_driver(host1x, driver); + + mutex_unlock(&devices_lock); + mutex_lock(&drivers_lock); list_del_init(&driver->list); mutex_unlock(&drivers_lock); -- cgit v1.2.3 From fce3a51d9b31312aa12ecb72ffabfc4c7b40bdc6 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 10 Jun 2020 13:30:59 +0200 Subject: drm/tegra: Add zpos property for cursor planes As of commit 4dc55525b095 ("drm: plane: Verify that no or all planes have a zpos property") a warning is emitted if there's a mix of planes with and without a zpos property. On Tegra, cursor planes are always composited on top of all other planes, which is why they never had a zpos property attached to them. However, since the composition order is fixed, this is trivial to remedy by simply attaching an immutable zpos property to them. v3: do not hardcode zpos for overlay planes used as cursor (Dmitry) v2: hardcode cursor plane zpos to 255 instead of 0 (Ville) Reported-by: Jonathan Hunter Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 83f31c6e891c..04d6848d19fc 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -957,6 +957,7 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, } drm_plane_helper_add(&plane->base, &tegra_cursor_plane_helper_funcs); + drm_plane_create_zpos_immutable_property(&plane->base, 255); return &plane->base; } -- cgit v1.2.3 From b984b6d8b52372b98cce0a6ff6c2787f50665b87 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 14 Jun 2020 00:30:26 +0200 Subject: drm: mcde: Fix display initialization problem The following bug appeared in the MCDE driver/display initialization during the recent merge window. First the place we call drm_fbdev_generic_setup() in the wrong place: this needs to be called AFTER calling drm_dev_register() else we get this splat: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at ../drivers/gpu/drm/drm_fb_helper.c:2198 drm_fbdev_generic_setup+0x164/0x1a8 mcde a0350000.mcde: Device has not been registered. Modules linked in: Hardware name: ST-Ericsson Ux5x0 platform (Device Tree Support) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x9c/0xb0) [] (dump_stack) from [] (__warn+0xb8/0xd0) [] (__warn) from [] (warn_slowpath_fmt+0x74/0xb8) [] (warn_slowpath_fmt) from [] (drm_fbdev_generic_setup+0x164/0x1a8) [] (drm_fbdev_generic_setup) from [] (mcde_drm_bind+0xc4/0x160) [] (mcde_drm_bind) from [] (try_to_bring_up_master+0x15c/0x1a4) (...) Signed-off-by: Linus Walleij Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200613223027.4189309-1-linus.walleij@linaro.org --- drivers/gpu/drm/mcde/mcde_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index 84f3e2dbd77b..80082d6dce3a 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -209,7 +209,6 @@ static int mcde_modeset_init(struct drm_device *drm) drm_mode_config_reset(drm); drm_kms_helper_poll_init(drm); - drm_fbdev_generic_setup(drm, 32); return 0; } @@ -264,6 +263,8 @@ static int mcde_drm_bind(struct device *dev) if (ret < 0) goto unbind; + drm_fbdev_generic_setup(drm, 32); + return 0; unbind: -- cgit v1.2.3 From b48fd568ac649f0fd750e89487eaa4a0ef8d2835 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 14 Jun 2020 00:30:27 +0200 Subject: drm: mcde: Fix forgotten user of drm->dev_private Unable to handle kernel NULL pointer dereference at virtual address 00000918 pgd = (ptrval) [00000918] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.7.0-15001-gfa384b50b96b-dirty #514 Hardware name: ST-Ericsson Ux5x0 platform (Device Tree Support) PC is at mcde_display_enable+0x78/0x7c0 LR is at mcde_display_enable+0x78/0x7c0 Fix this by using to_mcde() as in other functions. Fixes: fd7ee85cfe7b ("drm/mcde: Don't use drm_device->dev_private") Signed-off-by: Linus Walleij Reviewed-by: Sam Ravnborg Cc: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200613223027.4189309-2-linus.walleij@linaro.org --- drivers/gpu/drm/mcde/mcde_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/mcde/mcde_display.c b/drivers/gpu/drm/mcde/mcde_display.c index 04e1d38d41f7..08802e5177f6 100644 --- a/drivers/gpu/drm/mcde/mcde_display.c +++ b/drivers/gpu/drm/mcde/mcde_display.c @@ -812,7 +812,7 @@ static void mcde_display_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc *crtc = &pipe->crtc; struct drm_plane *plane = &pipe->plane; struct drm_device *drm = crtc->dev; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); const struct drm_display_mode *mode = &cstate->mode; struct drm_framebuffer *fb = plane->state->fb; u32 format = fb->format->format; -- cgit v1.2.3 From 5f9af404eec82981c4345c9943be48422234e7ab Mon Sep 17 00:00:00 2001 From: Daniel Gomez Date: Mon, 18 May 2020 22:16:46 +0200 Subject: drm: rcar-du: Fix build error Select DRM_KMS_HELPER dependency. Build error when DRM_KMS_HELPER is not selected: drivers/gpu/drm/rcar-du/rcar_lvds.o:(.rodata+0xd48): undefined reference to `drm_atomic_helper_bridge_duplicate_state' drivers/gpu/drm/rcar-du/rcar_lvds.o:(.rodata+0xd50): undefined reference to `drm_atomic_helper_bridge_destroy_state' drivers/gpu/drm/rcar-du/rcar_lvds.o:(.rodata+0xd70): undefined reference to `drm_atomic_helper_bridge_reset' drivers/gpu/drm/rcar-du/rcar_lvds.o:(.rodata+0xdc8): undefined reference to `drm_atomic_helper_connector_reset' drivers/gpu/drm/rcar-du/rcar_lvds.o:(.rodata+0xde0): undefined reference to `drm_helper_probe_single_connector_modes' drivers/gpu/drm/rcar-du/rcar_lvds.o:(.rodata+0xe08): undefined reference to `drm_atomic_helper_connector_duplicate_state' drivers/gpu/drm/rcar-du/rcar_lvds.o:(.rodata+0xe10): undefined reference to `drm_atomic_helper_connector_destroy_state' Fixes: c6a27fa41fab ("drm: rcar-du: Convert LVDS encoder code to bridge driver") Cc: Signed-off-by: Daniel Gomez Reviewed-by: Emil Velikov Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/rcar-du/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig index 0919f1f159a4..f65d1489dc50 100644 --- a/drivers/gpu/drm/rcar-du/Kconfig +++ b/drivers/gpu/drm/rcar-du/Kconfig @@ -31,6 +31,7 @@ config DRM_RCAR_DW_HDMI config DRM_RCAR_LVDS tristate "R-Car DU LVDS Encoder Support" depends on DRM && DRM_BRIDGE && OF + select DRM_KMS_HELPER select DRM_PANEL select OF_FLATTREE select OF_OVERLAY -- cgit v1.2.3 From efb94790852ae673b18efde1b171d284689ff333 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Mon, 15 Jun 2020 08:19:34 -0500 Subject: drm/panel-simple: fix connector type for LogicPD Type28 Display The LogicPD Type28 display used by several Logic PD products has not worked since v5.6. The connector type for the LogicPD Type 28 display is missing and drm_panel_bridge_add() requires connector type to be set. Signed-off-by: Adam Ford Fixes: 0d35408afbeb ("drm/panel: simple: Add Logic PD Type 28 display support") Cc: Adam Ford Cc: Sam Ravnborg Cc: Thierry Reding Cc: dri-devel@lists.freedesktop.org Cc: # v5.6+ Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200615131934.12440-1-aford173@gmail.com --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index b6ecd1552132..334e9de5b2c8 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2495,6 +2495,7 @@ static const struct panel_desc logicpd_type_28 = { .bus_format = MEDIA_BUS_FMT_RGB888_1X24, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE | DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE, + .connector_type = DRM_MODE_CONNECTOR_DPI, }; static const struct panel_desc mitsubishi_aa070mc01 = { -- cgit v1.2.3 From 8a4f5e1185db61bce6ce3a5dce6381a77bcf94e6 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 9 Jun 2020 13:28:09 +0300 Subject: drm/panel-simple: fix connector type for newhaven_nhd_43_480272ef_atxl Add connector type for newhaven_nhd_43_480272ef_atxl, as drm_panel_bridge_add() requires connector type to be set. Signed-off-by: Tomi Valkeinen Cc: stable@vger.kernel.org # v5.5+ Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200609102809.753203-1-tomi.valkeinen@ti.com --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 334e9de5b2c8..5178f87d6574 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2664,6 +2664,7 @@ static const struct panel_desc newhaven_nhd_43_480272ef_atxl = { .bus_format = MEDIA_BUS_FMT_RGB888_1X24, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE | DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE, + .connector_type = DRM_MODE_CONNECTOR_DPI, }; static const struct display_timing nlt_nl192108ac18_02d_timing = { -- cgit v1.2.3 From 7f757cb6b2fc0ad704d0ca0b7b5a2729aca35580 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 9 Jun 2020 11:29:43 +0200 Subject: video: fbdev: uvesafb: fix "noblank" option handling Fix the recent regression. Fixes: dbc7ece12a38 ("video: uvesafb: use true,false for bool variables") Cc: Jason Yan Reviewed-by: Sam Ravnborg Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/81c9f140-d6fb-803a-18c8-04dae1007ab3@samsung.com --- drivers/video/fbdev/uvesafb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c index bee29aadc646..def14ac0ebe1 100644 --- a/drivers/video/fbdev/uvesafb.c +++ b/drivers/video/fbdev/uvesafb.c @@ -1836,7 +1836,7 @@ static int uvesafb_setup(char *options) else if (!strcmp(this_opt, "noedid")) noedid = true; else if (!strcmp(this_opt, "noblank")) - blank = true; + blank = false; else if (!strncmp(this_opt, "vtotal:", 7)) vram_total = simple_strtoul(this_opt + 7, NULL, 0); else if (!strncmp(this_opt, "vremap:", 7)) -- cgit v1.2.3 From 6c22bc18a3b93a38018844636557ad02e588e055 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 31 May 2020 11:30:24 +0200 Subject: drm: panel-orientation-quirks: Add quirk for Asus T101HA panel Like the Asus T100HA the Asus T101HA also uses a panel which has been mounted 90 degrees rotated, albeit in the opposite direction. Add a quirk for this. Reviewed-by: Emil Velikov Signed-off-by: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20200531093025.28050-1-hdegoede@redhat.com --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index ffd95bfeaa94..d11d83703931 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -121,6 +121,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"), }, .driver_data = (void *)&asus_t100ha, + }, { /* Asus T101HA */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T101HA"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* GPD MicroPC (generic strings, also match on bios date) */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), -- cgit v1.2.3 From a05caf9e62a85d12da27e814ac13195f4683f21c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 31 May 2020 11:30:25 +0200 Subject: drm: panel-orientation-quirks: Use generic orientation-data for Acer S1003 The Acer S1003 has proper DMI strings for sys-vendor and product-name, so we do not need to match by BIOS-date. This means that the Acer S1003 can use the generic lcd800x1280_rightside_up drm_dmi_panel_orientation_data struct which is also used by other quirks. Reviewed-by: Emil Velikov Signed-off-by: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20200531093025.28050-2-hdegoede@redhat.com --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index d11d83703931..d00ea384dcbf 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -30,12 +30,6 @@ struct drm_dmi_panel_orientation_data { int orientation; }; -static const struct drm_dmi_panel_orientation_data acer_s1003 = { - .width = 800, - .height = 1280, - .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -}; - static const struct drm_dmi_panel_orientation_data asus_t100ha = { .width = 800, .height = 1280, @@ -114,7 +108,7 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), }, - .driver_data = (void *)&acer_s1003, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* Asus T100HA */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), -- cgit v1.2.3 From 842ec61f4006a6477a9deaedd69131e9f46e4cb5 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 13 May 2020 16:07:24 +0200 Subject: drm/sun4i: mixer: Call of_dma_configure if there's an IOMMU The main DRM device is actually a virtual device so it doesn't have the iommus property, which is instead on the DMA masters, in this case the mixers. Add a call to of_dma_configure with the mixers DT node but on the DRM virtual device to configure it in the same way than the mixers. Reviewed-by: Paul Kocialkowski Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/9a4daf438dd3f2fe07afb23688bfb793a0613d7d.1589378833.git-series.maxime@cerno.tech (cherry picked from commit b718102dbdfd0285ad559687a30e27cc9124e592) [Maxime: Applied to -fixes since it missed the merge window and display is broken without it] Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 56cc037fd312..cc4fb916318f 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -363,6 +363,19 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, mixer->engine.ops = &sun8i_engine_ops; mixer->engine.node = dev->of_node; + if (of_find_property(dev->of_node, "iommus", NULL)) { + /* + * This assume we have the same DMA constraints for + * all our the mixers in our pipeline. This sounds + * bad, but it has always been the case for us, and + * DRM doesn't do per-device allocation either, so we + * would need to fix DRM first... + */ + ret = of_dma_configure(drm->dev, dev->of_node, true); + if (ret) + return ret; + } + /* * While this function can fail, we shouldn't do anything * if this happens. Some early DE2 DT entries don't provide -- cgit v1.2.3 From ee434a4f9f5ea15b0f84bddd8c012838cf9472c5 Mon Sep 17 00:00:00 2001 From: John van der Kamp Date: Tue, 23 Jun 2020 23:30:54 +0200 Subject: drm/amdgpu/display: Unlock mutex on error Make sure we pass through ret label to unlock the mutex. Signed-off-by: John van der Kamp Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index dcf84a61de37..949d10ef8304 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -510,8 +510,10 @@ static ssize_t srm_data_read(struct file *filp, struct kobject *kobj, struct bin srm = psp_get_srm(work->hdcp.config.psp.handle, &srm_version, &srm_size); - if (!srm) - return -EINVAL; + if (!srm) { + ret = -EINVAL; + goto ret; + } if (pos >= srm_size) ret = 0; -- cgit v1.2.3 From 35f760b44b1b9cb16a306bdcc7220fbbf78c4789 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Mon, 22 Jun 2020 23:31:22 +0300 Subject: drm/radeon: fix fb_div check in ni_init_smc_spll_table() clk_s is checked twice in a row in ni_init_smc_spll_table(). fb_div should be checked instead. Fixes: 69e0b57a91ad ("drm/radeon/kms: add dpm support for cayman (v5)") Cc: stable@vger.kernel.org Signed-off-by: Denis Efremov Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ni_dpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index b57c37ddd164..c7fbb7932f37 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -2127,7 +2127,7 @@ static int ni_init_smc_spll_table(struct radeon_device *rdev) if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT)) ret = -EINVAL; - if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT)) + if (fb_div & ~(SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT)) ret = -EINVAL; if (clk_v & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT)) -- cgit v1.2.3 From dc5bdb68b5b369d5bc7d1de96fa64cc1737a6320 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 24 Jun 2020 11:29:10 +0200 Subject: drm/fb-helper: Fix vt restore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the past we had a pile of hacks to orchestrate access between fbdev emulation and native kms clients. We've tried to streamline this, by always preferring the kms side above fbdev calls when a drm master exists, because drm master controls access to the display resources. Unfortunately this breaks existing userspace, specifically Xorg. When exiting Xorg first restores the console to text mode using the KDSET ioctl on the vt. This does nothing, because a drm master is still around. Then it drops the drm master status, which again does nothing, because logind is keeping additional drm fd open to be able to orchestrate vt switches. In the past this is the point where fbdev was restored, as part of the ->lastclose hook on the drm side. Now to fix this regression we don't want to go back to letting fbdev restore things whenever it feels like, or to the pile of hacks we've had before. Instead try and go with a minimal exception to make the KDSET case work again, and nothing else. This means that if userspace does a KDSET call when switching between graphical compositors, there will be some flickering with fbcon showing up for a bit. But a) that's not a regression and b) userspace can fix it by improving the vt switching dance - logind should have all the information it needs. While pondering all this I'm also wondering wheter we should have a SWITCH_MASTER ioctl to allow race-free master status handover. But that's for another day. v2: Somehow forgot to cc all the fbdev people. v3: Fix typo Alex spotted. Reviewed-by: Alex Deucher Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=208179 Cc: shlomo@fastmail.com Reported-and-Tested-by: shlomo@fastmail.com Cc: Michel Dänzer Fixes: 64914da24ea9 ("drm/fbdev-helper: don't force restores") Cc: Noralf Trønnes Cc: Thomas Zimmermann Cc: Daniel Vetter Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Cc: # v5.7+ Cc: Bartlomiej Zolnierkiewicz Cc: Geert Uytterhoeven Cc: Nathan Chancellor Cc: Qiujun Huang Cc: Peter Rosin Cc: linux-fbdev@vger.kernel.org Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200624092910.3280448-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_fb_helper.c | 63 +++++++++++++++++++++++++++++++--------- drivers/video/fbdev/core/fbcon.c | 3 +- 2 files changed, 51 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 170aa7689110..5609e164805f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -227,18 +227,9 @@ int drm_fb_helper_debug_leave(struct fb_info *info) } EXPORT_SYMBOL(drm_fb_helper_debug_leave); -/** - * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration - * @fb_helper: driver-allocated fbdev helper, can be NULL - * - * This should be called from driver's drm &drm_driver.lastclose callback - * when implementing an fbcon on top of kms using this helper. This ensures that - * the user isn't greeted with a black screen when e.g. X dies. - * - * RETURNS: - * Zero if everything went ok, negative error code otherwise. - */ -int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) +static int +__drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper, + bool force) { bool do_delayed; int ret; @@ -250,7 +241,16 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) return 0; mutex_lock(&fb_helper->lock); - ret = drm_client_modeset_commit(&fb_helper->client); + if (force) { + /* + * Yes this is the _locked version which expects the master lock + * to be held. But for forced restores we're intentionally + * racing here, see drm_fb_helper_set_par(). + */ + ret = drm_client_modeset_commit_locked(&fb_helper->client); + } else { + ret = drm_client_modeset_commit(&fb_helper->client); + } do_delayed = fb_helper->delayed_hotplug; if (do_delayed) @@ -262,6 +262,22 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) return ret; } + +/** + * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration + * @fb_helper: driver-allocated fbdev helper, can be NULL + * + * This should be called from driver's drm &drm_driver.lastclose callback + * when implementing an fbcon on top of kms using this helper. This ensures that + * the user isn't greeted with a black screen when e.g. X dies. + * + * RETURNS: + * Zero if everything went ok, negative error code otherwise. + */ +int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) +{ + return __drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, false); +} EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked); #ifdef CONFIG_MAGIC_SYSRQ @@ -1318,6 +1334,7 @@ int drm_fb_helper_set_par(struct fb_info *info) { struct drm_fb_helper *fb_helper = info->par; struct fb_var_screeninfo *var = &info->var; + bool force; if (oops_in_progress) return -EBUSY; @@ -1327,7 +1344,25 @@ int drm_fb_helper_set_par(struct fb_info *info) return -EINVAL; } - drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); + /* + * Normally we want to make sure that a kms master takes precedence over + * fbdev, to avoid fbdev flickering and occasionally stealing the + * display status. But Xorg first sets the vt back to text mode using + * the KDSET IOCTL with KD_TEXT, and only after that drops the master + * status when exiting. + * + * In the past this was caught by drm_fb_helper_lastclose(), but on + * modern systems where logind always keeps a drm fd open to orchestrate + * the vt switching, this doesn't work. + * + * To not break the userspace ABI we have this special case here, which + * is only used for the above case. Everything else uses the normal + * commit function, which ensures that we never steal the display from + * an active drm master. + */ + force = var->activate & FB_ACTIVATE_KD_TEXT; + + __drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, force); return 0; } diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 9d28a8e3328f..e2a490c5ae08 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2402,7 +2402,8 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) ops->graphics = 1; if (!blank) { - var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; + var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE | + FB_ACTIVATE_KD_TEXT; fb_set_var(info, &var); ops->graphics = 0; ops->var = info->var; -- cgit v1.2.3 From edfaf6fa73f15568d4337f208b2333f647c35810 Mon Sep 17 00:00:00 2001 From: Wenhui Sheng Date: Thu, 18 Jun 2020 15:37:04 +0800 Subject: drm/amdgpu: add fw release for sdma v5_0 sdma fw isn't released when module exit Reviewed-by: Hawking Zhang Signed-off-by: Wenhui Sheng Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c index b544baf306f2..5d71c23e2640 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -1298,8 +1298,12 @@ static int sdma_v5_0_sw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; int i; - for (i = 0; i < adev->sdma.num_instances; i++) + for (i = 0; i < adev->sdma.num_instances; i++) { + if (adev->sdma.instance[i].fw != NULL) + release_firmware(adev->sdma.instance[i].fw); + amdgpu_ring_fini(&adev->sdma.instance[i].ring); + } return 0; } -- cgit v1.2.3 From 5ae9c378c3d88b40af72f8e8f961808e29f3e70b Mon Sep 17 00:00:00 2001 From: Stylon Wang Date: Mon, 1 Jun 2020 16:12:09 +0800 Subject: drm/amd/display: Enable output_bpc property on all outputs [Why] Connector property output_bpc is available on DP/eDP only. New IGT tests would benifit if this property works on HDMI. [How] Enable this read-only property on all types of connectors. Signed-off-by: Stylon Wang Reviewed-by: Nicholas Kazlauskas Acked-by: Rodrigo Siqueira Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 076af267b488..1d692f4f42f3 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -1058,7 +1058,6 @@ static const struct { {"link_settings", &dp_link_settings_debugfs_fops}, {"phy_settings", &dp_phy_settings_debugfs_fop}, {"test_pattern", &dp_phy_test_pattern_fops}, - {"output_bpc", &output_bpc_fops}, {"vrr_range", &vrr_range_fops}, #ifdef CONFIG_DRM_AMD_DC_HDCP {"hdcp_sink_capability", &hdcp_sink_capability_fops}, @@ -1142,6 +1141,9 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector, &force_yuv420_output_fops); + debugfs_create_file("output_bpc", 0644, dir, connector, + &output_bpc_fops); + connector->debugfs_dpcd_address = 0; connector->debugfs_dpcd_size = 0; -- cgit v1.2.3 From fa7041d9d2fc7401cece43f305eb5b87b7017fc4 Mon Sep 17 00:00:00 2001 From: Stylon Wang Date: Fri, 12 Jun 2020 19:04:18 +0800 Subject: drm/amd/display: Fix ineffective setting of max bpc property [Why] Regression was introduced where setting max bpc property has no effect on the atomic check and final commit. It has the same effect as max bpc being stuck at 8. [How] Correctly propagate max bpc with the new connector state. Signed-off-by: Stylon Wang Reviewed-by: Nicholas Kazlauskas Acked-by: Rodrigo Siqueira Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 7ced9f87be97..10ac8076d4f2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5024,7 +5024,8 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector, struct drm_connector *connector = &aconnector->base; struct amdgpu_device *adev = connector->dev->dev_private; struct dc_stream_state *stream; - int requested_bpc = connector->state ? connector->state->max_requested_bpc : 8; + const struct drm_connector_state *drm_state = dm_state ? &dm_state->base : NULL; + int requested_bpc = drm_state ? drm_state->max_requested_bpc : 8; enum dc_status dc_result = DC_OK; do { -- cgit v1.2.3 From b5b78a6c8d8cb9c307bc6b16a754603424459d6e Mon Sep 17 00:00:00 2001 From: Bernard Zhao Date: Sat, 20 Jun 2020 17:11:52 +0800 Subject: drm/amd: fix potential memleak in err branch The function kobject_init_and_add alloc memory like: kobject_init_and_add->kobject_add_varg->kobject_set_name_vargs ->kvasprintf_const->kstrdup_const->kstrdup->kmalloc_track_caller ->kmalloc_slab, in err branch this memory not free. If use kmemleak, this path maybe catched. These changes are to add kobject_put in kobject_init_and_add failed branch, fix potential memleak. Signed-off-by: Bernard Zhao Reviewed-by: Felix Kuehling Signed-off-by: Felix Kuehling Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index d27221ddcdeb..0e0c42e9f6a3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -428,6 +428,7 @@ struct kfd_process *kfd_create_process(struct file *filep) (int)process->lead_thread->pid); if (ret) { pr_warn("Creating procfs pid directory failed"); + kobject_put(process->kobj); goto out; } -- cgit v1.2.3