drm/exynos: hdmi: remove the i2c drivers and use
authorDaniel Kurtz <djkurtz@chromium.org>
Mon, 24 Feb 2014 09:52:51 +0000 (18:52 +0900)
committerInki Dae <daeinki@gmail.com>
Sun, 23 Mar 2014 15:36:32 +0000 (00:36 +0900)
The i2c client was previously being passed into the hdmi driver via a
dedicated i2c driver, and then a global variable. This patch removes all
of that and just uses the device tree to get the i2c_client. This patch
also properly references the client so we don't lose it before we're
done with it.

Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
[seanpaul changed to phandle lookup instead of using of node name]
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Documentation/devicetree/bindings/video/exynos_hdmi.txt
drivers/gpu/drm/exynos/Makefile
drivers/gpu/drm/exynos/exynos_hdmi.c

index 50decf8e1b90a573b11dc864c7b30612a5d5c5a0..f9187a259259f4a25dc80dfe08e66457228fa1fe 100644 (file)
@@ -25,6 +25,9 @@ Required properties:
                sclk_pixel.
 - clock-names: aliases as per driver requirements for above clock IDs:
        "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
+- ddc: phandle to the hdmi ddc node
+- phy: phandle to the hdmi phy node
+
 Example:
 
        hdmi {
@@ -32,4 +35,6 @@ Example:
                reg = <0x14530000 0x100000>;
                interrupts = <0 95 0>;
                hpd-gpio = <&gpx3 7 1>;
+               ddc = <&hdmi_ddc_node>;
+               phy = <&hdmi_phy_node>;
        };
index 639b49e1ec0586ceed662dbbfe3075bbf1157aa9..819961a3858c567a13938c70e88a6ed2d40e2704 100644 (file)
@@ -12,7 +12,6 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)    += exynos_drm_fimd.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)    += exynos_hdmi.o exynos_mixer.o \
-                                          exynos_ddc.o exynos_hdmiphy.o \
                                           exynos_drm_hdmi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI)    += exynos_drm_vidi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_G2D)     += exynos_drm_g2d.o
index b51672f538088993266db8e2fb434ebce88115e6..b0c58e4fdc56c08403a890dd6c424cd5e61e0822 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/i2c.h>
 #include <linux/of_gpio.h>
 #include <linux/hdmi.h>
 
@@ -41,8 +42,6 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_hdmi.h"
 
-#include "exynos_hdmi.h"
-
 #include <linux/gpio.h>
 #include <media/s5p_hdmi.h>
 
@@ -1907,20 +1906,6 @@ fail:
        return -ENODEV;
 }
 
-static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
-
-void hdmi_attach_ddc_client(struct i2c_client *ddc)
-{
-       if (ddc)
-               hdmi_ddc = ddc;
-}
-
-void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
-{
-       if (hdmiphy)
-               hdmi_hdmiphy = hdmiphy;
-}
-
 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
                                        (struct device *dev)
 {
@@ -1965,6 +1950,7 @@ static int hdmi_probe(struct platform_device *pdev)
        struct s5p_hdmi_platform_data *pdata;
        struct resource *res;
        const struct of_device_id *match;
+       struct device_node *ddc_node, *phy_node;
        int ret;
 
         if (!dev->of_node)
@@ -2015,21 +2001,30 @@ static int hdmi_probe(struct platform_device *pdev)
        }
 
        /* DDC i2c driver */
-       if (i2c_add_driver(&ddc_driver)) {
-               DRM_ERROR("failed to register ddc i2c driver\n");
-               return -ENOENT;
+       ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
+       if (!ddc_node) {
+               DRM_ERROR("Failed to find ddc node in device tree\n");
+               return -ENODEV;
+       }
+       hdata->ddc_port = of_find_i2c_device_by_node(ddc_node);
+       if (!hdata->ddc_port) {
+               DRM_ERROR("Failed to get ddc i2c client by node\n");
+               return -ENODEV;
        }
-
-       hdata->ddc_port = hdmi_ddc;
 
        /* hdmiphy i2c driver */
-       if (i2c_add_driver(&hdmiphy_driver)) {
-               DRM_ERROR("failed to register hdmiphy i2c driver\n");
-               ret = -ENOENT;
+       phy_node = of_parse_phandle(dev->of_node, "phy", 0);
+       if (!phy_node) {
+               DRM_ERROR("Failed to find hdmiphy node in device tree\n");
+               ret = -ENODEV;
+               goto err_ddc;
+       }
+       hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
+       if (!hdata->hdmiphy_port) {
+               DRM_ERROR("Failed to get hdmi phy i2c client from node\n");
+               ret = -ENODEV;
                goto err_ddc;
        }
-
-       hdata->hdmiphy_port = hdmi_hdmiphy;
 
        hdata->irq = gpio_to_irq(hdata->hpd_gpio);
        if (hdata->irq < 0) {
@@ -2060,22 +2055,22 @@ static int hdmi_probe(struct platform_device *pdev)
        return 0;
 
 err_hdmiphy:
-       i2c_del_driver(&hdmiphy_driver);
+       put_device(&hdata->hdmiphy_port->dev);
 err_ddc:
-       i2c_del_driver(&ddc_driver);
+       put_device(&hdata->ddc_port->dev);
        return ret;
 }
 
 static int hdmi_remove(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
+       struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
+       struct hdmi_context *hdata = ctx->ctx;
 
        pm_runtime_disable(dev);
 
-       /* hdmiphy i2c driver */
-       i2c_del_driver(&hdmiphy_driver);
-       /* DDC i2c driver */
-       i2c_del_driver(&ddc_driver);
+       put_device(&hdata->hdmiphy_port->dev);
+       put_device(&hdata->ddc_port->dev);
 
        return 0;
 }