diff options
Diffstat (limited to 'drivers/gpu/drm/bridge/lvds-encoder.c')
| -rw-r--r-- | drivers/gpu/drm/bridge/lvds-encoder.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/drivers/gpu/drm/bridge/lvds-encoder.c b/drivers/gpu/drm/bridge/lvds-encoder.c index 0903ba574f61..75b0d3f6e4de 100644 --- a/drivers/gpu/drm/bridge/lvds-encoder.c +++ b/drivers/gpu/drm/bridge/lvds-encoder.c | |||
| @@ -13,13 +13,37 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/of_graph.h> | 14 | #include <linux/of_graph.h> |
| 15 | 15 | ||
| 16 | struct lvds_encoder { | ||
| 17 | struct drm_bridge bridge; | ||
| 18 | struct drm_bridge *panel_bridge; | ||
| 19 | }; | ||
| 20 | |||
| 21 | static int lvds_encoder_attach(struct drm_bridge *bridge) | ||
| 22 | { | ||
| 23 | struct lvds_encoder *lvds_encoder = container_of(bridge, | ||
| 24 | struct lvds_encoder, | ||
| 25 | bridge); | ||
| 26 | |||
| 27 | return drm_bridge_attach(bridge->encoder, lvds_encoder->panel_bridge, | ||
| 28 | bridge); | ||
| 29 | } | ||
| 30 | |||
| 31 | static struct drm_bridge_funcs funcs = { | ||
| 32 | .attach = lvds_encoder_attach, | ||
| 33 | }; | ||
| 34 | |||
| 16 | static int lvds_encoder_probe(struct platform_device *pdev) | 35 | static int lvds_encoder_probe(struct platform_device *pdev) |
| 17 | { | 36 | { |
| 18 | struct device_node *port; | 37 | struct device_node *port; |
| 19 | struct device_node *endpoint; | 38 | struct device_node *endpoint; |
| 20 | struct device_node *panel_node; | 39 | struct device_node *panel_node; |
| 21 | struct drm_panel *panel; | 40 | struct drm_panel *panel; |
| 22 | struct drm_bridge *bridge; | 41 | struct lvds_encoder *lvds_encoder; |
| 42 | |||
| 43 | lvds_encoder = devm_kzalloc(&pdev->dev, sizeof(*lvds_encoder), | ||
| 44 | GFP_KERNEL); | ||
| 45 | if (!lvds_encoder) | ||
| 46 | return -ENOMEM; | ||
| 23 | 47 | ||
| 24 | /* Locate the panel DT node. */ | 48 | /* Locate the panel DT node. */ |
| 25 | port = of_graph_get_port_by_id(pdev->dev.of_node, 1); | 49 | port = of_graph_get_port_by_id(pdev->dev.of_node, 1); |
| @@ -49,20 +73,30 @@ static int lvds_encoder_probe(struct platform_device *pdev) | |||
| 49 | return -EPROBE_DEFER; | 73 | return -EPROBE_DEFER; |
| 50 | } | 74 | } |
| 51 | 75 | ||
| 52 | bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_LVDS); | 76 | lvds_encoder->panel_bridge = |
| 53 | if (IS_ERR(bridge)) | 77 | devm_drm_panel_bridge_add(&pdev->dev, |
| 54 | return PTR_ERR(bridge); | 78 | panel, DRM_MODE_CONNECTOR_LVDS); |
| 79 | if (IS_ERR(lvds_encoder->panel_bridge)) | ||
| 80 | return PTR_ERR(lvds_encoder->panel_bridge); | ||
| 81 | |||
| 82 | /* The panel_bridge bridge is attached to the panel's of_node, | ||
| 83 | * but we need a bridge attached to our of_node for our user | ||
| 84 | * to look up. | ||
| 85 | */ | ||
| 86 | lvds_encoder->bridge.of_node = pdev->dev.of_node; | ||
| 87 | lvds_encoder->bridge.funcs = &funcs; | ||
| 88 | drm_bridge_add(&lvds_encoder->bridge); | ||
| 55 | 89 | ||
| 56 | platform_set_drvdata(pdev, bridge); | 90 | platform_set_drvdata(pdev, lvds_encoder); |
| 57 | 91 | ||
| 58 | return 0; | 92 | return 0; |
| 59 | } | 93 | } |
| 60 | 94 | ||
| 61 | static int lvds_encoder_remove(struct platform_device *pdev) | 95 | static int lvds_encoder_remove(struct platform_device *pdev) |
| 62 | { | 96 | { |
| 63 | struct drm_bridge *bridge = platform_get_drvdata(pdev); | 97 | struct lvds_encoder *lvds_encoder = platform_get_drvdata(pdev); |
| 64 | 98 | ||
| 65 | drm_bridge_remove(bridge); | 99 | drm_bridge_remove(&lvds_encoder->bridge); |
| 66 | 100 | ||
| 67 | return 0; | 101 | return 0; |
| 68 | } | 102 | } |
