aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/bridge/ptn3460.c27
-rw-r--r--drivers/gpu/drm/drm_bridge.c91
-rw-r--r--drivers/gpu/drm/drm_crtc.c67
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c4
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.h1
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_bridge.c6
-rw-r--r--drivers/gpu/drm/sti/sti_hda.c10
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c10
-rw-r--r--include/drm/bridge/ptn3460.h8
-rw-r--r--include/drm/drm_crtc.h26
11 files changed, 133 insertions, 119 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index cf0eed8208b5..2c239b99de64 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -14,7 +14,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
14 drm_info.o drm_debugfs.o drm_encoder_slave.o \ 14 drm_info.o drm_debugfs.o drm_encoder_slave.o \
15 drm_trace_points.o drm_global.o drm_prime.o \ 15 drm_trace_points.o drm_global.o drm_prime.o \
16 drm_rect.o drm_vma_manager.o drm_flip_work.o \ 16 drm_rect.o drm_vma_manager.o drm_flip_work.o \
17 drm_modeset_lock.o drm_atomic.o 17 drm_modeset_lock.o drm_atomic.o drm_bridge.o
18 18
19drm-$(CONFIG_COMPAT) += drm_ioc32.o 19drm-$(CONFIG_COMPAT) += drm_ioc32.o
20drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o 20drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c
index a2ddc8d73c6a..4a818c1b62e0 100644
--- a/drivers/gpu/drm/bridge/ptn3460.c
+++ b/drivers/gpu/drm/bridge/ptn3460.c
@@ -176,24 +176,11 @@ static void ptn3460_post_disable(struct drm_bridge *bridge)
176{ 176{
177} 177}
178 178
179static void ptn3460_bridge_destroy(struct drm_bridge *bridge)
180{
181 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
182
183 drm_bridge_cleanup(bridge);
184 if (gpio_is_valid(ptn_bridge->gpio_pd_n))
185 gpio_free(ptn_bridge->gpio_pd_n);
186 if (gpio_is_valid(ptn_bridge->gpio_rst_n))
187 gpio_free(ptn_bridge->gpio_rst_n);
188 /* Nothing else to free, we've got devm allocated memory */
189}
190
191static struct drm_bridge_funcs ptn3460_bridge_funcs = { 179static struct drm_bridge_funcs ptn3460_bridge_funcs = {
192 .pre_enable = ptn3460_pre_enable, 180 .pre_enable = ptn3460_pre_enable,
193 .enable = ptn3460_enable, 181 .enable = ptn3460_enable,
194 .disable = ptn3460_disable, 182 .disable = ptn3460_disable,
195 .post_disable = ptn3460_post_disable, 183 .post_disable = ptn3460_post_disable,
196 .destroy = ptn3460_bridge_destroy,
197}; 184};
198 185
199static int ptn3460_get_modes(struct drm_connector *connector) 186static int ptn3460_get_modes(struct drm_connector *connector)
@@ -314,7 +301,7 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
314 } 301 }
315 302
316 ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs; 303 ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
317 ret = drm_bridge_init(dev, &ptn_bridge->bridge); 304 ret = drm_bridge_attach(dev, &ptn_bridge->bridge);
318 if (ret) { 305 if (ret) {
319 DRM_ERROR("Failed to initialize bridge with drm\n"); 306 DRM_ERROR("Failed to initialize bridge with drm\n");
320 goto err; 307 goto err;
@@ -343,3 +330,15 @@ err:
343 return ret; 330 return ret;
344} 331}
345EXPORT_SYMBOL(ptn3460_init); 332EXPORT_SYMBOL(ptn3460_init);
333
334void ptn3460_destroy(struct drm_bridge *bridge)
335{
336 struct ptn3460_bridge *ptn_bridge = bridge->driver_private;
337
338 if (gpio_is_valid(ptn_bridge->gpio_pd_n))
339 gpio_free(ptn_bridge->gpio_pd_n);
340 if (gpio_is_valid(ptn_bridge->gpio_rst_n))
341 gpio_free(ptn_bridge->gpio_rst_n);
342 /* Nothing else to free, we've got devm allocated memory */
343}
344EXPORT_SYMBOL(ptn3460_destroy);
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
new file mode 100644
index 000000000000..d1187e571c6d
--- /dev/null
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright (c) 2014 Samsung Electronics Co., Ltd
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <linux/err.h>
25#include <linux/module.h>
26
27#include <drm/drm_crtc.h>
28
29#include "drm/drmP.h"
30
31static DEFINE_MUTEX(bridge_lock);
32static LIST_HEAD(bridge_list);
33
34int drm_bridge_add(struct drm_bridge *bridge)
35{
36 mutex_lock(&bridge_lock);
37 list_add_tail(&bridge->list, &bridge_list);
38 mutex_unlock(&bridge_lock);
39
40 return 0;
41}
42EXPORT_SYMBOL(drm_bridge_add);
43
44void drm_bridge_remove(struct drm_bridge *bridge)
45{
46 mutex_lock(&bridge_lock);
47 list_del_init(&bridge->list);
48 mutex_unlock(&bridge_lock);
49}
50EXPORT_SYMBOL(drm_bridge_remove);
51
52extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
53{
54 if (!dev || !bridge)
55 return -EINVAL;
56
57 if (bridge->dev)
58 return -EBUSY;
59
60 bridge->dev = dev;
61
62 if (bridge->funcs->attach)
63 return bridge->funcs->attach(bridge);
64
65 return 0;
66}
67EXPORT_SYMBOL(drm_bridge_attach);
68
69#ifdef CONFIG_OF
70struct drm_bridge *of_drm_find_bridge(struct device_node *np)
71{
72 struct drm_bridge *bridge;
73
74 mutex_lock(&bridge_lock);
75
76 list_for_each_entry(bridge, &bridge_list, list) {
77 if (bridge->of_node == np) {
78 mutex_unlock(&bridge_lock);
79 return bridge;
80 }
81 }
82
83 mutex_unlock(&bridge_lock);
84 return NULL;
85}
86EXPORT_SYMBOL(of_drm_find_bridge);
87#endif
88
89MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
90MODULE_DESCRIPTION("DRM bridge infrastructure");
91MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 7936c5c2314c..0e4ec700b0a6 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1066,58 +1066,6 @@ void drm_connector_unplug_all(struct drm_device *dev)
1066EXPORT_SYMBOL(drm_connector_unplug_all); 1066EXPORT_SYMBOL(drm_connector_unplug_all);
1067 1067
1068/** 1068/**
1069 * drm_bridge_init - initialize a drm transcoder/bridge
1070 * @dev: drm device
1071 * @bridge: transcoder/bridge to set up
1072 *
1073 * Initialises a preallocated bridge. Bridges should be
1074 * subclassed as part of driver connector objects.
1075 *
1076 * Returns:
1077 * Zero on success, error code on failure.
1078 */
1079int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge)
1080{
1081 int ret;
1082
1083 drm_modeset_lock_all(dev);
1084
1085 ret = drm_mode_object_get(dev, &bridge->base, DRM_MODE_OBJECT_BRIDGE);
1086 if (ret)
1087 goto out;
1088
1089 bridge->dev = dev;
1090
1091 list_add_tail(&bridge->head, &dev->mode_config.bridge_list);
1092 dev->mode_config.num_bridge++;
1093
1094 out:
1095 drm_modeset_unlock_all(dev);
1096 return ret;
1097}
1098EXPORT_SYMBOL(drm_bridge_init);
1099
1100/**
1101 * drm_bridge_cleanup - cleans up an initialised bridge
1102 * @bridge: bridge to cleanup
1103 *
1104 * Cleans up the bridge but doesn't free the object.
1105 */
1106void drm_bridge_cleanup(struct drm_bridge *bridge)
1107{
1108 struct drm_device *dev = bridge->dev;
1109
1110 drm_modeset_lock_all(dev);
1111 drm_mode_object_put(dev, &bridge->base);
1112 list_del(&bridge->head);
1113 dev->mode_config.num_bridge--;
1114 drm_modeset_unlock_all(dev);
1115
1116 memset(bridge, 0, sizeof(*bridge));
1117}
1118EXPORT_SYMBOL(drm_bridge_cleanup);
1119
1120/**
1121 * drm_encoder_init - Init a preallocated encoder 1069 * drm_encoder_init - Init a preallocated encoder
1122 * @dev: drm device 1070 * @dev: drm device
1123 * @encoder: the encoder to init 1071 * @encoder: the encoder to init
@@ -1712,7 +1660,6 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
1712 total_objects += dev->mode_config.num_crtc; 1660 total_objects += dev->mode_config.num_crtc;
1713 total_objects += dev->mode_config.num_connector; 1661 total_objects += dev->mode_config.num_connector;
1714 total_objects += dev->mode_config.num_encoder; 1662 total_objects += dev->mode_config.num_encoder;
1715 total_objects += dev->mode_config.num_bridge;
1716 1663
1717 group->id_list = kcalloc(total_objects, sizeof(uint32_t), GFP_KERNEL); 1664 group->id_list = kcalloc(total_objects, sizeof(uint32_t), GFP_KERNEL);
1718 if (!group->id_list) 1665 if (!group->id_list)
@@ -1721,7 +1668,6 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
1721 group->num_crtcs = 0; 1668 group->num_crtcs = 0;
1722 group->num_connectors = 0; 1669 group->num_connectors = 0;
1723 group->num_encoders = 0; 1670 group->num_encoders = 0;
1724 group->num_bridges = 0;
1725 return 0; 1671 return 0;
1726} 1672}
1727 1673
@@ -1741,7 +1687,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
1741 struct drm_crtc *crtc; 1687 struct drm_crtc *crtc;
1742 struct drm_encoder *encoder; 1688 struct drm_encoder *encoder;
1743 struct drm_connector *connector; 1689 struct drm_connector *connector;
1744 struct drm_bridge *bridge;
1745 int ret; 1690 int ret;
1746 1691
1747 ret = drm_mode_group_init(dev, group); 1692 ret = drm_mode_group_init(dev, group);
@@ -1759,11 +1704,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
1759 group->id_list[group->num_crtcs + group->num_encoders + 1704 group->id_list[group->num_crtcs + group->num_encoders +
1760 group->num_connectors++] = connector->base.id; 1705 group->num_connectors++] = connector->base.id;
1761 1706
1762 list_for_each_entry(bridge, &dev->mode_config.bridge_list, head)
1763 group->id_list[group->num_crtcs + group->num_encoders +
1764 group->num_connectors + group->num_bridges++] =
1765 bridge->base.id;
1766
1767 return 0; 1707 return 0;
1768} 1708}
1769EXPORT_SYMBOL(drm_mode_group_init_legacy_group); 1709EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
@@ -5440,7 +5380,6 @@ void drm_mode_config_init(struct drm_device *dev)
5440 INIT_LIST_HEAD(&dev->mode_config.fb_list); 5380 INIT_LIST_HEAD(&dev->mode_config.fb_list);
5441 INIT_LIST_HEAD(&dev->mode_config.crtc_list); 5381 INIT_LIST_HEAD(&dev->mode_config.crtc_list);
5442 INIT_LIST_HEAD(&dev->mode_config.connector_list); 5382 INIT_LIST_HEAD(&dev->mode_config.connector_list);
5443 INIT_LIST_HEAD(&dev->mode_config.bridge_list);
5444 INIT_LIST_HEAD(&dev->mode_config.encoder_list); 5383 INIT_LIST_HEAD(&dev->mode_config.encoder_list);
5445 INIT_LIST_HEAD(&dev->mode_config.property_list); 5384 INIT_LIST_HEAD(&dev->mode_config.property_list);
5446 INIT_LIST_HEAD(&dev->mode_config.property_blob_list); 5385 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
@@ -5480,7 +5419,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
5480 struct drm_connector *connector, *ot; 5419 struct drm_connector *connector, *ot;
5481 struct drm_crtc *crtc, *ct; 5420 struct drm_crtc *crtc, *ct;
5482 struct drm_encoder *encoder, *enct; 5421 struct drm_encoder *encoder, *enct;
5483 struct drm_bridge *bridge, *brt;
5484 struct drm_framebuffer *fb, *fbt; 5422 struct drm_framebuffer *fb, *fbt;
5485 struct drm_property *property, *pt; 5423 struct drm_property *property, *pt;
5486 struct drm_property_blob *blob, *bt; 5424 struct drm_property_blob *blob, *bt;
@@ -5491,11 +5429,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
5491 encoder->funcs->destroy(encoder); 5429 encoder->funcs->destroy(encoder);
5492 } 5430 }
5493 5431
5494 list_for_each_entry_safe(bridge, brt,
5495 &dev->mode_config.bridge_list, head) {
5496 bridge->funcs->destroy(bridge);
5497 }
5498
5499 list_for_each_entry_safe(connector, ot, 5432 list_for_each_entry_safe(connector, ot,
5500 &dev->mode_config.connector_list, head) { 5433 &dev->mode_config.connector_list, head) {
5501 connector->funcs->destroy(connector); 5434 connector->funcs->destroy(connector);
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 062c68725376..95f7b8d0f3ef 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -247,9 +247,9 @@ int hdmi_modeset_init(struct hdmi *hdmi,
247 return 0; 247 return 0;
248 248
249fail: 249fail:
250 /* bridge/connector are normally destroyed by drm: */ 250 /* bridge is normally destroyed by drm: */
251 if (hdmi->bridge) { 251 if (hdmi->bridge) {
252 hdmi->bridge->funcs->destroy(hdmi->bridge); 252 hdmi_bridge_destroy(hdmi->bridge);
253 hdmi->bridge = NULL; 253 hdmi->bridge = NULL;
254 } 254 }
255 if (hdmi->connector) { 255 if (hdmi->connector) {
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 43e654f751b7..4d4cad42a776 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -146,6 +146,7 @@ void hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
146 */ 146 */
147 147
148struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi); 148struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi);
149void hdmi_bridge_destroy(struct drm_bridge *bridge);
149 150
150/* 151/*
151 * hdmi connector: 152 * hdmi connector:
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 52ed2b53b246..d6f8d5818e18 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -23,10 +23,9 @@ struct hdmi_bridge {
23}; 23};
24#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base) 24#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
25 25
26static void hdmi_bridge_destroy(struct drm_bridge *bridge) 26void hdmi_bridge_destroy(struct drm_bridge *bridge)
27{ 27{
28 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 28 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
29 drm_bridge_cleanup(bridge);
30 kfree(hdmi_bridge); 29 kfree(hdmi_bridge);
31} 30}
32 31
@@ -200,7 +199,6 @@ static const struct drm_bridge_funcs hdmi_bridge_funcs = {
200 .disable = hdmi_bridge_disable, 199 .disable = hdmi_bridge_disable,
201 .post_disable = hdmi_bridge_post_disable, 200 .post_disable = hdmi_bridge_post_disable,
202 .mode_set = hdmi_bridge_mode_set, 201 .mode_set = hdmi_bridge_mode_set,
203 .destroy = hdmi_bridge_destroy,
204}; 202};
205 203
206 204
@@ -222,7 +220,7 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi)
222 bridge = &hdmi_bridge->base; 220 bridge = &hdmi_bridge->base;
223 bridge->funcs = &hdmi_bridge_funcs; 221 bridge->funcs = &hdmi_bridge_funcs;
224 222
225 drm_bridge_init(hdmi->dev, bridge); 223 drm_bridge_attach(hdmi->dev, bridge);
226 224
227 return bridge; 225 return bridge;
228 226
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index 6cf145de9b41..a9bbb081ecad 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -508,19 +508,12 @@ static void sti_hda_bridge_nope(struct drm_bridge *bridge)
508 /* do nothing */ 508 /* do nothing */
509} 509}
510 510
511static void sti_hda_brigde_destroy(struct drm_bridge *bridge)
512{
513 drm_bridge_cleanup(bridge);
514 kfree(bridge);
515}
516
517static const struct drm_bridge_funcs sti_hda_bridge_funcs = { 511static const struct drm_bridge_funcs sti_hda_bridge_funcs = {
518 .pre_enable = sti_hda_pre_enable, 512 .pre_enable = sti_hda_pre_enable,
519 .enable = sti_hda_bridge_nope, 513 .enable = sti_hda_bridge_nope,
520 .disable = sti_hda_disable, 514 .disable = sti_hda_disable,
521 .post_disable = sti_hda_bridge_nope, 515 .post_disable = sti_hda_bridge_nope,
522 .mode_set = sti_hda_set_mode, 516 .mode_set = sti_hda_set_mode,
523 .destroy = sti_hda_brigde_destroy,
524}; 517};
525 518
526static int sti_hda_connector_get_modes(struct drm_connector *connector) 519static int sti_hda_connector_get_modes(struct drm_connector *connector)
@@ -665,7 +658,7 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
665 658
666 bridge->driver_private = hda; 659 bridge->driver_private = hda;
667 bridge->funcs = &sti_hda_bridge_funcs; 660 bridge->funcs = &sti_hda_bridge_funcs;
668 drm_bridge_init(drm_dev, bridge); 661 drm_bridge_attach(drm_dev, bridge);
669 662
670 encoder->bridge = bridge; 663 encoder->bridge = bridge;
671 connector->encoder = encoder; 664 connector->encoder = encoder;
@@ -694,7 +687,6 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
694err_sysfs: 687err_sysfs:
695 drm_connector_unregister(drm_connector); 688 drm_connector_unregister(drm_connector);
696err_connector: 689err_connector:
697 drm_bridge_cleanup(bridge);
698 drm_connector_cleanup(drm_connector); 690 drm_connector_cleanup(drm_connector);
699 return -EINVAL; 691 return -EINVAL;
700} 692}
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 74e943e655d1..e840ca5de401 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -463,19 +463,12 @@ static void sti_hdmi_bridge_nope(struct drm_bridge *bridge)
463 /* do nothing */ 463 /* do nothing */
464} 464}
465 465
466static void sti_hdmi_brigde_destroy(struct drm_bridge *bridge)
467{
468 drm_bridge_cleanup(bridge);
469 kfree(bridge);
470}
471
472static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = { 466static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = {
473 .pre_enable = sti_hdmi_pre_enable, 467 .pre_enable = sti_hdmi_pre_enable,
474 .enable = sti_hdmi_bridge_nope, 468 .enable = sti_hdmi_bridge_nope,
475 .disable = sti_hdmi_disable, 469 .disable = sti_hdmi_disable,
476 .post_disable = sti_hdmi_bridge_nope, 470 .post_disable = sti_hdmi_bridge_nope,
477 .mode_set = sti_hdmi_set_mode, 471 .mode_set = sti_hdmi_set_mode,
478 .destroy = sti_hdmi_brigde_destroy,
479}; 472};
480 473
481static int sti_hdmi_connector_get_modes(struct drm_connector *connector) 474static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
@@ -636,7 +629,7 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
636 629
637 bridge->driver_private = hdmi; 630 bridge->driver_private = hdmi;
638 bridge->funcs = &sti_hdmi_bridge_funcs; 631 bridge->funcs = &sti_hdmi_bridge_funcs;
639 drm_bridge_init(drm_dev, bridge); 632 drm_bridge_attach(drm_dev, bridge);
640 633
641 encoder->bridge = bridge; 634 encoder->bridge = bridge;
642 connector->encoder = encoder; 635 connector->encoder = encoder;
@@ -668,7 +661,6 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
668err_sysfs: 661err_sysfs:
669 drm_connector_unregister(drm_connector); 662 drm_connector_unregister(drm_connector);
670err_connector: 663err_connector:
671 drm_bridge_cleanup(bridge);
672 drm_connector_cleanup(drm_connector); 664 drm_connector_cleanup(drm_connector);
673err_adapt: 665err_adapt:
674 put_device(&hdmi->ddc_adapt->dev); 666 put_device(&hdmi->ddc_adapt->dev);
diff --git a/include/drm/bridge/ptn3460.h b/include/drm/bridge/ptn3460.h
index ff62344fec6c..b11f8e17e72f 100644
--- a/include/drm/bridge/ptn3460.h
+++ b/include/drm/bridge/ptn3460.h
@@ -15,6 +15,7 @@
15#define _DRM_BRIDGE_PTN3460_H_ 15#define _DRM_BRIDGE_PTN3460_H_
16 16
17struct drm_device; 17struct drm_device;
18struct drm_bridge;
18struct drm_encoder; 19struct drm_encoder;
19struct i2c_client; 20struct i2c_client;
20struct device_node; 21struct device_node;
@@ -23,6 +24,9 @@ struct device_node;
23 24
24int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, 25int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
25 struct i2c_client *client, struct device_node *node); 26 struct i2c_client *client, struct device_node *node);
27
28void ptn3460_destroy(struct drm_bridge *bridge);
29
26#else 30#else
27 31
28static inline int ptn3460_init(struct drm_device *dev, 32static inline int ptn3460_init(struct drm_device *dev,
@@ -32,6 +36,10 @@ static inline int ptn3460_init(struct drm_device *dev,
32 return 0; 36 return 0;
33} 37}
34 38
39static inline void ptn3460_destroy(struct drm_bridge *bridge)
40{
41}
42
35#endif 43#endif
36 44
37#endif 45#endif
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 15bb762fb316..920e21a8f3fd 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -868,15 +868,16 @@ struct drm_plane {
868 868
869/** 869/**
870 * struct drm_bridge_funcs - drm_bridge control functions 870 * struct drm_bridge_funcs - drm_bridge control functions
871 * @attach: Called during drm_bridge_attach
871 * @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge 872 * @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge
872 * @disable: Called right before encoder prepare, disables the bridge 873 * @disable: Called right before encoder prepare, disables the bridge
873 * @post_disable: Called right after encoder prepare, for lockstepped disable 874 * @post_disable: Called right after encoder prepare, for lockstepped disable
874 * @mode_set: Set this mode to the bridge 875 * @mode_set: Set this mode to the bridge
875 * @pre_enable: Called right before encoder commit, for lockstepped commit 876 * @pre_enable: Called right before encoder commit, for lockstepped commit
876 * @enable: Called right after encoder commit, enables the bridge 877 * @enable: Called right after encoder commit, enables the bridge
877 * @destroy: make object go away
878 */ 878 */
879struct drm_bridge_funcs { 879struct drm_bridge_funcs {
880 int (*attach)(struct drm_bridge *bridge);
880 bool (*mode_fixup)(struct drm_bridge *bridge, 881 bool (*mode_fixup)(struct drm_bridge *bridge,
881 const struct drm_display_mode *mode, 882 const struct drm_display_mode *mode,
882 struct drm_display_mode *adjusted_mode); 883 struct drm_display_mode *adjusted_mode);
@@ -887,22 +888,24 @@ struct drm_bridge_funcs {
887 struct drm_display_mode *adjusted_mode); 888 struct drm_display_mode *adjusted_mode);
888 void (*pre_enable)(struct drm_bridge *bridge); 889 void (*pre_enable)(struct drm_bridge *bridge);
889 void (*enable)(struct drm_bridge *bridge); 890 void (*enable)(struct drm_bridge *bridge);
890 void (*destroy)(struct drm_bridge *bridge);
891}; 891};
892 892
893/** 893/**
894 * struct drm_bridge - central DRM bridge control structure 894 * struct drm_bridge - central DRM bridge control structure
895 * @dev: DRM device this bridge belongs to 895 * @dev: DRM device this bridge belongs to
896 * @head: list management 896 * @of_node: device node pointer to the bridge
897 * @list: to keep track of all added bridges
897 * @base: base mode object 898 * @base: base mode object
898 * @funcs: control functions 899 * @funcs: control functions
899 * @driver_private: pointer to the bridge driver's internal context 900 * @driver_private: pointer to the bridge driver's internal context
900 */ 901 */
901struct drm_bridge { 902struct drm_bridge {
902 struct drm_device *dev; 903 struct drm_device *dev;
903 struct list_head head; 904 struct drm_encoder *encoder;
904 905#ifdef CONFIG_OF
905 struct drm_mode_object base; 906 struct device_node *of_node;
907#endif
908 struct list_head list;
906 909
907 const struct drm_bridge_funcs *funcs; 910 const struct drm_bridge_funcs *funcs;
908 void *driver_private; 911 void *driver_private;
@@ -1007,7 +1010,6 @@ struct drm_mode_group {
1007 uint32_t num_crtcs; 1010 uint32_t num_crtcs;
1008 uint32_t num_encoders; 1011 uint32_t num_encoders;
1009 uint32_t num_connectors; 1012 uint32_t num_connectors;
1010 uint32_t num_bridges;
1011 1013
1012 /* list of object IDs for this group */ 1014 /* list of object IDs for this group */
1013 uint32_t *id_list; 1015 uint32_t *id_list;
@@ -1026,8 +1028,6 @@ struct drm_mode_group {
1026 * @fb_list: list of framebuffers available 1028 * @fb_list: list of framebuffers available
1027 * @num_connector: number of connectors on this device 1029 * @num_connector: number of connectors on this device
1028 * @connector_list: list of connector objects 1030 * @connector_list: list of connector objects
1029 * @num_bridge: number of bridges on this device
1030 * @bridge_list: list of bridge objects
1031 * @num_encoder: number of encoders on this device 1031 * @num_encoder: number of encoders on this device
1032 * @encoder_list: list of encoder objects 1032 * @encoder_list: list of encoder objects
1033 * @num_overlay_plane: number of overlay planes on this device 1033 * @num_overlay_plane: number of overlay planes on this device
@@ -1072,8 +1072,6 @@ struct drm_mode_config {
1072 1072
1073 int num_connector; 1073 int num_connector;
1074 struct list_head connector_list; 1074 struct list_head connector_list;
1075 int num_bridge;
1076 struct list_head bridge_list;
1077 int num_encoder; 1075 int num_encoder;
1078 struct list_head encoder_list; 1076 struct list_head encoder_list;
1079 1077
@@ -1222,8 +1220,10 @@ extern unsigned int drm_connector_index(struct drm_connector *connector);
1222/* helper to unplug all connectors from sysfs for device */ 1220/* helper to unplug all connectors from sysfs for device */
1223extern void drm_connector_unplug_all(struct drm_device *dev); 1221extern void drm_connector_unplug_all(struct drm_device *dev);
1224 1222
1225extern int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge); 1223extern int drm_bridge_add(struct drm_bridge *bridge);
1226extern void drm_bridge_cleanup(struct drm_bridge *bridge); 1224extern void drm_bridge_remove(struct drm_bridge *bridge);
1225extern struct drm_bridge *of_drm_find_bridge(struct device_node *np);
1226extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge);
1227 1227
1228extern int drm_encoder_init(struct drm_device *dev, 1228extern int drm_encoder_init(struct drm_device *dev,
1229 struct drm_encoder *encoder, 1229 struct drm_encoder *encoder,