summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/display/connector/dvi-connector.txt1
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c50
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-dvi.c146
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-hdmi.c40
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-opa362.c40
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c39
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c69
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dpi.c37
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c44
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c38
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c42
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c38
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c41
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c49
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c32
-rw-r--r--drivers/gpu/drm/omapdrm/dss/base.c27
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc.c2346
-rw-r--r--drivers/gpu/drm/omapdrm/dss/display.c5
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dpi.c91
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c1553
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss-of.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.c823
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.h245
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi.h11
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi4.c406
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c4
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi4_core.h4
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi5.c418
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi5_core.c24
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_phy.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_pll.c15
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_wp.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/omapdss.h213
-rw-r--r--drivers/gpu/drm/omapdrm/dss/output.c53
-rw-r--r--drivers/gpu/drm/omapdrm/dss/pll.c44
-rw-r--r--drivers/gpu/drm/omapdrm/dss/sdi.c162
-rw-r--r--drivers/gpu/drm/omapdrm/dss/venc.c453
-rw-r--r--drivers/gpu/drm/omapdrm/dss/video-pll.c19
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c74
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.h4
-rw-r--r--drivers/gpu/drm/omapdrm/omap_dmm_priv.h10
-rw-r--r--drivers/gpu/drm/omapdrm/omap_dmm_tiler.c46
-rw-r--r--drivers/gpu/drm/omapdrm/omap_dmm_tiler.h22
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c122
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h8
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fb.c18
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.c38
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.h9
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c41
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.h16
-rw-r--r--drivers/gpu/drm/omapdrm/omap_irq.c38
-rw-r--r--drivers/gpu/drm/omapdrm/omap_irq.h2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c16
-rw-r--r--drivers/gpu/drm/omapdrm/tcm-sita.c12
-rw-r--r--drivers/gpu/drm/omapdrm/tcm.h4
55 files changed, 4277 insertions, 3831 deletions
diff --git a/Documentation/devicetree/bindings/display/connector/dvi-connector.txt b/Documentation/devicetree/bindings/display/connector/dvi-connector.txt
index fc53f7c60bc6..207e42e9eba0 100644
--- a/Documentation/devicetree/bindings/display/connector/dvi-connector.txt
+++ b/Documentation/devicetree/bindings/display/connector/dvi-connector.txt
@@ -10,6 +10,7 @@ Optional properties:
- analog: the connector has DVI analog pins
- digital: the connector has DVI digital pins
- dual-link: the connector has pins for DVI dual-link
+- hpd-gpios: HPD GPIO number
Required nodes:
- Video port for DVI input
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 95ea6abae914..9eabd7201a12 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -40,14 +40,12 @@ static const struct videomode tvc_pal_vm = {
DISPLAY_FLAGS_VSYNC_LOW,
};
-static const struct of_device_id tvc_of_match[];
-
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
static int tvc_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;
dev_dbg(ddata->dev, "connect\n");
@@ -55,10 +53,19 @@ static int tvc_connect(struct omap_dss_device *dssdev)
if (omapdss_device_is_connected(dssdev))
return 0;
+ in = omapdss_of_find_source_for_first_ep(ddata->dev->of_node);
+ if (IS_ERR(in)) {
+ dev_err(ddata->dev, "failed to find video source\n");
+ return PTR_ERR(in);
+ }
+
r = in->ops.atv->connect(in, dssdev);
- if (r)
+ if (r) {
+ omap_dss_put_device(in);
return r;
+ }
+ ddata->in = in;
return 0;
}
@@ -73,6 +80,9 @@ static void tvc_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.atv->disconnect(in, dssdev);
+
+ omap_dss_put_device(in);
+ ddata->in = NULL;
}
static int tvc_enable(struct omap_dss_device *dssdev)
@@ -175,32 +185,12 @@ static struct omap_dss_driver tvc_driver = {
.set_wss = tvc_set_wss,
};
-static int tvc_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;
-
- 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;
-}
-
static int tvc_probe(struct platform_device *pdev)
{
struct panel_drv_data *ddata;
struct omap_dss_device *dssdev;
int r;
- if (!pdev->dev.of_node)
- return -ENODEV;
-
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
@@ -208,10 +198,6 @@ static int tvc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
ddata->dev = &pdev->dev;
- r = tvc_probe_of(pdev);
- if (r)
- return r;
-
ddata->vm = tvc_pal_vm;
dssdev = &ddata->dssdev;
@@ -224,28 +210,22 @@ static int tvc_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 tvc_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(&ddata->dssdev);
tvc_disable(dssdev);
tvc_disconnect(dssdev);
- omap_dss_put_device(in);
-
return 0;
}
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index 10b4b97d3595..6d8cbd9e2110 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -9,6 +9,7 @@
* the Free Software Foundation.
*/
+#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -44,6 +45,14 @@ struct panel_drv_data {
struct videomode vm;
struct i2c_adapter *i2c_adapter;
+
+ struct gpio_desc *hpd_gpio;
+
+ void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
+ void *hpd_cb_data;
+ bool hpd_enabled;
+ /* mutex for hpd fields above */
+ struct mutex hpd_lock;
};
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
@@ -51,16 +60,25 @@ struct panel_drv_data {
static int dvic_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.dvi->connect(in, dssdev);
- if (r)
+ if (r) {
+ omap_dss_put_device(in);
return r;
+ }
+ ddata->in = in;
return 0;
}
@@ -73,6 +91,9 @@ static void dvic_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dvi->disconnect(in, dssdev);
+
+ omap_dss_put_device(in);
+ ddata->in = NULL;
}
static int dvic_enable(struct omap_dss_device *dssdev)
@@ -177,6 +198,9 @@ static int dvic_read_edid(struct omap_dss_device *dssdev,
struct panel_drv_data *ddata = to_panel_data(dssdev);
int r, l, bytes_read;
+ if (ddata->hpd_gpio && !gpiod_get_value_cansleep(ddata->hpd_gpio))
+ return -ENODEV;
+
if (!ddata->i2c_adapter)
return -ENODEV;
@@ -208,6 +232,9 @@ static bool dvic_detect(struct omap_dss_device *dssdev)
unsigned char out;
int r;
+ if (ddata->hpd_gpio)
+ return gpiod_get_value_cansleep(ddata->hpd_gpio);
+
if (!ddata->i2c_adapter)
return true;
@@ -216,6 +243,60 @@ static bool dvic_detect(struct omap_dss_device *dssdev)
return r == 0;
}
+static int dvic_register_hpd_cb(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
+ enum drm_connector_status status),
+ void *cb_data)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ if (!ddata->hpd_gpio)
+ return -ENOTSUPP;
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = cb;
+ ddata->hpd_cb_data = cb_data;
+ mutex_unlock(&ddata->hpd_lock);
+ return 0;
+}
+
+static void dvic_unregister_hpd_cb(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ if (!ddata->hpd_gpio)
+ return;
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = NULL;
+ ddata->hpd_cb_data = NULL;
+ mutex_unlock(&ddata->hpd_lock);
+}
+
+static void dvic_enable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ if (!ddata->hpd_gpio)
+ return;
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = true;
+ mutex_unlock(&ddata->hpd_lock);
+}
+
+static void dvic_disable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ if (!ddata->hpd_gpio)
+ return;
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = false;
+ mutex_unlock(&ddata->hpd_lock);
+}
+
static struct omap_dss_driver dvic_driver = {
.connect = dvic_connect,
.disconnect = dvic_disconnect,
@@ -229,23 +310,60 @@ static struct omap_dss_driver dvic_driver = {
.read_edid = dvic_read_edid,
.detect = dvic_detect,
+
+ .register_hpd_cb = dvic_register_hpd_cb,
+ .unregister_hpd_cb = dvic_unregister_hpd_cb,
+ .enable_hpd = dvic_enable_hpd,
+ .disable_hpd = dvic_disable_hpd,
};
+static irqreturn_t dvic_hpd_isr(int irq, void *data)
+{
+ struct panel_drv_data *ddata = data;
+
+ mutex_lock(&ddata->hpd_lock);
+ if (ddata->hpd_enabled && ddata->hpd_cb) {
+ enum drm_connector_status status;
+
+ if (dvic_detect(&ddata->dssdev))
+ status = connector_status_connected;
+ else
+ status = connector_status_disconnected;
+
+ ddata->hpd_cb(ddata->hpd_cb_data, status);
+ }
+ mutex_unlock(&ddata->hpd_lock);
+
+ return IRQ_HANDLED;
+}
+
static int dvic_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;
struct device_node *adapter_node;
struct i2c_adapter *adapter;
+ struct gpio_desc *gpio;
+ int 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);
+ gpio = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);
+ if (IS_ERR(gpio)) {
+ dev_err(&pdev->dev, "failed to parse HPD gpio\n");
+ return PTR_ERR(gpio);
}
- ddata->in = in;
+ ddata->hpd_gpio = gpio;
+
+ mutex_init(&ddata->hpd_lock);
+
+ if (ddata->hpd_gpio) {
+ r = devm_request_threaded_irq(&pdev->dev,
+ gpiod_to_irq(ddata->hpd_gpio), NULL, dvic_hpd_isr,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "DVI HPD", ddata);
+ if (r)
+ return r;
+ }
adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0);
if (adapter_node) {
@@ -253,7 +371,6 @@ static int dvic_probe_of(struct platform_device *pdev)
of_node_put(adapter_node);
if (adapter == NULL) {
dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n");
- omap_dss_put_device(ddata->in);
return -EPROBE_DEFER;
}
@@ -275,9 +392,6 @@ static int dvic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
- if (!pdev->dev.of_node)
- return -ENODEV;
-
r = dvic_probe_of(pdev);
if (r)
return r;
@@ -300,9 +414,8 @@ static int dvic_probe(struct platform_device *pdev)
return 0;
err_reg:
- omap_dss_put_device(ddata->in);
-
i2c_put_adapter(ddata->i2c_adapter);
+ mutex_destroy(&ddata->hpd_lock);
return r;
}
@@ -311,17 +424,16 @@ static int __exit dvic_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(&ddata->dssdev);
dvic_disable(dssdev);
dvic_disconnect(dssdev);
- omap_dss_put_device(in);
-
i2c_put_adapter(ddata->i2c_adapter);
+ mutex_destroy(&ddata->hpd_lock);
+
return 0;
}
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 2867476419dc..ca30ed9da7eb 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -55,7 +55,7 @@ struct panel_drv_data {
static int hdmic_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;
dev_dbg(ddata->dev, "connect\n");
@@ -63,10 +63,19 @@ static int hdmic_connect(struct omap_dss_device *dssdev)
if (omapdss_device_is_connected(dssdev))
return 0;
+ in = omapdss_of_find_source_for_first_ep(ddata->dev->of_node);
+ if (IS_ERR(in)) {
+ dev_err(ddata->dev, "failed to find video source\n");
+ return PTR_ERR(in);
+ }
+
r = in->ops.hdmi->connect(in, dssdev);
- if (r)
+ if (r) {
+ omap_dss_put_device(in);
return r;
+ }
+ ddata->in = in;
return 0;
}
@@ -81,6 +90,9 @@ static void hdmic_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.hdmi->disconnect(in, dssdev);
+
+ omap_dss_put_device(in);
+ ddata->in = NULL;
}
static int hdmic_enable(struct omap_dss_device *dssdev)
@@ -302,7 +314,6 @@ static int hdmic_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 gpio;
/* HPD GPIO */
@@ -312,14 +323,6 @@ static int hdmic_probe_of(struct platform_device *pdev)
else
ddata->hpd_gpio = -ENODEV;
- 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;
}
@@ -336,9 +339,6 @@ static int hdmic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
ddata->dev = &pdev->dev;
- if (!pdev->dev.of_node)
- return -ENODEV;
-
r = hdmic_probe_of(pdev);
if (r)
return r;
@@ -349,7 +349,7 @@ static int hdmic_probe(struct platform_device *pdev)
r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio,
GPIOF_DIR_IN, "hdmi_hpd");
if (r)
- goto err_reg;
+ return r;
r = devm_request_threaded_irq(&pdev->dev,
gpio_to_irq(ddata->hpd_gpio),
@@ -358,7 +358,7 @@ static int hdmic_probe(struct platform_device *pdev)
IRQF_ONESHOT,
"hdmic hpd", ddata);
if (r)
- goto err_reg;
+ return r;
}
ddata->vm = hdmic_default_vm;
@@ -373,28 +373,22 @@ static int hdmic_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 hdmic_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(&ddata->dssdev);
hdmic_disable(dssdev);
hdmic_disconnect(dssdev);
- omap_dss_put_device(in);
-
return 0;
}
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index d523c67a3ae3..afee1b8b457a 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -36,7 +36,7 @@ static int opa362_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
- struct omap_dss_device *in = ddata->in;
+ struct omap_dss_device *in;
int r;
dev_dbg(dssdev->dev, "connect\n");
@@ -44,13 +44,22 @@ static int opa362_connect(struct omap_dss_device *dssdev,
if (omapdss_device_is_connected(dssdev))
return -EBUSY;
+ 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.atv->connect(in, dssdev);
- if (r)
+ if (r) {
+ omap_dss_put_device(in);
return r;
+ }
dst->src = dssdev;
dssdev->dst = dst;
+ ddata->in = in;
return 0;
}
@@ -74,6 +83,9 @@ static void opa362_disconnect(struct omap_dss_device *dssdev,
dssdev->dst = NULL;
in->ops.atv->disconnect(in, &ddata->dssdev);
+
+ omap_dss_put_device(in);
+ ddata->in = NULL;
}
static int opa362_enable(struct omap_dss_device *dssdev)
@@ -171,19 +183,13 @@ static const struct omapdss_atv_ops opa362_atv_ops = {
static int opa362_probe(struct platform_device *pdev)
{
- struct device_node *node = pdev->dev.of_node;
struct panel_drv_data *ddata;
- struct omap_dss_device *dssdev, *in;
+ struct omap_dss_device *dssdev;
struct gpio_desc *gpio;
int r;
dev_dbg(&pdev->dev, "probe\n");
- if (node == NULL) {
- dev_err(&pdev->dev, "Unable to find device tree\n");
- return -EINVAL;
- }
-
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
@@ -196,14 +202,6 @@ static int opa362_probe(struct platform_device *pdev)
ddata->enable_gpio = gpio;
- 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;
-
dssdev = &ddata->dssdev;
dssdev->ops.atv = &opa362_atv_ops;
dssdev->dev = &pdev->dev;
@@ -214,20 +212,16 @@ static int opa362_probe(struct platform_device *pdev)
r = omapdss_register_output(dssdev);
if (r) {
dev_err(&pdev->dev, "Failed to register output\n");
- goto err_reg;
+ return r;
}
return 0;
-err_reg:
- omap_dss_put_device(ddata->in);
- return r;
}
static int __exit opa362_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_output(&ddata->dssdev);
@@ -239,8 +233,6 @@ static int __exit opa362_remove(struct platform_device *pdev)
if (omapdss_device_is_connected(dssdev))
opa362_disconnect(dssdev, dssdev->dst);
- omap_dss_put_device(in);
-
return 0;
}
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index e01ab3db6d86..ed7ae384c3ed 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -32,19 +32,28 @@ static int tfp410_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
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 -EBUSY;
+ 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;
+ }
dst->src = dssdev;
dssdev->dst = dst;
+ ddata->in = in;
return 0;
}
@@ -66,6 +75,9 @@ static void tfp410_disconnect(struct omap_dss_device *dssdev,
dssdev->dst = NULL;
in->ops.dpi->disconnect(in, &ddata->dssdev);
+
+ omap_dss_put_device(in);
+ ddata->in = NULL;
}
static int tfp410_enable(struct omap_dss_device *dssdev)
@@ -165,7 +177,6 @@ static int tfp410_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 gpio;
gpio = of_get_named_gpio(node, "powerdown-gpios", 0);
@@ -178,14 +189,6 @@ static int tfp410_probe_of(struct platform_device *pdev)
return gpio;
}
- 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;
}
@@ -201,9 +204,6 @@ static int tfp410_probe(struct platform_device *pdev)
pla