Commit 6e1f415e authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-next-2024-04-10' of...

Merge tag 'drm-misc-next-2024-04-10' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for v6.10:

Cross-subsystem Changes:
- Add Tomi as Xilinx maintainer.
- Add sound bindings to DT.

Core Changes:
- Make DP helper depend on KMS helper.

Driver Changes:
- Assorted small fixes to bridge/dw-hdmi, bridge/cdns-mhdp8456, xlnx,
  omap, tilcdc, bridge/imx8mp-hdmi-pvi.
- Add debugfs entries to qaic.
- Add conservative fallback to panel eDP.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/dc690de5-17da-4af6-93a9-8078c99245fd@linux.intel.com
parents 1f913730 29b39672
......@@ -9,6 +9,9 @@ title: ITE it6505
maintainers:
- Allen Chen <allen.chen@ite.com.tw>
allOf:
- $ref: /schemas/sound/dai-common.yaml#
description: |
The IT6505 is a high-performance DisplayPort 1.1a transmitter,
fully compliant with DisplayPort 1.1a, HDCP 1.3 specifications.
......@@ -52,6 +55,9 @@ properties:
maxItems: 1
description: extcon specifier for the Power Delivery
"#sound-dai-cells":
const: 0
ports:
$ref: /schemas/graph.yaml#/properties/ports
......@@ -105,7 +111,7 @@ required:
- extcon
- ports
additionalProperties: false
unevaluatedProperties: false
examples:
- |
......
......@@ -7380,6 +7380,7 @@ F: drivers/gpu/drm/xen/
DRM DRIVERS FOR XILINX
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
M: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
......
......@@ -11,3 +11,5 @@ qaic-y := \
qaic_data.o \
qaic_drv.o \
qaic_timesync.o
qaic-$(CONFIG_DEBUG_FS) += qaic_debugfs.o
......@@ -153,6 +153,14 @@ struct qaic_device {
struct mhi_device *qts_ch;
/* Work queue for tasks related to MHI "QAIC_TIMESYNC" channel */
struct workqueue_struct *qts_wq;
/* Head of list of page allocated by MHI bootlog device */
struct list_head bootlog;
/* MHI bootlog channel device */
struct mhi_device *bootlog_ch;
/* Work queue for tasks related to MHI bootlog device */
struct workqueue_struct *bootlog_wq;
/* Synchronizes access of pages in MHI bootlog device */
struct mutex bootlog_mutex;
};
struct qaic_drm_device {
......@@ -280,6 +288,7 @@ int disable_dbc(struct qaic_device *qdev, u32 dbc_id, struct qaic_user *usr);
void enable_dbc(struct qaic_device *qdev, u32 dbc_id, struct qaic_user *usr);
void wakeup_dbc(struct qaic_device *qdev, u32 dbc_id);
void release_dbc(struct qaic_device *qdev, u32 dbc_id);
void qaic_data_get_fifo_info(struct dma_bridge_chan *dbc, u32 *head, u32 *tail);
void wake_all_cntl(struct qaic_device *qdev);
void qaic_dev_reset_clean_local_state(struct qaic_device *qdev);
......
......@@ -1981,3 +1981,12 @@ void release_dbc(struct qaic_device *qdev, u32 dbc_id)
dbc->in_use = false;
wake_up(&dbc->dbc_release);
}
void qaic_data_get_fifo_info(struct dma_bridge_chan *dbc, u32 *head, u32 *tail)
{
if (!dbc || !head || !tail)
return;
*head = readl(dbc->dbc_base + REQHP_OFF);
*tail = readl(dbc->dbc_base + REQTP_OFF);
}
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2020, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. */
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/mhi.h>
#include <linux/mutex.h>
#include <linux/overflow.h>
#include <linux/pci.h>
#include <linux/seq_file.h>
#include <linux/sprintf.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include "qaic.h"
#include "qaic_debugfs.h"
#define BOOTLOG_POOL_SIZE 16
#define BOOTLOG_MSG_SIZE 512
#define QAIC_DBC_DIR_NAME 9
struct bootlog_msg {
/* Buffer for bootlog messages */
char str[BOOTLOG_MSG_SIZE];
/* Root struct of device, used to access device resources */
struct qaic_device *qdev;
/* Work struct to schedule work coming on QAIC_LOGGING channel */
struct work_struct work;
};
struct bootlog_page {
/* Node in list of bootlog pages maintained by root device struct */
struct list_head node;
/* Total size of the buffer that holds the bootlogs. It is PAGE_SIZE */
unsigned int size;
/* Offset for the next bootlog */
unsigned int offset;
};
static int bootlog_show(struct seq_file *s, void *unused)
{
struct bootlog_page *page;
struct qaic_device *qdev;
void *page_end;
void *log;
qdev = s->private;
mutex_lock(&qdev->bootlog_mutex);
list_for_each_entry(page, &qdev->bootlog, node) {
log = page + 1;
page_end = (void *)page + page->offset;
while (log < page_end) {
seq_printf(s, "%s", (char *)log);
log += strlen(log) + 1;
}
}
mutex_unlock(&qdev->bootlog_mutex);
return 0;
}
static int bootlog_fops_open(struct inode *inode, struct file *file)
{
return single_open(file, bootlog_show, inode->i_private);
}
static const struct file_operations bootlog_fops = {
.owner = THIS_MODULE,
.open = bootlog_fops_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int read_dbc_fifo_size(struct seq_file *s, void *unused)
{
struct dma_bridge_chan *dbc = s->private;
seq_printf(s, "%u\n", dbc->nelem);
return 0;
}
static int fifo_size_open(struct inode *inode, struct file *file)
{
return single_open(file, read_dbc_fifo_size, inode->i_private);
}
static const struct file_operations fifo_size_fops = {
.owner = THIS_MODULE,
.open = fifo_size_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int read_dbc_queued(struct seq_file *s, void *unused)
{
struct dma_bridge_chan *dbc = s->private;
u32 tail = 0, head = 0;
qaic_data_get_fifo_info(dbc, &head, &tail);
if (head == U32_MAX || tail == U32_MAX)
seq_printf(s, "%u\n", 0);
else if (head > tail)
seq_printf(s, "%u\n", dbc->nelem - head + tail);
else
seq_printf(s, "%u\n", tail - head);
return 0;
}
static int queued_open(struct inode *inode, struct file *file)
{
return single_open(file, read_dbc_queued, inode->i_private);
}
static const struct file_operations queued_fops = {
.owner = THIS_MODULE,
.open = queued_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
void qaic_debugfs_init(struct qaic_drm_device *qddev)
{
struct qaic_device *qdev = qddev->qdev;
struct dentry *debugfs_root;
struct dentry *debugfs_dir;
char name[QAIC_DBC_DIR_NAME];
u32 i;
debugfs_root = to_drm(qddev)->debugfs_root;
debugfs_create_file("bootlog", 0400, debugfs_root, qdev, &bootlog_fops);
/*
* 256 dbcs per device is likely the max we will ever see and lets static checking see a
* reasonable range.
*/
for (i = 0; i < qdev->num_dbc && i < 256; ++i) {
snprintf(name, QAIC_DBC_DIR_NAME, "dbc%03u", i);
debugfs_dir = debugfs_create_dir(name, debugfs_root);
debugfs_create_file("fifo_size", 0400, debugfs_dir, &qdev->dbc[i], &fifo_size_fops);
debugfs_create_file("queued", 0400, debugfs_dir, &qdev->dbc[i], &queued_fops);
}
}
static struct bootlog_page *alloc_bootlog_page(struct qaic_device *qdev)
{
struct bootlog_page *page;
page = (struct bootlog_page *)devm_get_free_pages(&qdev->pdev->dev, GFP_KERNEL, 0);
if (!page)
return page;
page->size = PAGE_SIZE;
page->offset = sizeof(*page);
list_add_tail(&page->node, &qdev->bootlog);
return page;
}
static int reset_bootlog(struct qaic_device *qdev)
{
struct bootlog_page *page;
struct bootlog_page *i;
mutex_lock(&qdev->bootlog_mutex);
list_for_each_entry_safe(page, i, &qdev->bootlog, node) {
list_del(&page->node);
devm_free_pages(&qdev->pdev->dev, (unsigned long)page);
}
page = alloc_bootlog_page(qdev);
mutex_unlock(&qdev->bootlog_mutex);
if (!page)
return -ENOMEM;
return 0;
}
static void *bootlog_get_space(struct qaic_device *qdev, unsigned int size)
{
struct bootlog_page *page;
page = list_last_entry(&qdev->bootlog, struct bootlog_page, node);
if (size_add(size, sizeof(*page)) > page->size)
return NULL;
if (page->offset + size > page->size) {
page = alloc_bootlog_page(qdev);
if (!page)
return NULL;
}
return (void *)page + page->offset;
}
static void bootlog_commit(struct qaic_device *qdev, unsigned int size)
{
struct bootlog_page *page;
page = list_last_entry(&qdev->bootlog, struct bootlog_page, node);
page->offset += size;
}
static void bootlog_log(struct work_struct *work)
{
struct bootlog_msg *msg = container_of(work, struct bootlog_msg, work);
unsigned int len = strlen(msg->str) + 1;
struct qaic_device *qdev = msg->qdev;
void *log;
mutex_lock(&qdev->bootlog_mutex);
log = bootlog_get_space(qdev, len);
if (log) {
memcpy(log, msg, len);
bootlog_commit(qdev, len);
}
mutex_unlock(&qdev->bootlog_mutex);
if (mhi_queue_buf(qdev->bootlog_ch, DMA_FROM_DEVICE, msg, BOOTLOG_MSG_SIZE, MHI_EOT))
devm_kfree(&qdev->pdev->dev, msg);
}
static int qaic_bootlog_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id)
{
struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_dev->mhi_cntrl->cntrl_dev));
struct bootlog_msg *msg;
int i, ret;
qdev->bootlog_wq = alloc_ordered_workqueue("qaic_bootlog", 0);
if (!qdev->bootlog_wq) {
ret = -ENOMEM;
goto out;
}
ret = reset_bootlog(qdev);
if (ret)
goto destroy_workqueue;
ret = mhi_prepare_for_transfer(mhi_dev);
if (ret)
goto destroy_workqueue;
for (i = 0; i < BOOTLOG_POOL_SIZE; i++) {
msg = devm_kzalloc(&qdev->pdev->dev, sizeof(*msg), GFP_KERNEL);
if (!msg) {
ret = -ENOMEM;
goto mhi_unprepare;
}
msg->qdev = qdev;
INIT_WORK(&msg->work, bootlog_log);
ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, msg, BOOTLOG_MSG_SIZE, MHI_EOT);
if (ret)
goto mhi_unprepare;
}
dev_set_drvdata(&mhi_dev->dev, qdev);
qdev->bootlog_ch = mhi_dev;
return 0;
mhi_unprepare:
mhi_unprepare_from_transfer(mhi_dev);
destroy_workqueue:
flush_workqueue(qdev->bootlog_wq);
destroy_workqueue(qdev->bootlog_wq);
out:
return ret;
}
static void qaic_bootlog_mhi_remove(struct mhi_device *mhi_dev)
{
struct qaic_device *qdev;
qdev = dev_get_drvdata(&mhi_dev->dev);
mhi_unprepare_from_transfer(qdev->bootlog_ch);
flush_workqueue(qdev->bootlog_wq);
destroy_workqueue(qdev->bootlog_wq);
qdev->bootlog_ch = NULL;
}
static void qaic_bootlog_mhi_ul_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result)
{
}
static void qaic_bootlog_mhi_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result)
{
struct qaic_device *qdev = dev_get_drvdata(&mhi_dev->dev);
struct bootlog_msg *msg = mhi_result->buf_addr;
if (mhi_result->transaction_status) {
devm_kfree(&qdev->pdev->dev, msg);
return;
}
/* Force a null at the end of the transferred string */
msg->str[mhi_result->bytes_xferd - 1] = 0;
queue_work(qdev->bootlog_wq, &msg->work);
}
static const struct mhi_device_id qaic_bootlog_mhi_match_table[] = {
{ .chan = "QAIC_LOGGING", },
{},
};
static struct mhi_driver qaic_bootlog_mhi_driver = {
.id_table = qaic_bootlog_mhi_match_table,
.remove = qaic_bootlog_mhi_remove,
.probe = qaic_bootlog_mhi_probe,
.ul_xfer_cb = qaic_bootlog_mhi_ul_xfer_cb,
.dl_xfer_cb = qaic_bootlog_mhi_dl_xfer_cb,
.driver = {
.name = "qaic_bootlog",
},
};
int qaic_bootlog_register(void)
{
return mhi_driver_register(&qaic_bootlog_mhi_driver);
}
void qaic_bootlog_unregister(void)
{
mhi_driver_unregister(&qaic_bootlog_mhi_driver);
}
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2020, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */
#ifndef __QAIC_DEBUGFS_H__
#define __QAIC_DEBUGFS_H__
#include <drm/drm_file.h>
#ifdef CONFIG_DEBUG_FS
int qaic_bootlog_register(void);
void qaic_bootlog_unregister(void);
void qaic_debugfs_init(struct qaic_drm_device *qddev);
#else
int qaic_bootlog_register(void) { return 0; }
void qaic_bootlog_unregister(void) {}
void qaic_debugfs_init(struct qaic_drm_device *qddev) {}
#endif /* CONFIG_DEBUG_FS */
#endif /* __QAIC_DEBUGFS_H__ */
......@@ -28,6 +28,7 @@
#include "mhi_controller.h"
#include "qaic.h"
#include "qaic_debugfs.h"
#include "qaic_timesync.h"
MODULE_IMPORT_NS(DMA_BUF);
......@@ -229,8 +230,12 @@ static int qaic_create_drm_device(struct qaic_device *qdev, s32 partition_id)
qddev->partition_id = partition_id;
ret = drm_dev_register(drm, 0);
if (ret)
if (ret) {
pci_dbg(qdev->pdev, "drm_dev_register failed %d\n", ret);
return ret;
}
qaic_debugfs_init(qddev);
return ret;
}
......@@ -380,6 +385,9 @@ static struct qaic_device *create_qdev(struct pci_dev *pdev, const struct pci_de
if (ret)
return NULL;
ret = drmm_mutex_init(drm, &qdev->cntl_mutex);
if (ret)
return NULL;
ret = drmm_mutex_init(drm, &qdev->bootlog_mutex);
if (ret)
return NULL;
......@@ -399,6 +407,7 @@ static struct qaic_device *create_qdev(struct pci_dev *pdev, const struct pci_de
qddev->qdev = qdev;
INIT_LIST_HEAD(&qdev->cntl_xfer_list);
INIT_LIST_HEAD(&qdev->bootlog);
INIT_LIST_HEAD(&qddev->users);
for (i = 0; i < qdev->num_dbc; ++i) {
......@@ -639,6 +648,10 @@ static int __init qaic_init(void)
if (ret)
pr_debug("qaic: qaic_timesync_init failed %d\n", ret);
ret = qaic_bootlog_register();
if (ret)
pr_debug("qaic: qaic_bootlog_register failed %d\n", ret);
return 0;
free_pci:
......@@ -664,6 +677,7 @@ static void __exit qaic_exit(void)
* reinitializing the link_up state after the cleanup is done.
*/
link_up = true;
qaic_bootlog_unregister();
qaic_timesync_deinit();
mhi_driver_unregister(&qaic_mhi_driver);
pci_unregister_driver(&qaic_pci_driver);
......
......@@ -2059,6 +2059,9 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
mhdp_state = to_cdns_mhdp_bridge_state(new_state);
mhdp_state->current_mode = drm_mode_duplicate(bridge->dev, mode);
if (!mhdp_state->current_mode)
return;
drm_mode_set_name(mhdp_state->current_mode);
dev_dbg(mhdp->dev, "%s: Enabling mode %s\n", __func__, mode->name);
......
......@@ -173,15 +173,13 @@ static int imx8mp_hdmi_pvi_probe(struct platform_device *pdev)
return 0;
}
static int imx8mp_hdmi_pvi_remove(struct platform_device *pdev)
static void imx8mp_hdmi_pvi_remove(struct platform_device *pdev)
{
struct imx8mp_hdmi_pvi *pvi = platform_get_drvdata(pdev);
drm_bridge_remove(&pvi->bridge);
pm_runtime_disable(&pdev->dev);
return 0;
}
static const struct of_device_id imx8mp_hdmi_pvi_match[] = {
......@@ -195,7 +193,7 @@ MODULE_DEVICE_TABLE(of, imx8mp_hdmi_pvi_match);
static struct platform_driver imx8mp_hdmi_pvi_driver = {
.probe = imx8mp_hdmi_pvi_probe,
.remove = imx8mp_hdmi_pvi_remove,
.remove_new = imx8mp_hdmi_pvi_remove,
.driver = {
.name = "imx-hdmi-pvi",
.of_match_table = imx8mp_hdmi_pvi_match,
......
# SPDX-License-Identifier: GPL-2.0-only
config DRM_DW_HDMI
tristate
tristate "Synopsys Designware HDMI TX Controller"
depends on DRM_DISPLAY_HDMI_HELPER
depends on DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
......
......@@ -39,6 +39,7 @@ config DRM_DISPLAY_DP_AUX_CHARDEV
config DRM_DISPLAY_DP_HELPER
bool "DRM DisplayPort Helpers"
depends on DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
default y
help
DRM display helpers for DisplayPort.
......
......@@ -1212,7 +1212,6 @@ struct platform_driver omap_dmm_driver = {
.probe = omap_dmm_probe,
.remove_new = omap_dmm_remove,
.driver = {
.owner = THIS_MODULE,
.name = DMM_DRIVER_NAME,
.of_match_table = of_match_ptr(dmm_of_match),
.pm = &omap_dmm_pm_ops,
......
......@@ -760,6 +760,25 @@ static void panel_edp_parse_panel_timing_node(struct device *dev,
static const struct edp_panel_entry *find_edp_panel(u32 panel_id, const struct drm_edid *edid);
static void panel_edp_set_conservative_timings(struct panel_edp *panel, struct panel_desc *desc)
{
/*
* It's highly likely that the panel will work if we use very
* conservative timings, so let's do that.
*
* Nearly all panels have a "unprepare" delay of 500 ms though
* there are a few with 1000. Let's stick 2000 in just to be
* super conservative.
*
* An "enable" delay of 80 ms seems the most common, but we'll
* throw in 200 ms to be safe.
*/
desc->delay.unprepare = 2000;
desc->delay.enable = 200;
panel->detected_panel = ERR_PTR(-EINVAL);
}
static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
{
struct panel_desc *desc;
......@@ -789,7 +808,10 @@ static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
/* Power the panel on so we can read the EDID */
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
dev_err(dev, "Couldn't power on panel to read EDID: %d\n", ret);
dev_err(dev,
"Couldn't power on panel to ID it; using conservative timings: %d\n",
ret);
panel_edp_set_conservative_timings(panel, desc);
goto exit;
}
......@@ -797,8 +819,8 @@ static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
if (base_block) {
panel_id = drm_edid_get_panel_id(base_block);
} else {
dev_err(dev, "Couldn't identify panel via EDID\n");
ret = -EIO;
dev_err(dev, "Couldn't read EDID for ID; using conservative timings\n");
panel_edp_set_conservative_timings(panel, desc);
goto exit;
}
drm_edid_decode_panel_id(panel_id, vend, &product_id);
......@@ -816,26 +838,7 @@ static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
dev_warn(dev,
"Unknown panel %s %#06x, using conservative timings\n",
vend, product_id);
/*
* It's highly likely that the panel will work if we use very
* conservative timings, so let's do that. We already know that
* the HPD-related delays must have worked since we got this
* far, so we really just need the "unprepare" / "enable"
* delays. We don't need "prepare_to_enable" since that
* overlaps the "enable" delay anyway.
*
* Nearly all panels have a "unprepare" delay of 500 ms though
* there are a few with 1000. Let's stick 2000 in just to be
* super conservative.
*
* An "enable" delay of 80 ms seems the most common, but we'll
* throw in 200 ms to be safe.
*/
desc->delay.unprepare = 2000;
desc->delay.enable = 200;
panel->detected_panel = ERR_PTR(-EINVAL);
panel_edp_set_conservative_timings(panel, desc);
} else {
dev_info(dev, "Detected %s %s (%#06x)\n",
vend, panel->detected_panel->ident.name, product_id);
......@@ -844,12 +847,11 @@ static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
desc->delay = *panel->detected_panel->delay;
}
ret = 0;
exit:
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
return ret;
return 0;
}
static int panel_edp_probe(struct device *dev, const struct panel_desc *desc,
......@@ -942,8 +944,14 @@ static int panel_edp_probe(struct device *dev, const struct panel_desc *desc,
err = drm_panel_dp_aux_backlight(&panel->base, panel->aux);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
/*
* Warn if we get an error, but don't consider it fatal. Having
* a panel where we can't control the backlight is better than
* no panel.
*/
if (err)
goto err_finished_pm_runtime;
dev_warn(dev, "failed to register dp aux backlight: %d\n", err);
}
drm_panel_add(&panel->base);
......
......@@ -328,9 +328,14 @@ static int atana33xc20_probe(struct dp_aux_ep_device *aux_ep)
ret = drm_panel_dp_aux_backlight(&panel->base, aux_ep->aux);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
/*
* Warn if we get an error, but don't consider it fatal. Having
* a panel where we can't control the backlight is better than
* no panel.
*/
if (ret)
return dev_err_probe(dev, ret,
"failed to register dp aux backlight\n");
dev_warn(dev, "failed to register dp aux backlight: %d\n", ret);
drm_panel_add(&panel->base);
......
......@@ -6,7 +6,6 @@
#include <linux/backlight.h>
#include <linux/gpio/consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <video/display_timing.h>
......@@ -308,7 +307,6 @@ static int panel_probe(struct platform_device *pdev)
struct backlight_device *backlight;
struct panel_module *panel_mod;
struct tilcdc_module *mod;
struct pinctrl *pinctrl;
int ret;
/* bail out early if no DT data: */
......@@ -342,10 +340,6 @@ static int panel_probe(struct platform_device *pdev)
tilcdc_module_init(mod, "panel", &panel_module_ops);
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR(pinctrl))
dev_warn(&pdev->dev, "pins are not configured\n");
panel_mod->timings = of_get_display_timings(node);
if (!panel_mod->timings) {
dev_err(&pdev->dev, "could not get panel timings\n");
......
......@@ -1716,7 +1716,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
ret = zynqmp_dp_reset(dp, true);
if (ret < 0)
return ret;
goto err_free;
ret = zynqmp_dp_reset(dp, false);
if (ret < 0)
......
/* SPDX-License-Identifier: GPL-2.0-only */
/**************************************************************************
* Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
* Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA.
* All Rights Reserved.
*
**************************************************************************/
#ifndef _GMA_DRM_H_
#define _GMA_DRM_H_
#endif
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