drm: omapdrm: displays: Get panel source at connect time

The connector drivers need a handle to the source they are connected to
in order to control the source.

All drivers get that handle at probe time, resulting in probe deferral
when the source hasn't been probed yet. However they don't need the
handle until their connect handler is called.

Move retrieval of the source handle to the connect handler to avoid
probe deferrals.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
Laurent Pinchart 2018-02-11 15:07:40 +02:00 committed by Tomi Valkeinen
parent b47e6dcb58
commit 2f8c4a8a9d
8 changed files with 131 additions and 164 deletions

View File

@ -38,16 +38,25 @@ struct panel_drv_data {
static int panel_dpi_connect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct omap_dss_device *in;
int r;
if (omapdss_device_is_connected(dssdev))
return 0;
r = in->ops.dpi->connect(in, dssdev);
if (r)
return r;
in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
if (IS_ERR(in)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
r = in->ops.dpi->connect(in, dssdev);
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
@ -60,6 +69,9 @@ static void panel_dpi_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int panel_dpi_enable(struct omap_dss_device *dssdev)
@ -157,7 +169,6 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct device_node *node = pdev->dev.of_node;
struct omap_dss_device *in;
int r;
struct display_timing timing;
struct gpio_desc *gpio;
@ -195,14 +206,6 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
videomode_from_timing(&timing, &ddata->vm);
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&pdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
@ -232,29 +235,22 @@ static int panel_dpi_probe(struct platform_device *pdev)
r = omapdss_register_display(dssdev);
if (r) {
dev_err(&pdev->dev, "Failed to register panel\n");
goto err_reg;
return r;
}
return 0;
err_reg:
omap_dss_put_device(ddata->in);
return r;
}
static int __exit panel_dpi_remove(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
omapdss_unregister_display(dssdev);
panel_dpi_disable(dssdev);
panel_dpi_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}

View File

@ -759,17 +759,23 @@ static int dsicm_panel_reset(struct panel_drv_data *ddata)
static int dsicm_connect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct device *dev = &ddata->pdev->dev;
struct omap_dss_device *in;
int r;
if (omapdss_device_is_connected(dssdev))
return 0;
in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
if (IS_ERR(in)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
r = in->ops.dsi->connect(in, dssdev);
if (r) {
dev_err(dev, "Failed to connect to video source\n");
return r;
goto err_connect;
}
r = in->ops.dsi->request_vc(ddata->in, &ddata->channel);
@ -784,12 +790,15 @@ static int dsicm_connect(struct omap_dss_device *dssdev)
goto err_vc_id;
}
ddata->in = in;
return 0;
err_vc_id:
in->ops.dsi->release_vc(ddata->in, ddata->channel);
err_req_vc:
in->ops.dsi->disconnect(in, dssdev);
err_connect:
omap_dss_put_device(in);
return r;
}
@ -803,6 +812,9 @@ static void dsicm_disconnect(struct omap_dss_device *dssdev)
in->ops.dsi->release_vc(in, ddata->channel);
in->ops.dsi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int dsicm_enable(struct omap_dss_device *dssdev)
@ -1223,7 +1235,6 @@ static int dsicm_probe_of(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
struct device_node *backlight;
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct omap_dss_device *in;
struct display_timing timing;
int err;
@ -1259,12 +1270,6 @@ static int dsicm_probe_of(struct platform_device *pdev)
ddata->height_mm = 0;
of_property_read_u32(node, "height-mm", &ddata->height_mm);
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&pdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->vpnl = devm_regulator_get_optional(&pdev->dev, "vpnl");
if (IS_ERR(ddata->vpnl)) {
err = PTR_ERR(ddata->vpnl);
@ -1281,8 +1286,6 @@ static int dsicm_probe_of(struct platform_device *pdev)
ddata->vddi = NULL;
}
ddata->in = in;
backlight = of_parse_phandle(node, "backlight", 0);
if (backlight) {
ddata->extbldev = of_find_backlight_by_node(backlight);
@ -1421,8 +1424,6 @@ static int __exit dsicm_remove(struct platform_device *pdev)
if (ddata->extbldev)
put_device(&ddata->extbldev->dev);
omap_dss_put_device(ddata->in);
dsicm_cancel_ulps_work(ddata);
destroy_workqueue(ddata->workqueue);

View File

@ -119,18 +119,27 @@ static void init_lb035q02_panel(struct spi_device *spi)
static int lb035q02_connect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct omap_dss_device *in;
int r;
if (omapdss_device_is_connected(dssdev))
return 0;
in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
if (IS_ERR(in)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
r = in->ops.dpi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
init_lb035q02_panel(ddata->spi);
ddata->in = in;
return 0;
}
@ -143,6 +152,9 @@ static void lb035q02_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int lb035q02_enable(struct omap_dss_device *dssdev)
@ -230,9 +242,7 @@ static struct omap_dss_driver lb035q02_ops = {
static int lb035q02_probe_of(struct spi_device *spi)
{
struct device_node *node = spi->dev.of_node;
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *in;
struct gpio_desc *gpio;
gpio = devm_gpiod_get(&spi->dev, "enable", GPIOD_OUT_LOW);
@ -243,14 +253,6 @@ static int lb035q02_probe_of(struct spi_device *spi)
ddata->enable_gpio = gpio;
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
@ -284,29 +286,22 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
r = omapdss_register_display(dssdev);
if (r) {
dev_err(&spi->dev, "Failed to register panel\n");
goto err_reg;
return r;
}
return 0;
err_reg:
omap_dss_put_device(ddata->in);
return r;
}
static int lb035q02_panel_spi_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
omapdss_unregister_display(dssdev);
lb035q02_disable(dssdev);
lb035q02_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}

View File

@ -115,16 +115,25 @@ static int init_nec_8048_wvga_lcd(struct spi_device *spi)
static int nec_8048_connect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct omap_dss_device *in;
int r;
if (omapdss_device_is_connected(dssdev))
return 0;
r = in->ops.dpi->connect(in, dssdev);
if (r)
return r;
in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
if (IS_ERR(in)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
r = in->ops.dpi->connect(in, dssdev);
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
@ -137,6 +146,9 @@ static void nec_8048_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int nec_8048_enable(struct omap_dss_device *dssdev)
@ -226,7 +238,6 @@ static int nec_8048_probe_of(struct spi_device *spi)
{
struct device_node *node = spi->dev.of_node;
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *in;
int gpio;
gpio = of_get_named_gpio(node, "reset-gpios", 0);
@ -239,14 +250,6 @@ static int nec_8048_probe_of(struct spi_device *spi)
/* XXX the panel spec doesn't mention any QVGA pin?? */
ddata->qvga_gpio = -ENOENT;
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
@ -285,14 +288,14 @@ static int nec_8048_probe(struct spi_device *spi)
r = devm_gpio_request_one(&spi->dev, ddata->qvga_gpio,
GPIOF_OUT_INIT_HIGH, "lcd QVGA");
if (r)
goto err_gpio;
return r;
}
if (gpio_is_valid(ddata->res_gpio)) {
r = devm_gpio_request_one(&spi->dev, ddata->res_gpio,
GPIOF_OUT_INIT_LOW, "lcd RES");
if (r)
goto err_gpio;
return r;
}
ddata->vm = nec_8048_panel_vm;
@ -307,22 +310,16 @@ static int nec_8048_probe(struct spi_device *spi)
r = omapdss_register_display(dssdev);
if (r) {
dev_err(&spi->dev, "Failed to register panel\n");
goto err_reg;
return r;
}
return 0;
err_reg:
err_gpio:
omap_dss_put_device(ddata->in);
return r;
}
static int nec_8048_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
@ -331,8 +328,6 @@ static int nec_8048_remove(struct spi_device *spi)
nec_8048_disable(dssdev);
nec_8048_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}

View File

@ -61,16 +61,25 @@ static const struct videomode sharp_ls_vm = {
static int sharp_ls_connect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct omap_dss_device *in;
int r;
if (omapdss_device_is_connected(dssdev))
return 0;
r = in->ops.dpi->connect(in, dssdev);
if (r)
return r;
in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
if (IS_ERR(in)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
r = in->ops.dpi->connect(in, dssdev);
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
@ -83,6 +92,9 @@ static void sharp_ls_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int sharp_ls_enable(struct omap_dss_device *dssdev)
@ -210,8 +222,6 @@ static int sharp_ls_get_gpio_of(struct device *dev, int index, int val,
static int sharp_ls_probe_of(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct device_node *node = pdev->dev.of_node;
struct omap_dss_device *in;
int r;
ddata->vcc = devm_regulator_get(&pdev->dev, "envdd");
@ -245,14 +255,6 @@ static int sharp_ls_probe_of(struct platform_device *pdev)
if (r)
return r;
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&pdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
@ -284,29 +286,22 @@ static int sharp_ls_probe(struct platform_device *pdev)
r = omapdss_register_display(dssdev);
if (r) {
dev_err(&pdev->dev, "Failed to register panel\n");
goto err_reg;
return r;
}
return 0;
err_reg:
omap_dss_put_device(ddata->in);
return r;
}
static int __exit sharp_ls_remove(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
omapdss_unregister_display(dssdev);
sharp_ls_disable(dssdev);
sharp_ls_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}

View File

@ -510,16 +510,25 @@ static const struct attribute_group bldev_attr_group = {
static int acx565akm_connect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct omap_dss_device *in;
int r;
if (omapdss_device_is_connected(dssdev))
return 0;
r = in->ops.sdi->connect(in, dssdev);
if (r)
return r;
in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
if (IS_ERR(in)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
r = in->ops.sdi->connect(in, dssdev);
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
@ -532,6 +541,9 @@ static void acx565akm_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.sdi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
@ -700,12 +712,6 @@ static int acx565akm_probe_of(struct spi_device *spi)
ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
ddata->in = omapdss_of_find_source_for_first_ep(np);
if (IS_ERR(ddata->in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(ddata->in);
}
return 0;
}
@ -823,7 +829,6 @@ err_sysfs:
err_reg_bl:
err_detect:
err_gpio:
omap_dss_put_device(ddata->in);
return r;
}
@ -831,7 +836,6 @@ static int acx565akm_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
@ -843,8 +847,6 @@ static int acx565akm_remove(struct spi_device *spi)
acx565akm_disable(dssdev);
acx565akm_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}

View File

@ -169,16 +169,25 @@ enum jbt_register {
static int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct omap_dss_device *in;
int r;
if (omapdss_device_is_connected(dssdev))
return 0;
r = in->ops.dpi->connect(in, dssdev);
if (r)
return r;
in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
if (IS_ERR(in)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
r = in->ops.dpi->connect(in, dssdev);
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
@ -191,6 +200,9 @@ static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
@ -362,23 +374,6 @@ static struct omap_dss_driver td028ttec1_ops = {
.check_timings = td028ttec1_panel_check_timings,
};
static int td028ttec1_probe_of(struct spi_device *spi)
{
struct device_node *node = spi->dev.of_node;
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *in;
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
static int td028ttec1_panel_probe(struct spi_device *spi)
{
struct panel_drv_data *ddata;
@ -404,10 +399,6 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
ddata->spi_dev = spi;
r = td028ttec1_probe_of(spi);
if (r)
return r;
ddata->vm = td028ttec1_panel_vm;
dssdev = &ddata->dssdev;
@ -420,21 +411,16 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
r = omapdss_register_display(dssdev);
if (r) {
dev_err(&spi->dev, "Failed to register panel\n");
goto err_reg;
return r;
}
return 0;
err_reg:
omap_dss_put_device(ddata->in);
return r;
}
static int td028ttec1_panel_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
dev_dbg(&ddata->spi_dev->dev, "%s\n", __func__);
@ -443,8 +429,6 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
td028ttec1_panel_disable(dssdev);
td028ttec1_panel_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}

View File

@ -340,16 +340,25 @@ static void tpo_td043_power_off(struct panel_drv_data *ddata)
static int tpo_td043_connect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct omap_dss_device *in;
int r;
if (omapdss_device_is_connected(dssdev))
return 0;
r = in->ops.dpi->connect(in, dssdev);
if (r)
return r;
in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
if (IS_ERR(in)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}
r = in->ops.dpi->connect(in, dssdev);
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
@ -362,6 +371,9 @@ static void tpo_td043_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int tpo_td043_enable(struct omap_dss_device *dssdev)
@ -463,7 +475,6 @@ static int tpo_td043_probe_of(struct spi_device *spi)
{
struct device_node *node = spi->dev.of_node;
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *in;
int gpio;
gpio = of_get_named_gpio(node, "reset-gpios", 0);
@ -473,14 +484,6 @@ static int tpo_td043_probe_of(struct spi_device *spi)
}
ddata->nreset_gpio = gpio;
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
@ -561,7 +564,6 @@ err_reg:
err_sysfs:
err_gpio_req:
err_regulator:
omap_dss_put_device(ddata->in);
return r;
}
@ -569,7 +571,6 @@ static int tpo_td043_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
@ -578,8 +579,6 @@ static int tpo_td043_remove(struct spi_device *spi)
tpo_td043_disable(dssdev);
tpo_td043_disconnect(dssdev);
omap_dss_put_device(in);
sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
return 0;