drm/omap: Reverse direction of DSS device (dis)connect operations

The omapdrm and omapdss drivers are architectured based on display
pipelines made of multiple components handled from sink (display) to
source (DSS output). This is incompatible with the DRM bridge and panel
APIs that handle components from source to sink.

To reconcile the omapdrm and omapdss drivers with the DRM bridge and
panel model, we need to reverse the direction of the DSS device
operations. Start with the connect and disconnect operations.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
Laurent Pinchart 2018-03-04 23:42:36 +02:00 committed by Tomi Valkeinen
parent 2ee767922e
commit 511afb44d7
24 changed files with 239 additions and 432 deletions

View File

@ -41,33 +41,15 @@ static const struct videomode tvc_pal_vm = {
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
static int tvc_connect(struct omap_dss_device *dssdev)
static int tvc_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
}
static void tvc_disconnect(struct omap_dss_device *dssdev)
static void tvc_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int tvc_enable(struct omap_dss_device *dssdev)
@ -184,7 +166,6 @@ static int __exit tvc_remove(struct platform_device *pdev)
omapdss_device_unregister(&ddata->dssdev);
tvc_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
return 0;
}

View File

@ -56,33 +56,15 @@ struct panel_drv_data {
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
static int dvic_connect(struct omap_dss_device *dssdev)
static int dvic_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
}
static void dvic_disconnect(struct omap_dss_device *dssdev)
static void dvic_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int dvic_enable(struct omap_dss_device *dssdev)
@ -405,7 +387,6 @@ static int __exit dvic_remove(struct platform_device *pdev)
omapdss_device_unregister(&ddata->dssdev);
dvic_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
i2c_put_adapter(ddata->i2c_adapter);

View File

@ -51,33 +51,15 @@ struct panel_drv_data {
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
static int hdmic_connect(struct omap_dss_device *dssdev)
static int hdmic_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
}
static void hdmic_disconnect(struct omap_dss_device *dssdev)
static void hdmic_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int hdmic_enable(struct omap_dss_device *dssdev)
@ -364,7 +346,6 @@ static int __exit hdmic_remove(struct platform_device *pdev)
omapdss_device_unregister(&ddata->dssdev);
hdmic_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
return 0;
}

View File

@ -31,36 +31,16 @@ struct panel_drv_data {
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
static int opa362_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static int opa362_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(src);
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
return omapdss_device_connect(dst->dss, dst, dst->next);
}
static void opa362_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static void opa362_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, &ddata->dssdev);
omapdss_device_put(src);
omapdss_device_disconnect(dst, dst->next);
}
static int opa362_enable(struct omap_dss_device *dssdev)
@ -196,7 +176,7 @@ static int __exit opa362_remove(struct platform_device *pdev)
WARN_ON(omapdss_device_is_connected(dssdev));
if (omapdss_device_is_connected(dssdev))
omapdss_device_disconnect(dssdev, dssdev->dst);
omapdss_device_disconnect(NULL, dssdev);
return 0;
}

View File

@ -27,36 +27,16 @@ struct panel_drv_data {
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
static int tfp410_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static int tfp410_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(src);
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
return omapdss_device_connect(dst->dss, dst, dst->next);
}
static void tfp410_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static void tfp410_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, &ddata->dssdev);
omapdss_device_put(src);
omapdss_device_disconnect(dst, dst->next);
}
static int tfp410_enable(struct omap_dss_device *dssdev)
@ -219,7 +199,7 @@ static int __exit tfp410_remove(struct platform_device *pdev)
WARN_ON(omapdss_device_is_connected(dssdev));
if (omapdss_device_is_connected(dssdev))
omapdss_device_disconnect(dssdev, dssdev->dst);
omapdss_device_disconnect(NULL, dssdev);
return 0;
}

View File

@ -35,24 +35,15 @@ struct panel_drv_data {
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
static int tpd_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static int tpd_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src;
struct panel_drv_data *ddata = to_panel_data(dst);
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return PTR_ERR(src);
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
r = omapdss_device_connect(dst->dss, dst, dst->next);
if (r)
return r;
}
gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1);
gpiod_set_value_cansleep(ddata->ls_oe_gpio, 1);
@ -63,18 +54,15 @@ static int tpd_connect(struct omap_dss_device *dssdev,
return 0;
}
static void tpd_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static void tpd_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
struct panel_drv_data *ddata = to_panel_data(dst);
gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0);
gpiod_set_value_cansleep(ddata->ls_oe_gpio, 0);
omapdss_device_disconnect(src, &ddata->dssdev);
omapdss_device_put(src);
omapdss_device_disconnect(dst, dst->next);
}
static int tpd_enable(struct omap_dss_device *dssdev)
@ -328,7 +316,7 @@ static int __exit tpd_remove(struct platform_device *pdev)
WARN_ON(omapdss_device_is_connected(dssdev));
if (omapdss_device_is_connected(dssdev))
omapdss_device_disconnect(dssdev, dssdev->dst);
omapdss_device_disconnect(NULL, dssdev);
return 0;
}

View File

@ -34,33 +34,15 @@ struct panel_drv_data {
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
static int panel_dpi_connect(struct omap_dss_device *dssdev)
static int panel_dpi_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
}
static void panel_dpi_disconnect(struct omap_dss_device *dssdev)
static void panel_dpi_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int panel_dpi_enable(struct omap_dss_device *dssdev)
@ -233,7 +215,6 @@ static int __exit panel_dpi_remove(struct platform_device *pdev)
omapdss_device_unregister(dssdev);
panel_dpi_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
return 0;
}

View File

@ -756,57 +756,35 @@ static int dsicm_panel_reset(struct panel_drv_data *ddata)
return dsicm_power_on(ddata);
}
static int dsicm_connect(struct omap_dss_device *dssdev)
static int dsicm_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct panel_drv_data *ddata = to_panel_data(dst);
struct device *dev = &ddata->pdev->dev;
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
dev_err(dev, "Failed to connect to video source\n");
goto err_connect;
}
r = src->ops->dsi.request_vc(src, &ddata->channel);
if (r) {
dev_err(dev, "failed to get virtual channel\n");
goto err_req_vc;
return r;
}
r = src->ops->dsi.set_vc_id(src, ddata->channel, TCH);
if (r) {
dev_err(dev, "failed to set VC_ID\n");
goto err_vc_id;
src->ops->dsi.release_vc(src, ddata->channel);
return r;
}
return 0;
err_vc_id:
src->ops->dsi.release_vc(src, ddata->channel);
err_req_vc:
omapdss_device_disconnect(src, dssdev);
err_connect:
omapdss_device_put(src);
return r;
}
static void dsicm_disconnect(struct omap_dss_device *dssdev)
static void dsicm_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
struct panel_drv_data *ddata = to_panel_data(dst);
src->ops->dsi.release_vc(src, ddata->channel);
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int dsicm_enable(struct omap_dss_device *dssdev)
@ -1404,7 +1382,7 @@ static int __exit dsicm_remove(struct platform_device *pdev)
omapdss_device_unregister(dssdev);
dsicm_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
omapdss_device_disconnect(dssdev->src, dssdev);
sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group);

View File

@ -115,36 +115,19 @@ static void init_lb035q02_panel(struct spi_device *spi)
lb035q02_write_reg(spi, 0x3b, 0x0806);
}
static int lb035q02_connect(struct omap_dss_device *dssdev)
static int lb035q02_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
struct panel_drv_data *ddata = to_panel_data(dst);
init_lb035q02_panel(ddata->spi);
return 0;
}
static void lb035q02_disconnect(struct omap_dss_device *dssdev)
static void lb035q02_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int lb035q02_enable(struct omap_dss_device *dssdev)
@ -285,7 +268,6 @@ static int lb035q02_panel_spi_remove(struct spi_device *spi)
omapdss_device_unregister(dssdev);
lb035q02_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
return 0;
}

View File

@ -111,33 +111,15 @@ static int init_nec_8048_wvga_lcd(struct spi_device *spi)
return 0;
}
static int nec_8048_connect(struct omap_dss_device *dssdev)
static int nec_8048_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
}
static void nec_8048_disconnect(struct omap_dss_device *dssdev)
static void nec_8048_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int nec_8048_enable(struct omap_dss_device *dssdev)
@ -310,7 +292,6 @@ static int nec_8048_remove(struct spi_device *spi)
omapdss_device_unregister(dssdev);
nec_8048_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
return 0;
}

View File

@ -57,33 +57,15 @@ static const struct videomode sharp_ls_vm = {
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
static int sharp_ls_connect(struct omap_dss_device *dssdev)
static int sharp_ls_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
}
static void sharp_ls_disconnect(struct omap_dss_device *dssdev)
static void sharp_ls_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int sharp_ls_enable(struct omap_dss_device *dssdev)
@ -284,7 +266,6 @@ static int __exit sharp_ls_remove(struct platform_device *pdev)
omapdss_device_unregister(dssdev);
sharp_ls_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
return 0;
}

View File

@ -506,33 +506,15 @@ static const struct attribute_group bldev_attr_group = {
.attrs = bldev_attrs,
};
static int acx565akm_connect(struct omap_dss_device *dssdev)
static int acx565akm_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
}
static void acx565akm_disconnect(struct omap_dss_device *dssdev)
static void acx565akm_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
@ -822,7 +804,6 @@ static int acx565akm_remove(struct spi_device *spi)
omapdss_device_unregister(dssdev);
acx565akm_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
return 0;
}

View File

@ -165,33 +165,15 @@ enum jbt_register {
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
static int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
static int td028ttec1_panel_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
}
static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
static void td028ttec1_panel_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
@ -411,7 +393,6 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
omapdss_device_unregister(dssdev);
td028ttec1_panel_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
return 0;
}

View File

@ -336,33 +336,15 @@ static void tpo_td043_power_off(struct panel_drv_data *ddata)
ddata->powered_on = 0;
}
static int tpo_td043_connect(struct omap_dss_device *dssdev)
static int tpo_td043_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src;
int r;
src = omapdss_of_find_connected_device(dssdev->dev->of_node, 0);
if (IS_ERR_OR_NULL(src)) {
dev_err(dssdev->dev, "failed to find video source\n");
return src ? PTR_ERR(src) : -EINVAL;
}
r = omapdss_device_connect(dssdev->dss, src, dssdev);
if (r) {
omapdss_device_put(src);
return r;
}
return 0;
}
static void tpo_td043_disconnect(struct omap_dss_device *dssdev)
static void tpo_td043_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct omap_dss_device *src = dssdev->src;
omapdss_device_disconnect(src, dssdev);
omapdss_device_put(src);
}
static int tpo_td043_enable(struct omap_dss_device *dssdev)
@ -553,7 +535,6 @@ static int tpo_td043_remove(struct spi_device *spi)
omapdss_device_unregister(dssdev);
tpo_td043_disable(dssdev);
omapdss_device_disconnect(dssdev, NULL);
sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);

View File

@ -190,24 +190,24 @@ int omapdss_device_connect(struct dss_device *dss,
{
int ret;
dev_dbg(src->dev, "connect\n");
dev_dbg(dst->dev, "connect\n");
if (omapdss_device_is_connected(src))
if (omapdss_device_is_connected(dst))
return -EBUSY;
src->dss = dss;
dst->dss = dss;
if (src->driver)
ret = src->driver->connect(src);
if (dst->driver)
ret = dst->driver->connect(src, dst);
else
ret = src->ops->connect(src, dst);
ret = dst->ops->connect(src, dst);
if (ret < 0) {
src->dss = NULL;
dst->dss = NULL;
return ret;
}
if (dst) {
if (src) {
dst->src = src;
src->dst = dst;
}
@ -219,14 +219,14 @@ EXPORT_SYMBOL_GPL(omapdss_device_connect);
void omapdss_device_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
dev_dbg(src->dev, "disconnect\n");
dev_dbg(dst->dev, "disconnect\n");
if (!src->id && !omapdss_device_is_connected(src)) {
WARN_ON(!src->driver);
if (!dst->id && !omapdss_device_is_connected(dst)) {
WARN_ON(!dst->driver);
return;
}
if (dst) {
if (src) {
if (WARN_ON(dst != src->dst))
return;
@ -234,12 +234,12 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
src->dst = NULL;
}
if (src->driver)
src->driver->disconnect(src);
if (dst->driver)
dst->driver->disconnect(src, dst);
else
src->ops->disconnect(src, dst);
dst->ops->disconnect(src, dst);
src->dss = NULL;
dst->dss = NULL;
}
EXPORT_SYMBOL_GPL(omapdss_device_disconnect);

View File

@ -608,35 +608,45 @@ static enum omap_channel dpi_get_channel(struct dpi_data *dpi)
}
}
static int dpi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static int dpi_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct dpi_data *dpi = dpi_get_data_from_dssdev(dst);
int r;
dpi_init_pll(dpi);
r = dss_mgr_connect(dssdev);
r = dss_mgr_connect(dst);
if (r)
return r;
r = omapdss_output_set_device(dssdev, dst);
r = omapdss_output_set_device(dst, dst->next);
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(dssdev);
return r;
goto err_mgr_disconnect;
}
r = omapdss_device_connect(dst->dss, dst, dst->next);
if (r)
goto err_output_unset;
return 0;
err_output_unset:
omapdss_output_unset_device(dst);
err_mgr_disconnect:
dss_mgr_disconnect(dst);
return r;
}
static void dpi_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static void dpi_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
omapdss_output_unset_device(dssdev);
omapdss_device_disconnect(dst, dst->next);
omapdss_output_unset_device(dst);
dss_mgr_disconnect(dssdev);
dss_mgr_disconnect(dst);
}
static const struct omap_dss_device_ops dpi_ops = {

View File

@ -4881,32 +4881,42 @@ static int dsi_get_clocks(struct dsi_data *dsi)
return 0;
}
static int dsi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static int dsi_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
int r;
r = dss_mgr_connect(dssdev);
r = dss_mgr_connect(dst);
if (r)
return r;
r = omapdss_output_set_device(dssdev, dst);
r = omapdss_output_set_device(dst, dst->next);
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dssdev->name);
dss_mgr_disconnect(dssdev);
return r;
dst->name);
goto err_mgr_disconnect;
}
r = omapdss_device_connect(dst->dss, dst, dst->next);
if (r)
goto err_output_unset;
return 0;
err_output_unset:
omapdss_output_unset_device(dst);
err_mgr_disconnect:
dss_mgr_disconnect(dst);
return r;
}
static void dsi_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static void dsi_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
omapdss_output_unset_device(dssdev);
omapdss_device_disconnect(dst, dst->next);
omapdss_output_unset_device(dst);
dss_mgr_disconnect(dssdev);
dss_mgr_disconnect(dst);
}
static const struct omap_dss_device_ops dsi_ops = {

View File

@ -428,32 +428,42 @@ void hdmi4_core_disable(struct hdmi_core_data *core)
mutex_unlock(&hdmi->lock);
}
static int hdmi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static int hdmi_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
int r;
r = dss_mgr_connect(dssdev);
r = dss_mgr_connect(dst);
if (r)
return r;
r = omapdss_output_set_device(dssdev, dst);
r = omapdss_output_set_device(dst, dst->next);
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(dssdev);
return r;
goto err_mgr_disconnect;
}
r = omapdss_device_connect(dst->dss, dst, dst->next);
if (r)
goto err_output_unset;
return 0;
err_output_unset:
omapdss_output_unset_device(dst);
err_mgr_disconnect:
dss_mgr_disconnect(dst);
return r;
}
static void hdmi_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static void hdmi_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
omapdss_output_unset_device(dssdev);
omapdss_device_disconnect(dst, dst->next);
omapdss_output_unset_device(dst);
dss_mgr_disconnect(dssdev);
dss_mgr_disconnect(dst);
}
static int hdmi_read_edid(struct omap_dss_device *dssdev,

View File

@ -433,32 +433,42 @@ static void hdmi_core_disable(struct omap_hdmi *hdmi)
mutex_unlock(&hdmi->lock);
}
static int hdmi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static int hdmi_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
int r;
r = dss_mgr_connect(dssdev);
r = dss_mgr_connect(dst);
if (r)
return r;
r = omapdss_output_set_device(dssdev, dst);
r = omapdss_output_set_device(dst, dst->next);
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(dssdev);
return r;
goto err_mgr_disconnect;
}
r = omapdss_device_connect(dst->dss, dst, dst->next);
if (r)
goto err_output_unset;
return 0;
err_output_unset:
omapdss_output_unset_device(dst);
err_mgr_disconnect:
dss_mgr_disconnect(dst);
return r;
}
static void hdmi_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static void hdmi_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
omapdss_output_unset_device(dssdev);
omapdss_device_disconnect(dst, dst->next);
omapdss_output_unset_device(dst);
dss_mgr_disconnect(dssdev);
dss_mgr_disconnect(dst);
}
static int hdmi_read_edid(struct omap_dss_device *dssdev,

View File

@ -437,8 +437,10 @@ struct omap_dss_driver {
int (*probe)(struct omap_dss_device *);
void (*remove)(struct omap_dss_device *);
int (*connect)(struct omap_dss_device *dssdev);
void (*disconnect)(struct omap_dss_device *dssdev);
int (*connect)(struct omap_dss_device *src,
struct omap_dss_device *dst);
void (*disconnect)(struct omap_dss_device *src,
struct omap_dss_device *dst);
int (*enable)(struct omap_dss_device *display);
void (*disable)(struct omap_dss_device *display);

View File

@ -252,32 +252,42 @@ static int sdi_check_timings(struct omap_dss_device *dssdev,
return 0;
}
static int sdi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static int sdi_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
int r;
r = dss_mgr_connect(dssdev);
r = dss_mgr_connect(dst);
if (r)
return r;
r = omapdss_output_set_device(dssdev, dst);
r = omapdss_output_set_device(dst, dst);
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(dssdev);
return r;
goto err_mgr_disconnect;
}
r = omapdss_device_connect(dst->dss, dst, dst->next);
if (r)
goto err_output_unset;
return 0;
err_output_unset:
omapdss_output_unset_device(dst);
err_mgr_disconnect:
dss_mgr_disconnect(dst);
return r;
}
static void sdi_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static void sdi_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
omapdss_output_unset_device(dssdev);
omapdss_device_disconnect(dst, dst->next);
omapdss_output_unset_device(dst);
dss_mgr_disconnect(dssdev);
dss_mgr_disconnect(dst);
}
static const struct omap_dss_device_ops sdi_ops = {

View File

@ -691,32 +691,42 @@ static int venc_get_clocks(struct venc_device *venc)
return 0;
}
static int venc_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static int venc_connect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
int r;
r = dss_mgr_connect(dssdev);
r = dss_mgr_connect(dst);
if (r)
return r;
r = omapdss_output_set_device(dssdev, dst);
r = omapdss_output_set_device(dst, dst->next);
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(dssdev);
return r;
goto err_mgr_disconnect;
}
r = omapdss_device_connect(dst->dss, dst, dst->next);
if (r)
goto err_output_unset;
return 0;
err_output_unset:
omapdss_output_unset_device(dst);
err_mgr_disconnect:
dss_mgr_disconnect(dst);
return r;
}
static void venc_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
static void venc_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst)
{
omapdss_output_unset_device(dssdev);
omapdss_device_disconnect(dst, dst->next);
omapdss_output_unset_device(dst);
dss_mgr_disconnect(dssdev);
dss_mgr_disconnect(dst);
}
static const struct omap_dss_device_ops venc_ops = {

View File

@ -157,11 +157,14 @@ static void omap_disconnect_pipelines(struct drm_device *ddev)
unsigned int i;
for (i = 0; i < priv->num_pipes; i++) {
struct omap_dss_device *display = priv->pipes[i].display;
struct omap_drm_pipeline *pipe = &priv->pipes[i];
omapdss_device_disconnect(display, NULL);
priv->pipes[i].display = NULL;
omapdss_device_put(display);
omapdss_device_disconnect(NULL, pipe->output);
omapdss_device_put(pipe->output);
omapdss_device_put(pipe->display);
pipe->output = NULL;
pipe->display = NULL;
}
priv->num_pipes = 0;
@ -182,26 +185,30 @@ static int omap_compare_pipes(const void *a, const void *b)
static int omap_connect_pipelines(struct drm_device *ddev)
{
struct omap_drm_private *priv = ddev->dev_private;
struct omap_dss_device *display = NULL;
struct omap_dss_device *output = NULL;
int r;
if (!omapdss_stack_is_ready())
return -EPROBE_DEFER;
for_each_dss_display(display) {
r = omapdss_device_connect(priv->dss, display, NULL);
for_each_dss_output(output) {
r = omapdss_device_connect(priv->dss, NULL, output);
if (r == -EPROBE_DEFER) {
omapdss_device_put(display);
omapdss_device_put(output);
goto cleanup;
} else if (r) {
dev_warn(display->dev, "could not connect display: %s\n",
display->name);
dev_warn(output->dev, "could not connect output %s\n",
output->name);
} else {
omapdss_device_get(display);
priv->pipes[priv->num_pipes++].display = display;
struct omap_drm_pipeline *pipe;
pipe = &priv->pipes[priv->num_pipes++];
pipe->output = omapdss_device_get(output);
pipe->display = omapdss_display_get(output);
if (priv->num_pipes == ARRAY_SIZE(priv->pipes)) {
/* To balance the 'for_each_dss_display' loop */
omapdss_device_put(display);
/* To balance the 'for_each_dss_output' loop */
omapdss_device_put(output);
break;
}
}

View File

@ -49,6 +49,7 @@ struct omap_drm_pipeline {
struct drm_crtc *crtc;
struct drm_encoder *encoder;
struct drm_connector *connector;
struct omap_dss_device *output;
struct omap_dss_device *display;
};