1/* 2 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 and 6 * only version 2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14#include <linux/of_irq.h> 15#include "edp.h" 16 17static irqreturn_t edp_irq(int irq, void *dev_id) 18{ 19 struct msm_edp *edp = dev_id; 20 21 /* Process eDP irq */ 22 return msm_edp_ctrl_irq(edp->ctrl); 23} 24 25static void edp_destroy(struct platform_device *pdev) 26{ 27 struct msm_edp *edp = platform_get_drvdata(pdev); 28 29 if (!edp) 30 return; 31 32 if (edp->ctrl) { 33 msm_edp_ctrl_destroy(edp->ctrl); 34 edp->ctrl = NULL; 35 } 36 37 platform_set_drvdata(pdev, NULL); 38} 39 40/* construct eDP at bind/probe time, grab all the resources. */ 41static struct msm_edp *edp_init(struct platform_device *pdev) 42{ 43 struct msm_edp *edp = NULL; 44 int ret; 45 46 if (!pdev) { 47 pr_err("no eDP device\n"); 48 ret = -ENXIO; 49 goto fail; 50 } 51 52 edp = devm_kzalloc(&pdev->dev, sizeof(*edp), GFP_KERNEL); 53 if (!edp) { 54 ret = -ENOMEM; 55 goto fail; 56 } 57 DBG("eDP probed=%p", edp); 58 59 edp->pdev = pdev; 60 platform_set_drvdata(pdev, edp); 61 62 ret = msm_edp_ctrl_init(edp); 63 if (ret) 64 goto fail; 65 66 return edp; 67 68fail: 69 if (edp) 70 edp_destroy(pdev); 71 72 return ERR_PTR(ret); 73} 74 75static int edp_bind(struct device *dev, struct device *master, void *data) 76{ 77 struct drm_device *drm = dev_get_drvdata(master); 78 struct msm_drm_private *priv = drm->dev_private; 79 struct msm_edp *edp; 80 81 DBG(""); 82 edp = edp_init(to_platform_device(dev)); 83 if (IS_ERR(edp)) 84 return PTR_ERR(edp); 85 priv->edp = edp; 86 87 return 0; 88} 89 90static void edp_unbind(struct device *dev, struct device *master, void *data) 91{ 92 struct drm_device *drm = dev_get_drvdata(master); 93 struct msm_drm_private *priv = drm->dev_private; 94 95 DBG(""); 96 if (priv->edp) { 97 edp_destroy(to_platform_device(dev)); 98 priv->edp = NULL; 99 } 100} 101 102static const struct component_ops edp_ops = { 103 .bind = edp_bind, 104 .unbind = edp_unbind, 105}; 106 107static int edp_dev_probe(struct platform_device *pdev) 108{ 109 DBG(""); 110 return component_add(&pdev->dev, &edp_ops); 111} 112 113static int edp_dev_remove(struct platform_device *pdev) 114{ 115 DBG(""); 116 component_del(&pdev->dev, &edp_ops); 117 return 0; 118} 119 120static const struct of_device_id dt_match[] = { 121 { .compatible = "qcom,mdss-edp" }, 122 {} 123}; 124 125static struct platform_driver edp_driver = { 126 .probe = edp_dev_probe, 127 .remove = edp_dev_remove, 128 .driver = { 129 .name = "msm_edp", 130 .of_match_table = dt_match, 131 }, 132}; 133 134void __init msm_edp_register(void) 135{ 136 DBG(""); 137 platform_driver_register(&edp_driver); 138} 139 140void __exit msm_edp_unregister(void) 141{ 142 DBG(""); 143 platform_driver_unregister(&edp_driver); 144} 145 146/* Second part of initialization, the drm/kms level modeset_init */ 147int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, 148 struct drm_encoder *encoder) 149{ 150 struct platform_device *pdev = edp->pdev; 151 struct msm_drm_private *priv = dev->dev_private; 152 int ret; 153 154 edp->encoder = encoder; 155 edp->dev = dev; 156 157 edp->bridge = msm_edp_bridge_init(edp); 158 if (IS_ERR(edp->bridge)) { 159 ret = PTR_ERR(edp->bridge); 160 dev_err(dev->dev, "failed to create eDP bridge: %d\n", ret); 161 edp->bridge = NULL; 162 goto fail; 163 } 164 165 edp->connector = msm_edp_connector_init(edp); 166 if (IS_ERR(edp->connector)) { 167 ret = PTR_ERR(edp->connector); 168 dev_err(dev->dev, "failed to create eDP connector: %d\n", ret); 169 edp->connector = NULL; 170 goto fail; 171 } 172 173 edp->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); 174 if (edp->irq < 0) { 175 ret = edp->irq; 176 dev_err(dev->dev, "failed to get IRQ: %d\n", ret); 177 goto fail; 178 } 179 180 ret = devm_request_irq(&pdev->dev, edp->irq, 181 edp_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 182 "edp_isr", edp); 183 if (ret < 0) { 184 dev_err(dev->dev, "failed to request IRQ%u: %d\n", 185 edp->irq, ret); 186 goto fail; 187 } 188 189 encoder->bridge = edp->bridge; 190 191 priv->bridges[priv->num_bridges++] = edp->bridge; 192 priv->connectors[priv->num_connectors++] = edp->connector; 193 194 return 0; 195 196fail: 197 /* bridge/connector are normally destroyed by drm */ 198 if (edp->bridge) { 199 edp_bridge_destroy(edp->bridge); 200 edp->bridge = NULL; 201 } 202 if (edp->connector) { 203 edp->connector->funcs->destroy(edp->connector); 204 edp->connector = NULL; 205 } 206 207 return ret; 208} 209