Skip to content

Commit ab5f9eb

Browse files
committed
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "This contains fixes for exynos, amdgpu, radeon, i915 and qxl. It also contains some fixes to the core drm edid parser. qxl: - fix for a cursor hotspot issue radeon: - some MST fixes that I've been running locally and make my monitor a bit happier exynos: - fix some regressions and build fixes amdgpu: - a couple of small fixes i915: - two DP MST fixes and a couple of other regression fixes Nothing too out of the ordinary or surprising at this point" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/exynos: Use VIDEO_SAMSUNG_S5P_G2D=n as G2D Kconfig dependency drm/exynos: fix a warning message drm/exynos: mic: fix an error code drm/exynos: fimd: fix broken dp_clock control drm/exynos: build fbdev code conditionally drm/exynos: fix adjusted_mode pointer in exynos_plane_mode_set drm/exynos: fix error handling in exynos_drm_subdrv_open drm/amd/amdgpu: fix irq domain remove for tonga ih drm/i915: fix deadlock on lid open drm/radeon: use helper for mst connector dpms. drm/radeon/mst: port some MST setup code from DAL. drm/amdgpu: add invisible pin size statistic drm/edid: Fix DMT 1024x768@43Hz (interlaced) timings drm/i915: Exit cherryview_irq_handler() after one pass drm/i915: Call intel_dp_mst_resume() before resuming displays drm/i915: Fix race condition in intel_dp_destroy_mst_connector() drm/edid: Fix parsing of EDID 1.4 Established Timings III descriptor drm/edid: Fix EDID Established Timings I and II drm/qxl: fix cursor position with non-zero hotspot
2 parents 60ea7bb + ff3e84e commit ab5f9eb

22 files changed

+104
-62
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,6 +2034,7 @@ struct amdgpu_device {
20342034

20352035
/* tracking pinned memory */
20362036
u64 vram_pin_size;
2037+
u64 invisible_pin_size;
20372038
u64 gart_pin_size;
20382039

20392040
/* amdkfd interface */

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
384384
vram_gtt.vram_size = adev->mc.real_vram_size;
385385
vram_gtt.vram_size -= adev->vram_pin_size;
386386
vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size;
387-
vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size;
387+
vram_gtt.vram_cpu_accessible_size -= (adev->vram_pin_size - adev->invisible_pin_size);
388388
vram_gtt.gtt_size = adev->mc.gtt_size;
389389
vram_gtt.gtt_size -= adev->gart_pin_size;
390390
return copy_to_user(out, &vram_gtt,

drivers/gpu/drm/amd/amdgpu/amdgpu_object.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
424424
bo->pin_count = 1;
425425
if (gpu_addr != NULL)
426426
*gpu_addr = amdgpu_bo_gpu_offset(bo);
427-
if (domain == AMDGPU_GEM_DOMAIN_VRAM)
427+
if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
428428
bo->adev->vram_pin_size += amdgpu_bo_size(bo);
429-
else
429+
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
430+
bo->adev->invisible_pin_size += amdgpu_bo_size(bo);
431+
} else
430432
bo->adev->gart_pin_size += amdgpu_bo_size(bo);
431433
} else {
432434
dev_err(bo->adev->dev, "%p pin failed\n", bo);
@@ -456,9 +458,11 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo)
456458
}
457459
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
458460
if (likely(r == 0)) {
459-
if (bo->tbo.mem.mem_type == TTM_PL_VRAM)
461+
if (bo->tbo.mem.mem_type == TTM_PL_VRAM) {
460462
bo->adev->vram_pin_size -= amdgpu_bo_size(bo);
461-
else
463+
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
464+
bo->adev->invisible_pin_size -= amdgpu_bo_size(bo);
465+
} else
462466
bo->adev->gart_pin_size -= amdgpu_bo_size(bo);
463467
} else {
464468
dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo);

drivers/gpu/drm/amd/amdgpu/tonga_ih.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ static int tonga_ih_sw_fini(void *handle)
307307

308308
amdgpu_irq_fini(adev);
309309
amdgpu_ih_ring_fini(adev);
310-
amdgpu_irq_add_domain(adev);
310+
amdgpu_irq_remove_domain(adev);
311311

312312
return 0;
313313
}

drivers/gpu/drm/drm_edid.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ static const struct drm_display_mode drm_dmt_modes[] = {
205205
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
206206
/* 0x0f - 1024x768@43Hz, interlace */
207207
{ DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
208-
1208, 1264, 0, 768, 768, 772, 817, 0,
208+
1208, 1264, 0, 768, 768, 776, 817, 0,
209209
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
210210
DRM_MODE_FLAG_INTERLACE) },
211211
/* 0x10 - 1024x768@60Hz */
@@ -522,12 +522,12 @@ static const struct drm_display_mode edid_est_modes[] = {
522522
720, 840, 0, 480, 481, 484, 500, 0,
523523
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
524524
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
525-
704, 832, 0, 480, 489, 491, 520, 0,
525+
704, 832, 0, 480, 489, 492, 520, 0,
526526
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
527527
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
528528
768, 864, 0, 480, 483, 486, 525, 0,
529529
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
530-
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
530+
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
531531
752, 800, 0, 480, 490, 492, 525, 0,
532532
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
533533
{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
@@ -539,7 +539,7 @@ static const struct drm_display_mode edid_est_modes[] = {
539539
{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
540540
1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
541541
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
542-
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
542+
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
543543
1136, 1312, 0, 768, 769, 772, 800, 0,
544544
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
545545
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
@@ -2241,7 +2241,7 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing)
22412241
{
22422242
int i, j, m, modes = 0;
22432243
struct drm_display_mode *mode;
2244-
u8 *est = ((u8 *)timing) + 5;
2244+
u8 *est = ((u8 *)timing) + 6;
22452245

22462246
for (i = 0; i < 6; i++) {
22472247
for (j = 7; j >= 0; j--) {

drivers/gpu/drm/exynos/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ comment "Sub-drivers"
9494

9595
config DRM_EXYNOS_G2D
9696
bool "G2D"
97-
depends on !VIDEO_SAMSUNG_S5P_G2D
97+
depends on VIDEO_SAMSUNG_S5P_G2D=n
9898
select FRAME_VECTOR
9999
help
100100
Choose this option if you want to use Exynos G2D for DRM.

drivers/gpu/drm/exynos/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
# Makefile for the drm device driver. This driver provides support for the
33
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
44

5-
exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \
6-
exynos_drm_fb.o exynos_drm_gem.o exynos_drm_core.o \
7-
exynos_drm_plane.o
5+
exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \
6+
exynos_drm_gem.o exynos_drm_core.o exynos_drm_plane.o
87

8+
exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o
99
exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
1010
exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
1111
exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o

drivers/gpu/drm/exynos/exynos_drm_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
101101
return 0;
102102

103103
err:
104-
list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
104+
list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) {
105105
if (subdrv->close)
106106
subdrv->close(dev, subdrv->dev, file);
107107
}

drivers/gpu/drm/exynos/exynos_drm_fb.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,6 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
199199
return exynos_fb->dma_addr[index];
200200
}
201201

202-
static void exynos_drm_output_poll_changed(struct drm_device *dev)
203-
{
204-
struct exynos_drm_private *private = dev->dev_private;
205-
struct drm_fb_helper *fb_helper = private->fb_helper;
206-
207-
if (fb_helper)
208-
drm_fb_helper_hotplug_event(fb_helper);
209-
else
210-
exynos_drm_fbdev_init(dev);
211-
}
212-
213202
static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
214203
.fb_create = exynos_user_fb_create,
215204
.output_poll_changed = exynos_drm_output_poll_changed,

drivers/gpu/drm/exynos/exynos_drm_fbdev.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,3 +317,14 @@ void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
317317

318318
drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper);
319319
}
320+
321+
void exynos_drm_output_poll_changed(struct drm_device *dev)
322+
{
323+
struct exynos_drm_private *private = dev->dev_private;
324+
struct drm_fb_helper *fb_helper = private->fb_helper;
325+
326+
if (fb_helper)
327+
drm_fb_helper_hotplug_event(fb_helper);
328+
else
329+
exynos_drm_fbdev_init(dev);
330+
}

drivers/gpu/drm/exynos/exynos_drm_fbdev.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,30 @@
1515
#ifndef _EXYNOS_DRM_FBDEV_H_
1616
#define _EXYNOS_DRM_FBDEV_H_
1717

18+
#ifdef CONFIG_DRM_FBDEV_EMULATION
19+
1820
int exynos_drm_fbdev_init(struct drm_device *dev);
19-
int exynos_drm_fbdev_reinit(struct drm_device *dev);
2021
void exynos_drm_fbdev_fini(struct drm_device *dev);
2122
void exynos_drm_fbdev_restore_mode(struct drm_device *dev);
23+
void exynos_drm_output_poll_changed(struct drm_device *dev);
24+
25+
#else
26+
27+
static inline int exynos_drm_fbdev_init(struct drm_device *dev)
28+
{
29+
return 0;
30+
}
31+
32+
static inline void exynos_drm_fbdev_fini(struct drm_device *dev)
33+
{
34+
}
35+
36+
static inline void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
37+
{
38+
}
39+
40+
#define exynos_drm_output_poll_changed (NULL)
41+
42+
#endif
2243

2344
#endif

drivers/gpu/drm/exynos/exynos_drm_fimd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@ static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable)
888888
* clock. On these SoCs the bootloader may enable it but any
889889
* power domain off/on will reset it to disable state.
890890
*/
891-
if (ctx->driver_data != &exynos5_fimd_driver_data ||
891+
if (ctx->driver_data != &exynos5_fimd_driver_data &&
892892
ctx->driver_data != &exynos5420_fimd_driver_data)
893893
return;
894894

drivers/gpu/drm/exynos/exynos_drm_mic.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ static void mic_set_path(struct exynos_mic *mic, bool enable)
129129
} else
130130
val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX);
131131

132-
regmap_write(mic->sysreg, DSD_CFG_MUX, val);
132+
ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val);
133133
if (ret)
134134
DRM_ERROR("mic: Failed to read system register\n");
135135
}
@@ -457,6 +457,7 @@ static int exynos_mic_probe(struct platform_device *pdev)
457457
"samsung,disp-syscon");
458458
if (IS_ERR(mic->sysreg)) {
459459
DRM_ERROR("mic: Failed to get system register.\n");
460+
ret = PTR_ERR(mic->sysreg);
460461
goto err;
461462
}
462463

drivers/gpu/drm/exynos/exynos_drm_plane.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111

1212
#include <drm/drmP.h>
1313

14-
#include <drm/exynos_drm.h>
15-
#include <drm/drm_plane_helper.h>
14+
#include <drm/drm_atomic.h>
1615
#include <drm/drm_atomic_helper.h>
16+
#include <drm/drm_plane_helper.h>
17+
#include <drm/exynos_drm.h>
1718
#include "exynos_drm_drv.h"
1819
#include "exynos_drm_crtc.h"
1920
#include "exynos_drm_fb.h"
@@ -57,11 +58,12 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
5758
}
5859

5960
static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
60-
6161
{
6262
struct drm_plane_state *state = &exynos_state->base;
63-
struct drm_crtc *crtc = exynos_state->base.crtc;
64-
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
63+
struct drm_crtc *crtc = state->crtc;
64+
struct drm_crtc_state *crtc_state =
65+
drm_atomic_get_existing_crtc_state(state->state, crtc);
66+
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
6567
int crtc_x, crtc_y;
6668
unsigned int crtc_w, crtc_h;
6769
unsigned int src_x, src_y;

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,10 +758,10 @@ static int i915_drm_resume(struct drm_device *dev)
758758
dev_priv->display.hpd_irq_setup(dev);
759759
spin_unlock_irq(&dev_priv->irq_lock);
760760

761-
intel_display_resume(dev);
762-
763761
intel_dp_mst_resume(dev);
764762

763+
intel_display_resume(dev);
764+
765765
/*
766766
* ... but also need to make sure that hotplug processing
767767
* doesn't cause havoc. Like in the driver load code we don't

drivers/gpu/drm/i915/i915_irq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,7 +1829,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
18291829
/* IRQs are synced during runtime_suspend, we don't require a wakeref */
18301830
disable_rpm_wakeref_asserts(dev_priv);
18311831

1832-
for (;;) {
1832+
do {
18331833
master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
18341834
iir = I915_READ(VLV_IIR);
18351835

@@ -1857,7 +1857,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
18571857

18581858
I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL);
18591859
POSTING_READ(GEN8_MASTER_IRQ);
1860-
}
1860+
} while (0);
18611861

18621862
enable_rpm_wakeref_asserts(dev_priv);
18631863

drivers/gpu/drm/i915/intel_dp_mst.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,8 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
506506
struct intel_connector *intel_connector = to_intel_connector(connector);
507507
struct drm_device *dev = connector->dev;
508508

509+
intel_connector->unregister(intel_connector);
510+
509511
/* need to nuke the connector */
510512
drm_modeset_lock_all(dev);
511513
if (connector->state->crtc) {
@@ -519,11 +521,7 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
519521

520522
WARN(ret, "Disabling mst crtc failed with %i\n", ret);
521523
}
522-
drm_modeset_unlock_all(dev);
523524

524-
intel_connector->unregister(intel_connector);
525-
526-
drm_modeset_lock_all(dev);
527525
intel_connector_remove_from_fbdev(intel_connector);
528526
drm_connector_cleanup(connector);
529527
drm_modeset_unlock_all(dev);

drivers/gpu/drm/i915/intel_lvds.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,8 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
478478
* and as part of the cleanup in the hw state restore we also redisable
479479
* the vga plane.
480480
*/
481-
if (!HAS_PCH_SPLIT(dev)) {
482-
drm_modeset_lock_all(dev);
481+
if (!HAS_PCH_SPLIT(dev))
483482
intel_display_resume(dev);
484-
drm_modeset_unlock_all(dev);
485-
}
486483

487484
dev_priv->modeset_restore = MODESET_DONE;
488485

drivers/gpu/drm/qxl/qxl_display.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,15 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
375375

376376
qxl_bo_kunmap(user_bo);
377377

378+
qcrtc->cur_x += qcrtc->hot_spot_x - hot_x;
379+
qcrtc->cur_y += qcrtc->hot_spot_y - hot_y;
380+
qcrtc->hot_spot_x = hot_x;
381+
qcrtc->hot_spot_y = hot_y;
382+
378383
cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
379384
cmd->type = QXL_CURSOR_SET;
380-
cmd->u.set.position.x = qcrtc->cur_x;
381-
cmd->u.set.position.y = qcrtc->cur_y;
385+
cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
386+
cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
382387

383388
cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0);
384389

@@ -441,8 +446,8 @@ static int qxl_crtc_cursor_move(struct drm_crtc *crtc,
441446

442447
cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
443448
cmd->type = QXL_CURSOR_MOVE;
444-
cmd->u.position.x = qcrtc->cur_x;
445-
cmd->u.position.y = qcrtc->cur_y;
449+
cmd->u.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
450+
cmd->u.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
446451
qxl_release_unmap(qdev, release, &cmd->release_info);
447452

448453
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);

drivers/gpu/drm/qxl/qxl_drv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ struct qxl_crtc {
135135
int index;
136136
int cur_x;
137137
int cur_y;
138+
int hot_spot_x;
139+
int hot_spot_y;
138140
};
139141

140142
struct qxl_output {

drivers/gpu/drm/radeon/ni_reg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@
109109
#define NI_DP_MSE_SAT2 0x7398
110110

111111
#define NI_DP_MSE_SAT_UPDATE 0x739c
112+
# define NI_DP_MSE_SAT_UPDATE_MASK 0x3
113+
# define NI_DP_MSE_16_MTP_KEEPOUT 0x100
112114

113115
#define NI_DIG_BE_CNTL 0x7140
114116
# define NI_DIG_FE_SOURCE_SELECT(x) (((x) & 0x7f) << 8)

0 commit comments

Comments
 (0)