| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 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 | 4 | */ |
|---|
| 13 | 5 | |
|---|
| 14 | 6 | #include "dsi.h" |
|---|
| .. | .. |
|---|
| 29 | 21 | |
|---|
| 30 | 22 | phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0); |
|---|
| 31 | 23 | if (!phy_node) { |
|---|
| 32 | | - dev_err(&pdev->dev, "cannot find phy device\n"); |
|---|
| 24 | + DRM_DEV_ERROR(&pdev->dev, "cannot find phy device\n"); |
|---|
| 33 | 25 | return -ENXIO; |
|---|
| 34 | 26 | } |
|---|
| 35 | 27 | |
|---|
| .. | .. |
|---|
| 41 | 33 | |
|---|
| 42 | 34 | of_node_put(phy_node); |
|---|
| 43 | 35 | |
|---|
| 44 | | - if (!phy_pdev || !msm_dsi->phy) { |
|---|
| 45 | | - dev_err(&pdev->dev, "%s: phy driver is not ready\n", __func__); |
|---|
| 36 | + if (!phy_pdev) { |
|---|
| 37 | + DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__); |
|---|
| 38 | + return -EPROBE_DEFER; |
|---|
| 39 | + } |
|---|
| 40 | + if (!msm_dsi->phy) { |
|---|
| 41 | + put_device(&phy_pdev->dev); |
|---|
| 42 | + DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__); |
|---|
| 46 | 43 | return -EPROBE_DEFER; |
|---|
| 47 | 44 | } |
|---|
| 48 | 45 | |
|---|
| .. | .. |
|---|
| 83 | 80 | return ERR_PTR(-ENOMEM); |
|---|
| 84 | 81 | DBG("dsi probed=%p", msm_dsi); |
|---|
| 85 | 82 | |
|---|
| 83 | + msm_dsi->id = -1; |
|---|
| 86 | 84 | msm_dsi->pdev = pdev; |
|---|
| 87 | 85 | platform_set_drvdata(pdev, msm_dsi); |
|---|
| 88 | 86 | |
|---|
| .. | .. |
|---|
| 117 | 115 | |
|---|
| 118 | 116 | DBG(""); |
|---|
| 119 | 117 | msm_dsi = dsi_init(pdev); |
|---|
| 120 | | - if (IS_ERR(msm_dsi)) |
|---|
| 121 | | - return PTR_ERR(msm_dsi); |
|---|
| 118 | + if (IS_ERR(msm_dsi)) { |
|---|
| 119 | + /* Don't fail the bind if the dsi port is not connected */ |
|---|
| 120 | + if (PTR_ERR(msm_dsi) == -ENODEV) |
|---|
| 121 | + return 0; |
|---|
| 122 | + else |
|---|
| 123 | + return PTR_ERR(msm_dsi); |
|---|
| 124 | + } |
|---|
| 122 | 125 | |
|---|
| 123 | 126 | priv->dsi[msm_dsi->id] = msm_dsi; |
|---|
| 124 | 127 | |
|---|
| .. | .. |
|---|
| 163 | 166 | |
|---|
| 164 | 167 | static const struct dev_pm_ops dsi_pm_ops = { |
|---|
| 165 | 168 | SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend, msm_dsi_runtime_resume, NULL) |
|---|
| 169 | + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
|---|
| 170 | + pm_runtime_force_resume) |
|---|
| 166 | 171 | }; |
|---|
| 167 | 172 | |
|---|
| 168 | 173 | static struct platform_driver dsi_driver = { |
|---|
| .. | .. |
|---|
| 200 | 205 | return -EINVAL; |
|---|
| 201 | 206 | |
|---|
| 202 | 207 | priv = dev->dev_private; |
|---|
| 208 | + |
|---|
| 209 | + if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) { |
|---|
| 210 | + DRM_DEV_ERROR(dev->dev, "too many bridges\n"); |
|---|
| 211 | + return -ENOSPC; |
|---|
| 212 | + } |
|---|
| 213 | + |
|---|
| 203 | 214 | msm_dsi->dev = dev; |
|---|
| 204 | 215 | |
|---|
| 205 | 216 | ret = msm_dsi_host_modeset_init(msm_dsi->host, dev); |
|---|
| 206 | 217 | if (ret) { |
|---|
| 207 | | - dev_err(dev->dev, "failed to modeset init host: %d\n", ret); |
|---|
| 218 | + DRM_DEV_ERROR(dev->dev, "failed to modeset init host: %d\n", ret); |
|---|
| 208 | 219 | goto fail; |
|---|
| 209 | 220 | } |
|---|
| 210 | 221 | |
|---|
| .. | .. |
|---|
| 218 | 229 | msm_dsi->bridge = msm_dsi_manager_bridge_init(msm_dsi->id); |
|---|
| 219 | 230 | if (IS_ERR(msm_dsi->bridge)) { |
|---|
| 220 | 231 | ret = PTR_ERR(msm_dsi->bridge); |
|---|
| 221 | | - dev_err(dev->dev, "failed to create dsi bridge: %d\n", ret); |
|---|
| 232 | + DRM_DEV_ERROR(dev->dev, "failed to create dsi bridge: %d\n", ret); |
|---|
| 222 | 233 | msm_dsi->bridge = NULL; |
|---|
| 223 | 234 | goto fail; |
|---|
| 224 | 235 | } |
|---|
| .. | .. |
|---|
| 240 | 251 | |
|---|
| 241 | 252 | if (IS_ERR(msm_dsi->connector)) { |
|---|
| 242 | 253 | ret = PTR_ERR(msm_dsi->connector); |
|---|
| 243 | | - dev_err(dev->dev, |
|---|
| 254 | + DRM_DEV_ERROR(dev->dev, |
|---|
| 244 | 255 | "failed to create dsi connector: %d\n", ret); |
|---|
| 245 | 256 | msm_dsi->connector = NULL; |
|---|
| 246 | 257 | goto fail; |
|---|
| 247 | 258 | } |
|---|
| 248 | 259 | |
|---|
| 260 | + msm_dsi_manager_setup_encoder(msm_dsi->id); |
|---|
| 261 | + |
|---|
| 249 | 262 | priv->bridges[priv->num_bridges++] = msm_dsi->bridge; |
|---|
| 250 | 263 | priv->connectors[priv->num_connectors++] = msm_dsi->connector; |
|---|
| 251 | 264 | |
|---|