Commit be48306f authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-fixes-2023-08-17' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

One EPROBE_DEFER handling fix for the JDI LT070ME05000, a timing fix for
the AUO G121EAN01 panel, an integer overflow and a memory leak fixes for
the qaic accel, a use-after-free fix for nouveau and a revert for an
alleged fix in EDID parsing.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/3olqt33em5uhxzjbqghwcwnvmw73h7bxkbdxookmnkecymd4vc@7ogm6gewpprq
parents dd64d8ae 50b6f2c8
...@@ -392,18 +392,31 @@ static int find_and_map_user_pages(struct qaic_device *qdev, ...@@ -392,18 +392,31 @@ static int find_and_map_user_pages(struct qaic_device *qdev,
struct qaic_manage_trans_dma_xfer *in_trans, struct qaic_manage_trans_dma_xfer *in_trans,
struct ioctl_resources *resources, struct dma_xfer *xfer) struct ioctl_resources *resources, struct dma_xfer *xfer)
{ {
u64 xfer_start_addr, remaining, end, total;
unsigned long need_pages; unsigned long need_pages;
struct page **page_list; struct page **page_list;
unsigned long nr_pages; unsigned long nr_pages;
struct sg_table *sgt; struct sg_table *sgt;
u64 xfer_start_addr;
int ret; int ret;
int i; int i;
xfer_start_addr = in_trans->addr + resources->xferred_dma_size; if (check_add_overflow(in_trans->addr, resources->xferred_dma_size, &xfer_start_addr))
return -EINVAL;
need_pages = DIV_ROUND_UP(in_trans->size + offset_in_page(xfer_start_addr) - if (in_trans->size < resources->xferred_dma_size)
resources->xferred_dma_size, PAGE_SIZE); return -EINVAL;
remaining = in_trans->size - resources->xferred_dma_size;
if (remaining == 0)
return 0;
if (check_add_overflow(xfer_start_addr, remaining, &end))
return -EINVAL;
total = remaining + offset_in_page(xfer_start_addr);
if (total >= SIZE_MAX)
return -EINVAL;
need_pages = DIV_ROUND_UP(total, PAGE_SIZE);
nr_pages = need_pages; nr_pages = need_pages;
...@@ -435,7 +448,7 @@ static int find_and_map_user_pages(struct qaic_device *qdev, ...@@ -435,7 +448,7 @@ static int find_and_map_user_pages(struct qaic_device *qdev,
ret = sg_alloc_table_from_pages(sgt, page_list, nr_pages, ret = sg_alloc_table_from_pages(sgt, page_list, nr_pages,
offset_in_page(xfer_start_addr), offset_in_page(xfer_start_addr),
in_trans->size - resources->xferred_dma_size, GFP_KERNEL); remaining, GFP_KERNEL);
if (ret) { if (ret) {
ret = -ENOMEM; ret = -ENOMEM;
goto free_sgt; goto free_sgt;
...@@ -566,9 +579,6 @@ static int encode_dma(struct qaic_device *qdev, void *trans, struct wrapper_list ...@@ -566,9 +579,6 @@ static int encode_dma(struct qaic_device *qdev, void *trans, struct wrapper_list
QAIC_MANAGE_EXT_MSG_LENGTH) QAIC_MANAGE_EXT_MSG_LENGTH)
return -ENOMEM; return -ENOMEM;
if (in_trans->addr + in_trans->size < in_trans->addr || !in_trans->size)
return -EINVAL;
xfer = kmalloc(sizeof(*xfer), GFP_KERNEL); xfer = kmalloc(sizeof(*xfer), GFP_KERNEL);
if (!xfer) if (!xfer)
return -ENOMEM; return -ENOMEM;
......
...@@ -1021,6 +1021,7 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi ...@@ -1021,6 +1021,7 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
bo->dbc = dbc; bo->dbc = dbc;
srcu_read_unlock(&dbc->ch_lock, rcu_id); srcu_read_unlock(&dbc->ch_lock, rcu_id);
drm_gem_object_put(obj); drm_gem_object_put(obj);
kfree(slice_ent);
srcu_read_unlock(&qdev->dev_lock, qdev_rcu_id); srcu_read_unlock(&qdev->dev_lock, qdev_rcu_id);
srcu_read_unlock(&usr->qddev_lock, usr_rcu_id); srcu_read_unlock(&usr->qddev_lock, usr_rcu_id);
......
...@@ -3456,6 +3456,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto ...@@ -3456,6 +3456,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto
connector->base.id, connector->name); connector->base.id, connector->name);
return NULL; return NULL;
} }
if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Composite sync not supported\n",
connector->base.id, connector->name);
}
/* it is incorrect if hsync/vsync width is zero */ /* it is incorrect if hsync/vsync width is zero */
if (!hsync_pulse_width || !vsync_pulse_width) { if (!hsync_pulse_width || !vsync_pulse_width) {
...@@ -3502,27 +3506,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto ...@@ -3502,27 +3506,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto
if (info->quirks & EDID_QUIRK_DETAILED_SYNC_PP) { if (info->quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
mode->flags |= DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC; mode->flags |= DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC;
} else { } else {
switch (pt->misc & DRM_EDID_PT_SYNC_MASK) { mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
case DRM_EDID_PT_ANALOG_CSYNC: DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
case DRM_EDID_PT_BIPOLAR_ANALOG_CSYNC: mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Analog composite sync!\n", DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
connector->base.id, connector->name);
mode->flags |= DRM_MODE_FLAG_CSYNC | DRM_MODE_FLAG_NCSYNC;
break;
case DRM_EDID_PT_DIGITAL_CSYNC:
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Digital composite sync!\n",
connector->base.id, connector->name);
mode->flags |= DRM_MODE_FLAG_CSYNC;
mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
DRM_MODE_FLAG_PCSYNC : DRM_MODE_FLAG_NCSYNC;
break;
case DRM_EDID_PT_DIGITAL_SEPARATE_SYNC:
mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
break;
}
} }
set_size: set_size:
......
...@@ -1408,8 +1408,7 @@ nouveau_connector_create(struct drm_device *dev, ...@@ -1408,8 +1408,7 @@ nouveau_connector_create(struct drm_device *dev,
ret = nvif_conn_ctor(&disp->disp, nv_connector->base.name, nv_connector->index, ret = nvif_conn_ctor(&disp->disp, nv_connector->base.name, nv_connector->index,
&nv_connector->conn); &nv_connector->conn);
if (ret) { if (ret) {
kfree(nv_connector); goto drm_conn_err;
return ERR_PTR(ret);
} }
ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsHotplug", ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsHotplug",
...@@ -1426,8 +1425,7 @@ nouveau_connector_create(struct drm_device *dev, ...@@ -1426,8 +1425,7 @@ nouveau_connector_create(struct drm_device *dev,
if (ret) { if (ret) {
nvif_event_dtor(&nv_connector->hpd); nvif_event_dtor(&nv_connector->hpd);
nvif_conn_dtor(&nv_connector->conn); nvif_conn_dtor(&nv_connector->conn);
kfree(nv_connector); goto drm_conn_err;
return ERR_PTR(ret);
} }
} }
} }
...@@ -1475,4 +1473,9 @@ nouveau_connector_create(struct drm_device *dev, ...@@ -1475,4 +1473,9 @@ nouveau_connector_create(struct drm_device *dev,
drm_connector_register(connector); drm_connector_register(connector);
return connector; return connector;
drm_conn_err:
drm_connector_cleanup(connector);
kfree(nv_connector);
return ERR_PTR(ret);
} }
...@@ -404,38 +404,30 @@ static int jdi_panel_add(struct jdi_panel *jdi) ...@@ -404,38 +404,30 @@ static int jdi_panel_add(struct jdi_panel *jdi)
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(jdi->supplies), ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(jdi->supplies),
jdi->supplies); jdi->supplies);
if (ret < 0) { if (ret < 0)
dev_err(dev, "failed to init regulator, ret=%d\n", ret); return dev_err_probe(dev, ret,
return ret; "failed to init regulator, ret=%d\n", ret);
}
jdi->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); jdi->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(jdi->enable_gpio)) { if (IS_ERR(jdi->enable_gpio)) {
ret = PTR_ERR(jdi->enable_gpio); return dev_err_probe(dev, PTR_ERR(jdi->enable_gpio),
dev_err(dev, "cannot get enable-gpio %d\n", ret); "cannot get enable-gpio %d\n", ret);
return ret;
} }
jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(jdi->reset_gpio)) { if (IS_ERR(jdi->reset_gpio))
ret = PTR_ERR(jdi->reset_gpio); return dev_err_probe(dev, PTR_ERR(jdi->reset_gpio),
dev_err(dev, "cannot get reset-gpios %d\n", ret); "cannot get reset-gpios %d\n", ret);
return ret;
}
jdi->dcdc_en_gpio = devm_gpiod_get(dev, "dcdc-en", GPIOD_OUT_LOW); jdi->dcdc_en_gpio = devm_gpiod_get(dev, "dcdc-en", GPIOD_OUT_LOW);
if (IS_ERR(jdi->dcdc_en_gpio)) { if (IS_ERR(jdi->dcdc_en_gpio))
ret = PTR_ERR(jdi->dcdc_en_gpio); return dev_err_probe(dev, PTR_ERR(jdi->dcdc_en_gpio),
dev_err(dev, "cannot get dcdc-en-gpio %d\n", ret); "cannot get dcdc-en-gpio %d\n", ret);
return ret;
}
jdi->backlight = drm_panel_create_dsi_backlight(jdi->dsi); jdi->backlight = drm_panel_create_dsi_backlight(jdi->dsi);
if (IS_ERR(jdi->backlight)) { if (IS_ERR(jdi->backlight))
ret = PTR_ERR(jdi->backlight); return dev_err_probe(dev, PTR_ERR(jdi->backlight),
dev_err(dev, "failed to register backlight %d\n", ret); "failed to register backlight %d\n", ret);
return ret;
}
drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs, drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs,
DRM_MODE_CONNECTOR_DSI); DRM_MODE_CONNECTOR_DSI);
......
...@@ -999,21 +999,21 @@ static const struct panel_desc auo_g104sn02 = { ...@@ -999,21 +999,21 @@ static const struct panel_desc auo_g104sn02 = {
.connector_type = DRM_MODE_CONNECTOR_LVDS, .connector_type = DRM_MODE_CONNECTOR_LVDS,
}; };
static const struct drm_display_mode auo_g121ean01_mode = { static const struct display_timing auo_g121ean01_timing = {
.clock = 66700, .pixelclock = { 60000000, 74400000, 90000000 },
.hdisplay = 1280, .hactive = { 1280, 1280, 1280 },
.hsync_start = 1280 + 58, .hfront_porch = { 20, 50, 100 },
.hsync_end = 1280 + 58 + 8, .hback_porch = { 20, 50, 100 },
.htotal = 1280 + 58 + 8 + 70, .hsync_len = { 30, 100, 200 },
.vdisplay = 800, .vactive = { 800, 800, 800 },
.vsync_start = 800 + 6, .vfront_porch = { 2, 10, 25 },
.vsync_end = 800 + 6 + 4, .vback_porch = { 2, 10, 25 },
.vtotal = 800 + 6 + 4 + 10, .vsync_len = { 4, 18, 50 },
}; };
static const struct panel_desc auo_g121ean01 = { static const struct panel_desc auo_g121ean01 = {
.modes = &auo_g121ean01_mode, .timings = &auo_g121ean01_timing,
.num_modes = 1, .num_timings = 1,
.bpc = 8, .bpc = 8,
.size = { .size = {
.width = 261, .width = 261,
......
...@@ -61,15 +61,9 @@ struct std_timing { ...@@ -61,15 +61,9 @@ struct std_timing {
u8 vfreq_aspect; u8 vfreq_aspect;
} __attribute__((packed)); } __attribute__((packed));
#define DRM_EDID_PT_SYNC_MASK (3 << 3) #define DRM_EDID_PT_HSYNC_POSITIVE (1 << 1)
# define DRM_EDID_PT_ANALOG_CSYNC (0 << 3) #define DRM_EDID_PT_VSYNC_POSITIVE (1 << 2)
# define DRM_EDID_PT_BIPOLAR_ANALOG_CSYNC (1 << 3) #define DRM_EDID_PT_SEPARATE_SYNC (3 << 3)
# define DRM_EDID_PT_DIGITAL_CSYNC (2 << 3)
# define DRM_EDID_PT_CSYNC_ON_RGB (1 << 1) /* analog csync only */
# define DRM_EDID_PT_CSYNC_SERRATE (1 << 2)
# define DRM_EDID_PT_DIGITAL_SEPARATE_SYNC (3 << 3)
# define DRM_EDID_PT_HSYNC_POSITIVE (1 << 1) /* also digital csync */
# define DRM_EDID_PT_VSYNC_POSITIVE (1 << 2)
#define DRM_EDID_PT_STEREO (1 << 5) #define DRM_EDID_PT_STEREO (1 << 5)
#define DRM_EDID_PT_INTERLACED (1 << 7) #define DRM_EDID_PT_INTERLACED (1 << 7)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment